Merge branch 'master' into magic-8.2

This commit is contained in:
Tim Edwards 2019-11-26 03:00:06 -05:00
commit 22a7922083
4 changed files with 156 additions and 3 deletions

View File

@ -514,7 +514,7 @@ cifGrowFunc(tile, table)
CIFTileOps += 1;
return 0;
}
/*
* ----------------------------------------------------------------------------
*
@ -1049,6 +1049,134 @@ cifBloatAllFunc(tile, bls)
return 0; /* Keep the search alive. . . */
}
/*
* ----------------------------------------------------------------------------
*
* cifCloseFunc --
*
* Called for each relevant tile during close operations.
*
* Results:
* Always returns 0 to keep the search alive.
*
* Side effects:
* Paints into cifNewPlane. Tiles in old plane are tagged with
* a static value in ClientData, which does not need to be reset
* since the old plane will be free'd.
* ----------------------------------------------------------------------------
*/
#define CLOSE_SEARCH 0
#define CLOSE_FILL 1
#define CLOSE_DONE 2
int
cifCloseFunc(tile, plane)
Tile *tile;
Plane *plane;
{
Rect area, newarea;
int atotal;
int cifGatherFunc();
/* If tile is marked, then it has been handled, so ignore it */
if (tile->ti_client != (ClientData)CIF_UNPROCESSED) return 0;
atotal = 0;
/* Search all sides for connected space tiles, and accumulate the total */
/* area. If any connected tile borders infinity, then stop searching */
/* because the area is not enclosed. */
cifGatherFunc(tile, &atotal, CLOSE_SEARCH);
/* If the total area is smaller than the rule area, then paint all the */
/* tile areas into the destination plane. */
if ((atotal != INFINITY) && (atotal < growDistance))
cifGatherFunc(tile, &atotal, CLOSE_FILL);
else
cifGatherFunc(tile, &atotal, CLOSE_DONE);
return 0;
}
int
cifGatherFunc(tile, atotal, mode)
Tile *tile;
int *atotal;
bool mode;
{
Tile *tp;
TileType type;
dlong locarea;
Rect area, newarea;
ClientData cdata = (mode == CLOSE_SEARCH) ? (ClientData)CIF_UNPROCESSED :
(ClientData)CIF_PENDING;
/* Ignore if tile has already been processed */
if (tile->ti_client != cdata) return 0;
TiToRect(tile, &area);
/* Boundary tiles indicate an unclosed area, so set the area total to */
/* INFINITY and don't try to run calculations on it. */
if ((area.r_xbot == TiPlaneRect.r_xbot) || (area.r_ybot == TiPlaneRect.r_ybot) ||
(area.r_xtop == TiPlaneRect.r_xtop) || (area.r_ytop == TiPlaneRect.r_ytop))
*atotal = INFINITY;
/* Stop accumulating if already larger than growDistance to avoid the */
/* possibility of integer overflow. */
if (mode == CLOSE_SEARCH)
{
if ((*atotal != INFINITY) && (*atotal < growDistance))
locarea = (dlong)(area.r_xtop - area.r_xbot)
* (dlong)(area.r_ytop - area.r_ybot);
if (locarea > (dlong)INFINITY)
*atotal = INFINITY;
else
*atotal += (int)locarea;
}
else if (mode == CLOSE_FILL)
{
DBPaintPlane(cifPlane, &area, CIFPaintTable, (PaintUndoInfo *)NULL);
CIFTileOps++;
}
if (mode == CLOSE_SEARCH)
tile->ti_client = (ClientData)CIF_PENDING;
else
tile->ti_client = (ClientData)CIF_PROCESSED;
/* Look for additional neighboring space tiles */
/* Check top */
if (area.r_ytop != TiPlaneRect.r_ytop)
for (tp = RT(tile); RIGHT(tp) > LEFT(tile); tp = BL(tp))
if (tp->ti_client == cdata && TiGetType(tp) == TT_SPACE)
cifGatherFunc(tp, atotal, mode);
/* Check bottom */
if (area.r_ybot != TiPlaneRect.r_ybot)
for (tp = LB(tile); LEFT(tp) < RIGHT(tile); tp = TR(tp))
if (tp->ti_client == cdata && TiGetType(tp) == TT_SPACE)
cifGatherFunc(tp, atotal, mode);
/* Check left */
if (area.r_xbot != TiPlaneRect.r_xbot)
for (tp = BL(tile); BOTTOM(tp) < TOP(tile); tp = RT(tp))
if (tp->ti_client == cdata && TiGetType(tp) == TT_SPACE)
cifGatherFunc(tp, atotal, mode);
/* Check right */
if (area.r_xtop != TiPlaneRect.r_xtop)
for (tp = TR(tile); TOP(tp) > BOTTOM(tile); tp = LB(tp))
if (tp->ti_client == cdata && TiGetType(tp) == TT_SPACE)
cifGatherFunc(tp, atotal, mode);
return 0;
}
/*--------------------------------------------------------------*/
/* Support routines and definitions for cifSquaresFillArea */
/*--------------------------------------------------------------*/
@ -3028,6 +3156,22 @@ CIFGenLayer(op, area, cellDef, temps, clientdata)
nextPlane = temp;
break;
case CIFOP_CLOSE:
growDistance = op->co_distance;
DBClearPaintPlane(nextPlane);
cifPlane = nextPlane;
cifScale = 1;
/* First copy the existing paint into the target plane */
(void) DBSrPaintArea((Tile *) NULL, curPlane, &TiPlaneRect,
&CIFSolidBits, cifPaintFunc, (ClientData)CIFPaintTable);
(void) DBSrPaintArea((Tile *) NULL, curPlane, &TiPlaneRect,
&DBSpaceBits, cifCloseFunc, (ClientData)&curPlane);
temp = curPlane;
curPlane = nextPlane;
nextPlane = temp;
break;
case CIFOP_BLOAT:
cifPlane = curPlane;
cifSrTiles(op, area, cellDef, temps,

View File

@ -131,6 +131,7 @@ typedef struct cifop
* CIFOP_COPYUP - Added 5/5/16---make and keep a copy the resulting layer,
* which will be painted into parent cells instead of the
* current cell. This replaces the "fault" method.
* CIFOP_CLOSE - Added 11/25/19---close up areas smaller than indicated
*/
#define CIFOP_AND 1
@ -151,6 +152,7 @@ typedef struct cifop
#define CIFOP_NET 16
#define CIFOP_MAXRECT 17
#define CIFOP_COPYUP 18
#define CIFOP_CLOSE 19
/* Added by Tim 10/21/2004 */
/* The following structure is used to pass information on how to draw

View File

@ -1049,6 +1049,8 @@ CIFTechLine(sectionName, argc, argv)
newOp->co_opcode = CIFOP_MAXRECT;
else if (strcmp(argv[0], "boundary") == 0)
newOp->co_opcode = CIFOP_BOUNDARY;
else if (strcmp(argv[0], "close") == 0)
newOp->co_opcode = CIFOP_CLOSE;
else
{
TechError("Unknown statement \"%s\".\n", argv[0]);
@ -1068,6 +1070,7 @@ CIFTechLine(sectionName, argc, argv)
case CIFOP_GROW:
case CIFOP_GROW_G:
case CIFOP_SHRINK:
case CIFOP_CLOSE:
if (argc != 2) goto wrongNumArgs;
newOp->co_distance = atoi(argv[1]);
if (newOp->co_distance <= 0)

View File

@ -513,7 +513,7 @@ drcCifCheck(arg)
TxPrintf("Loading DRC CIF style.\n");
CIFCurStyle = NULL;
CIFLoadStyle(drcNeedStyle);
if (drcCifValid == FALSE)
if (drcCifValid != FALSE)
CIFCurStyle = CIFSaveStyle;
else
drcCifStyle = CIFCurStyle;
@ -525,7 +525,11 @@ drcCifCheck(arg)
}
CIFCurStyle = drcCifStyle;
}
if (drcCifValid == FALSE) return;
if (drcCifValid == FALSE)
{
CIFCurStyle = CIFSaveStyle;
return;
}
scale = drcCifStyle->cs_scaleFactor;
cifrect = *checkRect;