Index: trunk/src/examples/psu.lht =================================================================== --- trunk/src/examples/psu.lht (revision 1338) +++ trunk/src/examples/psu.lht (revision 1339) @@ -4,13 +4,13 @@ li:objects { ha:group.10 { li:objects { - ha:line.11 { x1=2000; y1=1000; x2=8000; y2=1000; pen=8; } + ha:line.11 { x1=2000; y1=1000; x2=8000; y2=1000; pen=sym-decor; } ha:line.12 { x1=2000; y1=1000; x2=2000; y2=3000; pen=8; } - ha:line.13 { x1=2000; y1=3000; x2=8000; y2=3000; pen=8; } + ha:line.13 { x1=2000; y1=3000; x2=8000; y2=3000; pen=sym-decor; } ha:line.14 { x1=8000; y1=1000; x2=8000; y2=3000; pen=8; } ha:group.20 { li:objects { - ha:line.1 { x1=0000; y1=2000; x2=2000; y2=2000; pen=5; } + ha:line.1 { x1=0000; y1=2000; x2=2000; y2=2000; pen=terminal; } } ha:attrib { name=1 @@ -38,11 +38,11 @@ # (visible) objects directly under the sheet ha:obj_direct.2 { li:objects { - ha:pen.1 { shape=circle; size=250; color=#777777; } # sheet deco - ha:pen.3 { shape=circle; size=250; color=#2222BB; } # wire-nets - ha:pen.5 { shape=circle; size=250; color=#991111; } # terminal - ha:pen.8 { shape=circle; size=250; color=#119911; } # symbol decoration - ha:pen.13 { shape=circle; size=800; color=#2222BB; } # wire-net junctions + ha:pen.1 { shape=circle; size=250; color=#777777; name="sheet-decor"; } + ha:pen.3 { shape=circle; size=250; color=#2222BB; name="wire"; } + ha:pen.5 { shape=circle; size=250; color=#991111; name="terminal"; } + ha:pen.8 { shape=circle; size=250; color=#119911; name="sym-decor"; } + ha:pen.13 { shape=circle; size=800; color=#2222BB; name="junction"; } ha:group_ref.20 { x=10000; y=10000; rot=0; mirror=x; @@ -72,8 +72,8 @@ ha:group.30 { li:objects { - ha:line.31 { x1=20000; y1=12000; x2=22000; y2=12000; pen=3; } - ha:line.32 { x1=22000; y1=16000; x2=22000; y2=12000; pen=3; } + ha:line.31 { x1=20000; y1=12000; x2=22000; y2=12000; pen=wire; } + ha:line.32 { x1=22000; y1=16000; x2=22000; y2=12000; pen=wire; } } ha:attrib { uid=xxxxx3 @@ -84,7 +84,7 @@ ha:group.50 { li:objects { - ha:line.51 { x1=21000; y1=16000; x2=21000; y2=13000; pen=3; } + ha:line.51 { x1=21000; y1=16000; x2=21000; y2=13000; pen=wire; } } ha:attrib { uid=xxxxx3 Index: trunk/src/libcschem/cnc_grp.c =================================================================== --- trunk/src/libcschem/cnc_grp.c (revision 1338) +++ trunk/src/libcschem/cnc_grp.c (revision 1339) @@ -60,6 +60,7 @@ { csch_cobj_init(&grp->hdr, sheet, parent, oid, CSCH_CTYPE_GRP); htip_init(&grp->id2obj, longhash, longkeyeq); + htsp_init(&grp->name2pen, strhash, strkeyeq); csch_cgrp_xform_update(sheet, grp); grp->role = csch_role_str2role(NULL); /* role is explicit empty on start */ return grp; @@ -111,6 +112,7 @@ for(e = htip_first(&grp->id2obj); e != NULL; e = htip_next(&grp->id2obj, e)) csch_cobj_free(e->value); htip_uninit(&grp->id2obj); + htsp_uninit(&grp->name2pen); csch_cobj_uninit(&grp->hdr); } @@ -216,6 +218,7 @@ csch_cobj_init(&grp->hdr, sheet, parent, oid, CSCH_CTYPE_GRP_REF); htip_init(&grp->id2obj, longhash, longkeyeq); + htsp_init(&grp->name2pen, strhash, strkeyeq); csch_cgrp_xform_update(sheet, grp); return grp; } Index: trunk/src/libcschem/cnc_pen.c =================================================================== --- trunk/src/libcschem/cnc_pen.c (revision 1338) +++ trunk/src/libcschem/cnc_pen.c (revision 1339) @@ -26,6 +26,7 @@ #include "config.h" #include +#include #include "concrete.h" #include "cnc_obj.h" #include "cnc_pen.h" @@ -47,7 +48,7 @@ return pen_shape_names[shape]; } -csch_cpen_t *csch_pen_alloc(csch_sheet_t *sheet, csch_cgrp_t *parent, csch_oid_t oid) +csch_cpen_t *csch_pen_alloc(csch_sheet_t *sheet, csch_cgrp_t *parent, csch_oid_t oid, const char *name) { csch_cpen_t *pen; @@ -57,16 +58,20 @@ pen = calloc(sizeof(csch_cpen_t), 1); csch_cobj_init(&pen->hdr, sheet, parent, oid, CSCH_CTYPE_PEN); + pen->name = (name == NULL ? NULL : rnd_strdup(name)); + if (pen->name != NULL) + htsp_set(&parent->name2pen, pen->name, pen); return pen; } csch_cpen_t *csch_pen_dup(csch_sheet_t *sheet, csch_cgrp_t *parent, const csch_cpen_t *src) { - csch_cpen_t *dst = csch_pen_alloc(sheet, parent, src->hdr.oid); + csch_cpen_t *dst = csch_pen_alloc(sheet, parent, src->hdr.oid, src->name); dst->shape = src->shape; dst->size = src->size; dst->color = src->color; dst->dash = src->dash; + dst->name = src->name == NULL ? NULL : rnd_strdup(src->name); return dst; } @@ -85,11 +90,26 @@ } } csch_cobj_uninit(&pen->hdr); + if (pen->name != NULL) { + htsp_popentry(&pen->hdr.parent->name2pen, pen->name); + + /* it's unlikely, but if another pen has the same name in the same group, we should fall back to that */ + for(e = htip_first(&pen->hdr.parent->id2obj); e; e = htip_next(&pen->hdr.parent->id2obj, e)) { + csch_cpen_t *p = e->value; + if ((p != pen) && (p->name != NULL) && (strcmp(p->name, pen->name) == 0)) { + htsp_set(&pen->hdr.parent->name2pen, p->name, p); + break; + } + } + + free(pen->name); + } + free(pen); } -csch_cpen_t *csch_pen_get(csch_sheet_t *sheet, csch_cgrp_t *grp, csch_oid_t oid) +csch_cpen_t *csch_pen_get_oid(csch_sheet_t *sheet, csch_cgrp_t *grp, csch_oid_t oid) { csch_cpen_t *pen = htip_get(&grp->id2obj, oid); if ((pen != NULL) && (pen->hdr.type != CSCH_CTYPE_PEN)) @@ -96,3 +116,11 @@ return NULL; return pen; } + +csch_cpen_t *csch_pen_get_name(csch_sheet_t *sheet, csch_cgrp_t *grp, const char *name) +{ + csch_cpen_t *pen = htsp_get(&grp->name2pen, name); + if ((pen != NULL) && (pen->hdr.type != CSCH_CTYPE_PEN)) + return NULL; + return pen; +} Index: trunk/src/libcschem/cnc_pen.h =================================================================== --- trunk/src/libcschem/cnc_pen.h (revision 1338) +++ trunk/src/libcschem/cnc_pen.h (revision 1339) @@ -42,6 +42,7 @@ csch_pen_shape_t shape; csch_coord_t size; /* diameter or edge length */ rnd_color_t color; + char *name; unsigned int dash; }; @@ -68,10 +69,11 @@ const char *csch_pen_shape_name(csch_pen_shape_t shape); -csch_cpen_t *csch_pen_alloc(csch_sheet_t *sheet, csch_cgrp_t *parent, csch_oid_t oid); +csch_cpen_t *csch_pen_alloc(csch_sheet_t *sheet, csch_cgrp_t *parent, csch_oid_t oid, const char *name); csch_cpen_t *csch_pen_dup(csch_sheet_t *sheet, csch_cgrp_t *parent, const csch_cpen_t *src); void csch_pen_free(csch_cpen_t *pen); -csch_cpen_t *csch_pen_get(csch_sheet_t *sheet, csch_cgrp_t *grp, csch_oid_t oid); +csch_cpen_t *csch_pen_get_oid(csch_sheet_t *sheet, csch_cgrp_t *grp, csch_oid_t oid); +csch_cpen_t *csch_pen_get_name(csch_sheet_t *sheet, csch_cgrp_t *grp, const char *name); extern csch_cpen_t csch_pen_default_unknown; @@ -81,7 +83,10 @@ if (hdr->pen == NULL) { csch_cgrp_t *grp = hdr->parent; while((hdr->pen == NULL) && (grp != NULL) && ((grp->hdr.type == CSCH_CTYPE_GRP) || (grp->hdr.type == CSCH_CTYPE_GRP_REF))) { - hdr->pen = csch_pen_get(hdr->sheet, grp, hdr->pen_oid); + if (hdr->pen_name != NULL) + hdr->pen = csch_pen_get_name(hdr->sheet, grp, hdr->pen_name); + else + hdr->pen = csch_pen_get_oid(hdr->sheet, grp, hdr->pen_oid); grp = grp->hdr.parent; } } Index: trunk/src/libcschem/concrete.h =================================================================== --- trunk/src/libcschem/concrete.h (revision 1338) +++ trunk/src/libcschem/concrete.h (revision 1339) @@ -93,7 +93,8 @@ csch_ctype_t type; csch_cgrp_t *parent; htsp_t attr; - csch_oid_t pen_oid; + const char *pen_name; /* used to resolve pen if not NULL */ + csch_oid_t pen_oid; /* used to resolve pen if pen_name is NULL */ gdl_elem_t link; /* sheet's active or removed list */ /*** cached ***/ @@ -112,6 +113,7 @@ struct csch_cgrp_s { /* type=CSCH_CTYPE_GRP || CSCH_CTYPE_GRP_REF */ csch_chdr_t hdr; htip_t id2obj; /* members (memb): id -> object pointer (primary storage); also acts as a list of active children objects */ + htsp_t name2pen; /* all pen directly under this group; key: pen->name; value: pen */ union { struct { /* type=CSCH_CTYPE_GRP */ Index: trunk/src/plugins/io_lihata/read.c =================================================================== --- trunk/src/plugins/io_lihata/read.c (revision 1338) +++ trunk/src/plugins/io_lihata/read.c (revision 1339) @@ -233,22 +233,25 @@ return 0; } -static int parse_oid(read_ctx_t *ctx, csch_oid_t *dst, const lht_node_t *src) +static int parse_oid(read_ctx_t *ctx, csch_oid_t *dst, const lht_node_t *src, int silent) { char *end; long l; if (src->type != LHT_TEXT) { - error(src, ("oid value must be text\n")); + if (!silent) + error(src, ("oid value must be text\n")); return -1; } l = strtol(src->data.text.value, &end, 10); if (*end != '\0') { - error(src, ("oid value: invalid integer '%s'\n", src->data.text.value)); + if (!silent) + error(src, ("oid value: invalid integer '%s'\n", src->data.text.value)); return -1; } if (l < 0) { - error(src, ("oid value: must be positive: '%s'\n", src->data.text.value)); + if (!silent) + error(src, ("oid value: must be positive: '%s'\n", src->data.text.value)); return -1; } *dst = l; @@ -341,6 +344,7 @@ static int parse_pen(read_ctx_t *ctx, csch_cgrp_t *parent, lht_node_t *subtree, csch_oid_t oid) { csch_cpen_t *pen; + const char *name; if (subtree == NULL) return 0; @@ -347,7 +351,9 @@ if (oid == 0) return -1; - pen = csch_pen_alloc(ctx->sheet, parent, oid); + + name = lht_dom_hash_get(subtree, "name"); + pen = csch_pen_alloc(ctx->sheet, parent, oid, name); if (pen == NULL) { error(subtree, ("failed to allocate pen\n")); return -1; @@ -363,6 +369,18 @@ return 0; } +static int parse_pen_ref(read_ctx_t *ctx, csch_chdr_t *obj, lht_node_t *subtree) +{ + const lht_node_t *pn = lht_dom_hash_get(subtree, "pen"); + + /* first try if it is an oid - integers are treated as oid, not name */ + if (parse_oid(ctx, &obj->pen_oid, pn, 1) == 0) + return 0; + + obj->pen_name = rnd_strdup(pn->data.text.value); + return 0; +} + static int parse_line(read_ctx_t *ctx, csch_cgrp_t *parent, lht_node_t *subtree, csch_oid_t oid) { csch_line_t *line; @@ -385,10 +403,8 @@ return -1; if (parse_coord(ctx, &line->spec.p2.y, lht_dom_hash_get(subtree, "y2")) != 0) return -1; - if (parse_oid(ctx, &line->hdr.pen_oid, lht_dom_hash_get(subtree, "pen")) != 0) - return -1; - return 0; + return parse_pen_ref(ctx, &line->hdr, subtree); } static int parse_connection(read_ctx_t *ctx, csch_cgrp_t *parent, lht_node_t *subtree, csch_oid_t oid) Index: trunk/src/plugins/std_tools/line_common.c =================================================================== --- trunk/src/plugins/std_tools/line_common.c (revision 1338) +++ trunk/src/plugins/std_tools/line_common.c (revision 1339) @@ -159,7 +159,7 @@ { csch_sheet_t *sheet = (csch_sheet_t *)hl; csch_coord_t x1, y1, x2, y2; - csch_cpen_t *pen = csch_pen_get(sheet, parent, pen_oid); + csch_cpen_t *pen = csch_pen_get_oid(sheet, parent, pen_oid); rnd_coord_t ps = (pen == NULL) ? C2P(1000) : C2P(pen->size); rnd_hid_set_line_cap(csch_crosshair_gc, rnd_cap_round); Index: trunk/src/plugins/std_tools/tool_circle.c =================================================================== --- trunk/src/plugins/std_tools/tool_circle.c (revision 1338) +++ trunk/src/plugins/std_tools/tool_circle.c (revision 1339) @@ -83,7 +83,7 @@ TODO("when editing symbol, use the symbol deco style"); if (csch_tool_circle.clicked) { - csch_cpen_t *pen = csch_pen_get(sheet, &sheet->direct, CSCH_PEN_SHEET_DECO); + csch_cpen_t *pen = csch_pen_get_oid(sheet, &sheet->direct, CSCH_PEN_SHEET_DECO); double dx, dy; rnd_coord_t ps = (pen == NULL) ? C2P(1000) : C2P(pen->size); Index: trunk/src/plugins/std_tools/tool_rect.c =================================================================== --- trunk/src/plugins/std_tools/tool_rect.c (revision 1338) +++ trunk/src/plugins/std_tools/tool_rect.c (revision 1339) @@ -101,7 +101,7 @@ TODO("when editing symbol, use the symbol deco style"); if (csch_tool_rect.clicked) { - csch_cpen_t *pen = csch_pen_get(sheet, &sheet->direct, CSCH_PEN_SHEET_DECO); + csch_cpen_t *pen = csch_pen_get_oid(sheet, &sheet->direct, CSCH_PEN_SHEET_DECO); rnd_coord_t x1, y1, x2, y2, ps = (pen == NULL) ? C2P(1000) : C2P(pen->size); x1 = C2P(csch_tool_rect.x);