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);
|
||||
|
||||
propvalue = (char *)DBPropGet(origDef, propname, &found);
|
||||
propvalue = (char *)DBPropGet(cellDef, propname, &found);
|
||||
if (!found) break; /* No mask hints available */
|
||||
propptr = propvalue;
|
||||
while (*propptr)
|
||||
|
|
|
|||
129
cif/CIFhier.c
129
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,
|
||||
|
|
|
|||
|
|
@ -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: */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in New Issue