Extended the "mask-hints" operator to work correctly through a
hierarchy.
This commit is contained in:
parent
d6eeb90f6b
commit
d4c3939feb
|
|
@ -5175,7 +5175,7 @@ CIFGenLayer(op, area, cellDef, origDef, temps, hier, clientdata)
|
||||||
|
|
||||||
sprintf(propname, "MASKHINTS_%s", layername);
|
sprintf(propname, "MASKHINTS_%s", layername);
|
||||||
|
|
||||||
propvalue = (char *)DBPropGet(origDef, propname, &found);
|
propvalue = (char *)DBPropGet(cellDef, propname, &found);
|
||||||
if (!found) break; /* No mask hints available */
|
if (!found) break; /* No mask hints available */
|
||||||
propptr = propvalue;
|
propptr = propvalue;
|
||||||
while (*propptr)
|
while (*propptr)
|
||||||
|
|
|
||||||
129
cif/CIFhier.c
129
cif/CIFhier.c
|
|
@ -201,6 +201,123 @@ cifHierCleanup()
|
||||||
SigEnableInterrupts();
|
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,
|
(void) DBTreeSrTiles(&newscx, &CIFCurStyle->cs_yankLayers, 0,
|
||||||
cifHierCopyFunc, (ClientData) CIFComponentDef);
|
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
|
/* Set CIFErrorDef to NULL to ignore errors here... these will
|
||||||
* get reported anyway when the cell is CIF'ed non-hierarchically,
|
* get reported anyway when the cell is CIF'ed non-hierarchically,
|
||||||
* so there's no point in making a second report here.
|
* 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);
|
GEO_EXPAND(&interaction, CIFCurStyle->cs_radius, &scx.scx_area);
|
||||||
(void) DBTreeSrTiles(&scx, &CIFCurStyle->cs_yankLayers, 0,
|
(void) DBTreeSrTiles(&scx, &CIFCurStyle->cs_yankLayers, 0,
|
||||||
cifHierCopyFunc, (ClientData) CIFTotalDef);
|
cifHierCopyFunc, (ClientData) CIFTotalDef);
|
||||||
|
/* Flatten mask hints in the area of interest */
|
||||||
|
DBTreeSrCells(&scx, 0, cifHierCopyMaskHints,
|
||||||
|
(ClientData)CIFTotalDef);
|
||||||
|
|
||||||
CIFErrorDef = def;
|
CIFErrorDef = def;
|
||||||
CIFGen(CIFTotalDef, def, &interaction, CIFTotalPlanes,
|
CIFGen(CIFTotalDef, def, &interaction, CIFTotalPlanes,
|
||||||
&CIFCurStyle->cs_hierLayers, TRUE, TRUE, TRUE,
|
&CIFCurStyle->cs_hierLayers, TRUE, TRUE, TRUE,
|
||||||
|
|
@ -762,10 +887,14 @@ cifHierElementFunc(use, transform, x, y, checkArea)
|
||||||
scx.scx_use = use;
|
scx.scx_use = use;
|
||||||
(void) DBTreeSrTiles(&scx, &CIFCurStyle->cs_yankLayers, 0,
|
(void) DBTreeSrTiles(&scx, &CIFCurStyle->cs_yankLayers, 0,
|
||||||
cifHierCopyFunc, (ClientData) CIFTotalDef);
|
cifHierCopyFunc, (ClientData) CIFTotalDef);
|
||||||
|
DBTreeSrCells(&scx, 0, cifHierCopyMaskHints,
|
||||||
|
(ClientData)CIFTotalDef);
|
||||||
|
|
||||||
DBCellClearDef(CIFComponentDef);
|
DBCellClearDef(CIFComponentDef);
|
||||||
(void) DBTreeSrTiles(&scx, &CIFCurStyle->cs_yankLayers, 0,
|
(void) DBTreeSrTiles(&scx, &CIFCurStyle->cs_yankLayers, 0,
|
||||||
cifHierCopyFunc, (ClientData) CIFComponentDef);
|
cifHierCopyFunc, (ClientData) CIFComponentDef);
|
||||||
|
DBTreeSrCells(&scx, 0, cifHierCopyMaskHints,
|
||||||
|
(ClientData)CIFComponentDef);
|
||||||
|
|
||||||
CIFErrorDef = (CellDef *) NULL;
|
CIFErrorDef = (CellDef *) NULL;
|
||||||
CIFGen(CIFComponentDef, use->cu_def, checkArea, CIFComponentPlanes,
|
CIFGen(CIFComponentDef, use->cu_def, checkArea, CIFComponentPlanes,
|
||||||
|
|
|
||||||
|
|
@ -320,6 +320,7 @@ extern void CIFClearPlanes();
|
||||||
extern Plane *CIFGenLayer();
|
extern Plane *CIFGenLayer();
|
||||||
extern void CIFInitCells();
|
extern void CIFInitCells();
|
||||||
extern int cifHierCopyFunc();
|
extern int cifHierCopyFunc();
|
||||||
|
extern int cifHierCopyMaskHints();
|
||||||
extern void CIFLoadStyle();
|
extern void CIFLoadStyle();
|
||||||
|
|
||||||
/* Shared variables and structures: */
|
/* Shared variables and structures: */
|
||||||
|
|
|
||||||
|
|
@ -162,6 +162,9 @@ CIFPaintLayer(rootDef, area, cifLayer, magicLayer, paintDef)
|
||||||
scx.scx_trans = GeoIdentityTransform;
|
scx.scx_trans = GeoIdentityTransform;
|
||||||
(void) DBTreeSrTiles(&scx, &DBAllButSpaceAndDRCBits, 0,
|
(void) DBTreeSrTiles(&scx, &DBAllButSpaceAndDRCBits, 0,
|
||||||
cifHierCopyFunc, (ClientData) CIFComponentDef);
|
cifHierCopyFunc, (ClientData) CIFComponentDef);
|
||||||
|
DBTreeSrCells(&scx, 0, cifHierCopyMaskHints,
|
||||||
|
(ClientData)CIFComponentDef);
|
||||||
|
|
||||||
oldCount = DBWFeedbackCount;
|
oldCount = DBWFeedbackCount;
|
||||||
|
|
||||||
CIFGen(CIFComponentDef, rootDef, area, CIFPlanes, &depend, TRUE, TRUE, FALSE,
|
CIFGen(CIFComponentDef, rootDef, area, CIFPlanes, &depend, TRUE, TRUE, FALSE,
|
||||||
|
|
@ -278,6 +281,9 @@ CIFSeeLayer(rootDef, area, layer)
|
||||||
scx.scx_trans = GeoIdentityTransform;
|
scx.scx_trans = GeoIdentityTransform;
|
||||||
(void) DBTreeSrTiles(&scx, &DBAllButSpaceAndDRCBits, 0,
|
(void) DBTreeSrTiles(&scx, &DBAllButSpaceAndDRCBits, 0,
|
||||||
cifHierCopyFunc, (ClientData) CIFComponentDef);
|
cifHierCopyFunc, (ClientData) CIFComponentDef);
|
||||||
|
DBTreeSrCells(&scx, 0, cifHierCopyMaskHints,
|
||||||
|
(ClientData)CIFComponentDef);
|
||||||
|
|
||||||
oldCount = DBWFeedbackCount;
|
oldCount = DBWFeedbackCount;
|
||||||
CIFGen(CIFComponentDef, rootDef, area, CIFPlanes, &depend, TRUE, TRUE,
|
CIFGen(CIFComponentDef, rootDef, area, CIFPlanes, &depend, TRUE, TRUE,
|
||||||
FALSE, (ClientData)NULL);
|
FALSE, (ClientData)NULL);
|
||||||
|
|
@ -443,6 +449,9 @@ CIFCoverageLayer(rootDef, area, layer)
|
||||||
scx.scx_trans = GeoIdentityTransform;
|
scx.scx_trans = GeoIdentityTransform;
|
||||||
(void) DBTreeSrTiles(&scx, &DBAllButSpaceAndDRCBits, 0,
|
(void) DBTreeSrTiles(&scx, &DBAllButSpaceAndDRCBits, 0,
|
||||||
cifHierCopyFunc, (ClientData) CIFComponentDef);
|
cifHierCopyFunc, (ClientData) CIFComponentDef);
|
||||||
|
DBTreeSrCells(&scx, 0, cifHierCopyMaskHints,
|
||||||
|
(ClientData)CIFComponentDef);
|
||||||
|
|
||||||
CIFGen(CIFComponentDef, rootDef, area, CIFPlanes, &depend, TRUE, TRUE,
|
CIFGen(CIFComponentDef, rootDef, area, CIFPlanes, &depend, TRUE, TRUE,
|
||||||
FALSE, (ClientData)NULL);
|
FALSE, (ClientData)NULL);
|
||||||
DBCellClearDef(CIFComponentDef);
|
DBCellClearDef(CIFComponentDef);
|
||||||
|
|
|
||||||
|
|
@ -848,9 +848,8 @@ dbTreeCellSrFunc(scx, fp)
|
||||||
|
|
||||||
if ((fp->tf_xmask == CU_DESCEND_NO_LOCK) && (use->cu_flags & CU_LOCKED))
|
if ((fp->tf_xmask == CU_DESCEND_NO_LOCK) && (use->cu_flags & CU_LOCKED))
|
||||||
return 2;
|
return 2;
|
||||||
else if ((!DBDescendSubcell(use, fp->tf_xmask)) ||
|
else if (!DBDescendSubcell(use, fp->tf_xmask))
|
||||||
(fp->tf_xmask == CU_DESCEND_ALL))
|
return (*fp->tf_func)(scx, fp->tf_arg);
|
||||||
result = (*fp->tf_func)(scx, fp->tf_arg);
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((use->cu_def->cd_flags & CDAVAILABLE) == 0)
|
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))
|
if (!DBCellRead(use->cu_def, (char *) NULL, TRUE, dereference, NULL))
|
||||||
return 0;
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue