Implemented new cifinput/cifoutput operator "labeled" which operates
like "bloat-all" except starting with a label and expanding into a type rather than starting with a layer. This is equivalent to what many tools refer to as "stamping".
This commit is contained in:
parent
7bdd9e1d4f
commit
15943d0cb1
105
cif/CIFgen.c
105
cif/CIFgen.c
|
|
@ -25,6 +25,7 @@ static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magi
|
||||||
#include <stdlib.h> /* for abs() */
|
#include <stdlib.h> /* for abs() */
|
||||||
#include <math.h> /* for ceil() and sqrt() */
|
#include <math.h> /* for ceil() and sqrt() */
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <string.h> /* for strcmp() */
|
||||||
|
|
||||||
#include "utils/magic.h"
|
#include "utils/magic.h"
|
||||||
#include "utils/geometry.h"
|
#include "utils/geometry.h"
|
||||||
|
|
@ -5136,12 +5137,13 @@ CIFGenLayer(
|
||||||
CIFSquaresInfo csi;
|
CIFSquaresInfo csi;
|
||||||
SearchContext scx;
|
SearchContext scx;
|
||||||
TileType ttype;
|
TileType ttype;
|
||||||
char *netname;
|
char *netname, *text;
|
||||||
|
Label *label;
|
||||||
BloatStruct bls;
|
BloatStruct bls;
|
||||||
BridgeStruct brs;
|
BridgeStruct brs;
|
||||||
BridgeLimStruct brlims;
|
BridgeLimStruct brlims;
|
||||||
BridgeData *bridge;
|
BridgeData *bridge;
|
||||||
BloatData *bloats;
|
BloatData *bloats, locbloat;
|
||||||
bool hstop = FALSE;
|
bool hstop = FALSE;
|
||||||
PropertyRecord *proprec;
|
PropertyRecord *proprec;
|
||||||
char *propvalue;
|
char *propvalue;
|
||||||
|
|
@ -5601,6 +5603,105 @@ CIFGenLayer(
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CIFOP_LABELED:
|
||||||
|
if (hier)
|
||||||
|
{
|
||||||
|
hstop = TRUE; /* Stop hierarchical processing */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find all relevant labels by text matching and then continue
|
||||||
|
* like CIFOP_BLOATALL. CIFOP_BLOATALL uses a BloatData record
|
||||||
|
* which is not part of CIFOP_LABELED. Create a BloatData record
|
||||||
|
* on the fly for each labeled area based on type, and swap it for
|
||||||
|
* the text, so that cifBloatAllFunc believes this is actually a
|
||||||
|
* CIFOP_BLOATALL operation. Note that we don't actually care
|
||||||
|
* what layer the label is attached to (lab_type). We are looking
|
||||||
|
* for labels whose lab_rect values overlap the types that are given
|
||||||
|
* in the rule.
|
||||||
|
*/
|
||||||
|
|
||||||
|
cifPlane = curPlane;
|
||||||
|
bls.op = op;
|
||||||
|
bls.def = cellDef;
|
||||||
|
bls.temps = temps;
|
||||||
|
|
||||||
|
text = (char *)op->co_client;
|
||||||
|
|
||||||
|
bloats = &locbloat;
|
||||||
|
if (!TTMaskIsZero(&op->co_cifMask))
|
||||||
|
{
|
||||||
|
bloats->bl_plane = -1;
|
||||||
|
for (ttype = 0; ttype < TT_MAXTYPES; ttype++)
|
||||||
|
{
|
||||||
|
if (TTMaskHasType(&op->co_cifMask, ttype))
|
||||||
|
bloats->bl_distance[ttype] = 1;
|
||||||
|
else
|
||||||
|
bloats->bl_distance[ttype] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!TTMaskIsZero(&op->co_paintMask))
|
||||||
|
{
|
||||||
|
int plane, pmask;
|
||||||
|
pmask = DBTechTypesToPlanes(&op->co_paintMask);
|
||||||
|
for (plane = PL_TECHDEPBASE; plane < DBNumPlanes; plane++)
|
||||||
|
if (PlaneMaskHasPlane(pmask, plane))
|
||||||
|
break;
|
||||||
|
bloats->bl_plane = plane;
|
||||||
|
for (ttype = 0; ttype < TT_MAXTYPES; ttype++)
|
||||||
|
{
|
||||||
|
if (TTMaskHasType(&op->co_paintMask, ttype))
|
||||||
|
bloats->bl_distance[ttype] = 1;
|
||||||
|
else
|
||||||
|
bloats->bl_distance[ttype] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Replace the client data with the bloat record */
|
||||||
|
op->co_client = (ClientData)bloats;
|
||||||
|
|
||||||
|
if (bloats->bl_plane < 0)
|
||||||
|
{
|
||||||
|
/* bl_plane == -1 indicates bloating into a CIF templayer, */
|
||||||
|
/* so the only connecting type should be CIF_SOLIDTYPE. */
|
||||||
|
TTMaskSetOnlyType(&bls.connect, CIF_SOLIDTYPE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
TTMaskZero(&bls.connect);
|
||||||
|
for (i = 0; i < TT_MAXTYPES; i++)
|
||||||
|
if (bloats->bl_distance[i] != 0)
|
||||||
|
TTMaskSetType(&bls.connect, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (label = cellDef->cd_labels; label; label = label->lab_next)
|
||||||
|
if (!strcmp(label->lab_text, text))
|
||||||
|
cifSrTiles(op, &label->lab_rect, cellDef, temps,
|
||||||
|
cifBloatAllFunc, (ClientData)&bls);
|
||||||
|
|
||||||
|
/* Reset marked tiles */
|
||||||
|
|
||||||
|
if (bloats->bl_plane < 0) /* Bloat types are CIF types */
|
||||||
|
{
|
||||||
|
bls.temps = temps;
|
||||||
|
for (ttype = 0; ttype < TT_MAXTYPES; ttype++, bls.temps++)
|
||||||
|
if (bloats->bl_distance[ttype] > 0)
|
||||||
|
(void) DBSrPaintArea((Tile *)NULL, *bls.temps, &TiPlaneRect,
|
||||||
|
&CIFSolidBits, cifProcessResetFunc,
|
||||||
|
(ClientData)NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
DBSrPaintArea((Tile *)NULL, cellDef->cd_planes[bloats->bl_plane],
|
||||||
|
&TiPlaneRect, &bls.connect, cifProcessResetFunc,
|
||||||
|
(ClientData)NULL);
|
||||||
|
|
||||||
|
/* Replace the client data */
|
||||||
|
op->co_client = (ClientData)text;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
case CIFOP_BOUNDARY:
|
case CIFOP_BOUNDARY:
|
||||||
if (hier)
|
if (hier)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -146,6 +146,7 @@ typedef struct cifop
|
||||||
* CIFOP_BRIDGELIM - Added 27/07/20---Bridge across catecorner gaps, but with limiting layers
|
* CIFOP_BRIDGELIM - Added 27/07/20---Bridge across catecorner gaps, but with limiting layers
|
||||||
* CIFOP_MASKHINTS - Added 12/14/20---Add geometry from cell properties, if any.
|
* CIFOP_MASKHINTS - Added 12/14/20---Add geometry from cell properties, if any.
|
||||||
* CIFOP_NOTSQUARE - Added 2/26/26---Keep only geometry which is not square.
|
* CIFOP_NOTSQUARE - Added 2/26/26---Keep only geometry which is not square.
|
||||||
|
* CIFOP_LABELED - Added 3/11/26---Find geometry attached to the given text label
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define CIFOP_AND 1
|
#define CIFOP_AND 1
|
||||||
|
|
@ -174,6 +175,7 @@ typedef struct cifop
|
||||||
#define CIFOP_BRIDGELIM 24
|
#define CIFOP_BRIDGELIM 24
|
||||||
#define CIFOP_MASKHINTS 25
|
#define CIFOP_MASKHINTS 25
|
||||||
#define CIFOP_NOTSQUARE 26
|
#define CIFOP_NOTSQUARE 26
|
||||||
|
#define CIFOP_LABELED 27
|
||||||
|
|
||||||
/* Definitions of bit fields used in the value of co_client for CIFOP_INTERACT */
|
/* Definitions of bit fields used in the value of co_client for CIFOP_INTERACT */
|
||||||
#define CIFOP_INT_NOT 0x1 /* Inverted sense (not interacting) */
|
#define CIFOP_INT_NOT 0x1 /* Inverted sense (not interacting) */
|
||||||
|
|
|
||||||
|
|
@ -613,7 +613,7 @@ CIFPaintCurrent(
|
||||||
CIFOp *op;
|
CIFOp *op;
|
||||||
|
|
||||||
plane = CIFGenLayer(cifCurReadStyle->crs_layers[i]->crl_ops,
|
plane = CIFGenLayer(cifCurReadStyle->crs_layers[i]->crl_ops,
|
||||||
&TiPlaneRect, (CellDef *)NULL, (CellDef *)NULL,
|
&TiPlaneRect, cifReadCellDef, cifReadCellDef,
|
||||||
cifCurReadPlanes, FALSE, (ClientData)NULL);
|
cifCurReadPlanes, FALSE, (ClientData)NULL);
|
||||||
|
|
||||||
/* Generate a paint/erase table, then paint from the CIF
|
/* Generate a paint/erase table, then paint from the CIF
|
||||||
|
|
|
||||||
|
|
@ -332,7 +332,8 @@ cifNewReadStyle(void)
|
||||||
free_magic1_t mm1 = freeMagic1_init();
|
free_magic1_t mm1 = freeMagic1_init();
|
||||||
for (op = layer->crl_ops; op != NULL; op = op->co_next)
|
for (op = layer->crl_ops; op != NULL; op = op->co_next)
|
||||||
{
|
{
|
||||||
if (op->co_opcode == CIFOP_MASKHINTS)
|
if (op->co_opcode == CIFOP_MASKHINTS ||
|
||||||
|
op->co_opcode == CIFOP_LABELED)
|
||||||
freeMagic((char *)op->co_client);
|
freeMagic((char *)op->co_client);
|
||||||
freeMagic1(&mm1, (char *)op);
|
freeMagic1(&mm1, (char *)op);
|
||||||
}
|
}
|
||||||
|
|
@ -998,6 +999,8 @@ CIFReadTechLine(
|
||||||
newOp->co_opcode = CIFOP_NOTSQUARE;
|
newOp->co_opcode = CIFOP_NOTSQUARE;
|
||||||
else if (strcmp(argv[0], "mask-hints") == 0)
|
else if (strcmp(argv[0], "mask-hints") == 0)
|
||||||
newOp->co_opcode = CIFOP_MASKHINTS;
|
newOp->co_opcode = CIFOP_MASKHINTS;
|
||||||
|
else if (strcmp(argv[0], "labeled") == 0)
|
||||||
|
newOp->co_opcode = CIFOP_LABELED;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TechError("Unknown statement \"%s\".\n", argv[0]);
|
TechError("Unknown statement \"%s\".\n", argv[0]);
|
||||||
|
|
@ -1028,6 +1031,11 @@ CIFReadTechLine(
|
||||||
if (argc != 2) goto wrongNumArgs;
|
if (argc != 2) goto wrongNumArgs;
|
||||||
newOp->co_client = (ClientData)StrDup((char **)NULL, argv[1]);
|
newOp->co_client = (ClientData)StrDup((char **)NULL, argv[1]);
|
||||||
break;
|
break;
|
||||||
|
case CIFOP_LABELED:
|
||||||
|
if (argc != 3) goto wrongNumArgs;
|
||||||
|
newOp->co_client = (ClientData)StrDup((char **)NULL, argv[1]);
|
||||||
|
CIFParseReadLayers(argv[2], &newOp->co_cifMask, TRUE);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Link the new CIFOp onto the list. */
|
/* Link the new CIFOp onto the list. */
|
||||||
|
|
|
||||||
|
|
@ -1107,6 +1107,8 @@ CIFTechLine(
|
||||||
newOp->co_opcode = CIFOP_BBOX;
|
newOp->co_opcode = CIFOP_BBOX;
|
||||||
else if (strcmp(argv[0], "net") == 0)
|
else if (strcmp(argv[0], "net") == 0)
|
||||||
newOp->co_opcode = CIFOP_NET;
|
newOp->co_opcode = CIFOP_NET;
|
||||||
|
else if (strcmp(argv[0], "labeled") == 0)
|
||||||
|
newOp->co_opcode = CIFOP_LABELED;
|
||||||
else if (strcmp(argv[0], "maxrect") == 0)
|
else if (strcmp(argv[0], "maxrect") == 0)
|
||||||
newOp->co_opcode = CIFOP_MAXRECT;
|
newOp->co_opcode = CIFOP_MAXRECT;
|
||||||
else if (strcmp(argv[0], "boundary") == 0)
|
else if (strcmp(argv[0], "boundary") == 0)
|
||||||
|
|
@ -1357,6 +1359,7 @@ bloatCheck:
|
||||||
bloatDone: break;
|
bloatDone: break;
|
||||||
|
|
||||||
case CIFOP_NET:
|
case CIFOP_NET:
|
||||||
|
case CIFOP_LABELED:
|
||||||
if (argc != 3) goto wrongNumArgs;
|
if (argc != 3) goto wrongNumArgs;
|
||||||
newOp->co_client = (ClientData)StrDup((char **)NULL, argv[1]);
|
newOp->co_client = (ClientData)StrDup((char **)NULL, argv[1]);
|
||||||
cifParseLayers(argv[2], CIFCurStyle, &newOp->co_paintMask,
|
cifParseLayers(argv[2], CIFCurStyle, &newOp->co_paintMask,
|
||||||
|
|
@ -1671,12 +1674,12 @@ cifComputeRadii(
|
||||||
|
|
||||||
for (op = layer->cl_ops; op != NULL; op = op->co_next)
|
for (op = layer->cl_ops; op != NULL; op = op->co_next)
|
||||||
{
|
{
|
||||||
/* BBOX, NET, and MASKHINTS operators should never be used */
|
/* BBOX, NET, LABELED, and MASKHINTS operators should never be */
|
||||||
/* hierarchically so ignore any grow/shrink operators that */
|
/* used hierarchically so ignore any grow/shrink operators that */
|
||||||
/* come after them. */
|
/* come after them. */
|
||||||
|
|
||||||
if (op->co_opcode == CIFOP_BBOX || op->co_opcode == CIFOP_NET ||
|
if (op->co_opcode == CIFOP_BBOX || op->co_opcode == CIFOP_NET ||
|
||||||
op->co_opcode == CIFOP_MASKHINTS)
|
op->co_opcode == CIFOP_LABELED || op->co_opcode == CIFOP_MASKHINTS)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* If CIF layers are used, switch to the max of current
|
/* If CIF layers are used, switch to the max of current
|
||||||
|
|
@ -1988,8 +1991,8 @@ CIFTechFinal(void)
|
||||||
/* Presence of op->co_opcode in CIFOP_OR indicates a copy */
|
/* Presence of op->co_opcode in CIFOP_OR indicates a copy */
|
||||||
/* of the SquaresData pointer from a following operator. */
|
/* of the SquaresData pointer from a following operator. */
|
||||||
/* CIFOP_BBOX and CIFOP_MAXRECT uses the co_client field */
|
/* CIFOP_BBOX and CIFOP_MAXRECT uses the co_client field */
|
||||||
/* as a flag field, while CIFOP_NET and CIFOP_MASKHINTS */
|
/* as a flag field, while CIFOP_NET, CIFOP_MASKHINTS, and */
|
||||||
/* uses it for a string. */
|
/* CIFOP_LABELED use it for a string. */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
switch (op->co_opcode)
|
switch (op->co_opcode)
|
||||||
|
|
@ -2001,6 +2004,7 @@ CIFTechFinal(void)
|
||||||
case CIFOP_MAXRECT:
|
case CIFOP_MAXRECT:
|
||||||
case CIFOP_MANHATTAN:
|
case CIFOP_MANHATTAN:
|
||||||
case CIFOP_NET:
|
case CIFOP_NET:
|
||||||
|
case CIFOP_LABELED:
|
||||||
break;
|
break;
|
||||||
case CIFOP_BRIDGELIM:
|
case CIFOP_BRIDGELIM:
|
||||||
case CIFOP_BRIDGE:
|
case CIFOP_BRIDGE:
|
||||||
|
|
@ -2536,6 +2540,7 @@ CIFTechOutputScale(
|
||||||
case CIFOP_MAXRECT:
|
case CIFOP_MAXRECT:
|
||||||
case CIFOP_MANHATTAN:
|
case CIFOP_MANHATTAN:
|
||||||
case CIFOP_NET:
|
case CIFOP_NET:
|
||||||
|
case CIFOP_LABELED:
|
||||||
case CIFOP_INTERACT:
|
case CIFOP_INTERACT:
|
||||||
break;
|
break;
|
||||||
case CIFOP_BRIDGELIM:
|
case CIFOP_BRIDGELIM:
|
||||||
|
|
@ -2651,8 +2656,8 @@ CIFTechOutputScale(
|
||||||
default:
|
default:
|
||||||
/* op->co_opcode in CIFOP_OR is a pointer copy, */
|
/* op->co_opcode in CIFOP_OR is a pointer copy, */
|
||||||
/* in CIFOP_BBOX and CIFOP_MAXRECT is a flag, */
|
/* in CIFOP_BBOX and CIFOP_MAXRECT is a flag, */
|
||||||
/* and in CIFOP_NET and CIFOP_MASKHINTS is a */
|
/* and in CIFOP_NET, CIFOP_MASKHINTS, and */
|
||||||
/* string. */
|
/* CIFOP_LABELED is a string. */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue