circuit-to-svg 0.0.91 → 0.0.93
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.d.ts +9 -3
- package/dist/index.js +635 -289
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -865,6 +865,345 @@ function createSvgObjectFromPcbBoundary(transform, minX, minY, maxX, maxY) {
|
|
|
865
865
|
}
|
|
866
866
|
var circuitJsonToPcbSvg = convertCircuitJsonToPcbSvg;
|
|
867
867
|
|
|
868
|
+
// lib/assembly/convert-circuit-json-to-assembly-svg.ts
|
|
869
|
+
import { stringify as stringify2 } from "svgson";
|
|
870
|
+
import { su } from "@tscircuit/soup-util";
|
|
871
|
+
import {
|
|
872
|
+
applyToPoint as applyToPoint16,
|
|
873
|
+
compose as compose4,
|
|
874
|
+
scale as scale2,
|
|
875
|
+
translate as translate4
|
|
876
|
+
} from "transformation-matrix";
|
|
877
|
+
|
|
878
|
+
// lib/assembly/svg-object-fns/create-svg-objects-from-assembly-board.ts
|
|
879
|
+
import { applyToPoint as applyToPoint13 } from "transformation-matrix";
|
|
880
|
+
var DEFAULT_BOARD_STYLE = {
|
|
881
|
+
fill: "none",
|
|
882
|
+
stroke: "rgb(0,0,0)",
|
|
883
|
+
strokeOpacity: "0.8",
|
|
884
|
+
strokeWidthFactor: 0.2
|
|
885
|
+
};
|
|
886
|
+
function createSvgObjectsFromAssemblyBoard(pcbBoard, transform, style = {}) {
|
|
887
|
+
const { width, height, center, outline } = pcbBoard;
|
|
888
|
+
let path;
|
|
889
|
+
if (outline && Array.isArray(outline) && outline.length >= 3) {
|
|
890
|
+
path = outline.map((point, index) => {
|
|
891
|
+
const [x, y] = applyToPoint13(transform, [point.x, point.y]);
|
|
892
|
+
return index === 0 ? `M ${x} ${y}` : `L ${x} ${y}`;
|
|
893
|
+
}).join(" ");
|
|
894
|
+
} else {
|
|
895
|
+
const halfWidth = width / 2;
|
|
896
|
+
const halfHeight = height / 2;
|
|
897
|
+
const topLeft = applyToPoint13(transform, [
|
|
898
|
+
center.x - halfWidth,
|
|
899
|
+
center.y - halfHeight
|
|
900
|
+
]);
|
|
901
|
+
const topRight = applyToPoint13(transform, [
|
|
902
|
+
center.x + halfWidth,
|
|
903
|
+
center.y - halfHeight
|
|
904
|
+
]);
|
|
905
|
+
const bottomRight = applyToPoint13(transform, [
|
|
906
|
+
center.x + halfWidth,
|
|
907
|
+
center.y + halfHeight
|
|
908
|
+
]);
|
|
909
|
+
const bottomLeft = applyToPoint13(transform, [
|
|
910
|
+
center.x - halfWidth,
|
|
911
|
+
center.y + halfHeight
|
|
912
|
+
]);
|
|
913
|
+
path = `M ${topLeft[0]} ${topLeft[1]} L ${topRight[0]} ${topRight[1]} L ${bottomRight[0]} ${bottomRight[1]} L ${bottomLeft[0]} ${bottomLeft[1]}`;
|
|
914
|
+
}
|
|
915
|
+
path += " Z";
|
|
916
|
+
return [
|
|
917
|
+
{
|
|
918
|
+
name: "path",
|
|
919
|
+
type: "element",
|
|
920
|
+
value: "",
|
|
921
|
+
children: [],
|
|
922
|
+
attributes: {
|
|
923
|
+
class: "pcb-board",
|
|
924
|
+
d: path,
|
|
925
|
+
fill: style.fill ?? DEFAULT_BOARD_STYLE.fill,
|
|
926
|
+
stroke: style.stroke ?? DEFAULT_BOARD_STYLE.stroke,
|
|
927
|
+
"stroke-opacity": style.strokeOpacity ?? DEFAULT_BOARD_STYLE.strokeOpacity,
|
|
928
|
+
"stroke-width": ((style.strokeWidthFactor ?? DEFAULT_BOARD_STYLE.strokeWidthFactor) * Math.abs(transform.a)).toString()
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
];
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
// lib/assembly/svg-object-fns/create-svg-objects-from-assembly-component.ts
|
|
935
|
+
import { applyToPoint as applyToPoint15 } from "transformation-matrix";
|
|
936
|
+
|
|
937
|
+
// lib/utils/get-sch-font-size.ts
|
|
938
|
+
import "transformation-matrix";
|
|
939
|
+
var getSchMmFontSize = (textType) => {
|
|
940
|
+
return textType === "error" ? 0.05 : textType === "pin_number" ? 0.15 : 0.18;
|
|
941
|
+
};
|
|
942
|
+
var getSchScreenFontSize = (transform, textType) => {
|
|
943
|
+
return Math.abs(transform.a) * getSchMmFontSize(textType);
|
|
944
|
+
};
|
|
945
|
+
|
|
946
|
+
// lib/assembly/svg-object-fns/create-svg-objects-from-assembly-component.ts
|
|
947
|
+
function createSvgObjectsFromAssemblyComponent(component, transform, firstPin, name) {
|
|
948
|
+
const { center, width, height, rotation = 0 } = component;
|
|
949
|
+
const [x, y] = applyToPoint15(transform, [center.x, center.y]);
|
|
950
|
+
const [pinX, pinY] = applyToPoint15(transform, [firstPin.x, firstPin.y]);
|
|
951
|
+
const scaledWidth = width * Math.abs(transform.a);
|
|
952
|
+
const scaledHeight = height * Math.abs(transform.d);
|
|
953
|
+
return {
|
|
954
|
+
name: "g",
|
|
955
|
+
type: "element",
|
|
956
|
+
value: "",
|
|
957
|
+
attributes: {
|
|
958
|
+
transform: `translate(${x}, ${y}) rotate(${-rotation}) scale(1, -1)`
|
|
959
|
+
},
|
|
960
|
+
children: [
|
|
961
|
+
createComponentPath(
|
|
962
|
+
scaledWidth,
|
|
963
|
+
scaledHeight,
|
|
964
|
+
x,
|
|
965
|
+
y,
|
|
966
|
+
pinX,
|
|
967
|
+
pinY,
|
|
968
|
+
rotation
|
|
969
|
+
),
|
|
970
|
+
createComponentLabel(scaledWidth, scaledHeight, name ?? "", transform)
|
|
971
|
+
]
|
|
972
|
+
};
|
|
973
|
+
}
|
|
974
|
+
function createComponentPath(scaledWidth, scaledHeight, centerX, centerY, pinX, pinY, rotation) {
|
|
975
|
+
const w = scaledWidth / 2;
|
|
976
|
+
const h = scaledHeight / 2;
|
|
977
|
+
const cornerSize = Math.min(w, h) * 0.3;
|
|
978
|
+
const isTop = pinY > centerY;
|
|
979
|
+
const isLeft = pinX < centerX;
|
|
980
|
+
const path = getComponentPathData(w, h, cornerSize, isTop, isLeft, rotation);
|
|
981
|
+
return {
|
|
982
|
+
name: "path",
|
|
983
|
+
type: "element",
|
|
984
|
+
attributes: {
|
|
985
|
+
class: "assembly-component",
|
|
986
|
+
d: path
|
|
987
|
+
},
|
|
988
|
+
value: "",
|
|
989
|
+
children: []
|
|
990
|
+
};
|
|
991
|
+
}
|
|
992
|
+
function createComponentLabel(scaledWidth, scaledHeight, name, transform) {
|
|
993
|
+
const scale7 = Math.min(scaledWidth, scaledHeight) * 0.4;
|
|
994
|
+
const fontSize = getSchScreenFontSize(transform, "net_label") * (scale7 / 2.5);
|
|
995
|
+
const scaledFontSize = scale7 < 25 ? fontSize : fontSize * 0.6;
|
|
996
|
+
return {
|
|
997
|
+
name: "text",
|
|
998
|
+
type: "element",
|
|
999
|
+
attributes: {
|
|
1000
|
+
x: "0",
|
|
1001
|
+
y: `${0 + scaledFontSize / 8}`,
|
|
1002
|
+
class: "assembly-component-label",
|
|
1003
|
+
"text-anchor": "middle",
|
|
1004
|
+
"dominant-baseline": "middle",
|
|
1005
|
+
"font-size": `${scaledFontSize}px`,
|
|
1006
|
+
transform: "scale(1, -1)"
|
|
1007
|
+
},
|
|
1008
|
+
children: [
|
|
1009
|
+
{
|
|
1010
|
+
type: "text",
|
|
1011
|
+
value: name || "",
|
|
1012
|
+
name: "",
|
|
1013
|
+
attributes: {},
|
|
1014
|
+
children: []
|
|
1015
|
+
}
|
|
1016
|
+
],
|
|
1017
|
+
value: ""
|
|
1018
|
+
};
|
|
1019
|
+
}
|
|
1020
|
+
function getComponentPathData(w, h, cornerSize, isTop, isLeft, rotation) {
|
|
1021
|
+
const rotatePoint = (x, y, angle) => {
|
|
1022
|
+
const rad = Math.PI / 180 * angle;
|
|
1023
|
+
const cos = Math.cos(rad);
|
|
1024
|
+
const sin = Math.sin(rad);
|
|
1025
|
+
return [x * cos - y * sin, x * sin + y * cos];
|
|
1026
|
+
};
|
|
1027
|
+
let corners;
|
|
1028
|
+
if (isTop && isLeft) {
|
|
1029
|
+
corners = [
|
|
1030
|
+
[-w, -h + cornerSize],
|
|
1031
|
+
[-w + cornerSize, -h],
|
|
1032
|
+
[w, -h],
|
|
1033
|
+
[w, h],
|
|
1034
|
+
[-w, h]
|
|
1035
|
+
];
|
|
1036
|
+
} else if (isTop && !isLeft) {
|
|
1037
|
+
corners = [
|
|
1038
|
+
[-w, -h],
|
|
1039
|
+
[w - cornerSize, -h],
|
|
1040
|
+
[w, -h + cornerSize],
|
|
1041
|
+
[w, h],
|
|
1042
|
+
[-w, h]
|
|
1043
|
+
];
|
|
1044
|
+
} else if (!isTop && isLeft) {
|
|
1045
|
+
corners = [
|
|
1046
|
+
[-w, -h],
|
|
1047
|
+
[w, -h],
|
|
1048
|
+
[w, h],
|
|
1049
|
+
[-w + cornerSize, h],
|
|
1050
|
+
[-w, h - cornerSize]
|
|
1051
|
+
];
|
|
1052
|
+
} else {
|
|
1053
|
+
corners = [
|
|
1054
|
+
[-w, -h],
|
|
1055
|
+
[w, -h],
|
|
1056
|
+
[w, h - cornerSize],
|
|
1057
|
+
[w - cornerSize, h],
|
|
1058
|
+
[-w, h]
|
|
1059
|
+
];
|
|
1060
|
+
}
|
|
1061
|
+
const rotatedCorners = corners.map(([x, y]) => rotatePoint(x, y, rotation));
|
|
1062
|
+
const path = rotatedCorners.map(([x, y], index) => index === 0 ? `M${x},${y}` : `L${x},${y}`).join(" ");
|
|
1063
|
+
return `${path} Z`;
|
|
1064
|
+
}
|
|
1065
|
+
|
|
1066
|
+
// lib/assembly/convert-circuit-json-to-assembly-svg.ts
|
|
1067
|
+
var OBJECT_ORDER2 = ["pcb_board", "pcb_component"];
|
|
1068
|
+
function convertCircuitJsonToAssemblySvg(soup, options) {
|
|
1069
|
+
let minX = Number.POSITIVE_INFINITY;
|
|
1070
|
+
let minY = Number.POSITIVE_INFINITY;
|
|
1071
|
+
let maxX = Number.NEGATIVE_INFINITY;
|
|
1072
|
+
let maxY = Number.NEGATIVE_INFINITY;
|
|
1073
|
+
for (const item of soup) {
|
|
1074
|
+
if (item.type === "pcb_board") {
|
|
1075
|
+
const center = item.center;
|
|
1076
|
+
const width = item.width || 0;
|
|
1077
|
+
const height = item.height || 0;
|
|
1078
|
+
minX = Math.min(minX, center.x - width / 2);
|
|
1079
|
+
minY = Math.min(minY, center.y - height / 2);
|
|
1080
|
+
maxX = Math.max(maxX, center.x + width / 2);
|
|
1081
|
+
maxY = Math.max(maxY, center.y + height / 2);
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
1084
|
+
const padding = 1;
|
|
1085
|
+
const circuitWidth = maxX - minX + 2 * padding;
|
|
1086
|
+
const circuitHeight = maxY - minY + 2 * padding;
|
|
1087
|
+
const svgWidth = options?.width ?? 800;
|
|
1088
|
+
const svgHeight = options?.height ?? 600;
|
|
1089
|
+
const scaleX = svgWidth / circuitWidth;
|
|
1090
|
+
const scaleY = svgHeight / circuitHeight;
|
|
1091
|
+
const scaleFactor = Math.min(scaleX, scaleY);
|
|
1092
|
+
const offsetX = (svgWidth - circuitWidth * scaleFactor) / 2;
|
|
1093
|
+
const offsetY = (svgHeight - circuitHeight * scaleFactor) / 2;
|
|
1094
|
+
const transform = compose4(
|
|
1095
|
+
translate4(
|
|
1096
|
+
offsetX - minX * scaleFactor + padding * scaleFactor,
|
|
1097
|
+
svgHeight - offsetY + minY * scaleFactor - padding * scaleFactor
|
|
1098
|
+
),
|
|
1099
|
+
scale2(scaleFactor, -scaleFactor)
|
|
1100
|
+
// Flip in y-direction
|
|
1101
|
+
);
|
|
1102
|
+
const svgObjects = soup.sort(
|
|
1103
|
+
(a, b) => (OBJECT_ORDER2.indexOf(b.type) ?? 9999) - (OBJECT_ORDER2.indexOf(a.type) ?? 9999)
|
|
1104
|
+
).flatMap((item) => createSvgObjects2(item, transform, soup));
|
|
1105
|
+
const svgObject = {
|
|
1106
|
+
name: "svg",
|
|
1107
|
+
type: "element",
|
|
1108
|
+
attributes: {
|
|
1109
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
1110
|
+
width: svgWidth.toString(),
|
|
1111
|
+
height: svgHeight.toString()
|
|
1112
|
+
},
|
|
1113
|
+
value: "",
|
|
1114
|
+
children: [
|
|
1115
|
+
{
|
|
1116
|
+
name: "style",
|
|
1117
|
+
type: "element",
|
|
1118
|
+
children: [
|
|
1119
|
+
{
|
|
1120
|
+
type: "text",
|
|
1121
|
+
value: `
|
|
1122
|
+
.assembly-component { fill: #fff; stroke: #000; stroke-width: 3; }
|
|
1123
|
+
.assembly-board { fill: #f2f2f2; stroke: rgb(0,0,0); stroke-opacity: 0.8; }
|
|
1124
|
+
.assembly-component-label {
|
|
1125
|
+
fill: #000;
|
|
1126
|
+
font-family: Arial, serif;
|
|
1127
|
+
font-weight: bold;
|
|
1128
|
+
}
|
|
1129
|
+
.assembly-boundary { fill: none; stroke: #fff; stroke-width: 0.3; }
|
|
1130
|
+
`,
|
|
1131
|
+
name: "",
|
|
1132
|
+
attributes: {},
|
|
1133
|
+
children: []
|
|
1134
|
+
}
|
|
1135
|
+
],
|
|
1136
|
+
value: "",
|
|
1137
|
+
attributes: {}
|
|
1138
|
+
},
|
|
1139
|
+
{
|
|
1140
|
+
name: "rect",
|
|
1141
|
+
type: "element",
|
|
1142
|
+
attributes: {
|
|
1143
|
+
fill: "#fff",
|
|
1144
|
+
x: "0",
|
|
1145
|
+
y: "0",
|
|
1146
|
+
width: svgWidth.toString(),
|
|
1147
|
+
height: svgHeight.toString()
|
|
1148
|
+
},
|
|
1149
|
+
value: "",
|
|
1150
|
+
children: []
|
|
1151
|
+
},
|
|
1152
|
+
createSvgObjectFromAssemblyBoundary(transform, minX, minY, maxX, maxY),
|
|
1153
|
+
...svgObjects
|
|
1154
|
+
].filter((child) => child !== null)
|
|
1155
|
+
};
|
|
1156
|
+
return stringify2(svgObject);
|
|
1157
|
+
}
|
|
1158
|
+
function createSvgObjects2(elm, transform, soup) {
|
|
1159
|
+
const sourceComponents = su(soup).source_component.list();
|
|
1160
|
+
switch (elm.type) {
|
|
1161
|
+
case "pcb_board":
|
|
1162
|
+
return createSvgObjectsFromAssemblyBoard(elm, transform);
|
|
1163
|
+
case "pcb_component": {
|
|
1164
|
+
const sourceComponent = sourceComponents.find(
|
|
1165
|
+
(item) => item.source_component_id === elm.source_component_id
|
|
1166
|
+
);
|
|
1167
|
+
const ports = su(soup).pcb_port.list().filter((port) => port.pcb_component_id === elm.pcb_component_id);
|
|
1168
|
+
const firstPort = ports[0];
|
|
1169
|
+
if (sourceComponent && firstPort) {
|
|
1170
|
+
return [
|
|
1171
|
+
createSvgObjectsFromAssemblyComponent(
|
|
1172
|
+
elm,
|
|
1173
|
+
transform,
|
|
1174
|
+
{ x: firstPort.x, y: firstPort.y },
|
|
1175
|
+
sourceComponent.name
|
|
1176
|
+
)
|
|
1177
|
+
].filter(Boolean);
|
|
1178
|
+
}
|
|
1179
|
+
return [];
|
|
1180
|
+
}
|
|
1181
|
+
default:
|
|
1182
|
+
return [];
|
|
1183
|
+
}
|
|
1184
|
+
}
|
|
1185
|
+
function createSvgObjectFromAssemblyBoundary(transform, minX, minY, maxX, maxY) {
|
|
1186
|
+
const [x1, y1] = applyToPoint16(transform, [minX, minY]);
|
|
1187
|
+
const [x2, y2] = applyToPoint16(transform, [maxX, maxY]);
|
|
1188
|
+
const width = Math.abs(x2 - x1);
|
|
1189
|
+
const height = Math.abs(y2 - y1);
|
|
1190
|
+
const x = Math.min(x1, x2);
|
|
1191
|
+
const y = Math.min(y1, y2);
|
|
1192
|
+
return {
|
|
1193
|
+
name: "rect",
|
|
1194
|
+
type: "element",
|
|
1195
|
+
value: "",
|
|
1196
|
+
children: [],
|
|
1197
|
+
attributes: {
|
|
1198
|
+
class: "assembly-boundary",
|
|
1199
|
+
x: x.toString(),
|
|
1200
|
+
y: y.toString(),
|
|
1201
|
+
width: width.toString(),
|
|
1202
|
+
height: height.toString()
|
|
1203
|
+
}
|
|
1204
|
+
};
|
|
1205
|
+
}
|
|
1206
|
+
|
|
868
1207
|
// lib/utils/colors.ts
|
|
869
1208
|
var colorMap = {
|
|
870
1209
|
"3d_viewer": {
|
|
@@ -1103,20 +1442,20 @@ var colorMap = {
|
|
|
1103
1442
|
};
|
|
1104
1443
|
|
|
1105
1444
|
// lib/sch/convert-circuit-json-to-schematic-svg.ts
|
|
1106
|
-
import { stringify as
|
|
1445
|
+
import { stringify as stringify3 } from "svgson";
|
|
1107
1446
|
import {
|
|
1108
1447
|
fromTriangles
|
|
1109
1448
|
} from "transformation-matrix";
|
|
1110
1449
|
|
|
1111
1450
|
// lib/sch/draw-schematic-grid.ts
|
|
1112
|
-
import { applyToPoint as
|
|
1451
|
+
import { applyToPoint as applyToPoint17 } from "transformation-matrix";
|
|
1113
1452
|
function drawSchematicGrid(params) {
|
|
1114
1453
|
const { minX, minY, maxX, maxY } = params.bounds;
|
|
1115
1454
|
const cellSize = params.cellSize ?? 1;
|
|
1116
1455
|
const labelCells = params.labelCells ?? false;
|
|
1117
1456
|
const gridLines = [];
|
|
1118
1457
|
const transformPoint = (x, y) => {
|
|
1119
|
-
const [transformedX, transformedY] =
|
|
1458
|
+
const [transformedX, transformedY] = applyToPoint17(params.transform, [x, y]);
|
|
1120
1459
|
return { x: transformedX, y: transformedY };
|
|
1121
1460
|
};
|
|
1122
1461
|
for (let x = Math.floor(minX); x <= Math.ceil(maxX); x += cellSize) {
|
|
@@ -1197,15 +1536,15 @@ function drawSchematicGrid(params) {
|
|
|
1197
1536
|
}
|
|
1198
1537
|
|
|
1199
1538
|
// lib/sch/draw-schematic-labeled-points.ts
|
|
1200
|
-
import { applyToPoint as
|
|
1539
|
+
import { applyToPoint as applyToPoint18 } from "transformation-matrix";
|
|
1201
1540
|
function drawSchematicLabeledPoints(params) {
|
|
1202
1541
|
const { points, transform } = params;
|
|
1203
1542
|
const labeledPointsGroup = [];
|
|
1204
1543
|
for (const point of points) {
|
|
1205
|
-
const [x1, y1] =
|
|
1206
|
-
const [x2, y2] =
|
|
1207
|
-
const [x3, y3] =
|
|
1208
|
-
const [x4, y4] =
|
|
1544
|
+
const [x1, y1] = applyToPoint18(transform, [point.x - 0.1, point.y - 0.1]);
|
|
1545
|
+
const [x2, y2] = applyToPoint18(transform, [point.x + 0.1, point.y + 0.1]);
|
|
1546
|
+
const [x3, y3] = applyToPoint18(transform, [point.x - 0.1, point.y + 0.1]);
|
|
1547
|
+
const [x4, y4] = applyToPoint18(transform, [point.x + 0.1, point.y - 0.1]);
|
|
1209
1548
|
labeledPointsGroup.push({
|
|
1210
1549
|
name: "path",
|
|
1211
1550
|
type: "element",
|
|
@@ -1216,7 +1555,7 @@ function drawSchematicLabeledPoints(params) {
|
|
|
1216
1555
|
"stroke-opacity": "0.7"
|
|
1217
1556
|
}
|
|
1218
1557
|
});
|
|
1219
|
-
const [labelX, labelY] =
|
|
1558
|
+
const [labelX, labelY] = applyToPoint18(transform, [
|
|
1220
1559
|
point.x + 0.15,
|
|
1221
1560
|
point.y - 0.15
|
|
1222
1561
|
]);
|
|
@@ -1309,12 +1648,12 @@ function getSchematicBoundsFromCircuitJson(soup, padding = 0.5) {
|
|
|
1309
1648
|
}
|
|
1310
1649
|
|
|
1311
1650
|
// lib/sch/svg-object-fns/create-svg-objects-from-sch-component-with-symbol.ts
|
|
1312
|
-
import { su } from "@tscircuit/soup-util";
|
|
1651
|
+
import { su as su2 } from "@tscircuit/soup-util";
|
|
1313
1652
|
import { symbols } from "schematic-symbols";
|
|
1314
1653
|
import "svgson";
|
|
1315
1654
|
import {
|
|
1316
|
-
applyToPoint as
|
|
1317
|
-
compose as
|
|
1655
|
+
applyToPoint as applyToPoint20,
|
|
1656
|
+
compose as compose6
|
|
1318
1657
|
} from "transformation-matrix";
|
|
1319
1658
|
|
|
1320
1659
|
// lib/utils/get-sch-stroke-size.ts
|
|
@@ -1384,35 +1723,26 @@ var matchSchPortsToSymbolPorts = ({
|
|
|
1384
1723
|
};
|
|
1385
1724
|
|
|
1386
1725
|
// lib/utils/point-pairs-to-matrix.ts
|
|
1387
|
-
import { compose as
|
|
1726
|
+
import { compose as compose5, scale as scale3, translate as translate5 } from "transformation-matrix";
|
|
1388
1727
|
function pointPairsToMatrix(a1, a2, b1, b2) {
|
|
1389
1728
|
const tx = a2.x - a1.x;
|
|
1390
1729
|
const ty = a2.y - a1.y;
|
|
1391
1730
|
const originalDistance = Math.sqrt((b1.x - a1.x) ** 2 + (b1.y - a1.y) ** 2);
|
|
1392
1731
|
const transformedDistance = Math.sqrt((b2.x - a2.x) ** 2 + (b2.y - a2.y) ** 2);
|
|
1393
1732
|
const a = transformedDistance / originalDistance;
|
|
1394
|
-
const translateMatrix =
|
|
1395
|
-
const scaleMatrix =
|
|
1396
|
-
return
|
|
1733
|
+
const translateMatrix = translate5(tx, ty);
|
|
1734
|
+
const scaleMatrix = scale3(a, a);
|
|
1735
|
+
return compose5(translateMatrix, scaleMatrix);
|
|
1397
1736
|
}
|
|
1398
1737
|
|
|
1399
|
-
// lib/utils/get-sch-font-size.ts
|
|
1400
|
-
import "transformation-matrix";
|
|
1401
|
-
var getSchMmFontSize = (textType) => {
|
|
1402
|
-
return textType === "error" ? 0.05 : textType === "pin_number" ? 0.15 : 0.18;
|
|
1403
|
-
};
|
|
1404
|
-
var getSchScreenFontSize = (transform, textType) => {
|
|
1405
|
-
return Math.abs(transform.a) * getSchMmFontSize(textType);
|
|
1406
|
-
};
|
|
1407
|
-
|
|
1408
1738
|
// lib/sch/svg-object-fns/create-svg-error-text.ts
|
|
1409
|
-
import { applyToPoint as
|
|
1739
|
+
import { applyToPoint as applyToPoint19 } from "transformation-matrix";
|
|
1410
1740
|
var createSvgSchErrorText = ({
|
|
1411
1741
|
text,
|
|
1412
1742
|
realCenter,
|
|
1413
1743
|
realToScreenTransform
|
|
1414
1744
|
}) => {
|
|
1415
|
-
const screenCenter =
|
|
1745
|
+
const screenCenter = applyToPoint19(realToScreenTransform, realCenter);
|
|
1416
1746
|
return {
|
|
1417
1747
|
type: "element",
|
|
1418
1748
|
name: "text",
|
|
@@ -1477,10 +1807,10 @@ var createSvgObjectsFromSchematicComponentWithSymbol = ({
|
|
|
1477
1807
|
})
|
|
1478
1808
|
];
|
|
1479
1809
|
}
|
|
1480
|
-
const schPorts =
|
|
1810
|
+
const schPorts = su2(circuitJson).schematic_port.list({
|
|
1481
1811
|
schematic_component_id: schComponent.schematic_component_id
|
|
1482
1812
|
});
|
|
1483
|
-
const srcComponent =
|
|
1813
|
+
const srcComponent = su2(circuitJson).source_component.get(
|
|
1484
1814
|
schComponent.source_component_id
|
|
1485
1815
|
);
|
|
1486
1816
|
const schPortsWithSymbolPorts = matchSchPortsToSymbolPorts({
|
|
@@ -1513,12 +1843,12 @@ var createSvgObjectsFromSchematicComponentWithSymbol = ({
|
|
|
1513
1843
|
minY: Math.min(...paths.flatMap((p) => p.points.map((pt) => pt.y))),
|
|
1514
1844
|
maxY: Math.max(...paths.flatMap((p) => p.points.map((pt) => pt.y)))
|
|
1515
1845
|
};
|
|
1516
|
-
const [screenMinX, screenMinY] =
|
|
1517
|
-
|
|
1846
|
+
const [screenMinX, screenMinY] = applyToPoint20(
|
|
1847
|
+
compose6(realToScreenTransform, transformFromSymbolToReal),
|
|
1518
1848
|
[bounds.minX, bounds.minY]
|
|
1519
1849
|
);
|
|
1520
|
-
const [screenMaxX, screenMaxY] =
|
|
1521
|
-
|
|
1850
|
+
const [screenMaxX, screenMaxY] = applyToPoint20(
|
|
1851
|
+
compose6(realToScreenTransform, transformFromSymbolToReal),
|
|
1522
1852
|
[bounds.maxX, bounds.maxY]
|
|
1523
1853
|
);
|
|
1524
1854
|
const rectHeight = Math.abs(screenMaxY - screenMinY);
|
|
@@ -1546,8 +1876,8 @@ var createSvgObjectsFromSchematicComponentWithSymbol = ({
|
|
|
1546
1876
|
name: "path",
|
|
1547
1877
|
attributes: {
|
|
1548
1878
|
d: points.map((p, i) => {
|
|
1549
|
-
const [x, y] =
|
|
1550
|
-
|
|
1879
|
+
const [x, y] = applyToPoint20(
|
|
1880
|
+
compose6(realToScreenTransform, transformFromSymbolToReal),
|
|
1551
1881
|
[p.x, p.y]
|
|
1552
1882
|
);
|
|
1553
1883
|
return `${i === 0 ? "M" : "L"} ${x} ${y}`;
|
|
@@ -1561,8 +1891,8 @@ var createSvgObjectsFromSchematicComponentWithSymbol = ({
|
|
|
1561
1891
|
});
|
|
1562
1892
|
}
|
|
1563
1893
|
for (const text of texts) {
|
|
1564
|
-
const screenTextPos =
|
|
1565
|
-
|
|
1894
|
+
const screenTextPos = applyToPoint20(
|
|
1895
|
+
compose6(realToScreenTransform, transformFromSymbolToReal),
|
|
1566
1896
|
text
|
|
1567
1897
|
);
|
|
1568
1898
|
let textValue = "";
|
|
@@ -1595,11 +1925,11 @@ var createSvgObjectsFromSchematicComponentWithSymbol = ({
|
|
|
1595
1925
|
});
|
|
1596
1926
|
}
|
|
1597
1927
|
for (const box of boxes) {
|
|
1598
|
-
const screenBoxPos =
|
|
1599
|
-
|
|
1928
|
+
const screenBoxPos = applyToPoint20(
|
|
1929
|
+
compose6(realToScreenTransform, transformFromSymbolToReal),
|
|
1600
1930
|
box
|
|
1601
1931
|
);
|
|
1602
|
-
const symbolToScreenScale =
|
|
1932
|
+
const symbolToScreenScale = compose6(
|
|
1603
1933
|
realToScreenTransform,
|
|
1604
1934
|
transformFromSymbolToReal
|
|
1605
1935
|
).a;
|
|
@@ -1618,8 +1948,8 @@ var createSvgObjectsFromSchematicComponentWithSymbol = ({
|
|
|
1618
1948
|
});
|
|
1619
1949
|
}
|
|
1620
1950
|
for (const port of symbol.ports) {
|
|
1621
|
-
const screenPortPos =
|
|
1622
|
-
|
|
1951
|
+
const screenPortPos = applyToPoint20(
|
|
1952
|
+
compose6(realToScreenTransform, transformFromSymbolToReal),
|
|
1623
1953
|
port
|
|
1624
1954
|
);
|
|
1625
1955
|
svgObjects.push({
|
|
@@ -1641,18 +1971,18 @@ var createSvgObjectsFromSchematicComponentWithSymbol = ({
|
|
|
1641
1971
|
};
|
|
1642
1972
|
|
|
1643
1973
|
// lib/sch/svg-object-fns/create-svg-objects-from-sch-component-with-box.ts
|
|
1644
|
-
import { su as
|
|
1974
|
+
import { su as su5 } from "@tscircuit/soup-util";
|
|
1645
1975
|
import "schematic-symbols";
|
|
1646
1976
|
import "svgson";
|
|
1647
|
-
import { applyToPoint as
|
|
1977
|
+
import { applyToPoint as applyToPoint25 } from "transformation-matrix";
|
|
1648
1978
|
|
|
1649
1979
|
// lib/sch/svg-object-fns/create-svg-objects-from-sch-port-on-box.ts
|
|
1650
1980
|
import "transformation-matrix";
|
|
1651
1981
|
import "@tscircuit/soup-util";
|
|
1652
1982
|
|
|
1653
1983
|
// lib/sch/svg-object-fns/create-svg-objects-for-sch-port-box-line.ts
|
|
1654
|
-
import { applyToPoint as
|
|
1655
|
-
import { su as
|
|
1984
|
+
import { applyToPoint as applyToPoint21 } from "transformation-matrix";
|
|
1985
|
+
import { su as su3 } from "@tscircuit/soup-util";
|
|
1656
1986
|
var PIN_CIRCLE_RADIUS_MM = 0.02;
|
|
1657
1987
|
var createSvgObjectsForSchPortBoxLine = ({
|
|
1658
1988
|
schPort,
|
|
@@ -1661,7 +1991,7 @@ var createSvgObjectsForSchPortBoxLine = ({
|
|
|
1661
1991
|
circuitJson
|
|
1662
1992
|
}) => {
|
|
1663
1993
|
const svgObjects = [];
|
|
1664
|
-
const srcPort =
|
|
1994
|
+
const srcPort = su3(circuitJson).source_port.get(schPort.source_port_id);
|
|
1665
1995
|
const realEdgePos = {
|
|
1666
1996
|
x: schPort.center.x,
|
|
1667
1997
|
y: schPort.center.y
|
|
@@ -1681,8 +2011,8 @@ var createSvgObjectsForSchPortBoxLine = ({
|
|
|
1681
2011
|
realEdgePos.y += realPinLineLength;
|
|
1682
2012
|
break;
|
|
1683
2013
|
}
|
|
1684
|
-
const screenSchPortPos =
|
|
1685
|
-
const screenRealEdgePos =
|
|
2014
|
+
const screenSchPortPos = applyToPoint21(transform, schPort.center);
|
|
2015
|
+
const screenRealEdgePos = applyToPoint21(transform, realEdgePos);
|
|
1686
2016
|
const realLineEnd = { ...schPort.center };
|
|
1687
2017
|
switch (schPort.side_of_component) {
|
|
1688
2018
|
case "left":
|
|
@@ -1698,7 +2028,7 @@ var createSvgObjectsForSchPortBoxLine = ({
|
|
|
1698
2028
|
realLineEnd.y += PIN_CIRCLE_RADIUS_MM;
|
|
1699
2029
|
break;
|
|
1700
2030
|
}
|
|
1701
|
-
const screenLineEnd =
|
|
2031
|
+
const screenLineEnd = applyToPoint21(transform, realLineEnd);
|
|
1702
2032
|
svgObjects.push({
|
|
1703
2033
|
name: "line",
|
|
1704
2034
|
type: "element",
|
|
@@ -1745,7 +2075,7 @@ var getUnitVectorFromOutsideToEdge = (side) => {
|
|
|
1745
2075
|
};
|
|
1746
2076
|
|
|
1747
2077
|
// lib/sch/svg-object-fns/create-svg-objects-for-sch-port-pin-number-text.ts
|
|
1748
|
-
import { applyToPoint as
|
|
2078
|
+
import { applyToPoint as applyToPoint22 } from "transformation-matrix";
|
|
1749
2079
|
var createSvgObjectsForSchPortPinNumberText = (params) => {
|
|
1750
2080
|
const svgObjects = [];
|
|
1751
2081
|
const { schPort, schComponent, transform, circuitJson } = params;
|
|
@@ -1763,7 +2093,7 @@ var createSvgObjectsForSchPortPinNumberText = (params) => {
|
|
|
1763
2093
|
} else {
|
|
1764
2094
|
realPinNumberPos.y += 0.02;
|
|
1765
2095
|
}
|
|
1766
|
-
const screenPinNumberTextPos =
|
|
2096
|
+
const screenPinNumberTextPos = applyToPoint22(transform, realPinNumberPos);
|
|
1767
2097
|
svgObjects.push({
|
|
1768
2098
|
name: "text",
|
|
1769
2099
|
type: "element",
|
|
@@ -1793,7 +2123,7 @@ var createSvgObjectsForSchPortPinNumberText = (params) => {
|
|
|
1793
2123
|
};
|
|
1794
2124
|
|
|
1795
2125
|
// lib/sch/svg-object-fns/create-svg-objects-for-sch-port-pin-label.ts
|
|
1796
|
-
import { applyToPoint as
|
|
2126
|
+
import { applyToPoint as applyToPoint23 } from "transformation-matrix";
|
|
1797
2127
|
var LABEL_DIST_FROM_EDGE_MM = 0.1;
|
|
1798
2128
|
var createSvgObjectsForSchPortPinLabel = (params) => {
|
|
1799
2129
|
const svgObjects = [];
|
|
@@ -1807,7 +2137,7 @@ var createSvgObjectsForSchPortPinLabel = (params) => {
|
|
|
1807
2137
|
const realPinEdgeDistance = schPort.distance_from_component_edge ?? 0.4;
|
|
1808
2138
|
realPinNumberPos.x += vecToEdge.x * (realPinEdgeDistance + LABEL_DIST_FROM_EDGE_MM);
|
|
1809
2139
|
realPinNumberPos.y += vecToEdge.y * (realPinEdgeDistance + LABEL_DIST_FROM_EDGE_MM);
|
|
1810
|
-
const screenPinNumberTextPos =
|
|
2140
|
+
const screenPinNumberTextPos = applyToPoint23(transform, realPinNumberPos);
|
|
1811
2141
|
const label = schPort.display_pin_label ?? schComponent.port_labels?.[`${schPort.pin_number}`];
|
|
1812
2142
|
if (!label) return [];
|
|
1813
2143
|
svgObjects.push({
|
|
@@ -1855,11 +2185,11 @@ var createSvgObjectsFromSchematicComponentWithBox = ({
|
|
|
1855
2185
|
circuitJson
|
|
1856
2186
|
}) => {
|
|
1857
2187
|
const svgObjects = [];
|
|
1858
|
-
const componentScreenTopLeft =
|
|
2188
|
+
const componentScreenTopLeft = applyToPoint25(transform, {
|
|
1859
2189
|
x: schComponent.center.x - schComponent.size.width / 2,
|
|
1860
2190
|
y: schComponent.center.y + schComponent.size.height / 2
|
|
1861
2191
|
});
|
|
1862
|
-
const componentScreenBottomRight =
|
|
2192
|
+
const componentScreenBottomRight = applyToPoint25(transform, {
|
|
1863
2193
|
x: schComponent.center.x + schComponent.size.width / 2,
|
|
1864
2194
|
y: schComponent.center.y - schComponent.size.height / 2
|
|
1865
2195
|
});
|
|
@@ -1895,7 +2225,7 @@ var createSvgObjectsFromSchematicComponentWithBox = ({
|
|
|
1895
2225
|
},
|
|
1896
2226
|
children: []
|
|
1897
2227
|
});
|
|
1898
|
-
const schematicPorts =
|
|
2228
|
+
const schematicPorts = su5(circuitJson).schematic_port.list({
|
|
1899
2229
|
schematic_component_id: schComponent.schematic_component_id
|
|
1900
2230
|
});
|
|
1901
2231
|
for (const schPort of schematicPorts) {
|
|
@@ -1930,9 +2260,9 @@ function createSvgObjectsFromSchematicComponent(params) {
|
|
|
1930
2260
|
}
|
|
1931
2261
|
|
|
1932
2262
|
// lib/sch/svg-object-fns/create-svg-objects-from-sch-voltage-probe.ts
|
|
1933
|
-
import { applyToPoint as
|
|
2263
|
+
import { applyToPoint as applyToPoint26 } from "transformation-matrix";
|
|
1934
2264
|
function createSvgObjectsFromSchVoltageProbe(probe, transform) {
|
|
1935
|
-
const [screenX, screenY] =
|
|
2265
|
+
const [screenX, screenY] = applyToPoint26(transform, [
|
|
1936
2266
|
probe.position.x,
|
|
1937
2267
|
probe.position.y
|
|
1938
2268
|
]);
|
|
@@ -1992,14 +2322,14 @@ function createSvgObjectsFromSchVoltageProbe(probe, transform) {
|
|
|
1992
2322
|
}
|
|
1993
2323
|
|
|
1994
2324
|
// lib/sch/svg-object-fns/create-svg-objects-from-sch-debug-object.ts
|
|
1995
|
-
import { applyToPoint as
|
|
2325
|
+
import { applyToPoint as applyToPoint27 } from "transformation-matrix";
|
|
1996
2326
|
function createSvgObjectsFromSchDebugObject(debugObject, transform) {
|
|
1997
2327
|
if (debugObject.shape === "rect") {
|
|
1998
|
-
let [screenLeft, screenTop] =
|
|
2328
|
+
let [screenLeft, screenTop] = applyToPoint27(transform, [
|
|
1999
2329
|
debugObject.center.x - debugObject.size.width / 2,
|
|
2000
2330
|
debugObject.center.y - debugObject.size.height / 2
|
|
2001
2331
|
]);
|
|
2002
|
-
let [screenRight, screenBottom] =
|
|
2332
|
+
let [screenRight, screenBottom] = applyToPoint27(transform, [
|
|
2003
2333
|
debugObject.center.x + debugObject.size.width / 2,
|
|
2004
2334
|
debugObject.center.y + debugObject.size.height / 2
|
|
2005
2335
|
]);
|
|
@@ -2009,7 +2339,7 @@ function createSvgObjectsFromSchDebugObject(debugObject, transform) {
|
|
|
2009
2339
|
];
|
|
2010
2340
|
const width = Math.abs(screenRight - screenLeft);
|
|
2011
2341
|
const height = Math.abs(screenBottom - screenTop);
|
|
2012
|
-
const [screenCenterX, screenCenterY] =
|
|
2342
|
+
const [screenCenterX, screenCenterY] = applyToPoint27(transform, [
|
|
2013
2343
|
debugObject.center.x,
|
|
2014
2344
|
debugObject.center.y
|
|
2015
2345
|
]);
|
|
@@ -2055,11 +2385,11 @@ function createSvgObjectsFromSchDebugObject(debugObject, transform) {
|
|
|
2055
2385
|
];
|
|
2056
2386
|
}
|
|
2057
2387
|
if (debugObject.shape === "line") {
|
|
2058
|
-
const [screenStartX, screenStartY] =
|
|
2388
|
+
const [screenStartX, screenStartY] = applyToPoint27(transform, [
|
|
2059
2389
|
debugObject.start.x,
|
|
2060
2390
|
debugObject.start.y
|
|
2061
2391
|
]);
|
|
2062
|
-
const [screenEndX, screenEndY] =
|
|
2392
|
+
const [screenEndX, screenEndY] = applyToPoint27(transform, [
|
|
2063
2393
|
debugObject.end.x,
|
|
2064
2394
|
debugObject.end.y
|
|
2065
2395
|
]);
|
|
@@ -2109,7 +2439,7 @@ function createSvgObjectsFromSchDebugObject(debugObject, transform) {
|
|
|
2109
2439
|
}
|
|
2110
2440
|
|
|
2111
2441
|
// lib/sch/svg-object-fns/create-svg-objects-from-sch-trace.ts
|
|
2112
|
-
import { applyToPoint as
|
|
2442
|
+
import { applyToPoint as applyToPoint28 } from "transformation-matrix";
|
|
2113
2443
|
function createSchematicTrace(trace, transform) {
|
|
2114
2444
|
const edges = trace.edges;
|
|
2115
2445
|
if (edges.length === 0) return [];
|
|
@@ -2118,11 +2448,11 @@ function createSchematicTrace(trace, transform) {
|
|
|
2118
2448
|
for (let edgeIndex = 0; edgeIndex < edges.length; edgeIndex++) {
|
|
2119
2449
|
const edge = edges[edgeIndex];
|
|
2120
2450
|
if (edge.is_crossing) continue;
|
|
2121
|
-
const [screenFromX, screenFromY] =
|
|
2451
|
+
const [screenFromX, screenFromY] = applyToPoint28(transform, [
|
|
2122
2452
|
edge.from.x,
|
|
2123
2453
|
edge.from.y
|
|
2124
2454
|
]);
|
|
2125
|
-
const [screenToX, screenToY] =
|
|
2455
|
+
const [screenToX, screenToY] = applyToPoint28(transform, [
|
|
2126
2456
|
edge.to.x,
|
|
2127
2457
|
edge.to.y
|
|
2128
2458
|
]);
|
|
@@ -2134,11 +2464,11 @@ function createSchematicTrace(trace, transform) {
|
|
|
2134
2464
|
}
|
|
2135
2465
|
for (const edge of edges) {
|
|
2136
2466
|
if (!edge.is_crossing) continue;
|
|
2137
|
-
const [screenFromX, screenFromY] =
|
|
2467
|
+
const [screenFromX, screenFromY] = applyToPoint28(transform, [
|
|
2138
2468
|
edge.from.x,
|
|
2139
2469
|
edge.from.y
|
|
2140
2470
|
]);
|
|
2141
|
-
const [screenToX, screenToY] =
|
|
2471
|
+
const [screenToX, screenToY] = applyToPoint28(transform, [
|
|
2142
2472
|
edge.to.x,
|
|
2143
2473
|
edge.to.y
|
|
2144
2474
|
]);
|
|
@@ -2214,7 +2544,7 @@ function createSchematicTrace(trace, transform) {
|
|
|
2214
2544
|
}
|
|
2215
2545
|
if (trace.junctions) {
|
|
2216
2546
|
for (const junction of trace.junctions) {
|
|
2217
|
-
const [screenX, screenY] =
|
|
2547
|
+
const [screenX, screenY] = applyToPoint28(transform, [
|
|
2218
2548
|
junction.x,
|
|
2219
2549
|
junction.y
|
|
2220
2550
|
]);
|
|
@@ -2247,11 +2577,11 @@ function createSchematicTrace(trace, transform) {
|
|
|
2247
2577
|
|
|
2248
2578
|
// lib/sch/svg-object-fns/create-svg-objects-for-sch-net-label.ts
|
|
2249
2579
|
import {
|
|
2250
|
-
applyToPoint as
|
|
2251
|
-
compose as
|
|
2252
|
-
rotate as
|
|
2253
|
-
scale as
|
|
2254
|
-
translate as
|
|
2580
|
+
applyToPoint as applyToPoint30,
|
|
2581
|
+
compose as compose8,
|
|
2582
|
+
rotate as rotate4,
|
|
2583
|
+
scale as scale5,
|
|
2584
|
+
translate as translate8
|
|
2255
2585
|
} from "transformation-matrix";
|
|
2256
2586
|
|
|
2257
2587
|
// lib/sch/arial-text-metrics.ts
|
|
@@ -3033,193 +3363,22 @@ var estimateTextWidth = (text) => {
|
|
|
3033
3363
|
return totalWidth / 27;
|
|
3034
3364
|
};
|
|
3035
3365
|
|
|
3036
|
-
// lib/sch/svg-object-fns/create-svg-objects-for-sch-net-label.ts
|
|
3366
|
+
// lib/sch/svg-object-fns/create-svg-objects-for-sch-net-label-with-symbol.ts
|
|
3367
|
+
import {
|
|
3368
|
+
applyToPoint as applyToPoint29,
|
|
3369
|
+
compose as compose7,
|
|
3370
|
+
rotate as rotate3,
|
|
3371
|
+
scale as scale4,
|
|
3372
|
+
translate as translate7
|
|
3373
|
+
} from "transformation-matrix";
|
|
3374
|
+
import { symbols as symbols3 } from "schematic-symbols";
|
|
3375
|
+
|
|
3376
|
+
// lib/utils/net-label-utils.ts
|
|
3377
|
+
import "transformation-matrix";
|
|
3378
|
+
import "schematic-symbols";
|
|
3037
3379
|
var ARROW_POINT_WIDTH_FSR = 0.3;
|
|
3038
3380
|
var END_PADDING_FSR = 0.3;
|
|
3039
3381
|
var END_PADDING_EXTRA_PER_CHARACTER_FSR = 0.06;
|
|
3040
|
-
var createSvgObjectsForSchNetLabel = (schNetLabel, realToScreenTransform) => {
|
|
3041
|
-
if (!schNetLabel.text) return [];
|
|
3042
|
-
const svgObjects = [];
|
|
3043
|
-
const fontSizePx = getSchScreenFontSize(realToScreenTransform, "net_label");
|
|
3044
|
-
const fontSizeMm = getSchMmFontSize("net_label");
|
|
3045
|
-
const textWidthFSR = estimateTextWidth(schNetLabel.text || "");
|
|
3046
|
-
const screenCenter = applyToPoint26(realToScreenTransform, schNetLabel.center);
|
|
3047
|
-
const realTextGrowthVec = getUnitVectorFromOutsideToEdge(
|
|
3048
|
-
schNetLabel.anchor_side
|
|
3049
|
-
);
|
|
3050
|
-
const screenTextGrowthVec = { ...realTextGrowthVec };
|
|
3051
|
-
screenTextGrowthVec.y *= -1;
|
|
3052
|
-
const fullWidthFsr = textWidthFSR + ARROW_POINT_WIDTH_FSR * 2 + END_PADDING_EXTRA_PER_CHARACTER_FSR * schNetLabel.text.length + END_PADDING_FSR;
|
|
3053
|
-
const screenAnchorPosition = schNetLabel.anchor_position ? applyToPoint26(realToScreenTransform, schNetLabel.anchor_position) : {
|
|
3054
|
-
x: screenCenter.x - screenTextGrowthVec.x * fullWidthFsr * fontSizePx / 2,
|
|
3055
|
-
y: screenCenter.y - screenTextGrowthVec.y * fullWidthFsr * fontSizePx / 2
|
|
3056
|
-
};
|
|
3057
|
-
const realAnchorPosition = schNetLabel.anchor_position ?? {
|
|
3058
|
-
x: schNetLabel.center.x - realTextGrowthVec.x * fullWidthFsr * fontSizeMm / 2,
|
|
3059
|
-
y: schNetLabel.center.y - realTextGrowthVec.y * fullWidthFsr * fontSizeMm / 2
|
|
3060
|
-
};
|
|
3061
|
-
const pathRotation = {
|
|
3062
|
-
left: 0,
|
|
3063
|
-
top: -90,
|
|
3064
|
-
bottom: 90,
|
|
3065
|
-
right: 180
|
|
3066
|
-
}[schNetLabel.anchor_side];
|
|
3067
|
-
const screenOutlinePoints = [
|
|
3068
|
-
// Arrow point in font-relative coordinates
|
|
3069
|
-
{
|
|
3070
|
-
x: 0,
|
|
3071
|
-
y: 0
|
|
3072
|
-
},
|
|
3073
|
-
// Top left corner in font-relative coordinates
|
|
3074
|
-
{
|
|
3075
|
-
x: ARROW_POINT_WIDTH_FSR,
|
|
3076
|
-
y: 0.6
|
|
3077
|
-
},
|
|
3078
|
-
// Top right corner in font-relative coordinates
|
|
3079
|
-
{
|
|
3080
|
-
x: ARROW_POINT_WIDTH_FSR * 2 + END_PADDING_FSR + END_PADDING_EXTRA_PER_CHARACTER_FSR * schNetLabel.text.length + textWidthFSR,
|
|
3081
|
-
y: 0.6
|
|
3082
|
-
},
|
|
3083
|
-
// Bottom right corner in font-relative coordinates
|
|
3084
|
-
{
|
|
3085
|
-
x: ARROW_POINT_WIDTH_FSR * 2 + END_PADDING_FSR + END_PADDING_EXTRA_PER_CHARACTER_FSR * schNetLabel.text.length + textWidthFSR,
|
|
3086
|
-
y: -0.6
|
|
3087
|
-
},
|
|
3088
|
-
// Bottom left corner in font-relative coordinates
|
|
3089
|
-
{
|
|
3090
|
-
x: ARROW_POINT_WIDTH_FSR,
|
|
3091
|
-
y: -0.6
|
|
3092
|
-
}
|
|
3093
|
-
].map(
|
|
3094
|
-
(fontRelativePoint) => applyToPoint26(
|
|
3095
|
-
compose6(
|
|
3096
|
-
realToScreenTransform,
|
|
3097
|
-
translate6(realAnchorPosition.x, realAnchorPosition.y),
|
|
3098
|
-
scale3(fontSizeMm),
|
|
3099
|
-
rotate3(pathRotation / 180 * Math.PI)
|
|
3100
|
-
),
|
|
3101
|
-
fontRelativePoint
|
|
3102
|
-
)
|
|
3103
|
-
);
|
|
3104
|
-
const pathD = `
|
|
3105
|
-
M ${screenOutlinePoints[0].x},${screenOutlinePoints[0].y}
|
|
3106
|
-
L ${screenOutlinePoints[1].x},${screenOutlinePoints[1].y}
|
|
3107
|
-
L ${screenOutlinePoints[2].x},${screenOutlinePoints[2].y}
|
|
3108
|
-
L ${screenOutlinePoints[3].x},${screenOutlinePoints[3].y}
|
|
3109
|
-
L ${screenOutlinePoints[4].x},${screenOutlinePoints[4].y}
|
|
3110
|
-
Z
|
|
3111
|
-
`;
|
|
3112
|
-
svgObjects.push({
|
|
3113
|
-
name: "path",
|
|
3114
|
-
type: "element",
|
|
3115
|
-
attributes: {
|
|
3116
|
-
class: "net-label",
|
|
3117
|
-
d: pathD,
|
|
3118
|
-
fill: "white",
|
|
3119
|
-
stroke: colorMap.schematic.label_global,
|
|
3120
|
-
"stroke-width": `${getSchStrokeSize(realToScreenTransform)}px`
|
|
3121
|
-
},
|
|
3122
|
-
value: "",
|
|
3123
|
-
children: []
|
|
3124
|
-
});
|
|
3125
|
-
const screenTextPos = {
|
|
3126
|
-
x: screenAnchorPosition.x + screenTextGrowthVec.x * fontSizePx * 0.5,
|
|
3127
|
-
y: screenAnchorPosition.y + screenTextGrowthVec.y * fontSizePx * 0.5
|
|
3128
|
-
};
|
|
3129
|
-
const textAnchor = {
|
|
3130
|
-
left: "start",
|
|
3131
|
-
top: "start",
|
|
3132
|
-
bottom: "start",
|
|
3133
|
-
right: "end"
|
|
3134
|
-
}[schNetLabel.anchor_side];
|
|
3135
|
-
const textTransformString = {
|
|
3136
|
-
left: "",
|
|
3137
|
-
right: "",
|
|
3138
|
-
top: `rotate(90 ${screenTextPos.x} ${screenTextPos.y})`,
|
|
3139
|
-
bottom: `rotate(-90 ${screenTextPos.x} ${screenTextPos.y})`
|
|
3140
|
-
}[schNetLabel.anchor_side];
|
|
3141
|
-
svgObjects.push({
|
|
3142
|
-
name: "text",
|
|
3143
|
-
type: "element",
|
|
3144
|
-
attributes: {
|
|
3145
|
-
class: "net-label-text",
|
|
3146
|
-
x: screenTextPos.x.toString(),
|
|
3147
|
-
y: screenTextPos.y.toString(),
|
|
3148
|
-
fill: colorMap.schematic.label_global,
|
|
3149
|
-
"text-anchor": textAnchor,
|
|
3150
|
-
"dominant-baseline": "central",
|
|
3151
|
-
"font-family": "sans-serif",
|
|
3152
|
-
"font-variant-numeric": "tabular-nums",
|
|
3153
|
-
"font-size": `${fontSizePx}px`,
|
|
3154
|
-
transform: textTransformString
|
|
3155
|
-
},
|
|
3156
|
-
children: [
|
|
3157
|
-
{
|
|
3158
|
-
type: "text",
|
|
3159
|
-
value: schNetLabel.text || "",
|
|
3160
|
-
name: "",
|
|
3161
|
-
attributes: {},
|
|
3162
|
-
children: []
|
|
3163
|
-
}
|
|
3164
|
-
],
|
|
3165
|
-
value: ""
|
|
3166
|
-
});
|
|
3167
|
-
return svgObjects;
|
|
3168
|
-
};
|
|
3169
|
-
|
|
3170
|
-
// lib/sch/svg-object-fns/create-svg-objects-for-sch-text.ts
|
|
3171
|
-
import { applyToPoint as applyToPoint27 } from "transformation-matrix";
|
|
3172
|
-
var createSvgSchText = (elm, transform) => {
|
|
3173
|
-
const center = applyToPoint27(transform, elm.position);
|
|
3174
|
-
const textAnchorMap = {
|
|
3175
|
-
center: "middle",
|
|
3176
|
-
left: "start",
|
|
3177
|
-
right: "end",
|
|
3178
|
-
top: "middle",
|
|
3179
|
-
bottom: "middle"
|
|
3180
|
-
};
|
|
3181
|
-
const dominantBaselineMap = {
|
|
3182
|
-
center: "middle",
|
|
3183
|
-
left: "middle",
|
|
3184
|
-
right: "middle",
|
|
3185
|
-
top: "hanging",
|
|
3186
|
-
bottom: "ideographic"
|
|
3187
|
-
};
|
|
3188
|
-
return {
|
|
3189
|
-
type: "element",
|
|
3190
|
-
name: "text",
|
|
3191
|
-
value: "",
|
|
3192
|
-
attributes: {
|
|
3193
|
-
x: center.x.toString(),
|
|
3194
|
-
y: center.y.toString(),
|
|
3195
|
-
fill: elm.color ?? colorMap.schematic.sheet_label,
|
|
3196
|
-
"text-anchor": textAnchorMap[elm.anchor],
|
|
3197
|
-
"dominant-baseline": dominantBaselineMap[elm.anchor],
|
|
3198
|
-
"font-family": "sans-serif",
|
|
3199
|
-
"font-size": `${getSchScreenFontSize(transform, "reference_designator")}px`,
|
|
3200
|
-
transform: `rotate(${elm.rotation}, ${center.x}, ${center.y})`
|
|
3201
|
-
},
|
|
3202
|
-
children: [
|
|
3203
|
-
{
|
|
3204
|
-
type: "text",
|
|
3205
|
-
value: elm.text,
|
|
3206
|
-
name: elm.schematic_text_id,
|
|
3207
|
-
attributes: {},
|
|
3208
|
-
children: []
|
|
3209
|
-
}
|
|
3210
|
-
]
|
|
3211
|
-
};
|
|
3212
|
-
};
|
|
3213
|
-
|
|
3214
|
-
// lib/sch/svg-object-fns/create-svg-objects-for-sch-net-symbol.ts
|
|
3215
|
-
import {
|
|
3216
|
-
applyToPoint as applyToPoint28,
|
|
3217
|
-
compose as compose7,
|
|
3218
|
-
rotate as rotate4,
|
|
3219
|
-
scale as scale4,
|
|
3220
|
-
translate as translate7
|
|
3221
|
-
} from "transformation-matrix";
|
|
3222
|
-
import { symbols as symbols3 } from "schematic-symbols";
|
|
3223
3382
|
var ninePointAnchorToTextAnchor2 = {
|
|
3224
3383
|
top_left: "start",
|
|
3225
3384
|
top_right: "end",
|
|
@@ -3242,13 +3401,27 @@ var ninePointAnchorToDominantBaseline2 = {
|
|
|
3242
3401
|
middle_top: "auto",
|
|
3243
3402
|
middle_bottom: "hanging"
|
|
3244
3403
|
};
|
|
3245
|
-
|
|
3246
|
-
|
|
3247
|
-
|
|
3248
|
-
|
|
3404
|
+
function getTextOffsets(pathRotation, transform) {
|
|
3405
|
+
const scale7 = Math.abs(transform.a);
|
|
3406
|
+
const baseOffset = scale7 * 0.1;
|
|
3407
|
+
const rotationOffsetMap = {
|
|
3408
|
+
"0": { x: baseOffset * 0.8, y: -baseOffset },
|
|
3409
|
+
// Left
|
|
3410
|
+
"-90": { x: baseOffset * 3.3, y: baseOffset * 2.8 },
|
|
3411
|
+
// Top
|
|
3412
|
+
"90": { x: -baseOffset * 3.55, y: -baseOffset * 4.2 },
|
|
3413
|
+
// Bottom
|
|
3414
|
+
"180": { x: -baseOffset * 0.85, y: -baseOffset * 0.2 }
|
|
3415
|
+
// Right
|
|
3416
|
+
};
|
|
3417
|
+
return rotationOffsetMap[pathRotation.toString()] || { x: 0, y: 0 };
|
|
3418
|
+
}
|
|
3419
|
+
|
|
3420
|
+
// lib/sch/svg-object-fns/create-svg-objects-for-sch-net-label-with-symbol.ts
|
|
3421
|
+
var createSvgObjectsForSchNetLabelWithSymbol = (schNetLabel, realToScreenTransform) => {
|
|
3249
3422
|
if (!schNetLabel.text) return [];
|
|
3250
3423
|
const svgObjects = [];
|
|
3251
|
-
const symbol = symbols3[
|
|
3424
|
+
const symbol = symbols3[schNetLabel.symbol_name];
|
|
3252
3425
|
if (!symbol) {
|
|
3253
3426
|
svgObjects.push(
|
|
3254
3427
|
createSvgSchErrorText({
|
|
@@ -3271,7 +3444,7 @@ var createSvgObjectsForSchNetSymbol = (schNetLabel, realToScreenTransform) => {
|
|
|
3271
3444
|
};
|
|
3272
3445
|
const fontSizeMm = getSchMmFontSize("net_label");
|
|
3273
3446
|
const textWidthFSR = estimateTextWidth(schNetLabel.text || "");
|
|
3274
|
-
const fullWidthFsr = textWidthFSR +
|
|
3447
|
+
const fullWidthFsr = textWidthFSR + ARROW_POINT_WIDTH_FSR * 2 + END_PADDING_EXTRA_PER_CHARACTER_FSR * schNetLabel.text.length + END_PADDING_FSR;
|
|
3275
3448
|
const realTextGrowthVec = getUnitVectorFromOutsideToEdge(
|
|
3276
3449
|
schNetLabel.anchor_side
|
|
3277
3450
|
);
|
|
@@ -3285,7 +3458,7 @@ var createSvgObjectsForSchNetSymbol = (schNetLabel, realToScreenTransform) => {
|
|
|
3285
3458
|
bottom: 90,
|
|
3286
3459
|
right: 180
|
|
3287
3460
|
}[schNetLabel.anchor_side];
|
|
3288
|
-
const rotationMatrix =
|
|
3461
|
+
const rotationMatrix = rotate3(pathRotation / 180 * Math.PI);
|
|
3289
3462
|
const symbolBounds = {
|
|
3290
3463
|
minX: Math.min(
|
|
3291
3464
|
...symbol.primitives.flatMap(
|
|
@@ -3312,7 +3485,7 @@ var createSvgObjectsForSchNetSymbol = (schNetLabel, realToScreenTransform) => {
|
|
|
3312
3485
|
x: symbolBounds.minX,
|
|
3313
3486
|
y: (symbolBounds.minY + symbolBounds.maxY) / 2
|
|
3314
3487
|
};
|
|
3315
|
-
const rotatedSymbolEnd =
|
|
3488
|
+
const rotatedSymbolEnd = applyToPoint29(rotationMatrix, symbolEndPoint);
|
|
3316
3489
|
const symbolToRealTransform = compose7(
|
|
3317
3490
|
translate7(
|
|
3318
3491
|
realAnchorPosition.x - rotatedSymbolEnd.x,
|
|
@@ -3322,11 +3495,11 @@ var createSvgObjectsForSchNetSymbol = (schNetLabel, realToScreenTransform) => {
|
|
|
3322
3495
|
scale4(1)
|
|
3323
3496
|
// Use full symbol size
|
|
3324
3497
|
);
|
|
3325
|
-
const [screenMinX, screenMinY] =
|
|
3498
|
+
const [screenMinX, screenMinY] = applyToPoint29(
|
|
3326
3499
|
compose7(realToScreenTransform, symbolToRealTransform),
|
|
3327
3500
|
[bounds.minX, bounds.minY]
|
|
3328
3501
|
);
|
|
3329
|
-
const [screenMaxX, screenMaxY] =
|
|
3502
|
+
const [screenMaxX, screenMaxY] = applyToPoint29(
|
|
3330
3503
|
compose7(realToScreenTransform, symbolToRealTransform),
|
|
3331
3504
|
[bounds.maxX, bounds.maxY]
|
|
3332
3505
|
);
|
|
@@ -3350,7 +3523,7 @@ var createSvgObjectsForSchNetSymbol = (schNetLabel, realToScreenTransform) => {
|
|
|
3350
3523
|
});
|
|
3351
3524
|
for (const path of symbolPaths) {
|
|
3352
3525
|
const symbolPath = path.points.map((p, i) => {
|
|
3353
|
-
const [x, y] =
|
|
3526
|
+
const [x, y] = applyToPoint29(
|
|
3354
3527
|
compose7(realToScreenTransform, symbolToRealTransform),
|
|
3355
3528
|
[p.x, p.y]
|
|
3356
3529
|
);
|
|
@@ -3370,7 +3543,7 @@ var createSvgObjectsForSchNetSymbol = (schNetLabel, realToScreenTransform) => {
|
|
|
3370
3543
|
});
|
|
3371
3544
|
}
|
|
3372
3545
|
for (const text of symbolTexts) {
|
|
3373
|
-
const screenTextPos =
|
|
3546
|
+
const screenTextPos = applyToPoint29(
|
|
3374
3547
|
compose7(realToScreenTransform, symbolToRealTransform),
|
|
3375
3548
|
text
|
|
3376
3549
|
);
|
|
@@ -3380,18 +3553,9 @@ var createSvgObjectsForSchNetSymbol = (schNetLabel, realToScreenTransform) => {
|
|
|
3380
3553
|
} else if (textValue === "{VAL}") {
|
|
3381
3554
|
textValue = "";
|
|
3382
3555
|
}
|
|
3383
|
-
const
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
"-90": { x: 33, y: 28 },
|
|
3387
|
-
// Top
|
|
3388
|
-
"90": { x: -32.5, y: -38 },
|
|
3389
|
-
// Bottom
|
|
3390
|
-
"180": { x: -8.5, y: -2 }
|
|
3391
|
-
// Right
|
|
3392
|
-
};
|
|
3393
|
-
const currentRotation = pathRotation.toString();
|
|
3394
|
-
const rotationOffset = rotationOffsetMap[currentRotation] || { x: 0, y: 0 };
|
|
3556
|
+
const scale7 = Math.abs(realToScreenTransform.a);
|
|
3557
|
+
const baseOffset = scale7 * 0.1;
|
|
3558
|
+
const rotationOffset = getTextOffsets(pathRotation, realToScreenTransform);
|
|
3395
3559
|
const offsetScreenPos = {
|
|
3396
3560
|
x: screenTextPos.x + rotationOffset.x,
|
|
3397
3561
|
y: screenTextPos.y + rotationOffset.y
|
|
@@ -3402,7 +3566,7 @@ var createSvgObjectsForSchNetSymbol = (schNetLabel, realToScreenTransform) => {
|
|
|
3402
3566
|
attributes: {
|
|
3403
3567
|
x: offsetScreenPos.x.toString(),
|
|
3404
3568
|
y: offsetScreenPos.y.toString(),
|
|
3405
|
-
fill: colorMap.schematic.
|
|
3569
|
+
fill: colorMap.schematic.label_local,
|
|
3406
3570
|
"font-family": "sans-serif",
|
|
3407
3571
|
"text-anchor": ninePointAnchorToTextAnchor2[text.anchor],
|
|
3408
3572
|
"dominant-baseline": ninePointAnchorToDominantBaseline2[text.anchor],
|
|
@@ -3421,7 +3585,7 @@ var createSvgObjectsForSchNetSymbol = (schNetLabel, realToScreenTransform) => {
|
|
|
3421
3585
|
});
|
|
3422
3586
|
}
|
|
3423
3587
|
for (const box of symbolBoxes) {
|
|
3424
|
-
const screenBoxPos =
|
|
3588
|
+
const screenBoxPos = applyToPoint29(
|
|
3425
3589
|
compose7(realToScreenTransform, symbolToRealTransform),
|
|
3426
3590
|
box
|
|
3427
3591
|
);
|
|
@@ -3444,7 +3608,7 @@ var createSvgObjectsForSchNetSymbol = (schNetLabel, realToScreenTransform) => {
|
|
|
3444
3608
|
});
|
|
3445
3609
|
}
|
|
3446
3610
|
for (const circle of symbolCircles) {
|
|
3447
|
-
const screenCirclePos =
|
|
3611
|
+
const screenCirclePos = applyToPoint29(
|
|
3448
3612
|
compose7(realToScreenTransform, symbolToRealTransform),
|
|
3449
3613
|
circle
|
|
3450
3614
|
);
|
|
@@ -3470,6 +3634,187 @@ var createSvgObjectsForSchNetSymbol = (schNetLabel, realToScreenTransform) => {
|
|
|
3470
3634
|
return svgObjects;
|
|
3471
3635
|
};
|
|
3472
3636
|
|
|
3637
|
+
// lib/sch/svg-object-fns/create-svg-objects-for-sch-net-label.ts
|
|
3638
|
+
var createSvgObjectsForSchNetLabel = (schNetLabel, realToScreenTransform) => {
|
|
3639
|
+
if (!schNetLabel.text) return [];
|
|
3640
|
+
if (schNetLabel.symbol_name) {
|
|
3641
|
+
return createSvgObjectsForSchNetLabelWithSymbol(
|
|
3642
|
+
schNetLabel,
|
|
3643
|
+
realToScreenTransform
|
|
3644
|
+
);
|
|
3645
|
+
}
|
|
3646
|
+
const svgObjects = [];
|
|
3647
|
+
const fontSizePx = getSchScreenFontSize(realToScreenTransform, "net_label");
|
|
3648
|
+
const fontSizeMm = getSchMmFontSize("net_label");
|
|
3649
|
+
const textWidthFSR = estimateTextWidth(schNetLabel.text || "");
|
|
3650
|
+
const screenCenter = applyToPoint30(realToScreenTransform, schNetLabel.center);
|
|
3651
|
+
const realTextGrowthVec = getUnitVectorFromOutsideToEdge(
|
|
3652
|
+
schNetLabel.anchor_side
|
|
3653
|
+
);
|
|
3654
|
+
const screenTextGrowthVec = { ...realTextGrowthVec };
|
|
3655
|
+
screenTextGrowthVec.y *= -1;
|
|
3656
|
+
const fullWidthFsr = textWidthFSR + ARROW_POINT_WIDTH_FSR * 2 + END_PADDING_EXTRA_PER_CHARACTER_FSR * schNetLabel.text.length + END_PADDING_FSR;
|
|
3657
|
+
const screenAnchorPosition = schNetLabel.anchor_position ? applyToPoint30(realToScreenTransform, schNetLabel.anchor_position) : {
|
|
3658
|
+
x: screenCenter.x - screenTextGrowthVec.x * fullWidthFsr * fontSizePx / 2,
|
|
3659
|
+
y: screenCenter.y - screenTextGrowthVec.y * fullWidthFsr * fontSizePx / 2
|
|
3660
|
+
};
|
|
3661
|
+
const realAnchorPosition = schNetLabel.anchor_position ?? {
|
|
3662
|
+
x: schNetLabel.center.x - realTextGrowthVec.x * fullWidthFsr * fontSizeMm / 2,
|
|
3663
|
+
y: schNetLabel.center.y - realTextGrowthVec.y * fullWidthFsr * fontSizeMm / 2
|
|
3664
|
+
};
|
|
3665
|
+
const pathRotation = {
|
|
3666
|
+
left: 0,
|
|
3667
|
+
top: -90,
|
|
3668
|
+
bottom: 90,
|
|
3669
|
+
right: 180
|
|
3670
|
+
}[schNetLabel.anchor_side];
|
|
3671
|
+
const screenOutlinePoints = [
|
|
3672
|
+
// Arrow point in font-relative coordinates
|
|
3673
|
+
{
|
|
3674
|
+
x: 0,
|
|
3675
|
+
y: 0
|
|
3676
|
+
},
|
|
3677
|
+
// Top left corner in font-relative coordinates
|
|
3678
|
+
{
|
|
3679
|
+
x: ARROW_POINT_WIDTH_FSR,
|
|
3680
|
+
y: 0.6
|
|
3681
|
+
},
|
|
3682
|
+
// Top right corner in font-relative coordinates
|
|
3683
|
+
{
|
|
3684
|
+
x: ARROW_POINT_WIDTH_FSR * 2 + END_PADDING_FSR + END_PADDING_EXTRA_PER_CHARACTER_FSR * schNetLabel.text.length + textWidthFSR,
|
|
3685
|
+
y: 0.6
|
|
3686
|
+
},
|
|
3687
|
+
// Bottom right corner in font-relative coordinates
|
|
3688
|
+
{
|
|
3689
|
+
x: ARROW_POINT_WIDTH_FSR * 2 + END_PADDING_FSR + END_PADDING_EXTRA_PER_CHARACTER_FSR * schNetLabel.text.length + textWidthFSR,
|
|
3690
|
+
y: -0.6
|
|
3691
|
+
},
|
|
3692
|
+
// Bottom left corner in font-relative coordinates
|
|
3693
|
+
{
|
|
3694
|
+
x: ARROW_POINT_WIDTH_FSR,
|
|
3695
|
+
y: -0.6
|
|
3696
|
+
}
|
|
3697
|
+
].map(
|
|
3698
|
+
(fontRelativePoint) => applyToPoint30(
|
|
3699
|
+
compose8(
|
|
3700
|
+
realToScreenTransform,
|
|
3701
|
+
translate8(realAnchorPosition.x, realAnchorPosition.y),
|
|
3702
|
+
scale5(fontSizeMm),
|
|
3703
|
+
rotate4(pathRotation / 180 * Math.PI)
|
|
3704
|
+
),
|
|
3705
|
+
fontRelativePoint
|
|
3706
|
+
)
|
|
3707
|
+
);
|
|
3708
|
+
const pathD = `
|
|
3709
|
+
M ${screenOutlinePoints[0].x},${screenOutlinePoints[0].y}
|
|
3710
|
+
L ${screenOutlinePoints[1].x},${screenOutlinePoints[1].y}
|
|
3711
|
+
L ${screenOutlinePoints[2].x},${screenOutlinePoints[2].y}
|
|
3712
|
+
L ${screenOutlinePoints[3].x},${screenOutlinePoints[3].y}
|
|
3713
|
+
L ${screenOutlinePoints[4].x},${screenOutlinePoints[4].y}
|
|
3714
|
+
Z
|
|
3715
|
+
`;
|
|
3716
|
+
svgObjects.push({
|
|
3717
|
+
name: "path",
|
|
3718
|
+
type: "element",
|
|
3719
|
+
attributes: {
|
|
3720
|
+
class: "net-label",
|
|
3721
|
+
d: pathD,
|
|
3722
|
+
fill: "white",
|
|
3723
|
+
stroke: colorMap.schematic.label_global,
|
|
3724
|
+
"stroke-width": `${getSchStrokeSize(realToScreenTransform)}px`
|
|
3725
|
+
},
|
|
3726
|
+
value: "",
|
|
3727
|
+
children: []
|
|
3728
|
+
});
|
|
3729
|
+
const screenTextPos = {
|
|
3730
|
+
x: screenAnchorPosition.x + screenTextGrowthVec.x * fontSizePx * 0.5,
|
|
3731
|
+
y: screenAnchorPosition.y + screenTextGrowthVec.y * fontSizePx * 0.5
|
|
3732
|
+
};
|
|
3733
|
+
const textAnchor = {
|
|
3734
|
+
left: "start",
|
|
3735
|
+
top: "start",
|
|
3736
|
+
bottom: "start",
|
|
3737
|
+
right: "end"
|
|
3738
|
+
}[schNetLabel.anchor_side];
|
|
3739
|
+
const textTransformString = {
|
|
3740
|
+
left: "",
|
|
3741
|
+
right: "",
|
|
3742
|
+
top: `rotate(90 ${screenTextPos.x} ${screenTextPos.y})`,
|
|
3743
|
+
bottom: `rotate(-90 ${screenTextPos.x} ${screenTextPos.y})`
|
|
3744
|
+
}[schNetLabel.anchor_side];
|
|
3745
|
+
svgObjects.push({
|
|
3746
|
+
name: "text",
|
|
3747
|
+
type: "element",
|
|
3748
|
+
attributes: {
|
|
3749
|
+
class: "net-label-text",
|
|
3750
|
+
x: screenTextPos.x.toString(),
|
|
3751
|
+
y: screenTextPos.y.toString(),
|
|
3752
|
+
fill: colorMap.schematic.label_global,
|
|
3753
|
+
"text-anchor": textAnchor,
|
|
3754
|
+
"dominant-baseline": "central",
|
|
3755
|
+
"font-family": "sans-serif",
|
|
3756
|
+
"font-variant-numeric": "tabular-nums",
|
|
3757
|
+
"font-size": `${fontSizePx}px`,
|
|
3758
|
+
transform: textTransformString
|
|
3759
|
+
},
|
|
3760
|
+
children: [
|
|
3761
|
+
{
|
|
3762
|
+
type: "text",
|
|
3763
|
+
value: schNetLabel.text || "",
|
|
3764
|
+
name: "",
|
|
3765
|
+
attributes: {},
|
|
3766
|
+
children: []
|
|
3767
|
+
}
|
|
3768
|
+
],
|
|
3769
|
+
value: ""
|
|
3770
|
+
});
|
|
3771
|
+
return svgObjects;
|
|
3772
|
+
};
|
|
3773
|
+
|
|
3774
|
+
// lib/sch/svg-object-fns/create-svg-objects-for-sch-text.ts
|
|
3775
|
+
import { applyToPoint as applyToPoint31 } from "transformation-matrix";
|
|
3776
|
+
var createSvgSchText = (elm, transform) => {
|
|
3777
|
+
const center = applyToPoint31(transform, elm.position);
|
|
3778
|
+
const textAnchorMap = {
|
|
3779
|
+
center: "middle",
|
|
3780
|
+
left: "start",
|
|
3781
|
+
right: "end",
|
|
3782
|
+
top: "middle",
|
|
3783
|
+
bottom: "middle"
|
|
3784
|
+
};
|
|
3785
|
+
const dominantBaselineMap = {
|
|
3786
|
+
center: "middle",
|
|
3787
|
+
left: "middle",
|
|
3788
|
+
right: "middle",
|
|
3789
|
+
top: "hanging",
|
|
3790
|
+
bottom: "ideographic"
|
|
3791
|
+
};
|
|
3792
|
+
return {
|
|
3793
|
+
type: "element",
|
|
3794
|
+
name: "text",
|
|
3795
|
+
value: "",
|
|
3796
|
+
attributes: {
|
|
3797
|
+
x: center.x.toString(),
|
|
3798
|
+
y: center.y.toString(),
|
|
3799
|
+
fill: elm.color ?? colorMap.schematic.sheet_label,
|
|
3800
|
+
"text-anchor": textAnchorMap[elm.anchor],
|
|
3801
|
+
"dominant-baseline": dominantBaselineMap[elm.anchor],
|
|
3802
|
+
"font-family": "sans-serif",
|
|
3803
|
+
"font-size": `${getSchScreenFontSize(transform, "reference_designator")}px`,
|
|
3804
|
+
transform: `rotate(${elm.rotation}, ${center.x}, ${center.y})`
|
|
3805
|
+
},
|
|
3806
|
+
children: [
|
|
3807
|
+
{
|
|
3808
|
+
type: "text",
|
|
3809
|
+
value: elm.text,
|
|
3810
|
+
name: elm.schematic_text_id,
|
|
3811
|
+
attributes: {},
|
|
3812
|
+
children: []
|
|
3813
|
+
}
|
|
3814
|
+
]
|
|
3815
|
+
};
|
|
3816
|
+
};
|
|
3817
|
+
|
|
3473
3818
|
// lib/sch/convert-circuit-json-to-schematic-svg.ts
|
|
3474
3819
|
function convertCircuitJsonToSchematicSvg(circuitJson, options) {
|
|
3475
3820
|
const realBounds = getSchematicBoundsFromCircuitJson(circuitJson);
|
|
@@ -3547,7 +3892,7 @@ function convertCircuitJsonToSchematicSvg(circuitJson, options) {
|
|
|
3547
3892
|
} else if (elm.type === "schematic_trace") {
|
|
3548
3893
|
schTraceSvgs.push(...createSchematicTrace(elm, transform));
|
|
3549
3894
|
} else if (elm.type === "schematic_net_label") {
|
|
3550
|
-
|
|
3895
|
+
schNetLabel.push(...createSvgObjectsForSchNetLabel(elm, transform));
|
|
3551
3896
|
} else if (elm.type === "schematic_text") {
|
|
3552
3897
|
schText.push(createSvgSchText(elm, transform));
|
|
3553
3898
|
} else if (elm.type === "schematic_voltage_probe") {
|
|
@@ -3620,12 +3965,13 @@ function convertCircuitJsonToSchematicSvg(circuitJson, options) {
|
|
|
3620
3965
|
],
|
|
3621
3966
|
value: ""
|
|
3622
3967
|
};
|
|
3623
|
-
return
|
|
3968
|
+
return stringify3(svgObject);
|
|
3624
3969
|
}
|
|
3625
3970
|
var circuitJsonToSchematicSvg = convertCircuitJsonToSchematicSvg;
|
|
3626
3971
|
export {
|
|
3627
3972
|
circuitJsonToPcbSvg,
|
|
3628
3973
|
circuitJsonToSchematicSvg,
|
|
3974
|
+
convertCircuitJsonToAssemblySvg,
|
|
3629
3975
|
convertCircuitJsonToPcbSvg,
|
|
3630
3976
|
convertCircuitJsonToSchematicSvg
|
|
3631
3977
|
};
|