Extended the "mask-hints" operator to work correctly through a

hierarchy.
This commit is contained in:
Tim Edwards 2021-01-06 10:33:43 -05:00
parent d6eeb90f6b
commit d4c3939feb
6 changed files with 151 additions and 7 deletions

View File

@ -1 +1 @@
8.3.110
8.3.111

View File

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

View File

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

View File

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

View File

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

View File

@ -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);
}
/*