From d4c3939febaba8f1ffeeb5003f8d9ca8daa15f7b Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Wed, 6 Jan 2021 10:33:43 -0500 Subject: [PATCH] Extended the "mask-hints" operator to work correctly through a hierarchy. --- VERSION | 2 +- cif/CIFgen.c | 2 +- cif/CIFhier.c | 129 ++++++++++++++++++++++++++++++++++++++++++ cif/CIFint.h | 1 + cif/CIFsee.c | 9 +++ database/DBcellsrch.c | 15 +++-- 6 files changed, 151 insertions(+), 7 deletions(-) diff --git a/VERSION b/VERSION index dcc5cfe0..f67731d6 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.110 +8.3.111 diff --git a/cif/CIFgen.c b/cif/CIFgen.c index 4a3a4899..35e7465a 100644 --- a/cif/CIFgen.c +++ b/cif/CIFgen.c @@ -5175,7 +5175,7 @@ CIFGenLayer(op, area, cellDef, origDef, temps, hier, clientdata) sprintf(propname, "MASKHINTS_%s", layername); - propvalue = (char *)DBPropGet(origDef, propname, &found); + propvalue = (char *)DBPropGet(cellDef, propname, &found); if (!found) break; /* No mask hints available */ propptr = propvalue; while (*propptr) diff --git a/cif/CIFhier.c b/cif/CIFhier.c index a7370d69..0a5e4da2 100644 --- a/cif/CIFhier.c +++ b/cif/CIFhier.c @@ -201,6 +201,123 @@ cifHierCleanup() SigEnableInterrupts(); } +/* Structure used by cifFlatMaskHints */ + +typedef struct _maskHintsData +{ + Transform *mh_trans; + CellDef *mh_def; +} MaskHintsData; + +/* + * ---------------------------------------------------------------------------- + * + * cifFlatMaskHints -- + * + * Copy a mask hint into a flattened cell by transforming it into the + * coordinate system of the flattened cell, and adding it to the + * property list of the flattened cell. + * + * Returns: + * 0 to keep the search going. + * + * Side effects: + * Modifies properties of the cell def passed in MaskHintsData. + * + * ---------------------------------------------------------------------------- + */ + +cifFlatMaskHints(name, value, mhd) + char *name; + char *value; + MaskHintsData *mhd; +{ + Rect r, newr; + char *vptr, *newval, *lastval, *propvalue; + bool propfound; + int lastlen; + + if (!strncmp(name, "MASKHINTS_", 10)) + { + newval = (char *)NULL; + vptr = value; + while (*vptr != '\0') + { + if (sscanf(vptr, "%d %d %d %d", &r.r_xbot, &r.r_ybot, + &r.r_xtop, &r.r_ytop) == 4) + { + /* Transform rectangle to top level coordinates */ + GeoTransRect(mhd->mh_trans, &r, &newr); + lastval = newval; + lastlen = (lastval) ? strlen(lastval) : 0; + newval = mallocMagic(40 + lastlen); + if (lastval) + strcpy(newval, lastval); + else + *newval = '\0'; + sprintf(newval + lastlen, "%s%d %d %d %d", (lastval) ? "" : " ", + newr.r_xbot, newr.r_ybot, newr.r_xtop, newr.r_ytop); + if (lastval) freeMagic(lastval); + + /* Parse through the four values and check if there's more */ + while (*vptr && !isspace(*vptr)) vptr++; + while (*vptr && isspace(*vptr)) vptr++; + while (*vptr && !isspace(*vptr)) vptr++; + while (*vptr && isspace(*vptr)) vptr++; + while (*vptr && !isspace(*vptr)) vptr++; + while (*vptr && isspace(*vptr)) vptr++; + while (*vptr && !isspace(*vptr)) vptr++; + while (*vptr && isspace(*vptr)) vptr++; + } + } + + /* Check if name exists already in the flattened cell */ + propvalue = (char *)DBPropGet(mhd->mh_def, name, &propfound); + if (propfound) + { + /* Append newval to the property */ + lastval = newval; + newval = mallocMagic(strlen(lastval) + strlen(propvalue) + 2); + sprintf(newval, "%s %s", propvalue, lastval); + freeMagic(lastval); + } + DBPropPut(mhd->mh_def, name, newval); + } + return 0; +} + + +/* + * ---------------------------------------------------------------------------- + * + * cifHierCopyMaskHints -- + * + * Callback function to copy mask hints from a subcell into a flattened + * cell, which is passed in the clientData record. + * + * Results: + * Always returns 0 to keep the search alive. + * + * Side effects: + * May modify properties in the flattened cell. + * + * ---------------------------------------------------------------------------- + */ + +int +cifHierCopyMaskHints(scx, clientData) + SearchContext *scx; + ClientData clientData; +{ + MaskHintsData mhd; + + mhd.mh_trans = &scx->scx_trans; + mhd.mh_def = (CellDef *)clientData; + + DBPropEnum(scx->scx_use->cu_def, cifFlatMaskHints, &mhd); + return 0; +} + /* * ---------------------------------------------------------------------------- * @@ -319,6 +436,10 @@ cifHierCellFunc(scx) (void) DBTreeSrTiles(&newscx, &CIFCurStyle->cs_yankLayers, 0, cifHierCopyFunc, (ClientData) CIFComponentDef); + /* Flatten mask hints in the area of interest */ + DBTreeSrCells(&newscx, 0, cifHierCopyMaskHints, + (ClientData)CIFComponentDef); + /* Set CIFErrorDef to NULL to ignore errors here... these will * get reported anyway when the cell is CIF'ed non-hierarchically, * so there's no point in making a second report here. @@ -637,6 +758,10 @@ CIFGenSubcells(def, area, output) GEO_EXPAND(&interaction, CIFCurStyle->cs_radius, &scx.scx_area); (void) DBTreeSrTiles(&scx, &CIFCurStyle->cs_yankLayers, 0, cifHierCopyFunc, (ClientData) CIFTotalDef); + /* Flatten mask hints in the area of interest */ + DBTreeSrCells(&scx, 0, cifHierCopyMaskHints, + (ClientData)CIFTotalDef); + CIFErrorDef = def; CIFGen(CIFTotalDef, def, &interaction, CIFTotalPlanes, &CIFCurStyle->cs_hierLayers, TRUE, TRUE, TRUE, @@ -762,10 +887,14 @@ cifHierElementFunc(use, transform, x, y, checkArea) scx.scx_use = use; (void) DBTreeSrTiles(&scx, &CIFCurStyle->cs_yankLayers, 0, cifHierCopyFunc, (ClientData) CIFTotalDef); + DBTreeSrCells(&scx, 0, cifHierCopyMaskHints, + (ClientData)CIFTotalDef); DBCellClearDef(CIFComponentDef); (void) DBTreeSrTiles(&scx, &CIFCurStyle->cs_yankLayers, 0, cifHierCopyFunc, (ClientData) CIFComponentDef); + DBTreeSrCells(&scx, 0, cifHierCopyMaskHints, + (ClientData)CIFComponentDef); CIFErrorDef = (CellDef *) NULL; CIFGen(CIFComponentDef, use->cu_def, checkArea, CIFComponentPlanes, diff --git a/cif/CIFint.h b/cif/CIFint.h index 88a87bf4..0532cdaf 100644 --- a/cif/CIFint.h +++ b/cif/CIFint.h @@ -320,6 +320,7 @@ extern void CIFClearPlanes(); extern Plane *CIFGenLayer(); extern void CIFInitCells(); extern int cifHierCopyFunc(); +extern int cifHierCopyMaskHints(); extern void CIFLoadStyle(); /* Shared variables and structures: */ diff --git a/cif/CIFsee.c b/cif/CIFsee.c index e450e003..0b835444 100644 --- a/cif/CIFsee.c +++ b/cif/CIFsee.c @@ -162,6 +162,9 @@ CIFPaintLayer(rootDef, area, cifLayer, magicLayer, paintDef) scx.scx_trans = GeoIdentityTransform; (void) DBTreeSrTiles(&scx, &DBAllButSpaceAndDRCBits, 0, cifHierCopyFunc, (ClientData) CIFComponentDef); + DBTreeSrCells(&scx, 0, cifHierCopyMaskHints, + (ClientData)CIFComponentDef); + oldCount = DBWFeedbackCount; CIFGen(CIFComponentDef, rootDef, area, CIFPlanes, &depend, TRUE, TRUE, FALSE, @@ -278,6 +281,9 @@ CIFSeeLayer(rootDef, area, layer) scx.scx_trans = GeoIdentityTransform; (void) DBTreeSrTiles(&scx, &DBAllButSpaceAndDRCBits, 0, cifHierCopyFunc, (ClientData) CIFComponentDef); + DBTreeSrCells(&scx, 0, cifHierCopyMaskHints, + (ClientData)CIFComponentDef); + oldCount = DBWFeedbackCount; CIFGen(CIFComponentDef, rootDef, area, CIFPlanes, &depend, TRUE, TRUE, FALSE, (ClientData)NULL); @@ -443,6 +449,9 @@ CIFCoverageLayer(rootDef, area, layer) scx.scx_trans = GeoIdentityTransform; (void) DBTreeSrTiles(&scx, &DBAllButSpaceAndDRCBits, 0, cifHierCopyFunc, (ClientData) CIFComponentDef); + DBTreeSrCells(&scx, 0, cifHierCopyMaskHints, + (ClientData)CIFComponentDef); + CIFGen(CIFComponentDef, rootDef, area, CIFPlanes, &depend, TRUE, TRUE, FALSE, (ClientData)NULL); DBCellClearDef(CIFComponentDef); diff --git a/database/DBcellsrch.c b/database/DBcellsrch.c index 8673b32c..f41b7911 100644 --- a/database/DBcellsrch.c +++ b/database/DBcellsrch.c @@ -848,9 +848,8 @@ dbTreeCellSrFunc(scx, fp) if ((fp->tf_xmask == CU_DESCEND_NO_LOCK) && (use->cu_flags & CU_LOCKED)) return 2; - else if ((!DBDescendSubcell(use, fp->tf_xmask)) || - (fp->tf_xmask == CU_DESCEND_ALL)) - result = (*fp->tf_func)(scx, fp->tf_arg); + else if (!DBDescendSubcell(use, fp->tf_xmask)) + return (*fp->tf_func)(scx, fp->tf_arg); else { if ((use->cu_def->cd_flags & CDAVAILABLE) == 0) @@ -859,9 +858,15 @@ dbTreeCellSrFunc(scx, fp) if (!DBCellRead(use->cu_def, (char *) NULL, TRUE, dereference, NULL)) return 0; } - result = DBCellSrArea(scx, dbTreeCellSrFunc, (ClientData) fp); } - return result; + if (fp->tf_xmask == CU_DESCEND_ALL) + { + result = (*fp->tf_func)(scx, fp->tf_arg); + if (result != 0) return result; + } + + /* Run recursively on children in search area */ + return DBCellSrArea(scx, dbTreeCellSrFunc, (ClientData) fp); } /*