Solved three issues:

(1) There was still one place that dimensional units were not being
    printed, which was "setlabel", with both "setlabel size" and
    "setlabel offset".  This has been fixed.
(2) Fixing (1) surfaced an error in the text helper dialog, which was
    not setting units properly when checking the size and offset entries.
(3) Fixed a very long-standing problem in which port labels were showing
    up with the "pale" style of a subcell's label being drawn on top
    when the parent and child had the same label in exactly the same
    position.  This was due to a parent-first search resulting in the
    child cell being visited last, so its "pale" style label being drawn
    last.  Added a flag for label searches for display to reverse the
    search order, visiting children first and then the parent, so that
    the top cell's labels are the last to be drawn.
This commit is contained in:
R. Timothy Edwards 2026-04-01 21:17:54 -04:00
parent 06eab7feb6
commit 05561b90f3
6 changed files with 127 additions and 54 deletions

View File

@ -1 +1 @@
8.3.629 8.3.630

View File

@ -1801,13 +1801,18 @@ cmdLabelSizeFunc(
if (value == NULL) if (value == NULL)
{ {
char *labsize;
MagWindow *w;
windCheckOnlyWindow(&w, DBWclientID);
labsize = DBWPrintValue(label->lab_size / 8, w, FALSE);
#ifdef MAGIC_WRAPPER #ifdef MAGIC_WRAPPER
lobj = Tcl_GetObjResult(magicinterp); lobj = Tcl_GetObjResult(magicinterp);
Tcl_ListObjAppendElement(magicinterp, lobj, Tcl_ListObjAppendElement(magicinterp, lobj, Tcl_NewStringObj(labsize, -1));
Tcl_NewDoubleObj((double)label->lab_size / 8.0));
Tcl_SetObjResult(magicinterp, lobj); Tcl_SetObjResult(magicinterp, lobj);
#else #else
TxPrintf("%g\n", (double)label->lab_size / 8.0); TxPrintf("%s\n", labsize);
#endif #endif
} }
else if (label->lab_size != *value) else if (label->lab_size != *value)
@ -1952,18 +1957,22 @@ cmdLabelOffsetFunc(
if (point == NULL) if (point == NULL)
{ {
char *laboffx, *laboffy;
MagWindow *w;
windCheckOnlyWindow(&w, DBWclientID);
laboffx = DBWPrintValue(label->lab_offset.p_x / 8, w, TRUE);
laboffy = DBWPrintValue(label->lab_offset.p_x / 8, w, FALSE);
#ifdef MAGIC_WRAPPER #ifdef MAGIC_WRAPPER
lobj = Tcl_GetObjResult(magicinterp); lobj = Tcl_GetObjResult(magicinterp);
pobj = Tcl_NewListObj(0, NULL); pobj = Tcl_NewListObj(0, NULL);
Tcl_ListObjAppendElement(magicinterp, lobj, pobj); Tcl_ListObjAppendElement(magicinterp, lobj, pobj);
Tcl_ListObjAppendElement(magicinterp, pobj, Tcl_ListObjAppendElement(magicinterp, pobj, Tcl_NewStringObj(laboffx, -1));
Tcl_NewDoubleObj((double)label->lab_offset.p_x / 8.0)); Tcl_ListObjAppendElement(magicinterp, pobj, Tcl_NewStringObj(laboffy, -1));
Tcl_ListObjAppendElement(magicinterp, pobj,
Tcl_NewDoubleObj((double)label->lab_offset.p_y / 8.0));
Tcl_SetObjResult(magicinterp, lobj); Tcl_SetObjResult(magicinterp, lobj);
#else #else
TxPrintf("%g %g\n", (double)(label->lab_offset.p_x) / 8.0, TxPrintf("%s %s\n", laboffx, laboffy);
(double)(label->lab_offset.p_y) / 8.0);
#endif #endif
} }
else if (!GEO_SAMEPOINT(label->lab_offset, *point)) else if (!GEO_SAMEPOINT(label->lab_offset, *point))
@ -2212,9 +2221,13 @@ CmdSetLabel(
} }
else if (EditCellUse) else if (EditCellUse)
{ {
SelEnumLabelsMirror(&DBAllTypeBits, TRUE, (bool *)NULL, if (locargc == 2)
cmdLabelTextFunc, (locargc == 3) ? SelEnumLabels(&DBAllTypeBits, TRUE, (bool *)NULL,
(ClientData)cmd->tx_argv[argstart + 1] : (ClientData)NULL); cmdLabelTextFunc, (ClientData)NULL);
else
SelEnumLabelsMirror(&DBAllTypeBits, TRUE, (bool *)NULL,
cmdLabelTextFunc,
(ClientData)cmd->tx_argv[argstart + 1]);
} }
break; break;
@ -2280,9 +2293,12 @@ CmdSetLabel(
} }
else if (EditCellUse) else if (EditCellUse)
{ {
SelEnumLabelsMirror(&DBAllTypeBits, TRUE, (bool *)NULL, if (locargc == 2)
cmdLabelFontFunc, (locargc == 3) ? SelEnumLabels(&DBAllTypeBits, TRUE, (bool *)NULL,
(ClientData)&font : (ClientData)NULL); cmdLabelFontFunc, (ClientData)NULL);
else
SelEnumLabelsMirror(&DBAllTypeBits, TRUE, (bool *)NULL,
cmdLabelFontFunc, (ClientData)&font);
} }
} }
break; break;
@ -2310,9 +2326,12 @@ CmdSetLabel(
} }
else if (EditCellUse) else if (EditCellUse)
{ {
SelEnumLabelsMirror(&DBAllTypeBits, TRUE, (bool *)NULL, if (locargc == 2)
cmdLabelJustFunc, (locargc == 3) ? SelEnumLabels(&DBAllTypeBits, TRUE, (bool *)NULL,
(ClientData)&pos : (ClientData)NULL); cmdLabelJustFunc, (ClientData)NULL);
else
SelEnumLabelsMirror(&DBAllTypeBits, TRUE, (bool *)NULL,
cmdLabelJustFunc, (ClientData)&pos);
} }
break; break;
@ -2341,9 +2360,12 @@ CmdSetLabel(
} }
else if (EditCellUse) else if (EditCellUse)
{ {
SelEnumLabelsMirror(&DBAllTypeBits, TRUE, (bool *)NULL, if (locargc == 2)
cmdLabelSizeFunc, (locargc == 3) ? SelEnumLabels(&DBAllTypeBits, TRUE, (bool *)NULL,
(ClientData)&size : (ClientData)NULL); cmdLabelSizeFunc, (ClientData)NULL);
else
SelEnumLabelsMirror(&DBAllTypeBits, TRUE, (bool *)NULL,
cmdLabelSizeFunc, (ClientData)&size);
} }
break; break;
@ -2393,9 +2415,12 @@ CmdSetLabel(
} }
else if (EditCellUse) else if (EditCellUse)
{ {
SelEnumLabelsMirror(&DBAllTypeBits, TRUE, (bool *)NULL, if (locargc == 2)
cmdLabelOffsetFunc, (locargc != 2) ? SelEnumLabels(&DBAllTypeBits, TRUE, (bool *)NULL,
(ClientData)&offset : (ClientData)NULL); cmdLabelOffsetFunc, (ClientData)NULL);
else
SelEnumLabelsMirror(&DBAllTypeBits, TRUE, (bool *)NULL,
cmdLabelOffsetFunc, (ClientData)&offset);
} }
break; break;
@ -2459,10 +2484,12 @@ CmdSetLabel(
rect.r_ytop = cmdScaleCoord(w, cmd->tx_argv[argstart + 4], rect.r_ytop = cmdScaleCoord(w, cmd->tx_argv[argstart + 4],
TRUE, FALSE, 1); TRUE, FALSE, 1);
} }
SelEnumLabelsMirror(&DBAllTypeBits, TRUE, (bool *)NULL, if ((locargc == 3) || (locargc == 6))
cmdLabelRectFunc, SelEnumLabelsMirror(&DBAllTypeBits, TRUE, (bool *)NULL,
((locargc == 6) || (locargc == 3)) ? cmdLabelRectFunc, (ClientData)&rect);
(ClientData)&rect : (ClientData)NULL); else
SelEnumLabels(&DBAllTypeBits, TRUE, (bool *)NULL,
cmdLabelRectFunc, (ClientData)NULL);
} }
break; break;
@ -2488,9 +2515,12 @@ CmdSetLabel(
} }
else if (EditCellUse) else if (EditCellUse)
{ {
SelEnumLabelsMirror(&DBAllTypeBits, TRUE, (bool *)NULL, if (locargc == 2)
cmdLabelRotateFunc, (locargc == 3) ? SelEnumLabels(&DBAllTypeBits, TRUE, (bool *)NULL,
(ClientData)&rotate : (ClientData)NULL); cmdLabelRotateFunc, (ClientData)NULL);
else
SelEnumLabelsMirror(&DBAllTypeBits, TRUE, (bool *)NULL,
cmdLabelRotateFunc, (ClientData)&rotate);
} }
break; break;
@ -2522,9 +2552,12 @@ CmdSetLabel(
} }
else if (EditCellUse) else if (EditCellUse)
{ {
SelEnumLabels(&DBAllTypeBits, TRUE, (bool *)NULL, if (locargc == 2)
cmdLabelStickyFunc, (locargc == 3) ? SelEnumLabels(&DBAllTypeBits, TRUE, (bool *)NULL,
(ClientData)&flags : (ClientData)NULL); cmdLabelStickyFunc, (ClientData)NULL);
else
SelEnumLabelsMirror(&DBAllTypeBits, TRUE, (bool *)NULL,
cmdLabelStickyFunc, (ClientData)&flags);
} }
break; break;
@ -2563,9 +2596,12 @@ CmdSetLabel(
} }
else if (EditCellUse) else if (EditCellUse)
{ {
SelEnumLabels(&DBAllTypeBits, TRUE, (bool *)NULL, if (locargc == 2)
cmdLabelLayerFunc, (locargc == 3) ? SelEnumLabels(&DBAllTypeBits, TRUE, (bool *)NULL,
(ClientData)&ttype : (ClientData)NULL); cmdLabelLayerFunc, (ClientData)NULL);
else
SelEnumLabelsMirror(&DBAllTypeBits, TRUE, (bool *)NULL,
cmdLabelLayerFunc, (ClientData)&ttype);
} }
break; break;

