@tscircuit/schematic-trace-solver 0.0.167 → 0.0.168
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +41 -28
- package/lib/solvers/InlineNetLabelSolver/InlineNetLabelSolver.ts +3 -8
- package/lib/solvers/InlineNetLabelSolver/getAnchoredNetLabelRenderedBounds.ts +34 -0
- package/lib/solvers/InlineNetLabelSolver/pushAnchoredNetLabelsAwayFromInlineLabels.ts +15 -16
- package/lib/solvers/InlineNetLabelSolver/pushInlineTerminalLabelsAwayFromAnchoredLabels.ts +9 -11
- package/package.json +1 -1
- package/tests/repros/__snapshots__/repro-core-ground-inline-label-fallback.snap.svg +151 -187
- package/tests/repros/repro-core-ground-inline-label-fallback.test.ts +6 -7
- package/tests/solvers/InlineNetLabelSolver/__snapshots__/inline-net-label-anchored-label-clearance.snap.svg +24 -24
- package/tests/solvers/InlineNetLabelSolver/get-anchored-net-label-rendered-bounds.test.ts +39 -0
package/dist/index.js
CHANGED
|
@@ -11582,10 +11582,10 @@ function isPointOnPath(point, path) {
|
|
|
11582
11582
|
}
|
|
11583
11583
|
function buildMergedObstacleLabel(seedLabel, allLabels) {
|
|
11584
11584
|
const TOUCH_MARGIN = 0.01;
|
|
11585
|
-
const
|
|
11585
|
+
const getBounds3 = (l) => getRectBounds(l.center, l.width, l.height);
|
|
11586
11586
|
const touches = (a, b) => {
|
|
11587
|
-
const ba =
|
|
11588
|
-
const bb =
|
|
11587
|
+
const ba = getBounds3(a);
|
|
11588
|
+
const bb = getBounds3(b);
|
|
11589
11589
|
return ba.minX <= bb.maxX + TOUCH_MARGIN && ba.maxX >= bb.minX - TOUCH_MARGIN && ba.minY <= bb.maxY + TOUCH_MARGIN && ba.maxY >= bb.minY - TOUCH_MARGIN;
|
|
11590
11590
|
};
|
|
11591
11591
|
const group = /* @__PURE__ */ new Set([seedLabel]);
|
|
@@ -11602,7 +11602,7 @@ function buildMergedObstacleLabel(seedLabel, allLabels) {
|
|
|
11602
11602
|
}
|
|
11603
11603
|
let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
|
|
11604
11604
|
for (const l of group) {
|
|
11605
|
-
const b =
|
|
11605
|
+
const b = getBounds3(l);
|
|
11606
11606
|
if (b.minX < minX) minX = b.minX;
|
|
11607
11607
|
if (b.minY < minY) minY = b.minY;
|
|
11608
11608
|
if (b.maxX > maxX) maxX = b.maxX;
|
|
@@ -13836,12 +13836,28 @@ var getAxisAlignedSegments = (path, epsilon = 1e-6) => {
|
|
|
13836
13836
|
return segments.sort((a, b) => b.length - a.length);
|
|
13837
13837
|
};
|
|
13838
13838
|
|
|
13839
|
+
// lib/solvers/InlineNetLabelSolver/getAnchoredNetLabelRenderedBounds.ts
|
|
13840
|
+
var getAnchoredNetLabelRenderedBounds = (placement) => {
|
|
13841
|
+
if (placement.orientation !== "x-" && placement.orientation !== "x+") {
|
|
13842
|
+
return getRectBounds(placement.center, placement.width, placement.height);
|
|
13843
|
+
}
|
|
13844
|
+
const width = Math.max(placement.width, placement.height);
|
|
13845
|
+
const height = NET_LABEL_HORIZONTAL_HEIGHT;
|
|
13846
|
+
const center = getCenterFromAnchor(
|
|
13847
|
+
placement.anchorPoint,
|
|
13848
|
+
placement.orientation,
|
|
13849
|
+
width,
|
|
13850
|
+
height
|
|
13851
|
+
);
|
|
13852
|
+
return getRectBounds(center, width, height);
|
|
13853
|
+
};
|
|
13854
|
+
|
|
13839
13855
|
// lib/solvers/InlineNetLabelSolver/pushAnchoredNetLabelsAwayFromInlineLabels.ts
|
|
13840
13856
|
var LABEL_CLEARANCE2 = 0.05;
|
|
13841
13857
|
var POINT_EPSILON = 1e-6;
|
|
13842
13858
|
var CONTIGUOUS_LABEL_GAP = 0.01;
|
|
13843
13859
|
var MAX_OUTWARD_DISTANCE = 5;
|
|
13844
|
-
var
|
|
13860
|
+
var getInlineBounds = (placement) => {
|
|
13845
13861
|
const renderedWidth = placement.axis === "y" ? placement.height : placement.width;
|
|
13846
13862
|
const renderedHeight = placement.axis === "y" ? placement.width : placement.height;
|
|
13847
13863
|
return {
|
|
@@ -13883,7 +13899,7 @@ var isPointOnPath2 = (point, path) => {
|
|
|
13883
13899
|
return false;
|
|
13884
13900
|
};
|
|
13885
13901
|
var getRequiredOutwardDistance = (label, inlineBounds) => {
|
|
13886
|
-
const labelBounds =
|
|
13902
|
+
const labelBounds = getAnchoredNetLabelRenderedBounds(label);
|
|
13887
13903
|
if (label.orientation === "x-" || label.orientation === "x+") {
|
|
13888
13904
|
const nearby2 = inlineBounds.filter(
|
|
13889
13905
|
(bounds) => labelBounds.minY < bounds.maxY && labelBounds.maxY > bounds.minY
|
|
@@ -14010,8 +14026,8 @@ var getContiguousLabelGroup = ({
|
|
|
14010
14026
|
if (group.has(labelIndex)) continue;
|
|
14011
14027
|
if ([...group].some(
|
|
14012
14028
|
(memberIndex) => boundsGapOnPerpendicularAxis(
|
|
14013
|
-
|
|
14014
|
-
|
|
14029
|
+
getAnchoredNetLabelRenderedBounds(labels[memberIndex]),
|
|
14030
|
+
getAnchoredNetLabelRenderedBounds(label),
|
|
14015
14031
|
trigger.orientation
|
|
14016
14032
|
) <= CONTIGUOUS_LABEL_GAP
|
|
14017
14033
|
)) {
|
|
@@ -14033,7 +14049,7 @@ var pushAnchoredNetLabelsAwayFromInlineLabels = ({
|
|
|
14033
14049
|
tracePath: trace.tracePath.map((point) => ({ ...point }))
|
|
14034
14050
|
}));
|
|
14035
14051
|
const outputLabels = netLabelPlacements.map((label) => ({ ...label }));
|
|
14036
|
-
const inlineBounds = inlineNetLabelPlacements.map(
|
|
14052
|
+
const inlineBounds = inlineNetLabelPlacements.map(getInlineBounds);
|
|
14037
14053
|
const pinMap = getPinMap(inputProblem);
|
|
14038
14054
|
const chipIdByPinId = /* @__PURE__ */ new Map();
|
|
14039
14055
|
for (const chip of inputProblem.chips) {
|
|
@@ -14056,7 +14072,7 @@ var pushAnchoredNetLabelsAwayFromInlineLabels = ({
|
|
|
14056
14072
|
for (let iteration = 0; iteration < outputLabels.length; iteration++) {
|
|
14057
14073
|
let adjustedObstacle = false;
|
|
14058
14074
|
for (const [movingIndex, movingDistance] of distances) {
|
|
14059
|
-
const movingBounds =
|
|
14075
|
+
const movingBounds = getAnchoredNetLabelRenderedBounds(
|
|
14060
14076
|
moveLabel(
|
|
14061
14077
|
outputLabels[movingIndex],
|
|
14062
14078
|
trigger.orientation,
|
|
@@ -14067,7 +14083,7 @@ var pushAnchoredNetLabelsAwayFromInlineLabels = ({
|
|
|
14067
14083
|
if (group.has(obstacleIndex)) continue;
|
|
14068
14084
|
const obstacle = outputLabels[obstacleIndex];
|
|
14069
14085
|
const existingObstacleDistance = distances.get(obstacleIndex) ?? 0;
|
|
14070
|
-
const obstacleBounds =
|
|
14086
|
+
const obstacleBounds = getAnchoredNetLabelRenderedBounds(
|
|
14071
14087
|
moveLabel(obstacle, trigger.orientation, existingObstacleDistance)
|
|
14072
14088
|
);
|
|
14073
14089
|
if (!boundsOverlap(movingBounds, obstacleBounds)) continue;
|
|
@@ -14076,7 +14092,7 @@ var pushAnchoredNetLabelsAwayFromInlineLabels = ({
|
|
|
14076
14092
|
break;
|
|
14077
14093
|
}
|
|
14078
14094
|
const shoveDistance = getDistanceToShoveBoundsPast(
|
|
14079
|
-
|
|
14095
|
+
getAnchoredNetLabelRenderedBounds(obstacle),
|
|
14080
14096
|
movingBounds,
|
|
14081
14097
|
trigger.orientation
|
|
14082
14098
|
);
|
|
@@ -14105,7 +14121,7 @@ var pushAnchoredNetLabelsAwayFromInlineLabels = ({
|
|
|
14105
14121
|
}
|
|
14106
14122
|
const finalLabelAt = (labelIndex) => proposals.get(labelIndex) ?? outputLabels[labelIndex];
|
|
14107
14123
|
for (const [labelIndex, movedLabel] of proposals) {
|
|
14108
|
-
const movedBounds =
|
|
14124
|
+
const movedBounds = getAnchoredNetLabelRenderedBounds(movedLabel);
|
|
14109
14125
|
if (inlineBounds.some((bounds) => boundsOverlap(movedBounds, bounds))) {
|
|
14110
14126
|
failed = true;
|
|
14111
14127
|
break;
|
|
@@ -14124,7 +14140,10 @@ var pushAnchoredNetLabelsAwayFromInlineLabels = ({
|
|
|
14124
14140
|
break;
|
|
14125
14141
|
}
|
|
14126
14142
|
if (outputLabels.some(
|
|
14127
|
-
(_, otherIndex) => otherIndex !== labelIndex && boundsOverlap(
|
|
14143
|
+
(_, otherIndex) => otherIndex !== labelIndex && boundsOverlap(
|
|
14144
|
+
movedBounds,
|
|
14145
|
+
getAnchoredNetLabelRenderedBounds(finalLabelAt(otherIndex))
|
|
14146
|
+
)
|
|
14128
14147
|
)) {
|
|
14129
14148
|
failed = true;
|
|
14130
14149
|
break;
|
|
@@ -14169,7 +14188,7 @@ var pushAnchoredNetLabelsAwayFromInlineLabels = ({
|
|
|
14169
14188
|
) || outputLabels.some(
|
|
14170
14189
|
(_, otherIndex) => otherIndex !== labelIndex && pathIntersectsBounds(
|
|
14171
14190
|
connector.tracePath,
|
|
14172
|
-
|
|
14191
|
+
getAnchoredNetLabelRenderedBounds(finalLabelAt(otherIndex))
|
|
14173
14192
|
)
|
|
14174
14193
|
);
|
|
14175
14194
|
if (connectorObstructed) {
|
|
@@ -14205,7 +14224,7 @@ var getStubDirection2 = (path) => {
|
|
|
14205
14224
|
}
|
|
14206
14225
|
return end.y >= start.y ? "y+" : "y-";
|
|
14207
14226
|
};
|
|
14208
|
-
var
|
|
14227
|
+
var getInlineLabelBounds = (placement) => {
|
|
14209
14228
|
const renderedWidth = placement.axis === "y" ? placement.height : placement.width;
|
|
14210
14229
|
const renderedHeight = placement.axis === "y" ? placement.width : placement.height;
|
|
14211
14230
|
return {
|
|
@@ -14305,12 +14324,12 @@ var pushInlineTerminalLabelsAwayFromAnchoredLabels = ({
|
|
|
14305
14324
|
direction,
|
|
14306
14325
|
distance7
|
|
14307
14326
|
);
|
|
14308
|
-
const shiftedBounds =
|
|
14327
|
+
const shiftedBounds = getInlineLabelBounds(shiftedPlacement);
|
|
14309
14328
|
for (const anchoredPlacement of anchoredNetLabelPlacements) {
|
|
14310
14329
|
if (anchoredPlacement.globalConnNetId === placement.globalConnNetId) {
|
|
14311
14330
|
continue;
|
|
14312
14331
|
}
|
|
14313
|
-
const anchoredBounds =
|
|
14332
|
+
const anchoredBounds = getAnchoredNetLabelRenderedBounds(anchoredPlacement);
|
|
14314
14333
|
if (!boundsOverlap(shiftedBounds, anchoredBounds)) continue;
|
|
14315
14334
|
requiredAdditionalDistance = Math.max(
|
|
14316
14335
|
requiredAdditionalDistance,
|
|
@@ -14334,13 +14353,13 @@ var pushInlineTerminalLabelsAwayFromAnchoredLabels = ({
|
|
|
14334
14353
|
const originalEnd = originalPlacement.stubTracePath[1];
|
|
14335
14354
|
const shiftedEnd = proposal.stubTracePath[1];
|
|
14336
14355
|
const addedStubSegment = [originalEnd, shiftedEnd];
|
|
14337
|
-
const labelBounds =
|
|
14356
|
+
const labelBounds = getInlineLabelBounds(proposal);
|
|
14338
14357
|
const ownerChipId = group[proposalIndex].ownerChipId;
|
|
14339
14358
|
if (anchoredNetLabelPlacements.some((anchoredPlacement) => {
|
|
14340
14359
|
if (anchoredPlacement.globalConnNetId === proposal.globalConnNetId) {
|
|
14341
14360
|
return false;
|
|
14342
14361
|
}
|
|
14343
|
-
const anchoredBounds =
|
|
14362
|
+
const anchoredBounds = getAnchoredNetLabelRenderedBounds(anchoredPlacement);
|
|
14344
14363
|
return boundsOverlap(labelBounds, anchoredBounds) || doesPathIntersectBounds2(addedStubSegment, anchoredBounds);
|
|
14345
14364
|
})) {
|
|
14346
14365
|
return true;
|
|
@@ -14373,7 +14392,7 @@ var pushInlineTerminalLabelsAwayFromAnchoredLabels = ({
|
|
|
14373
14392
|
}
|
|
14374
14393
|
}
|
|
14375
14394
|
for (const fixedPlacement of fixedInlinePlacements) {
|
|
14376
|
-
const fixedBounds =
|
|
14395
|
+
const fixedBounds = getInlineLabelBounds(fixedPlacement);
|
|
14377
14396
|
if (boundsOverlap(labelBounds, fixedBounds) || doesPathIntersectBounds2(addedStubSegment, fixedBounds) || fixedPlacement.stubTracePath && doesPathIntersectBounds2(fixedPlacement.stubTracePath, labelBounds)) {
|
|
14378
14397
|
return true;
|
|
14379
14398
|
}
|
|
@@ -14420,12 +14439,6 @@ var getInlinePlacementBounds = (placement) => {
|
|
|
14420
14439
|
maxY: placement.center.y + renderedHeight / 2
|
|
14421
14440
|
};
|
|
14422
14441
|
};
|
|
14423
|
-
var getAnchoredPlacementBounds = (placement) => ({
|
|
14424
|
-
minX: placement.center.x - placement.width / 2,
|
|
14425
|
-
maxX: placement.center.x + placement.width / 2,
|
|
14426
|
-
minY: placement.center.y - placement.height / 2,
|
|
14427
|
-
maxY: placement.center.y + placement.height / 2
|
|
14428
|
-
});
|
|
14429
14442
|
var InlineNetLabelSolver = class extends BaseSolver {
|
|
14430
14443
|
inputProblem;
|
|
14431
14444
|
traces;
|
|
@@ -14995,7 +15008,7 @@ var InlineNetLabelSolver = class extends BaseSolver {
|
|
|
14995
15008
|
if (anchoredPlacement.globalConnNetId === inlinePlacement.globalConnNetId) {
|
|
14996
15009
|
continue;
|
|
14997
15010
|
}
|
|
14998
|
-
const anchoredBounds =
|
|
15011
|
+
const anchoredBounds = getAnchoredNetLabelRenderedBounds(anchoredPlacement);
|
|
14999
15012
|
if (boundsOverlap(inlineBounds, anchoredBounds) || inlinePlacement.stubTracePath && doesPathIntersectBounds3(
|
|
15000
15013
|
inlinePlacement.stubTracePath,
|
|
15001
15014
|
anchoredBounds
|
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
type AxisAlignedSegment,
|
|
22
22
|
getAxisAlignedSegments,
|
|
23
23
|
} from "./getAxisAlignedSegments"
|
|
24
|
+
import { getAnchoredNetLabelRenderedBounds } from "./getAnchoredNetLabelRenderedBounds"
|
|
24
25
|
import { pushAnchoredNetLabelsAwayFromInlineLabels } from "./pushAnchoredNetLabelsAwayFromInlineLabels"
|
|
25
26
|
import { pushInlineTerminalLabelsAwayFromAnchoredLabels } from "./pushInlineTerminalLabelsAwayFromAnchoredLabels"
|
|
26
27
|
|
|
@@ -157,13 +158,6 @@ const getInlinePlacementBounds = (
|
|
|
157
158
|
}
|
|
158
159
|
}
|
|
159
160
|
|
|
160
|
-
const getAnchoredPlacementBounds = (placement: NetLabelPlacement): Bounds => ({
|
|
161
|
-
minX: placement.center.x - placement.width / 2,
|
|
162
|
-
maxX: placement.center.x + placement.width / 2,
|
|
163
|
-
minY: placement.center.y - placement.height / 2,
|
|
164
|
-
maxY: placement.center.y + placement.height / 2,
|
|
165
|
-
})
|
|
166
|
-
|
|
167
161
|
/**
|
|
168
162
|
* Places "inline net labels" - net names drawn alongside the trace they belong
|
|
169
163
|
* to - for connections that opted in via `allowInlineNetLabel`.
|
|
@@ -1007,7 +1001,8 @@ export class InlineNetLabelSolver extends BaseSolver {
|
|
|
1007
1001
|
) {
|
|
1008
1002
|
continue
|
|
1009
1003
|
}
|
|
1010
|
-
const anchoredBounds =
|
|
1004
|
+
const anchoredBounds =
|
|
1005
|
+
getAnchoredNetLabelRenderedBounds(anchoredPlacement)
|
|
1011
1006
|
if (
|
|
1012
1007
|
boundsOverlap(inlineBounds, anchoredBounds) ||
|
|
1013
1008
|
(inlinePlacement.stubTracePath &&
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { Bounds } from "@tscircuit/math-utils"
|
|
2
|
+
import type { NetLabelPlacement } from "lib/solvers/NetLabelPlacementSolver/NetLabelPlacementSolver"
|
|
3
|
+
import {
|
|
4
|
+
getCenterFromAnchor,
|
|
5
|
+
getRectBounds,
|
|
6
|
+
NET_LABEL_HORIZONTAL_HEIGHT,
|
|
7
|
+
} from "lib/solvers/NetLabelPlacementSolver/SingleNetLabelPlacementSolver/geometry"
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Returns the visible schematic-world bounds of a conventional net label.
|
|
11
|
+
*
|
|
12
|
+
* Horizontal labels render as tags whose text remains horizontal. Rail inputs
|
|
13
|
+
* encode their vertical-symbol dimensions in width/height, so a rail label
|
|
14
|
+
* that later falls back to an x-facing tag can have those extents transposed.
|
|
15
|
+
* Normalize that tag to the renderer's horizontal envelope before using it as
|
|
16
|
+
* an obstacle.
|
|
17
|
+
*/
|
|
18
|
+
export const getAnchoredNetLabelRenderedBounds = (
|
|
19
|
+
placement: NetLabelPlacement,
|
|
20
|
+
): Bounds => {
|
|
21
|
+
if (placement.orientation !== "x-" && placement.orientation !== "x+") {
|
|
22
|
+
return getRectBounds(placement.center, placement.width, placement.height)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const width = Math.max(placement.width, placement.height)
|
|
26
|
+
const height = NET_LABEL_HORIZONTAL_HEIGHT
|
|
27
|
+
const center = getCenterFromAnchor(
|
|
28
|
+
placement.anchorPoint,
|
|
29
|
+
placement.orientation,
|
|
30
|
+
width,
|
|
31
|
+
height,
|
|
32
|
+
)
|
|
33
|
+
return getRectBounds(center, width, height)
|
|
34
|
+
}
|
|
@@ -8,6 +8,7 @@ import type { SolvedTracePath } from "lib/solvers/SchematicTraceLinesSolver/Sche
|
|
|
8
8
|
import type { InputProblem } from "lib/types/InputProblem"
|
|
9
9
|
import { dir, type FacingDirection } from "lib/utils/dir"
|
|
10
10
|
import { boundsOverlap, getTextBoxBounds } from "lib/utils/textBoxBounds"
|
|
11
|
+
import { getAnchoredNetLabelRenderedBounds } from "./getAnchoredNetLabelRenderedBounds"
|
|
11
12
|
import type { InlineNetLabelPlacement } from "./InlineNetLabelSolver"
|
|
12
13
|
|
|
13
14
|
const LABEL_CLEARANCE = 0.05
|
|
@@ -15,12 +16,7 @@ const POINT_EPSILON = 1e-6
|
|
|
15
16
|
const CONTIGUOUS_LABEL_GAP = 0.01
|
|
16
17
|
const MAX_OUTWARD_DISTANCE = 5
|
|
17
18
|
|
|
18
|
-
const
|
|
19
|
-
center: Point
|
|
20
|
-
width: number
|
|
21
|
-
height: number
|
|
22
|
-
axis?: "x" | "y"
|
|
23
|
-
}): Bounds => {
|
|
19
|
+
const getInlineBounds = (placement: InlineNetLabelPlacement): Bounds => {
|
|
24
20
|
const renderedWidth =
|
|
25
21
|
placement.axis === "y" ? placement.height : placement.width
|
|
26
22
|
const renderedHeight =
|
|
@@ -79,7 +75,7 @@ const getRequiredOutwardDistance = (
|
|
|
79
75
|
label: NetLabelPlacement,
|
|
80
76
|
inlineBounds: Bounds[],
|
|
81
77
|
) => {
|
|
82
|
-
const labelBounds =
|
|
78
|
+
const labelBounds = getAnchoredNetLabelRenderedBounds(label)
|
|
83
79
|
|
|
84
80
|
if (label.orientation === "x-" || label.orientation === "x+") {
|
|
85
81
|
const nearby = inlineBounds.filter(
|
|
@@ -272,8 +268,8 @@ const getContiguousLabelGroup = ({
|
|
|
272
268
|
[...group].some(
|
|
273
269
|
(memberIndex) =>
|
|
274
270
|
boundsGapOnPerpendicularAxis(
|
|
275
|
-
|
|
276
|
-
|
|
271
|
+
getAnchoredNetLabelRenderedBounds(labels[memberIndex]!),
|
|
272
|
+
getAnchoredNetLabelRenderedBounds(label),
|
|
277
273
|
trigger.orientation,
|
|
278
274
|
) <= CONTIGUOUS_LABEL_GAP,
|
|
279
275
|
)
|
|
@@ -316,7 +312,7 @@ export const pushAnchoredNetLabelsAwayFromInlineLabels = ({
|
|
|
316
312
|
tracePath: trace.tracePath.map((point) => ({ ...point })),
|
|
317
313
|
}))
|
|
318
314
|
const outputLabels = netLabelPlacements.map((label) => ({ ...label }))
|
|
319
|
-
const inlineBounds = inlineNetLabelPlacements.map(
|
|
315
|
+
const inlineBounds = inlineNetLabelPlacements.map(getInlineBounds)
|
|
320
316
|
const pinMap = getPinMap(inputProblem)
|
|
321
317
|
const chipIdByPinId = new Map<string, string>()
|
|
322
318
|
for (const chip of inputProblem.chips) {
|
|
@@ -346,7 +342,7 @@ export const pushAnchoredNetLabelsAwayFromInlineLabels = ({
|
|
|
346
342
|
for (let iteration = 0; iteration < outputLabels.length; iteration++) {
|
|
347
343
|
let adjustedObstacle = false
|
|
348
344
|
for (const [movingIndex, movingDistance] of distances) {
|
|
349
|
-
const movingBounds =
|
|
345
|
+
const movingBounds = getAnchoredNetLabelRenderedBounds(
|
|
350
346
|
moveLabel(
|
|
351
347
|
outputLabels[movingIndex]!,
|
|
352
348
|
trigger.orientation,
|
|
@@ -361,7 +357,7 @@ export const pushAnchoredNetLabelsAwayFromInlineLabels = ({
|
|
|
361
357
|
if (group.has(obstacleIndex)) continue
|
|
362
358
|
const obstacle = outputLabels[obstacleIndex]!
|
|
363
359
|
const existingObstacleDistance = distances.get(obstacleIndex) ?? 0
|
|
364
|
-
const obstacleBounds =
|
|
360
|
+
const obstacleBounds = getAnchoredNetLabelRenderedBounds(
|
|
365
361
|
moveLabel(obstacle, trigger.orientation, existingObstacleDistance),
|
|
366
362
|
)
|
|
367
363
|
if (!boundsOverlap(movingBounds, obstacleBounds)) continue
|
|
@@ -374,7 +370,7 @@ export const pushAnchoredNetLabelsAwayFromInlineLabels = ({
|
|
|
374
370
|
break
|
|
375
371
|
}
|
|
376
372
|
const shoveDistance = getDistanceToShoveBoundsPast(
|
|
377
|
-
|
|
373
|
+
getAnchoredNetLabelRenderedBounds(obstacle),
|
|
378
374
|
movingBounds,
|
|
379
375
|
trigger.orientation,
|
|
380
376
|
)
|
|
@@ -409,7 +405,7 @@ export const pushAnchoredNetLabelsAwayFromInlineLabels = ({
|
|
|
409
405
|
const finalLabelAt = (labelIndex: number) =>
|
|
410
406
|
proposals.get(labelIndex) ?? outputLabels[labelIndex]!
|
|
411
407
|
for (const [labelIndex, movedLabel] of proposals) {
|
|
412
|
-
const movedBounds =
|
|
408
|
+
const movedBounds = getAnchoredNetLabelRenderedBounds(movedLabel)
|
|
413
409
|
if (inlineBounds.some((bounds) => boundsOverlap(movedBounds, bounds))) {
|
|
414
410
|
failed = true
|
|
415
411
|
break
|
|
@@ -434,7 +430,10 @@ export const pushAnchoredNetLabelsAwayFromInlineLabels = ({
|
|
|
434
430
|
outputLabels.some(
|
|
435
431
|
(_, otherIndex) =>
|
|
436
432
|
otherIndex !== labelIndex &&
|
|
437
|
-
boundsOverlap(
|
|
433
|
+
boundsOverlap(
|
|
434
|
+
movedBounds,
|
|
435
|
+
getAnchoredNetLabelRenderedBounds(finalLabelAt(otherIndex)),
|
|
436
|
+
),
|
|
438
437
|
)
|
|
439
438
|
) {
|
|
440
439
|
failed = true
|
|
@@ -503,7 +502,7 @@ export const pushAnchoredNetLabelsAwayFromInlineLabels = ({
|
|
|
503
502
|
otherIndex !== labelIndex &&
|
|
504
503
|
pathIntersectsBounds(
|
|
505
504
|
connector.tracePath,
|
|
506
|
-
|
|
505
|
+
getAnchoredNetLabelRenderedBounds(finalLabelAt(otherIndex)),
|
|
507
506
|
),
|
|
508
507
|
)
|
|
509
508
|
if (connectorObstructed) {
|
|
@@ -3,6 +3,7 @@ import type { NetLabelPlacement } from "lib/solvers/NetLabelPlacementSolver/NetL
|
|
|
3
3
|
import type { SolvedTracePath } from "lib/solvers/SchematicTraceLinesSolver/SchematicTraceLinesSolver"
|
|
4
4
|
import type { InputProblem } from "lib/types/InputProblem"
|
|
5
5
|
import { boundsOverlap, getTextBoxBounds } from "lib/utils/textBoxBounds"
|
|
6
|
+
import { getAnchoredNetLabelRenderedBounds } from "./getAnchoredNetLabelRenderedBounds"
|
|
6
7
|
import type { InlineNetLabelPlacement } from "./InlineNetLabelSolver"
|
|
7
8
|
|
|
8
9
|
type StubDirection = "x+" | "x-" | "y+" | "y-"
|
|
@@ -18,12 +19,7 @@ const getStubDirection = (path: [Point, Point]): StubDirection => {
|
|
|
18
19
|
return end.y >= start.y ? "y+" : "y-"
|
|
19
20
|
}
|
|
20
21
|
|
|
21
|
-
const
|
|
22
|
-
center: Point
|
|
23
|
-
width: number
|
|
24
|
-
height: number
|
|
25
|
-
axis?: "x" | "y"
|
|
26
|
-
}): Bounds => {
|
|
22
|
+
const getInlineLabelBounds = (placement: InlineNetLabelPlacement): Bounds => {
|
|
27
23
|
const renderedWidth =
|
|
28
24
|
placement.axis === "y" ? placement.height : placement.width
|
|
29
25
|
const renderedHeight =
|
|
@@ -178,12 +174,13 @@ export const pushInlineTerminalLabelsAwayFromAnchoredLabels = ({
|
|
|
178
174
|
direction,
|
|
179
175
|
distance,
|
|
180
176
|
)
|
|
181
|
-
const shiftedBounds =
|
|
177
|
+
const shiftedBounds = getInlineLabelBounds(shiftedPlacement)
|
|
182
178
|
for (const anchoredPlacement of anchoredNetLabelPlacements) {
|
|
183
179
|
if (anchoredPlacement.globalConnNetId === placement.globalConnNetId) {
|
|
184
180
|
continue
|
|
185
181
|
}
|
|
186
|
-
const anchoredBounds =
|
|
182
|
+
const anchoredBounds =
|
|
183
|
+
getAnchoredNetLabelRenderedBounds(anchoredPlacement)
|
|
187
184
|
if (!boundsOverlap(shiftedBounds, anchoredBounds)) continue
|
|
188
185
|
requiredAdditionalDistance = Math.max(
|
|
189
186
|
requiredAdditionalDistance,
|
|
@@ -209,7 +206,7 @@ export const pushInlineTerminalLabelsAwayFromAnchoredLabels = ({
|
|
|
209
206
|
const originalEnd = originalPlacement.stubTracePath![1]
|
|
210
207
|
const shiftedEnd = proposal.stubTracePath![1]
|
|
211
208
|
const addedStubSegment: [Point, Point] = [originalEnd, shiftedEnd]
|
|
212
|
-
const labelBounds =
|
|
209
|
+
const labelBounds = getInlineLabelBounds(proposal)
|
|
213
210
|
const ownerChipId = group[proposalIndex]!.ownerChipId
|
|
214
211
|
|
|
215
212
|
if (
|
|
@@ -217,7 +214,8 @@ export const pushInlineTerminalLabelsAwayFromAnchoredLabels = ({
|
|
|
217
214
|
if (anchoredPlacement.globalConnNetId === proposal.globalConnNetId) {
|
|
218
215
|
return false
|
|
219
216
|
}
|
|
220
|
-
const anchoredBounds =
|
|
217
|
+
const anchoredBounds =
|
|
218
|
+
getAnchoredNetLabelRenderedBounds(anchoredPlacement)
|
|
221
219
|
return (
|
|
222
220
|
boundsOverlap(labelBounds, anchoredBounds) ||
|
|
223
221
|
doesPathIntersectBounds(addedStubSegment, anchoredBounds)
|
|
@@ -267,7 +265,7 @@ export const pushInlineTerminalLabelsAwayFromAnchoredLabels = ({
|
|
|
267
265
|
}
|
|
268
266
|
|
|
269
267
|
for (const fixedPlacement of fixedInlinePlacements) {
|
|
270
|
-
const fixedBounds =
|
|
268
|
+
const fixedBounds = getInlineLabelBounds(fixedPlacement)
|
|
271
269
|
if (
|
|
272
270
|
boundsOverlap(labelBounds, fixedBounds) ||
|
|
273
271
|
doesPathIntersectBounds(addedStubSegment, fixedBounds) ||
|