diff --git a/cif/CIFgen.c b/cif/CIFgen.c index 4381742b..ac4b8056 100644 --- a/cif/CIFgen.c +++ b/cif/CIFgen.c @@ -111,6 +111,71 @@ cifPaintFunc(tile, table) 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 { - maxr = FindMaxRectangle2(&bbox, tile, plane); + maxr = FindMaxRectangle2(&bbox, tile, plane, NULL); DBPaintPlane(cifPlane, maxr, CIFPaintTable, (PaintUndoInfo *)NULL); CIFTileOps++; } @@ -3126,6 +3191,20 @@ CIFGenLayer(op, area, cellDef, temps, clientdata) nextPlane = temp; 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. */ case CIFOP_GROW_G: diff --git a/cif/CIFint.h b/cif/CIFint.h index d08c0ba1..79564a34 100644 --- a/cif/CIFint.h +++ b/cif/CIFint.h @@ -96,6 +96,7 @@ typedef struct cifop * the masks. * CIFOP_GROW - Grow the current results uniformly by co_distance. * 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_BLOAT - Find layers in paintMask, then bloat selectively * according to bl_distance, and OR the results into @@ -137,22 +138,23 @@ typedef struct cifop #define CIFOP_AND 1 #define CIFOP_OR 2 #define CIFOP_GROW 3 -#define CIFOP_GROW_G 4 -#define CIFOP_SHRINK 5 -#define CIFOP_BLOAT 6 -#define CIFOP_SQUARES 7 -#define CIFOP_SLOTS 8 -#define CIFOP_BLOATMAX 9 -#define CIFOP_BLOATMIN 10 -#define CIFOP_BLOATALL 11 -#define CIFOP_ANDNOT 12 -#define CIFOP_SQUARES_G 13 -#define CIFOP_BBOX 14 -#define CIFOP_BOUNDARY 15 -#define CIFOP_NET 16 -#define CIFOP_MAXRECT 17 -#define CIFOP_COPYUP 18 -#define CIFOP_CLOSE 19 +#define CIFOP_GROWMIN 4 +#define CIFOP_GROW_G 5 +#define CIFOP_SHRINK 6 +#define CIFOP_BLOAT 7 +#define CIFOP_SQUARES 8 +#define CIFOP_SLOTS 9 +#define CIFOP_BLOATMAX 10 +#define CIFOP_BLOATMIN 11 +#define CIFOP_BLOATALL 12 +#define CIFOP_ANDNOT 13 +#define CIFOP_SQUARES_G 14 +#define CIFOP_BBOX 15 +#define CIFOP_BOUNDARY 16 +#define CIFOP_NET 17 +#define CIFOP_MAXRECT 18 +#define CIFOP_COPYUP 19 +#define CIFOP_CLOSE 20 /* Added by Tim 10/21/2004 */ /* The following structure is used to pass information on how to draw diff --git a/cif/CIFtech.c b/cif/CIFtech.c index af6af38e..9639ea00 100644 --- a/cif/CIFtech.c +++ b/cif/CIFtech.c @@ -1023,6 +1023,8 @@ CIFTechLine(sectionName, argc, argv) newOp->co_opcode = CIFOP_OR; else if (strcmp(argv[0], "grow") == 0) 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) newOp->co_opcode = CIFOP_GROW_G; else if (strcmp(argv[0], "shrink") == 0) @@ -1068,6 +1070,7 @@ CIFTechLine(sectionName, argc, argv) break; case CIFOP_GROW: + case CIFOP_GROWMIN: case CIFOP_GROW_G: case CIFOP_SHRINK: case CIFOP_CLOSE: @@ -1499,6 +1502,7 @@ cifComputeRadii(layer, des) case CIFOP_OR: break; case CIFOP_GROW: + case CIFOP_GROWMIN: case CIFOP_GROW_G: grow += op->co_distance; break; diff --git a/utils/maxrect.c b/utils/maxrect.c index 75a1f78a..7b7df302 100644 --- a/utils/maxrect.c +++ b/utils/maxrect.c @@ -234,6 +234,9 @@ FindMaxRects(tile, mrd) * example, from the router code to expand a point label into the * maximum size rectangular terminal. * + * If expandtypes is NULL, then searching is done over tiles that + * match by the ClientData record instead of types. + * * Results: * Pointer to a rectangle containing the maximum size area found. * This pointer should not be deallocated! @@ -290,7 +293,7 @@ FindMaxRectangle(bbox, startpoint, plane, expandtypes) * FindMaxRectangle2 --- * * This routine differs from FindMaxRectangle in passing a starting - * tile to the routine + * tile to the routine. * * Results: * Pointer to a rectangle containing the maximum size area found. @@ -300,10 +303,11 @@ FindMaxRectangle(bbox, startpoint, plane, expandtypes) */ Rect * -FindMaxRectangle2(bbox, starttile, plane) +FindMaxRectangle2(bbox, starttile, plane, expandtypes) Rect *bbox; /* bounding box of area searched */ Tile *starttile; /* use this tile to start */ Plane *plane; /* plane of types to expand */ + TileTypeBitMask *expandtypes; /* types to expand in, may be NULL */ { MaxRectsData *mrd; TileType tt; @@ -312,7 +316,7 @@ FindMaxRectangle2(bbox, starttile, plane) int s, sidx = -1; /* 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 */