View File

@ -588,6 +588,25 @@ DBTreeSrLabels(scx, mask, xMask, tpath, flags, func, cdarg)
if (!DBCellRead(def, TRUE, TRUE, NULL)) if (!DBCellRead(def, TRUE, TRUE, NULL))
return 0; return 0;
if (flags & TF_LABEL_REVERSE_SEARCH)
{
/* Search children first */
filter.tf_func = func;
filter.tf_arg = cdarg;
filter.tf_mask = mask;
filter.tf_xmask = xMask;
filter.tf_tpath = tpath;
filter.tf_flags = flags;
scx2 = *scx;
if (scx2.scx_area.r_xbot > TiPlaneRect.r_xbot) scx2.scx_area.r_xbot -= 1;
if (scx2.scx_area.r_ybot > TiPlaneRect.r_ybot) scx2.scx_area.r_ybot -= 1;
if (scx2.scx_area.r_xtop < TiPlaneRect.r_xtop) scx2.scx_area.r_xtop += 1;
if (scx2.scx_area.r_ytop < TiPlaneRect.r_ytop) scx2.scx_area.r_ytop += 1;
if (DBCellSrArea(&scx2, dbCellLabelSrFunc, (ClientData) &filter))
return 1;
}
for (lab = def->cd_labels; lab; lab = lab->lab_next) for (lab = def->cd_labels; lab; lab = lab->lab_next)
{ {
if (SigInterruptPending) break; if (SigInterruptPending) break;
@ -640,6 +659,8 @@ DBTreeSrLabels(scx, mask, xMask, tpath, flags, func, cdarg)
return (1); return (1);
} }
if (flags & TF_LABEL_REVERSE_SEARCH) return 0; /* children already searched */
filter.tf_func = func; filter.tf_func = func;
filter.tf_arg = cdarg; filter.tf_arg = cdarg;
filter.tf_mask = mask; filter.tf_mask = mask;
@ -711,6 +732,16 @@ dbCellLabelSrFunc(scx, fp)
} }
} }
/* If fp->tf_flags has TF_LABEL_REVERSE_SEARCH, then search child
* uses first, then the parent. This is for display, so that if
* a child cell and parent cell have overlapping labels, the parent
* label is the one on top.
*/
if (fp->tf_flags & TF_LABEL_REVERSE_SEARCH)
if (DBCellSrArea(scx, dbCellLabelSrFunc, (ClientData) fp))
result = 1;
/* Apply the function first to any of the labels in this def. */ /* Apply the function first to any of the labels in this def. */
result = 0; result = 0;
@ -732,9 +763,11 @@ dbCellLabelSrFunc(scx, fp)
} }
} }
/* Now visit each child use recursively */ /* Now visit each child use recursively, if not doing a reverse search */
if (DBCellSrArea(scx, dbCellLabelSrFunc, (ClientData) fp))
result = 1; if (!(fp->tf_flags & TF_LABEL_REVERSE_SEARCH))
if (DBCellSrArea(scx, dbCellLabelSrFunc, (ClientData) fp))
result = 1;
cleanup: cleanup:
/* Remove the trailing pathname component from the TerminalPath */ /* Remove the trailing pathname component from the TerminalPath */

