Added new CIF generation op "grow-min" that ensures a minimum width

for a layer.
This commit is contained in:
Tim Edwards 2019-12-02 10:18:37 -05:00
parent cfaccd973f
commit 31612b593f
4 changed files with 109 additions and 20 deletions

View File

@ -111,6 +111,71 @@ cifPaintFunc(tile, table)
return 0; return 0;
} }
/*
* ----------------------------------------------------------------------------
*
* cifGrowMinFunc --
*
* Called for each relevant tile during grow-min operations.
*
* Results:
* Always returns 0 to keep the search alive.
*
* Side effects:
* Scales the tile by cifScale, then expands its area by the
* remainder of the distance to meet the minimum dimension, as
* defined by the grid distance (growDistance) in the current
* CIFOp, then paints this area into cifNewPlane using the table
* passed as parameter.
* ----------------------------------------------------------------------------
*/
int
cifGrowMinFunc(tile, plane)
Tile *tile;
Plane *plane;
{
Rect area, *maxr;
int locDist, width, height;
TileTypeBitMask mask;
TileType type;
TiToRect(tile, &area);
type = TiGetType(tile);
TTMaskZero(&mask);
TTMaskSetType(&mask, type);
maxr = FindMaxRectangle2(&area, tile, plane, &mask);
if (maxr == NULL) return 0; /* Should not happen */
maxr->r_xbot *= cifScale;
maxr->r_xtop *= cifScale;
maxr->r_ybot *= cifScale;
maxr->r_ytop *= cifScale;
width = maxr->r_xtop - maxr->r_xbot;
height = maxr->r_ytop - maxr->r_ybot;
locDist = (growDistance - width) / 2;
if (locDist > 0)
{
maxr->r_xbot -= locDist;
maxr->r_xtop += locDist;
}
locDist = (growDistance - height) / 2;
if (locDist > 0)
{
maxr->r_ybot -= locDist;
maxr->r_ytop += locDist;
}
DBPaintPlane(cifPlane, maxr, CIFPaintTable, (PaintUndoInfo *) NULL);
CIFTileOps += 1;
return 0;
}
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -1505,7 +1570,7 @@ cifRectBoundingBox(op, cellDef, plane)
} }
else else
{ {
maxr = FindMaxRectangle2(&bbox, tile, plane); maxr = FindMaxRectangle2(&bbox, tile, plane, NULL);
DBPaintPlane(cifPlane, maxr, CIFPaintTable, (PaintUndoInfo *)NULL); DBPaintPlane(cifPlane, maxr, CIFPaintTable, (PaintUndoInfo *)NULL);
CIFTileOps++; CIFTileOps++;
} }
@ -3126,6 +3191,20 @@ CIFGenLayer(op, area, cellDef, temps, clientdata)
nextPlane = temp; nextPlane = temp;
break; break;
/* GROWMIN grows non-uniformly to ensure minimum dimensions */
case CIFOP_GROWMIN:
growDistance = op->co_distance;
DBClearPaintPlane(nextPlane);
cifPlane = nextPlane;
cifScale = 1;
(void) DBSrPaintArea((Tile *) NULL, curPlane, &TiPlaneRect,
&CIFSolidBits, cifGrowMinFunc, (ClientData)curPlane);
temp = curPlane;
curPlane = nextPlane;
nextPlane = temp;
break;
/* GROW_G grows non-uniformly to the indicated grid. */ /* GROW_G grows non-uniformly to the indicated grid. */
case CIFOP_GROW_G: case CIFOP_GROW_G:

View File

