From 1d8fcca09bdbfad1066b78c3a6ac9742043f7d13 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Thu, 6 Apr 2023 12:26:18 -0400 Subject: [PATCH] Implemented a change to differentiate between "sticky" labels and labels that are not connected to their declared layers. It's the latter type that need additional processing in ExtSubtree. Limiting this processing significantly cuts down on processing time when there are many labels in a layout, as happens with the "def read -labels" command option. --- VERSION | 2 +- database/database.h.in | 1 - extract/ExtSubtree.c | 61 +++++++++++++++++++++++++++++++++++++++++- 3 files changed, 61 insertions(+), 3 deletions(-) diff --git a/VERSION b/VERSION index 50da268e..18f2fc9b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.388 +8.3.389 diff --git a/database/database.h.in b/database/database.h.in index 477da56a..0981d485 100644 --- a/database/database.h.in +++ b/database/database.h.in @@ -305,7 +305,6 @@ typedef struct label #define PORT_VISITED 0x2000 /* Bit for checking if a port */ /* has been previously visited. */ - #define LABEL_STICKY 0x4000 /* Label does not change layers */ #define LABEL_GENERATE 0x8000 /* Auto-generated label */ diff --git a/extract/ExtSubtree.c b/extract/ExtSubtree.c index 08a03a48..3bd018c1 100644 --- a/extract/ExtSubtree.c +++ b/extract/ExtSubtree.c @@ -698,6 +698,26 @@ extSubtreeOutputCoupling(ha) } } +/* + * ---------------------------------------------------------------------------- + * + * extFoundProc --- + * + * Simple callback function that returns 1 when a tile is found during a + * plane area search. Used to determine if a label has incompatible material + * inside the label area. + * + * ---------------------------------------------------------------------------- + */ + +int +extFoundProc(tile, clientData) + Tile *tile; + ClientData clientData; +{ + return 1; +} + /* * ---------------------------------------------------------------------------- * @@ -782,17 +802,56 @@ extSubtreeFunc(scx, ha) // Copy any sticky labels to cumUse->cu_def, so that the labels // can be found even when there is no geometry underneath in // the parent cell. + // + // Update, 4/6/2023: Overuse of the sticky flag can make this + // ridiculously inefficient. The goal is to capture labels + // that don't have a layer underneath that is incompatible + // with the label type. Adding a simple search over the + // area of the label and the plane of the label layer. Only + // if the search finds nothing will the label be copied. CellDef *cumDef = ha->ha_cumFlat.et_lookNames; if (cumDef != NULL) { + Rect r; Label *lab, *newlab; unsigned int n; - for (lab = cumDef->cd_labels; lab ; lab = lab->lab_next) + for (lab = cumDef->cd_labels; lab; lab = lab->lab_next) { if (!(lab->lab_flags & LABEL_STICKY)) continue; + + r = lab->lab_rect; + GEOCLIP(&r, &ha->ha_interArea); + if (GEO_RECTNULL(&r)) continue; + + if (r.r_xbot == r.r_xtop) + { + if (r.r_ybot == r.r_ytop) + { + /* Quick solution for point labels--use GOTOPOINT + * instead of an area search. + */ + Plane *plane = cumDef->cd_planes[DBPlane(lab->lab_type)]; + Tile *tile = plane->pl_hint; + GOTOPOINT(tile, &r.r_ll); + if (TTMaskHasType(&DBConnectTbl[lab->lab_type], TiGetType(tile))) + continue; + } + r.r_xbot--; + r.r_xtop++; + } + if (r.r_ybot == r.r_ytop) + { + r.r_ybot--; + r.r_ytop++; + } + if (DBSrPaintArea((Tile *)NULL, + cumDef->cd_planes[DBPlane(lab->lab_type)], + &r, &DBNotConnectTbl[lab->lab_type], + extFoundProc, (ClientData)NULL) == 0) + continue; n = sizeof (Label) + strlen(lab->lab_text) - sizeof lab->lab_text + 1;