Skip to content

Commit ca99d0b

Browse files
Altered the behavior of handling labels when a layer under a label
is erased. In cases where magic would previously unattach the label from the material and attach it to "space", now magic will instead adjust the size of the label to stay entirely on the material. That avoids a common error of losing label or port connections when the material is trimmed back. Thanks to Philipp Guhring for suggesting this implementation (github issue #305).
1 parent efccdbf commit ca99d0b

File tree

1 file changed

+88
-9
lines changed

1 file changed

+88
-9
lines changed

database/DBlabel.c

+88-9
Original file line numberDiff line numberDiff line change
@@ -561,6 +561,41 @@ DBReOrientLabel(cellDef, area, newPos)
561561
}
562562
}
563563

564+
/*
565+
* ----------------------------------------------------------------------------
566+
*
567+
* dbGetLabelArea ---
568+
*
569+
* Callback function used by DBAdjustLabels. Find all material under a label
570+
* that is *not* the label type, and return the
571+
*
572+
* Note: This clips in a regular order, and does not consider what is the
573+
* largest rectangular area outside the area that has been clipped out.
574+
*
575+
* ----------------------------------------------------------------------------
576+
*/
577+
578+
int
579+
dbGetLabelArea(tile, area)
580+
Tile *tile; /* Tile found. */
581+
Rect *area; /* Area to be modified. */
582+
{
583+
Rect r;
584+
585+
TiToRect(tile, &r);
586+
587+
if (r.r_xbot > area->r_xbot)
588+
area->r_xtop = r.r_xbot;
589+
else if (r.r_xtop < area->r_xtop)
590+
area->r_xbot = r.r_xtop;
591+
else if (r.r_ybot > area->r_ybot)
592+
area->r_ytop = r.r_ybot;
593+
else if (r.r_ytop < area->r_ytop)
594+
area->r_ybot = r.r_ytop;
595+
596+
return 0;
597+
}
598+
564599
/*
565600
* ----------------------------------------------------------------------------
566601
*
@@ -590,7 +625,7 @@ DBAdjustLabels(def, area)
590625
{
591626
Label *lab;
592627
TileType newType;
593-
bool modified = FALSE;
628+
bool modified = FALSE, adjusted = FALSE;
594629

595630
/* First, find each label that crosses the area we're
596631
* interested in.
@@ -602,16 +637,60 @@ DBAdjustLabels(def, area)
602637
newType = DBPickLabelLayer(def, lab, FALSE);
603638
if (newType == lab->lab_type) continue;
604639
if (lab->lab_flags & LABEL_STICKY) continue;
605-
if ((DBVerbose >= DB_VERBOSE_ALL) && ((def->cd_flags & CDINTERNAL) == 0))
640+
641+
/* New behavior (5/2024) (idea from Philipp Guhring)---If the new
642+
* type is space, then instead of immediately casting the label off
643+
* of its material, find the amount of the label that is still
644+
* covered by the material. If the material covers more than half
645+
* the label area, then adjust the label area to match the material.
646+
*/
647+
648+
adjusted = FALSE;
649+
if (newType == TT_SPACE)
606650
{
607-
TxPrintf("Moving label \"%s\" from %s to %s in cell %s.\n",
608-
lab->lab_text, DBTypeLongName(lab->lab_type),
609-
DBTypeLongName(newType), def->cd_name);
651+
Rect r;
652+
TileTypeBitMask lmask;
653+
654+
TTMaskSetOnlyType(&lmask, lab->lab_type);
655+
/* To do: Add compatible types (contact, residue) */
656+
TTMaskCom(&lmask);
657+
658+
r = lab->lab_rect;
659+
DBSrPaintArea((Tile *) NULL, def->cd_planes[DBPlane(lab->lab_type)],
660+
&lab->lab_rect, &lmask, dbGetLabelArea, (ClientData) &r);
661+
662+
if (!GEO_RECTNULL(&r))
663+
{
664+
if ((DBVerbose >= DB_VERBOSE_ALL) && ((def->cd_flags & CDINTERNAL) == 0))
665+
{
666+
TxPrintf("Adjusting size of label \"%s\" in cell %s.\n",
667+
lab->lab_text, def->cd_name);
668+
}
669+
670+
DBUndoEraseLabel(def, lab);
671+
DBWLabelChanged(def, lab, DBW_ALLWINDOWS);
672+
lab->lab_rect = r;
673+
DBFontLabelSetBBox(lab);
674+
DBUndoPutLabel(def, lab);
675+
DBWLabelChanged(def, lab, DBW_ALLWINDOWS);
676+
modified = TRUE;
677+
adjusted = TRUE;
678+
}
679+
}
680+
681+
if (!adjusted)
682+
{
683+
if ((DBVerbose >= DB_VERBOSE_ALL) && ((def->cd_flags & CDINTERNAL) == 0))
684+
{
685+
TxPrintf("Moving label \"%s\" from %s to %s in cell %s.\n",
686+
lab->lab_text, DBTypeLongName(lab->lab_type),
687+
DBTypeLongName(newType), def->cd_name);
688+
}
689+
DBUndoEraseLabel(def, lab);
690+
lab->lab_type = newType;
691+
DBUndoPutLabel(def, lab);
692+
modified = TRUE;
610693
}
611-
DBUndoEraseLabel(def, lab);
612-
lab->lab_type = newType;
613-
DBUndoPutLabel(def, lab);
614-
modified = TRUE;
615694
}
616695

617696
if (modified) DBCellSetModified(def, TRUE);

0 commit comments

Comments
 (0)