From b90166985d50b1dbda40cf370fd258c4637e77a3 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Mon, 25 Nov 2019 11:07:59 -0500 Subject: [PATCH 1/3] Corrected an error in the dual CIF style (output & drc) method where the output style is not set back to what it was before if there are no cif rules in the default DRC style. --- drc/DRCcif.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drc/DRCcif.c b/drc/DRCcif.c index 9031ea4c..3a4a4bbd 100644 --- a/drc/DRCcif.c +++ b/drc/DRCcif.c @@ -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; From 1fe128a405a4b975d3b88fe775f69e7982022191 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Mon, 25 Nov 2019 15:14:41 -0500 Subject: [PATCH 2/3] Implemented new CIF operator "close", in the syntax "close ", which takes the existing generated CIF plane, finds all enclosed areas that have an area less than , and fills them in. This satisfies a minimum hole area rule in a way that is not possible with any of the existing CIF operators. --- cif/CIFgen.c | 140 +++++++++++++++++++++++++++++++++++++++++++++++++- cif/CIFint.h | 2 + cif/CIFtech.c | 3 ++ 3 files changed, 144 insertions(+), 1 deletion(-) diff --git a/cif/CIFgen.c b/cif/CIFgen.c index 6de88309..1316f1fd 100644 --- a/cif/CIFgen.c +++ b/cif/CIFgen.c @@ -514,7 +514,7 @@ cifGrowFunc(tile, table) CIFTileOps += 1; return 0; } - + /* * ---------------------------------------------------------------------------- * @@ -1049,6 +1049,128 @@ 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; + 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)) + *atotal += (area.r_xtop - area.r_xbot) * (area.r_ytop - area.r_ybot); + } + 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 +3150,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, diff --git a/cif/CIFint.h b/cif/CIFint.h index 157a3cff..d08c0ba1 100644 --- a/cif/CIFint.h +++ b/cif/CIFint.h @@ -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 diff --git a/cif/CIFtech.c b/cif/CIFtech.c index 2040bc7f..af6af38e 100644 --- a/cif/CIFtech.c +++ b/cif/CIFtech.c @@ -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) From 46eefe8c33ef35ef4ae7fe66b72e4d3a67acac51 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Mon, 25 Nov 2019 16:37:03 -0500 Subject: [PATCH 3/3] Small correction on the last commit to avoid an integer overflow error on large areas (need type dlong to encode areas in internal units). --- cif/CIFgen.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/cif/CIFgen.c b/cif/CIFgen.c index 1316f1fd..4381742b 100644 --- a/cif/CIFgen.c +++ b/cif/CIFgen.c @@ -1109,6 +1109,7 @@ cifGatherFunc(tile, atotal, mode) { Tile *tp; TileType type; + dlong locarea; Rect area, newarea; ClientData cdata = (mode == CLOSE_SEARCH) ? (ClientData)CIF_UNPROCESSED : (ClientData)CIF_PENDING; @@ -1130,7 +1131,12 @@ cifGatherFunc(tile, atotal, mode) if (mode == CLOSE_SEARCH) { if ((*atotal != INFINITY) && (*atotal < growDistance)) - *atotal += (area.r_xtop - area.r_xbot) * (area.r_ytop - area.r_ybot); + 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) {