Substantially revised the equations for computing bridges for the

"bridge" GDS output operator;  the previous equations were, under
some situations, failing to meet the width requirement.  Also:
corrected the "cif style" check so that it does not claim that a
style name with an exact match is ambiguous.  Also:  Corrected the
use of "grid limit", so that the limit correctly scales with the
output expander value.
This commit is contained in:
Tim Edwards 2021-01-24 13:29:20 -05:00
parent 171287a131
commit dfba4601f1
4 changed files with 218 additions and 508 deletions

View File

@ -1 +1 @@
8.3.120
8.3.121

View File

@ -1299,8 +1299,6 @@ typedef struct _bridgeCheckStruct {
/* Direction flags */
#define BRIDGE_NW 1
#define BRIDGE_SW 2
#define BRIDGE_SE 3
#define BRIDGE_NE 4
/*
* ----------------------------------------------------------------------------
@ -1320,20 +1318,163 @@ GetEuclideanWidthGrid(width)
{
int weuclid;
int delta;
int limit;
limit = CIFCurStyle->cs_gridLimit * CIFCurStyle->cs_expander;
limit /= (CIFCurStyle->cs_flags & CWF_ANGSTROMS) ? 100 : 10;
weuclid = (int)(ceil((double)width * 0.70711));
if (CIFCurStyle && (CIFCurStyle->cs_gridLimit > 1))
if (CIFCurStyle && (limit > 1))
{
delta = weuclid % CIFCurStyle->cs_gridLimit;
delta = weuclid % limit;
if (delta > 0)
{
weuclid -= delta;
weuclid += CIFCurStyle->cs_gridLimit;
weuclid += limit;
}
}
return weuclid;
}
/*
* ----------------------------------------------------------------------------
*
* GetExpandedAreaGrid --
*
* Given a pointer "area" to a Rect and a minimum layer width "width",
* find the minimum size rectangle that expands "area" in all directions
* equally to ensure that the length of the diagonal of the expanded
* area is greater than or equal to "width". This is used by the
* "bridge" operator to ensure that the bridging rectangle meets the
* minimum layer width requirement.
*
* Results:
* None.
*
* Side effects:
* The Rect structure pointed to by "area" may be altered.
*
* Notes:
* The calculation needed depends on the geometry. If there is a
* horizontal gap between the tiles, then the bridging shape must
* be as tall as the minimum width rule; this is the vertical
* case (horiz = FALSE). If there is a vertical gap between the
* tiles, then the bridging shape must be as wide as the minimum
* width rule; this is the horizontal case (horiz = TRUE). Then
* calculate the length of the bridging shape in the other direction
* needed to ensure that the join of the bridging shape and the
* preexisting shapes is always wide enough to satisfy the width
* rule. Which calculation is needed depends on whether the shapes
* are catecorner (overlap = FALSE) or overlapping in one direction
* (overlap = TRUE).
*
* ----------------------------------------------------------------------------
*/
void
GetExpandedAreaGrid(wrule, space, area)
int wrule;
bool space;
Rect *area;
{
bool horiz;
bool overlap;
Rect r;
int width, height, dx, dy, a, b, delta, dx2, dy2, limit;
overlap = FALSE;
if (area->r_xbot > area->r_xtop)
{
overlap = TRUE;
horiz = (space) ? FALSE : TRUE;
}
if (area->r_ybot > area->r_ytop)
{
overlap = TRUE;
horiz = (space) ? TRUE : FALSE;
}
GeoCanonicalRect(area, &r);
width = r.r_xtop - r.r_xbot;
height = r.r_ytop - r.r_ybot;
if (overlap == FALSE)
horiz = (width > height);
if (horiz)
{
a = wrule - width;
dx = (int)ceilf((float)a / 2.0);
if (overlap || space)
b = wrule * wrule - (width + dx) * (width + dx);
else
b = wrule * wrule - dx * dx;
if (space && !overlap)
dy = (int)ceilf(sqrtf((float)b) - height);
else
dy = (int)ceilf(sqrtf((float)b));
b = wrule * wrule - width * width;
dy2 = (int)ceilf((sqrtf((float)b) - height) / 2.0);
if (dy2 > dy) dy = dy2;
}
else
{
a = wrule - height;
dy = (int)ceilf((float)a / 2.0);
if (overlap || space)
b = wrule * wrule - (height + dy) * (height + dy);
else
b = wrule * wrule - dy * dy;
if (space && !overlap)
dx = (int)ceilf(sqrtf((float)b) - width);
else
dx = (int)ceilf(sqrtf((float)b));
b = wrule * wrule - height * height;
dx2 = (int)ceilf((sqrtf((float)b) - width) / 2.0);
if (dx2 > dx) dx = dx2;
}
r.r_xbot -= dx;
r.r_xtop += dx;
r.r_ybot -= dy;
r.r_ytop += dy;
limit = CIFCurStyle->cs_gridLimit * CIFCurStyle->cs_expander;
limit /= (CIFCurStyle->cs_flags & CWF_ANGSTROMS) ? 100 : 10;
if (CIFCurStyle && (limit > 1))
{
delta = r.r_xbot % limit;
if (delta > 0)
r.r_xbot -= delta;
else if (delta < 0)
r.r_xbot -= limit + delta;
delta = r.r_xtop % limit;
if (delta > 0)
r.r_xtop += limit - delta;
else if (delta < 0)
r.r_xtop -= delta;
delta = r.r_ybot % limit;
if (delta > 0)
r.r_ybot -= delta;
else if (delta < 0)
r.r_ybot -= limit + delta;
delta = r.r_ytop % limit;
if (delta > 0)
r.r_ytop += limit - delta;
else if (delta < 0)
r.r_ytop -= delta;
}
*area = r;
}
/*
* ----------------------------------------------------------------------------
*
@ -1376,14 +1517,13 @@ cifBridgeFunc1(tile, brs)
Tile *tp1, *tp2, *tpx;
int width = brs->bridge->br_width;
int spacing = growDistance;
int weuclid;
BridgeCheckStruct brcs;
int cifBridgeCheckFunc(); /* Forward reference */
/* If tile is marked, then it has been handled, so ignore it */
if (tile->ti_client != (ClientData)CIF_UNPROCESSED) return 0;
/* Find each tile outside corner (up to four) */
/* Find each tile outside corner (only two cases need to be checked) */
/* Check for NE outside corner */
tp1 = TR(tile); /* Tile on right side at the top of this tile */
@ -1406,50 +1546,13 @@ cifBridgeFunc1(tile, brs)
&CIFSolidBits, cifBridgeCheckFunc, (ClientData)&brcs) == 1)
{
tpx = brcs.violator;
/* Resize box to satisfy width requirement on both ends */
weuclid = GetEuclideanWidthGrid(width);
area.r_xtop = MAX(RIGHT(tile), LEFT(tpx) + weuclid);
area.r_ytop = MAX(TOP(tile), BOTTOM(tpx) + weuclid);
area.r_xbot = RIGHT(tile);
area.r_ybot = TOP(tile);
area.r_xtop = LEFT(tpx);
area.r_ytop = BOTTOM(tpx);
area.r_xbot = MIN(LEFT(tpx), RIGHT(tile) - weuclid);
area.r_ybot = MIN(BOTTOM(tpx), TOP(tile) - weuclid);
/* Trivial implementation: fill box */
/* (to do: use stairstep to avoid filling unnecessary areas) */
DBPaintPlane(cifPlane, &area, CIFPaintTable, (PaintUndoInfo *) NULL);
}
}
/* Check for SW outside corner */
tp1 = BL(tile); /* Tile on left side at the bottom of this tile */
tp2 = LB(tile); /* Tile on bottom side at the left of this tile */
if ((TiGetRightType(tp1) == TT_SPACE) &&
(TiGetTopType(tp2) == TT_SPACE))
{
/* Set search box */
area.r_xbot = LEFT(tile) - spacing;
area.r_xtop = LEFT(tile) + width;
area.r_ybot = BOTTOM(tile) - spacing;
area.r_ytop = BOTTOM(tile) + width;
/* Find violator tiles */
brcs.tile = tile;
brcs.area = &area;
brcs.direction = BRIDGE_NE;
brcs.checktype = TT_SPACE;
if (DBSrPaintArea((Tile *) NULL, plane, &area,
&CIFSolidBits, cifBridgeCheckFunc, (ClientData)&brcs) == 1)
{
tpx = brcs.violator;
/* Resize box to satisfy width requirement on both ends */
weuclid = GetEuclideanWidthGrid(width);
area.r_xbot = MIN(LEFT(tile), RIGHT(tpx) - weuclid);
area.r_ybot = MIN(BOTTOM(tile), TOP(tpx) - weuclid);
area.r_xtop = MAX(RIGHT(tpx), LEFT(tile) + weuclid);
area.r_ytop = MAX(TOP(tpx), BOTTOM(tile) + weuclid);
GetExpandedAreaGrid(width, FALSE, &area);
/* Trivial implementation: fill box */
/* (to do: use stairstep to avoid filling unnecessary areas) */
@ -1478,57 +1581,19 @@ cifBridgeFunc1(tile, brs)
&CIFSolidBits, cifBridgeCheckFunc, (ClientData)&brcs) == 1)
{
tpx = brcs.violator;
/* Resize box to satisfy width requirement on both ends */
weuclid = GetEuclideanWidthGrid(width);
area.r_xtop = MAX(RIGHT(tile), LEFT(tpx) + weuclid);
area.r_ybot = MIN(BOTTOM(tile), TOP(tpx) - weuclid);
area.r_xbot = RIGHT(tile);
area.r_ybot = TOP(tpx);
area.r_xtop = LEFT(tpx);
area.r_ytop = BOTTOM(tile);
area.r_xbot = MIN(LEFT(tpx), RIGHT(tile) - weuclid);
area.r_ytop = MAX(TOP(tpx), BOTTOM(tile) + weuclid);
GetExpandedAreaGrid(width, FALSE, &area);
/* Trivial implementation: fill box */
/* (to do: use stairstep to avoid filling unnecessary areas) */
DBPaintPlane(cifPlane, &area, CIFPaintTable, (PaintUndoInfo *) NULL);
}
}
/* Check for NW outside corner */
for (tp1 = BL(tile); TOP(tp1) < TOP(tile); tp1 = RT(tp1));
for (tp2 = RT(tile); LEFT(tp1) > LEFT(tile); tp2 = BL(tp1));
if ((TiGetRightType(tp1) == TT_SPACE) &&
(TiGetBottomType(tp2) == TT_SPACE))
{
/* Set search box */
area.r_xbot = LEFT(tile) - spacing;
area.r_xtop = LEFT(tile) + width;
area.r_ybot = TOP(tile) - width;
area.r_ytop = TOP(tile) + spacing;
/* Find violator tiles */
brcs.tile = tile;
brcs.area = &area;
brcs.direction = BRIDGE_SE;
brcs.checktype = TT_SPACE;
if (DBSrPaintArea((Tile *) NULL, plane, &area,
&CIFSolidBits, cifBridgeCheckFunc, (ClientData)&brcs) == 1)
{
tpx = brcs.violator;
/* Resize box to satisfy width requirement on both ends */
weuclid = GetEuclideanWidthGrid(width);
area.r_xbot = MIN(LEFT(tile), RIGHT(tpx) - weuclid);
area.r_ytop = MAX(TOP(tile), BOTTOM(tpx) + weuclid);
area.r_xtop = MAX(RIGHT(tpx), LEFT(tile) + weuclid);
area.r_ybot = MIN(BOTTOM(tpx), TOP(tile) - weuclid);
/* Trivial implementation: fill box */
/* (to do: use stairstep to avoid filling unnecessary areas) */
DBPaintPlane(cifPlane, &area, CIFPaintTable, (PaintUndoInfo *) NULL);
}
}
return 0;
}
@ -1555,6 +1620,7 @@ SetMinBoxGrid(area, width)
int wtest;
int wtot;
int delta;
int limit;
wtest = (area->r_xtop - area->r_xbot);
wtot = area->r_xtop + area->r_xbot;
@ -1571,21 +1637,24 @@ SetMinBoxGrid(area, width)
area->r_ytop = (wtot + width) / 2;
}
if (CIFCurStyle && (CIFCurStyle->cs_gridLimit > 1))
limit = CIFCurStyle->cs_gridLimit * CIFCurStyle->cs_expander;
limit /= (CIFCurStyle->cs_flags & CWF_ANGSTROMS) ? 100 : 10;
if (CIFCurStyle && (limit > 1))
{
delta = abs(area->r_xbot) % CIFCurStyle->cs_gridLimit;
delta = abs(area->r_xbot) % limit;
if (delta > 0)
{
if (area->r_xbot < 0)
{
area->r_xbot += delta;
area->r_xbot -= CIFCurStyle->cs_gridLimit;
area->r_xbot -= limit;
}
else
area->r_xbot -= delta;
}
delta = abs(area->r_xtop) % CIFCurStyle->cs_gridLimit;
delta = abs(area->r_xtop) % limit;
if (delta > 0)
{
if (area->r_xtop < 0)
@ -1593,23 +1662,23 @@ SetMinBoxGrid(area, width)
else
{
area->r_xtop -= delta;
area->r_xtop += CIFCurStyle->cs_gridLimit;
area->r_xtop += limit;
}
}
delta = abs(area->r_ybot) % CIFCurStyle->cs_gridLimit;
delta = abs(area->r_ybot) % limit;
if (delta > 0)
{
if (area->r_ybot < 0)
{
area->r_ybot += delta;
area->r_ybot -= CIFCurStyle->cs_gridLimit;
area->r_ybot -= limit;
}
else
area->r_ybot -= delta;
}
delta = abs(area->r_ytop) % CIFCurStyle->cs_gridLimit;
delta = abs(area->r_ytop) % limit;
if (delta > 0)
{
if (area->r_ytop < 0)
@ -1617,7 +1686,7 @@ SetMinBoxGrid(area, width)
else
{
area->r_ytop -= delta;
area->r_ytop += CIFCurStyle->cs_gridLimit;
area->r_ytop += limit;
}
}
}
@ -1664,7 +1733,7 @@ cifBridgeFunc2(tile, brs)
Rect area;
Tile *tp1, *tp2, *tpx;
int width = brs->bridge->br_width;
int weuclid, wtest;
int wtest;
int spacing = growDistance;
BridgeCheckStruct brcs;
int cifBridgeCheckFunc(); /* Forward reference */
@ -1672,7 +1741,7 @@ cifBridgeFunc2(tile, brs)
/* If tile is marked, then it has been handled, so ignore it */
if (tile->ti_client != (ClientData)CIF_UNPROCESSED) return 0;
/* Find each tile outside corner (up to four) */
/* Find each tile outside corner (only two cases need to be checked) */
/* Check for NE outside corner */
tp1 = TR(tile); /* Tile on right side at the top of this tile */
@ -1690,61 +1759,18 @@ cifBridgeFunc2(tile, brs)
brcs.tile = tile;
brcs.area = &area;
brcs.direction = BRIDGE_SW;
brcs.checktype = TT_SPACE;
if (DBSrPaintArea((Tile *) NULL, plane, &area,
&DBSpaceBits, cifBridgeCheckFunc, (ClientData)&brcs) == 1)
{
tpx = brcs.violator;
/* Resize box to satisfy width requirement on both ends */
weuclid = GetEuclideanWidthGrid(width);
area.r_xbot = LEFT(tpx) - weuclid;
area.r_ytop = TOP(tile) + weuclid;
area.r_xtop = RIGHT(tile) + weuclid;
area.r_ybot = BOTTOM(tpx) - weuclid;
/* Box must meet width and height requirements */
SetMinBoxGrid(&area, width);
/* Trivial implementation: fill box */
/* (to do: use stairstep to avoid filling unnecessary areas) */
DBPaintPlane(cifPlane, &area, CIFPaintTable, (PaintUndoInfo *) NULL);
}
}
/* Check for SW outside corner */
tp1 = BL(tile); /* Tile on left side at the bottom of this tile */
tp2 = LB(tile); /* Tile on bottom side at the left of this tile */
if ((TiGetRightType(tp1) == CIF_SOLIDTYPE) &&
(TiGetTopType(tp2) == CIF_SOLIDTYPE))
{
/* Set search box */
area.r_xbot = LEFT(tile) - width;
area.r_xtop = LEFT(tile) + spacing;
area.r_ybot = BOTTOM(tile) - width;
area.r_ytop = BOTTOM(tile) + spacing;
/* Find violator tiles */
brcs.tile = tile;
brcs.area = &area;
brcs.direction = BRIDGE_NE;
brcs.checktype = CIF_SOLIDTYPE;
if (DBSrPaintArea((Tile *) NULL, plane, &area,
&DBSpaceBits, cifBridgeCheckFunc, (ClientData)&brcs) == 1)
{
tpx = brcs.violator;
/* Resize box to satisfy width requirement on both ends */
weuclid = GetEuclideanWidthGrid(width);
area.r_xbot = LEFT(tile) - weuclid;
area.r_ytop = TOP(tpx) + weuclid;
area.r_xbot = RIGHT(tile);
area.r_ybot = TOP(tile);
area.r_xtop = LEFT(tpx);
area.r_ytop = BOTTOM(tpx);
area.r_xtop = RIGHT(tpx) + weuclid;
area.r_ybot = BOTTOM(tile) - weuclid;
/* Box must meet width and height requirements */
SetMinBoxGrid(&area, width);
GetExpandedAreaGrid(width, TRUE, &area);
/* Trivial implementation: fill box */
/* (to do: use stairstep to avoid filling unnecessary areas) */
@ -1773,63 +1799,19 @@ cifBridgeFunc2(tile, brs)
&DBSpaceBits, cifBridgeCheckFunc, (ClientData)&brcs) == 1)
{
tpx = brcs.violator;
/* Resize box to satisfy width requirement on both ends */
weuclid = GetEuclideanWidthGrid(width);
area.r_xbot = LEFT(tpx) - weuclid;
area.r_ytop = TOP(tpx) + weuclid;
area.r_xbot = RIGHT(tile);
area.r_ybot = TOP(tpx);
area.r_xtop = LEFT(tpx);
area.r_ytop = BOTTOM(tile);
area.r_xtop = RIGHT(tile) + weuclid;
area.r_ybot = BOTTOM(tile) - weuclid;
/* Box must meet width and height requirements */
SetMinBoxGrid(&area, width);
GetExpandedAreaGrid(width, TRUE, &area);
/* Trivial implementation: fill box */
/* (to do: use stairstep to avoid filling unnecessary areas) */
DBPaintPlane(cifPlane, &area, CIFPaintTable, (PaintUndoInfo *) NULL);
}
}
/* Check for NW outside corner */
for (tp1 = BL(tile); TOP(tp1) < TOP(tile); tp1 = RT(tp1));
for (tp2 = RT(tile); LEFT(tp2) > LEFT(tile); tp2 = BL(tp2));
if ((TiGetRightType(tp1) == CIF_SOLIDTYPE) &&
(TiGetBottomType(tp2) == CIF_SOLIDTYPE))
{
/* Set search box */
area.r_xbot = LEFT(tile) - width;
area.r_xtop = LEFT(tile) + spacing;
area.r_ybot = TOP(tile) - spacing;
area.r_ytop = TOP(tile) + width;
/* Find violator tiles */
brcs.tile = tile;
brcs.area = &area;
brcs.direction = BRIDGE_SE;
brcs.checktype = CIF_SOLIDTYPE;
if (DBSrPaintArea((Tile *) NULL, plane, &area,
&DBSpaceBits, cifBridgeCheckFunc, (ClientData)&brcs) == 1)
{
tpx = brcs.violator;
weuclid = GetEuclideanWidthGrid(width);
/* Resize box to satisfy width requirement on both ends */
area.r_xbot = LEFT(tile) - weuclid;
area.r_ytop = TOP(tile) + weuclid;
area.r_xtop = RIGHT(tpx) + weuclid;
area.r_ybot = BOTTOM(tpx) - weuclid;
/* Box must meet width and height requirements */
SetMinBoxGrid(&area, width);
/* Trivial implementation: fill box */
/* (to do: use stairstep to avoid filling unnecessary areas) */
DBPaintPlane(cifPlane, &area, CIFPaintTable, (PaintUndoInfo *) NULL);
}
}
return 0;
}
@ -1871,22 +1853,6 @@ cifBridgeCheckFunc(tile, brcs)
return 1; /* Violator found */
}
break;
case BRIDGE_NE:
/* Ignore tile if NE corner is not in the search area */
if (RIGHT(tile) >= brcs->area->r_xtop || TOP(tile) >= brcs->area->r_ytop)
break;
/* Ignore tile if split, and SW corner is clipped */
if (TiGetLeftType(tile) == checktype || TiGetBottomType(tile) == checktype)
break;
tp1 = RT(tile);
tp2 = TR(tile);
if ((TiGetBottomType(tp1) == checktype) &&
(TiGetLeftType(tp2) == checktype))
{
brcs->violator = tile;
return 1; /* Violator found */
}
break;
case BRIDGE_SW:
/* Ignore tile if SW corner is not in the search area */
if (LEFT(tile) <= brcs->area->r_xbot || BOTTOM(tile) <= brcs->area->r_ybot)
@ -1896,29 +1862,13 @@ cifBridgeCheckFunc(tile, brcs)
break;
tp1 = LB(tile);
tp2 = BL(tile);
if ((TiGetTopType(tp1) == checktype) &&
if ((TiGetTopType(tp1) == checktype) ||
(TiGetRightType(tp2) == checktype))
{
brcs->violator = tile;
return 1; /* Violator found */
}
break;
case BRIDGE_SE:
/* Ignore tile if SE corner is not in the search area */
if (RIGHT(tile) >= brcs->area->r_xtop || BOTTOM(tile) <= brcs->area->r_ybot)
break;
/* Ignore tile if split, and NW corner is clipped */
if (TiGetLeftType(tile) == checktype || TiGetTopType(tile) == checktype)
break;
for (tp1 = LB(tile); RIGHT(tp1) < RIGHT(tile); tp1 = TR(tp1));
for (tp2 = TR(tile); BOTTOM(tp2) > BOTTOM(tile); tp2 = LB(tp2));
if ((TiGetTopType(tp1) == checktype) &&
(TiGetLeftType(tp2) == checktype))
{
brcs->violator = tile;
return 1; /* Violator found */
}
break;
}
return 0; /* Nothing found here, so keep going */
}
@ -3422,7 +3372,7 @@ cifSlotFunc(area, op, numY, numX, cut, vertical)
Rect *cut; /* initial (lower left) cut area */
bool vertical; /* if TRUE, slot is aligned vertically */
{
int i, j, xpitch, ypitch, delta;
int i, j, xpitch, ypitch, delta, limit;
int *axtop, *axbot, *aytop, *aybot;
int *sxtop, *sxbot, *sytop, *sybot;
int *rows, *columns;
@ -3475,9 +3425,12 @@ calcX:
/* Check that we are not violating any gridlimit */
if (CIFCurStyle && (CIFCurStyle->cs_gridLimit > 1))
limit = CIFCurStyle->cs_gridLimit * CIFCurStyle->cs_expander;
limit /= (CIFCurStyle->cs_flags & CWF_ANGSTROMS) ? 100 : 10;
if (CIFCurStyle && (limit > 1))
{
delta = abs(*sxbot) % CIFCurStyle->cs_gridLimit;
delta = abs(*sxbot) % limit;
if (delta > 0)
{
if (*sxbot >= 0)
@ -3505,9 +3458,9 @@ calcY:
/* Check that we are not violating any gridlimit */
if (CIFCurStyle && (CIFCurStyle->cs_gridLimit > 1))
if (CIFCurStyle && (limit > 1))
{
delta = abs(*sybot) % CIFCurStyle->cs_gridLimit;
delta = abs(*sybot) % limit;
if (delta > 0)
{
if (*sybot >= 0)
@ -3558,11 +3511,14 @@ cifSquareFunc(area, op, rows, columns, cut)
int *rows, *columns; /* Return values: # rows and # columns, */
Rect *cut; /* initial (lower left) cut area. */
{
int pitch, delta;
int pitch, delta, limit;
bool glimit;
SquaresData *squares = (SquaresData *)op->co_client;
glimit = (CIFCurStyle && (CIFCurStyle->cs_gridLimit > 1)) ? TRUE : FALSE;
limit = CIFCurStyle->cs_gridLimit * CIFCurStyle->cs_expander;
limit /= (CIFCurStyle->cs_flags & CWF_ANGSTROMS) ? 100 : 10;
glimit = (CIFCurStyle && (limit > 1)) ? TRUE : FALSE;
pitch = squares->sq_size + squares->sq_sep;
/* Compute the real border to leave around the sides. If only
@ -3602,7 +3558,7 @@ sqX:
if (glimit)
{
delta = abs(cut->r_xbot) % CIFCurStyle->cs_gridLimit;
delta = abs(cut->r_xbot) % limit;
if (delta > 0)
{
area->r_xtop -= 2 * delta;
@ -3630,7 +3586,7 @@ sqY:
if (glimit)
{
delta = abs(cut->r_ybot) % CIFCurStyle->cs_gridLimit;
delta = abs(cut->r_ybot) % limit;
if (delta > 0)
{
area->r_ytop -= 2 * delta;
@ -4013,6 +3969,7 @@ bridgeLimCheckFunc(tile, brlimcs)
switch (dir) {
case BRIDGE_NW:
/* Ignore tile if split, and SE corner is clipped */
if (IsSplit(tile))
if (TiGetRightType(tile) == checktype || TiGetBottomType(tile) == checktype)
break;
for (tp1 = RT(tile); LEFT(tp1) > LEFT(tile); tp1 = BL(tp1));
@ -4032,29 +3989,9 @@ bridgeLimCheckFunc(tile, brlimcs)
return 1; /* Violator found */
}
break;
case BRIDGE_NE:
/* Ignore tile if split, and SW corner is clipped */
if (TiGetLeftType(tile) == checktype || TiGetBottomType(tile) == checktype)
break;
tp1 = RT(tile);
tp2 = TR(tile);
if ((TiGetBottomType(tp1) == checktype) &&
(TiGetLeftType(tp2) == checktype))
{
dx = LEFT(self) - RIGHT(tile);
dy = BOTTOM(self) - TOP(tile);
if ((dx > 0) && (dy > 0))
{
sqcheck = (long)dx*dx + (long)dy*dy;
if (sqcheck >= sqdistance)
return 0;
}
brlimcs->violator = tile;
return 1; /* Violator found */
}
break;
case BRIDGE_SW:
/* Ignore tile if split, and NE corner is clipped */
if (IsSplit(tile))
if (TiGetRightType(tile) == checktype || TiGetTopType(tile) == checktype)
break;
tp1 = LB(tile);
@ -4074,27 +4011,6 @@ bridgeLimCheckFunc(tile, brlimcs)
return 1; /* Violator found */
}
break;
case BRIDGE_SE:
/* Ignore tile if split, and NW corner is clipped */
if (TiGetLeftType(tile) == checktype || TiGetTopType(tile) == checktype)
break;
for (tp1 = LB(tile); RIGHT(tp1) < RIGHT(tile); tp1 = TR(tp1));
for (tp2 = TR(tile); BOTTOM(tp2) > BOTTOM(tile); tp2 = LB(tp2));
if ((TiGetTopType(tp1) == checktype) &&
(TiGetLeftType(tp2) == checktype))
{
dx = LEFT(self) - RIGHT(tile);
dy = BOTTOM(tile) - TOP(self);
if ((dx > 0) && (dy > 0))
{
sqcheck = (long)dx*dx + (long)dy*dy;
if (sqcheck >= sqdistance)
return 0;
}
brlimcs->violator = tile;
return 1; /* Violator found */
}
break;
}
return 0; /* Nothing found here, so keep going */
}
@ -4229,68 +4145,6 @@ cifBridgeLimFunc1(tile, brlims)
}
}
/* Check for SW outside corner */
tp1 = BL(tile); /* Tile on left side at the bottom of this tile */
tp2 = LB(tile); /* Tile on bottom side at the left of this tile */
if ((TiGetRightType(tp1) == TT_SPACE) &&
(TiGetTopType(tp2) == TT_SPACE))
{
/* Set search box */
area.r_xbot = LEFT(tile) - spacing;
area.r_xtop = LEFT(tile);
area.r_ybot = BOTTOM(tile) - spacing;
area.r_ytop = BOTTOM(tile);
/* Find violator tiles */
brlimcs.tile = tile;
brlimcs.direction = BRIDGE_NE;
brlimcs.checktype = TT_SPACE;
if (DBSrPaintArea((Tile *) NULL, plane, &area,
&CIFSolidBits, bridgeLimCheckFunc, (ClientData)&brlimcs) == 1)
{
tpx = brlimcs.violator;
area.r_xtop = MAX(RIGHT(tpx), LEFT(tile) + width);
area.r_ytop = MAX(TOP(tpx), BOTTOM(tile));
area.r_xbot = MIN(LEFT(tile), RIGHT(tpx));
area.r_ybot = MIN(BOTTOM(tile), TOP(tpx) - width);
if (bridgeLimSrTiles(brlims, &area, FALSE))
{
/* First option of bridge can be implemented (there are not limiting tiles in the area)*/
area.r_ytop = TOP(tpx);
DBPaintPlane(cifPlane, &area, CIFPaintTable, (PaintUndoInfo *) NULL);
area.r_xbot = LEFT(tile);
area.r_ytop = MAX(TOP(tpx), BOTTOM(tile));
DBPaintPlane(cifPlane, &area, CIFPaintTable, (PaintUndoInfo *) NULL);
}
else
{
area.r_xtop = MAX(RIGHT(tpx), LEFT(tile));
area.r_ytop = MAX(TOP(tpx), BOTTOM(tile) + width);
area.r_xbot = MIN(LEFT(tile), RIGHT(tpx) - width);
area.r_ybot = MIN(BOTTOM(tile), TOP(tpx));
if (bridgeLimSrTiles(brlims, &area, FALSE))
{
/* Second option of bridge can be implemented (there are not limiting tiles in the area)*/
area.r_ybot = BOTTOM(tile);
DBPaintPlane(cifPlane, &area, CIFPaintTable, (PaintUndoInfo *) NULL);
area.r_xtop = RIGHT(tpx);
area.r_ybot = MIN(BOTTOM(tile), TOP(tpx));
DBPaintPlane(cifPlane, &area, CIFPaintTable, (PaintUndoInfo *) NULL);
}
else
{
/* Last option (Limiting tiles are present on both sides, those areas must be excluded from the bridge)*/
area.r_xtop = MAX(RIGHT(tpx), LEFT(tile) + width);
area.r_ytop = MAX(TOP(tpx), BOTTOM(tile) + width);
area.r_xbot = MIN(LEFT(tile), RIGHT(tpx) - width);
area.r_ybot = MIN(BOTTOM(tile), TOP(tpx) - width);
DBPaintPlane(cifPlane, &area, CIFPaintTable, (PaintUndoInfo *) NULL);
bridgeErase(brlims, &area);
}
}
}
}
/* Check for SE outside corner */
for (tp1 = TR(tile); BOTTOM(tp1) > BOTTOM(tile); tp1 = LB(tp1));
for (tp2 = LB(tile); RIGHT(tp1) < RIGHT(tile); tp2 = TR(tp2));
@ -4353,68 +4207,6 @@ cifBridgeLimFunc1(tile, brlims)
}
}
/* Check for NW outside corner */
for (tp1 = BL(tile); TOP(tp1) < TOP(tile); tp1 = RT(tp1));
for (tp2 = RT(tile); LEFT(tp1) > LEFT(tile); tp2 = BL(tp1));
if ((TiGetRightType(tp1) == TT_SPACE) &&
(TiGetBottomType(tp2) == TT_SPACE))
{
/* Set search box */
area.r_xbot = LEFT(tile) - spacing;
area.r_xtop = LEFT(tile);
area.r_ybot = TOP(tile);
area.r_ytop = TOP(tile) + spacing;
/* Find violator tiles */
brlimcs.tile = tile;
brlimcs.direction = BRIDGE_SE;
brlimcs.checktype = TT_SPACE;
if (DBSrPaintArea((Tile *) NULL, plane, &area,
&CIFSolidBits, bridgeLimCheckFunc, (ClientData)&brlimcs) == 1)
{
tpx = brlimcs.violator;
area.r_xtop = MAX(RIGHT(tpx), LEFT(tile));
area.r_ybot = MIN(BOTTOM(tpx), TOP(tile) - width);
area.r_xbot = MIN(LEFT(tile), RIGHT(tpx) - width);
area.r_ytop = MAX(TOP(tile), BOTTOM(tpx));
if (bridgeLimSrTiles(brlims, &area, FALSE))
{
/* First option of bridge can be implemented (there are not limiting tiles in the area)*/
area.r_xtop = RIGHT(tpx);
DBPaintPlane(cifPlane, &area, CIFPaintTable, (PaintUndoInfo *) NULL);
area.r_xtop = MAX(RIGHT(tpx), LEFT(tile));
area.r_ytop = TOP(tile);
DBPaintPlane(cifPlane, &area, CIFPaintTable, (PaintUndoInfo *) NULL);
}
else
{
area.r_xtop = MAX(RIGHT(tpx), LEFT(tile) + width);
area.r_ybot = MIN(BOTTOM(tpx), TOP(tile));
area.r_xbot = MIN(LEFT(tile), RIGHT(tpx));
area.r_ytop = MAX(TOP(tile), BOTTOM(tpx) + width);
if (bridgeLimSrTiles(brlims, &area, FALSE))
{
/* Second option of bridge can be implemented (there are not limiting tiles in the area)*/
area.r_xbot = LEFT(tile);
DBPaintPlane(cifPlane, &area, CIFPaintTable, (PaintUndoInfo *) NULL);
area.r_xbot = MIN(LEFT(tile), RIGHT(tpx));
area.r_ybot = BOTTOM(tpx);
DBPaintPlane(cifPlane, &area, CIFPaintTable, (PaintUndoInfo *) NULL);
}
else
{
/* Last option (Limiting tiles are present on both sides, those areas must be excluded from the bridge)*/
area.r_xtop = MAX(RIGHT(tpx), LEFT(tile) + width);
area.r_ybot = MIN(BOTTOM(tpx), TOP(tile) - width);
area.r_xbot = MIN(LEFT(tile), RIGHT(tpx) - width);
area.r_ytop = MAX(TOP(tile), BOTTOM(tpx) + width);
DBPaintPlane(cifPlane, &area, CIFPaintTable, (PaintUndoInfo *) NULL);
bridgeErase(brlims, &area);
}
}
}
}
return 0;
}
@ -4498,51 +4290,6 @@ cifBridgeLimFunc2(tile, brlims)
}
}
/* Check for SW outside corner */
tp1 = BL(tile); /* Tile on left side at the bottom of this tile */
tp2 = LB(tile); /* Tile on bottom side at the left of this tile */
if ((TiGetRightType(tp1) == CIF_SOLIDTYPE) &&
(TiGetTopType(tp2) == CIF_SOLIDTYPE))
{
/* Set search box */
area.r_xbot = LEFT(tile) - width;
area.r_xtop = LEFT(tile);
area.r_ybot = BOTTOM(tile) - width;
area.r_ytop = BOTTOM(tile);
/* Find violator tiles */
brlimcs.tile = tile;
brlimcs.direction = BRIDGE_NE;
brlimcs.checktype = CIF_SOLIDTYPE;
if (DBSrPaintArea((Tile *) NULL, plane, &area,
&DBSpaceBits, bridgeLimCheckFunc, (ClientData)&brlimcs) == 1)
{
tpx = brlimcs.violator;
area.r_xtop = RIGHT(tpx);
area.r_ytop = TOP(tpx);
area.r_xbot = LEFT(tile) - width;
area.r_ybot = BOTTOM(tile) - width;
thirdOption = 0;
if (!bridgeLimSrTiles(brlims, &area, FALSE))
{
area.r_xtop = RIGHT(tpx) + width;
area.r_ytop = TOP(tpx) + width;
area.r_xbot = LEFT(tile);
area.r_ybot = BOTTOM(tile);
if (!bridgeLimSrTiles(brlims, &area, FALSE))
{
area.r_xbot = LEFT(tile) - width;
area.r_ybot = BOTTOM(tile) - width;
thirdOption = 1;
}
}
DBPaintPlane(cifPlane, &area, CIFPaintTable, (PaintUndoInfo *) NULL);
if (thirdOption)
bridgeErase(brlims, &area);
}
}
/* Check for SE outside corner */
for (tp1 = TR(tile); BOTTOM(tp1) > BOTTOM(tile); tp1 = LB(tp1));
for (tp2 = LB(tile); RIGHT(tp2) < RIGHT(tile); tp2 = TR(tp2));
@ -4588,51 +4335,6 @@ cifBridgeLimFunc2(tile, brlims)
}
}
/* Check for NW outside corner */
for (tp1 = BL(tile); TOP(tp1) < TOP(tile); tp1 = RT(tp1));
for (tp2 = RT(tile); LEFT(tp2) > LEFT(tile); tp2 = BL(tp2));
if ((TiGetRightType(tp1) == CIF_SOLIDTYPE) &&
(TiGetBottomType(tp2) == CIF_SOLIDTYPE))
{
/* Set search box */
area.r_xbot = LEFT(tile) - width;
area.r_xtop = LEFT(tile);
area.r_ybot = TOP(tile);
area.r_ytop = TOP(tile) + width;
/* Find violator tiles */
brlimcs.tile = tile;
brlimcs.direction = BRIDGE_SE;
brlimcs.checktype = CIF_SOLIDTYPE;
if (DBSrPaintArea((Tile *) NULL, plane, &area,
&DBSpaceBits, bridgeLimCheckFunc, (ClientData)&brlimcs) == 1)
{
tpx = brlimcs.violator;
area.r_xtop = RIGHT(tpx) + width;
area.r_ytop = TOP(tile);
area.r_xbot = LEFT(tile);
area.r_ybot = BOTTOM(tpx) - width;
thirdOption = 0;
if (!bridgeLimSrTiles(brlims, &area, FALSE))
{
area.r_xtop = RIGHT(tpx);
area.r_ytop = TOP(tile) + width;
area.r_xbot = LEFT(tile) - width;
area.r_ybot = BOTTOM(tpx);
if (!bridgeLimSrTiles(brlims, &area, FALSE))
{
area.r_xtop = RIGHT(tpx) + width;
area.r_ybot = BOTTOM(tpx) - width;
thirdOption = 1;
}
}
DBPaintPlane(cifPlane, &area, CIFPaintTable, (PaintUndoInfo *) NULL);
if (thirdOption)
bridgeErase(brlims, &area);
}
}
return 0;
}