View File

@ -651,6 +651,7 @@ typedef struct treeFilter
#define TF_LABEL_ATTACH_NOT_SE 0x10 /* Same as above, ignore tile SE corner */ #define TF_LABEL_ATTACH_NOT_SE 0x10 /* Same as above, ignore tile SE corner */
#define TF_LABEL_ATTACH_NOT_SW 0x20 /* Same as above, ignore tile SW corner */ #define TF_LABEL_ATTACH_NOT_SW 0x20 /* Same as above, ignore tile SW corner */
#define TF_LABEL_ATTACH_CORNER 0x3C /* Mask of the four types above */ #define TF_LABEL_ATTACH_CORNER 0x3C /* Mask of the four types above */
#define TF_LABEL_REVERSE_SEARCH 0x40 /* Search children before parent */
/* To do: Make the tpath entries dynamically allocated */ /* To do: Make the tpath entries dynamically allocated */
#define FLATTERMSIZE 4096 /* Used for generating flattened labels */ #define FLATTERMSIZE 4096 /* Used for generating flattened labels */

View File

@ -421,7 +421,8 @@ DBWredisplay(w, rootArea, clipArea)
/* Set style information beforehand */ /* Set style information beforehand */
GrSetStuff(STYLE_LABEL); GrSetStuff(STYLE_LABEL);
(void) DBTreeSrLabels(&scontext, &DBAllTypeBits, bitMask, (void) DBTreeSrLabels(&scontext, &DBAllTypeBits, bitMask,
(TerminalPath *) NULL, TF_LABEL_DISPLAY | TF_LABEL_ATTACH, (TerminalPath *) NULL,
TF_LABEL_DISPLAY | TF_LABEL_ATTACH | TF_LABEL_REVERSE_SEARCH,
dbwLabelFunc, (ClientData)(&crec->dbw_visibleLayers)); dbwLabelFunc, (ClientData)(&crec->dbw_visibleLayers));
GrClipTo(&rootClip); GrClipTo(&rootClip);
} }