@ -96,6 +96,7 @@ typedef struct cifop
* the masks. * the masks.
* CIFOP_GROW - Grow the current results uniformly by co_distance. * CIFOP_GROW - Grow the current results uniformly by co_distance.
* CIFOP_GROW_G - Grow the current results to snap to the indicated grid. * CIFOP_GROW_G - Grow the current results to snap to the indicated grid.
* CIFOP_GROWMIN - Grow result such that no dimension is less than co_distance.
* CIFOP_SHRINK - Shrink the current results uniformly by co_distance. * CIFOP_SHRINK - Shrink the current results uniformly by co_distance.
* CIFOP_BLOAT - Find layers in paintMask, then bloat selectively * CIFOP_BLOAT - Find layers in paintMask, then bloat selectively
* according to bl_distance, and OR the results into * according to bl_distance, and OR the results into
@ -137,22 +138,23 @@ typedef struct cifop
#define CIFOP_AND 1 #define CIFOP_AND 1
#define CIFOP_OR 2 #define CIFOP_OR 2
#define CIFOP_GROW 3 #define CIFOP_GROW 3
#define CIFOP_GROW_G 4 #define CIFOP_GROWMIN 4
#define CIFOP_SHRINK 5 #define CIFOP_GROW_G 5
#define CIFOP_BLOAT 6 #define CIFOP_SHRINK 6
#define CIFOP_SQUARES 7 #define CIFOP_BLOAT 7
#define CIFOP_SLOTS 8 #define CIFOP_SQUARES 8
#define CIFOP_BLOATMAX 9 #define CIFOP_SLOTS 9
#define CIFOP_BLOATMIN 10 #define CIFOP_BLOATMAX 10
#define CIFOP_BLOATALL 11 #define CIFOP_BLOATMIN 11
#define CIFOP_ANDNOT 12 #define CIFOP_BLOATALL 12
#define CIFOP_SQUARES_G 13 #define CIFOP_ANDNOT 13
#define CIFOP_BBOX 14 #define CIFOP_SQUARES_G 14
#define CIFOP_BOUNDARY 15 #define CIFOP_BBOX 15
#define CIFOP_NET 16 #define CIFOP_BOUNDARY 16
#define CIFOP_MAXRECT 17 #define CIFOP_NET 17
#define CIFOP_COPYUP 18 #define CIFOP_MAXRECT 18
#define CIFOP_CLOSE 19 #define CIFOP_COPYUP 19
#define CIFOP_CLOSE 20
/* Added by Tim 10/21/2004 */ /* Added by Tim 10/21/2004 */
/* The following structure is used to pass information on how to draw /* The following structure is used to pass information on how to draw

View File

@ -1023,6 +1023,8 @@ CIFTechLine(sectionName, argc, argv)
newOp->co_opcode = CIFOP_OR; newOp->co_opcode = CIFOP_OR;
else if (strcmp(argv[0], "grow") == 0) else if (strcmp(argv[0], "grow") == 0)
newOp->co_opcode = CIFOP_GROW; newOp->co_opcode = CIFOP_GROW;
else if (strcmp(argv[0], "grow-min") == 0)
newOp->co_opcode = CIFOP_GROWMIN;
else if (strcmp(argv[0], "grow-grid") == 0) else if (strcmp(argv[0], "grow-grid") == 0)
newOp->co_opcode = CIFOP_GROW_G; newOp->co_opcode = CIFOP_GROW_G;
else if (strcmp(argv[0], "shrink") == 0) else if (strcmp(argv[0], "shrink") == 0)
@ -1068,6 +1070,7 @@ CIFTechLine(sectionName, argc, argv)
break; break;
case CIFOP_GROW: case CIFOP_GROW:
case CIFOP_GROWMIN:
case CIFOP_GROW_G: case CIFOP_GROW_G:
case CIFOP_SHRINK: case CIFOP_SHRINK:
case CIFOP_CLOSE: case CIFOP_CLOSE:
@ -1499,6 +1502,7 @@ cifComputeRadii(layer, des)
case CIFOP_OR: break; case CIFOP_OR: break;
case CIFOP_GROW: case CIFOP_GROW:
case CIFOP_GROWMIN:
case CIFOP_GROW_G: case CIFOP_GROW_G:
grow += op->co_distance; grow += op->co_distance;
break; break;

View File

@ -234,6 +234,9 @@ FindMaxRects(tile, mrd)
* example, from the router code to expand a point label into the * example, from the router code to expand a point label into the
* maximum size rectangular terminal. * maximum size rectangular terminal.
* *
* If expandtypes is NULL, then searching is done over tiles that
* match by the ClientData record instead of types.
*
* Results: * Results:
* Pointer to a rectangle containing the maximum size area found. * Pointer to a rectangle containing the maximum size area found.
* This pointer should not be deallocated! * This pointer should not be deallocated!
@ -290,7 +293,7 @@ FindMaxRectangle(bbox, startpoint, plane, expandtypes)
* FindMaxRectangle2 --- * FindMaxRectangle2 ---
* *
* This routine differs from FindMaxRectangle in passing a starting * This routine differs from FindMaxRectangle in passing a starting
* tile to the routine * tile to the routine.
* *
* Results: * Results:
* Pointer to a rectangle containing the maximum size area found. * Pointer to a rectangle containing the maximum size area found.
@ -300,10 +303,11 @@ FindMaxRectangle(bbox, startpoint, plane, expandtypes)
*/ */
Rect * Rect *
FindMaxRectangle2(bbox, starttile, plane) FindMaxRectangle2(bbox, starttile, plane, expandtypes)
Rect *bbox; /* bounding box of area searched */ Rect *bbox; /* bounding box of area searched */
Tile *starttile; /* use this tile to start */ Tile *starttile; /* use this tile to start */
Plane *plane; /* plane of types to expand */ Plane *plane; /* plane of types to expand */
TileTypeBitMask *expandtypes; /* types to expand in, may be NULL */
{ {
MaxRectsData *mrd; MaxRectsData *mrd;
TileType tt; TileType tt;
@ -312,7 +316,7 @@ FindMaxRectangle2(bbox, starttile, plane)
int s, sidx = -1; int s, sidx = -1;
/* Find tile in def that surrounds or touches startpoint */ /* Find tile in def that surrounds or touches startpoint */
mrd = genCanonicalMaxwidth(bbox, starttile, plane, NULL); mrd = genCanonicalMaxwidth(bbox, starttile, plane, expandtypes);
/* Return only the largest rectangle found */ /* Return only the largest rectangle found */