diff --git a/calma/CalmaRdpt.c b/calma/CalmaRdpt.c index cd5109c2..aee5c4b2 100644 --- a/calma/CalmaRdpt.c +++ b/calma/CalmaRdpt.c @@ -57,8 +57,6 @@ extern HashTable calmaDefInitHash; extern void calmaLayerError(); bool calmaReadPath(); -typedef enum { LABEL_TYPE_NONE, LABEL_TYPE_TEXT, LABEL_TYPE_PORT } labelType; - /* * ---------------------------------------------------------------------------- * @@ -274,7 +272,6 @@ calmaElementBoundary() } } - CIFPropRecordPath(cifReadCellDef, pathheadp, FALSE); rp = CIFPolyToRects(pathheadp, plane, CIFPaintTable, (PaintUndoInfo *)NULL); CIFFreePath(pathheadp); @@ -300,7 +297,7 @@ calmaElementBoundary() rpc.r_ytop /= calmaReadScale1; if ((ciftype >= 0) && - ((cifCurReadStyle->crs_labelSticky[ciftype] != LABEL_TYPE_NONE))) + (cifCurReadStyle->crs_labelSticky[ciftype] != LABEL_TYPE_NONE)) { Label *lab; TileType type; @@ -652,7 +649,7 @@ calmaElementPath() } } - CIFPropRecordPath(cifReadCellDef, pathheadp, TRUE); + CIFPropRecordPath(cifReadCellDef, pathheadp, TRUE, "path"); CIFPaintWirePath(pathheadp, width, (pathtype == CALMAPATH_SQUAREFLUSH || pathtype == CALMAPATH_CUSTOM) ? FALSE : TRUE, plane, CIFPaintTable, (PaintUndoInfo *)NULL); @@ -715,7 +712,7 @@ calmaElementText() cifnum = CIFCalmaLayerToCifLayer(layer, textt, cifCurReadStyle); if (cifnum < 0) { - if(cifCurReadStyle->crs_flags & CRF_IGNORE_UNKNOWNLAYER_LABELS) + if (cifCurReadStyle->crs_flags & CRF_IGNORE_UNKNOWNLAYER_LABELS) type = -1; else { calmaLayerError("Label on unknown layer/datatype", layer, textt); @@ -889,6 +886,12 @@ calmaElementText() r.r_ll.p_x * cifCurReadStyle->crs_scaleFactor, r.r_ll.p_y * cifCurReadStyle->crs_scaleFactor); } + else if (cifCurReadStyle->crs_labelSticky[cifnum] == LABEL_TYPE_CELLID) + { + /* Special handling of label layers marked "cellid" in the techfile. */ + /* The actual cellname is the ID string, not the GDS structure name. */ + DBCellRenameDef(cifReadCellDef, textbody); + } else if (type < 0) { calmaReadError("Warning: label \"%s\" at (%d, %d) is on unhandled" diff --git a/calma/calmaInt.h b/calma/calmaInt.h index 978da3a6..407d5c40 100644 --- a/calma/calmaInt.h +++ b/calma/calmaInt.h @@ -130,6 +130,9 @@ typedef struct /* Length of record header */ #define CALMAHEADERLENGTH 4 +/* Label types */ +typedef enum { LABEL_TYPE_NONE, LABEL_TYPE_TEXT, LABEL_TYPE_PORT, LABEL_TYPE_CELLID } labelType; + /* ------------------------- Input macros ----------------------------- */ /* Globals for Calma reading */ diff --git a/cif/CIFgen.c b/cif/CIFgen.c index 86eb3fb7..d063a087 100644 --- a/cif/CIFgen.c +++ b/cif/CIFgen.c @@ -3036,6 +3036,29 @@ CIFGenLayer(op, area, cellDef, temps, clientdata) } break; + case CIFOP_BOUNDARY: + cifPlane = curPlane; + /* This function for cifoutput only. cifinput handled separately. */ + if (cellDef && (cellDef->cd_flags & CDFIXEDBBOX)) + { + char *propvalue; + bool found; + + propvalue = (char *)DBPropGet(cellDef, "FIXED_BBOX", &found); + if (!found) break; + if (sscanf(propvalue, "%d %d %d %d", &bbox.r_xbot, &bbox.r_ybot, + &bbox.r_xtop, &bbox.r_ytop) != 4) break; + + cifScale = (CIFCurStyle) ? CIFCurStyle->cs_scaleFactor : 1; + bbox.r_xbot *= cifScale; + bbox.r_xtop *= cifScale; + bbox.r_ybot *= cifScale; + bbox.r_ytop *= cifScale; + DBNMPaintPlane(cifPlane, CIF_SOLIDTYPE, &bbox, + CIFPaintTable, (PaintUndoInfo *)NULL); + } + break; + case CIFOP_BBOX: if (CIFErrorDef == NULL) break; @@ -3149,6 +3172,7 @@ CIFGen(cellDef, area, planes, layers, replace, genAllPlanes, clientdata) CIFErrorLayer = i; new[i] = CIFGenLayer(CIFCurStyle->cs_layers[i]->cl_ops, &expanded, cellDef, new, clientdata); + /* Clean up the non-manhattan geometry in the plane */ if (CIFUnfracture) DBMergeNMTiles(new[i], &expanded, (PaintUndoInfo *)NULL); diff --git a/cif/CIFint.h b/cif/CIFint.h index f7f82105..6d3ef7ba 100644 --- a/cif/CIFint.h +++ b/cif/CIFint.h @@ -121,6 +121,8 @@ typedef struct cifop * the cell bounding box. This involves no magic type * layers but may itself be acted upon with grow/shrink * rules. + * CIFOP_BOUNDARY - Added 6/5/19---map the FIXED_BBOX property bounding + * box coordinates into CIF layer geometry. * CIFOP_NET - Added 11/3/08---pull an entire electrical net into * the CIF layer, selectively picking layers. * CIFOP_MAXRECT - Reduce all areas to the largest internal fitting @@ -144,9 +146,10 @@ typedef struct cifop #define CIFOP_ANDNOT 12 #define CIFOP_SQUARES_G 13 #define CIFOP_BBOX 14 -#define CIFOP_NET 15 -#define CIFOP_MAXRECT 16 -#define CIFOP_COPYUP 17 +#define CIFOP_BOUNDARY 15 +#define CIFOP_NET 16 +#define CIFOP_MAXRECT 17 +#define CIFOP_COPYUP 18 /* Added by Tim 10/21/2004 */ /* The following structure is used to pass information on how to draw diff --git a/cif/CIFrdcl.c b/cif/CIFrdcl.c index 9654af0a..1ddbfb8e 100644 --- a/cif/CIFrdcl.c +++ b/cif/CIFrdcl.c @@ -559,13 +559,15 @@ cifCopyPaintFunc(tile, cifCopyRec) int CIFPaintCurrent() { + extern int cifMakeBoundaryFunc(); /* Forward declaration. */ + extern int cifPaintCurrentFunc(); /* Forward declaration. */ + Plane *plane, *swapplane; int i; for (i = 0; i < cifCurReadStyle->crs_nLayers; i++) { TileType type; - extern int cifPaintCurrentFunc(); /* Forward declaration. */ CIFOp *op; plane = CIFGenLayer(cifCurReadStyle->crs_layers[i]->crl_ops, @@ -641,6 +643,23 @@ CIFPaintCurrent() } } } + else if (op == NULL) + { + /* Handle boundary layer */ + + op = cifCurReadStyle->crs_layers[i]->crl_ops; + while (op) + { + if (op->co_opcode == CIFOP_BOUNDARY) break; + op = op->co_next; + } + + if (op && (DBSrPaintArea((Tile *)NULL, plane, &TiPlaneRect, + &DBAllButSpaceBits, cifCheckPaintFunc, + (ClientData)NULL) == 1)) + DBSrPaintArea((Tile *) NULL, plane, &TiPlaneRect, + &CIFSolidBits, cifMakeBoundaryFunc, (ClientData)NULL); + } /* Swap planes */ swapplane = cifCurReadPlanes[type]; @@ -652,8 +671,8 @@ CIFPaintCurrent() DBSrPaintArea((Tile *) NULL, plane, &TiPlaneRect, &CIFSolidBits, cifPaintCurrentFunc, (ClientData)type); - } - + } + /* Recycle the plane, which was dynamically allocated. */ DBFreePaintPlane(plane); @@ -668,9 +687,34 @@ CIFPaintCurrent() return 0; } -/* Below is the search function invoked for each CIF tile type - * found for the current layer. - */ +/* Use CIF layer geometry to define a fixed bounding box for the current cell */ + +int +cifMakeBoundaryFunc(tile, clientdata) + Tile *tile; /* Tile of CIF information. */ + ClientData clientdata; /* Not used */ +{ + /* It is assumed that there is one rectangle for the boundary. */ + /* If there are multiple rectangles defined with the boundary */ + /* layer, then the last one defines the FIXED_BBOX property. */ + + Rect area; + char propertyvalue[128], *storedvalue; + + TiToRect(tile, &area); + + if (cifReadCellDef->cd_flags & CDFIXEDBBOX) + CIFReadError("Warning: Cell %s boundary was redefined.\n", + cifReadCellDef->cd_name); + + sprintf(propertyvalue, "%d %d %d %d", + area.r_xbot, area.r_ybot, area.r_xtop, area.r_ytop); + storedvalue = StrDup((char **)NULL, propertyvalue); + DBPropPut(cifReadCellDef, "FIXED_BBOX", storedvalue); + cifReadCellDef->cd_flags |= CDFIXEDBBOX; +} + +/* Paint CIF layer geometry into the current cell def as magic layer "type" */ int cifPaintCurrentFunc(tile, type) diff --git a/cif/CIFrdpt.c b/cif/CIFrdpt.c index d0cf25cf..ec3846af 100644 --- a/cif/CIFrdpt.c +++ b/cif/CIFrdpt.c @@ -234,9 +234,10 @@ CIFParseFlash() */ void -CIFPropRecordPath(def, pathheadp, iswire) +CIFPropRecordPath(def, pathheadp, iswire, propname) CellDef *def; CIFPath *pathheadp; + char *propname; { extern float CIFGetOutputScale(); CIFPath *pathp; @@ -273,7 +274,7 @@ CIFPropRecordPath(def, pathheadp, iswire) /* Reallocate pathstr to be no larger than needed to hold the path contents */ StrDup(&pathstr, pathstr); - DBPropPut(def, "path", (ClientData)pathstr); + DBPropPut(def, propname, (ClientData)pathstr); } /* diff --git a/cif/CIFrdtech.c b/cif/CIFrdtech.c index 0ec99571..297ad7b6 100644 --- a/cif/CIFrdtech.c +++ b/cif/CIFrdtech.c @@ -62,9 +62,6 @@ CIFOp *cifCurReadOp; /* Last geometric operation seen. */ void cifReadStyleInit(); void CIFReadLoadStyle(); -/* Label types used by the "labels" statement option */ -typedef enum { LABEL_TYPE_NONE, LABEL_TYPE_TEXT, LABEL_TYPE_PORT } labelType; - /* * ---------------------------------------------------------------------------- * @@ -858,6 +855,8 @@ CIFReadTechLine(sectionName, argc, argv) calmaLabelType = LABEL_TYPE_TEXT; else if (!strcmp(argv[2], "port")) calmaLabelType = LABEL_TYPE_PORT; + else if (!strncmp(argv[2], "cell", 4)) + calmaLabelType = LABEL_TYPE_CELLID; else goto wrongNumArgs; } @@ -952,6 +951,8 @@ CIFReadTechLine(sectionName, argc, argv) newOp->co_opcode = CIFOP_SHRINK; else if (strcmp(argv[0], "copyup") == 0) newOp->co_opcode = CIFOP_COPYUP; + else if (strcmp(argv[0], "boundary") == 0) + newOp->co_opcode = CIFOP_BOUNDARY; else { TechError("Unknown statement \"%s\".\n", argv[0]); @@ -967,7 +968,6 @@ CIFReadTechLine(sectionName, argc, argv) if (argc != 2) goto wrongNumArgs; CIFParseReadLayers(argv[1], &newOp->co_cifMask); break; - case CIFOP_GROW: case CIFOP_GROW_G: case CIFOP_SHRINK: diff --git a/cif/CIFread.h b/cif/CIFread.h index bd225e04..5656600f 100644 --- a/cif/CIFread.h +++ b/cif/CIFread.h @@ -54,8 +54,8 @@ typedef struct * the "crl_magicType" should be interpreted as a CIF layer. */ -#define CIFR_SIMPLE 1 -#define CIFR_TEMPLAYER 2 +#define CIFR_SIMPLE 1 +#define CIFR_TEMPLAYER 2 /* The following structure defines a complete CIF read-in style. * The constant MAXCIFRLAYERS must be less than TT_MAXTYPES, and diff --git a/cif/CIFtech.c b/cif/CIFtech.c index ff9e2b03..54bb05c6 100644 --- a/cif/CIFtech.c +++ b/cif/CIFtech.c @@ -104,6 +104,7 @@ cifTechFreeStyle() case CIFOP_OR: case CIFOP_BBOX: case CIFOP_MAXRECT: + case CIFOP_BOUNDARY: /* These options use co_client to hold a single */ /* integer value, so it is not allocated. */ break; @@ -802,8 +803,7 @@ CIFTechLine(sectionName, argc, argv) if (CIFCurStyle->cs_status != TECH_PENDING) return TRUE; newLayer = NULL; - if ((strcmp(argv[0], "templayer") == 0) - || (strcmp(argv[0], "layer") == 0)) + if ((strcmp(argv[0], "templayer") == 0) || (strcmp(argv[0], "layer") == 0)) { if (CIFCurStyle->cs_nLayers == MAXCIFLAYERS) { @@ -1047,6 +1047,8 @@ CIFTechLine(sectionName, argc, argv) newOp->co_opcode = CIFOP_NET; else if (strcmp(argv[0], "maxrect") == 0) newOp->co_opcode = CIFOP_MAXRECT; + else if (strcmp(argv[0], "boundary") == 0) + newOp->co_opcode = CIFOP_BOUNDARY; else { TechError("Unknown statement \"%s\".\n", argv[0]); @@ -1196,6 +1198,12 @@ bloatCheck: goto wrongNumArgs; break; + case CIFOP_BOUNDARY: + /* CIFOP_BOUNDARY has no arguments */ + if (argc != 1) + goto wrongNumArgs; + break; + case CIFOP_SQUARES_G: case CIFOP_SQUARES: @@ -1752,6 +1760,7 @@ CIFTechFinal() { case CIFOP_OR: case CIFOP_BBOX: + case CIFOP_BOUNDARY: case CIFOP_MAXRECT: case CIFOP_NET: break; @@ -2232,6 +2241,7 @@ CIFTechOutputScale(n, d) { case CIFOP_OR: case CIFOP_BBOX: + case CIFOP_BOUNDARY: case CIFOP_MAXRECT: case CIFOP_NET: break; diff --git a/database/DBprop.c b/database/DBprop.c index 2ea9b652..c2ded840 100644 --- a/database/DBprop.c +++ b/database/DBprop.c @@ -55,6 +55,7 @@ DBPropPut(cellDef, name, value) { HashTable *htab; HashEntry *entry; + char *oldvalue; /* Honor the NOEDIT flag */ if (cellDef->cd_flags & CDNOEDIT) return; @@ -67,6 +68,8 @@ DBPropPut(cellDef, name, value) htab = (HashTable *) cellDef->cd_props; entry = HashFind(htab, name); + oldvalue = (char *)HashGetValue(entry); + if (oldvalue != NULL) freeMagic(oldvalue); HashSetValue(entry, value); } diff --git a/wiring/wireTech.c b/wiring/wireTech.c index 7f49e9a9..a8e4aa75 100644 --- a/wiring/wireTech.c +++ b/wiring/wireTech.c @@ -108,6 +108,7 @@ WireTechLine(sectionName, argc, argv) return TRUE; } WireUnits = atoi(argv[1]); + return TRUE; } if (strcmp(argv[0], "contact") != 0)