diff --git a/VERSION b/VERSION index b2898ae9..36c57972 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.618 +8.3.619 diff --git a/cif/CIFgen.c b/cif/CIFgen.c index 8f8cc362..8e03f1f8 100644 --- a/cif/CIFgen.c +++ b/cif/CIFgen.c @@ -25,6 +25,7 @@ static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magi #include /* for abs() */ #include /* for ceil() and sqrt() */ #include +#include /* for strcmp() */ #include "utils/magic.h" #include "utils/geometry.h" @@ -5136,12 +5137,13 @@ CIFGenLayer( CIFSquaresInfo csi; SearchContext scx; TileType ttype; - char *netname; + char *netname, *text; + Label *label; BloatStruct bls; BridgeStruct brs; BridgeLimStruct brlims; BridgeData *bridge; - BloatData *bloats; + BloatData *bloats, locbloat; bool hstop = FALSE; PropertyRecord *proprec; char *propvalue; @@ -5601,6 +5603,105 @@ CIFGenLayer( } break; + case CIFOP_LABELED: + if (hier) + { + hstop = TRUE; /* Stop hierarchical processing */ + break; + } + + /* + * Find all relevant labels by text matching and then continue + * like CIFOP_BLOATALL. CIFOP_BLOATALL uses a BloatData record + * which is not part of CIFOP_LABELED. Create a BloatData record + * on the fly for each labeled area based on type, and swap it for + * the text, so that cifBloatAllFunc believes this is actually a + * CIFOP_BLOATALL operation. Note that we don't actually care + * what layer the label is attached to (lab_type). We are looking + * for labels whose lab_rect values overlap the types that are given + * in the rule. + */ + + cifPlane = curPlane; + bls.op = op; + bls.def = cellDef; + bls.temps = temps; + + text = (char *)op->co_client; + + bloats = &locbloat; + if (!TTMaskIsZero(&op->co_cifMask)) + { + bloats->bl_plane = -1; + for (ttype = 0; ttype < TT_MAXTYPES; ttype++) + { + if (TTMaskHasType(&op->co_cifMask, ttype)) + bloats->bl_distance[ttype] = 1; + else + bloats->bl_distance[ttype] = 0; + } + } + else if (!TTMaskIsZero(&op->co_paintMask)) + { + int plane, pmask; + pmask = DBTechTypesToPlanes(&op->co_paintMask); + for (plane = PL_TECHDEPBASE; plane < DBNumPlanes; plane++) + if (PlaneMaskHasPlane(pmask, plane)) + break; + bloats->bl_plane = plane; + for (ttype = 0; ttype < TT_MAXTYPES; ttype++) + { + if (TTMaskHasType(&op->co_paintMask, ttype)) + bloats->bl_distance[ttype] = 1; + else + bloats->bl_distance[ttype] = 0; + } + } + + /* Replace the client data with the bloat record */ + op->co_client = (ClientData)bloats; + + if (bloats->bl_plane < 0) + { + /* bl_plane == -1 indicates bloating into a CIF templayer, */ + /* so the only connecting type should be CIF_SOLIDTYPE. */ + TTMaskSetOnlyType(&bls.connect, CIF_SOLIDTYPE); + } + else + { + int i; + TTMaskZero(&bls.connect); + for (i = 0; i < TT_MAXTYPES; i++) + if (bloats->bl_distance[i] != 0) + TTMaskSetType(&bls.connect, i); + } + + for (label = cellDef->cd_labels; label; label = label->lab_next) + if (!strcmp(label->lab_text, text)) + cifSrTiles(op, &label->lab_rect, cellDef, temps, + cifBloatAllFunc, (ClientData)&bls); + + /* Reset marked tiles */ + + if (bloats->bl_plane < 0) /* Bloat types are CIF types */ + { + bls.temps = temps; + for (ttype = 0; ttype < TT_MAXTYPES; ttype++, bls.temps++) + if (bloats->bl_distance[ttype] > 0) + (void) DBSrPaintArea((Tile *)NULL, *bls.temps, &TiPlaneRect, + &CIFSolidBits, cifProcessResetFunc, + (ClientData)NULL); + } + else + DBSrPaintArea((Tile *)NULL, cellDef->cd_planes[bloats->bl_plane], + &TiPlaneRect, &bls.connect, cifProcessResetFunc, + (ClientData)NULL); + + /* Replace the client data */ + op->co_client = (ClientData)text; + + break; + case CIFOP_BOUNDARY: if (hier) { diff --git a/cif/CIFint.h b/cif/CIFint.h index 1b91a72d..ba29bd94 100644 --- a/cif/CIFint.h +++ b/cif/CIFint.h @@ -146,6 +146,7 @@ typedef struct cifop * CIFOP_BRIDGELIM - Added 27/07/20---Bridge across catecorner gaps, but with limiting layers * CIFOP_MASKHINTS - Added 12/14/20---Add geometry from cell properties, if any. * CIFOP_NOTSQUARE - Added 2/26/26---Keep only geometry which is not square. + * CIFOP_LABELED - Added 3/11/26---Find geometry attached to the given text label */ #define CIFOP_AND 1 @@ -174,6 +175,7 @@ typedef struct cifop #define CIFOP_BRIDGELIM 24 #define CIFOP_MASKHINTS 25 #define CIFOP_NOTSQUARE 26 +#define CIFOP_LABELED 27 /* Definitions of bit fields used in the value of co_client for CIFOP_INTERACT */ #define CIFOP_INT_NOT 0x1 /* Inverted sense (not interacting) */ diff --git a/cif/CIFrdcl.c b/cif/CIFrdcl.c index cf10a7b3..c965bbaa 100644 --- a/cif/CIFrdcl.c +++ b/cif/CIFrdcl.c @@ -613,7 +613,7 @@ CIFPaintCurrent( CIFOp *op; plane = CIFGenLayer(cifCurReadStyle->crs_layers[i]->crl_ops, - &TiPlaneRect, (CellDef *)NULL, (CellDef *)NULL, + &TiPlaneRect, cifReadCellDef, cifReadCellDef, cifCurReadPlanes, FALSE, (ClientData)NULL); /* Generate a paint/erase table, then paint from the CIF diff --git a/cif/CIFrdtech.c b/cif/CIFrdtech.c index 9efaee72..107d1c31 100644 --- a/cif/CIFrdtech.c +++ b/cif/CIFrdtech.c @@ -332,7 +332,8 @@ cifNewReadStyle(void) free_magic1_t mm1 = freeMagic1_init(); for (op = layer->crl_ops; op != NULL; op = op->co_next) { - if (op->co_opcode == CIFOP_MASKHINTS) + if (op->co_opcode == CIFOP_MASKHINTS || + op->co_opcode == CIFOP_LABELED) freeMagic((char *)op->co_client); freeMagic1(&mm1, (char *)op); } @@ -998,6 +999,8 @@ CIFReadTechLine( newOp->co_opcode = CIFOP_NOTSQUARE; else if (strcmp(argv[0], "mask-hints") == 0) newOp->co_opcode = CIFOP_MASKHINTS; + else if (strcmp(argv[0], "labeled") == 0) + newOp->co_opcode = CIFOP_LABELED; else { TechError("Unknown statement \"%s\".\n", argv[0]); @@ -1028,6 +1031,11 @@ CIFReadTechLine( if (argc != 2) goto wrongNumArgs; newOp->co_client = (ClientData)StrDup((char **)NULL, argv[1]); break; + case CIFOP_LABELED: + if (argc != 3) goto wrongNumArgs; + newOp->co_client = (ClientData)StrDup((char **)NULL, argv[1]); + CIFParseReadLayers(argv[2], &newOp->co_cifMask, TRUE); + break; } /* Link the new CIFOp onto the list. */ diff --git a/cif/CIFtech.c b/cif/CIFtech.c index 3e6844c5..38e42238 100644 --- a/cif/CIFtech.c +++ b/cif/CIFtech.c @@ -1107,6 +1107,8 @@ CIFTechLine( newOp->co_opcode = CIFOP_BBOX; else if (strcmp(argv[0], "net") == 0) newOp->co_opcode = CIFOP_NET; + else if (strcmp(argv[0], "labeled") == 0) + newOp->co_opcode = CIFOP_LABELED; else if (strcmp(argv[0], "maxrect") == 0) newOp->co_opcode = CIFOP_MAXRECT; else if (strcmp(argv[0], "boundary") == 0) @@ -1357,6 +1359,7 @@ bloatCheck: bloatDone: break; case CIFOP_NET: + case CIFOP_LABELED: if (argc != 3) goto wrongNumArgs; newOp->co_client = (ClientData)StrDup((char **)NULL, argv[1]); cifParseLayers(argv[2], CIFCurStyle, &newOp->co_paintMask, @@ -1671,12 +1674,12 @@ cifComputeRadii( for (op = layer->cl_ops; op != NULL; op = op->co_next) { - /* BBOX, NET, and MASKHINTS operators should never be used */ - /* hierarchically so ignore any grow/shrink operators that */ + /* BBOX, NET, LABELED, and MASKHINTS operators should never be */ + /* used hierarchically so ignore any grow/shrink operators that */ /* come after them. */ if (op->co_opcode == CIFOP_BBOX || op->co_opcode == CIFOP_NET || - op->co_opcode == CIFOP_MASKHINTS) + op->co_opcode == CIFOP_LABELED || op->co_opcode == CIFOP_MASKHINTS) break; /* If CIF layers are used, switch to the max of current @@ -1988,8 +1991,8 @@ CIFTechFinal(void) /* Presence of op->co_opcode in CIFOP_OR indicates a copy */ /* of the SquaresData pointer from a following operator. */ /* CIFOP_BBOX and CIFOP_MAXRECT uses the co_client field */ - /* as a flag field, while CIFOP_NET and CIFOP_MASKHINTS */ - /* uses it for a string. */ + /* as a flag field, while CIFOP_NET, CIFOP_MASKHINTS, and */ + /* CIFOP_LABELED use it for a string. */ else { switch (op->co_opcode) @@ -2001,6 +2004,7 @@ CIFTechFinal(void) case CIFOP_MAXRECT: case CIFOP_MANHATTAN: case CIFOP_NET: + case CIFOP_LABELED: break; case CIFOP_BRIDGELIM: case CIFOP_BRIDGE: @@ -2536,6 +2540,7 @@ CIFTechOutputScale( case CIFOP_MAXRECT: case CIFOP_MANHATTAN: case CIFOP_NET: + case CIFOP_LABELED: case CIFOP_INTERACT: break; case CIFOP_BRIDGELIM: @@ -2651,8 +2656,8 @@ CIFTechOutputScale( default: /* op->co_opcode in CIFOP_OR is a pointer copy, */ /* in CIFOP_BBOX and CIFOP_MAXRECT is a flag, */ - /* and in CIFOP_NET and CIFOP_MASKHINTS is a */ - /* string. */ + /* and in CIFOP_NET, CIFOP_MASKHINTS, and */ + /* CIFOP_LABELED is a string. */ break; } }