View File

@ -259,7 +259,8 @@ CIFSetStyle(name)
* print out the valid styles.
*/
{
CIFKeep *style, *match;
CIFKeep *style, *match, *exactmatch;
bool ambiguous = FALSE;
int length;
if (name == NULL) return;
@ -269,18 +270,25 @@ CIFSetStyle(name)
for (style = CIFStyleList; style != NULL; style = style->cs_next)
{
if (strncmp(name, style->cs_name, length) == 0)
if (!strcmp(name, style->cs_name)) {
match = style;
ambiguous = FALSE;
break;
}
else if (!strncmp(name, style->cs_name, length))
{
if (match != NULL)
{
TxError("CIF output style \"%s\" is ambiguous.\n", name);
CIFPrintStyle(FALSE, TRUE, TRUE);
return;
}
if (match != NULL) ambiguous = TRUE;
match = style;
}
}
if (ambiguous)
{
TxError("CIF output style \"%s\" is ambiguous.\n", name);
CIFPrintStyle(FALSE, TRUE, TRUE);
return;
}
if (match != NULL)
{
CIFLoadStyle(match->cs_name);

View File

@ -2437,7 +2437,7 @@ CIFTechOutputScale(n, d)
/* Reduce the scale and all distances by the greatest common */
/* factor of everything. */
/* fprintf(stderr, "All CIF units divisible by %d\n", lexpand); */
/* fprintf(stderr, "All CIF units divisible by %d\n", lexpand); */
/* fflush(stderr); */
lgcf = FindGCF(ostyle->cs_scaleFactor, ostyle->cs_expander);