Modified the routine for the cif-output "bloat-all <dist>" operator
to make it slightly more efficient. Noting, however, that it is still highly inefficient relative to the stepped "grow" + "and" (or "and-not") operators that it was supposed to replace, I also implemented a convenience function "repeat <steps>" ... "endrepeat" to the tech file syntax. This allows the "grow" + "and" series to be defined with a few lines, whereas if the steps have to be spelled out, the series can be scores or hundreds of lines long.
This commit is contained in:
parent
f3478cba7b
commit
ecd6ec56ae
47
cif/CIFgen.c
47
cif/CIFgen.c
|
|
@ -1500,6 +1500,7 @@ cifBloatAllFunc(
|
|||
|
||||
while (!StackEmpty(BloatStack))
|
||||
{
|
||||
Rect cifarea;
|
||||
TileType tt;
|
||||
|
||||
POPTILE(t, dinfo, BloatStack);
|
||||
|
|
@ -1516,8 +1517,6 @@ cifBloatAllFunc(
|
|||
|
||||
if (op->co_distance > 0)
|
||||
{
|
||||
Rect cifarea;
|
||||
|
||||
cifarea.r_xbot = area.r_xbot;
|
||||
cifarea.r_ybot = area.r_ybot;
|
||||
cifarea.r_xtop = area.r_xtop;
|
||||
|
|
@ -1555,40 +1554,42 @@ cifBloatAllFunc(
|
|||
{
|
||||
tt = TiGetTypeExact(t);
|
||||
if (op->co_distance > 0)
|
||||
GeoClip(&area, &clipArea);
|
||||
DBNMPaintPlane(cifPlane, TiGetTypeExact(t), &area,
|
||||
DBNMPaintPlane(cifPlane, TiGetTypeExact(t), &cifarea,
|
||||
CIFPaintTable, (PaintUndoInfo *) NULL);
|
||||
else
|
||||
DBNMPaintPlane(cifPlane, TiGetTypeExact(t), &area,
|
||||
CIFPaintTable, (PaintUndoInfo *) NULL);
|
||||
}
|
||||
|
||||
/* Top */
|
||||
for (tp = RT(t); RIGHT(tp) > LEFT(t); tp = BL(tp))
|
||||
if (TTMaskHasType(connect, TiGetBottomType(tp)))
|
||||
PUSHTILE(tp,
|
||||
(SplitDirection(tp) == ((tt & TT_DIRECTION) ? 1 : 0)) ?
|
||||
(TileType)0 : (TileType)TT_SIDE,
|
||||
BloatStack);
|
||||
if ((op->co_distance == 0) || (area.r_ytop < clipArea.r_ytop))
|
||||
for (tp = RT(t); RIGHT(tp) > LEFT(t); tp = BL(tp))
|
||||
if (TTMaskHasType(connect, TiGetBottomType(tp)))
|
||||
PUSHTILE(tp, (SplitDirection(tp) == ((tt & TT_DIRECTION) ? 1 : 0)) ?
|
||||
(TileType)0 : (TileType)TT_SIDE, BloatStack);
|
||||
|
||||
/* Left */
|
||||
for (tp = BL(t); BOTTOM(tp) < TOP(t); tp = RT(tp))
|
||||
if (TTMaskHasType(connect, TiGetRightType(tp)))
|
||||
PUSHTILE(tp, (TileType)TT_SIDE, BloatStack);
|
||||
if ((op->co_distance == 0) || (area.r_xbot > clipArea.r_xbot))
|
||||
for (tp = BL(t); BOTTOM(tp) < TOP(t); tp = RT(tp))
|
||||
if (TTMaskHasType(connect, TiGetRightType(tp)))
|
||||
PUSHTILE(tp, (TileType)TT_SIDE, BloatStack);
|
||||
|
||||
/* Bottom */
|
||||
for (tp = LB(t); LEFT(tp) < RIGHT(t); tp = TR(tp))
|
||||
if (TTMaskHasType(connect, TiGetTopType(tp)))
|
||||
PUSHTILE(tp,
|
||||
(SplitDirection(tp) == ((tt & TT_DIRECTION) ? 1 : 0)) ?
|
||||
(TileType)TT_SIDE : (TileType)0,
|
||||
BloatStack);
|
||||
if ((op->co_distance == 0) || (area.r_ybot > clipArea.r_ybot))
|
||||
for (tp = LB(t); LEFT(tp) < RIGHT(t); tp = TR(tp))
|
||||
if (TTMaskHasType(connect, TiGetTopType(tp)))
|
||||
PUSHTILE(tp, (SplitDirection(tp) == ((tt & TT_DIRECTION) ? 1 : 0)) ?
|
||||
(TileType)TT_SIDE : (TileType)0, BloatStack);
|
||||
|
||||
/* Right */
|
||||
for (tp = TR(t); TOP(tp) > BOTTOM(t); tp = LB(tp))
|
||||
if (TTMaskHasType(connect, TiGetLeftType(tp)))
|
||||
PUSHTILE(tp, (TileType)0, BloatStack);
|
||||
if ((op->co_distance == 0) || (area.r_xtop < clipArea.r_xtop))
|
||||
for (tp = TR(t); TOP(tp) > BOTTOM(t); tp = LB(tp))
|
||||
if (TTMaskHasType(connect, TiGetLeftType(tp)))
|
||||
PUSHTILE(tp, (TileType)0, BloatStack);
|
||||
}
|
||||
|
||||
/* Clear self */
|
||||
TiSetClient(tile, CIF_UNPROCESSED);
|
||||
// TiSetClient(tile, CIF_UNPROCESSED);
|
||||
|
||||
/* NOTE: Tiles must be cleared after the bloat-all function has
|
||||
* completed. However, for bloat-all with a limiting distance,
|
||||
|
|
|
|||
28
utils/tech.c
28
utils/tech.c
|
|
@ -432,7 +432,8 @@ TechLoad(filename, initmask)
|
|||
char suffix[20], line[MAXLINESIZE], *realname;
|
||||
char *argv[MAXARGS];
|
||||
SectionID mask, badMask;
|
||||
int argc, s;
|
||||
int argc, s, repeatcount = 0;
|
||||
off_t repeatpos;
|
||||
bool retval, skip;
|
||||
filestack *fstack, *newstack;
|
||||
filestack topfile;
|
||||
|
|
@ -603,6 +604,31 @@ TechLoad(filename, initmask)
|
|||
skip = FALSE;
|
||||
while ((argc = techGetTokens(line, sizeof line, &fstack, argv)) >= 0)
|
||||
{
|
||||
/* Check for end-of-loop */
|
||||
if ((argc == 1) && (!strcmp(argv[0], "endrepeat")))
|
||||
{
|
||||
if (repeatcount > 0)
|
||||
{
|
||||
repeatcount--;
|
||||
fseek(fstack->file, repeatpos, SEEK_SET);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
/* "repeat <number>" reads the lines until "endrepeat" <number> times */
|
||||
else if ((argc == 2) && (!strcmp(argv[0], "repeat")))
|
||||
{
|
||||
char *endptr;
|
||||
repeatcount = (off_t)strtol(argv[1], &endptr, 0);
|
||||
if (*endptr != '\0')
|
||||
{
|
||||
TechError("Error: \"repeat\" with invalid count %s\n", argv[1]);
|
||||
repeatcount = 0;
|
||||
}
|
||||
else
|
||||
repeatpos = ftell(fstack->file);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check for file inclusions (can be nested) */
|
||||
if ((argc > 1) && (!strcmp(argv[0], "include")))
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue