diff --git a/calma/CalmaRdcl.c b/calma/CalmaRdcl.c index cd331a86..b036bd26 100644 --- a/calma/CalmaRdcl.c +++ b/calma/CalmaRdcl.c @@ -53,6 +53,7 @@ int calmaNonManhattan; int CalmaFlattenLimit = 10; int NameConvertErrors = 0; bool CalmaRewound = FALSE; +bool CalmaRecordPaths = FALSE; TileTypeBitMask *CalmaMaskHints = NULL; extern HashTable calmaDefInitHash; diff --git a/calma/CalmaRdpt.c b/calma/CalmaRdpt.c index 4d58ede2..ef0cf396 100644 --- a/calma/CalmaRdpt.c +++ b/calma/CalmaRdpt.c @@ -692,7 +692,12 @@ calmaElementPath(void) } } - CIFPropRecordPath(cifReadCellDef, pathheadp, TRUE, "path"); + /* If requested by command option, record the path centerline as a + * property of the cell def. + */ + if (CalmaRecordPaths) + CIFPropRecordPath(cifReadCellDef, pathheadp, TRUE, "path"); + CIFPaintWirePath(pathheadp, width, (pathtype == CALMAPATH_SQUAREFLUSH || pathtype == CALMAPATH_CUSTOM) ? FALSE : TRUE, plane, CIFPaintTable, (PaintUndoInfo *)NULL); diff --git a/calma/calma.h b/calma/calma.h index a2730b80..f745e1d6 100644 --- a/calma/calma.h +++ b/calma/calma.h @@ -38,6 +38,7 @@ extern TileTypeBitMask *CalmaMaskHints; extern bool CalmaMergeTiles; extern bool CalmaFlattenArrays; extern bool CalmaNoDRCCheck; +extern bool CalmaRecordPaths; extern bool CalmaFlattenUses; extern int CalmaFlattenLimit; extern float CalmaMagScale; diff --git a/cif/CIFrdpt.c b/cif/CIFrdpt.c index 35adc0b0..dee267d9 100644 --- a/cif/CIFrdpt.c +++ b/cif/CIFrdpt.c @@ -244,40 +244,61 @@ CIFPropRecordPath( { extern float CIFGetOutputScale(int convert); CIFPath *pathp; - char *pathstr, *sptr; - int components; - float x, y, oscale, mult; + char *namestr = NULL; + int components, i, x, y, mult, pathnum; + PropertyRecord *proprec; + bool propfound; - oscale = CIFGetOutputScale(1000); /* 1000 for conversion to um */ - if (oscale == 0.0) oscale = 1.0; - mult = (iswire == TRUE) ? 0.5 : 1.0; + /* If "name" is a property, then append a suffix to it to ensure uniqueness */ + DBPropGet(def, propname, &propfound); + if (propfound) + { + pathnum = 0; + namestr = mallocMagic(strlen(propname) + 10); + while (propfound) + { + sprintf(namestr, "%s_%d", propname, pathnum); + DBPropGet(def, namestr, &propfound); + pathnum++; + } + } - pathp = pathheadp; - components = 0; + mult = (iswire == TRUE) ? 1 : 0; /* Count the number of components in the path */ + pathp = pathheadp; + components = 0; while (pathp != NULL) { - pathp = pathp->cifp_next; components++; + pathp = pathp->cifp_next; } - /* Allocate enough space to hold 2 * N points at "infinity" */ - pathstr = (char *)mallocMagic(components * 40); + /* Allocate enough space to hold 2 * N points. */ + proprec = (PropertyRecord *)mallocMagic(sizeof(PropertyRecord) + + ((components - 1) * 2) * sizeof(int)); + proprec->prop_type = PROPERTY_TYPE_DIMENSION; + proprec->prop_len = components * 2; pathp = pathheadp; - sptr = pathstr; + i = 0; while (pathp != NULL) { - x = (float)pathp->cifp_x * oscale * mult; - y = (float)pathp->cifp_y * oscale * mult; - sprintf(sptr, "%.3f %.3f ", x, y); - sptr = sptr + strlen(sptr); + x = pathp->cifp_x >> mult; + y = pathp->cifp_y >> mult; + + proprec->prop_value.prop_integer[i] = x; + proprec->prop_value.prop_integer[i + 1] = y; + + i += 2; pathp = pathp->cifp_next; } - - /* Reallocate pathstr to be no larger than needed to hold the path contents */ - StrDup(&pathstr, pathstr); - DBPropPut(def, propname, (ClientData)pathstr); + if (namestr) + { + DBPropPut(def, namestr, proprec); + freeMagic(namestr); + } + else + DBPropPut(def, propname, proprec); } /* diff --git a/commands/CmdAB.c b/commands/CmdAB.c index 375ac307..472aea1c 100644 --- a/commands/CmdAB.c +++ b/commands/CmdAB.c @@ -779,8 +779,8 @@ CmdBox( break; case BOX_EXISTS: #ifdef MAGIC_WRAPPER - Tcl_SetResult(magicinterp, ToolGetBox(NULL, NULL) ? "1" : "0", - NULL); + Tcl_SetObjResult(magicinterp, + Tcl_NewBooleanObj(ToolGetBox(NULL, NULL) ? TRUE : FALSE)); #else TxPrintf("%s\n", ToolGetBox(NULL, NULL) ? "True" : "False"); #endif diff --git a/commands/CmdCD.c b/commands/CmdCD.c index 7e2ac203..c9315378 100644 --- a/commands/CmdCD.c +++ b/commands/CmdCD.c @@ -117,12 +117,13 @@ bool cmdDumpParseArgs(char *cmdName, MagWindow *w, TxCommand *cmd, CellUse *dumm #define CALMA_READ 19 #define CALMA_READONLY 20 #define CALMA_RESCALE 21 -#define CALMA_WARNING 22 -#define CALMA_WRITE 23 -#define CALMA_POLYS 24 -#define CALMA_PATHS 25 -#define CALMA_UNDEFINED 26 -#define CALMA_UNIQUE 27 +#define CALMA_SAVEPATHS 22 +#define CALMA_WARNING 23 +#define CALMA_WRITE 24 +#define CALMA_POLYS 25 +#define CALMA_PATHS 26 +#define CALMA_UNDEFINED 27 +#define CALMA_UNIQUE 28 #define CALMA_WARN_HELP CIF_WARN_END /* undefined by CIF module */ @@ -175,6 +176,7 @@ CmdCalma( " into edit cell", "readonly [yes|no] set cell as read-only and generate output from GDS file", "rescale [yes|no] allow or disallow internal grid subdivision", + "savepaths [yes|no] save path centerlines as cell properties", "warning [option] set warning information level", "write file output Calma GDS-II format to \"file\"\n" " for the window's root cell", @@ -738,6 +740,27 @@ CmdCalma( CalmaSubcellPolygons = (unsigned char)option; return; + case CALMA_SAVEPATHS: + if (cmd->tx_argc == 2) + { +#ifdef MAGIC_WRAPPER + Tcl_SetObjResult(magicinterp, Tcl_NewBooleanObj(CalmaRecordPaths)); +#else + TxPrintf("Paths in GDS cells read from input file are%s recorded" + " as cell properties.\n", + (CalmaRecordPaths) ? " " : " not"); +#endif + return; + } + else if (cmd->tx_argc != 3) + goto wrongNumArgs; + + option = Lookup(cmd->tx_argv[2], cmdCalmaYesNo); + if (option < 0) + goto wrongNumArgs; + CalmaRecordPaths = (option < 4) ? FALSE : TRUE; + return; + case CALMA_NO_DUP: if (cmd->tx_argc == 2) { diff --git a/doc/html/gds.html b/doc/html/gds.html index 3a0de05a..0a259921 100644 --- a/doc/html/gds.html +++ b/doc/html/gds.html @@ -182,6 +182,13 @@ Read GDSII input or generate GDSII output. than to subsplit the internal grid to such a fine value. The "cif limit" function may also be used to limit grid subdivision to a minimum value. +
savepaths [yes|no] +
When reading paths from a GDS file, record the centerline of + the path as a property in the cell. The default behavior is + no. If no argument is given, then return the status + of the savepaths option. The first path property is + named "path", followed by "path_0" and + increasing the suffix index for each individual path read.
unique [yes|no]
When reading a GDS file, this option forces magic to rename cell definitions in the database when a cell of the same name diff --git a/tcltk/wrapper.tcl b/tcltk/wrapper.tcl index a9d0e82e..db08aa0a 100644 --- a/tcltk/wrapper.tcl +++ b/tcltk/wrapper.tcl @@ -684,7 +684,10 @@ proc magic::cursorview {win} { *bypass crosshair ${olstx}um ${olsty}um } - if {[${win} box exists]} { + # I do not know why the T/F result gets lost or overridden sometimes + set gotbox [${win} box exists] + if {$gotbox == {}} {set gotbox false} + if {$gotbox} { set curunits [${win} units list] ${win} units microns noprint set dlst [${win} box position]