circuit-to-svg 0.0.163 → 0.0.165
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 +400 -75
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1866,8 +1866,16 @@ import { applyToPoint as applyToPoint21 } from "transformation-matrix";
|
|
|
1866
1866
|
|
|
1867
1867
|
// lib/utils/get-sch-font-size.ts
|
|
1868
1868
|
import "transformation-matrix";
|
|
1869
|
+
var fontSizeMap = {
|
|
1870
|
+
pin_number: 0.15,
|
|
1871
|
+
negated_pin_number: 0.15 * 0.8,
|
|
1872
|
+
reference_designator: 0.18,
|
|
1873
|
+
manufacturer_number: 0.18,
|
|
1874
|
+
net_label: 0.18,
|
|
1875
|
+
error: 0.05
|
|
1876
|
+
};
|
|
1869
1877
|
var getSchMmFontSize = (textType, fontSize) => {
|
|
1870
|
-
return
|
|
1878
|
+
return fontSize ?? fontSizeMap[textType];
|
|
1871
1879
|
};
|
|
1872
1880
|
var getSchScreenFontSize = (transform, textType, fontSize) => {
|
|
1873
1881
|
return Math.abs(transform.a) * getSchMmFontSize(textType, fontSize);
|
|
@@ -2979,69 +2987,6 @@ function drawSchematicLabeledPoints(params) {
|
|
|
2979
2987
|
};
|
|
2980
2988
|
}
|
|
2981
2989
|
|
|
2982
|
-
// lib/utils/get-unit-vector-from-outside-to-edge.ts
|
|
2983
|
-
var getUnitVectorFromOutsideToEdge = (side) => {
|
|
2984
|
-
switch (side) {
|
|
2985
|
-
case "top":
|
|
2986
|
-
return { x: 0, y: -1 };
|
|
2987
|
-
case "bottom":
|
|
2988
|
-
return { x: 0, y: 1 };
|
|
2989
|
-
case "left":
|
|
2990
|
-
return { x: 1, y: 0 };
|
|
2991
|
-
case "right":
|
|
2992
|
-
return { x: -1, y: 0 };
|
|
2993
|
-
}
|
|
2994
|
-
throw new Error(`Invalid side: ${side}`);
|
|
2995
|
-
};
|
|
2996
|
-
|
|
2997
|
-
// lib/utils/net-label-utils.ts
|
|
2998
|
-
import "transformation-matrix";
|
|
2999
|
-
import "schematic-symbols";
|
|
3000
|
-
var ARROW_POINT_WIDTH_FSR = 0.3;
|
|
3001
|
-
var END_PADDING_FSR = 0.3;
|
|
3002
|
-
var END_PADDING_EXTRA_PER_CHARACTER_FSR = 0.06;
|
|
3003
|
-
var ninePointAnchorToTextAnchor = {
|
|
3004
|
-
top_left: "start",
|
|
3005
|
-
top_right: "end",
|
|
3006
|
-
middle_left: "start",
|
|
3007
|
-
middle_right: "end",
|
|
3008
|
-
bottom_left: "start",
|
|
3009
|
-
bottom_right: "end",
|
|
3010
|
-
center: "middle",
|
|
3011
|
-
middle_top: "middle",
|
|
3012
|
-
middle_bottom: "middle"
|
|
3013
|
-
};
|
|
3014
|
-
var ninePointAnchorToDominantBaseline = {
|
|
3015
|
-
top_left: "hanging",
|
|
3016
|
-
top_right: "hanging",
|
|
3017
|
-
bottom_left: "ideographic",
|
|
3018
|
-
bottom_right: "ideographic",
|
|
3019
|
-
center: "middle",
|
|
3020
|
-
middle_left: "middle",
|
|
3021
|
-
middle_right: "middle",
|
|
3022
|
-
middle_top: "hanging",
|
|
3023
|
-
middle_bottom: "ideographic"
|
|
3024
|
-
};
|
|
3025
|
-
function getPathRotation(anchorSide) {
|
|
3026
|
-
const rotationMap = {
|
|
3027
|
-
left: 180,
|
|
3028
|
-
top: 90,
|
|
3029
|
-
bottom: -90,
|
|
3030
|
-
right: 0
|
|
3031
|
-
};
|
|
3032
|
-
return rotationMap[anchorSide] ?? 0;
|
|
3033
|
-
}
|
|
3034
|
-
function calculateAnchorPosition(schNetLabel, fontSizeMm, textWidthFSR) {
|
|
3035
|
-
const fullWidthFsr = textWidthFSR + ARROW_POINT_WIDTH_FSR * 2 + END_PADDING_EXTRA_PER_CHARACTER_FSR * schNetLabel.text.length + END_PADDING_FSR;
|
|
3036
|
-
const realTextGrowthVec = getUnitVectorFromOutsideToEdge(
|
|
3037
|
-
schNetLabel.anchor_side
|
|
3038
|
-
);
|
|
3039
|
-
return schNetLabel.anchor_position ?? {
|
|
3040
|
-
x: schNetLabel.center.x - realTextGrowthVec.x * fullWidthFsr * fontSizeMm / 2,
|
|
3041
|
-
y: schNetLabel.center.y - realTextGrowthVec.y * fullWidthFsr * fontSizeMm / 2
|
|
3042
|
-
};
|
|
3043
|
-
}
|
|
3044
|
-
|
|
3045
2990
|
// lib/sch/arial-text-metrics.ts
|
|
3046
2991
|
var arialTextMetrics = {
|
|
3047
2992
|
"0": {
|
|
@@ -3821,6 +3766,149 @@ var estimateTextWidth = (text) => {
|
|
|
3821
3766
|
return totalWidth / 27;
|
|
3822
3767
|
};
|
|
3823
3768
|
|
|
3769
|
+
// lib/sch/get-table-dimensions.ts
|
|
3770
|
+
var getTableDimensions = (schematicTable, circuitJson) => {
|
|
3771
|
+
if (schematicTable.column_widths && schematicTable.column_widths.length > 0 && schematicTable.row_heights && schematicTable.row_heights.length > 0) {
|
|
3772
|
+
const unitToMm = (v) => {
|
|
3773
|
+
if (typeof v === "number") return v;
|
|
3774
|
+
if (v.endsWith("mm")) return parseFloat(v);
|
|
3775
|
+
if (v.endsWith("in")) return parseFloat(v) * 25.4;
|
|
3776
|
+
return parseFloat(v);
|
|
3777
|
+
};
|
|
3778
|
+
return {
|
|
3779
|
+
column_widths: schematicTable.column_widths.map(unitToMm),
|
|
3780
|
+
row_heights: schematicTable.row_heights.map(unitToMm)
|
|
3781
|
+
};
|
|
3782
|
+
}
|
|
3783
|
+
const cells = circuitJson.filter(
|
|
3784
|
+
(elm) => elm.type === "schematic_table_cell" && elm.schematic_table_id === schematicTable.schematic_table_id
|
|
3785
|
+
);
|
|
3786
|
+
if (cells.length === 0) {
|
|
3787
|
+
return { column_widths: [], row_heights: [] };
|
|
3788
|
+
}
|
|
3789
|
+
const numColumns = cells.reduce((max, c) => Math.max(max, c.end_column_index), -1) + 1;
|
|
3790
|
+
const numRows = cells.reduce((max, c) => Math.max(max, c.end_row_index), -1) + 1;
|
|
3791
|
+
const { cell_padding = 0.2 } = schematicTable;
|
|
3792
|
+
const column_widths = new Array(numColumns).fill(0);
|
|
3793
|
+
const row_heights = new Array(numRows).fill(0);
|
|
3794
|
+
const cell_widths = {};
|
|
3795
|
+
const cell_heights = {};
|
|
3796
|
+
for (const cell of cells) {
|
|
3797
|
+
const fontSizeMm = getSchMmFontSize("reference_designator", cell.font_size);
|
|
3798
|
+
const textWidthMm = estimateTextWidth(cell.text ?? "") * fontSizeMm;
|
|
3799
|
+
const requiredWidth = textWidthMm + 2 * cell_padding;
|
|
3800
|
+
const requiredHeight = fontSizeMm * 1.2 + 2 * cell_padding;
|
|
3801
|
+
const key = `${cell.start_row_index}-${cell.start_column_index}`;
|
|
3802
|
+
cell_widths[key] = requiredWidth;
|
|
3803
|
+
cell_heights[key] = requiredHeight;
|
|
3804
|
+
}
|
|
3805
|
+
for (let i = 0; i < numRows; i++) {
|
|
3806
|
+
for (let j = 0; j < numColumns; j++) {
|
|
3807
|
+
const key = `${i}-${j}`;
|
|
3808
|
+
if (cell_widths[key] && cell_widths[key] > column_widths[j]) {
|
|
3809
|
+
column_widths[j] = cell_widths[key];
|
|
3810
|
+
}
|
|
3811
|
+
if (cell_heights[key] && cell_heights[key] > row_heights[i]) {
|
|
3812
|
+
row_heights[i] = cell_heights[key];
|
|
3813
|
+
}
|
|
3814
|
+
}
|
|
3815
|
+
}
|
|
3816
|
+
for (const cell of cells) {
|
|
3817
|
+
if (cell.start_column_index === cell.end_column_index && cell.start_row_index === cell.end_row_index)
|
|
3818
|
+
continue;
|
|
3819
|
+
const key = `${cell.start_row_index}-${cell.start_column_index}`;
|
|
3820
|
+
const requiredWidth = cell_widths[key];
|
|
3821
|
+
const requiredHeight = cell_heights[key];
|
|
3822
|
+
if (requiredWidth === void 0 || requiredHeight === void 0) continue;
|
|
3823
|
+
let currentWidth = 0;
|
|
3824
|
+
for (let i = cell.start_column_index; i <= cell.end_column_index; i++) {
|
|
3825
|
+
currentWidth += column_widths[i];
|
|
3826
|
+
}
|
|
3827
|
+
if (requiredWidth > currentWidth) {
|
|
3828
|
+
const diff = requiredWidth - currentWidth;
|
|
3829
|
+
const extraPerColumn = diff / (cell.end_column_index - cell.start_column_index + 1);
|
|
3830
|
+
for (let i = cell.start_column_index; i <= cell.end_column_index; i++) {
|
|
3831
|
+
column_widths[i] += extraPerColumn;
|
|
3832
|
+
}
|
|
3833
|
+
}
|
|
3834
|
+
let currentHeight = 0;
|
|
3835
|
+
for (let i = cell.start_row_index; i <= cell.end_row_index; i++) {
|
|
3836
|
+
currentHeight += row_heights[i];
|
|
3837
|
+
}
|
|
3838
|
+
if (requiredHeight > currentHeight) {
|
|
3839
|
+
const diff = requiredHeight - currentHeight;
|
|
3840
|
+
const extraPerRow = diff / (cell.end_row_index - cell.start_row_index + 1);
|
|
3841
|
+
for (let i = cell.start_row_index; i <= cell.end_row_index; i++) {
|
|
3842
|
+
row_heights[i] += extraPerRow;
|
|
3843
|
+
}
|
|
3844
|
+
}
|
|
3845
|
+
}
|
|
3846
|
+
return { column_widths, row_heights };
|
|
3847
|
+
};
|
|
3848
|
+
|
|
3849
|
+
// lib/utils/get-unit-vector-from-outside-to-edge.ts
|
|
3850
|
+
var getUnitVectorFromOutsideToEdge = (side) => {
|
|
3851
|
+
switch (side) {
|
|
3852
|
+
case "top":
|
|
3853
|
+
return { x: 0, y: -1 };
|
|
3854
|
+
case "bottom":
|
|
3855
|
+
return { x: 0, y: 1 };
|
|
3856
|
+
case "left":
|
|
3857
|
+
return { x: 1, y: 0 };
|
|
3858
|
+
case "right":
|
|
3859
|
+
return { x: -1, y: 0 };
|
|
3860
|
+
}
|
|
3861
|
+
throw new Error(`Invalid side: ${side}`);
|
|
3862
|
+
};
|
|
3863
|
+
|
|
3864
|
+
// lib/utils/net-label-utils.ts
|
|
3865
|
+
import "transformation-matrix";
|
|
3866
|
+
import "schematic-symbols";
|
|
3867
|
+
var ARROW_POINT_WIDTH_FSR = 0.3;
|
|
3868
|
+
var END_PADDING_FSR = 0.3;
|
|
3869
|
+
var END_PADDING_EXTRA_PER_CHARACTER_FSR = 0.06;
|
|
3870
|
+
var ninePointAnchorToTextAnchor = {
|
|
3871
|
+
top_left: "start",
|
|
3872
|
+
top_right: "end",
|
|
3873
|
+
middle_left: "start",
|
|
3874
|
+
middle_right: "end",
|
|
3875
|
+
bottom_left: "start",
|
|
3876
|
+
bottom_right: "end",
|
|
3877
|
+
center: "middle",
|
|
3878
|
+
middle_top: "middle",
|
|
3879
|
+
middle_bottom: "middle"
|
|
3880
|
+
};
|
|
3881
|
+
var ninePointAnchorToDominantBaseline = {
|
|
3882
|
+
top_left: "hanging",
|
|
3883
|
+
top_right: "hanging",
|
|
3884
|
+
bottom_left: "ideographic",
|
|
3885
|
+
bottom_right: "ideographic",
|
|
3886
|
+
center: "middle",
|
|
3887
|
+
middle_left: "middle",
|
|
3888
|
+
middle_right: "middle",
|
|
3889
|
+
middle_top: "hanging",
|
|
3890
|
+
middle_bottom: "ideographic"
|
|
3891
|
+
};
|
|
3892
|
+
function getPathRotation(anchorSide) {
|
|
3893
|
+
const rotationMap = {
|
|
3894
|
+
left: 180,
|
|
3895
|
+
top: 90,
|
|
3896
|
+
bottom: -90,
|
|
3897
|
+
right: 0
|
|
3898
|
+
};
|
|
3899
|
+
return rotationMap[anchorSide] ?? 0;
|
|
3900
|
+
}
|
|
3901
|
+
function calculateAnchorPosition(schNetLabel, fontSizeMm, textWidthFSR) {
|
|
3902
|
+
const fullWidthFsr = textWidthFSR + ARROW_POINT_WIDTH_FSR * 2 + END_PADDING_EXTRA_PER_CHARACTER_FSR * schNetLabel.text.length + END_PADDING_FSR;
|
|
3903
|
+
const realTextGrowthVec = getUnitVectorFromOutsideToEdge(
|
|
3904
|
+
schNetLabel.anchor_side
|
|
3905
|
+
);
|
|
3906
|
+
return schNetLabel.anchor_position ?? {
|
|
3907
|
+
x: schNetLabel.center.x - realTextGrowthVec.x * fullWidthFsr * fontSizeMm / 2,
|
|
3908
|
+
y: schNetLabel.center.y - realTextGrowthVec.y * fullWidthFsr * fontSizeMm / 2
|
|
3909
|
+
};
|
|
3910
|
+
}
|
|
3911
|
+
|
|
3824
3912
|
// lib/sch/get-schematic-bounds-from-circuit-json.ts
|
|
3825
3913
|
function getSchematicBoundsFromCircuitJson(soup, padding = 0.5) {
|
|
3826
3914
|
let minX = Number.POSITIVE_INFINITY;
|
|
@@ -3881,6 +3969,30 @@ function getSchematicBoundsFromCircuitJson(soup, padding = 0.5) {
|
|
|
3881
3969
|
{ width: item.width, height: item.height },
|
|
3882
3970
|
0
|
|
3883
3971
|
);
|
|
3972
|
+
} else if (item.type === "schematic_table") {
|
|
3973
|
+
const { column_widths, row_heights } = getTableDimensions(item, soup);
|
|
3974
|
+
const totalWidth = column_widths.reduce((a, b) => a + b, 0);
|
|
3975
|
+
const totalHeight = row_heights.reduce((a, b) => a + b, 0);
|
|
3976
|
+
const anchor = item.anchor ?? "center";
|
|
3977
|
+
let topLeftX = item.anchor_position.x;
|
|
3978
|
+
let topLeftY = item.anchor_position.y;
|
|
3979
|
+
if (anchor.includes("center")) {
|
|
3980
|
+
topLeftX -= totalWidth / 2;
|
|
3981
|
+
} else if (anchor.includes("right")) {
|
|
3982
|
+
topLeftX -= totalWidth;
|
|
3983
|
+
}
|
|
3984
|
+
if (anchor.includes("center")) {
|
|
3985
|
+
topLeftY += totalHeight / 2;
|
|
3986
|
+
} else if (anchor.includes("bottom")) {
|
|
3987
|
+
topLeftY += totalHeight;
|
|
3988
|
+
}
|
|
3989
|
+
const centerX = topLeftX + totalWidth / 2;
|
|
3990
|
+
const centerY = topLeftY - totalHeight / 2;
|
|
3991
|
+
updateBounds(
|
|
3992
|
+
{ x: centerX, y: centerY },
|
|
3993
|
+
{ width: totalWidth, height: totalHeight },
|
|
3994
|
+
0
|
|
3995
|
+
);
|
|
3884
3996
|
}
|
|
3885
3997
|
}
|
|
3886
3998
|
minX -= padding;
|
|
@@ -4432,6 +4544,10 @@ var createSvgObjectsForSchPortPinLabel = (params) => {
|
|
|
4432
4544
|
if (!label) return [];
|
|
4433
4545
|
const isNegated = label.startsWith("N_");
|
|
4434
4546
|
const displayLabel = isNegated ? label.slice(2) : label;
|
|
4547
|
+
let fontSizePx = getSchScreenFontSize(
|
|
4548
|
+
transform,
|
|
4549
|
+
isNegated ? "negated_pin_number" : "pin_number"
|
|
4550
|
+
);
|
|
4435
4551
|
svgObjects.push({
|
|
4436
4552
|
name: "text",
|
|
4437
4553
|
type: "element",
|
|
@@ -4443,7 +4559,7 @@ var createSvgObjectsForSchPortPinLabel = (params) => {
|
|
|
4443
4559
|
fill: colorMap.schematic.pin_number,
|
|
4444
4560
|
"text-anchor": schPort.side_of_component === "left" || schPort.side_of_component === "bottom" ? "start" : "end",
|
|
4445
4561
|
"dominant-baseline": "middle",
|
|
4446
|
-
"font-size": `${
|
|
4562
|
+
"font-size": `${fontSizePx}px`,
|
|
4447
4563
|
transform: schPort.side_of_component === "top" || schPort.side_of_component === "bottom" ? `rotate(-90 ${screenPinNumberTextPos.x} ${screenPinNumberTextPos.y})` : ""
|
|
4448
4564
|
},
|
|
4449
4565
|
children: [
|
|
@@ -5220,8 +5336,7 @@ var createSvgObjectsForSchNetLabel = ({
|
|
|
5220
5336
|
colorMap: colorMap2
|
|
5221
5337
|
}) => {
|
|
5222
5338
|
if (!schNetLabel.text) return [];
|
|
5223
|
-
const
|
|
5224
|
-
const labelText = isNegated ? schNetLabel.text.slice(2) : schNetLabel.text;
|
|
5339
|
+
const labelText = schNetLabel.text;
|
|
5225
5340
|
if (schNetLabel.symbol_name) {
|
|
5226
5341
|
return createSvgObjectsForSchNetLabelWithSymbol({
|
|
5227
5342
|
schNetLabel,
|
|
@@ -5341,8 +5456,7 @@ var createSvgObjectsForSchNetLabel = ({
|
|
|
5341
5456
|
"font-family": "sans-serif",
|
|
5342
5457
|
"font-variant-numeric": "tabular-nums",
|
|
5343
5458
|
"font-size": `${fontSizePx}px`,
|
|
5344
|
-
transform: textTransformString
|
|
5345
|
-
...isNegated ? { style: "text-decoration: overline;" } : {}
|
|
5459
|
+
transform: textTransformString
|
|
5346
5460
|
},
|
|
5347
5461
|
children: [
|
|
5348
5462
|
{
|
|
@@ -5402,6 +5516,206 @@ var createSvgObjectsFromSchematicBox = ({
|
|
|
5402
5516
|
];
|
|
5403
5517
|
};
|
|
5404
5518
|
|
|
5519
|
+
// lib/sch/svg-object-fns/create-svg-objects-from-sch-table.ts
|
|
5520
|
+
import { applyToPoint as applyToPoint42 } from "transformation-matrix";
|
|
5521
|
+
var createSvgObjectsFromSchematicTable = ({
|
|
5522
|
+
schematicTable,
|
|
5523
|
+
transform,
|
|
5524
|
+
colorMap: colorMap2,
|
|
5525
|
+
circuitJson
|
|
5526
|
+
}) => {
|
|
5527
|
+
const {
|
|
5528
|
+
anchor_position,
|
|
5529
|
+
border_width = 0.05,
|
|
5530
|
+
anchor = "center"
|
|
5531
|
+
} = schematicTable;
|
|
5532
|
+
const { column_widths, row_heights } = getTableDimensions(
|
|
5533
|
+
schematicTable,
|
|
5534
|
+
circuitJson
|
|
5535
|
+
);
|
|
5536
|
+
const totalWidth = column_widths.reduce((a, b) => a + b, 0);
|
|
5537
|
+
const totalHeight = row_heights.reduce((a, b) => a + b, 0);
|
|
5538
|
+
let topLeftX = anchor_position.x;
|
|
5539
|
+
let topLeftY = anchor_position.y;
|
|
5540
|
+
if (anchor.includes("center")) {
|
|
5541
|
+
topLeftX -= totalWidth / 2;
|
|
5542
|
+
} else if (anchor.includes("right")) {
|
|
5543
|
+
topLeftX -= totalWidth;
|
|
5544
|
+
}
|
|
5545
|
+
if (anchor.includes("center")) {
|
|
5546
|
+
topLeftY += totalHeight / 2;
|
|
5547
|
+
} else if (anchor.includes("bottom")) {
|
|
5548
|
+
topLeftY += totalHeight;
|
|
5549
|
+
}
|
|
5550
|
+
const svgObjects = [];
|
|
5551
|
+
const borderStrokeWidth = border_width * Math.abs(transform.a);
|
|
5552
|
+
const gridStrokeWidth = getSchStrokeSize(transform);
|
|
5553
|
+
const [screenTopLeftX, screenTopLeftY] = applyToPoint42(transform, [
|
|
5554
|
+
topLeftX,
|
|
5555
|
+
topLeftY
|
|
5556
|
+
]);
|
|
5557
|
+
const [screenBottomRightX, screenBottomRightY] = applyToPoint42(transform, [
|
|
5558
|
+
topLeftX + totalWidth,
|
|
5559
|
+
topLeftY - totalHeight
|
|
5560
|
+
]);
|
|
5561
|
+
svgObjects.push({
|
|
5562
|
+
name: "rect",
|
|
5563
|
+
type: "element",
|
|
5564
|
+
attributes: {
|
|
5565
|
+
x: screenTopLeftX.toString(),
|
|
5566
|
+
y: screenTopLeftY.toString(),
|
|
5567
|
+
width: (screenBottomRightX - screenTopLeftX).toString(),
|
|
5568
|
+
height: (screenBottomRightY - screenTopLeftY).toString(),
|
|
5569
|
+
fill: "none",
|
|
5570
|
+
stroke: "#666",
|
|
5571
|
+
"stroke-width": borderStrokeWidth.toString()
|
|
5572
|
+
},
|
|
5573
|
+
children: [],
|
|
5574
|
+
value: ""
|
|
5575
|
+
});
|
|
5576
|
+
const cells = circuitJson.filter(
|
|
5577
|
+
(elm) => elm.type === "schematic_table_cell" && elm.schematic_table_id === schematicTable.schematic_table_id
|
|
5578
|
+
);
|
|
5579
|
+
let currentX = topLeftX;
|
|
5580
|
+
for (let i = 0; i < column_widths.length - 1; i++) {
|
|
5581
|
+
currentX += column_widths[i];
|
|
5582
|
+
let segmentStartY = topLeftY;
|
|
5583
|
+
for (let j = 0; j < row_heights.length; j++) {
|
|
5584
|
+
const segmentEndY = segmentStartY - row_heights[j];
|
|
5585
|
+
const isMerged = cells.some(
|
|
5586
|
+
(cell) => cell.start_column_index <= i && cell.end_column_index > i && cell.start_row_index <= j && cell.end_row_index >= j
|
|
5587
|
+
);
|
|
5588
|
+
if (!isMerged) {
|
|
5589
|
+
const start = applyToPoint42(transform, { x: currentX, y: segmentStartY });
|
|
5590
|
+
const end = applyToPoint42(transform, { x: currentX, y: segmentEndY });
|
|
5591
|
+
svgObjects.push({
|
|
5592
|
+
name: "line",
|
|
5593
|
+
type: "element",
|
|
5594
|
+
attributes: {
|
|
5595
|
+
x1: start.x.toString(),
|
|
5596
|
+
y1: start.y.toString(),
|
|
5597
|
+
x2: end.x.toString(),
|
|
5598
|
+
y2: end.y.toString(),
|
|
5599
|
+
stroke: "#666",
|
|
5600
|
+
"stroke-width": gridStrokeWidth.toString()
|
|
5601
|
+
},
|
|
5602
|
+
children: [],
|
|
5603
|
+
value: ""
|
|
5604
|
+
});
|
|
5605
|
+
}
|
|
5606
|
+
segmentStartY = segmentEndY;
|
|
5607
|
+
}
|
|
5608
|
+
}
|
|
5609
|
+
let currentY = topLeftY;
|
|
5610
|
+
for (let i = 0; i < row_heights.length - 1; i++) {
|
|
5611
|
+
currentY -= row_heights[i];
|
|
5612
|
+
let segmentStartX = topLeftX;
|
|
5613
|
+
for (let j = 0; j < column_widths.length; j++) {
|
|
5614
|
+
const segmentEndX = segmentStartX + column_widths[j];
|
|
5615
|
+
const isMerged = cells.some(
|
|
5616
|
+
(cell) => cell.start_row_index <= i && cell.end_row_index > i && cell.start_column_index <= j && cell.end_column_index >= j
|
|
5617
|
+
);
|
|
5618
|
+
if (!isMerged) {
|
|
5619
|
+
const start = applyToPoint42(transform, {
|
|
5620
|
+
x: segmentStartX,
|
|
5621
|
+
y: currentY
|
|
5622
|
+
});
|
|
5623
|
+
const end = applyToPoint42(transform, { x: segmentEndX, y: currentY });
|
|
5624
|
+
svgObjects.push({
|
|
5625
|
+
name: "line",
|
|
5626
|
+
type: "element",
|
|
5627
|
+
attributes: {
|
|
5628
|
+
x1: start.x.toString(),
|
|
5629
|
+
y1: start.y.toString(),
|
|
5630
|
+
x2: end.x.toString(),
|
|
5631
|
+
y2: end.y.toString(),
|
|
5632
|
+
stroke: "#666",
|
|
5633
|
+
"stroke-width": gridStrokeWidth.toString()
|
|
5634
|
+
},
|
|
5635
|
+
children: [],
|
|
5636
|
+
value: ""
|
|
5637
|
+
});
|
|
5638
|
+
}
|
|
5639
|
+
segmentStartX = segmentEndX;
|
|
5640
|
+
}
|
|
5641
|
+
}
|
|
5642
|
+
for (const cell of cells) {
|
|
5643
|
+
if (cell.text) {
|
|
5644
|
+
const cellWidth = column_widths.slice(cell.start_column_index, cell.end_column_index + 1).reduce((a, b) => a + b, 0);
|
|
5645
|
+
const cellHeight = row_heights.slice(cell.start_row_index, cell.end_row_index + 1).reduce((a, b) => a + b, 0);
|
|
5646
|
+
const cellTopLeftX = topLeftX + column_widths.slice(0, cell.start_column_index).reduce((a, b) => a + b, 0);
|
|
5647
|
+
const cellTopLeftY = topLeftY - row_heights.slice(0, cell.start_row_index).reduce((a, b) => a + b, 0);
|
|
5648
|
+
const { cell_padding = 0.2 } = schematicTable;
|
|
5649
|
+
const horizontal_align = cell.horizontal_align ?? "center";
|
|
5650
|
+
const vertical_align = cell.vertical_align ?? "middle";
|
|
5651
|
+
let realTextAnchorPos = {
|
|
5652
|
+
x: cellTopLeftX + cellWidth / 2,
|
|
5653
|
+
y: cellTopLeftY - cellHeight / 2
|
|
5654
|
+
};
|
|
5655
|
+
if (horizontal_align === "left") {
|
|
5656
|
+
realTextAnchorPos.x = cellTopLeftX + cell_padding;
|
|
5657
|
+
} else if (horizontal_align === "right") {
|
|
5658
|
+
realTextAnchorPos.x = cellTopLeftX + cellWidth - cell_padding;
|
|
5659
|
+
}
|
|
5660
|
+
if (vertical_align === "top") {
|
|
5661
|
+
realTextAnchorPos.y = cellTopLeftY - cell_padding;
|
|
5662
|
+
} else if (vertical_align === "bottom") {
|
|
5663
|
+
realTextAnchorPos.y = cellTopLeftY - cellHeight + cell_padding;
|
|
5664
|
+
}
|
|
5665
|
+
const screenTextAnchorPos = applyToPoint42(transform, realTextAnchorPos);
|
|
5666
|
+
const fontSize = getSchScreenFontSize(
|
|
5667
|
+
transform,
|
|
5668
|
+
"reference_designator",
|
|
5669
|
+
cell.font_size
|
|
5670
|
+
);
|
|
5671
|
+
const textAnchorMap = {
|
|
5672
|
+
left: "start",
|
|
5673
|
+
center: "middle",
|
|
5674
|
+
right: "end"
|
|
5675
|
+
};
|
|
5676
|
+
const dominantBaselineMap = {
|
|
5677
|
+
top: "hanging",
|
|
5678
|
+
middle: "middle",
|
|
5679
|
+
bottom: "ideographic"
|
|
5680
|
+
};
|
|
5681
|
+
svgObjects.push({
|
|
5682
|
+
name: "text",
|
|
5683
|
+
type: "element",
|
|
5684
|
+
attributes: {
|
|
5685
|
+
x: screenTextAnchorPos.x.toString(),
|
|
5686
|
+
y: screenTextAnchorPos.y.toString(),
|
|
5687
|
+
"font-size": `${fontSize}px`,
|
|
5688
|
+
"text-anchor": textAnchorMap[horizontal_align],
|
|
5689
|
+
"dominant-baseline": dominantBaselineMap[vertical_align],
|
|
5690
|
+
fill: colorMap2.schematic.sheet_label,
|
|
5691
|
+
"font-family": "sans-serif"
|
|
5692
|
+
},
|
|
5693
|
+
children: [
|
|
5694
|
+
{
|
|
5695
|
+
type: "text",
|
|
5696
|
+
value: cell.text,
|
|
5697
|
+
name: "",
|
|
5698
|
+
attributes: {},
|
|
5699
|
+
children: []
|
|
5700
|
+
}
|
|
5701
|
+
],
|
|
5702
|
+
value: ""
|
|
5703
|
+
});
|
|
5704
|
+
}
|
|
5705
|
+
}
|
|
5706
|
+
return [
|
|
5707
|
+
{
|
|
5708
|
+
name: "g",
|
|
5709
|
+
type: "element",
|
|
5710
|
+
attributes: {
|
|
5711
|
+
"data-schematic-table-id": schematicTable.schematic_table_id
|
|
5712
|
+
},
|
|
5713
|
+
children: svgObjects,
|
|
5714
|
+
value: ""
|
|
5715
|
+
}
|
|
5716
|
+
];
|
|
5717
|
+
};
|
|
5718
|
+
|
|
5405
5719
|
// lib/sch/convert-circuit-json-to-schematic-svg.ts
|
|
5406
5720
|
function convertCircuitJsonToSchematicSvg(circuitJson, options) {
|
|
5407
5721
|
const realBounds = getSchematicBoundsFromCircuitJson(circuitJson);
|
|
@@ -5472,6 +5786,7 @@ function convertCircuitJsonToSchematicSvg(circuitJson, options) {
|
|
|
5472
5786
|
const schText = [];
|
|
5473
5787
|
const voltageProbeSvgs = [];
|
|
5474
5788
|
const schBoxSvgs = [];
|
|
5789
|
+
const schTableSvgs = [];
|
|
5475
5790
|
for (const elm of circuitJson) {
|
|
5476
5791
|
if (elm.type === "schematic_debug_object") {
|
|
5477
5792
|
schDebugObjectSvgs.push(
|
|
@@ -5529,6 +5844,15 @@ function convertCircuitJsonToSchematicSvg(circuitJson, options) {
|
|
|
5529
5844
|
colorMap: colorMap2
|
|
5530
5845
|
})
|
|
5531
5846
|
);
|
|
5847
|
+
} else if (elm.type === "schematic_table") {
|
|
5848
|
+
schTableSvgs.push(
|
|
5849
|
+
...createSvgObjectsFromSchematicTable({
|
|
5850
|
+
schematicTable: elm,
|
|
5851
|
+
transform,
|
|
5852
|
+
colorMap: colorMap2,
|
|
5853
|
+
circuitJson
|
|
5854
|
+
})
|
|
5855
|
+
);
|
|
5532
5856
|
}
|
|
5533
5857
|
}
|
|
5534
5858
|
svgChildren.push(
|
|
@@ -5538,7 +5862,8 @@ function convertCircuitJsonToSchematicSvg(circuitJson, options) {
|
|
|
5538
5862
|
...schNetLabel,
|
|
5539
5863
|
...schText,
|
|
5540
5864
|
...schBoxSvgs,
|
|
5541
|
-
...voltageProbeSvgs
|
|
5865
|
+
...voltageProbeSvgs,
|
|
5866
|
+
...schTableSvgs
|
|
5542
5867
|
);
|
|
5543
5868
|
if (options?.labeledPoints) {
|
|
5544
5869
|
svgChildren.push(
|
|
@@ -5611,18 +5936,18 @@ var circuitJsonToSchematicSvg = convertCircuitJsonToSchematicSvg;
|
|
|
5611
5936
|
// lib/pcb/convert-circuit-json-to-solder-paste-mask.ts
|
|
5612
5937
|
import { stringify as stringify4 } from "svgson";
|
|
5613
5938
|
import {
|
|
5614
|
-
applyToPoint as
|
|
5939
|
+
applyToPoint as applyToPoint45,
|
|
5615
5940
|
compose as compose11,
|
|
5616
5941
|
scale as scale8,
|
|
5617
5942
|
translate as translate11
|
|
5618
5943
|
} from "transformation-matrix";
|
|
5619
5944
|
|
|
5620
5945
|
// lib/pcb/svg-object-fns/convert-circuit-json-to-solder-paste-mask.ts
|
|
5621
|
-
import { applyToPoint as
|
|
5946
|
+
import { applyToPoint as applyToPoint44 } from "transformation-matrix";
|
|
5622
5947
|
function createSvgObjectsFromSolderPaste(solderPaste, ctx) {
|
|
5623
5948
|
const { transform, layer: layerFilter } = ctx;
|
|
5624
5949
|
if (layerFilter && solderPaste.layer !== layerFilter) return [];
|
|
5625
|
-
const [x, y] =
|
|
5950
|
+
const [x, y] = applyToPoint44(transform, [solderPaste.x, solderPaste.y]);
|
|
5626
5951
|
if (solderPaste.shape === "rect" || solderPaste.shape === "rotated_rect") {
|
|
5627
5952
|
const width = solderPaste.width * Math.abs(transform.a);
|
|
5628
5953
|
const height = solderPaste.height * Math.abs(transform.d);
|
|
@@ -5821,8 +6146,8 @@ function createSvgObjects3({ elm, ctx }) {
|
|
|
5821
6146
|
}
|
|
5822
6147
|
}
|
|
5823
6148
|
function createSvgObjectFromPcbBoundary2(transform, minX, minY, maxX, maxY) {
|
|
5824
|
-
const [x1, y1] =
|
|
5825
|
-
const [x2, y2] =
|
|
6149
|
+
const [x1, y1] = applyToPoint45(transform, [minX, minY]);
|
|
6150
|
+
const [x2, y2] = applyToPoint45(transform, [maxX, maxY]);
|
|
5826
6151
|
const width = Math.abs(x2 - x1);
|
|
5827
6152
|
const height = Math.abs(y2 - y1);
|
|
5828
6153
|
const x = Math.min(x1, x2);
|