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 <math.h> /* for ceil() and sqrt() */
|
||||
#include <ctype.h>
|
||||
#include <string.h> /* for strcmp() */
|
||||
|
||||
#include "utils/magic.h"
|
||||
#include "utils/geometry.h"
|
||||
|
|
@ -5136,12 +5137,13 @@ CIFGenLayer(
|
|||
CIFSquaresInfo csi;
|
||||
SearchContext scx;
|
||||
TileType ttype;
|
||||
char *netname;
|
||||
char *netname, *text;
|
||||
Label *label;
|
||||
BloatStruct bls;
|
||||
BridgeStruct brs;
|
||||
BridgeLimStruct brlims;
|
||||
BridgeData *bridge;
|
||||
BloatData *bloats;
|
||||
BloatData *bloats, locbloat;
|
||||
bool hstop = FALSE;
|
||||
PropertyRecord *proprec;
|
||||
char *propvalue;
|
||||
|
|
@ -5601,6 +5603,105 @@ CIFGenLayer(
|
|||
}
|
||||
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:
|
||||
if (hier)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -146,6 +146,7 @@ typedef struct cifop
|
|||
* 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_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
|
||||
|
|
@ -174,6 +175,7 @@ typedef struct cifop
|
|||
#define CIFOP_BRIDGELIM 24
|
||||
#define CIFOP_MASKHINTS 25
|
||||
#define CIFOP_NOTSQUARE 26
|
||||
#define CIFOP_LABELED 27
|
||||
|
||||
/* Definitions of bit fields used in the value of co_client for CIFOP_INTERACT */
|
||||
#define CIFOP_INT_NOT 0x1 /* Inverted sense (not interacting) */
|
||||
|
|
|
|||
|
|
@ -613,7 +613,7 @@ CIFPaintCurrent(
|
|||
CIFOp *op;
|
||||
|
||||
plane = CIFGenLayer(cifCurReadStyle->crs_layers[i]->crl_ops,
|
||||
&TiPlaneRect, (CellDef *)NULL, (CellDef *)NULL,
|
||||
&TiPlaneRect, cifReadCellDef, cifReadCellDef,
|
||||
cifCurReadPlanes, FALSE, (ClientData)NULL);
|
||||
|
||||
/* Generate a paint/erase table, then paint from the CIF
|
||||
|
|
|
|||
|
|
@ -332,7 +332,8 @@ cifNewReadStyle(void)
|
|||
free_magic1_t mm1 = freeMagic1_init();
|
||||
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);
|
||||
freeMagic1(&mm1, (char *)op);
|
||||
}
|
||||
|
|
@ -998,6 +999,8 @@ CIFReadTechLine(
|
|||
newOp->co_opcode = CIFOP_NOTSQUARE;
|
||||
else if (strcmp(argv[0], "mask-hints") == 0)
|
||||
newOp->co_opcode = CIFOP_MASKHINTS;
|
||||
else if (strcmp(argv[0], "labeled") == 0)
|
||||
newOp->co_opcode = CIFOP_LABELED;
|
||||
else
|
||||
{
|
||||
TechError("Unknown statement \"%s\".\n", argv[0]);
|
||||
|
|
@ -1028,6 +1031,11 @@ CIFReadTechLine(
|
|||
if (argc != 2) goto wrongNumArgs;
|
||||
newOp->co_client = (ClientData)StrDup((char **)NULL, argv[1]);
|
||||
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. */
|
||||
|
|
|
|||
|
|
@ -1107,6 +1107,8 @@ CIFTechLine(
|
|||
newOp->co_opcode = CIFOP_BBOX;
|
||||
else if (strcmp(argv[0], "net") == 0)
|
||||
newOp->co_opcode = CIFOP_NET;
|
||||
else if (strcmp(argv[0], "labeled") == 0)
|
||||
newOp->co_opcode = CIFOP_LABELED;
|
||||
else if (strcmp(argv[0], "maxrect") == 0)
|
||||
newOp->co_opcode = CIFOP_MAXRECT;
|
||||
else if (strcmp(argv[0], "boundary") == 0)
|
||||
|
|
@ -1357,6 +1359,7 @@ bloatCheck:
|
|||
bloatDone: break;
|
||||
|
||||
case CIFOP_NET:
|
||||
case CIFOP_LABELED:
|
||||
if (argc != 3) goto wrongNumArgs;
|
||||
newOp->co_client = (ClientData)StrDup((char **)NULL, argv[1]);
|
||||
cifParseLayers(argv[2], CIFCurStyle, &newOp->co_paintMask,
|
||||
|
|
@ -1671,12 +1674,12 @@ cifComputeRadii(
|
|||
|
||||
for (op = layer->cl_ops; op != NULL; op = op->co_next)
|
||||
{
|
||||
/* BBOX, NET, and MASKHINTS operators should never be used */
|
||||
/* hierarchically so ignore any grow/shrink operators that */
|
||||
/* BBOX, NET, LABELED, and MASKHINTS operators should never be */
|
||||
/* used hierarchically so ignore any grow/shrink operators that */
|
||||
/* come after them. */
|
||||
|
||||
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;
|
||||
|
||||
/* 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 */
|
||||
/* of the SquaresData pointer from a following operator. */
|
||||
/* CIFOP_BBOX and CIFOP_MAXRECT uses the co_client field */
|
||||
/* as a flag field, while CIFOP_NET and CIFOP_MASKHINTS */
|
||||
/* uses it for a string. */
|
||||
/* as a flag field, while CIFOP_NET, CIFOP_MASKHINTS, and */
|
||||
/* CIFOP_LABELED use it for a string. */
|
||||
else
|
||||
{
|
||||
switch (op->co_opcode)
|
||||
|
|
@ -2001,6 +2004,7 @@ CIFTechFinal(void)
|
|||
case CIFOP_MAXRECT:
|
||||
case CIFOP_MANHATTAN:
|
||||
case CIFOP_NET:
|
||||
case CIFOP_LABELED:
|
||||
break;
|
||||
case CIFOP_BRIDGELIM:
|
||||
case CIFOP_BRIDGE:
|
||||
|
|
@ -2536,6 +2540,7 @@ CIFTechOutputScale(
|
|||
case CIFOP_MAXRECT:
|
||||
case CIFOP_MANHATTAN:
|
||||
case CIFOP_NET:
|
||||
case CIFOP_LABELED:
|
||||
case CIFOP_INTERACT:
|
||||
break;
|
||||
case CIFOP_BRIDGELIM:
|
||||
|
|
@ -2651,8 +2656,8 @@ CIFTechOutputScale(
|
|||
default:
|
||||
/* op->co_opcode in CIFOP_OR is a pointer copy, */
|
||||
/* in CIFOP_BBOX and CIFOP_MAXRECT is a flag, */
|
||||
/* and in CIFOP_NET and CIFOP_MASKHINTS is a */
|
||||
/* string. */
|
||||
/* and in CIFOP_NET, CIFOP_MASKHINTS, and */
|
||||
/* CIFOP_LABELED is a string. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue