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.
This commit is contained in:
Tim Edwards 2022-11-10 14:08:58 -05:00
parent 70e15b1d33
commit e37a4f418a
7 changed files with 60 additions and 17 deletions

View File

@ -1 +1 @@
8.3.338
8.3.339

View File

@ -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;
}
}

View File

@ -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

View File

@ -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
*

View File

@ -86,6 +86,7 @@ extern void calmaRemoveColinear();
#ifdef HAVE_ZLIB
extern bool CalmaWriteZ();
extern bool CalmaGenerateArrayZ();
#endif
#endif /* _CALMA_H */

View File

@ -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:

View File

@ -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;