Reworked the method from the previous set of commits, which creates
yet another property type "plane". This allows mask hints to be handled like tile planes. That is, after all, what they represent. Although this change is transparent to the end user (apart from a slight performance improvement that is probably not noticeable), it allows for a number of useful future extensions, including the ability to handle non-Manhattan geometry in mask hints, and the ability to view and edit mask hints like any other layout.
This commit is contained in:
parent
725c8e9235
commit
7bdd9e1d4f
71
cif/CIFgen.c
71
cif/CIFgen.c
|
|
@ -5044,6 +5044,47 @@ cifInteractingRegions(
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* cifCopyPropPlaneFunc --
|
||||
*
|
||||
* Copy the contents of a plane saved as a plane-type property into the
|
||||
* current CIF plane. The property plane is in magic internal
|
||||
* coordinates, so each tile needs to be scaled and redrawn into the
|
||||
* current CIF plane.
|
||||
*
|
||||
* Results:
|
||||
* Zero to keep the search going
|
||||
*
|
||||
* Side effects:
|
||||
* Copies translated geometry into the target plane.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
cifCopyPropPlaneFunc(Tile *tile,
|
||||
TileType dinfo,
|
||||
Plane *curPlane)
|
||||
{
|
||||
Rect bbox;
|
||||
|
||||
TiToRect(tile, &bbox);
|
||||
|
||||
cifScale = (CIFCurStyle) ? CIFCurStyle->cs_scaleFactor : 1;
|
||||
|
||||
bbox.r_xbot *= cifScale;
|
||||
bbox.r_ybot *= cifScale;
|
||||
bbox.r_xtop *= cifScale;
|
||||
bbox.r_ytop *= cifScale;
|
||||
|
||||
cifScale = 1;
|
||||
DBNMPaintPlane(curPlane, CIF_SOLIDTYPE, &bbox,
|
||||
CIFPaintTable, (PaintUndoInfo *)NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
|
|
@ -5646,6 +5687,7 @@ CIFGenLayer(
|
|||
int n;
|
||||
char propname[512];
|
||||
char *layername = (char *)op->co_client;
|
||||
Tile *t;
|
||||
|
||||
snprintf(propname, 512, "MASKHINTS_%s", layername);
|
||||
|
||||
|
|
@ -5653,30 +5695,11 @@ CIFGenLayer(
|
|||
proprec = DBPropGet(cellDef, propname, &found);
|
||||
if (!found) break; /* No mask hints available */
|
||||
|
||||
if (proprec->prop_type == PROPERTY_TYPE_DIMENSION)
|
||||
{
|
||||
for (n = 0; n < proprec->prop_len; n += 4)
|
||||
{
|
||||
if ((n + 3) >= proprec->prop_len) break;
|
||||
|
||||
cifPlane = curPlane;
|
||||
cifScale = (CIFCurStyle) ? CIFCurStyle->cs_scaleFactor : 1;
|
||||
|
||||
bbox.r_xbot = proprec->prop_value.prop_integer[n];
|
||||
bbox.r_ybot = proprec->prop_value.prop_integer[n + 1];
|
||||
bbox.r_xtop = proprec->prop_value.prop_integer[n + 2];
|
||||
bbox.r_ytop = proprec->prop_value.prop_integer[n + 3];
|
||||
|
||||
bbox.r_xbot *= cifScale;
|
||||
bbox.r_ybot *= cifScale;
|
||||
bbox.r_xtop *= cifScale;
|
||||
bbox.r_ytop *= cifScale;
|
||||
|
||||
cifScale = 1;
|
||||
DBNMPaintPlane(curPlane, CIF_SOLIDTYPE, &bbox,
|
||||
CIFPaintTable, (PaintUndoInfo *)NULL);
|
||||
}
|
||||
}
|
||||
ASSERT (proprec->prop_type == PROPERTY_TYPE_PLANE, "CIFGenLayer");
|
||||
t = PlaneGetHint(proprec->prop_value.prop_plane);
|
||||
DBSrPaintArea(t, proprec->prop_value.prop_plane,
|
||||
&TiPlaneRect, &CIFSolidBits,
|
||||
cifCopyPropPlaneFunc, (ClientData)curPlane);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
|||
140
cif/CIFhier.c
140
cif/CIFhier.c
|
|
@ -209,16 +209,52 @@ typedef struct _maskHintsData
|
|||
{
|
||||
Transform *mh_trans;
|
||||
CellDef *mh_def;
|
||||
Plane *mh_plane;
|
||||
} MaskHintsData;
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* cifCopyMaskHintFunc --
|
||||
*
|
||||
* Callback function used by cifFlatMaskHints. Transforms a tile
|
||||
* from the original plane and paints it into the target plane,
|
||||
* both of which are properties.
|
||||
*
|
||||
* Results:
|
||||
* Zero to keep the search going.
|
||||
*
|
||||
* Side effects:
|
||||
* Paints geometry into the target plane.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
cifCopyMaskHintFunc(Tile *tile,
|
||||
TileType dinfo,
|
||||
ClientData cdata)
|
||||
{
|
||||
MaskHintsData *mhd = (MaskHintsData *)cdata;
|
||||
Rect r, newr;
|
||||
|
||||
TiToRect(tile, &r);
|
||||
|
||||
/* Transform tile area to coordinates of mhd->mh_plane and paint */
|
||||
GeoTransRect(mhd->mh_trans, &r, &newr);
|
||||
DBPaintPlane(mhd->mh_plane, &newr, CIFPaintTable, (PaintUndoInfo *)NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
* coordinate system of the flattened cell, and painting it into the
|
||||
* property plane of the flattened cell.
|
||||
*
|
||||
* Returns:
|
||||
* 0 to keep the search going.
|
||||
|
|
@ -240,6 +276,7 @@ cifFlatMaskHints(
|
|||
bool propfound;
|
||||
int i, lastlen, numvals;
|
||||
PropertyRecord *newproprec, *oldproprec;
|
||||
Plane *plane;
|
||||
|
||||
if (!strncmp(name, "MASKHINTS_", 10))
|
||||
{
|
||||
|
|
@ -247,53 +284,24 @@ cifFlatMaskHints(
|
|||
oldproprec = (PropertyRecord *)DBPropGet(mhd->mh_def, name, &propfound);
|
||||
if (propfound)
|
||||
{
|
||||
newproprec = (PropertyRecord *)mallocMagic(sizeof(PropertyRecord) +
|
||||
(oldproprec->prop_len + proprec->prop_len - 2) * sizeof(int));
|
||||
newproprec->prop_len = oldproprec->prop_len + proprec->prop_len;
|
||||
newproprec->prop_type = PROPERTY_TYPE_DIMENSION;
|
||||
ASSERT(oldproprec->prop_value.prop_type == PROPERTY_TYPE_PLANE,
|
||||
"cifFlatMaskHints");
|
||||
plane = oldproprec->prop_value.prop_plane;
|
||||
}
|
||||
else
|
||||
{
|
||||
newproprec = (PropertyRecord *)mallocMagic(sizeof(PropertyRecord) +
|
||||
(proprec->prop_len - 2) * sizeof(int));
|
||||
newproprec->prop_len = proprec->prop_len;
|
||||
newproprec->prop_type = PROPERTY_TYPE_DIMENSION;
|
||||
newproprec = (PropertyRecord *)mallocMagic(sizeof(PropertyRecord));
|
||||
newproprec->prop_len = 0; /* (unused) */
|
||||
newproprec->prop_type = PROPERTY_TYPE_PLANE;
|
||||
plane = DBNewPlane((ClientData)TT_SPACE);
|
||||
newproprec->prop_value.prop_plane = plane;
|
||||
DBPropPut(mhd->mh_def, name, newproprec);
|
||||
}
|
||||
|
||||
for (i = 0; i < proprec->prop_len; i += 4)
|
||||
{
|
||||
/* There should be a multiple of 4 values but avoid an array overrun
|
||||
* if not.
|
||||
*/
|
||||
if ((i + 3) >= proprec->prop_len)
|
||||
{
|
||||
TxError("MASKHINTS_%s: Expected 4 values, found only %d\n",
|
||||
name + 10, numvals);
|
||||
break;
|
||||
}
|
||||
|
||||
r.r_xbot = proprec->prop_value.prop_integer[i];
|
||||
r.r_ybot = proprec->prop_value.prop_integer[i + 1];
|
||||
r.r_xtop = proprec->prop_value.prop_integer[i + 2];
|
||||
r.r_ytop = proprec->prop_value.prop_integer[i + 3];
|
||||
|
||||
/* Transform rectangle to top level coordinates */
|
||||
GeoTransRect(mhd->mh_trans, &r, &newr);
|
||||
|
||||
newproprec->prop_value.prop_integer[i] = newr.r_xbot;
|
||||
newproprec->prop_value.prop_integer[i + 1] = newr.r_ybot;
|
||||
newproprec->prop_value.prop_integer[i + 2] = newr.r_xtop;
|
||||
newproprec->prop_value.prop_integer[i + 3] = newr.r_ytop;
|
||||
}
|
||||
|
||||
/* If there were existing entries, copy them into the new property */
|
||||
if (propfound)
|
||||
{
|
||||
for (i = 0; i < oldproprec->prop_len; i++)
|
||||
newproprec->prop_value.prop_integer[i + proprec->prop_len] =
|
||||
oldproprec->prop_value.prop_integer[i];
|
||||
}
|
||||
DBPropPut(mhd->mh_def, name, newproprec);
|
||||
mhd->mh_plane = plane;
|
||||
DBSrPaintArea((Tile *)NULL, proprec->prop_value.prop_plane,
|
||||
&TiPlaneRect, &CIFSolidBits,
|
||||
cifCopyMaskHintFunc, (ClientData)mhd);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -304,9 +312,10 @@ cifFlatMaskHints(
|
|||
* CIFCopyMaskHints --
|
||||
*
|
||||
* Callback function to copy mask hints from one cell into another.
|
||||
* (Occasionally called as a standalone function, not as a callback.)
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
* Return 0 to keep the search going.
|
||||
*
|
||||
* Side effects:
|
||||
* May modify properties in the target cell.
|
||||
|
|
@ -314,7 +323,7 @@ cifFlatMaskHints(
|
|||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
int
|
||||
CIFCopyMaskHints(
|
||||
SearchContext *scx,
|
||||
CellDef *targetDef)
|
||||
|
|
@ -324,38 +333,9 @@ CIFCopyMaskHints(
|
|||
CellDef *sourceDef = scx->scx_use->cu_def;
|
||||
mhd.mh_trans = &scx->scx_trans;
|
||||
mhd.mh_def = targetDef;
|
||||
mhd.mh_plane = (Plane *)NULL;
|
||||
|
||||
DBPropEnum(sourceDef, cifFlatMaskHints, &mhd);
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* 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(
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -480,7 +460,7 @@ cifHierCellFunc(
|
|||
|
||||
/* Flatten mask hints in the area of interest */
|
||||
CIFCopyMaskHints(scx, CIFComponentDef);
|
||||
DBTreeSrCells(&newscx, 0, cifHierCopyMaskHints,
|
||||
DBTreeSrCells(&newscx, 0, CIFCopyMaskHints,
|
||||
(ClientData)CIFComponentDef);
|
||||
|
||||
/* Set CIFErrorDef to NULL to ignore errors here... these will
|
||||
|
|
@ -808,7 +788,7 @@ CIFGenSubcells(
|
|||
cifHierCopyFunc, (ClientData) CIFTotalDef);
|
||||
/* Flatten mask hints in the area of interest */
|
||||
CIFCopyMaskHints(&scx, CIFTotalDef);
|
||||
DBTreeSrCells(&scx, 0, cifHierCopyMaskHints,
|
||||
DBTreeSrCells(&scx, 0, CIFCopyMaskHints,
|
||||
(ClientData)CIFTotalDef);
|
||||
|
||||
CIFErrorDef = def;
|
||||
|
|
@ -986,14 +966,14 @@ cifHierElementFunc(
|
|||
(void) DBTreeSrTiles(&scx, &CIFCurStyle->cs_yankLayers, 0,
|
||||
cifHierCopyFunc, (ClientData) CIFTotalDef);
|
||||
CIFCopyMaskHints(&scx, CIFTotalDef);
|
||||
DBTreeSrCells(&scx, 0, cifHierCopyMaskHints,
|
||||
DBTreeSrCells(&scx, 0, CIFCopyMaskHints,
|
||||
(ClientData)CIFTotalDef);
|
||||
|
||||
DBCellClearDef(CIFComponentDef);
|
||||
(void) DBTreeSrTiles(&scx, &CIFCurStyle->cs_yankLayers, 0,
|
||||
cifHierCopyFunc, (ClientData) CIFComponentDef);
|
||||
CIFCopyMaskHints(&scx, CIFComponentDef);
|
||||
DBTreeSrCells(&scx, 0, cifHierCopyMaskHints,
|
||||
DBTreeSrCells(&scx, 0, CIFCopyMaskHints,
|
||||
(ClientData)CIFComponentDef);
|
||||
|
||||
CIFErrorDef = (CellDef *) NULL;
|
||||
|
|
|
|||
|
|
@ -338,9 +338,8 @@ extern Plane *CIFGenLayer(CIFOp *op, const Rect *area, CellDef *cellDef, CellDef
|
|||
bool hier, ClientData clientdata);
|
||||
extern void CIFInitCells(void);
|
||||
extern int cifHierCopyFunc(Tile *tile, TileType dinfo, TreeContext *cxp);
|
||||
extern int cifHierCopyMaskHints(SearchContext *scx, ClientData clientData);
|
||||
extern void CIFLoadStyle(char *stylename);
|
||||
extern void CIFCopyMaskHints(SearchContext *scx, CellDef *targetDef);
|
||||
extern int CIFCopyMaskHints(SearchContext *scx, CellDef *targetDef);
|
||||
|
||||
/* C99 compat */
|
||||
extern void CIFCoverageLayer(CellDef *rootDef, Rect *area, char *layer, bool dolist);
|
||||
|
|
|
|||
104
cif/CIFrdcl.c
104
cif/CIFrdcl.c
|
|
@ -718,6 +718,9 @@ CIFPaintCurrent(
|
|||
&DBAllButSpaceBits, cifCheckPaintFunc,
|
||||
(ClientData)NULL) == 1))
|
||||
{
|
||||
/* (To do: remove the linked Rects and paint directly
|
||||
* into the plane in cifMaskHintFunc())
|
||||
*/
|
||||
DBSrPaintArea((Tile *) NULL, plane, &TiPlaneRect,
|
||||
&CIFSolidBits, cifMaskHintFunc,
|
||||
(ClientData)&lrec);
|
||||
|
|
@ -728,30 +731,29 @@ CIFPaintCurrent(
|
|||
char *propname, *layername;
|
||||
int proplen, i, savescale;
|
||||
bool origfound = FALSE;
|
||||
Plane *plane;
|
||||
|
||||
layername = (char *)op->co_client;
|
||||
propname = (char *)mallocMagic(11 + strlen(layername));
|
||||
sprintf(propname, "MASKHINTS_%s", layername);
|
||||
|
||||
/* Turn all linked Rects into a mask-hints property in the
|
||||
* target cell.
|
||||
/* If there is already a mask hint plane for this layer,
|
||||
* then add to it; otherwise, create a new plane.
|
||||
*/
|
||||
proplen = 0;
|
||||
for (lsrch = lrec; lsrch; lsrch = lsrch->r_next)
|
||||
proplen += 4;
|
||||
proprec = DBPropGet(cifReadCellDef, layername, &origfound);
|
||||
if (origfound)
|
||||
plane = proprec->prop_value.prop_plane;
|
||||
else
|
||||
{
|
||||
proprec = (PropertyRecord *)mallocMagic(
|
||||
sizeof(PropertyRecord));
|
||||
proprec->prop_type = PROPERTY_TYPE_PLANE;
|
||||
proprec->prop_len = 0; /* (unused) */
|
||||
plane = DBNewPlane((ClientData)TT_SPACE);
|
||||
proprec->prop_value.prop_plane = plane;
|
||||
DBPropPut(cifReadCellDef, propname, proprec);
|
||||
}
|
||||
|
||||
/* If there is already a mask hint for this layer, then
|
||||
* prepend to its data.
|
||||
*/
|
||||
proporig = DBPropGet(cifReadCellDef, layername, &origfound);
|
||||
if (origfound) proplen += proporig->prop_len;
|
||||
|
||||
proprec = (PropertyRecord *)mallocMagic(sizeof(PropertyRecord) *
|
||||
(proplen - 2) * sizeof(int));
|
||||
proprec->prop_type = PROPERTY_TYPE_DIMENSION;
|
||||
proprec->prop_len = proplen;
|
||||
|
||||
proplen = 0;
|
||||
while (lrec != NULL)
|
||||
{
|
||||
lrec->r_r.r_xtop =
|
||||
|
|
@ -787,29 +789,14 @@ CIFPaintCurrent(
|
|||
(savescale / cifCurReadStyle->crs_scaleFactor);
|
||||
}
|
||||
|
||||
proprec->prop_value.prop_integer[proplen] =
|
||||
lrec->r_r.r_xbot;
|
||||
proprec->prop_value.prop_integer[proplen + 1] =
|
||||
lrec->r_r.r_ybot;
|
||||
proprec->prop_value.prop_integer[proplen + 2] =
|
||||
lrec->r_r.r_xtop;
|
||||
proprec->prop_value.prop_integer[proplen + 3] =
|
||||
lrec->r_r.r_ytop;
|
||||
DBPaintPlane(plane, &lrec->r_r, CIFPaintTable,
|
||||
(PaintUndoInfo *)NULL);
|
||||
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
freeMagic1(&mm1, lrec);
|
||||
lrec = lrec->r_next;
|
||||
freeMagic1_end(&mm1);
|
||||
|
||||
proplen += 4;
|
||||
}
|
||||
|
||||
if (origfound)
|
||||
for (i = 0; i < proporig->prop_len; i++)
|
||||
proprec->prop_value.prop_integer[proplen++] =
|
||||
proporig->prop_value.prop_integer[i];
|
||||
|
||||
DBPropPut(cifReadCellDef, propname, proprec);
|
||||
freeMagic(propname);
|
||||
}
|
||||
}
|
||||
|
|
@ -926,7 +913,9 @@ CIFPaintCurrent(
|
|||
(CellDef *)NULL, CIFPlanes, FALSE, (ClientData)NULL);
|
||||
|
||||
/* Scan the resulting plane and generate linked Rect structures for
|
||||
* each shape found.
|
||||
* each shape found. (To do: Remove the linked Rects and paint
|
||||
* directly into the plane in cifMaskHintFunc(), which is more
|
||||
* efficient but not hugely so.)
|
||||
*/
|
||||
DBSrPaintArea((Tile *)NULL, presult, &TiPlaneRect, &CIFSolidBits,
|
||||
cifMaskHintFunc, (ClientData)&lrec);
|
||||
|
|
@ -934,44 +923,45 @@ CIFPaintCurrent(
|
|||
if (lrec != NULL)
|
||||
{
|
||||
PropertyRecord *proprec;
|
||||
bool propfound;
|
||||
char *propname;
|
||||
int proplen;
|
||||
Plane *plane;
|
||||
|
||||
propname = (char *)mallocMagic(11 + strlen(cifReadLayers[i]));
|
||||
sprintf(propname, "MASKHINTS_%s", cifReadLayers[i]);
|
||||
|
||||
/* Turn all linked Rects into a mask-hints property in the
|
||||
* target cell.
|
||||
/* Paint all linked Rects into a mask-hints property plane
|
||||
* in the target cell.
|
||||
*/
|
||||
proplen = 0;
|
||||
for (lsrch = lrec; lsrch; lsrch = lsrch->r_next)
|
||||
proplen += 4;
|
||||
|
||||
proprec = (PropertyRecord *)mallocMagic(sizeof(PropertyRecord) *
|
||||
(proplen - 2) * sizeof(int));
|
||||
proprec->prop_type = PROPERTY_TYPE_DIMENSION;
|
||||
proprec->prop_len = proplen;
|
||||
proprec = DBPropGet(cifReadCellDef, propname, &propfound);
|
||||
if (!propfound)
|
||||
{
|
||||
proprec = (PropertyRecord *)mallocMagic(sizeof(PropertyRecord));
|
||||
proprec->prop_type = PROPERTY_TYPE_PLANE;
|
||||
proprec->prop_len = 0; /* (unused) */
|
||||
plane = DBNewPlane((ClientData)TT_SPACE);
|
||||
proprec->prop_value.prop_plane = plane;
|
||||
DBPropPut(cifReadCellDef, propname, proprec);
|
||||
}
|
||||
else
|
||||
plane = proprec->prop_value.prop_plane;
|
||||
|
||||
proplen = 0;
|
||||
while (lrec != NULL)
|
||||
{
|
||||
proprec->prop_value.prop_integer[proplen] =
|
||||
lrec->r_r.r_xbot / CIFCurStyle->cs_scaleFactor;
|
||||
proprec->prop_value.prop_integer[proplen + 1] =
|
||||
lrec->r_r.r_ybot / CIFCurStyle->cs_scaleFactor;
|
||||
proprec->prop_value.prop_integer[proplen + 2] =
|
||||
lrec->r_r.r_xtop / CIFCurStyle->cs_scaleFactor;
|
||||
proprec->prop_value.prop_integer[proplen + 3] =
|
||||
lrec->r_r.r_ytop / CIFCurStyle->cs_scaleFactor;
|
||||
lrec->r_r.r_xbot /= CIFCurStyle->cs_scaleFactor;
|
||||
lrec->r_r.r_ybot /= CIFCurStyle->cs_scaleFactor;
|
||||
lrec->r_r.r_xtop /= CIFCurStyle->cs_scaleFactor;
|
||||
lrec->r_r.r_ytop /= CIFCurStyle->cs_scaleFactor;
|
||||
|
||||
DBPaintPlane(plane, &lrec->r_r, CIFPaintTable,
|
||||
(PaintUndoInfo *)NULL);
|
||||
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
freeMagic1(&mm1, lrec);
|
||||
lrec = lrec->r_next;
|
||||
freeMagic1_end(&mm1);
|
||||
|
||||
proplen += 4;
|
||||
}
|
||||
DBPropPut(cifReadCellDef, propname, proprec);
|
||||
freeMagic(propname);
|
||||
}
|
||||
|
||||
|
|
|
|||
12
cif/CIFsee.c
12
cif/CIFsee.c
|
|
@ -166,9 +166,9 @@ CIFPaintLayer(
|
|||
scx.scx_use = CIFDummyUse;
|
||||
scx.scx_trans = GeoIdentityTransform;
|
||||
(void) DBTreeSrTiles(&scx, &DBAllButSpaceAndDRCBits, 0,
|
||||
cifHierCopyFunc, (ClientData) CIFComponentDef);
|
||||
cifHierCopyFunc, (ClientData) CIFComponentDef);
|
||||
CIFCopyMaskHints(&scx, CIFComponentDef);
|
||||
DBTreeSrCells(&scx, 0, cifHierCopyMaskHints,
|
||||
DBTreeSrCells(&scx, 0, CIFCopyMaskHints,
|
||||
(ClientData)CIFComponentDef);
|
||||
|
||||
oldCount = DBWFeedbackCount;
|
||||
|
|
@ -287,9 +287,9 @@ CIFSeeLayer(
|
|||
scx.scx_use = CIFDummyUse;
|
||||
scx.scx_trans = GeoIdentityTransform;
|
||||
(void) DBTreeSrTiles(&scx, &DBAllButSpaceAndDRCBits, 0,
|
||||
cifHierCopyFunc, (ClientData) CIFComponentDef);
|
||||
cifHierCopyFunc, (ClientData) CIFComponentDef);
|
||||
CIFCopyMaskHints(&scx, CIFComponentDef);
|
||||
DBTreeSrCells(&scx, 0, cifHierCopyMaskHints,
|
||||
DBTreeSrCells(&scx, 0, CIFCopyMaskHints,
|
||||
(ClientData)CIFComponentDef);
|
||||
|
||||
oldCount = DBWFeedbackCount;
|
||||
|
|
@ -459,9 +459,9 @@ CIFCoverageLayer(
|
|||
scx.scx_use = CIFDummyUse;
|
||||
scx.scx_trans = GeoIdentityTransform;
|
||||
(void) DBTreeSrTiles(&scx, &DBAllButSpaceAndDRCBits, 0,
|
||||
cifHierCopyFunc, (ClientData) CIFComponentDef);
|
||||
cifHierCopyFunc, (ClientData) CIFComponentDef);
|
||||
CIFCopyMaskHints(&scx, CIFComponentDef);
|
||||
DBTreeSrCells(&scx, 0, cifHierCopyMaskHints,
|
||||
DBTreeSrCells(&scx, 0, CIFCopyMaskHints,
|
||||
(ClientData)CIFComponentDef);
|
||||
|
||||
CIFGen(CIFComponentDef, rootDef, area, CIFPlanes, &depend, TRUE, TRUE,
|
||||
|
|
|
|||
187
commands/CmdLQ.c
187
commands/CmdLQ.c
|
|
@ -45,9 +45,8 @@ static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magi
|
|||
#include "utils/undo.h"
|
||||
#include "select/select.h"
|
||||
#include "netmenu/netmenu.h"
|
||||
|
||||
/* C99 compat */
|
||||
#include "cif/cif.h"
|
||||
#include "cif/CIFint.h"
|
||||
|
||||
/* Forward declarations */
|
||||
|
||||
|
|
@ -2335,13 +2334,15 @@ CmdDoProperty(
|
|||
Tcl_Obj *tobj;
|
||||
#endif
|
||||
|
||||
int printPropertiesFunc(); /* Forward declaration */
|
||||
/* Forward declarations */
|
||||
int printPropertiesFunc();
|
||||
int printPlanePropFunc();
|
||||
|
||||
/* These should match the property codes in database.h.in, except
|
||||
* for "compat" which must come at the end.
|
||||
*/
|
||||
static const char * const cmdPropertyType[] = {
|
||||
"string", "integer", "dimension", "double", "compat", NULL
|
||||
"string", "integer", "dimension", "double", "plane", "compat", NULL
|
||||
};
|
||||
|
||||
/* If a property type is given, parse it and then strip it from
|
||||
|
|
@ -2393,7 +2394,7 @@ CmdDoProperty(
|
|||
return;
|
||||
}
|
||||
|
||||
/* print the value of the indicated property */
|
||||
/* Print the value of the indicated property */
|
||||
proprec = (PropertyRecord *)DBPropGet(def, cmd->tx_argv[argstart], &propfound);
|
||||
if (propfound)
|
||||
{
|
||||
|
|
@ -2434,6 +2435,14 @@ CmdDoProperty(
|
|||
Tcl_SetObjResult(magicinterp, tobj);
|
||||
}
|
||||
break;
|
||||
case PROPERTY_TYPE_PLANE:
|
||||
tobj = Tcl_NewListObj(0, NULL);
|
||||
DBSrPaintArea(PlaneGetHint(proprec->prop_value.prop_plane),
|
||||
proprec->prop_value.prop_plane,
|
||||
&TiPlaneRect, &CIFSolidBits, printPlanePropFunc,
|
||||
(ClientData)tobj);
|
||||
Tcl_SetObjResult(magicinterp, tobj);
|
||||
break;
|
||||
case PROPERTY_TYPE_DOUBLE:
|
||||
if (proprec->prop_len == 1)
|
||||
Tcl_SetObjResult(magicinterp,
|
||||
|
|
@ -2469,6 +2478,13 @@ CmdDoProperty(
|
|||
|
||||
TxPrintf("\n");
|
||||
break;
|
||||
case PROPERTY_TYPE_PLANE:
|
||||
DBSrPaintArea(PlaneGetHint(proprec->prop_value.prop_plane),
|
||||
proprec->prop_value.prop_plane,
|
||||
&TiPlaneRect, &CIFSolidBits, printPlanePropFunc,
|
||||
(ClientData)NULL);
|
||||
TxPrintf("\n");
|
||||
break;
|
||||
case PROPERTY_TYPE_DOUBLE:
|
||||
for (i = 0; i < proprec->prop_len; i++)
|
||||
TxPrintf( "%"DLONG_PREFIX"d",
|
||||
|
|
@ -2514,7 +2530,7 @@ CmdDoProperty(
|
|||
* keyword functions work correctly.
|
||||
*
|
||||
* GDS_START, GDS_END: PROPERTY_TYPE_DOUBLE
|
||||
* MASKHINTS_*: PROPERTY_TYPE_DIMENSION
|
||||
* MASKHINTS_*: PROPERTY_TYPE_PLANE
|
||||
* FIXED_BBOX: PROPERTY_TYPE_DIMENSION
|
||||
*/
|
||||
if (!strcmp(cmd->tx_argv[argstart], "GDS_START"))
|
||||
|
|
@ -2528,7 +2544,7 @@ CmdDoProperty(
|
|||
else if (!strcmp(cmd->tx_argv[argstart], "OBS_BBOX"))
|
||||
proptype = PROPERTY_TYPE_DIMENSION;
|
||||
else if (!strncmp(cmd->tx_argv[argstart], "MASKHINTS_", 10))
|
||||
proptype = PROPERTY_TYPE_DIMENSION;
|
||||
proptype = PROPERTY_TYPE_PLANE;
|
||||
|
||||
if (strlen(cmd->tx_argv[argstart + 1]) == 0)
|
||||
DBPropPut(def, cmd->tx_argv[argstart], NULL);
|
||||
|
|
@ -2543,8 +2559,11 @@ CmdDoProperty(
|
|||
proprec->prop_len = proplen;
|
||||
strcpy(proprec->prop_value.prop_string, cmd->tx_argv[argstart + 1]);
|
||||
}
|
||||
else /* PROPERTY_TYPE_INTEGER or PROPERTY_TYPE_DIMENSION */
|
||||
else /* All non-string properties */
|
||||
{
|
||||
Plane *plane;
|
||||
Rect r;
|
||||
|
||||
/* Two choices: If locargc == 3 then all values are in one
|
||||
* argument. If locargc > 3, then parse each argument as a
|
||||
* separate value.
|
||||
|
|
@ -2555,6 +2574,12 @@ CmdDoProperty(
|
|||
if (proptype == PROPERTY_TYPE_DOUBLE)
|
||||
proprec = (PropertyRecord *)mallocMagic(sizeof(PropertyRecord) +
|
||||
(proplen - 1)*sizeof(dlong));
|
||||
else if (proptype == PROPERTY_TYPE_PLANE)
|
||||
{
|
||||
proprec = (PropertyRecord *)mallocMagic(sizeof(PropertyRecord));
|
||||
plane = DBNewPlane((ClientData)TT_SPACE);
|
||||
proprec->prop_value.prop_plane = plane;
|
||||
}
|
||||
else
|
||||
proprec = (PropertyRecord *)mallocMagic(sizeof(PropertyRecord) +
|
||||
(proplen - 2)*sizeof(int));
|
||||
|
|
@ -2587,6 +2612,28 @@ CmdDoProperty(
|
|||
proprec->prop_value.prop_double[i - 1] = 0;
|
||||
}
|
||||
}
|
||||
else if (proptype == PROPERTY_TYPE_PLANE)
|
||||
{
|
||||
propvalue = cmdParseCoord(w, cmd->tx_argv[argstart + i],
|
||||
FALSE, ((i % 2) == 0) ? FALSE : TRUE);
|
||||
switch ((i - 1) % 4)
|
||||
{
|
||||
case 0:
|
||||
r.r_xbot = propvalue;
|
||||
break;
|
||||
case 1:
|
||||
r.r_ybot = propvalue;
|
||||
break;
|
||||
case 2:
|
||||
r.r_xtop = propvalue;
|
||||
break;
|
||||
case 3:
|
||||
r.r_ytop = propvalue;
|
||||
DBPaintPlane(plane, &r, CIFPaintTable,
|
||||
(PaintUndoInfo *)NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else /* PROPERTY_TYPE_DIMENSION */
|
||||
{
|
||||
propvalue = cmdParseCoord(w, cmd->tx_argv[argstart + i],
|
||||
|
|
@ -2601,22 +2648,32 @@ CmdDoProperty(
|
|||
* the valid number of arguments, then again to parse the
|
||||
* values, once the property record has been allocated
|
||||
*/
|
||||
value = cmd->tx_argv[argstart + 1];
|
||||
for (proplen = 0; *value != '\0'; )
|
||||
if (proptype == PROPERTY_TYPE_PLANE)
|
||||
{
|
||||
if (isspace(*value) && (*value != '\0')) value++;
|
||||
if (!isspace(*value))
|
||||
{
|
||||
proplen++;
|
||||
while (!isspace(*value) && (*value != '\0')) value++;
|
||||
}
|
||||
proprec = (PropertyRecord *)mallocMagic(sizeof(PropertyRecord));
|
||||
plane = DBNewPlane((ClientData)TT_SPACE);
|
||||
proprec->prop_value.prop_plane = plane;
|
||||
}
|
||||
if (proplen > 0)
|
||||
else
|
||||
{
|
||||
proprec = (PropertyRecord *)mallocMagic(sizeof(PropertyRecord) +
|
||||
(proplen - 2)*sizeof(int));
|
||||
proprec->prop_type = proptype;
|
||||
proprec->prop_len = proplen;
|
||||
value = cmd->tx_argv[argstart + 1];
|
||||
for (proplen = 0; *value != '\0'; )
|
||||
{
|
||||
if (isspace(*value) && (*value != '\0')) value++;
|
||||
if (!isspace(*value))
|
||||
{
|
||||
proplen++;
|
||||
while (!isspace(*value) && (*value != '\0')) value++;
|
||||
}
|
||||
}
|
||||
if (proplen > 0)
|
||||
{
|
||||
proprec = (PropertyRecord *)mallocMagic(
|
||||
sizeof(PropertyRecord) +
|
||||
(proplen - 2) * sizeof(int));
|
||||
proprec->prop_type = proptype;
|
||||
proprec->prop_len = proplen;
|
||||
}
|
||||
}
|
||||
/* Second pass */
|
||||
value = cmd->tx_argv[argstart + 1];
|
||||
|
|
@ -2657,6 +2714,28 @@ CmdDoProperty(
|
|||
}
|
||||
proprec->prop_value.prop_double[proplen] = dvalue;
|
||||
}
|
||||
else if (proptype == PROPERTY_TYPE_PLANE)
|
||||
{
|
||||
propvalue = cmdParseCoord(w, value, FALSE,
|
||||
((proplen % 2) == 0) ? TRUE : FALSE);
|
||||
switch (proplen % 4)
|
||||
{
|
||||
case 0:
|
||||
r.r_xbot = propvalue;
|
||||
break;
|
||||
case 1:
|
||||
r.r_ybot = propvalue;
|
||||
break;
|
||||
case 2:
|
||||
r.r_xtop = propvalue;
|
||||
break;
|
||||
case 3:
|
||||
r.r_ytop = propvalue;
|
||||
DBPaintPlane(plane, &r, CIFPaintTable,
|
||||
(PaintUndoInfo *)NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else /* PROPERTY_TYPE_DIMENSION */
|
||||
{
|
||||
propvalue = cmdParseCoord(w, value, FALSE,
|
||||
|
|
@ -2727,6 +2806,59 @@ CmdProperty(
|
|||
CmdDoProperty(def, w, cmd, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
* Callback function for printing values from a Plane property
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifdef MAGIC_WRAPPER
|
||||
int
|
||||
printPlanePropFunc(
|
||||
Tile *tile,
|
||||
TileType dinfo,
|
||||
Tcl_Obj *lobj)
|
||||
{
|
||||
Rect r;
|
||||
MagWindow *w;
|
||||
|
||||
TiToRect(tile, &r);
|
||||
windCheckOnlyWindow(&w, DBWclientID);
|
||||
|
||||
Tcl_ListObjAppendElement(magicinterp, lobj,
|
||||
Tcl_NewStringObj(DBWPrintValue(r.r_xbot, w, TRUE), -1));
|
||||
Tcl_ListObjAppendElement(magicinterp, lobj,
|
||||
Tcl_NewStringObj(DBWPrintValue(r.r_ybot, w, FALSE), -1));
|
||||
Tcl_ListObjAppendElement(magicinterp, lobj,
|
||||
Tcl_NewStringObj(DBWPrintValue(r.r_xtop, w, TRUE), -1));
|
||||
Tcl_ListObjAppendElement(magicinterp, lobj,
|
||||
Tcl_NewStringObj(DBWPrintValue(r.r_ytop, w, FALSE), -1));
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int
|
||||
printPlanePropFunc(
|
||||
Tile *tile,
|
||||
TileType dinfo,
|
||||
ClientData cdata /* (unused) */
|
||||
{
|
||||
Rect r;
|
||||
MagWindow *w;
|
||||
|
||||
TiToRect(tile, &r)
|
||||
windCheckOnlyWindow(&w, DBWclientID);
|
||||
|
||||
TxPrintf("%s ", DBWPrintValue(r.r_xbot, w, TRUE);
|
||||
TxPrintf("%s ", DBWPrintValue(r.r_ybot, w, FALSE);
|
||||
TxPrintf("%s ", DBWPrintValue(r.r_xtop, w, TRUE);
|
||||
TxPrintf("%s ", DBWPrintValue(r.r_ytop, w, FALSE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
* Callback function for printing a single property key:value pair
|
||||
|
|
@ -2766,6 +2898,12 @@ printPropertiesFunc(
|
|||
DBWPrintValue(proprec->prop_value.prop_integer[i],
|
||||
w, ((i % 2) == 0) ? TRUE : FALSE), -1));
|
||||
break;
|
||||
case PROPERTY_TYPE_PLANE:
|
||||
DBSrPaintArea(PlaneGetHint(proprec->prop_value.prop_plane),
|
||||
proprec->prop_value.prop_plane,
|
||||
&TiPlaneRect, &CIFSolidBits, printPlanePropFunc,
|
||||
(ClientData)lobj);
|
||||
break;
|
||||
case PROPERTY_TYPE_DOUBLE:
|
||||
for (i = 0; i < proprec->prop_len; i++)
|
||||
Tcl_ListObjAppendElement(magicinterp, lobj,
|
||||
|
|
@ -2794,6 +2932,13 @@ printPropertiesFunc(
|
|||
w, ((i % 2) == 0) ? TRUE : FALSE);
|
||||
TxPrintf("\n");
|
||||
break;
|
||||
case PROPERTY_TYPE_PLANE:
|
||||
TxPrintf("%s = ", name);
|
||||
DBSrPaintArea((Tile *)NULL, proprec->prop_value.prop_plane,
|
||||
&TiPlaneRect, &CIFSolidBits, printPlanePropFunc,
|
||||
(ClientData)NULL);
|
||||
TxPrintf("\n");
|
||||
break;
|
||||
case PROPERTY_TYPE_DOUBLE:
|
||||
TxPrintf("%s = ", name);
|
||||
for (i = 0; i < proprec->prop_len; i++)
|
||||
|
|
|
|||
|
|
@ -37,9 +37,8 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
#include "windows/windows.h"
|
||||
#include "dbwind/dbwind.h"
|
||||
#include "commands/commands.h"
|
||||
|
||||
/* C99 compat */
|
||||
#include "graphics/graphics.h"
|
||||
#include "cif/CIFint.h"
|
||||
|
||||
/*
|
||||
* The following variable points to the tables currently used for
|
||||
|
|
@ -357,10 +356,43 @@ DBCellCheckCopyAllPaint(scx, mask, xMask, targetUse, func)
|
|||
struct propUseDefStruct {
|
||||
CellDef *puds_source;
|
||||
CellDef *puds_dest;
|
||||
Plane *puds_plane; /* Mask hint plane in dest */
|
||||
Transform *puds_trans; /* Transform from source use to dest */
|
||||
Rect *puds_area; /* Clip area in source coordinates */
|
||||
};
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* dbCopyMaskHintPlaneFunc --
|
||||
*
|
||||
* Translate tiles from a child mask-hint property plane into the
|
||||
* coordinate system of the parent, and paint the mask-hint area
|
||||
* into the mask-hint property plane of the parent.
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
dbCopyMaskHintPlaneFunc(Tile *tile,
|
||||
TileType dinfo,
|
||||
struct propUseDefStruct *puds)
|
||||
{
|
||||
Transform *trans = puds->puds_trans;
|
||||
Rect *clip = puds->puds_area;
|
||||
Rect r, rnew;
|
||||
Plane *plane = puds->puds_plane;
|
||||
|
||||
TiToRect(tile, &r);
|
||||
GeoClip(&r, clip);
|
||||
if (!GEO_RECTNULL(&r))
|
||||
{
|
||||
GeoTransRect(trans, &r, &rnew);
|
||||
DBPaintPlane(plane, &rnew, CIFPaintTable, (PaintUndoInfo *)NULL);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
|
|
@ -399,56 +431,34 @@ dbCopyMaskHintsFunc(key, proprec, puds)
|
|||
{
|
||||
char *vptr, *lastval;
|
||||
int lastlen;
|
||||
Plane *plane;
|
||||
|
||||
/* Append to existing mask hint (if any) */
|
||||
ASSERT(proprec->prop_type == PROPERTY_TYPE_PLANE, "dbCopyMaskHintsFunc");
|
||||
|
||||
/* Get the existing mask hint plane in the parent cell, and
|
||||
* create it if it does not already exist.
|
||||
*/
|
||||
parentproprec = (PropertyRecord *)DBPropGet(dest, key, &propfound);
|
||||
|
||||
if (propfound)
|
||||
{
|
||||
newproprec = (PropertyRecord *)mallocMagic(sizeof(PropertyRecord) +
|
||||
(proprec->prop_len + parentproprec->prop_len - 2) *
|
||||
sizeof(int));
|
||||
newproprec->prop_type = PROPERTY_TYPE_DIMENSION;
|
||||
newproprec->prop_len = parentproprec->prop_len;
|
||||
}
|
||||
plane = parentproprec->prop_value.prop_plane;
|
||||
else
|
||||
{
|
||||
newproprec = (PropertyRecord *)mallocMagic(sizeof(PropertyRecord) +
|
||||
(proprec->prop_len - 2) * sizeof(int));
|
||||
newproprec->prop_type = PROPERTY_TYPE_DIMENSION;
|
||||
newproprec = (PropertyRecord *)mallocMagic(sizeof(PropertyRecord));
|
||||
newproprec->prop_type = PROPERTY_TYPE_PLANE;
|
||||
newproprec->prop_len = 0;
|
||||
plane = DBNewPlane((ClientData)TT_SPACE);
|
||||
newproprec->prop_value.prop_plane = plane;
|
||||
DBPropPut(dest, key, newproprec);
|
||||
}
|
||||
puds->puds_plane = plane;
|
||||
|
||||
for (i = 0, j = 0; i < proprec->prop_len; i += 4)
|
||||
{
|
||||
r.r_xbot = proprec->prop_value.prop_integer[i];
|
||||
r.r_ybot = proprec->prop_value.prop_integer[i + 1];
|
||||
r.r_xtop = proprec->prop_value.prop_integer[i + 2];
|
||||
r.r_ytop = proprec->prop_value.prop_integer[i + 3];
|
||||
GeoClip(&r, clip);
|
||||
if (!GEO_RECTNULL(&r))
|
||||
{
|
||||
GeoTransRect(trans, &r, &rnew);
|
||||
newproprec->prop_value.prop_integer[j] = rnew.r_xbot;
|
||||
newproprec->prop_value.prop_integer[j + 1] = rnew.r_ybot;
|
||||
newproprec->prop_value.prop_integer[j + 2] = rnew.r_xtop;
|
||||
newproprec->prop_value.prop_integer[j + 3] = rnew.r_ytop;
|
||||
newproprec->prop_len += 4;
|
||||
j += 4;
|
||||
}
|
||||
}
|
||||
|
||||
if (propfound)
|
||||
{
|
||||
/* Append the original values to the end of the list */
|
||||
for (i = 0; i < parentproprec->prop_len; i++)
|
||||
newproprec->prop_value.prop_integer[i + j] =
|
||||
parentproprec->prop_value.prop_integer[i];
|
||||
}
|
||||
|
||||
DBPropPut(dest, key, newproprec);
|
||||
/* Copy the properties from child to parent */
|
||||
DBSrPaintArea(PlaneGetHint(proprec->prop_value.prop_plane),
|
||||
proprec->prop_value.prop_plane,
|
||||
clip, &CIFSolidBits, dbCopyMaskHintPlaneFunc,
|
||||
(ClientData)puds);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1713,7 +1713,7 @@ dbTileMoveFunc(tile, dinfo, mvvals)
|
|||
if (IsSplit(tile))
|
||||
type = (dinfo & TT_SIDE) ? SplitRightType(tile) : SplitLeftType(tile);
|
||||
DBNMPaintPlane(mvvals->ptarget, exact, &targetRect,
|
||||
DBStdPaintTbl(type, mvvals->pnum),
|
||||
(mvvals->pnum < 0) ? CIFPaintTable : DBStdPaintTbl(type, mvvals->pnum),
|
||||
(PaintUndoInfo *)NULL);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1814,7 +1814,22 @@ int dbScaleProp(name, proprec, cps)
|
|||
int i, scalen, scaled;
|
||||
Point p;
|
||||
|
||||
/* Only "dimension" type properties get scaled */
|
||||
/* Only "dimension" and "plane" type properties get scaled */
|
||||
|
||||
if (proprec->prop_type == PROPERTY_TYPE_PLANE)
|
||||
{
|
||||
Plane *newplane;
|
||||
newplane = DBNewPlane((ClientData)TT_SPACE);
|
||||
DBClearPaintPlane(newplane);
|
||||
/* Plane index is unused; arbitrarily substitute -1 */
|
||||
dbScalePlane(proprec->prop_value.prop_plane, newplane, -1,
|
||||
scalen, scaled, TRUE);
|
||||
DBFreePaintPlane(proprec->prop_value.prop_plane);
|
||||
TiFreePlane(proprec->prop_value.prop_plane);
|
||||
proprec->prop_value.prop_plane = newplane;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (proprec->prop_type != PROPERTY_TYPE_DIMENSION) return 0;
|
||||
|
||||
/* Scale numerator held in point X value, */
|
||||
|
|
@ -1857,7 +1872,22 @@ int dbMoveProp(name, proprec, cps)
|
|||
char *newvalue;
|
||||
Point p;
|
||||
|
||||
/* Only "dimension" type properties get scaled */
|
||||
/* Only "dimension" and "plane" type properties get scaled */
|
||||
|
||||
if (proprec->prop_type == PROPERTY_TYPE_PLANE)
|
||||
{
|
||||
Plane *newplane;
|
||||
|
||||
newplane = DBNewPlane((ClientData) TT_SPACE);
|
||||
DBClearPaintPlane(newplane);
|
||||
/* Use plane index -1 to indicate use of CIFPaintTable */
|
||||
dbMovePlane(proprec->prop_value.prop_plane, newplane, -1, origx, origy);
|
||||
DBFreePaintPlane(proprec->prop_value.prop_plane);
|
||||
TiFreePlane(proprec->prop_value.prop_plane);
|
||||
proprec->prop_value.prop_plane = newplane;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (proprec->prop_type != PROPERTY_TYPE_DIMENSION) return 0;
|
||||
|
||||
origx = cps->cps_point.p_x;
|
||||
|
|
|
|||
337
database/DBio.c
337
database/DBio.c
|
|
@ -73,10 +73,9 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
#include "utils/undo.h"
|
||||
#include "utils/malloc.h"
|
||||
#include "utils/signals.h"
|
||||
|
||||
/* C99 compat */
|
||||
#include "dbwind/dbwtech.h"
|
||||
#include "cif/cif.h"
|
||||
#include "cif/CIFint.h"
|
||||
#include "lef/lef.h"
|
||||
#include "commands/commands.h"
|
||||
#include "graphics/graphics.h"
|
||||
|
|
@ -2492,10 +2491,24 @@ dbReadProperties(cellDef, line, len, f, scalen, scaled)
|
|||
* (2) "integer" (a fixed integer or list of integers)
|
||||
* (3) "dimension" (an integer that scales with internal units)
|
||||
* (4) "double" (a fixed double-wide integer or list thereof)
|
||||
* (5) "plane" (a tile plane structure)
|
||||
*/
|
||||
|
||||
switch (option)
|
||||
{
|
||||
case PROPERTY_TYPE_PLANE:
|
||||
/* Treat this like "string" but make sure property is a
|
||||
* mask hint. There is currently no method to specify
|
||||
* a plane property other than to write out the bounding
|
||||
* box coordinates of all the tiles in a list.
|
||||
*/
|
||||
if (strncmp(propertyname, "MASKHINTS_", 10))
|
||||
{
|
||||
TxError("Plane type specified for property \"%s\" but "
|
||||
"property is not a mask hint!\n", propertyname);
|
||||
break;
|
||||
}
|
||||
/* Else drop through */
|
||||
case PROPERTY_TYPE_STRING:
|
||||
/* Go ahead and process the vendor GDS property */
|
||||
if (!strcmp(propertyname, "GDS_FILE"))
|
||||
|
|
@ -2565,68 +2578,54 @@ dbReadProperties(cellDef, line, len, f, scalen, scaled)
|
|||
else if (!strncmp(propertyname, "MASKHINTS_", 10))
|
||||
{
|
||||
pptr = pvalueptr;
|
||||
proprec = (PropertyRecord *)mallocMagic(sizeof(PropertyRecord));
|
||||
proprec->prop_type = PROPERTY_TYPE_PLANE;
|
||||
proprec->prop_len = 0;
|
||||
|
||||
/* Do one pass through the string to count the number of
|
||||
* values and make sure they all parse as integers.
|
||||
*/
|
||||
numvals = 0;
|
||||
while (*pptr != '\0')
|
||||
{
|
||||
while (isspace(*pptr) && (*pptr != '\0')) pptr++;
|
||||
if (!isspace(*pptr))
|
||||
{
|
||||
char *endptr;
|
||||
long result;
|
||||
|
||||
/* Check that the value is an integer */
|
||||
result = strtol(pptr, &endptr, 0);
|
||||
if (endptr == pptr)
|
||||
{
|
||||
/* Unable to parse correctly. Save as a string value */
|
||||
proplen = strlen(pvalueptr);
|
||||
proprec = (PropertyRecord *)mallocMagic(
|
||||
sizeof(PropertyRecord) - 7 + proplen);
|
||||
proprec->prop_type = PROPERTY_TYPE_STRING;
|
||||
proprec->prop_len = proplen;
|
||||
strcpy(proprec->prop_value.prop_string, pvalueptr);
|
||||
(void) DBPropPut(cellDef, propertyname, proprec);
|
||||
break;
|
||||
}
|
||||
while (!isspace(*pptr) && (*pptr != '\0')) pptr++;
|
||||
numvals++;
|
||||
}
|
||||
}
|
||||
if (numvals % 4 != 0)
|
||||
{
|
||||
TxError("Cannot read bounding box values in %s property",
|
||||
propertyname);
|
||||
/* This does not need to be a fatal error. Extra
|
||||
* values will be unused.
|
||||
*/
|
||||
}
|
||||
|
||||
pptr = pvalueptr;
|
||||
proprec = (PropertyRecord *)mallocMagic(
|
||||
sizeof(PropertyRecord) + ((numvals - 2) * sizeof(int)));
|
||||
proprec->prop_type = PROPERTY_TYPE_DIMENSION;
|
||||
proprec->prop_len = numvals;
|
||||
|
||||
/* Do a second pass through the string to convert the values
|
||||
* to dimensions and save as an integer array.
|
||||
proprec->prop_value.prop_plane = DBNewPlane((ClientData)TT_SPACE);
|
||||
|
||||
/* Parse the string and convert sets of four values
|
||||
* to coordinates and paint into the plane.
|
||||
*/
|
||||
numvals = 0;
|
||||
while (*pptr != '\0')
|
||||
{
|
||||
Rect r;
|
||||
while (isspace(*pptr) && (*pptr != '\0')) pptr++;
|
||||
if (!isspace(*pptr))
|
||||
{
|
||||
sscanf(pptr, "%d", &ival);
|
||||
if (scalen > 1) ival *= scalen;
|
||||
if (scaled > 1) ival /= scaled;
|
||||
proprec->prop_value.prop_integer[numvals] = ival;
|
||||
|
||||
switch (numvals)
|
||||
{
|
||||
case 0:
|
||||
r.r_xbot = ival;
|
||||
numvals++;
|
||||
break;
|
||||
case 1:
|
||||
r.r_ybot = ival;
|
||||
numvals++;
|
||||
break;
|
||||
case 2:
|
||||
r.r_xtop = ival;
|
||||
numvals++;
|
||||
break;
|
||||
case 3:
|
||||
r.r_ytop = ival;
|
||||
numvals = 0;
|
||||
/* Paint this into the plane */
|
||||
DBPaintPlane(proprec->prop_value.prop_plane,
|
||||
&r, CIFPaintTable,
|
||||
(PaintUndoInfo *)NULL);
|
||||
break;
|
||||
}
|
||||
while (!isspace(*pptr) && (*pptr != '\0')) pptr++;
|
||||
numvals++;
|
||||
}
|
||||
if (numvals == 0)
|
||||
{
|
||||
TxError("Mask-hint property number of values is not"
|
||||
" divisible by four. Truncated.\n");
|
||||
}
|
||||
}
|
||||
(void) DBPropPut(cellDef, propertyname, proprec);
|
||||
|
|
@ -3481,6 +3480,23 @@ DBCellFindScale(cellDef)
|
|||
return ggcf;
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* dbFindGCFFunc ---
|
||||
*
|
||||
* Find the greatest common factor between the current GCF and each point
|
||||
* in a tile.
|
||||
*
|
||||
* Results:
|
||||
* 0 to keep the search going.
|
||||
*
|
||||
* Side effects:
|
||||
* May modify the GCF passed as client data to the function.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
dbFindGCFFunc(tile, dinfo, ggcf)
|
||||
Tile *tile;
|
||||
|
|
@ -3503,6 +3519,24 @@ dbFindGCFFunc(tile, dinfo, ggcf)
|
|||
return (*ggcf == 1) ? 1 : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* dbFindCellGCFFunc ---
|
||||
*
|
||||
* Find the greatest common factor between the current GCF and each point
|
||||
* of a uses bounding box, each component of the use's transform , and
|
||||
* for arrays, the array pitch.
|
||||
*
|
||||
* Results:
|
||||
* 0 to keep the search going.
|
||||
*
|
||||
* Side effects:
|
||||
* May modify the GCF passed as client data to the function.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
dbFindCellGCFFunc(cellUse, ggcf)
|
||||
CellUse *cellUse; /* Cell use whose "call" is to be written to a file */
|
||||
|
|
@ -3543,6 +3577,23 @@ dbFindCellGCFFunc(cellUse, ggcf)
|
|||
return (*ggcf == 1) ? 1 : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* dbFindPropGCFFunc ---
|
||||
*
|
||||
* Find the greatest common factor between the current GCF and each point
|
||||
* of a dimension property, or each point of each tile in a plane property.
|
||||
*
|
||||
* Results:
|
||||
* 0 to keep the search going.
|
||||
*
|
||||
* Side effects:
|
||||
* May modify the GCF passed as client data to the function.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
dbFindPropGCFFunc(key, proprec, ggcf)
|
||||
char *key;
|
||||
|
|
@ -3551,20 +3602,28 @@ dbFindPropGCFFunc(key, proprec, ggcf)
|
|||
{
|
||||
int value, n;
|
||||
|
||||
/* Only PROPERTY_TYPE_DIMENSION properties get handled */
|
||||
if (proprec->prop_type != PROPERTY_TYPE_DIMENSION) return 0;
|
||||
|
||||
for (n = 0; n < proprec->prop_len; n++)
|
||||
if (proprec->prop_type == PROPERTY_TYPE_PLANE)
|
||||
{
|
||||
value = proprec->prop_value.prop_integer[n];
|
||||
if (value % (*ggcf) != 0)
|
||||
*ggcf = FindGCF(value, *ggcf);
|
||||
if (DBSrPaintArea(PlaneGetHint(proprec->prop_value.prop_plane),
|
||||
proprec->prop_value.prop_plane,
|
||||
&TiPlaneRect, &CIFSolidBits, dbFindGCFFunc, (ClientData)ggcf))
|
||||
return (*ggcf == 1) ? 1 : 0;
|
||||
}
|
||||
|
||||
return (*ggcf == 1) ? 1 : 0;
|
||||
else if (proprec->prop_type == PROPERTY_TYPE_DIMENSION)
|
||||
{
|
||||
for (n = 0; n < proprec->prop_len; n++)
|
||||
{
|
||||
value = proprec->prop_value.prop_integer[n];
|
||||
if (value % (*ggcf) != 0)
|
||||
*ggcf = FindGCF(value, *ggcf);
|
||||
}
|
||||
return (*ggcf == 1) ? 1 : 0;
|
||||
}
|
||||
else
|
||||
/* Only PROPERTY_TYPE_PLANE and PROPERTY_TYPE_DIMENSION get handled */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
|
|
@ -3573,6 +3632,12 @@ dbFindPropGCFFunc(key, proprec, ggcf)
|
|||
* String comparison of two instance names, for the purpose of sorting
|
||||
* the instances in a .mag file output in a repeatable way.
|
||||
*
|
||||
* Results:
|
||||
* The string comparison, equivalent to the return value of strcmp().
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
|
@ -3610,6 +3675,9 @@ struct cellUseList {
|
|||
* Return value:
|
||||
* Return 0 to keep the search going.
|
||||
*
|
||||
* Side effects:
|
||||
* Adds to the list of cell uses passed as client data.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
|
@ -3635,6 +3703,9 @@ dbGetUseFunc(cellUse, useRec)
|
|||
* Return value:
|
||||
* Return 0 to keep the search going.
|
||||
*
|
||||
* Side effects:
|
||||
* Increments the count passed as client data.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
|
@ -3663,6 +3734,12 @@ struct keyValuePair {
|
|||
* String comparison of two property keys, for the purpose of sorting
|
||||
* the properties in a .mag file output in a repeatable way.
|
||||
*
|
||||
* Results:
|
||||
* The string comparison, equivalent to the result of strcmp().
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
|
@ -3698,6 +3775,9 @@ struct cellPropList {
|
|||
* Return value:
|
||||
* Return 0 to keep the search going.
|
||||
*
|
||||
* Side Effects:
|
||||
* Adds to the list of property records passed as client data.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
|
@ -3727,6 +3807,9 @@ dbGetPropFunc(key, proprec, propRec)
|
|||
* Return value:
|
||||
* Return 0 to keep the search going.
|
||||
*
|
||||
* Side Effects:
|
||||
* Increments the count passed as client data.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
|
@ -4064,6 +4147,52 @@ ioerror:
|
|||
return (TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* dbWritePropPaintFunc --
|
||||
*
|
||||
* Transform tiles in a plane into a set of four coordinate values and output
|
||||
* them to the file. This turns plane data into a PROP_TYPE_DIMENSION array,
|
||||
* which is not a very efficient form and may be revisited. For relatively
|
||||
* simple plane data, it suffices. The property planes are single-bit types.
|
||||
* Note that there is no support for non-Manhattan geometry in the property
|
||||
* plane at this time.
|
||||
*
|
||||
* Results:
|
||||
* 0 to keep the search going.
|
||||
*
|
||||
* Side effects:
|
||||
* Writes output to a file.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
dbWritePropPaintFunc(Tile *tile,
|
||||
TileType dinfo,
|
||||
ClientData cdata)
|
||||
{
|
||||
pwfrec *pwf = (pwfrec *)cdata;
|
||||
FILE *f = pwf->pwf_file;
|
||||
int reducer = pwf->pwf_reducer;
|
||||
Rect r;
|
||||
char newvalue[20];
|
||||
|
||||
TiToRect(tile, &r);
|
||||
|
||||
snprintf(newvalue, 20, " %d", r.r_xbot / reducer);
|
||||
FPUTSR(f, newvalue);
|
||||
snprintf(newvalue, 20, " %d", r.r_ybot / reducer);
|
||||
FPUTSR(f, newvalue);
|
||||
snprintf(newvalue, 20, " %d", r.r_xtop / reducer);
|
||||
FPUTSR(f, newvalue);
|
||||
snprintf(newvalue, 20, " %d", r.r_ytop / reducer);
|
||||
FPUTSR(f, newvalue);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
|
|
@ -4111,6 +4240,12 @@ dbWritePropFunc(key, proprec, cdata)
|
|||
case PROPERTY_TYPE_INTEGER:
|
||||
FPUTSR(f, "integer ");
|
||||
break;
|
||||
case PROPERTY_TYPE_PLANE:
|
||||
/* A mask hint is a plane type property; declare it
|
||||
* as a dimension, but it's arbitrary anyway since
|
||||
* the prefix "MASKHINTS_" is detected on read-in and
|
||||
* the property is parsed as plane data.
|
||||
*/
|
||||
case PROPERTY_TYPE_DIMENSION:
|
||||
FPUTSR(f, "dimension ");
|
||||
break;
|
||||
|
|
@ -4143,6 +4278,13 @@ dbWritePropFunc(key, proprec, cdata)
|
|||
FPUTSR(f, newvalue);
|
||||
}
|
||||
break;
|
||||
case PROPERTY_TYPE_PLANE:
|
||||
/* Scan the plane and output each non-space tile as four values */
|
||||
DBSrPaintArea(PlaneGetHint(proprec->prop_value.prop_plane),
|
||||
proprec->prop_value.prop_plane,
|
||||
&TiPlaneRect, &CIFSolidBits, dbWritePropPaintFunc,
|
||||
(ClientData)cdata);
|
||||
break;
|
||||
case PROPERTY_TYPE_DOUBLE:
|
||||
for (i = 0; i < proprec->prop_len; i++)
|
||||
{
|
||||
|
|
@ -4395,6 +4537,12 @@ ioerror:
|
|||
* Callback function used by DBCellWriteCommandFile() to output
|
||||
* commands corresponding to cell layout geometry.
|
||||
*
|
||||
* Results:
|
||||
* 0 to keep the search going.
|
||||
*
|
||||
* Side effects:
|
||||
* Writes output to a file.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
|
@ -4460,6 +4608,12 @@ dbWritePaintCommandsFunc(tile, dinfo, cdarg)
|
|||
* Callback function used by DBCellWriteCommandFile() to output
|
||||
* commands corresponding to cell uses in the layout.
|
||||
*
|
||||
* Results:
|
||||
* 0 to keep the search going.
|
||||
*
|
||||
* Side effects:
|
||||
* Writes output to a file.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
|
@ -4479,6 +4633,45 @@ dbWriteUseCommandsFunc(cellUse, cdarg)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* dbWritePropCommandPaintFunc --
|
||||
*
|
||||
* Transform tiles in a plane into a set of four coordinate values and output
|
||||
* them to the file. This turns plane data into a PROP_TYPE_DIMENSION array,
|
||||
* which is not a very efficient form and may be revisited. For relatively
|
||||
* simple plane data, it suffices. The property planes are single-bit types.
|
||||
* Note that there is no support for non-Manhattan geometry in the property
|
||||
* plane at this time.
|
||||
*
|
||||
* Results:
|
||||
* 0 to keep the search going.
|
||||
*
|
||||
* Side effects:
|
||||
* Writes output to a file.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
dbWritePropCommandPaintFunc(Tile *tile,
|
||||
TileType dinfo,
|
||||
FILE *f)
|
||||
{
|
||||
Rect r;
|
||||
MagWindow *w;
|
||||
|
||||
TiToRect(tile, &r);
|
||||
windCheckOnlyWindow(&w, DBWclientID);
|
||||
fprintf(f, "%s ", DBWPrintValue(r.r_xbot, w, TRUE));
|
||||
fprintf(f, "%s ", DBWPrintValue(r.r_ybot, w, FALSE));
|
||||
fprintf(f, "%s ", DBWPrintValue(r.r_xtop, w, TRUE));
|
||||
fprintf(f, "%s ", DBWPrintValue(r.r_ytop, w, FALSE));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
|
|
@ -4487,6 +4680,12 @@ dbWriteUseCommandsFunc(cellUse, cdarg)
|
|||
* Callback function used by DBCellWriteCommandFile() to output
|
||||
* commands corresponding to properties in the layout.
|
||||
*
|
||||
* Results:
|
||||
* 0 to keep the search going.
|
||||
*
|
||||
* Side effects:
|
||||
* Writes output to a file.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
|
@ -4540,6 +4739,19 @@ dbWritePropCommandsFunc(key, proprec, cdarg)
|
|||
fprintf(f, "\n");
|
||||
break;
|
||||
|
||||
case PROPERTY_TYPE_PLANE:
|
||||
/* Plane properties are automatically handled as plane data,
|
||||
* so the property type does not need to be declared.
|
||||
* Only mask hints can be plane properties.
|
||||
*/
|
||||
fprintf(f, "property %s ", key);
|
||||
DBSrPaintArea(PlaneGetHint(proprec->prop_value.prop_plane),
|
||||
proprec->prop_value.prop_plane,
|
||||
&TiPlaneRect, &CIFSolidBits, dbWritePropCommandPaintFunc,
|
||||
(ClientData)f);
|
||||
fprintf(f, "\n");
|
||||
break;
|
||||
|
||||
case PROPERTY_TYPE_DOUBLE:
|
||||
fprintf(f, "property double %s ", key);
|
||||
for (i = 0; i < proprec->prop_len; i++)
|
||||
|
|
@ -4573,7 +4785,6 @@ dbWritePropCommandsFunc(key, proprec, cdarg)
|
|||
* the file. If successful, rewind the now-expanded file and
|
||||
* overwrite the beginning of the file, then truncate it.
|
||||
*
|
||||
*
|
||||
* Results:
|
||||
* TRUE if the cell could be written successfully, FALSE otherwise.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -106,7 +106,18 @@ DBPropPut(cellDef, name, value)
|
|||
|
||||
entry = HashFind(htab, name);
|
||||
oldvalue = (PropertyRecord *)HashGetValue(entry);
|
||||
if (oldvalue != NULL) freeMagic((char *)oldvalue);
|
||||
/* All properties are allocated as a single block and can just be freed,
|
||||
* except for plane properties, which require freeing the plane.
|
||||
*/
|
||||
if (oldvalue != NULL)
|
||||
{
|
||||
if (oldvalue->prop_type == PROPERTY_TYPE_PLANE)
|
||||
{
|
||||
DBFreePaintPlane(oldvalue->prop_value.prop_plane);
|
||||
TiFreePlane(oldvalue->prop_value.prop_plane);
|
||||
}
|
||||
freeMagic((char *)oldvalue);
|
||||
}
|
||||
if (value == (PropertyRecord *)NULL)
|
||||
HashRemove(htab, name);
|
||||
else
|
||||
|
|
|
|||
|
|
@ -719,6 +719,7 @@ typedef struct
|
|||
char prop_string[8]; /* For PROPERTY_TYPE_STRING */
|
||||
int prop_integer[2]; /* For PROPERTY_TYPE_INTEGER or _DIMENSION */
|
||||
dlong prop_double[1]; /* For PROPERTY_TYPE_DOUBLE */
|
||||
Plane *prop_plane; /* For PROPERTY_TYPE_PLANE */
|
||||
} prop_value;
|
||||
} PropertyRecord;
|
||||
|
||||
|
|
@ -760,6 +761,7 @@ typedef struct
|
|||
#define PROPERTY_TYPE_INTEGER 1 /* Fixed integer property */
|
||||
#define PROPERTY_TYPE_DIMENSION 2 /* Integer property that scales with units */
|
||||
#define PROPERTY_TYPE_DOUBLE 3 /* Double-long integer (for file positions) */
|
||||
#define PROPERTY_TYPE_PLANE 4 /* A tile plane structure */
|
||||
|
||||
/* -------------------- Exported procedure headers -------------------- */
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
#include <stdio.h>
|
||||
#include <string.h> // for memcpy()
|
||||
#include <math.h> // for sqrt() for diagonal check
|
||||
|
||||
#include "tcltk/tclmagic.h"
|
||||
#include "utils/magic.h"
|
||||
#include "utils/geometry.h"
|
||||
#include "tiles/tile.h"
|
||||
|
|
@ -36,7 +38,9 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
#include "utils/signals.h"
|
||||
#include "utils/maxrect.h"
|
||||
#include "utils/malloc.h"
|
||||
#include "utils/undo.h"
|
||||
#include "textio/textio.h"
|
||||
#include "cif/CIFint.h"
|
||||
|
||||
int dbDRCDebug = 0;
|
||||
|
||||
|
|
@ -62,7 +66,33 @@ extern MaxRectsData *drcCanonicalMaxwidth();
|
|||
/*
|
||||
*-----------------------------------------------------------------------
|
||||
*
|
||||
* drcCifPointToSegment
|
||||
* drcFoundOneFunc --
|
||||
*
|
||||
* Simple callback for a plane search on a mask-hint plane inside
|
||||
* a DRC check area.
|
||||
*
|
||||
* Results:
|
||||
* Return 1 always, indicating that a tile has been found in the
|
||||
* DRC search area, and the search can end.
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
*
|
||||
*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
drcFoundOneFunc(Tile *tile,
|
||||
TileType dinfo,
|
||||
ClientData cdata)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------
|
||||
*
|
||||
* drcCifPointToSegment --
|
||||
*
|
||||
* Euclidean-distance point-to-segment distance (squared)
|
||||
* calculation (borrowed from XCircuit)
|
||||
|
|
@ -468,6 +498,13 @@ DRCBasicCheck (celldef, checkRect, clipRect, function, cdata)
|
|||
DBResetTilePlane(celldef->cd_planes[planeNum], DRC_UNPROCESSED);
|
||||
(void) DBSrPaintArea ((Tile *) NULL, celldef->cd_planes[planeNum],
|
||||
checkRect, &DBAllTypeBits, drcTile, (ClientData) &arg);
|
||||
|
||||
#ifdef MAGIC_WRAPPER
|
||||
/* Execute pending Tcl events, so the DRC process doesn't block. */
|
||||
UndoEnable();
|
||||
while (Tcl_DoOneEvent(TCL_DONT_WAIT));
|
||||
UndoDisable();
|
||||
#endif
|
||||
}
|
||||
drcCifCheck(&arg);
|
||||
if (arg.dCD_rlist != NULL) freeMagic(arg.dCD_rlist);
|
||||
|
|
@ -743,27 +780,17 @@ drcTile (tile, dinfo, arg)
|
|||
/* If an exception area exists, is the error edge inside? */
|
||||
if (propfound)
|
||||
{
|
||||
int i;
|
||||
Rect r, redge;
|
||||
Rect redge;
|
||||
|
||||
redge.r_xbot = redge.r_xtop = edgeX;
|
||||
redge.r_ybot = edgeBot;
|
||||
redge.r_ytop = edgeTop;
|
||||
isinside = FALSE;
|
||||
for (i = 0; i < proprec->prop_len; i += 4)
|
||||
{
|
||||
if ((i + 4) > proprec->prop_len) break;
|
||||
r.r_xbot = proprec->prop_value.prop_integer[i];
|
||||
r.r_ybot = proprec->prop_value.prop_integer[i + 1];
|
||||
r.r_xtop = proprec->prop_value.prop_integer[i + 2];
|
||||
r.r_ytop = proprec->prop_value.prop_integer[i + 3];
|
||||
|
||||
if (GEO_OVERLAP(&redge, &r))
|
||||
{
|
||||
isinside = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (DBSrPaintArea(PlaneGetHint(proprec->prop_value.prop_plane),
|
||||
proprec->prop_value.prop_plane,
|
||||
&redge, &CIFSolidBits, drcFoundOneFunc,
|
||||
(ClientData)NULL) == 1)
|
||||
isinside = TRUE;
|
||||
}
|
||||
|
||||
/* Exemption rules are ignored if the edge is inside
|
||||
|
|
@ -1205,26 +1232,17 @@ drcTile (tile, dinfo, arg)
|
|||
/* If an exception area exists, is the error edge inside? */
|
||||
if (propfound)
|
||||
{
|
||||
int i;
|
||||
Rect r, redge;
|
||||
Rect redge;
|
||||
|
||||
redge.r_ybot = redge.r_ytop = edgeY;
|
||||
redge.r_xbot = edgeLeft;
|
||||
redge.r_xtop = edgeRight;
|
||||
for (i = 0; i < proprec->prop_len; i += 4)
|
||||
{
|
||||
if ((i + 4) > proprec->prop_len) break;
|
||||
r.r_xbot = proprec->prop_value.prop_integer[i];
|
||||
r.r_ybot = proprec->prop_value.prop_integer[i + 1];
|
||||
r.r_xtop = proprec->prop_value.prop_integer[i + 2];
|
||||
r.r_ytop = proprec->prop_value.prop_integer[i + 3];
|
||||
|
||||
if (GEO_OVERLAP(&redge, &r))
|
||||
{
|
||||
isinside = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (DBSrPaintArea(PlaneGetHint(proprec->prop_value.prop_plane),
|
||||
proprec->prop_value.prop_plane,
|
||||
&redge, &CIFSolidBits, drcFoundOneFunc,
|
||||
(ClientData)NULL) == 1)
|
||||
isinside = TRUE;
|
||||
}
|
||||
|
||||
/* Exemption rules are ignored if the edge is inside
|
||||
|
|
|
|||
Loading…
Reference in New Issue