From e37a4f418a22c8dec67694b780003c458d3cd474 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Thu, 10 Nov 2022 14:08:58 -0500 Subject: [PATCH] Based on output from a large contact array for a pad, modified the default behavior of magic to make use of the "gds contacts true" option to output contacts as arrays of subcells instead of individual boundary entries, as the former is much more efficient than the latter. Set the option to be true by default, and set the "gds flatglob" option to have one entry "$$*$$" corresponding to the contact subcells created by the "gds contacts" option, so that GDS reads and writes as it did previously (but using a different method). Expanded the method to include "squares-grid" and "slots" operators (the latter should produce much more efficient fill pattern arrays). Implemented for both compressed and uncompressed GDS. Tested in all variations. --- VERSION | 2 +- calma/CalmaRead.c | 12 ++++++++++++ calma/CalmaWrite.c | 3 ++- calma/CalmaWriteZ.c | 17 ++++++++++++++++- calma/calma.h | 1 + cif/CIFgen.c | 38 +++++++++++++++++++++++++------------- cif/CIFtech.c | 4 +++- 7 files changed, 60 insertions(+), 17 deletions(-) diff --git a/VERSION b/VERSION index 7b425238..5936d050 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.338 +8.3.339 diff --git a/calma/CalmaRead.c b/calma/CalmaRead.c index a920df9d..9197b16e 100644 --- a/calma/CalmaRead.c +++ b/calma/CalmaRead.c @@ -563,4 +563,16 @@ CalmaTechInit() { ASSERT(sizeof(FourByteInt)==4, "definition in calmaInt.h"); ASSERT(sizeof(TwoByteInt)==2, "definition in calmaInt.h"); + + /* Initialize CalmaFlattenByName to have one entry for */ + /* "$$*$$" to match the name style used by the contact */ + /* array cell generation. This can be overridden by the */ + /* "gds flatglob none" command option. */ + + if (CalmaFlattenUsesByName == (char **)NULL) + { + CalmaFlattenUsesByName = (char **)mallocMagic(2 * sizeof(char *)); + *CalmaFlattenUsesByName = StrDup((char **)NULL, "$$*$$"); + *(CalmaFlattenUsesByName + 1) = NULL; + } } diff --git a/calma/CalmaWrite.c b/calma/CalmaWrite.c index 93fa7ce6..31b0d7fc 100644 --- a/calma/CalmaWrite.c +++ b/calma/CalmaWrite.c @@ -67,8 +67,9 @@ time_t *CalmaDateStamp = NULL; /* If non-NULL, output this for creation date s bool CalmaAllowUndefined = FALSE; /* If TRUE, allow calls to undefined cells */ bool CalmaAllowAbstract = FALSE; /* If TRUE, allow abstract views to be written */ + /* CalmaContactArrays changed from FALSE to TRUE 11/10/2022 */ +bool CalmaContactArrays = TRUE; /* If TRUE, output contacts as subcell arrays */ /* Experimental stuff---not thoroughly tested (as of Sept. 2007)! */ -bool CalmaContactArrays = FALSE; /* If TRUE, output contacts as subcell arrays */ bool CalmaMergeTiles = FALSE; /* If TRUE, merge tiles into polygons in output. */ #ifdef HAVE_ZLIB diff --git a/calma/CalmaWriteZ.c b/calma/CalmaWriteZ.c index c699af4e..8ceb54cf 100644 --- a/calma/CalmaWriteZ.c +++ b/calma/CalmaWriteZ.c @@ -1144,6 +1144,8 @@ calmaOutFuncZ(def, f, cliprect) int type; int dbunits; calmaOutputStructZ cos; + bool propfound; + char *propvalue; cos.f = f; cos.area = (cliprect == &TiPlaneRect) ? NULL : cliprect; @@ -1200,6 +1202,19 @@ calmaOutFuncZ(def, f, cliprect) /* Output all the tiles associated with this cell; skip temporary layers */ GEO_EXPAND(&def->cd_bbox, CIFCurStyle->cs_radius, &bigArea); + + /* Include any fixed bounding box as part of the area to process, */ + /* in case the fixed bounding box is larger than the geometry. */ + propvalue = (char *)DBPropGet(def, "FIXED_BBOX", &propfound); + if (propfound) + { + Rect bbox; + + if (sscanf(propvalue, "%d %d %d %d", &bbox.r_xbot, &bbox.r_ybot, + &bbox.r_xtop, &bbox.r_ytop) == 4) + GeoInclude(&bbox, &bigArea); + } + CIFErrorDef = def; CIFGen(def, def, &bigArea, CIFPlanes, &DBAllTypeBits, TRUE, TRUE, FALSE, (ClientData)f); @@ -1559,7 +1574,7 @@ bad: /* * ---------------------------------------------------------------------------- * - * CalmaGenerateArray -- + * CalmaGenerateArrayZ -- * * This routine * diff --git a/calma/calma.h b/calma/calma.h index 4e828d92..9abc433e 100644 --- a/calma/calma.h +++ b/calma/calma.h @@ -86,6 +86,7 @@ extern void calmaRemoveColinear(); #ifdef HAVE_ZLIB extern bool CalmaWriteZ(); +extern bool CalmaGenerateArrayZ(); #endif #endif /* _CALMA_H */ diff --git a/cif/CIFgen.c b/cif/CIFgen.c index ec357b41..1591088c 100644 --- a/cif/CIFgen.c +++ b/cif/CIFgen.c @@ -3433,7 +3433,13 @@ cifContactFunc(tile, csi) left += halfsize; bottom += halfsize; - result = CalmaGenerateArray((FILE *)csi->csi_client, csi->csi_type, +#ifdef HAVE_ZLIB + if (CalmaCompression > 0) + result = CalmaGenerateArrayZ((FILETYPE)csi->csi_client, csi->csi_type, + left, bottom, pitch, nAcross, nUp); + else +#endif + result = CalmaGenerateArray((FILE *)csi->csi_client, csi->csi_type, left, bottom, pitch, nAcross, nUp); return (result == TRUE) ? 0 : 1; @@ -4840,12 +4846,15 @@ CIFGenLayer(op, area, cellDef, origDef, temps, hier, clientdata) break; } } - DBClearPaintPlane(nextPlane); - cifPlane = nextPlane; - cifSquaresFillArea(op, cellDef, curPlane); - temp = curPlane; - curPlane = nextPlane; - nextPlane = temp; + if (CalmaContactArrays == FALSE) + { + DBClearPaintPlane(nextPlane); + cifPlane = nextPlane; + cifSquaresFillArea(op, cellDef, curPlane); + temp = curPlane; + curPlane = nextPlane; + nextPlane = temp; + } break; case CIFOP_SLOTS: @@ -4857,12 +4866,15 @@ CIFGenLayer(op, area, cellDef, origDef, temps, hier, clientdata) break; } } - DBClearPaintPlane(nextPlane); - cifPlane = nextPlane; - cifSlotsFillArea(op, cellDef, curPlane); - temp = curPlane; - curPlane = nextPlane; - nextPlane = temp; + if (CalmaContactArrays == FALSE) + { + DBClearPaintPlane(nextPlane); + cifPlane = nextPlane; + cifSlotsFillArea(op, cellDef, curPlane); + temp = curPlane; + curPlane = nextPlane; + nextPlane = temp; + } break; case CIFOP_MAXRECT: diff --git a/cif/CIFtech.c b/cif/CIFtech.c index e1d40cb3..d6e8ca34 100644 --- a/cif/CIFtech.c +++ b/cif/CIFtech.c @@ -2049,7 +2049,9 @@ CIFTechFinal() for (op = style->cs_layers[i]->cl_ops; (op != NULL) && (op->co_opcode == CIFOP_OR) && (TTMaskIsZero(&op->co_cifMask)); op = op->co_next); - if (op && (op->co_opcode == CIFOP_SQUARES) && (op->co_next == NULL)) + if (op && ((op->co_opcode == CIFOP_SQUARES) || + (op->co_opcode == CIFOP_SQUARES_G) || + (op->co_opcode == CIFOP_SLOTS)) && (op->co_next == NULL)) { clientdata = op->co_client; for (op = style->cs_layers[i]->cl_ops; op->co_opcode == CIFOP_OR;