View File

@ -148,6 +148,10 @@ proc magic::make_texthelper { mgrpath } {
proc magic::analyze_labels {} { proc magic::analyze_labels {} {
global typedflt typesticky typeport global typedflt typesticky typeport
# Ensure units of microns
set curunits [units]
units microns
# Pick up values from the first entry returned # Pick up values from the first entry returned
set tval [lindex [setlabel text] 0] set tval [lindex [setlabel text] 0]
@ -157,6 +161,7 @@ proc magic::analyze_labels {} {
set oval [lindex [setlabel offset] 0] set oval [lindex [setlabel offset] 0]
set lval [lindex [setlabel layer] 0] set lval [lindex [setlabel layer] 0]
set kval [lindex [setlabel sticky] 0] set kval [lindex [setlabel sticky] 0]
set sval [lindex [setlabel size] 0]
set isport [lindex [port exists] 0] set isport [lindex [port exists] 0]
if {$isport} { if {$isport} {
set pval [lindex [port index] 0] set pval [lindex [port index] 0]
@ -164,14 +169,6 @@ proc magic::analyze_labels {} {
set pval -1 set pval -1
} }
# Rescale internal units to microns
set sval [lindex [setlabel size] 0]
set sscale [cif scale out]
set tmp_pre $::tcl_precision
set ::tcl_precision 3
set sval [expr $sscale * $sval]
set ::tcl_precision $tmp_pre
.texthelper.text.tent delete 0 end .texthelper.text.tent delete 0 end
.texthelper.text.tent insert 0 $tval .texthelper.text.tent insert 0 $tval
set jbtn [string map {NORTH N WEST W SOUTH S EAST E CENTER center} $jval] set jbtn [string map {NORTH N WEST W SOUTH S EAST E CENTER center} $jval]
@ -206,6 +203,9 @@ proc magic::analyze_labels {} {
pack .texthelper.layer.tent -side left -fill x -expand true pack .texthelper.layer.tent -side left -fill x -expand true
pack .texthelper.layer.btn2 -side left pack .texthelper.layer.btn2 -side left
} }
# Revert units
units {*}$curunits
} }
@ -220,6 +220,9 @@ proc magic::change_label {} {
return return
} }
set curunits [units]
units microns
set ltext [.texthelper.text.tent get] set ltext [.texthelper.text.tent get]
set lfont [.texthelper.font.btn cget -text] set lfont [.texthelper.font.btn cget -text]
set lsize [.texthelper.size.tent get] set lsize [.texthelper.size.tent get]
@ -247,13 +250,10 @@ proc magic::change_label {} {
} }
} }
if {$lsize != ""} { if {$lsize != ""} {
setlabel size ${lsize}um setlabel size $lsize
} }
if {$loff != ""} { if {$loff != ""} {
set oldunits [units]
units internal
setlabel offset [join $loff] setlabel offset [join $loff]
units $oldunits
} }
if {$lrot != ""} { if {$lrot != ""} {
setlabel rotate $lrot setlabel rotate $lrot
@ -274,6 +274,8 @@ proc magic::change_label {} {
port remove port remove
} }
} }
units {*}$curunits
} }
proc magic::make_new_label {} { proc magic::make_new_label {} {