circuit-to-svg 0.0.283 → 0.0.285
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 +1211 -927
- package/dist/index.js.map +1 -1
- package/package.json +7 -3
package/dist/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
// lib/pcb/convert-circuit-json-to-pcb-svg.ts
|
|
2
|
-
import { distance } from "circuit-json";
|
|
2
|
+
import { distance as distance2 } from "circuit-json";
|
|
3
3
|
import { stringify } from "svgson";
|
|
4
4
|
import {
|
|
5
|
-
applyToPoint as
|
|
6
|
-
compose as
|
|
7
|
-
scale as
|
|
8
|
-
translate as
|
|
5
|
+
applyToPoint as applyToPoint33,
|
|
6
|
+
compose as compose6,
|
|
7
|
+
scale as scale3,
|
|
8
|
+
translate as translate6
|
|
9
9
|
} from "transformation-matrix";
|
|
10
10
|
|
|
11
11
|
// lib/pcb/svg-object-fns/create-svg-objects-from-pcb-trace-error.ts
|
|
@@ -2677,8 +2677,326 @@ function createSvgObjectsFromPcbSilkscreenRect(pcbSilkscreenRect, ctx) {
|
|
|
2677
2677
|
return [svgObject];
|
|
2678
2678
|
}
|
|
2679
2679
|
|
|
2680
|
+
// lib/pcb/svg-object-fns/create-svg-objects-from-pcb-copper-text.ts
|
|
2681
|
+
import {
|
|
2682
|
+
applyToPoint as applyToPoint16,
|
|
2683
|
+
compose as compose3,
|
|
2684
|
+
rotate as rotate3,
|
|
2685
|
+
translate as translate3,
|
|
2686
|
+
scale as scale2,
|
|
2687
|
+
toString as matrixToString4
|
|
2688
|
+
} from "transformation-matrix";
|
|
2689
|
+
|
|
2690
|
+
// lib/pcb/colors.ts
|
|
2691
|
+
var DEFAULT_PCB_COLOR_MAP = {
|
|
2692
|
+
copper: {
|
|
2693
|
+
top: "rgb(200, 52, 52)",
|
|
2694
|
+
inner1: "rgb(255, 140, 0)",
|
|
2695
|
+
inner2: "rgb(255, 215, 0)",
|
|
2696
|
+
inner3: "rgb(50, 205, 50)",
|
|
2697
|
+
inner4: "rgb(64, 224, 208)",
|
|
2698
|
+
inner5: "rgb(138, 43, 226)",
|
|
2699
|
+
inner6: "rgb(255, 105, 180)",
|
|
2700
|
+
bottom: "rgb(77, 127, 196)"
|
|
2701
|
+
},
|
|
2702
|
+
soldermaskWithCopperUnderneath: {
|
|
2703
|
+
top: "rgb(18, 82, 50)",
|
|
2704
|
+
bottom: "rgb(77, 127, 196)"
|
|
2705
|
+
},
|
|
2706
|
+
soldermask: {
|
|
2707
|
+
top: "rgb(12, 55, 33)",
|
|
2708
|
+
bottom: "rgb(12, 55, 33)"
|
|
2709
|
+
},
|
|
2710
|
+
soldermaskOverCopper: {
|
|
2711
|
+
top: "rgb(52, 135, 73)",
|
|
2712
|
+
bottom: "rgb(52, 135, 73)"
|
|
2713
|
+
},
|
|
2714
|
+
substrate: "rgb(201, 162, 110)",
|
|
2715
|
+
// FR4 substrate color (tan/beige)
|
|
2716
|
+
drill: "#FF26E2",
|
|
2717
|
+
silkscreen: {
|
|
2718
|
+
top: "#f2eda1",
|
|
2719
|
+
bottom: "#5da9e9"
|
|
2720
|
+
},
|
|
2721
|
+
boardOutline: "rgba(255, 255, 255, 0.5)",
|
|
2722
|
+
courtyard: "#FF00FF",
|
|
2723
|
+
debugComponent: {
|
|
2724
|
+
fill: null,
|
|
2725
|
+
stroke: null
|
|
2726
|
+
}
|
|
2727
|
+
};
|
|
2728
|
+
var HOLE_COLOR = DEFAULT_PCB_COLOR_MAP.drill;
|
|
2729
|
+
var SILKSCREEN_TOP_COLOR = DEFAULT_PCB_COLOR_MAP.silkscreen.top;
|
|
2730
|
+
var SILKSCREEN_BOTTOM_COLOR = DEFAULT_PCB_COLOR_MAP.silkscreen.bottom;
|
|
2731
|
+
|
|
2732
|
+
// lib/pcb/layer-name-to-color.ts
|
|
2733
|
+
var LAYER_NAME_TO_COLOR = {
|
|
2734
|
+
...DEFAULT_PCB_COLOR_MAP.copper
|
|
2735
|
+
};
|
|
2736
|
+
function layerNameToColor(layerName, colorMap2 = DEFAULT_PCB_COLOR_MAP) {
|
|
2737
|
+
return colorMap2.copper[layerName] ?? "white";
|
|
2738
|
+
}
|
|
2739
|
+
var SOLDER_PASTE_LAYER_NAME_TO_COLOR = {
|
|
2740
|
+
bottom: "rgb(105, 105, 105)",
|
|
2741
|
+
top: "rgb(105, 105, 105)"
|
|
2742
|
+
};
|
|
2743
|
+
function solderPasteLayerNameToColor(layerName) {
|
|
2744
|
+
return SOLDER_PASTE_LAYER_NAME_TO_COLOR[layerName] ?? "rgb(105, 105, 105)";
|
|
2745
|
+
}
|
|
2746
|
+
|
|
2747
|
+
// lib/pcb/svg-object-fns/create-svg-objects-from-pcb-copper-text.ts
|
|
2748
|
+
import { distance } from "circuit-json";
|
|
2749
|
+
import { lineAlphabet } from "@tscircuit/alphabet";
|
|
2750
|
+
var CHAR_WIDTH = 1;
|
|
2751
|
+
var CHAR_SPACING = 0.2;
|
|
2752
|
+
var LINE_HEIGHT = 1.4;
|
|
2753
|
+
function linesToPathData(lines, offsetX, offsetY, charScale) {
|
|
2754
|
+
return lines.map((line) => {
|
|
2755
|
+
const x1 = offsetX + line.x1 * charScale;
|
|
2756
|
+
const y1 = offsetY + (1 - line.y1) * charScale;
|
|
2757
|
+
const x2 = offsetX + line.x2 * charScale;
|
|
2758
|
+
const y2 = offsetY + (1 - line.y2) * charScale;
|
|
2759
|
+
return `M${x1} ${y1}L${x2} ${y2}`;
|
|
2760
|
+
}).join(" ");
|
|
2761
|
+
}
|
|
2762
|
+
function textToAlphabetPath(text, fontSize) {
|
|
2763
|
+
const paths = [];
|
|
2764
|
+
const charAdvance = (CHAR_WIDTH + CHAR_SPACING) * fontSize;
|
|
2765
|
+
let x = 0;
|
|
2766
|
+
for (const char of text) {
|
|
2767
|
+
if (char === " ") {
|
|
2768
|
+
x += charAdvance * 0.6;
|
|
2769
|
+
continue;
|
|
2770
|
+
}
|
|
2771
|
+
const lines = lineAlphabet[char];
|
|
2772
|
+
if (lines) {
|
|
2773
|
+
paths.push(linesToPathData(lines, x, 0, fontSize));
|
|
2774
|
+
}
|
|
2775
|
+
x += charAdvance;
|
|
2776
|
+
}
|
|
2777
|
+
const width = x > 0 ? x - CHAR_SPACING * fontSize : 0;
|
|
2778
|
+
return { pathData: paths.join(" "), width };
|
|
2779
|
+
}
|
|
2780
|
+
var maskIdCounter = 0;
|
|
2781
|
+
function textToCenteredAlphabetPaths(text, fontSize) {
|
|
2782
|
+
const textLines = text.split("\n");
|
|
2783
|
+
const lineHeight = fontSize * LINE_HEIGHT;
|
|
2784
|
+
const totalHeight = textLines.length * lineHeight;
|
|
2785
|
+
const lineWidths = [];
|
|
2786
|
+
let maxWidth = 0;
|
|
2787
|
+
for (const line of textLines) {
|
|
2788
|
+
const { width } = textToAlphabetPath(line, fontSize);
|
|
2789
|
+
lineWidths.push(width);
|
|
2790
|
+
if (width > maxWidth) maxWidth = width;
|
|
2791
|
+
}
|
|
2792
|
+
const paths = [];
|
|
2793
|
+
let y = -totalHeight / 2;
|
|
2794
|
+
for (let i = 0; i < textLines.length; i++) {
|
|
2795
|
+
const line = textLines[i];
|
|
2796
|
+
const lineWidth = lineWidths[i];
|
|
2797
|
+
const charAdvance = (CHAR_WIDTH + CHAR_SPACING) * fontSize;
|
|
2798
|
+
let x = -lineWidth / 2;
|
|
2799
|
+
for (const char of line) {
|
|
2800
|
+
if (char === " ") {
|
|
2801
|
+
x += charAdvance * 0.6;
|
|
2802
|
+
continue;
|
|
2803
|
+
}
|
|
2804
|
+
const charLines = lineAlphabet[char];
|
|
2805
|
+
if (charLines) {
|
|
2806
|
+
paths.push(linesToPathData(charLines, x, y, fontSize));
|
|
2807
|
+
}
|
|
2808
|
+
x += charAdvance;
|
|
2809
|
+
}
|
|
2810
|
+
y += lineHeight;
|
|
2811
|
+
}
|
|
2812
|
+
return {
|
|
2813
|
+
pathData: paths.join(" "),
|
|
2814
|
+
width: maxWidth,
|
|
2815
|
+
height: totalHeight
|
|
2816
|
+
};
|
|
2817
|
+
}
|
|
2818
|
+
function createSvgObjectsFromPcbCopperText(pcbCopperText, ctx) {
|
|
2819
|
+
const { transform, layer: filterLayer, colorMap: colorMap2 } = ctx;
|
|
2820
|
+
const {
|
|
2821
|
+
anchor_position,
|
|
2822
|
+
text,
|
|
2823
|
+
font_size = "0.2mm",
|
|
2824
|
+
layer,
|
|
2825
|
+
ccw_rotation = 0,
|
|
2826
|
+
anchor_alignment = "center",
|
|
2827
|
+
is_knockout = false,
|
|
2828
|
+
knockout_padding,
|
|
2829
|
+
is_mirrored = false
|
|
2830
|
+
} = pcbCopperText;
|
|
2831
|
+
const layerName = layer ?? "top";
|
|
2832
|
+
if (filterLayer && filterLayer !== layerName) return [];
|
|
2833
|
+
if (!anchor_position) return [];
|
|
2834
|
+
const [ax, ay] = applyToPoint16(transform, [
|
|
2835
|
+
anchor_position.x,
|
|
2836
|
+
anchor_position.y
|
|
2837
|
+
]);
|
|
2838
|
+
const fontSizeNum = distance.parse(font_size) ?? 0.2;
|
|
2839
|
+
const scaleFactor = Math.abs(transform.a);
|
|
2840
|
+
const copperColor = layerNameToColor(layerName, colorMap2);
|
|
2841
|
+
const isBottom = layerName === "bottom";
|
|
2842
|
+
const applyMirror = isBottom ? true : is_mirrored === true;
|
|
2843
|
+
if (is_knockout) {
|
|
2844
|
+
const { pathData: pathData2, width: width2, height: height2 } = textToCenteredAlphabetPaths(
|
|
2845
|
+
text,
|
|
2846
|
+
fontSizeNum
|
|
2847
|
+
);
|
|
2848
|
+
const padX = knockout_padding?.left ?? fontSizeNum * 0.5;
|
|
2849
|
+
const padY = knockout_padding?.top ?? fontSizeNum * 0.3;
|
|
2850
|
+
const rectW = width2 + padX * 2;
|
|
2851
|
+
const rectH = height2 + padY * 2;
|
|
2852
|
+
const strokeWidth2 = fontSizeNum * 0.15;
|
|
2853
|
+
const knockoutTransform = matrixToString4(
|
|
2854
|
+
compose3(
|
|
2855
|
+
translate3(ax, ay),
|
|
2856
|
+
rotate3(-ccw_rotation * Math.PI / 180),
|
|
2857
|
+
...applyMirror ? [scale2(-1, 1)] : [],
|
|
2858
|
+
scale2(scaleFactor, scaleFactor)
|
|
2859
|
+
)
|
|
2860
|
+
);
|
|
2861
|
+
const maskId = `knockout-mask-${pcbCopperText.pcb_copper_text_id}-${maskIdCounter++}`;
|
|
2862
|
+
return [
|
|
2863
|
+
{
|
|
2864
|
+
name: "defs",
|
|
2865
|
+
type: "element",
|
|
2866
|
+
value: "",
|
|
2867
|
+
children: [
|
|
2868
|
+
{
|
|
2869
|
+
name: "mask",
|
|
2870
|
+
type: "element",
|
|
2871
|
+
value: "",
|
|
2872
|
+
attributes: {
|
|
2873
|
+
id: maskId
|
|
2874
|
+
},
|
|
2875
|
+
children: [
|
|
2876
|
+
// White background - area that will show copper
|
|
2877
|
+
{
|
|
2878
|
+
name: "rect",
|
|
2879
|
+
type: "element",
|
|
2880
|
+
value: "",
|
|
2881
|
+
attributes: {
|
|
2882
|
+
x: (-rectW / 2).toString(),
|
|
2883
|
+
y: (-rectH / 2).toString(),
|
|
2884
|
+
width: rectW.toString(),
|
|
2885
|
+
height: rectH.toString(),
|
|
2886
|
+
fill: "white"
|
|
2887
|
+
},
|
|
2888
|
+
children: []
|
|
2889
|
+
},
|
|
2890
|
+
// Black text strokes - area that will be cut out
|
|
2891
|
+
{
|
|
2892
|
+
name: "path",
|
|
2893
|
+
type: "element",
|
|
2894
|
+
value: "",
|
|
2895
|
+
attributes: {
|
|
2896
|
+
d: pathData2,
|
|
2897
|
+
fill: "none",
|
|
2898
|
+
stroke: "black",
|
|
2899
|
+
"stroke-width": strokeWidth2.toString(),
|
|
2900
|
+
"stroke-linecap": "round",
|
|
2901
|
+
"stroke-linejoin": "round"
|
|
2902
|
+
},
|
|
2903
|
+
children: []
|
|
2904
|
+
}
|
|
2905
|
+
]
|
|
2906
|
+
}
|
|
2907
|
+
],
|
|
2908
|
+
attributes: {}
|
|
2909
|
+
},
|
|
2910
|
+
{
|
|
2911
|
+
name: "rect",
|
|
2912
|
+
type: "element",
|
|
2913
|
+
value: "",
|
|
2914
|
+
children: [],
|
|
2915
|
+
attributes: {
|
|
2916
|
+
x: (-rectW / 2).toString(),
|
|
2917
|
+
y: (-rectH / 2).toString(),
|
|
2918
|
+
width: rectW.toString(),
|
|
2919
|
+
height: rectH.toString(),
|
|
2920
|
+
fill: copperColor,
|
|
2921
|
+
mask: `url(#${maskId})`,
|
|
2922
|
+
transform: knockoutTransform,
|
|
2923
|
+
class: `pcb-copper-text-knockout pcb-copper-${layerName}`,
|
|
2924
|
+
"data-type": "pcb_copper_text",
|
|
2925
|
+
"data-pcb-copper-text-id": pcbCopperText.pcb_copper_text_id
|
|
2926
|
+
}
|
|
2927
|
+
}
|
|
2928
|
+
];
|
|
2929
|
+
}
|
|
2930
|
+
const { pathData, width, height } = textToCenteredAlphabetPaths(
|
|
2931
|
+
text,
|
|
2932
|
+
fontSizeNum
|
|
2933
|
+
);
|
|
2934
|
+
let offsetX = 0;
|
|
2935
|
+
let offsetY = 0;
|
|
2936
|
+
switch (anchor_alignment) {
|
|
2937
|
+
case "top_left":
|
|
2938
|
+
offsetX = width / 2;
|
|
2939
|
+
offsetY = height / 2;
|
|
2940
|
+
break;
|
|
2941
|
+
case "top_center":
|
|
2942
|
+
offsetY = height / 2;
|
|
2943
|
+
break;
|
|
2944
|
+
case "top_right":
|
|
2945
|
+
offsetX = -width / 2;
|
|
2946
|
+
offsetY = height / 2;
|
|
2947
|
+
break;
|
|
2948
|
+
case "center_left":
|
|
2949
|
+
offsetX = width / 2;
|
|
2950
|
+
break;
|
|
2951
|
+
case "center_right":
|
|
2952
|
+
offsetX = -width / 2;
|
|
2953
|
+
break;
|
|
2954
|
+
case "bottom_left":
|
|
2955
|
+
offsetX = width / 2;
|
|
2956
|
+
offsetY = -height / 2;
|
|
2957
|
+
break;
|
|
2958
|
+
case "bottom_center":
|
|
2959
|
+
offsetY = -height / 2;
|
|
2960
|
+
break;
|
|
2961
|
+
case "bottom_right":
|
|
2962
|
+
offsetX = -width / 2;
|
|
2963
|
+
offsetY = -height / 2;
|
|
2964
|
+
break;
|
|
2965
|
+
}
|
|
2966
|
+
const textTransform = matrixToString4(
|
|
2967
|
+
compose3(
|
|
2968
|
+
translate3(ax, ay),
|
|
2969
|
+
rotate3(-ccw_rotation * Math.PI / 180),
|
|
2970
|
+
...applyMirror ? [scale2(-1, 1)] : [],
|
|
2971
|
+
translate3(offsetX, offsetY),
|
|
2972
|
+
scale2(scaleFactor, scaleFactor)
|
|
2973
|
+
)
|
|
2974
|
+
);
|
|
2975
|
+
const strokeWidth = fontSizeNum * 0.15;
|
|
2976
|
+
return [
|
|
2977
|
+
{
|
|
2978
|
+
name: "path",
|
|
2979
|
+
type: "element",
|
|
2980
|
+
attributes: {
|
|
2981
|
+
d: pathData,
|
|
2982
|
+
fill: "none",
|
|
2983
|
+
stroke: copperColor,
|
|
2984
|
+
"stroke-width": strokeWidth.toString(),
|
|
2985
|
+
"stroke-linecap": "round",
|
|
2986
|
+
"stroke-linejoin": "round",
|
|
2987
|
+
transform: textTransform,
|
|
2988
|
+
class: `pcb-copper-text pcb-copper-${layerName}`,
|
|
2989
|
+
"data-type": "pcb_copper_text",
|
|
2990
|
+
"data-pcb-copper-text-id": pcbCopperText.pcb_copper_text_id
|
|
2991
|
+
},
|
|
2992
|
+
children: [],
|
|
2993
|
+
value: ""
|
|
2994
|
+
}
|
|
2995
|
+
];
|
|
2996
|
+
}
|
|
2997
|
+
|
|
2680
2998
|
// lib/pcb/svg-object-fns/create-svg-objects-from-pcb-silkscreen-circle.ts
|
|
2681
|
-
import { applyToPoint as
|
|
2999
|
+
import { applyToPoint as applyToPoint17 } from "transformation-matrix";
|
|
2682
3000
|
function createSvgObjectsFromPcbSilkscreenCircle(pcbSilkscreenCircle, ctx) {
|
|
2683
3001
|
const { transform, layer: layerFilter, colorMap: colorMap2 } = ctx;
|
|
2684
3002
|
const {
|
|
@@ -2693,7 +3011,7 @@ function createSvgObjectsFromPcbSilkscreenCircle(pcbSilkscreenCircle, ctx) {
|
|
|
2693
3011
|
console.error("Invalid PCB Silkscreen Circle data:", { center, radius });
|
|
2694
3012
|
return [];
|
|
2695
3013
|
}
|
|
2696
|
-
const [transformedX, transformedY] =
|
|
3014
|
+
const [transformedX, transformedY] = applyToPoint17(transform, [
|
|
2697
3015
|
center.x,
|
|
2698
3016
|
center.y
|
|
2699
3017
|
]);
|
|
@@ -2721,7 +3039,7 @@ function createSvgObjectsFromPcbSilkscreenCircle(pcbSilkscreenCircle, ctx) {
|
|
|
2721
3039
|
}
|
|
2722
3040
|
|
|
2723
3041
|
// lib/pcb/svg-object-fns/create-svg-objects-from-pcb-silkscreen-line.ts
|
|
2724
|
-
import { applyToPoint as
|
|
3042
|
+
import { applyToPoint as applyToPoint18 } from "transformation-matrix";
|
|
2725
3043
|
function createSvgObjectsFromPcbSilkscreenLine(pcbSilkscreenLine, ctx) {
|
|
2726
3044
|
const { transform, layer: layerFilter, colorMap: colorMap2 } = ctx;
|
|
2727
3045
|
const {
|
|
@@ -2738,8 +3056,8 @@ function createSvgObjectsFromPcbSilkscreenLine(pcbSilkscreenLine, ctx) {
|
|
|
2738
3056
|
console.error("Invalid coordinates:", { x1, y1, x2, y2 });
|
|
2739
3057
|
return [];
|
|
2740
3058
|
}
|
|
2741
|
-
const [transformedX1, transformedY1] =
|
|
2742
|
-
const [transformedX2, transformedY2] =
|
|
3059
|
+
const [transformedX1, transformedY1] = applyToPoint18(transform, [x1, y1]);
|
|
3060
|
+
const [transformedX2, transformedY2] = applyToPoint18(transform, [x2, y2]);
|
|
2743
3061
|
const transformedStrokeWidth = stroke_width * Math.abs(transform.a);
|
|
2744
3062
|
const color = layer === "bottom" ? colorMap2.silkscreen.bottom : colorMap2.silkscreen.top;
|
|
2745
3063
|
return [
|
|
@@ -2765,7 +3083,7 @@ function createSvgObjectsFromPcbSilkscreenLine(pcbSilkscreenLine, ctx) {
|
|
|
2765
3083
|
}
|
|
2766
3084
|
|
|
2767
3085
|
// lib/pcb/svg-object-fns/create-svg-objects-from-pcb-courtyard-rect.ts
|
|
2768
|
-
import { applyToPoint as
|
|
3086
|
+
import { applyToPoint as applyToPoint19 } from "transformation-matrix";
|
|
2769
3087
|
function createSvgObjectsFromPcbCourtyardRect(pcbCourtyardRect, ctx) {
|
|
2770
3088
|
const { transform, layer: layerFilter, colorMap: colorMap2 } = ctx;
|
|
2771
3089
|
const {
|
|
@@ -2784,7 +3102,7 @@ function createSvgObjectsFromPcbCourtyardRect(pcbCourtyardRect, ctx) {
|
|
|
2784
3102
|
});
|
|
2785
3103
|
return [];
|
|
2786
3104
|
}
|
|
2787
|
-
const [transformedX, transformedY] =
|
|
3105
|
+
const [transformedX, transformedY] = applyToPoint19(transform, [
|
|
2788
3106
|
center.x,
|
|
2789
3107
|
center.y
|
|
2790
3108
|
]);
|
|
@@ -2825,66 +3143,7 @@ function pairs(arr) {
|
|
|
2825
3143
|
}
|
|
2826
3144
|
|
|
2827
3145
|
// lib/pcb/svg-object-fns/create-svg-objects-from-pcb-trace.ts
|
|
2828
|
-
import { applyToPoint as
|
|
2829
|
-
|
|
2830
|
-
// lib/pcb/colors.ts
|
|
2831
|
-
var DEFAULT_PCB_COLOR_MAP = {
|
|
2832
|
-
copper: {
|
|
2833
|
-
top: "rgb(200, 52, 52)",
|
|
2834
|
-
inner1: "rgb(255, 140, 0)",
|
|
2835
|
-
inner2: "rgb(255, 215, 0)",
|
|
2836
|
-
inner3: "rgb(50, 205, 50)",
|
|
2837
|
-
inner4: "rgb(64, 224, 208)",
|
|
2838
|
-
inner5: "rgb(138, 43, 226)",
|
|
2839
|
-
inner6: "rgb(255, 105, 180)",
|
|
2840
|
-
bottom: "rgb(77, 127, 196)"
|
|
2841
|
-
},
|
|
2842
|
-
soldermaskWithCopperUnderneath: {
|
|
2843
|
-
top: "rgb(18, 82, 50)",
|
|
2844
|
-
bottom: "rgb(77, 127, 196)"
|
|
2845
|
-
},
|
|
2846
|
-
soldermask: {
|
|
2847
|
-
top: "rgb(12, 55, 33)",
|
|
2848
|
-
bottom: "rgb(12, 55, 33)"
|
|
2849
|
-
},
|
|
2850
|
-
soldermaskOverCopper: {
|
|
2851
|
-
top: "rgb(52, 135, 73)",
|
|
2852
|
-
bottom: "rgb(52, 135, 73)"
|
|
2853
|
-
},
|
|
2854
|
-
substrate: "rgb(201, 162, 110)",
|
|
2855
|
-
// FR4 substrate color (tan/beige)
|
|
2856
|
-
drill: "#FF26E2",
|
|
2857
|
-
silkscreen: {
|
|
2858
|
-
top: "#f2eda1",
|
|
2859
|
-
bottom: "#5da9e9"
|
|
2860
|
-
},
|
|
2861
|
-
boardOutline: "rgba(255, 255, 255, 0.5)",
|
|
2862
|
-
courtyard: "#FF00FF",
|
|
2863
|
-
debugComponent: {
|
|
2864
|
-
fill: null,
|
|
2865
|
-
stroke: null
|
|
2866
|
-
}
|
|
2867
|
-
};
|
|
2868
|
-
var HOLE_COLOR = DEFAULT_PCB_COLOR_MAP.drill;
|
|
2869
|
-
var SILKSCREEN_TOP_COLOR = DEFAULT_PCB_COLOR_MAP.silkscreen.top;
|
|
2870
|
-
var SILKSCREEN_BOTTOM_COLOR = DEFAULT_PCB_COLOR_MAP.silkscreen.bottom;
|
|
2871
|
-
|
|
2872
|
-
// lib/pcb/layer-name-to-color.ts
|
|
2873
|
-
var LAYER_NAME_TO_COLOR = {
|
|
2874
|
-
...DEFAULT_PCB_COLOR_MAP.copper
|
|
2875
|
-
};
|
|
2876
|
-
function layerNameToColor(layerName, colorMap2 = DEFAULT_PCB_COLOR_MAP) {
|
|
2877
|
-
return colorMap2.copper[layerName] ?? "white";
|
|
2878
|
-
}
|
|
2879
|
-
var SOLDER_PASTE_LAYER_NAME_TO_COLOR = {
|
|
2880
|
-
bottom: "rgb(105, 105, 105)",
|
|
2881
|
-
top: "rgb(105, 105, 105)"
|
|
2882
|
-
};
|
|
2883
|
-
function solderPasteLayerNameToColor(layerName) {
|
|
2884
|
-
return SOLDER_PASTE_LAYER_NAME_TO_COLOR[layerName] ?? "rgb(105, 105, 105)";
|
|
2885
|
-
}
|
|
2886
|
-
|
|
2887
|
-
// lib/pcb/svg-object-fns/create-svg-objects-from-pcb-trace.ts
|
|
3146
|
+
import { applyToPoint as applyToPoint20 } from "transformation-matrix";
|
|
2888
3147
|
function createSvgObjectsFromPcbTrace(trace, ctx) {
|
|
2889
3148
|
const { transform, layer: layerFilter, colorMap: colorMap2, showSolderMask } = ctx;
|
|
2890
3149
|
if (!trace.route || !Array.isArray(trace.route) || trace.route.length < 2)
|
|
@@ -2892,8 +3151,8 @@ function createSvgObjectsFromPcbTrace(trace, ctx) {
|
|
|
2892
3151
|
const segments = pairs(trace.route);
|
|
2893
3152
|
const svgObjects = [];
|
|
2894
3153
|
for (const [start, end] of segments) {
|
|
2895
|
-
const startPoint =
|
|
2896
|
-
const endPoint =
|
|
3154
|
+
const startPoint = applyToPoint20(transform, [start.x, start.y]);
|
|
3155
|
+
const endPoint = applyToPoint20(transform, [end.x, end.y]);
|
|
2897
3156
|
const layer = "layer" in start ? start.layer : "layer" in end ? end.layer : null;
|
|
2898
3157
|
if (!layer) continue;
|
|
2899
3158
|
if (layerFilter && layer !== layerFilter) continue;
|
|
@@ -2948,7 +3207,7 @@ function createSvgObjectsFromPcbTrace(trace, ctx) {
|
|
|
2948
3207
|
}
|
|
2949
3208
|
|
|
2950
3209
|
// lib/pcb/svg-object-fns/create-svg-objects-from-smt-pads.ts
|
|
2951
|
-
import { applyToPoint as
|
|
3210
|
+
import { applyToPoint as applyToPoint21 } from "transformation-matrix";
|
|
2952
3211
|
function createSvgObjectsFromSmtPad(pad, ctx) {
|
|
2953
3212
|
const { transform, layer: layerFilter, colorMap: colorMap2, showSolderMask } = ctx;
|
|
2954
3213
|
if (layerFilter && pad.layer !== layerFilter) return [];
|
|
@@ -2959,7 +3218,7 @@ function createSvgObjectsFromSmtPad(pad, ctx) {
|
|
|
2959
3218
|
if (pad.shape === "rect" || pad.shape === "rotated_rect") {
|
|
2960
3219
|
const width = pad.width * Math.abs(transform.a);
|
|
2961
3220
|
const height = pad.height * Math.abs(transform.d);
|
|
2962
|
-
const [x, y] =
|
|
3221
|
+
const [x, y] = applyToPoint21(transform, [pad.x, pad.y]);
|
|
2963
3222
|
const cornerRadiusValue = pad.corner_radius ?? pad.rect_border_radius ?? 0;
|
|
2964
3223
|
const scaledBorderRadius = cornerRadiusValue * Math.abs(transform.a);
|
|
2965
3224
|
if (pad.shape === "rotated_rect" && pad.ccw_rotation) {
|
|
@@ -3201,7 +3460,7 @@ function createSvgObjectsFromSmtPad(pad, ctx) {
|
|
|
3201
3460
|
const width = pad.width * Math.abs(transform.a);
|
|
3202
3461
|
const height = pad.height * Math.abs(transform.d);
|
|
3203
3462
|
const radius = pad.radius * Math.abs(transform.a);
|
|
3204
|
-
const [x, y] =
|
|
3463
|
+
const [x, y] = applyToPoint21(transform, [pad.x, pad.y]);
|
|
3205
3464
|
const rotationTransformAttributes = isRotated ? {
|
|
3206
3465
|
transform: `translate(${x} ${y}) rotate(${-(pad.ccw_rotation ?? 0)})`
|
|
3207
3466
|
} : void 0;
|
|
@@ -3319,7 +3578,7 @@ function createSvgObjectsFromSmtPad(pad, ctx) {
|
|
|
3319
3578
|
}
|
|
3320
3579
|
if (pad.shape === "circle") {
|
|
3321
3580
|
const radius = pad.radius * Math.abs(transform.a);
|
|
3322
|
-
const [x, y] =
|
|
3581
|
+
const [x, y] = applyToPoint21(transform, [pad.x, pad.y]);
|
|
3323
3582
|
const padElement = {
|
|
3324
3583
|
name: "circle",
|
|
3325
3584
|
type: "element",
|
|
@@ -3409,7 +3668,7 @@ function createSvgObjectsFromSmtPad(pad, ctx) {
|
|
|
3409
3668
|
}
|
|
3410
3669
|
if (pad.shape === "polygon") {
|
|
3411
3670
|
const points = (pad.points ?? []).map(
|
|
3412
|
-
(point) =>
|
|
3671
|
+
(point) => applyToPoint21(transform, [point.x, point.y])
|
|
3413
3672
|
);
|
|
3414
3673
|
const padElement = {
|
|
3415
3674
|
name: "polygon",
|
|
@@ -3434,10 +3693,10 @@ function createSvgObjectsFromSmtPad(pad, ctx) {
|
|
|
3434
3693
|
maskPoints = points.map(([px, py]) => {
|
|
3435
3694
|
const dx = px - centroidX;
|
|
3436
3695
|
const dy = py - centroidY;
|
|
3437
|
-
const
|
|
3438
|
-
if (
|
|
3439
|
-
const normalizedDx = dx /
|
|
3440
|
-
const normalizedDy = dy /
|
|
3696
|
+
const distance4 = Math.sqrt(dx * dx + dy * dy);
|
|
3697
|
+
if (distance4 === 0) return [px, py];
|
|
3698
|
+
const normalizedDx = dx / distance4;
|
|
3699
|
+
const normalizedDy = dy / distance4;
|
|
3441
3700
|
return [
|
|
3442
3701
|
px + normalizedDx * soldermaskMargin,
|
|
3443
3702
|
py + normalizedDy * soldermaskMargin
|
|
@@ -3508,190 +3767,513 @@ function createSvgObjectsFromSmtPad(pad, ctx) {
|
|
|
3508
3767
|
}
|
|
3509
3768
|
|
|
3510
3769
|
// lib/pcb/svg-object-fns/create-svg-objects-from-pcb-board.ts
|
|
3511
|
-
import { applyToPoint as
|
|
3512
|
-
function createSvgObjectsFromPcbBoard(pcbBoard, ctx) {
|
|
3513
|
-
const { transform, colorMap: colorMap2, showSolderMask } = ctx;
|
|
3514
|
-
const { width, height, center, outline } = pcbBoard;
|
|
3515
|
-
let path;
|
|
3516
|
-
if (outline && Array.isArray(outline) && outline.length >= 3) {
|
|
3517
|
-
path = outline.map((point, index) => {
|
|
3518
|
-
const [x, y] = applyToPoint21(transform, [point.x, point.y]);
|
|
3519
|
-
return index === 0 ? `M ${x} ${y}` : `L ${x} ${y}`;
|
|
3520
|
-
}).join(" ");
|
|
3521
|
-
} else {
|
|
3522
|
-
const halfWidth = width / 2;
|
|
3523
|
-
const halfHeight = height / 2;
|
|
3524
|
-
const topLeft = applyToPoint21(transform, [
|
|
3525
|
-
center.x - halfWidth,
|
|
3526
|
-
center.y - halfHeight
|
|
3527
|
-
]);
|
|
3528
|
-
const topRight = applyToPoint21(transform, [
|
|
3529
|
-
center.x + halfWidth,
|
|
3530
|
-
center.y - halfHeight
|
|
3531
|
-
]);
|
|
3532
|
-
const bottomRight = applyToPoint21(transform, [
|
|
3533
|
-
center.x + halfWidth,
|
|
3534
|
-
center.y + halfHeight
|
|
3535
|
-
]);
|
|
3536
|
-
const bottomLeft = applyToPoint21(transform, [
|
|
3537
|
-
center.x - halfWidth,
|
|
3538
|
-
center.y + halfHeight
|
|
3539
|
-
]);
|
|
3540
|
-
path = `M ${topLeft[0]} ${topLeft[1]} L ${topRight[0]} ${topRight[1]} L ${bottomRight[0]} ${bottomRight[1]} L ${bottomLeft[0]} ${bottomLeft[1]}`;
|
|
3541
|
-
}
|
|
3542
|
-
path += " Z";
|
|
3543
|
-
const svgObjects = [];
|
|
3544
|
-
if (showSolderMask) {
|
|
3545
|
-
const layer = ctx.layer ?? "top";
|
|
3546
|
-
const maskLayer = layer === "bottom" ? "soldermask-bottom" : "soldermask-top";
|
|
3547
|
-
svgObjects.push({
|
|
3548
|
-
name: "path",
|
|
3549
|
-
type: "element",
|
|
3550
|
-
value: "",
|
|
3551
|
-
children: [],
|
|
3552
|
-
attributes: {
|
|
3553
|
-
class: "pcb-board-soldermask",
|
|
3554
|
-
d: path,
|
|
3555
|
-
fill: colorMap2.soldermask.top,
|
|
3556
|
-
"fill-opacity": "0.8",
|
|
3557
|
-
stroke: "none",
|
|
3558
|
-
"data-type": "pcb_soldermask",
|
|
3559
|
-
"data-pcb-layer": maskLayer
|
|
3560
|
-
}
|
|
3561
|
-
});
|
|
3562
|
-
}
|
|
3563
|
-
svgObjects.push({
|
|
3564
|
-
name: "path",
|
|
3565
|
-
type: "element",
|
|
3566
|
-
value: "",
|
|
3567
|
-
children: [],
|
|
3568
|
-
attributes: {
|
|
3569
|
-
class: "pcb-board",
|
|
3570
|
-
d: path,
|
|
3571
|
-
fill: "none",
|
|
3572
|
-
stroke: colorMap2.boardOutline,
|
|
3573
|
-
"stroke-width": (0.1 * Math.abs(transform.a)).toString(),
|
|
3574
|
-
"data-type": "pcb_board",
|
|
3575
|
-
"data-pcb-layer": "board"
|
|
3576
|
-
}
|
|
3577
|
-
});
|
|
3578
|
-
return svgObjects;
|
|
3579
|
-
}
|
|
3770
|
+
import { applyToPoint as applyToPoint23 } from "transformation-matrix";
|
|
3580
3771
|
|
|
3581
|
-
// lib/
|
|
3772
|
+
// lib/utils/create-pcb-component-anchor-offset-indicators.ts
|
|
3582
3773
|
import { applyToPoint as applyToPoint22 } from "transformation-matrix";
|
|
3583
|
-
|
|
3584
|
-
|
|
3585
|
-
|
|
3586
|
-
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
|
|
3591
|
-
|
|
3592
|
-
|
|
3593
|
-
|
|
3594
|
-
|
|
3595
|
-
|
|
3596
|
-
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
|
|
3600
|
-
|
|
3774
|
+
var OFFSET_THRESHOLD_MM = 0.01;
|
|
3775
|
+
var TICK_SIZE_PX = 4;
|
|
3776
|
+
var LABEL_GAP_PX = 8;
|
|
3777
|
+
var LABEL_FONT_SIZE_PX = 11;
|
|
3778
|
+
var STROKE_WIDTH_PX = 1;
|
|
3779
|
+
var ANCHOR_MARKER_SIZE_PX = 5;
|
|
3780
|
+
var ANCHOR_MARKER_STROKE_WIDTH_PX = 1.5;
|
|
3781
|
+
var COMPONENT_GAP_PX = 15;
|
|
3782
|
+
var COMPONENT_SIDE_GAP_PX = 10;
|
|
3783
|
+
var DISTANCE_MULTIPLIER = 0.2;
|
|
3784
|
+
var MAX_OFFSET_PX = 50;
|
|
3785
|
+
function createAnchorOffsetIndicators(params) {
|
|
3786
|
+
const {
|
|
3787
|
+
groupAnchorPosition,
|
|
3788
|
+
componentPosition,
|
|
3789
|
+
transform,
|
|
3790
|
+
componentWidth = 0,
|
|
3791
|
+
componentHeight = 0
|
|
3792
|
+
} = params;
|
|
3793
|
+
const objects = [];
|
|
3794
|
+
const [screenGroupAnchorX, screenGroupAnchorY] = applyToPoint22(transform, [
|
|
3795
|
+
groupAnchorPosition.x,
|
|
3796
|
+
groupAnchorPosition.y
|
|
3601
3797
|
]);
|
|
3602
|
-
const
|
|
3603
|
-
|
|
3604
|
-
|
|
3798
|
+
const [screenComponentX, screenComponentY] = applyToPoint22(transform, [
|
|
3799
|
+
componentPosition.x,
|
|
3800
|
+
componentPosition.y
|
|
3605
3801
|
]);
|
|
3606
|
-
const
|
|
3607
|
-
const
|
|
3608
|
-
const
|
|
3609
|
-
|
|
3802
|
+
const offsetX = componentPosition.x - groupAnchorPosition.x;
|
|
3803
|
+
const offsetY = componentPosition.y - groupAnchorPosition.y;
|
|
3804
|
+
const scale10 = Math.abs(transform.a);
|
|
3805
|
+
const screenComponentWidth = componentWidth * scale10;
|
|
3806
|
+
const screenComponentHeight = componentHeight * scale10;
|
|
3807
|
+
objects.push(createAnchorMarker(screenGroupAnchorX, screenGroupAnchorY));
|
|
3808
|
+
objects.push({
|
|
3809
|
+
name: "line",
|
|
3810
|
+
type: "element",
|
|
3811
|
+
attributes: {
|
|
3812
|
+
x1: screenGroupAnchorX.toString(),
|
|
3813
|
+
y1: screenGroupAnchorY.toString(),
|
|
3814
|
+
x2: screenComponentX.toString(),
|
|
3815
|
+
y2: screenComponentY.toString(),
|
|
3816
|
+
stroke: "#ffffff",
|
|
3817
|
+
"stroke-width": "0.5",
|
|
3818
|
+
"stroke-dasharray": "3,3",
|
|
3819
|
+
opacity: "0.5",
|
|
3820
|
+
class: "anchor-offset-connector"
|
|
3821
|
+
},
|
|
3822
|
+
children: [],
|
|
3823
|
+
value: ""
|
|
3824
|
+
});
|
|
3825
|
+
objects.push({
|
|
3826
|
+
name: "circle",
|
|
3827
|
+
type: "element",
|
|
3828
|
+
attributes: {
|
|
3829
|
+
cx: screenComponentX.toString(),
|
|
3830
|
+
cy: screenComponentY.toString(),
|
|
3831
|
+
r: "2",
|
|
3832
|
+
fill: "#ffffff",
|
|
3833
|
+
opacity: "0.7",
|
|
3834
|
+
class: "anchor-offset-component-marker"
|
|
3835
|
+
},
|
|
3836
|
+
children: [],
|
|
3837
|
+
value: ""
|
|
3838
|
+
});
|
|
3839
|
+
const yDistance = Math.abs(screenComponentY - screenGroupAnchorY);
|
|
3840
|
+
const xDistance = Math.abs(screenComponentX - screenGroupAnchorX);
|
|
3841
|
+
const totalDistance = Math.sqrt(xDistance * xDistance + yDistance * yDistance);
|
|
3842
|
+
const componentHeightOffset = screenComponentHeight / 2 + COMPONENT_GAP_PX;
|
|
3843
|
+
const dynamicOffset = Math.max(
|
|
3844
|
+
componentHeightOffset,
|
|
3845
|
+
Math.min(MAX_OFFSET_PX, totalDistance * DISTANCE_MULTIPLIER)
|
|
3610
3846
|
);
|
|
3611
|
-
|
|
3612
|
-
|
|
3613
|
-
|
|
3614
|
-
|
|
3615
|
-
|
|
3616
|
-
|
|
3617
|
-
|
|
3618
|
-
|
|
3619
|
-
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
|
|
3847
|
+
const horizontalLineY = offsetY > 0 ? screenComponentY - dynamicOffset : screenComponentY + dynamicOffset;
|
|
3848
|
+
const componentWidthOffset = screenComponentWidth / 2 + COMPONENT_SIDE_GAP_PX;
|
|
3849
|
+
const verticalLineX = offsetX > 0 ? screenComponentX + componentWidthOffset : screenComponentX - componentWidthOffset;
|
|
3850
|
+
if (Math.abs(offsetX) > OFFSET_THRESHOLD_MM) {
|
|
3851
|
+
objects.push(
|
|
3852
|
+
...createHorizontalDimension({
|
|
3853
|
+
startX: screenGroupAnchorX,
|
|
3854
|
+
endX: screenComponentX,
|
|
3855
|
+
y: horizontalLineY,
|
|
3856
|
+
offsetMm: offsetX,
|
|
3857
|
+
offsetY
|
|
3858
|
+
})
|
|
3859
|
+
);
|
|
3860
|
+
}
|
|
3861
|
+
if (Math.abs(offsetY) > OFFSET_THRESHOLD_MM) {
|
|
3862
|
+
objects.push(
|
|
3863
|
+
...createVerticalDimension({
|
|
3864
|
+
x: verticalLineX,
|
|
3865
|
+
startY: screenGroupAnchorY,
|
|
3866
|
+
endY: screenComponentY,
|
|
3867
|
+
offsetMm: offsetY,
|
|
3868
|
+
offsetX
|
|
3869
|
+
})
|
|
3870
|
+
);
|
|
3871
|
+
}
|
|
3872
|
+
return objects;
|
|
3628
3873
|
}
|
|
3629
|
-
|
|
3630
|
-
// lib/pcb/svg-object-fns/create-svg-objects-from-pcb-via.ts
|
|
3631
|
-
import { applyToPoint as applyToPoint23 } from "transformation-matrix";
|
|
3632
|
-
function createSvgObjectsFromPcbVia(hole, ctx) {
|
|
3633
|
-
const { transform, colorMap: colorMap2 } = ctx;
|
|
3634
|
-
const [x, y] = applyToPoint23(transform, [hole.x, hole.y]);
|
|
3635
|
-
const scaledOuterWidth = hole.outer_diameter * Math.abs(transform.a);
|
|
3636
|
-
const scaledOuterHeight = hole.outer_diameter * Math.abs(transform.a);
|
|
3637
|
-
const scaledHoleWidth = hole.hole_diameter * Math.abs(transform.a);
|
|
3638
|
-
const scaledHoleHeight = hole.hole_diameter * Math.abs(transform.a);
|
|
3639
|
-
const outerRadius = Math.min(scaledOuterWidth, scaledOuterHeight) / 2;
|
|
3640
|
-
const innerRadius = Math.min(scaledHoleWidth, scaledHoleHeight) / 2;
|
|
3874
|
+
function createAnchorMarker(x, y) {
|
|
3641
3875
|
return {
|
|
3642
3876
|
name: "g",
|
|
3643
3877
|
type: "element",
|
|
3644
3878
|
attributes: {
|
|
3645
|
-
|
|
3646
|
-
"data-
|
|
3879
|
+
class: "anchor-offset-marker",
|
|
3880
|
+
"data-type": "anchor_offset_marker"
|
|
3647
3881
|
},
|
|
3648
3882
|
children: [
|
|
3649
3883
|
{
|
|
3650
|
-
name: "
|
|
3884
|
+
name: "line",
|
|
3651
3885
|
type: "element",
|
|
3652
3886
|
attributes: {
|
|
3653
|
-
|
|
3654
|
-
|
|
3655
|
-
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
"
|
|
3659
|
-
"
|
|
3660
|
-
}
|
|
3887
|
+
x1: x.toString(),
|
|
3888
|
+
y1: (y - ANCHOR_MARKER_SIZE_PX).toString(),
|
|
3889
|
+
x2: x.toString(),
|
|
3890
|
+
y2: (y + ANCHOR_MARKER_SIZE_PX).toString(),
|
|
3891
|
+
stroke: "#ffffff",
|
|
3892
|
+
"stroke-width": ANCHOR_MARKER_STROKE_WIDTH_PX.toString(),
|
|
3893
|
+
"stroke-linecap": "round"
|
|
3894
|
+
},
|
|
3895
|
+
children: [],
|
|
3896
|
+
value: ""
|
|
3661
3897
|
},
|
|
3662
3898
|
{
|
|
3663
|
-
name: "
|
|
3899
|
+
name: "line",
|
|
3664
3900
|
type: "element",
|
|
3665
3901
|
attributes: {
|
|
3666
|
-
|
|
3667
|
-
|
|
3668
|
-
|
|
3669
|
-
|
|
3670
|
-
|
|
3671
|
-
"
|
|
3672
|
-
"
|
|
3673
|
-
}
|
|
3902
|
+
x1: (x - ANCHOR_MARKER_SIZE_PX).toString(),
|
|
3903
|
+
y1: y.toString(),
|
|
3904
|
+
x2: (x + ANCHOR_MARKER_SIZE_PX).toString(),
|
|
3905
|
+
y2: y.toString(),
|
|
3906
|
+
stroke: "#ffffff",
|
|
3907
|
+
"stroke-width": ANCHOR_MARKER_STROKE_WIDTH_PX.toString(),
|
|
3908
|
+
"stroke-linecap": "round"
|
|
3909
|
+
},
|
|
3910
|
+
children: [],
|
|
3911
|
+
value: ""
|
|
3674
3912
|
}
|
|
3675
|
-
]
|
|
3913
|
+
],
|
|
3914
|
+
value: ""
|
|
3676
3915
|
};
|
|
3677
3916
|
}
|
|
3678
|
-
|
|
3679
|
-
|
|
3680
|
-
|
|
3681
|
-
|
|
3682
|
-
|
|
3683
|
-
|
|
3684
|
-
|
|
3685
|
-
const
|
|
3686
|
-
|
|
3687
|
-
|
|
3688
|
-
|
|
3689
|
-
|
|
3690
|
-
|
|
3691
|
-
|
|
3692
|
-
|
|
3693
|
-
|
|
3694
|
-
|
|
3917
|
+
function createHorizontalDimension({
|
|
3918
|
+
startX,
|
|
3919
|
+
endX,
|
|
3920
|
+
y,
|
|
3921
|
+
offsetMm,
|
|
3922
|
+
offsetY
|
|
3923
|
+
}) {
|
|
3924
|
+
const objects = [];
|
|
3925
|
+
objects.push({
|
|
3926
|
+
name: "line",
|
|
3927
|
+
type: "element",
|
|
3928
|
+
attributes: {
|
|
3929
|
+
x1: startX.toString(),
|
|
3930
|
+
y1: y.toString(),
|
|
3931
|
+
x2: endX.toString(),
|
|
3932
|
+
y2: y.toString(),
|
|
3933
|
+
stroke: "#ffffff",
|
|
3934
|
+
"stroke-width": STROKE_WIDTH_PX.toString(),
|
|
3935
|
+
class: "anchor-offset-dimension-x"
|
|
3936
|
+
},
|
|
3937
|
+
children: [],
|
|
3938
|
+
value: ""
|
|
3939
|
+
});
|
|
3940
|
+
objects.push({
|
|
3941
|
+
name: "line",
|
|
3942
|
+
type: "element",
|
|
3943
|
+
attributes: {
|
|
3944
|
+
x1: startX.toString(),
|
|
3945
|
+
y1: (y - TICK_SIZE_PX).toString(),
|
|
3946
|
+
x2: startX.toString(),
|
|
3947
|
+
y2: (y + TICK_SIZE_PX).toString(),
|
|
3948
|
+
stroke: "#ffffff",
|
|
3949
|
+
"stroke-width": STROKE_WIDTH_PX.toString()
|
|
3950
|
+
},
|
|
3951
|
+
children: [],
|
|
3952
|
+
value: ""
|
|
3953
|
+
});
|
|
3954
|
+
objects.push({
|
|
3955
|
+
name: "line",
|
|
3956
|
+
type: "element",
|
|
3957
|
+
attributes: {
|
|
3958
|
+
x1: endX.toString(),
|
|
3959
|
+
y1: (y - TICK_SIZE_PX).toString(),
|
|
3960
|
+
x2: endX.toString(),
|
|
3961
|
+
y2: (y + TICK_SIZE_PX).toString(),
|
|
3962
|
+
stroke: "#ffffff",
|
|
3963
|
+
"stroke-width": STROKE_WIDTH_PX.toString()
|
|
3964
|
+
},
|
|
3965
|
+
children: [],
|
|
3966
|
+
value: ""
|
|
3967
|
+
});
|
|
3968
|
+
const midX = (startX + endX) / 2;
|
|
3969
|
+
const labelY = offsetY > 0 ? y - TICK_SIZE_PX - LABEL_GAP_PX : y + TICK_SIZE_PX + LABEL_GAP_PX;
|
|
3970
|
+
objects.push({
|
|
3971
|
+
name: "text",
|
|
3972
|
+
type: "element",
|
|
3973
|
+
attributes: {
|
|
3974
|
+
x: midX.toString(),
|
|
3975
|
+
y: labelY.toString(),
|
|
3976
|
+
fill: "#ffffff",
|
|
3977
|
+
"font-size": LABEL_FONT_SIZE_PX.toString(),
|
|
3978
|
+
"font-family": "Arial, sans-serif",
|
|
3979
|
+
"text-anchor": "middle",
|
|
3980
|
+
"dominant-baseline": offsetY > 0 ? "baseline" : "hanging",
|
|
3981
|
+
class: "anchor-offset-label"
|
|
3982
|
+
},
|
|
3983
|
+
children: [
|
|
3984
|
+
{
|
|
3985
|
+
type: "text",
|
|
3986
|
+
value: `X: ${offsetMm.toFixed(2)}mm`,
|
|
3987
|
+
name: "",
|
|
3988
|
+
attributes: {},
|
|
3989
|
+
children: []
|
|
3990
|
+
}
|
|
3991
|
+
],
|
|
3992
|
+
value: ""
|
|
3993
|
+
});
|
|
3994
|
+
return objects;
|
|
3995
|
+
}
|
|
3996
|
+
function createVerticalDimension({
|
|
3997
|
+
x,
|
|
3998
|
+
startY,
|
|
3999
|
+
endY,
|
|
4000
|
+
offsetMm,
|
|
4001
|
+
offsetX
|
|
4002
|
+
}) {
|
|
4003
|
+
const objects = [];
|
|
4004
|
+
objects.push({
|
|
4005
|
+
name: "line",
|
|
4006
|
+
type: "element",
|
|
4007
|
+
attributes: {
|
|
4008
|
+
x1: x.toString(),
|
|
4009
|
+
y1: startY.toString(),
|
|
4010
|
+
x2: x.toString(),
|
|
4011
|
+
y2: endY.toString(),
|
|
4012
|
+
stroke: "#ffffff",
|
|
4013
|
+
"stroke-width": STROKE_WIDTH_PX.toString(),
|
|
4014
|
+
class: "anchor-offset-dimension-y"
|
|
4015
|
+
},
|
|
4016
|
+
children: [],
|
|
4017
|
+
value: ""
|
|
4018
|
+
});
|
|
4019
|
+
objects.push({
|
|
4020
|
+
name: "line",
|
|
4021
|
+
type: "element",
|
|
4022
|
+
attributes: {
|
|
4023
|
+
x1: (x - TICK_SIZE_PX).toString(),
|
|
4024
|
+
y1: startY.toString(),
|
|
4025
|
+
x2: (x + TICK_SIZE_PX).toString(),
|
|
4026
|
+
y2: startY.toString(),
|
|
4027
|
+
stroke: "#ffffff",
|
|
4028
|
+
"stroke-width": STROKE_WIDTH_PX.toString()
|
|
4029
|
+
},
|
|
4030
|
+
children: [],
|
|
4031
|
+
value: ""
|
|
4032
|
+
});
|
|
4033
|
+
objects.push({
|
|
4034
|
+
name: "line",
|
|
4035
|
+
type: "element",
|
|
4036
|
+
attributes: {
|
|
4037
|
+
x1: (x - TICK_SIZE_PX).toString(),
|
|
4038
|
+
y1: endY.toString(),
|
|
4039
|
+
x2: (x + TICK_SIZE_PX).toString(),
|
|
4040
|
+
y2: endY.toString(),
|
|
4041
|
+
stroke: "#ffffff",
|
|
4042
|
+
"stroke-width": STROKE_WIDTH_PX.toString()
|
|
4043
|
+
},
|
|
4044
|
+
children: [],
|
|
4045
|
+
value: ""
|
|
4046
|
+
});
|
|
4047
|
+
const midY = (startY + endY) / 2;
|
|
4048
|
+
const labelX = offsetX < 0 ? x - TICK_SIZE_PX - 4 : x + TICK_SIZE_PX + 4;
|
|
4049
|
+
objects.push({
|
|
4050
|
+
name: "text",
|
|
4051
|
+
type: "element",
|
|
4052
|
+
attributes: {
|
|
4053
|
+
x: labelX.toString(),
|
|
4054
|
+
y: midY.toString(),
|
|
4055
|
+
fill: "#ffffff",
|
|
4056
|
+
"font-size": LABEL_FONT_SIZE_PX.toString(),
|
|
4057
|
+
"font-family": "Arial, sans-serif",
|
|
4058
|
+
"text-anchor": offsetX < 0 ? "end" : "start",
|
|
4059
|
+
"dominant-baseline": "middle",
|
|
4060
|
+
class: "anchor-offset-label"
|
|
4061
|
+
},
|
|
4062
|
+
children: [
|
|
4063
|
+
{
|
|
4064
|
+
type: "text",
|
|
4065
|
+
value: `Y: ${offsetMm.toFixed(2)}mm`,
|
|
4066
|
+
name: "",
|
|
4067
|
+
attributes: {},
|
|
4068
|
+
children: []
|
|
4069
|
+
}
|
|
4070
|
+
],
|
|
4071
|
+
value: ""
|
|
4072
|
+
});
|
|
4073
|
+
return objects;
|
|
4074
|
+
}
|
|
4075
|
+
|
|
4076
|
+
// lib/pcb/svg-object-fns/create-svg-objects-from-pcb-board.ts
|
|
4077
|
+
function createSvgObjectsFromPcbBoard(pcbBoard, ctx) {
|
|
4078
|
+
const { transform, colorMap: colorMap2, showSolderMask, circuitJson } = ctx;
|
|
4079
|
+
const { width, height, center, outline } = pcbBoard;
|
|
4080
|
+
let path;
|
|
4081
|
+
if (outline && Array.isArray(outline) && outline.length >= 3) {
|
|
4082
|
+
path = outline.map((point, index) => {
|
|
4083
|
+
const [x, y] = applyToPoint23(transform, [point.x, point.y]);
|
|
4084
|
+
return index === 0 ? `M ${x} ${y}` : `L ${x} ${y}`;
|
|
4085
|
+
}).join(" ");
|
|
4086
|
+
} else {
|
|
4087
|
+
const halfWidth = width / 2;
|
|
4088
|
+
const halfHeight = height / 2;
|
|
4089
|
+
const topLeft = applyToPoint23(transform, [
|
|
4090
|
+
center.x - halfWidth,
|
|
4091
|
+
center.y - halfHeight
|
|
4092
|
+
]);
|
|
4093
|
+
const topRight = applyToPoint23(transform, [
|
|
4094
|
+
center.x + halfWidth,
|
|
4095
|
+
center.y - halfHeight
|
|
4096
|
+
]);
|
|
4097
|
+
const bottomRight = applyToPoint23(transform, [
|
|
4098
|
+
center.x + halfWidth,
|
|
4099
|
+
center.y + halfHeight
|
|
4100
|
+
]);
|
|
4101
|
+
const bottomLeft = applyToPoint23(transform, [
|
|
4102
|
+
center.x - halfWidth,
|
|
4103
|
+
center.y + halfHeight
|
|
4104
|
+
]);
|
|
4105
|
+
path = `M ${topLeft[0]} ${topLeft[1]} L ${topRight[0]} ${topRight[1]} L ${bottomRight[0]} ${bottomRight[1]} L ${bottomLeft[0]} ${bottomLeft[1]}`;
|
|
4106
|
+
}
|
|
4107
|
+
path += " Z";
|
|
4108
|
+
const svgObjects = [];
|
|
4109
|
+
if (showSolderMask) {
|
|
4110
|
+
const layer = ctx.layer ?? "top";
|
|
4111
|
+
const maskLayer = layer === "bottom" ? "soldermask-bottom" : "soldermask-top";
|
|
4112
|
+
svgObjects.push({
|
|
4113
|
+
name: "path",
|
|
4114
|
+
type: "element",
|
|
4115
|
+
value: "",
|
|
4116
|
+
children: [],
|
|
4117
|
+
attributes: {
|
|
4118
|
+
class: "pcb-board-soldermask",
|
|
4119
|
+
d: path,
|
|
4120
|
+
fill: colorMap2.soldermask.top,
|
|
4121
|
+
"fill-opacity": "0.8",
|
|
4122
|
+
stroke: "none",
|
|
4123
|
+
"data-type": "pcb_soldermask",
|
|
4124
|
+
"data-pcb-layer": maskLayer
|
|
4125
|
+
}
|
|
4126
|
+
});
|
|
4127
|
+
}
|
|
4128
|
+
svgObjects.push({
|
|
4129
|
+
name: "path",
|
|
4130
|
+
type: "element",
|
|
4131
|
+
value: "",
|
|
4132
|
+
children: [],
|
|
4133
|
+
attributes: {
|
|
4134
|
+
class: "pcb-board",
|
|
4135
|
+
d: path,
|
|
4136
|
+
fill: "none",
|
|
4137
|
+
stroke: colorMap2.boardOutline,
|
|
4138
|
+
"stroke-width": (0.1 * Math.abs(transform.a)).toString(),
|
|
4139
|
+
"data-type": "pcb_board",
|
|
4140
|
+
"data-pcb-layer": "board"
|
|
4141
|
+
}
|
|
4142
|
+
});
|
|
4143
|
+
if (ctx.showAnchorOffsets && circuitJson) {
|
|
4144
|
+
const panel = circuitJson.find(
|
|
4145
|
+
(elm) => elm.type === "pcb_panel"
|
|
4146
|
+
);
|
|
4147
|
+
if (panel) {
|
|
4148
|
+
const panelCenter = panel.center ?? { x: 0, y: 0 };
|
|
4149
|
+
svgObjects.push(
|
|
4150
|
+
...createAnchorOffsetIndicators({
|
|
4151
|
+
groupAnchorPosition: panelCenter,
|
|
4152
|
+
componentPosition: center,
|
|
4153
|
+
transform,
|
|
4154
|
+
componentWidth: width,
|
|
4155
|
+
componentHeight: height
|
|
4156
|
+
})
|
|
4157
|
+
);
|
|
4158
|
+
}
|
|
4159
|
+
}
|
|
4160
|
+
return svgObjects;
|
|
4161
|
+
}
|
|
4162
|
+
|
|
4163
|
+
// lib/pcb/svg-object-fns/create-svg-objects-from-pcb-panel.ts
|
|
4164
|
+
import { applyToPoint as applyToPoint24 } from "transformation-matrix";
|
|
4165
|
+
function createSvgObjectsFromPcbPanel(pcbPanel, ctx) {
|
|
4166
|
+
const { transform, colorMap: colorMap2, showSolderMask } = ctx;
|
|
4167
|
+
const width = Number(pcbPanel.width);
|
|
4168
|
+
const height = Number(pcbPanel.height);
|
|
4169
|
+
const center = pcbPanel.center ?? { x: width / 2, y: height / 2 };
|
|
4170
|
+
const halfWidth = width / 2;
|
|
4171
|
+
const halfHeight = height / 2;
|
|
4172
|
+
const topLeft = applyToPoint24(transform, [
|
|
4173
|
+
center.x - halfWidth,
|
|
4174
|
+
center.y - halfHeight
|
|
4175
|
+
]);
|
|
4176
|
+
const topRight = applyToPoint24(transform, [
|
|
4177
|
+
center.x + halfWidth,
|
|
4178
|
+
center.y - halfHeight
|
|
4179
|
+
]);
|
|
4180
|
+
const bottomRight = applyToPoint24(transform, [
|
|
4181
|
+
center.x + halfWidth,
|
|
4182
|
+
center.y + halfHeight
|
|
4183
|
+
]);
|
|
4184
|
+
const bottomLeft = applyToPoint24(transform, [
|
|
4185
|
+
center.x - halfWidth,
|
|
4186
|
+
center.y + halfHeight
|
|
4187
|
+
]);
|
|
4188
|
+
const path = `M ${topLeft[0]} ${topLeft[1]} L ${topRight[0]} ${topRight[1]} L ${bottomRight[0]} ${bottomRight[1]} L ${bottomLeft[0]} ${bottomLeft[1]} Z`;
|
|
4189
|
+
const isCoveredWithSolderMask = pcbPanel.covered_with_solder_mask !== false;
|
|
4190
|
+
const shouldShowSolderMask = Boolean(
|
|
4191
|
+
showSolderMask && isCoveredWithSolderMask
|
|
4192
|
+
);
|
|
4193
|
+
return [
|
|
4194
|
+
{
|
|
4195
|
+
name: "path",
|
|
4196
|
+
type: "element",
|
|
4197
|
+
value: "",
|
|
4198
|
+
children: [],
|
|
4199
|
+
attributes: {
|
|
4200
|
+
class: "pcb-panel",
|
|
4201
|
+
d: path,
|
|
4202
|
+
fill: "none",
|
|
4203
|
+
stroke: colorMap2.boardOutline,
|
|
4204
|
+
"stroke-width": (0.1 * Math.abs(transform.a)).toString(),
|
|
4205
|
+
"data-type": "pcb_panel",
|
|
4206
|
+
"data-pcb-layer": "board"
|
|
4207
|
+
}
|
|
4208
|
+
}
|
|
4209
|
+
];
|
|
4210
|
+
}
|
|
4211
|
+
|
|
4212
|
+
// lib/pcb/svg-object-fns/create-svg-objects-from-pcb-via.ts
|
|
4213
|
+
import { applyToPoint as applyToPoint25 } from "transformation-matrix";
|
|
4214
|
+
function createSvgObjectsFromPcbVia(hole, ctx) {
|
|
4215
|
+
const { transform, colorMap: colorMap2 } = ctx;
|
|
4216
|
+
const [x, y] = applyToPoint25(transform, [hole.x, hole.y]);
|
|
4217
|
+
const scaledOuterWidth = hole.outer_diameter * Math.abs(transform.a);
|
|
4218
|
+
const scaledOuterHeight = hole.outer_diameter * Math.abs(transform.a);
|
|
4219
|
+
const scaledHoleWidth = hole.hole_diameter * Math.abs(transform.a);
|
|
4220
|
+
const scaledHoleHeight = hole.hole_diameter * Math.abs(transform.a);
|
|
4221
|
+
const outerRadius = Math.min(scaledOuterWidth, scaledOuterHeight) / 2;
|
|
4222
|
+
const innerRadius = Math.min(scaledHoleWidth, scaledHoleHeight) / 2;
|
|
4223
|
+
return {
|
|
4224
|
+
name: "g",
|
|
4225
|
+
type: "element",
|
|
4226
|
+
attributes: {
|
|
4227
|
+
"data-type": "pcb_via",
|
|
4228
|
+
"data-pcb-layer": "through"
|
|
4229
|
+
},
|
|
4230
|
+
children: [
|
|
4231
|
+
{
|
|
4232
|
+
name: "circle",
|
|
4233
|
+
type: "element",
|
|
4234
|
+
attributes: {
|
|
4235
|
+
class: "pcb-hole-outer",
|
|
4236
|
+
fill: colorMap2.copper.top,
|
|
4237
|
+
cx: x.toString(),
|
|
4238
|
+
cy: y.toString(),
|
|
4239
|
+
r: outerRadius.toString(),
|
|
4240
|
+
"data-type": "pcb_via",
|
|
4241
|
+
"data-pcb-layer": "top"
|
|
4242
|
+
}
|
|
4243
|
+
},
|
|
4244
|
+
{
|
|
4245
|
+
name: "circle",
|
|
4246
|
+
type: "element",
|
|
4247
|
+
attributes: {
|
|
4248
|
+
class: "pcb-hole-inner",
|
|
4249
|
+
fill: colorMap2.drill,
|
|
4250
|
+
cx: x.toString(),
|
|
4251
|
+
cy: y.toString(),
|
|
4252
|
+
r: innerRadius.toString(),
|
|
4253
|
+
"data-type": "pcb_via",
|
|
4254
|
+
"data-pcb-layer": "drill"
|
|
4255
|
+
}
|
|
4256
|
+
}
|
|
4257
|
+
]
|
|
4258
|
+
};
|
|
4259
|
+
}
|
|
4260
|
+
|
|
4261
|
+
// lib/pcb/svg-object-fns/create-svg-objects-from-pcb-hole.ts
|
|
4262
|
+
import { applyToPoint as applyToPoint26 } from "transformation-matrix";
|
|
4263
|
+
function createSvgObjectsFromPcbHole(hole, ctx) {
|
|
4264
|
+
const { transform, colorMap: colorMap2, showSolderMask } = ctx;
|
|
4265
|
+
const layer = ctx.layer ?? "top";
|
|
4266
|
+
const [x, y] = applyToPoint26(transform, [hole.x, hole.y]);
|
|
4267
|
+
const isCoveredWithSolderMask = Boolean(hole.is_covered_with_solder_mask);
|
|
4268
|
+
const soldermaskMargin = (hole.soldermask_margin ?? 0) * Math.abs(transform.a);
|
|
4269
|
+
const shouldShowSolderMask = showSolderMask && isCoveredWithSolderMask && soldermaskMargin !== 0;
|
|
4270
|
+
const solderMaskColor = colorMap2.soldermask.top;
|
|
4271
|
+
if (hole.hole_shape === "circle" || hole.hole_shape === "square") {
|
|
4272
|
+
const scaledDiameter = hole.hole_diameter * Math.abs(transform.a);
|
|
4273
|
+
const radius = scaledDiameter / 2;
|
|
4274
|
+
if (hole.hole_shape === "circle") {
|
|
4275
|
+
const holeElement2 = {
|
|
4276
|
+
name: "circle",
|
|
3695
4277
|
type: "element",
|
|
3696
4278
|
attributes: {
|
|
3697
4279
|
class: "pcb-hole",
|
|
@@ -4178,7 +4760,7 @@ import {
|
|
|
4178
4760
|
getFullConnectivityMapFromCircuitJson
|
|
4179
4761
|
} from "circuit-json-to-connectivity-map";
|
|
4180
4762
|
import "svgson";
|
|
4181
|
-
import { applyToPoint as
|
|
4763
|
+
import { applyToPoint as applyToPoint27 } from "transformation-matrix";
|
|
4182
4764
|
|
|
4183
4765
|
// lib/pcb/create-svg-objects-from-pcb-rats-nest/get-element-position.ts
|
|
4184
4766
|
import { su } from "@tscircuit/circuit-json-util";
|
|
@@ -4205,9 +4787,9 @@ var findNearestPointInNet = (sourcePoint, netId, connectivity, circuitJson) => {
|
|
|
4205
4787
|
if (pos) {
|
|
4206
4788
|
const dx = sourcePoint.x - pos.x;
|
|
4207
4789
|
const dy = sourcePoint.y - pos.y;
|
|
4208
|
-
const
|
|
4209
|
-
if (
|
|
4210
|
-
minDistance =
|
|
4790
|
+
const distance4 = Math.sqrt(dx * dx + dy * dy);
|
|
4791
|
+
if (distance4 > 0 && distance4 < minDistance) {
|
|
4792
|
+
minDistance = distance4;
|
|
4211
4793
|
nearestPoint = pos;
|
|
4212
4794
|
}
|
|
4213
4795
|
}
|
|
@@ -4258,11 +4840,11 @@ function createSvgObjectsForRatsNest(circuitJson, ctx) {
|
|
|
4258
4840
|
});
|
|
4259
4841
|
const svgObjects = [];
|
|
4260
4842
|
for (const line of ratsNestLines) {
|
|
4261
|
-
const transformedStart =
|
|
4843
|
+
const transformedStart = applyToPoint27(transform, [
|
|
4262
4844
|
line.startPoint.x,
|
|
4263
4845
|
line.startPoint.y
|
|
4264
4846
|
]);
|
|
4265
|
-
const transformedEnd =
|
|
4847
|
+
const transformedEnd = applyToPoint27(transform, [
|
|
4266
4848
|
line.endPoint.x,
|
|
4267
4849
|
line.endPoint.y
|
|
4268
4850
|
]);
|
|
@@ -4290,17 +4872,17 @@ function createSvgObjectsForRatsNest(circuitJson, ctx) {
|
|
|
4290
4872
|
|
|
4291
4873
|
// lib/pcb/svg-object-fns/create-svg-objects-from-pcb-cutout.ts
|
|
4292
4874
|
import {
|
|
4293
|
-
applyToPoint as
|
|
4294
|
-
compose as
|
|
4295
|
-
rotate as
|
|
4296
|
-
translate as
|
|
4297
|
-
toString as
|
|
4875
|
+
applyToPoint as applyToPoint28,
|
|
4876
|
+
compose as compose4,
|
|
4877
|
+
rotate as rotate4,
|
|
4878
|
+
translate as translate4,
|
|
4879
|
+
toString as matrixToString7
|
|
4298
4880
|
} from "transformation-matrix";
|
|
4299
4881
|
function createSvgObjectsFromPcbCutout(cutout, ctx) {
|
|
4300
4882
|
const { transform, colorMap: colorMap2 } = ctx;
|
|
4301
4883
|
if (cutout.shape === "rect") {
|
|
4302
4884
|
const rectCutout = cutout;
|
|
4303
|
-
const [cx, cy] =
|
|
4885
|
+
const [cx, cy] = applyToPoint28(transform, [
|
|
4304
4886
|
rectCutout.center.x,
|
|
4305
4887
|
rectCutout.center.y
|
|
4306
4888
|
]);
|
|
@@ -4318,8 +4900,8 @@ function createSvgObjectsFromPcbCutout(cutout, ctx) {
|
|
|
4318
4900
|
width: scaledWidth.toString(),
|
|
4319
4901
|
height: scaledHeight.toString(),
|
|
4320
4902
|
fill: colorMap2.drill,
|
|
4321
|
-
transform:
|
|
4322
|
-
|
|
4903
|
+
transform: matrixToString7(
|
|
4904
|
+
compose4(translate4(cx, cy), rotate4(svgRotation * Math.PI / 180))
|
|
4323
4905
|
),
|
|
4324
4906
|
"data-type": "pcb_cutout",
|
|
4325
4907
|
"data-pcb-layer": "drill"
|
|
@@ -4342,7 +4924,7 @@ function createSvgObjectsFromPcbCutout(cutout, ctx) {
|
|
|
4342
4924
|
}
|
|
4343
4925
|
if (cutout.shape === "circle") {
|
|
4344
4926
|
const circleCutout = cutout;
|
|
4345
|
-
const [cx, cy] =
|
|
4927
|
+
const [cx, cy] = applyToPoint28(transform, [
|
|
4346
4928
|
circleCutout.center.x,
|
|
4347
4929
|
circleCutout.center.y
|
|
4348
4930
|
]);
|
|
@@ -4369,7 +4951,7 @@ function createSvgObjectsFromPcbCutout(cutout, ctx) {
|
|
|
4369
4951
|
const polygonCutout = cutout;
|
|
4370
4952
|
if (!polygonCutout.points || polygonCutout.points.length === 0) return [];
|
|
4371
4953
|
const transformedPoints = polygonCutout.points.map(
|
|
4372
|
-
(p) =>
|
|
4954
|
+
(p) => applyToPoint28(transform, [p.x, p.y])
|
|
4373
4955
|
);
|
|
4374
4956
|
const pointsString = transformedPoints.map((p) => `${p[0]},${p[1]}`).join(" ");
|
|
4375
4957
|
return [
|
|
@@ -4393,19 +4975,19 @@ function createSvgObjectsFromPcbCutout(cutout, ctx) {
|
|
|
4393
4975
|
|
|
4394
4976
|
// lib/pcb/svg-object-fns/create-svg-objects-from-pcb-copper-pour.ts
|
|
4395
4977
|
import {
|
|
4396
|
-
applyToPoint as
|
|
4397
|
-
compose as
|
|
4398
|
-
rotate as
|
|
4399
|
-
toString as
|
|
4400
|
-
translate as
|
|
4978
|
+
applyToPoint as applyToPoint30,
|
|
4979
|
+
compose as compose5,
|
|
4980
|
+
rotate as rotate5,
|
|
4981
|
+
toString as matrixToString8,
|
|
4982
|
+
translate as translate5
|
|
4401
4983
|
} from "transformation-matrix";
|
|
4402
4984
|
|
|
4403
4985
|
// lib/utils/ring-to-path-d.ts
|
|
4404
|
-
import { applyToPoint as
|
|
4986
|
+
import { applyToPoint as applyToPoint29 } from "transformation-matrix";
|
|
4405
4987
|
function ringToPathD(vertices, transform) {
|
|
4406
4988
|
if (vertices.length === 0) return "";
|
|
4407
4989
|
const transformedVertices = vertices.map((v) => {
|
|
4408
|
-
const [x, y] =
|
|
4990
|
+
const [x, y] = applyToPoint29(transform, [v.x, v.y]);
|
|
4409
4991
|
return { ...v, x, y };
|
|
4410
4992
|
});
|
|
4411
4993
|
let d = `M ${transformedVertices[0].x} ${transformedVertices[0].y}`;
|
|
@@ -4494,7 +5076,7 @@ function createSvgObjectsFromPcbCopperPour(pour, ctx) {
|
|
|
4494
5076
|
const maskOverlayColor = layer === "bottom" ? colorMap2.soldermaskOverCopper.bottom : colorMap2.soldermaskOverCopper.top;
|
|
4495
5077
|
const maskOverlayOpacity = "0.9";
|
|
4496
5078
|
if (pour.shape === "rect") {
|
|
4497
|
-
const [cx, cy] =
|
|
5079
|
+
const [cx, cy] = applyToPoint30(transform, [pour.center.x, pour.center.y]);
|
|
4498
5080
|
const scaledWidth = pour.width * Math.abs(transform.a);
|
|
4499
5081
|
const scaledHeight = pour.height * Math.abs(transform.d);
|
|
4500
5082
|
const svgRotation = -(pour.rotation ?? 0);
|
|
@@ -4503,8 +5085,8 @@ function createSvgObjectsFromPcbCopperPour(pour, ctx) {
|
|
|
4503
5085
|
y: (-scaledHeight / 2).toString(),
|
|
4504
5086
|
width: scaledWidth.toString(),
|
|
4505
5087
|
height: scaledHeight.toString(),
|
|
4506
|
-
transform:
|
|
4507
|
-
|
|
5088
|
+
transform: matrixToString8(
|
|
5089
|
+
compose5(translate5(cx, cy), rotate5(svgRotation * Math.PI / 180))
|
|
4508
5090
|
)
|
|
4509
5091
|
};
|
|
4510
5092
|
const copperRect = {
|
|
@@ -4546,7 +5128,7 @@ function createSvgObjectsFromPcbCopperPour(pour, ctx) {
|
|
|
4546
5128
|
if (pour.shape === "polygon") {
|
|
4547
5129
|
if (!pour.points || pour.points.length === 0) return [];
|
|
4548
5130
|
const transformedPoints = pour.points.map(
|
|
4549
|
-
(p) =>
|
|
5131
|
+
(p) => applyToPoint30(transform, [p.x, p.y])
|
|
4550
5132
|
);
|
|
4551
5133
|
const pointsString = transformedPoints.map((p) => `${p[0]},${p[1]}`).join(" ");
|
|
4552
5134
|
const copperPolygon = {
|
|
@@ -4632,454 +5214,148 @@ function createSvgObjectsFromPcbCopperPour(pour, ctx) {
|
|
|
4632
5214
|
}
|
|
4633
5215
|
|
|
4634
5216
|
// lib/pcb/svg-object-fns/create-svg-objects-for-pcb-grid.ts
|
|
4635
|
-
import "svgson";
|
|
4636
|
-
var DEFAULT_GRID_LINE_COLOR = "rgba(255, 255, 255, 0.5)";
|
|
4637
|
-
var GRID_PATTERN_ID = "pcb-grid-pattern";
|
|
4638
|
-
function createSvgObjectsForPcbGrid({
|
|
4639
|
-
grid,
|
|
4640
|
-
svgWidth,
|
|
4641
|
-
svgHeight
|
|
4642
|
-
}) {
|
|
4643
|
-
if (!grid) {
|
|
4644
|
-
return {};
|
|
4645
|
-
}
|
|
4646
|
-
const gridLineColor = grid.lineColor ?? DEFAULT_GRID_LINE_COLOR;
|
|
4647
|
-
const gridCellSize = grid.cellSize;
|
|
4648
|
-
const majorCellSize = grid.majorCellSize;
|
|
4649
|
-
const majorLineColor = grid.majorLineColor ?? gridLineColor;
|
|
4650
|
-
if (majorCellSize !== void 0) {
|
|
4651
|
-
if (!gridCellSize || gridCellSize <= 0) {
|
|
4652
|
-
throw new Error("grid.majorCellSize requires a positive grid.cellSize");
|
|
4653
|
-
}
|
|
4654
|
-
if (majorCellSize <= 0) {
|
|
4655
|
-
throw new Error(
|
|
4656
|
-
"grid.majorCellSize must be a positive multiple of grid.cellSize"
|
|
4657
|
-
);
|
|
4658
|
-
}
|
|
4659
|
-
const ratio = majorCellSize / gridCellSize;
|
|
4660
|
-
const nearestInteger = Math.round(ratio);
|
|
4661
|
-
if (!Number.isFinite(ratio) || Math.abs(ratio - nearestInteger) > 1e-6) {
|
|
4662
|
-
throw new Error(
|
|
4663
|
-
"grid.majorCellSize must be a positive multiple of grid.cellSize"
|
|
4664
|
-
);
|
|
4665
|
-
}
|
|
4666
|
-
}
|
|
4667
|
-
if (!gridCellSize || gridCellSize <= 0) {
|
|
4668
|
-
return {};
|
|
4669
|
-
}
|
|
4670
|
-
const hasMajorGrid = majorCellSize !== void 0;
|
|
4671
|
-
const patternChildren = hasMajorGrid ? createMajorGridPatternChildren(
|
|
4672
|
-
gridCellSize,
|
|
4673
|
-
majorCellSize,
|
|
4674
|
-
gridLineColor,
|
|
4675
|
-
majorLineColor
|
|
4676
|
-
) : [
|
|
4677
|
-
{
|
|
4678
|
-
name: "path",
|
|
4679
|
-
type: "element",
|
|
4680
|
-
value: "",
|
|
4681
|
-
attributes: {
|
|
4682
|
-
d: `M ${gridCellSize} 0 L 0 0 0 ${gridCellSize}`,
|
|
4683
|
-
fill: "none",
|
|
4684
|
-
stroke: gridLineColor,
|
|
4685
|
-
"stroke-width": "1",
|
|
4686
|
-
"shape-rendering": "crispEdges"
|
|
4687
|
-
},
|
|
4688
|
-
children: []
|
|
4689
|
-
}
|
|
4690
|
-
];
|
|
4691
|
-
const defs = {
|
|
4692
|
-
name: "defs",
|
|
4693
|
-
type: "element",
|
|
4694
|
-
value: "",
|
|
4695
|
-
attributes: {},
|
|
4696
|
-
children: [
|
|
4697
|
-
{
|
|
4698
|
-
name: "pattern",
|
|
4699
|
-
type: "element",
|
|
4700
|
-
value: "",
|
|
4701
|
-
attributes: {
|
|
4702
|
-
id: GRID_PATTERN_ID,
|
|
4703
|
-
width: hasMajorGrid ? majorCellSize.toString() : gridCellSize.toString(),
|
|
4704
|
-
height: hasMajorGrid ? majorCellSize.toString() : gridCellSize.toString(),
|
|
4705
|
-
patternUnits: "userSpaceOnUse"
|
|
4706
|
-
},
|
|
4707
|
-
children: patternChildren
|
|
4708
|
-
}
|
|
4709
|
-
]
|
|
4710
|
-
};
|
|
4711
|
-
const rect = {
|
|
4712
|
-
name: "rect",
|
|
4713
|
-
type: "element",
|
|
4714
|
-
value: "",
|
|
4715
|
-
attributes: {
|
|
4716
|
-
x: "0",
|
|
4717
|
-
y: "0",
|
|
4718
|
-
width: svgWidth.toString(),
|
|
4719
|
-
height: svgHeight.toString(),
|
|
4720
|
-
fill: `url(#${GRID_PATTERN_ID})`,
|
|
4721
|
-
"pointer-events": "none",
|
|
4722
|
-
"data-type": "pcb_grid",
|
|
4723
|
-
"data-pcb-layer": "global"
|
|
4724
|
-
},
|
|
4725
|
-
children: []
|
|
4726
|
-
};
|
|
4727
|
-
return { defs, rect };
|
|
4728
|
-
}
|
|
4729
|
-
function createMajorGridPatternChildren(cellSize, majorCellSize, lineColor, majorLineColor) {
|
|
4730
|
-
const children = [];
|
|
4731
|
-
const steps = Math.round(majorCellSize / cellSize);
|
|
4732
|
-
for (let step = 0; step < steps; step += 1) {
|
|
4733
|
-
const offset = Number((step * cellSize).toFixed(6));
|
|
4734
|
-
const offsetString = offset.toString();
|
|
4735
|
-
const color = step === 0 ? majorLineColor : lineColor;
|
|
4736
|
-
const majorSizeString = majorCellSize.toString();
|
|
4737
|
-
children.push({
|
|
4738
|
-
name: "line",
|
|
4739
|
-
type: "element",
|
|
4740
|
-
value: "",
|
|
4741
|
-
attributes: {
|
|
4742
|
-
x1: offsetString,
|
|
4743
|
-
y1: "0",
|
|
4744
|
-
x2: offsetString,
|
|
4745
|
-
y2: majorSizeString,
|
|
4746
|
-
stroke: color,
|
|
4747
|
-
"stroke-width": "1",
|
|
4748
|
-
"shape-rendering": "crispEdges"
|
|
4749
|
-
},
|
|
4750
|
-
children: []
|
|
4751
|
-
});
|
|
4752
|
-
children.push({
|
|
4753
|
-
name: "line",
|
|
5217
|
+
import "svgson";
|
|
5218
|
+
var DEFAULT_GRID_LINE_COLOR = "rgba(255, 255, 255, 0.5)";
|
|
5219
|
+
var GRID_PATTERN_ID = "pcb-grid-pattern";
|
|
5220
|
+
function createSvgObjectsForPcbGrid({
|
|
5221
|
+
grid,
|
|
5222
|
+
svgWidth,
|
|
5223
|
+
svgHeight
|
|
5224
|
+
}) {
|
|
5225
|
+
if (!grid) {
|
|
5226
|
+
return {};
|
|
5227
|
+
}
|
|
5228
|
+
const gridLineColor = grid.lineColor ?? DEFAULT_GRID_LINE_COLOR;
|
|
5229
|
+
const gridCellSize = grid.cellSize;
|
|
5230
|
+
const majorCellSize = grid.majorCellSize;
|
|
5231
|
+
const majorLineColor = grid.majorLineColor ?? gridLineColor;
|
|
5232
|
+
if (majorCellSize !== void 0) {
|
|
5233
|
+
if (!gridCellSize || gridCellSize <= 0) {
|
|
5234
|
+
throw new Error("grid.majorCellSize requires a positive grid.cellSize");
|
|
5235
|
+
}
|
|
5236
|
+
if (majorCellSize <= 0) {
|
|
5237
|
+
throw new Error(
|
|
5238
|
+
"grid.majorCellSize must be a positive multiple of grid.cellSize"
|
|
5239
|
+
);
|
|
5240
|
+
}
|
|
5241
|
+
const ratio = majorCellSize / gridCellSize;
|
|
5242
|
+
const nearestInteger = Math.round(ratio);
|
|
5243
|
+
if (!Number.isFinite(ratio) || Math.abs(ratio - nearestInteger) > 1e-6) {
|
|
5244
|
+
throw new Error(
|
|
5245
|
+
"grid.majorCellSize must be a positive multiple of grid.cellSize"
|
|
5246
|
+
);
|
|
5247
|
+
}
|
|
5248
|
+
}
|
|
5249
|
+
if (!gridCellSize || gridCellSize <= 0) {
|
|
5250
|
+
return {};
|
|
5251
|
+
}
|
|
5252
|
+
const hasMajorGrid = majorCellSize !== void 0;
|
|
5253
|
+
const patternChildren = hasMajorGrid ? createMajorGridPatternChildren(
|
|
5254
|
+
gridCellSize,
|
|
5255
|
+
majorCellSize,
|
|
5256
|
+
gridLineColor,
|
|
5257
|
+
majorLineColor
|
|
5258
|
+
) : [
|
|
5259
|
+
{
|
|
5260
|
+
name: "path",
|
|
4754
5261
|
type: "element",
|
|
4755
5262
|
value: "",
|
|
4756
5263
|
attributes: {
|
|
4757
|
-
|
|
4758
|
-
|
|
4759
|
-
|
|
4760
|
-
y2: offsetString,
|
|
4761
|
-
stroke: color,
|
|
5264
|
+
d: `M ${gridCellSize} 0 L 0 0 0 ${gridCellSize}`,
|
|
5265
|
+
fill: "none",
|
|
5266
|
+
stroke: gridLineColor,
|
|
4762
5267
|
"stroke-width": "1",
|
|
4763
5268
|
"shape-rendering": "crispEdges"
|
|
4764
5269
|
},
|
|
4765
5270
|
children: []
|
|
4766
|
-
}
|
|
4767
|
-
|
|
4768
|
-
|
|
4769
|
-
|
|
4770
|
-
|
|
4771
|
-
// lib/pcb/svg-object-fns/create-svg-objects-from-pcb-component.ts
|
|
4772
|
-
import { applyToPoint as applyToPoint30 } from "transformation-matrix";
|
|
4773
|
-
|
|
4774
|
-
// lib/utils/create-pcb-component-anchor-offset-indicators.ts
|
|
4775
|
-
import { applyToPoint as applyToPoint29 } from "transformation-matrix";
|
|
4776
|
-
var OFFSET_THRESHOLD_MM = 0.01;
|
|
4777
|
-
var TICK_SIZE_PX = 4;
|
|
4778
|
-
var LABEL_GAP_PX = 8;
|
|
4779
|
-
var LABEL_FONT_SIZE_PX = 11;
|
|
4780
|
-
var STROKE_WIDTH_PX = 1;
|
|
4781
|
-
var ANCHOR_MARKER_SIZE_PX = 5;
|
|
4782
|
-
var ANCHOR_MARKER_STROKE_WIDTH_PX = 1.5;
|
|
4783
|
-
var COMPONENT_GAP_PX = 15;
|
|
4784
|
-
var COMPONENT_SIDE_GAP_PX = 10;
|
|
4785
|
-
var DISTANCE_MULTIPLIER = 0.2;
|
|
4786
|
-
var MAX_OFFSET_PX = 50;
|
|
4787
|
-
function createAnchorOffsetIndicators(params) {
|
|
4788
|
-
const {
|
|
4789
|
-
groupAnchorPosition,
|
|
4790
|
-
componentPosition,
|
|
4791
|
-
transform,
|
|
4792
|
-
componentWidth = 0,
|
|
4793
|
-
componentHeight = 0
|
|
4794
|
-
} = params;
|
|
4795
|
-
const objects = [];
|
|
4796
|
-
const [screenGroupAnchorX, screenGroupAnchorY] = applyToPoint29(transform, [
|
|
4797
|
-
groupAnchorPosition.x,
|
|
4798
|
-
groupAnchorPosition.y
|
|
4799
|
-
]);
|
|
4800
|
-
const [screenComponentX, screenComponentY] = applyToPoint29(transform, [
|
|
4801
|
-
componentPosition.x,
|
|
4802
|
-
componentPosition.y
|
|
4803
|
-
]);
|
|
4804
|
-
const offsetX = componentPosition.x - groupAnchorPosition.x;
|
|
4805
|
-
const offsetY = componentPosition.y - groupAnchorPosition.y;
|
|
4806
|
-
const scale9 = Math.abs(transform.a);
|
|
4807
|
-
const screenComponentWidth = componentWidth * scale9;
|
|
4808
|
-
const screenComponentHeight = componentHeight * scale9;
|
|
4809
|
-
objects.push(createAnchorMarker(screenGroupAnchorX, screenGroupAnchorY));
|
|
4810
|
-
objects.push({
|
|
4811
|
-
name: "line",
|
|
4812
|
-
type: "element",
|
|
4813
|
-
attributes: {
|
|
4814
|
-
x1: screenGroupAnchorX.toString(),
|
|
4815
|
-
y1: screenGroupAnchorY.toString(),
|
|
4816
|
-
x2: screenComponentX.toString(),
|
|
4817
|
-
y2: screenComponentY.toString(),
|
|
4818
|
-
stroke: "#ffffff",
|
|
4819
|
-
"stroke-width": "0.5",
|
|
4820
|
-
"stroke-dasharray": "3,3",
|
|
4821
|
-
opacity: "0.5",
|
|
4822
|
-
class: "anchor-offset-connector"
|
|
4823
|
-
},
|
|
4824
|
-
children: [],
|
|
4825
|
-
value: ""
|
|
4826
|
-
});
|
|
4827
|
-
objects.push({
|
|
4828
|
-
name: "circle",
|
|
4829
|
-
type: "element",
|
|
4830
|
-
attributes: {
|
|
4831
|
-
cx: screenComponentX.toString(),
|
|
4832
|
-
cy: screenComponentY.toString(),
|
|
4833
|
-
r: "2",
|
|
4834
|
-
fill: "#ffffff",
|
|
4835
|
-
opacity: "0.7",
|
|
4836
|
-
class: "anchor-offset-component-marker"
|
|
4837
|
-
},
|
|
4838
|
-
children: [],
|
|
4839
|
-
value: ""
|
|
4840
|
-
});
|
|
4841
|
-
const yDistance = Math.abs(screenComponentY - screenGroupAnchorY);
|
|
4842
|
-
const xDistance = Math.abs(screenComponentX - screenGroupAnchorX);
|
|
4843
|
-
const totalDistance = Math.sqrt(xDistance * xDistance + yDistance * yDistance);
|
|
4844
|
-
const componentHeightOffset = screenComponentHeight / 2 + COMPONENT_GAP_PX;
|
|
4845
|
-
const dynamicOffset = Math.max(
|
|
4846
|
-
componentHeightOffset,
|
|
4847
|
-
Math.min(MAX_OFFSET_PX, totalDistance * DISTANCE_MULTIPLIER)
|
|
4848
|
-
);
|
|
4849
|
-
const horizontalLineY = offsetY > 0 ? screenComponentY - dynamicOffset : screenComponentY + dynamicOffset;
|
|
4850
|
-
const componentWidthOffset = screenComponentWidth / 2 + COMPONENT_SIDE_GAP_PX;
|
|
4851
|
-
const verticalLineX = offsetX > 0 ? screenComponentX + componentWidthOffset : screenComponentX - componentWidthOffset;
|
|
4852
|
-
if (Math.abs(offsetX) > OFFSET_THRESHOLD_MM) {
|
|
4853
|
-
objects.push(
|
|
4854
|
-
...createHorizontalDimension({
|
|
4855
|
-
startX: screenGroupAnchorX,
|
|
4856
|
-
endX: screenComponentX,
|
|
4857
|
-
y: horizontalLineY,
|
|
4858
|
-
offsetMm: offsetX,
|
|
4859
|
-
offsetY
|
|
4860
|
-
})
|
|
4861
|
-
);
|
|
4862
|
-
}
|
|
4863
|
-
if (Math.abs(offsetY) > OFFSET_THRESHOLD_MM) {
|
|
4864
|
-
objects.push(
|
|
4865
|
-
...createVerticalDimension({
|
|
4866
|
-
x: verticalLineX,
|
|
4867
|
-
startY: screenGroupAnchorY,
|
|
4868
|
-
endY: screenComponentY,
|
|
4869
|
-
offsetMm: -offsetY,
|
|
4870
|
-
offsetX
|
|
4871
|
-
})
|
|
4872
|
-
);
|
|
4873
|
-
}
|
|
4874
|
-
return objects;
|
|
4875
|
-
}
|
|
4876
|
-
function createAnchorMarker(x, y) {
|
|
4877
|
-
return {
|
|
4878
|
-
name: "g",
|
|
4879
|
-
type: "element",
|
|
4880
|
-
attributes: {
|
|
4881
|
-
class: "anchor-offset-marker",
|
|
4882
|
-
"data-type": "anchor_offset_marker"
|
|
4883
|
-
},
|
|
4884
|
-
children: [
|
|
4885
|
-
{
|
|
4886
|
-
name: "line",
|
|
4887
|
-
type: "element",
|
|
4888
|
-
attributes: {
|
|
4889
|
-
x1: x.toString(),
|
|
4890
|
-
y1: (y - ANCHOR_MARKER_SIZE_PX).toString(),
|
|
4891
|
-
x2: x.toString(),
|
|
4892
|
-
y2: (y + ANCHOR_MARKER_SIZE_PX).toString(),
|
|
4893
|
-
stroke: "#ffffff",
|
|
4894
|
-
"stroke-width": ANCHOR_MARKER_STROKE_WIDTH_PX.toString(),
|
|
4895
|
-
"stroke-linecap": "round"
|
|
4896
|
-
},
|
|
4897
|
-
children: [],
|
|
4898
|
-
value: ""
|
|
4899
|
-
},
|
|
4900
|
-
{
|
|
4901
|
-
name: "line",
|
|
4902
|
-
type: "element",
|
|
4903
|
-
attributes: {
|
|
4904
|
-
x1: (x - ANCHOR_MARKER_SIZE_PX).toString(),
|
|
4905
|
-
y1: y.toString(),
|
|
4906
|
-
x2: (x + ANCHOR_MARKER_SIZE_PX).toString(),
|
|
4907
|
-
y2: y.toString(),
|
|
4908
|
-
stroke: "#ffffff",
|
|
4909
|
-
"stroke-width": ANCHOR_MARKER_STROKE_WIDTH_PX.toString(),
|
|
4910
|
-
"stroke-linecap": "round"
|
|
4911
|
-
},
|
|
4912
|
-
children: [],
|
|
4913
|
-
value: ""
|
|
4914
|
-
}
|
|
4915
|
-
],
|
|
4916
|
-
value: ""
|
|
4917
|
-
};
|
|
4918
|
-
}
|
|
4919
|
-
function createHorizontalDimension({
|
|
4920
|
-
startX,
|
|
4921
|
-
endX,
|
|
4922
|
-
y,
|
|
4923
|
-
offsetMm,
|
|
4924
|
-
offsetY
|
|
4925
|
-
}) {
|
|
4926
|
-
const objects = [];
|
|
4927
|
-
objects.push({
|
|
4928
|
-
name: "line",
|
|
4929
|
-
type: "element",
|
|
4930
|
-
attributes: {
|
|
4931
|
-
x1: startX.toString(),
|
|
4932
|
-
y1: y.toString(),
|
|
4933
|
-
x2: endX.toString(),
|
|
4934
|
-
y2: y.toString(),
|
|
4935
|
-
stroke: "#ffffff",
|
|
4936
|
-
"stroke-width": STROKE_WIDTH_PX.toString(),
|
|
4937
|
-
class: "anchor-offset-dimension-x"
|
|
4938
|
-
},
|
|
4939
|
-
children: [],
|
|
4940
|
-
value: ""
|
|
4941
|
-
});
|
|
4942
|
-
objects.push({
|
|
4943
|
-
name: "line",
|
|
4944
|
-
type: "element",
|
|
4945
|
-
attributes: {
|
|
4946
|
-
x1: startX.toString(),
|
|
4947
|
-
y1: (y - TICK_SIZE_PX).toString(),
|
|
4948
|
-
x2: startX.toString(),
|
|
4949
|
-
y2: (y + TICK_SIZE_PX).toString(),
|
|
4950
|
-
stroke: "#ffffff",
|
|
4951
|
-
"stroke-width": STROKE_WIDTH_PX.toString()
|
|
4952
|
-
},
|
|
4953
|
-
children: [],
|
|
4954
|
-
value: ""
|
|
4955
|
-
});
|
|
4956
|
-
objects.push({
|
|
4957
|
-
name: "line",
|
|
4958
|
-
type: "element",
|
|
4959
|
-
attributes: {
|
|
4960
|
-
x1: endX.toString(),
|
|
4961
|
-
y1: (y - TICK_SIZE_PX).toString(),
|
|
4962
|
-
x2: endX.toString(),
|
|
4963
|
-
y2: (y + TICK_SIZE_PX).toString(),
|
|
4964
|
-
stroke: "#ffffff",
|
|
4965
|
-
"stroke-width": STROKE_WIDTH_PX.toString()
|
|
4966
|
-
},
|
|
4967
|
-
children: [],
|
|
4968
|
-
value: ""
|
|
4969
|
-
});
|
|
4970
|
-
const midX = (startX + endX) / 2;
|
|
4971
|
-
const labelY = offsetY > 0 ? y - TICK_SIZE_PX - LABEL_GAP_PX : y + TICK_SIZE_PX + LABEL_GAP_PX;
|
|
4972
|
-
objects.push({
|
|
4973
|
-
name: "text",
|
|
5271
|
+
}
|
|
5272
|
+
];
|
|
5273
|
+
const defs = {
|
|
5274
|
+
name: "defs",
|
|
4974
5275
|
type: "element",
|
|
4975
|
-
|
|
4976
|
-
|
|
4977
|
-
y: labelY.toString(),
|
|
4978
|
-
fill: "#ffffff",
|
|
4979
|
-
"font-size": LABEL_FONT_SIZE_PX.toString(),
|
|
4980
|
-
"font-family": "Arial, sans-serif",
|
|
4981
|
-
"text-anchor": "middle",
|
|
4982
|
-
"dominant-baseline": offsetY > 0 ? "baseline" : "hanging",
|
|
4983
|
-
class: "anchor-offset-label"
|
|
4984
|
-
},
|
|
5276
|
+
value: "",
|
|
5277
|
+
attributes: {},
|
|
4985
5278
|
children: [
|
|
4986
5279
|
{
|
|
4987
|
-
|
|
4988
|
-
|
|
4989
|
-
|
|
4990
|
-
attributes: {
|
|
4991
|
-
|
|
5280
|
+
name: "pattern",
|
|
5281
|
+
type: "element",
|
|
5282
|
+
value: "",
|
|
5283
|
+
attributes: {
|
|
5284
|
+
id: GRID_PATTERN_ID,
|
|
5285
|
+
width: hasMajorGrid ? majorCellSize.toString() : gridCellSize.toString(),
|
|
5286
|
+
height: hasMajorGrid ? majorCellSize.toString() : gridCellSize.toString(),
|
|
5287
|
+
patternUnits: "userSpaceOnUse"
|
|
5288
|
+
},
|
|
5289
|
+
children: patternChildren
|
|
4992
5290
|
}
|
|
4993
|
-
]
|
|
4994
|
-
|
|
4995
|
-
|
|
4996
|
-
|
|
4997
|
-
}
|
|
4998
|
-
function createVerticalDimension({
|
|
4999
|
-
x,
|
|
5000
|
-
startY,
|
|
5001
|
-
endY,
|
|
5002
|
-
offsetMm,
|
|
5003
|
-
offsetX
|
|
5004
|
-
}) {
|
|
5005
|
-
const objects = [];
|
|
5006
|
-
objects.push({
|
|
5007
|
-
name: "line",
|
|
5008
|
-
type: "element",
|
|
5009
|
-
attributes: {
|
|
5010
|
-
x1: x.toString(),
|
|
5011
|
-
y1: startY.toString(),
|
|
5012
|
-
x2: x.toString(),
|
|
5013
|
-
y2: endY.toString(),
|
|
5014
|
-
stroke: "#ffffff",
|
|
5015
|
-
"stroke-width": STROKE_WIDTH_PX.toString(),
|
|
5016
|
-
class: "anchor-offset-dimension-y"
|
|
5017
|
-
},
|
|
5018
|
-
children: [],
|
|
5019
|
-
value: ""
|
|
5020
|
-
});
|
|
5021
|
-
objects.push({
|
|
5022
|
-
name: "line",
|
|
5023
|
-
type: "element",
|
|
5024
|
-
attributes: {
|
|
5025
|
-
x1: (x - TICK_SIZE_PX).toString(),
|
|
5026
|
-
y1: startY.toString(),
|
|
5027
|
-
x2: (x + TICK_SIZE_PX).toString(),
|
|
5028
|
-
y2: startY.toString(),
|
|
5029
|
-
stroke: "#ffffff",
|
|
5030
|
-
"stroke-width": STROKE_WIDTH_PX.toString()
|
|
5031
|
-
},
|
|
5032
|
-
children: [],
|
|
5033
|
-
value: ""
|
|
5034
|
-
});
|
|
5035
|
-
objects.push({
|
|
5036
|
-
name: "line",
|
|
5037
|
-
type: "element",
|
|
5038
|
-
attributes: {
|
|
5039
|
-
x1: (x - TICK_SIZE_PX).toString(),
|
|
5040
|
-
y1: endY.toString(),
|
|
5041
|
-
x2: (x + TICK_SIZE_PX).toString(),
|
|
5042
|
-
y2: endY.toString(),
|
|
5043
|
-
stroke: "#ffffff",
|
|
5044
|
-
"stroke-width": STROKE_WIDTH_PX.toString()
|
|
5045
|
-
},
|
|
5046
|
-
children: [],
|
|
5047
|
-
value: ""
|
|
5048
|
-
});
|
|
5049
|
-
const midY = (startY + endY) / 2;
|
|
5050
|
-
const labelX = offsetX < 0 ? x - TICK_SIZE_PX - 4 : x + TICK_SIZE_PX + 4;
|
|
5051
|
-
objects.push({
|
|
5052
|
-
name: "text",
|
|
5291
|
+
]
|
|
5292
|
+
};
|
|
5293
|
+
const rect = {
|
|
5294
|
+
name: "rect",
|
|
5053
5295
|
type: "element",
|
|
5296
|
+
value: "",
|
|
5054
5297
|
attributes: {
|
|
5055
|
-
x:
|
|
5056
|
-
y:
|
|
5057
|
-
|
|
5058
|
-
|
|
5059
|
-
|
|
5060
|
-
"
|
|
5061
|
-
"
|
|
5062
|
-
|
|
5298
|
+
x: "0",
|
|
5299
|
+
y: "0",
|
|
5300
|
+
width: svgWidth.toString(),
|
|
5301
|
+
height: svgHeight.toString(),
|
|
5302
|
+
fill: `url(#${GRID_PATTERN_ID})`,
|
|
5303
|
+
"pointer-events": "none",
|
|
5304
|
+
"data-type": "pcb_grid",
|
|
5305
|
+
"data-pcb-layer": "global"
|
|
5063
5306
|
},
|
|
5064
|
-
children: [
|
|
5065
|
-
|
|
5066
|
-
|
|
5067
|
-
|
|
5068
|
-
|
|
5069
|
-
|
|
5070
|
-
|
|
5071
|
-
|
|
5072
|
-
|
|
5073
|
-
|
|
5074
|
-
|
|
5075
|
-
|
|
5307
|
+
children: []
|
|
5308
|
+
};
|
|
5309
|
+
return { defs, rect };
|
|
5310
|
+
}
|
|
5311
|
+
function createMajorGridPatternChildren(cellSize, majorCellSize, lineColor, majorLineColor) {
|
|
5312
|
+
const children = [];
|
|
5313
|
+
const steps = Math.round(majorCellSize / cellSize);
|
|
5314
|
+
for (let step = 0; step < steps; step += 1) {
|
|
5315
|
+
const offset = Number((step * cellSize).toFixed(6));
|
|
5316
|
+
const offsetString = offset.toString();
|
|
5317
|
+
const color = step === 0 ? majorLineColor : lineColor;
|
|
5318
|
+
const majorSizeString = majorCellSize.toString();
|
|
5319
|
+
children.push({
|
|
5320
|
+
name: "line",
|
|
5321
|
+
type: "element",
|
|
5322
|
+
value: "",
|
|
5323
|
+
attributes: {
|
|
5324
|
+
x1: offsetString,
|
|
5325
|
+
y1: "0",
|
|
5326
|
+
x2: offsetString,
|
|
5327
|
+
y2: majorSizeString,
|
|
5328
|
+
stroke: color,
|
|
5329
|
+
"stroke-width": "1",
|
|
5330
|
+
"shape-rendering": "crispEdges"
|
|
5331
|
+
},
|
|
5332
|
+
children: []
|
|
5333
|
+
});
|
|
5334
|
+
children.push({
|
|
5335
|
+
name: "line",
|
|
5336
|
+
type: "element",
|
|
5337
|
+
value: "",
|
|
5338
|
+
attributes: {
|
|
5339
|
+
x1: "0",
|
|
5340
|
+
y1: offsetString,
|
|
5341
|
+
x2: majorSizeString,
|
|
5342
|
+
y2: offsetString,
|
|
5343
|
+
stroke: color,
|
|
5344
|
+
"stroke-width": "1",
|
|
5345
|
+
"shape-rendering": "crispEdges"
|
|
5346
|
+
},
|
|
5347
|
+
children: []
|
|
5348
|
+
});
|
|
5349
|
+
}
|
|
5350
|
+
return children;
|
|
5076
5351
|
}
|
|
5077
5352
|
|
|
5078
5353
|
// lib/pcb/svg-object-fns/create-svg-objects-from-pcb-component.ts
|
|
5354
|
+
import { applyToPoint as applyToPoint31 } from "transformation-matrix";
|
|
5079
5355
|
function createSvgObjectsFromPcbComponent(component, ctx) {
|
|
5080
5356
|
const { transform, circuitJson } = ctx;
|
|
5081
5357
|
const { center, width, height, rotation = 0 } = component;
|
|
5082
|
-
const [x, y] =
|
|
5358
|
+
const [x, y] = applyToPoint31(transform, [center.x, center.y]);
|
|
5083
5359
|
const scaledWidth = width * Math.abs(transform.a);
|
|
5084
5360
|
const scaledHeight = height * Math.abs(transform.d);
|
|
5085
5361
|
const transformStr = `translate(${x}, ${y}) rotate(${-rotation}) scale(1, -1)`;
|
|
@@ -5134,7 +5410,7 @@ function createSvgObjectsFromPcbComponent(component, ctx) {
|
|
|
5134
5410
|
}
|
|
5135
5411
|
|
|
5136
5412
|
// lib/pcb/svg-object-fns/create-svg-objects-from-pcb-group.ts
|
|
5137
|
-
import { applyToPoint as
|
|
5413
|
+
import { applyToPoint as applyToPoint32 } from "transformation-matrix";
|
|
5138
5414
|
var DEFAULT_GROUP_COLOR = "rgba(100, 200, 255, 0.6)";
|
|
5139
5415
|
var DEFAULT_STROKE_WIDTH = 0.1;
|
|
5140
5416
|
function createSvgObjectsFromPcbGroup(pcbGroup, ctx) {
|
|
@@ -5161,7 +5437,7 @@ function createSvgObjectsFromPcbGroup(pcbGroup, ctx) {
|
|
|
5161
5437
|
(point) => point && typeof point.x === "number" && typeof point.y === "number"
|
|
5162
5438
|
)) {
|
|
5163
5439
|
const path = outline.map((point, index) => {
|
|
5164
|
-
const [x, y] =
|
|
5440
|
+
const [x, y] = applyToPoint32(transform, [point.x, point.y]);
|
|
5165
5441
|
return index === 0 ? `M ${x} ${y}` : `L ${x} ${y}`;
|
|
5166
5442
|
}).join(" ");
|
|
5167
5443
|
return [
|
|
@@ -5183,11 +5459,11 @@ function createSvgObjectsFromPcbGroup(pcbGroup, ctx) {
|
|
|
5183
5459
|
}
|
|
5184
5460
|
const halfWidth = width / 2;
|
|
5185
5461
|
const halfHeight = height / 2;
|
|
5186
|
-
const [topLeftX, topLeftY] =
|
|
5462
|
+
const [topLeftX, topLeftY] = applyToPoint32(transform, [
|
|
5187
5463
|
center.x - halfWidth,
|
|
5188
5464
|
center.y + halfHeight
|
|
5189
5465
|
]);
|
|
5190
|
-
const [bottomRightX, bottomRightY] =
|
|
5466
|
+
const [bottomRightX, bottomRightY] = applyToPoint32(transform, [
|
|
5191
5467
|
center.x + halfWidth,
|
|
5192
5468
|
center.y - halfHeight
|
|
5193
5469
|
]);
|
|
@@ -5223,7 +5499,7 @@ function getSoftwareUsedString(circuitJson) {
|
|
|
5223
5499
|
var package_default = {
|
|
5224
5500
|
name: "circuit-to-svg",
|
|
5225
5501
|
type: "module",
|
|
5226
|
-
version: "0.0.
|
|
5502
|
+
version: "0.0.284",
|
|
5227
5503
|
description: "Convert Circuit JSON to SVG",
|
|
5228
5504
|
main: "dist/index.js",
|
|
5229
5505
|
files: [
|
|
@@ -5241,22 +5517,26 @@ var package_default = {
|
|
|
5241
5517
|
license: "ISC",
|
|
5242
5518
|
devDependencies: {
|
|
5243
5519
|
"@biomejs/biome": "^1.9.4",
|
|
5520
|
+
"@tscircuit/alphabet": "^0.0.8",
|
|
5244
5521
|
"@types/bun": "^1.2.8",
|
|
5245
5522
|
"@vitejs/plugin-react": "5.0.0",
|
|
5246
5523
|
biome: "^0.3.3",
|
|
5247
5524
|
"bun-match-svg": "^0.0.12",
|
|
5525
|
+
"circuit-json": "^0.0.327",
|
|
5248
5526
|
esbuild: "^0.20.2",
|
|
5249
5527
|
"performance-now": "^2.1.0",
|
|
5250
|
-
"circuit-json": "^0.0.319",
|
|
5251
5528
|
react: "19.1.0",
|
|
5252
5529
|
"react-cosmos": "7.0.0",
|
|
5253
5530
|
"react-cosmos-plugin-vite": "7.0.0",
|
|
5254
5531
|
"react-dom": "19.1.0",
|
|
5255
|
-
tscircuit: "^0.0.
|
|
5532
|
+
tscircuit: "^0.0.1018",
|
|
5256
5533
|
tsup: "^8.0.2",
|
|
5257
5534
|
typescript: "^5.4.5",
|
|
5258
5535
|
"vite-tsconfig-paths": "^5.0.1"
|
|
5259
5536
|
},
|
|
5537
|
+
peerDependencies: {
|
|
5538
|
+
"@tscircuit/alphabet": "*"
|
|
5539
|
+
},
|
|
5260
5540
|
dependencies: {
|
|
5261
5541
|
"@types/node": "^22.5.5",
|
|
5262
5542
|
"bun-types": "^1.1.40",
|
|
@@ -5452,8 +5732,8 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
|
|
|
5452
5732
|
for (const circuitJsonElm of circuitJson) {
|
|
5453
5733
|
if (circuitJsonElm.type === "pcb_panel") {
|
|
5454
5734
|
const panel = circuitJsonElm;
|
|
5455
|
-
const width =
|
|
5456
|
-
const height =
|
|
5735
|
+
const width = distance2.parse(panel.width);
|
|
5736
|
+
const height = distance2.parse(panel.height);
|
|
5457
5737
|
if (width === void 0 || height === void 0) {
|
|
5458
5738
|
continue;
|
|
5459
5739
|
}
|
|
@@ -5480,7 +5760,7 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
|
|
|
5480
5760
|
if (pad.shape === "rect" || pad.shape === "rotated_rect" || pad.shape === "pill") {
|
|
5481
5761
|
updateBounds({ x: pad.x, y: pad.y }, pad.width, pad.height);
|
|
5482
5762
|
} else if (pad.shape === "circle") {
|
|
5483
|
-
const radius =
|
|
5763
|
+
const radius = distance2.parse(pad.radius);
|
|
5484
5764
|
if (radius !== void 0) {
|
|
5485
5765
|
updateBounds({ x: pad.x, y: pad.y }, radius * 2, radius * 2);
|
|
5486
5766
|
}
|
|
@@ -5502,7 +5782,7 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
|
|
|
5502
5782
|
if (cutout.shape === "rect") {
|
|
5503
5783
|
updateBounds(cutout.center, cutout.width, cutout.height);
|
|
5504
5784
|
} else if (cutout.shape === "circle") {
|
|
5505
|
-
const radius =
|
|
5785
|
+
const radius = distance2.parse(cutout.radius);
|
|
5506
5786
|
if (radius !== void 0) {
|
|
5507
5787
|
updateBounds(cutout.center, radius * 2, radius * 2);
|
|
5508
5788
|
}
|
|
@@ -5511,6 +5791,8 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
|
|
|
5511
5791
|
}
|
|
5512
5792
|
} else if (circuitJsonElm.type === "pcb_silkscreen_text" || circuitJsonElm.type === "pcb_silkscreen_rect" || circuitJsonElm.type === "pcb_silkscreen_circle" || circuitJsonElm.type === "pcb_silkscreen_line") {
|
|
5513
5793
|
updateSilkscreenBounds(circuitJsonElm);
|
|
5794
|
+
} else if (circuitJsonElm.type === "pcb_copper_text") {
|
|
5795
|
+
updateBounds(circuitJsonElm.anchor_position, 0, 0);
|
|
5514
5796
|
} else if (circuitJsonElm.type === "pcb_copper_pour") {
|
|
5515
5797
|
if (circuitJsonElm.shape === "rect") {
|
|
5516
5798
|
updateBounds(
|
|
@@ -5557,12 +5839,12 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
|
|
|
5557
5839
|
const scaleFactor = Math.min(scaleX, scaleY);
|
|
5558
5840
|
const offsetX = (svgWidth - circuitWidth * scaleFactor) / 2;
|
|
5559
5841
|
const offsetY = (svgHeight - circuitHeight * scaleFactor) / 2;
|
|
5560
|
-
const transform =
|
|
5561
|
-
|
|
5842
|
+
const transform = compose6(
|
|
5843
|
+
translate6(
|
|
5562
5844
|
offsetX - boundsMinX * scaleFactor + padding * scaleFactor,
|
|
5563
5845
|
svgHeight - offsetY + boundsMinY * scaleFactor - padding * scaleFactor
|
|
5564
5846
|
),
|
|
5565
|
-
|
|
5847
|
+
scale3(scaleFactor, -scaleFactor)
|
|
5566
5848
|
// Flip in y-direction
|
|
5567
5849
|
);
|
|
5568
5850
|
const ctx = {
|
|
@@ -5678,11 +5960,11 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
|
|
|
5678
5960
|
}
|
|
5679
5961
|
function updateBounds(center, width, height) {
|
|
5680
5962
|
if (!center) return;
|
|
5681
|
-
const centerX =
|
|
5682
|
-
const centerY =
|
|
5963
|
+
const centerX = distance2.parse(center.x);
|
|
5964
|
+
const centerY = distance2.parse(center.y);
|
|
5683
5965
|
if (centerX === void 0 || centerY === void 0) return;
|
|
5684
|
-
const numericWidth =
|
|
5685
|
-
const numericHeight =
|
|
5966
|
+
const numericWidth = distance2.parse(width) ?? 0;
|
|
5967
|
+
const numericHeight = distance2.parse(height) ?? 0;
|
|
5686
5968
|
const halfWidth = numericWidth / 2;
|
|
5687
5969
|
const halfHeight = numericHeight / 2;
|
|
5688
5970
|
minX = Math.min(minX, centerX - halfWidth);
|
|
@@ -5693,11 +5975,11 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
|
|
|
5693
5975
|
}
|
|
5694
5976
|
function updateBoardBounds(center, width, height) {
|
|
5695
5977
|
if (!center) return;
|
|
5696
|
-
const centerX =
|
|
5697
|
-
const centerY =
|
|
5978
|
+
const centerX = distance2.parse(center.x);
|
|
5979
|
+
const centerY = distance2.parse(center.y);
|
|
5698
5980
|
if (centerX === void 0 || centerY === void 0) return;
|
|
5699
|
-
const numericWidth =
|
|
5700
|
-
const numericHeight =
|
|
5981
|
+
const numericWidth = distance2.parse(width) ?? 0;
|
|
5982
|
+
const numericHeight = distance2.parse(height) ?? 0;
|
|
5701
5983
|
const halfWidth = numericWidth / 2;
|
|
5702
5984
|
const halfHeight = numericHeight / 2;
|
|
5703
5985
|
boardMinX = Math.min(boardMinX, centerX - halfWidth);
|
|
@@ -5710,8 +5992,8 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
|
|
|
5710
5992
|
function updateBoundsToIncludeOutline(outline) {
|
|
5711
5993
|
let updated = false;
|
|
5712
5994
|
for (const point of outline) {
|
|
5713
|
-
const x =
|
|
5714
|
-
const y =
|
|
5995
|
+
const x = distance2.parse(point.x);
|
|
5996
|
+
const y = distance2.parse(point.y);
|
|
5715
5997
|
if (x === void 0 || y === void 0) continue;
|
|
5716
5998
|
minX = Math.min(minX, x);
|
|
5717
5999
|
minY = Math.min(minY, y);
|
|
@@ -5726,8 +6008,8 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
|
|
|
5726
6008
|
function updateBoardBoundsToIncludeOutline(outline) {
|
|
5727
6009
|
let updated = false;
|
|
5728
6010
|
for (const point of outline) {
|
|
5729
|
-
const x =
|
|
5730
|
-
const y =
|
|
6011
|
+
const x = distance2.parse(point.x);
|
|
6012
|
+
const y = distance2.parse(point.y);
|
|
5731
6013
|
if (x === void 0 || y === void 0) continue;
|
|
5732
6014
|
boardMinX = Math.min(boardMinX, x);
|
|
5733
6015
|
boardMinY = Math.min(boardMinY, y);
|
|
@@ -5743,8 +6025,8 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
|
|
|
5743
6025
|
function updateTraceBounds(route) {
|
|
5744
6026
|
let updated = false;
|
|
5745
6027
|
for (const point of route) {
|
|
5746
|
-
const x =
|
|
5747
|
-
const y =
|
|
6028
|
+
const x = distance2.parse(point?.x);
|
|
6029
|
+
const y = distance2.parse(point?.y);
|
|
5748
6030
|
if (x === void 0 || y === void 0) continue;
|
|
5749
6031
|
minX = Math.min(minX, x);
|
|
5750
6032
|
minY = Math.min(minY, y);
|
|
@@ -5764,7 +6046,7 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
|
|
|
5764
6046
|
} else if (item.type === "pcb_silkscreen_rect") {
|
|
5765
6047
|
updateBounds(item.center, item.width, item.height);
|
|
5766
6048
|
} else if (item.type === "pcb_silkscreen_circle") {
|
|
5767
|
-
const radius =
|
|
6049
|
+
const radius = distance2.parse(item.radius);
|
|
5768
6050
|
if (radius !== void 0) {
|
|
5769
6051
|
updateBounds(item.center, radius * 2, radius * 2);
|
|
5770
6052
|
}
|
|
@@ -5776,7 +6058,7 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
|
|
|
5776
6058
|
if (cutout.shape === "rect") {
|
|
5777
6059
|
updateBounds(cutout.center, cutout.width, cutout.height);
|
|
5778
6060
|
} else if (cutout.shape === "circle") {
|
|
5779
|
-
const radius =
|
|
6061
|
+
const radius = distance2.parse(cutout.radius);
|
|
5780
6062
|
if (radius !== void 0) {
|
|
5781
6063
|
updateBounds(cutout.center, radius * 2, radius * 2);
|
|
5782
6064
|
}
|
|
@@ -5822,6 +6104,8 @@ function createSvgObjects({
|
|
|
5822
6104
|
return createSvgObjectsFromPcbSilkscreenCircle(elm, ctx);
|
|
5823
6105
|
case "pcb_silkscreen_line":
|
|
5824
6106
|
return createSvgObjectsFromPcbSilkscreenLine(elm, ctx);
|
|
6107
|
+
case "pcb_copper_text":
|
|
6108
|
+
return createSvgObjectsFromPcbCopperText(elm, ctx);
|
|
5825
6109
|
case "pcb_courtyard_rect":
|
|
5826
6110
|
if (!ctx.showCourtyards) return [];
|
|
5827
6111
|
return createSvgObjectsFromPcbCourtyardRect(elm, ctx);
|
|
@@ -5860,8 +6144,8 @@ function createSvgObjects({
|
|
|
5860
6144
|
}
|
|
5861
6145
|
}
|
|
5862
6146
|
function createSvgObjectFromPcbBoundary(transform, minX, minY, maxX, maxY) {
|
|
5863
|
-
const [x1, y1] =
|
|
5864
|
-
const [x2, y2] =
|
|
6147
|
+
const [x1, y1] = applyToPoint33(transform, [minX, minY]);
|
|
6148
|
+
const [x2, y2] = applyToPoint33(transform, [maxX, maxY]);
|
|
5865
6149
|
const width = Math.abs(x2 - x1);
|
|
5866
6150
|
const height = Math.abs(y2 - y1);
|
|
5867
6151
|
const x = Math.min(x1, x2);
|
|
@@ -5891,14 +6175,14 @@ var circuitJsonToPcbSvg = convertCircuitJsonToPcbSvg;
|
|
|
5891
6175
|
import { stringify as stringify2 } from "svgson";
|
|
5892
6176
|
import { su as su3 } from "@tscircuit/circuit-json-util";
|
|
5893
6177
|
import {
|
|
5894
|
-
applyToPoint as
|
|
5895
|
-
compose as
|
|
5896
|
-
scale as
|
|
5897
|
-
translate as
|
|
6178
|
+
applyToPoint as applyToPoint40,
|
|
6179
|
+
compose as compose7,
|
|
6180
|
+
scale as scale4,
|
|
6181
|
+
translate as translate7
|
|
5898
6182
|
} from "transformation-matrix";
|
|
5899
6183
|
|
|
5900
6184
|
// lib/assembly/svg-object-fns/create-svg-objects-from-assembly-board.ts
|
|
5901
|
-
import { applyToPoint as
|
|
6185
|
+
import { applyToPoint as applyToPoint34 } from "transformation-matrix";
|
|
5902
6186
|
var DEFAULT_BOARD_STYLE = {
|
|
5903
6187
|
fill: "none",
|
|
5904
6188
|
stroke: "rgb(0,0,0)",
|
|
@@ -5910,25 +6194,25 @@ function createSvgObjectsFromAssemblyBoard(pcbBoard, transform, style = {}) {
|
|
|
5910
6194
|
let path;
|
|
5911
6195
|
if (outline && Array.isArray(outline) && outline.length >= 3) {
|
|
5912
6196
|
path = outline.map((point, index) => {
|
|
5913
|
-
const [x, y] =
|
|
6197
|
+
const [x, y] = applyToPoint34(transform, [point.x, point.y]);
|
|
5914
6198
|
return index === 0 ? `M ${x} ${y}` : `L ${x} ${y}`;
|
|
5915
6199
|
}).join(" ");
|
|
5916
6200
|
} else {
|
|
5917
6201
|
const halfWidth = width / 2;
|
|
5918
6202
|
const halfHeight = height / 2;
|
|
5919
|
-
const topLeft =
|
|
6203
|
+
const topLeft = applyToPoint34(transform, [
|
|
5920
6204
|
center.x - halfWidth,
|
|
5921
6205
|
center.y - halfHeight
|
|
5922
6206
|
]);
|
|
5923
|
-
const topRight =
|
|
6207
|
+
const topRight = applyToPoint34(transform, [
|
|
5924
6208
|
center.x + halfWidth,
|
|
5925
6209
|
center.y - halfHeight
|
|
5926
6210
|
]);
|
|
5927
|
-
const bottomRight =
|
|
6211
|
+
const bottomRight = applyToPoint34(transform, [
|
|
5928
6212
|
center.x + halfWidth,
|
|
5929
6213
|
center.y + halfHeight
|
|
5930
6214
|
]);
|
|
5931
|
-
const bottomLeft =
|
|
6215
|
+
const bottomLeft = applyToPoint34(transform, [
|
|
5932
6216
|
center.x - halfWidth,
|
|
5933
6217
|
center.y + halfHeight
|
|
5934
6218
|
]);
|
|
@@ -5954,7 +6238,7 @@ function createSvgObjectsFromAssemblyBoard(pcbBoard, transform, style = {}) {
|
|
|
5954
6238
|
}
|
|
5955
6239
|
|
|
5956
6240
|
// lib/assembly/svg-object-fns/create-svg-objects-from-assembly-component.ts
|
|
5957
|
-
import { applyToPoint as
|
|
6241
|
+
import { applyToPoint as applyToPoint36 } from "transformation-matrix";
|
|
5958
6242
|
|
|
5959
6243
|
// lib/utils/get-sch-font-size.ts
|
|
5960
6244
|
import "transformation-matrix";
|
|
@@ -5980,8 +6264,8 @@ function createSvgObjectsFromAssemblyComponent(params, ctx) {
|
|
|
5980
6264
|
const { center, width, height, rotation = 0, layer = "top" } = elm;
|
|
5981
6265
|
if (!center || typeof width !== "number" || typeof height !== "number")
|
|
5982
6266
|
return null;
|
|
5983
|
-
const [x, y] =
|
|
5984
|
-
const [pinX, pinY] =
|
|
6267
|
+
const [x, y] = applyToPoint36(transform, [center.x, center.y]);
|
|
6268
|
+
const [pinX, pinY] = applyToPoint36(transform, [portPosition.x, portPosition.y]);
|
|
5985
6269
|
const scaledWidth = width * Math.abs(transform.a);
|
|
5986
6270
|
const scaledHeight = height * Math.abs(transform.d);
|
|
5987
6271
|
const isTopLayer = layer === "top";
|
|
@@ -6143,11 +6427,11 @@ function getRectPathData(w, h, rotation) {
|
|
|
6143
6427
|
}
|
|
6144
6428
|
|
|
6145
6429
|
// lib/assembly/svg-object-fns/create-svg-objects-from-assembly-hole.ts
|
|
6146
|
-
import { applyToPoint as
|
|
6430
|
+
import { applyToPoint as applyToPoint37 } from "transformation-matrix";
|
|
6147
6431
|
var HOLE_COLOR2 = "rgb(190, 190, 190)";
|
|
6148
6432
|
function createSvgObjectsFromAssemblyHole(hole, ctx) {
|
|
6149
6433
|
const { transform } = ctx;
|
|
6150
|
-
const [x, y] =
|
|
6434
|
+
const [x, y] = applyToPoint37(transform, [hole.x, hole.y]);
|
|
6151
6435
|
if (hole.hole_shape === "circle" || hole.hole_shape === "square") {
|
|
6152
6436
|
const scaledDiameter = hole.hole_diameter * Math.abs(transform.a);
|
|
6153
6437
|
const radius = scaledDiameter / 2;
|
|
@@ -6211,12 +6495,12 @@ function createSvgObjectsFromAssemblyHole(hole, ctx) {
|
|
|
6211
6495
|
}
|
|
6212
6496
|
|
|
6213
6497
|
// lib/assembly/svg-object-fns/create-svg-objects-from-assembly-plated-hole.ts
|
|
6214
|
-
import { applyToPoint as
|
|
6498
|
+
import { applyToPoint as applyToPoint38 } from "transformation-matrix";
|
|
6215
6499
|
var PAD_COLOR = "rgb(210, 210, 210)";
|
|
6216
6500
|
var HOLE_COLOR3 = "rgb(190, 190, 190)";
|
|
6217
6501
|
function createSvgObjectsFromAssemblyPlatedHole(hole, ctx) {
|
|
6218
6502
|
const { transform } = ctx;
|
|
6219
|
-
const [x, y] =
|
|
6503
|
+
const [x, y] = applyToPoint38(transform, [hole.x, hole.y]);
|
|
6220
6504
|
if (hole.shape === "pill") {
|
|
6221
6505
|
const scaledOuterWidth = hole.outer_width * Math.abs(transform.a);
|
|
6222
6506
|
const scaledOuterHeight = hole.outer_height * Math.abs(transform.a);
|
|
@@ -6311,7 +6595,7 @@ function createSvgObjectsFromAssemblyPlatedHole(hole, ctx) {
|
|
|
6311
6595
|
const scaledRectPadHeight = circularHole.rect_pad_height * Math.abs(transform.a);
|
|
6312
6596
|
const scaledRectBorderRadius = (circularHole.rect_border_radius ?? 0) * Math.abs(transform.a);
|
|
6313
6597
|
const holeRadius = scaledHoleDiameter / 2;
|
|
6314
|
-
const [holeCx, holeCy] =
|
|
6598
|
+
const [holeCx, holeCy] = applyToPoint38(transform, [
|
|
6315
6599
|
circularHole.x + circularHole.hole_offset_x,
|
|
6316
6600
|
circularHole.y + circularHole.hole_offset_y
|
|
6317
6601
|
]);
|
|
@@ -6369,7 +6653,7 @@ function createSvgObjectsFromAssemblyPlatedHole(hole, ctx) {
|
|
|
6369
6653
|
const pillHoleWithOffsets = pillHole;
|
|
6370
6654
|
const holeOffsetX = pillHoleWithOffsets.hole_offset_x ?? 0;
|
|
6371
6655
|
const holeOffsetY = pillHoleWithOffsets.hole_offset_y ?? 0;
|
|
6372
|
-
const [holeCenterX, holeCenterY] =
|
|
6656
|
+
const [holeCenterX, holeCenterY] = applyToPoint38(transform, [
|
|
6373
6657
|
pillHole.x + holeOffsetX,
|
|
6374
6658
|
pillHole.y + holeOffsetY
|
|
6375
6659
|
]);
|
|
@@ -6431,7 +6715,7 @@ function createSvgObjectsFromAssemblyPlatedHole(hole, ctx) {
|
|
|
6431
6715
|
const rotatedHoleWithOffsets = rotatedHole;
|
|
6432
6716
|
const holeOffsetX = rotatedHoleWithOffsets.hole_offset_x ?? 0;
|
|
6433
6717
|
const holeOffsetY = rotatedHoleWithOffsets.hole_offset_y ?? 0;
|
|
6434
|
-
const [holeCenterX, holeCenterY] =
|
|
6718
|
+
const [holeCenterX, holeCenterY] = applyToPoint38(transform, [
|
|
6435
6719
|
rotatedHole.x + holeOffsetX,
|
|
6436
6720
|
rotatedHole.y + holeOffsetY
|
|
6437
6721
|
]);
|
|
@@ -6487,14 +6771,14 @@ function createSvgObjectsFromAssemblyPlatedHole(hole, ctx) {
|
|
|
6487
6771
|
}
|
|
6488
6772
|
|
|
6489
6773
|
// lib/assembly/svg-object-fns/create-svg-objects-from-assembly-smt-pad.ts
|
|
6490
|
-
import { applyToPoint as
|
|
6774
|
+
import { applyToPoint as applyToPoint39 } from "transformation-matrix";
|
|
6491
6775
|
var PAD_COLOR2 = "rgb(210, 210, 210)";
|
|
6492
6776
|
function createSvgObjectsFromAssemblySmtPad(pad, ctx) {
|
|
6493
6777
|
const { transform } = ctx;
|
|
6494
6778
|
if (pad.shape === "rect" || pad.shape === "rotated_rect") {
|
|
6495
6779
|
const width = pad.width * Math.abs(transform.a);
|
|
6496
6780
|
const height = pad.height * Math.abs(transform.d);
|
|
6497
|
-
const [x, y] =
|
|
6781
|
+
const [x, y] = applyToPoint39(transform, [pad.x, pad.y]);
|
|
6498
6782
|
const scaledBorderRadius = (pad.rect_border_radius ?? 0) * Math.abs(transform.a);
|
|
6499
6783
|
if (pad.shape === "rotated_rect" && pad.ccw_rotation) {
|
|
6500
6784
|
return [
|
|
@@ -6546,7 +6830,7 @@ function createSvgObjectsFromAssemblySmtPad(pad, ctx) {
|
|
|
6546
6830
|
const width = pad.width * Math.abs(transform.a);
|
|
6547
6831
|
const height = pad.height * Math.abs(transform.d);
|
|
6548
6832
|
const radius = pad.radius * Math.abs(transform.a);
|
|
6549
|
-
const [x, y] =
|
|
6833
|
+
const [x, y] = applyToPoint39(transform, [pad.x, pad.y]);
|
|
6550
6834
|
return [
|
|
6551
6835
|
{
|
|
6552
6836
|
name: "rect",
|
|
@@ -6569,7 +6853,7 @@ function createSvgObjectsFromAssemblySmtPad(pad, ctx) {
|
|
|
6569
6853
|
}
|
|
6570
6854
|
if (pad.shape === "circle") {
|
|
6571
6855
|
const radius = pad.radius * Math.abs(transform.a);
|
|
6572
|
-
const [x, y] =
|
|
6856
|
+
const [x, y] = applyToPoint39(transform, [pad.x, pad.y]);
|
|
6573
6857
|
return [
|
|
6574
6858
|
{
|
|
6575
6859
|
name: "circle",
|
|
@@ -6589,7 +6873,7 @@ function createSvgObjectsFromAssemblySmtPad(pad, ctx) {
|
|
|
6589
6873
|
}
|
|
6590
6874
|
if (pad.shape === "polygon") {
|
|
6591
6875
|
const points = (pad.points ?? []).map(
|
|
6592
|
-
(point) =>
|
|
6876
|
+
(point) => applyToPoint39(transform, [point.x, point.y])
|
|
6593
6877
|
);
|
|
6594
6878
|
return [
|
|
6595
6879
|
{
|
|
@@ -6643,12 +6927,12 @@ function convertCircuitJsonToAssemblySvg(soup, options) {
|
|
|
6643
6927
|
const scaleFactor = Math.min(scaleX, scaleY);
|
|
6644
6928
|
const offsetX = (svgWidth - circuitWidth * scaleFactor) / 2;
|
|
6645
6929
|
const offsetY = (svgHeight - circuitHeight * scaleFactor) / 2;
|
|
6646
|
-
const transform =
|
|
6647
|
-
|
|
6930
|
+
const transform = compose7(
|
|
6931
|
+
translate7(
|
|
6648
6932
|
offsetX - minX * scaleFactor + padding * scaleFactor,
|
|
6649
6933
|
svgHeight - offsetY + minY * scaleFactor - padding * scaleFactor
|
|
6650
6934
|
),
|
|
6651
|
-
|
|
6935
|
+
scale4(scaleFactor, -scaleFactor)
|
|
6652
6936
|
// Flip in y-direction
|
|
6653
6937
|
);
|
|
6654
6938
|
const ctx = { transform };
|
|
@@ -6773,8 +7057,8 @@ function createSvgObjects2(elm, ctx, soup) {
|
|
|
6773
7057
|
}
|
|
6774
7058
|
}
|
|
6775
7059
|
function createSvgObjectFromAssemblyBoundary(transform, minX, minY, maxX, maxY) {
|
|
6776
|
-
const [x1, y1] =
|
|
6777
|
-
const [x2, y2] =
|
|
7060
|
+
const [x1, y1] = applyToPoint40(transform, [minX, minY]);
|
|
7061
|
+
const [x2, y2] = applyToPoint40(transform, [maxX, maxY]);
|
|
6778
7062
|
const width = Math.abs(x2 - x1);
|
|
6779
7063
|
const height = Math.abs(y2 - y1);
|
|
6780
7064
|
const x = Math.min(x1, x2);
|
|
@@ -6797,13 +7081,13 @@ function createSvgObjectFromAssemblyBoundary(transform, minX, minY, maxX, maxY)
|
|
|
6797
7081
|
// lib/pinout/convert-circuit-json-to-pinout-svg.ts
|
|
6798
7082
|
import { stringify as stringify3 } from "svgson";
|
|
6799
7083
|
import {
|
|
6800
|
-
compose as
|
|
7084
|
+
compose as compose8,
|
|
6801
7085
|
scale as matrixScale,
|
|
6802
|
-
translate as
|
|
7086
|
+
translate as translate8
|
|
6803
7087
|
} from "transformation-matrix";
|
|
6804
7088
|
|
|
6805
7089
|
// lib/pinout/svg-object-fns/create-svg-objects-from-pinout-board.ts
|
|
6806
|
-
import { applyToPoint as
|
|
7090
|
+
import { applyToPoint as applyToPoint41 } from "transformation-matrix";
|
|
6807
7091
|
import { su as su4 } from "@tscircuit/circuit-json-util";
|
|
6808
7092
|
var BOARD_FILL_COLOR = "rgb(26, 115, 143)";
|
|
6809
7093
|
var BOARD_STROKE_COLOR = "rgba(0,0,0,0.9)";
|
|
@@ -6817,25 +7101,25 @@ function createSvgObjectsFromPinoutBoard(pcbBoard, ctx) {
|
|
|
6817
7101
|
let path;
|
|
6818
7102
|
if (outline && Array.isArray(outline) && outline.length >= 3) {
|
|
6819
7103
|
path = outline.map((point, index) => {
|
|
6820
|
-
const [x, y] =
|
|
7104
|
+
const [x, y] = applyToPoint41(transform, [point.x, point.y]);
|
|
6821
7105
|
return index === 0 ? `M ${x} ${y}` : `L ${x} ${y}`;
|
|
6822
7106
|
}).join(" ");
|
|
6823
7107
|
} else {
|
|
6824
7108
|
const halfWidth = width / 2;
|
|
6825
7109
|
const halfHeight = height / 2;
|
|
6826
|
-
const topLeft =
|
|
7110
|
+
const topLeft = applyToPoint41(transform, [
|
|
6827
7111
|
center.x - halfWidth,
|
|
6828
7112
|
center.y - halfHeight
|
|
6829
7113
|
]);
|
|
6830
|
-
const topRight =
|
|
7114
|
+
const topRight = applyToPoint41(transform, [
|
|
6831
7115
|
center.x + halfWidth,
|
|
6832
7116
|
center.y - halfHeight
|
|
6833
7117
|
]);
|
|
6834
|
-
const bottomRight =
|
|
7118
|
+
const bottomRight = applyToPoint41(transform, [
|
|
6835
7119
|
center.x + halfWidth,
|
|
6836
7120
|
center.y + halfHeight
|
|
6837
7121
|
]);
|
|
6838
|
-
const bottomLeft =
|
|
7122
|
+
const bottomLeft = applyToPoint41(transform, [
|
|
6839
7123
|
center.x - halfWidth,
|
|
6840
7124
|
center.y + halfHeight
|
|
6841
7125
|
]);
|
|
@@ -6853,10 +7137,10 @@ function createSvgObjectsFromPinoutBoard(pcbBoard, ctx) {
|
|
|
6853
7137
|
const halfWidth = width2 / 2;
|
|
6854
7138
|
const halfHeight = height2 / 2;
|
|
6855
7139
|
const [tl, tr, br, bl] = [
|
|
6856
|
-
|
|
6857
|
-
|
|
6858
|
-
|
|
6859
|
-
|
|
7140
|
+
applyToPoint41(transform, [x - halfWidth, y - halfHeight]),
|
|
7141
|
+
applyToPoint41(transform, [x + halfWidth, y - halfHeight]),
|
|
7142
|
+
applyToPoint41(transform, [x + halfWidth, y + halfHeight]),
|
|
7143
|
+
applyToPoint41(transform, [x - halfWidth, y + halfHeight])
|
|
6860
7144
|
];
|
|
6861
7145
|
path += ` M ${tl[0]} ${tl[1]} L ${tr[0]} ${tr[1]} L ${br[0]} ${br[1]} L ${bl[0]} ${bl[1]} Z`;
|
|
6862
7146
|
} else if (cutout.shape === "circle") {
|
|
@@ -6906,7 +7190,7 @@ function createSvgObjectsFromPinoutBoard(pcbBoard, ctx) {
|
|
|
6906
7190
|
|
|
6907
7191
|
// lib/pinout/svg-object-fns/create-svg-objects-from-pinout-component.ts
|
|
6908
7192
|
import { su as su5 } from "@tscircuit/circuit-json-util";
|
|
6909
|
-
import { applyToPoint as
|
|
7193
|
+
import { applyToPoint as applyToPoint42 } from "transformation-matrix";
|
|
6910
7194
|
var COMPONENT_FILL_COLOR = "rgba(120, 120, 120, 0.6)";
|
|
6911
7195
|
var COMPONENT_LABEL_COLOR = "rgba(255, 255, 255, 0.9)";
|
|
6912
7196
|
function createSvgObjectsFromPinoutComponent(elm, ctx) {
|
|
@@ -6916,7 +7200,7 @@ function createSvgObjectsFromPinoutComponent(elm, ctx) {
|
|
|
6916
7200
|
if (!center || typeof width !== "number" || typeof height !== "number" || width === 0 || height === 0) {
|
|
6917
7201
|
return [];
|
|
6918
7202
|
}
|
|
6919
|
-
const [x, y] =
|
|
7203
|
+
const [x, y] = applyToPoint42(transform, [center.x, center.y]);
|
|
6920
7204
|
const scaledWidth = width * Math.abs(transform.a);
|
|
6921
7205
|
const scaledHeight = height * Math.abs(transform.d);
|
|
6922
7206
|
const transformStr = `translate(${x}, ${y})`;
|
|
@@ -6977,11 +7261,11 @@ function createSvgObjectsFromPinoutComponent(elm, ctx) {
|
|
|
6977
7261
|
}
|
|
6978
7262
|
|
|
6979
7263
|
// lib/pinout/svg-object-fns/create-svg-objects-from-pinout-hole.ts
|
|
6980
|
-
import { applyToPoint as
|
|
7264
|
+
import { applyToPoint as applyToPoint43 } from "transformation-matrix";
|
|
6981
7265
|
var HOLE_COLOR4 = "rgb(50, 50, 50)";
|
|
6982
7266
|
function createSvgObjectsFromPinoutHole(hole, ctx) {
|
|
6983
7267
|
const { transform } = ctx;
|
|
6984
|
-
const [x, y] =
|
|
7268
|
+
const [x, y] = applyToPoint43(transform, [hole.x, hole.y]);
|
|
6985
7269
|
if (hole.hole_shape === "circle" || hole.hole_shape === "square") {
|
|
6986
7270
|
const scaledDiameter = hole.hole_diameter * Math.abs(transform.a);
|
|
6987
7271
|
const radius = scaledDiameter / 2;
|
|
@@ -7045,12 +7329,12 @@ function createSvgObjectsFromPinoutHole(hole, ctx) {
|
|
|
7045
7329
|
}
|
|
7046
7330
|
|
|
7047
7331
|
// lib/pinout/svg-object-fns/create-svg-objects-from-pinout-plated-hole.ts
|
|
7048
|
-
import { applyToPoint as
|
|
7332
|
+
import { applyToPoint as applyToPoint44 } from "transformation-matrix";
|
|
7049
7333
|
var PAD_COLOR3 = "rgb(218, 165, 32)";
|
|
7050
7334
|
var HOLE_COLOR5 = "rgb(40, 40, 40)";
|
|
7051
7335
|
function createSvgObjectsFromPinoutPlatedHole(hole, ctx) {
|
|
7052
7336
|
const { transform } = ctx;
|
|
7053
|
-
const [x, y] =
|
|
7337
|
+
const [x, y] = applyToPoint44(transform, [hole.x, hole.y]);
|
|
7054
7338
|
if (hole.shape === "pill") {
|
|
7055
7339
|
const scaledOuterWidth = hole.outer_width * Math.abs(transform.a);
|
|
7056
7340
|
const scaledOuterHeight = hole.outer_height * Math.abs(transform.a);
|
|
@@ -7285,14 +7569,14 @@ function createSvgObjectsFromPinoutPlatedHole(hole, ctx) {
|
|
|
7285
7569
|
}
|
|
7286
7570
|
|
|
7287
7571
|
// lib/pinout/svg-object-fns/create-svg-objects-from-pinout-smt-pad.ts
|
|
7288
|
-
import { applyToPoint as
|
|
7572
|
+
import { applyToPoint as applyToPoint45 } from "transformation-matrix";
|
|
7289
7573
|
var PAD_COLOR4 = "rgb(218, 165, 32)";
|
|
7290
7574
|
function createSvgObjectsFromPinoutSmtPad(pad, ctx) {
|
|
7291
7575
|
const { transform } = ctx;
|
|
7292
7576
|
if (pad.shape === "rect" || pad.shape === "rotated_rect") {
|
|
7293
7577
|
const width = pad.width * Math.abs(transform.a);
|
|
7294
7578
|
const height = pad.height * Math.abs(transform.d);
|
|
7295
|
-
const [x, y] =
|
|
7579
|
+
const [x, y] = applyToPoint45(transform, [pad.x, pad.y]);
|
|
7296
7580
|
if (pad.shape === "rotated_rect" && pad.ccw_rotation) {
|
|
7297
7581
|
return [
|
|
7298
7582
|
{
|
|
@@ -7335,7 +7619,7 @@ function createSvgObjectsFromPinoutSmtPad(pad, ctx) {
|
|
|
7335
7619
|
const width = pad.width * Math.abs(transform.a);
|
|
7336
7620
|
const height = pad.height * Math.abs(transform.d);
|
|
7337
7621
|
const radius = pad.radius * Math.abs(transform.a);
|
|
7338
|
-
const [x, y] =
|
|
7622
|
+
const [x, y] = applyToPoint45(transform, [pad.x, pad.y]);
|
|
7339
7623
|
return [
|
|
7340
7624
|
{
|
|
7341
7625
|
name: "rect",
|
|
@@ -7358,7 +7642,7 @@ function createSvgObjectsFromPinoutSmtPad(pad, ctx) {
|
|
|
7358
7642
|
}
|
|
7359
7643
|
if (pad.shape === "circle") {
|
|
7360
7644
|
const radius = pad.radius * Math.abs(transform.a);
|
|
7361
|
-
const [x, y] =
|
|
7645
|
+
const [x, y] = applyToPoint45(transform, [pad.x, pad.y]);
|
|
7362
7646
|
return [
|
|
7363
7647
|
{
|
|
7364
7648
|
name: "circle",
|
|
@@ -7378,7 +7662,7 @@ function createSvgObjectsFromPinoutSmtPad(pad, ctx) {
|
|
|
7378
7662
|
}
|
|
7379
7663
|
if (pad.shape === "polygon") {
|
|
7380
7664
|
const points = (pad.points ?? []).map(
|
|
7381
|
-
(point) =>
|
|
7665
|
+
(point) => applyToPoint45(transform, [point.x, point.y])
|
|
7382
7666
|
);
|
|
7383
7667
|
return [
|
|
7384
7668
|
{
|
|
@@ -7399,7 +7683,7 @@ function createSvgObjectsFromPinoutSmtPad(pad, ctx) {
|
|
|
7399
7683
|
}
|
|
7400
7684
|
|
|
7401
7685
|
// lib/pinout/svg-object-fns/create-svg-objects-from-pinout-port.ts
|
|
7402
|
-
import { applyToPoint as
|
|
7686
|
+
import { applyToPoint as applyToPoint46 } from "transformation-matrix";
|
|
7403
7687
|
import { calculateElbow } from "calculate-elbow";
|
|
7404
7688
|
|
|
7405
7689
|
// lib/pinout/svg-object-fns/pinout-label-box.ts
|
|
@@ -7476,7 +7760,7 @@ function createSvgObjectsFromPinoutPort(pcb_port, ctx) {
|
|
|
7476
7760
|
const label_info = ctx.label_positions.get(pcb_port.pcb_port_id);
|
|
7477
7761
|
if (!label_info) return [];
|
|
7478
7762
|
const { text: label, aliases, elbow_end, label_pos, edge } = label_info;
|
|
7479
|
-
const [port_x, port_y] =
|
|
7763
|
+
const [port_x, port_y] = applyToPoint46(ctx.transform, [pcb_port.x, pcb_port.y]);
|
|
7480
7764
|
const start_facing_direction = edge === "left" ? "x-" : edge === "right" ? "x+" : edge === "top" ? "y-" : "y+";
|
|
7481
7765
|
const end_facing_direction = edge === "left" ? "x+" : edge === "right" ? "x-" : edge === "top" ? "y+" : "y-";
|
|
7482
7766
|
const elbow_path = calculateElbow(
|
|
@@ -7617,7 +7901,7 @@ function createSvgObjectsFromPinoutPort(pcb_port, ctx) {
|
|
|
7617
7901
|
}
|
|
7618
7902
|
|
|
7619
7903
|
// lib/pinout/calculate-label-positions.ts
|
|
7620
|
-
import { applyToPoint as
|
|
7904
|
+
import { applyToPoint as applyToPoint47 } from "transformation-matrix";
|
|
7621
7905
|
|
|
7622
7906
|
// lib/pinout/constants.ts
|
|
7623
7907
|
var LABEL_RECT_HEIGHT_BASE_MM = 1.6;
|
|
@@ -7655,7 +7939,7 @@ function calculateVerticalEdgeLabels(edge, pinout_labels, {
|
|
|
7655
7939
|
);
|
|
7656
7940
|
const mapToEdgePort = (pinout_label) => ({
|
|
7657
7941
|
pcb_port: pinout_label.pcb_port,
|
|
7658
|
-
y:
|
|
7942
|
+
y: applyToPoint47(transform, [
|
|
7659
7943
|
pinout_label.pcb_port.x,
|
|
7660
7944
|
pinout_label.pcb_port.y
|
|
7661
7945
|
])[1],
|
|
@@ -7670,7 +7954,7 @@ function calculateVerticalEdgeLabels(edge, pinout_labels, {
|
|
|
7670
7954
|
} else {
|
|
7671
7955
|
edge_ports = pinout_labels.map((pinout_label) => ({
|
|
7672
7956
|
pcb_port: pinout_label.pcb_port,
|
|
7673
|
-
y:
|
|
7957
|
+
y: applyToPoint47(transform, [
|
|
7674
7958
|
pinout_label.pcb_port.x,
|
|
7675
7959
|
pinout_label.pcb_port.y
|
|
7676
7960
|
])[1],
|
|
@@ -7678,7 +7962,7 @@ function calculateVerticalEdgeLabels(edge, pinout_labels, {
|
|
|
7678
7962
|
})).sort((a, b) => a.y - b.y);
|
|
7679
7963
|
}
|
|
7680
7964
|
if (edge_ports.length === 0) return;
|
|
7681
|
-
const board_edge_x =
|
|
7965
|
+
const board_edge_x = applyToPoint47(transform, [
|
|
7682
7966
|
edge === "left" ? board_bounds.minX : board_bounds.maxX,
|
|
7683
7967
|
0
|
|
7684
7968
|
])[0];
|
|
@@ -7998,8 +8282,8 @@ function convertCircuitJsonToPinoutSvg(soup, options) {
|
|
|
7998
8282
|
const pxPerMm = Math.min(pxPerMmX, pxPerMmY);
|
|
7999
8283
|
const offsetX = (svgWidth - circuitWidth * pxPerMm) / 2;
|
|
8000
8284
|
const offsetY = (svgHeight - circuitHeight * pxPerMm) / 2;
|
|
8001
|
-
const transform =
|
|
8002
|
-
|
|
8285
|
+
const transform = compose8(
|
|
8286
|
+
translate8(
|
|
8003
8287
|
offsetX - expandedMinX * pxPerMm + paddingMm * pxPerMm,
|
|
8004
8288
|
svgHeight - offsetY + minY * pxPerMm - paddingMm * pxPerMm
|
|
8005
8289
|
),
|
|
@@ -8100,14 +8384,14 @@ import {
|
|
|
8100
8384
|
} from "transformation-matrix";
|
|
8101
8385
|
|
|
8102
8386
|
// lib/sch/draw-schematic-grid.ts
|
|
8103
|
-
import { applyToPoint as
|
|
8387
|
+
import { applyToPoint as applyToPoint48 } from "transformation-matrix";
|
|
8104
8388
|
function drawSchematicGrid(params) {
|
|
8105
8389
|
const { minX, minY, maxX, maxY } = params.bounds;
|
|
8106
8390
|
const cellSize = params.cellSize ?? 1;
|
|
8107
8391
|
const labelCells = params.labelCells ?? false;
|
|
8108
8392
|
const gridLines = [];
|
|
8109
8393
|
const transformPoint = (x, y) => {
|
|
8110
|
-
const [transformedX, transformedY] =
|
|
8394
|
+
const [transformedX, transformedY] = applyToPoint48(params.transform, [x, y]);
|
|
8111
8395
|
return { x: transformedX, y: transformedY };
|
|
8112
8396
|
};
|
|
8113
8397
|
for (let x = Math.floor(minX); x <= Math.ceil(maxX); x += cellSize) {
|
|
@@ -8188,15 +8472,15 @@ function drawSchematicGrid(params) {
|
|
|
8188
8472
|
}
|
|
8189
8473
|
|
|
8190
8474
|
// lib/sch/draw-schematic-labeled-points.ts
|
|
8191
|
-
import { applyToPoint as
|
|
8475
|
+
import { applyToPoint as applyToPoint49 } from "transformation-matrix";
|
|
8192
8476
|
function drawSchematicLabeledPoints(params) {
|
|
8193
8477
|
const { points, transform } = params;
|
|
8194
8478
|
const labeledPointsGroup = [];
|
|
8195
8479
|
for (const point of points) {
|
|
8196
|
-
const [x1, y1] =
|
|
8197
|
-
const [x2, y2] =
|
|
8198
|
-
const [x3, y3] =
|
|
8199
|
-
const [x4, y4] =
|
|
8480
|
+
const [x1, y1] = applyToPoint49(transform, [point.x - 0.1, point.y - 0.1]);
|
|
8481
|
+
const [x2, y2] = applyToPoint49(transform, [point.x + 0.1, point.y + 0.1]);
|
|
8482
|
+
const [x3, y3] = applyToPoint49(transform, [point.x - 0.1, point.y + 0.1]);
|
|
8483
|
+
const [x4, y4] = applyToPoint49(transform, [point.x + 0.1, point.y - 0.1]);
|
|
8200
8484
|
labeledPointsGroup.push({
|
|
8201
8485
|
name: "path",
|
|
8202
8486
|
type: "element",
|
|
@@ -8207,7 +8491,7 @@ function drawSchematicLabeledPoints(params) {
|
|
|
8207
8491
|
"stroke-opacity": "0.7"
|
|
8208
8492
|
}
|
|
8209
8493
|
});
|
|
8210
|
-
const [labelX, labelY] =
|
|
8494
|
+
const [labelX, labelY] = applyToPoint49(transform, [
|
|
8211
8495
|
point.x + 0.15,
|
|
8212
8496
|
point.y - 0.15
|
|
8213
8497
|
]);
|
|
@@ -9301,8 +9585,8 @@ import { su as su7 } from "@tscircuit/circuit-json-util";
|
|
|
9301
9585
|
import { symbols } from "schematic-symbols";
|
|
9302
9586
|
import "svgson";
|
|
9303
9587
|
import {
|
|
9304
|
-
applyToPoint as
|
|
9305
|
-
compose as
|
|
9588
|
+
applyToPoint as applyToPoint51,
|
|
9589
|
+
compose as compose10
|
|
9306
9590
|
} from "transformation-matrix";
|
|
9307
9591
|
|
|
9308
9592
|
// lib/utils/get-sch-stroke-size.ts
|
|
@@ -9372,26 +9656,26 @@ var matchSchPortsToSymbolPorts = ({
|
|
|
9372
9656
|
};
|
|
9373
9657
|
|
|
9374
9658
|
// lib/utils/point-pairs-to-matrix.ts
|
|
9375
|
-
import { compose as
|
|
9659
|
+
import { compose as compose9, scale as scale5, translate as translate9 } from "transformation-matrix";
|
|
9376
9660
|
function pointPairsToMatrix(a1, a2, b1, b2) {
|
|
9377
9661
|
const tx = a2.x - a1.x;
|
|
9378
9662
|
const ty = a2.y - a1.y;
|
|
9379
9663
|
const originalDistance = Math.sqrt((b1.x - a1.x) ** 2 + (b1.y - a1.y) ** 2);
|
|
9380
9664
|
const transformedDistance = Math.sqrt((b2.x - a2.x) ** 2 + (b2.y - a2.y) ** 2);
|
|
9381
9665
|
const a = transformedDistance / originalDistance;
|
|
9382
|
-
const translateMatrix =
|
|
9383
|
-
const scaleMatrix =
|
|
9384
|
-
return
|
|
9666
|
+
const translateMatrix = translate9(tx, ty);
|
|
9667
|
+
const scaleMatrix = scale5(a, a);
|
|
9668
|
+
return compose9(translateMatrix, scaleMatrix);
|
|
9385
9669
|
}
|
|
9386
9670
|
|
|
9387
9671
|
// lib/sch/svg-object-fns/create-svg-error-text.ts
|
|
9388
|
-
import { applyToPoint as
|
|
9672
|
+
import { applyToPoint as applyToPoint50 } from "transformation-matrix";
|
|
9389
9673
|
var createSvgSchErrorText = ({
|
|
9390
9674
|
text,
|
|
9391
9675
|
realCenter,
|
|
9392
9676
|
realToScreenTransform
|
|
9393
9677
|
}) => {
|
|
9394
|
-
const screenCenter =
|
|
9678
|
+
const screenCenter = applyToPoint50(realToScreenTransform, realCenter);
|
|
9395
9679
|
return {
|
|
9396
9680
|
type: "element",
|
|
9397
9681
|
name: "text",
|
|
@@ -9500,12 +9784,12 @@ var createSvgObjectsFromSchematicComponentWithSymbol = ({
|
|
|
9500
9784
|
minY: Math.min(...paths.flatMap((p) => p.points.map((pt) => pt.y))),
|
|
9501
9785
|
maxY: Math.max(...paths.flatMap((p) => p.points.map((pt) => pt.y)))
|
|
9502
9786
|
};
|
|
9503
|
-
const [screenMinX, screenMinY] =
|
|
9504
|
-
|
|
9787
|
+
const [screenMinX, screenMinY] = applyToPoint51(
|
|
9788
|
+
compose10(realToScreenTransform, transformFromSymbolToReal),
|
|
9505
9789
|
[bounds.minX, bounds.minY]
|
|
9506
9790
|
);
|
|
9507
|
-
const [screenMaxX, screenMaxY] =
|
|
9508
|
-
|
|
9791
|
+
const [screenMaxX, screenMaxY] = applyToPoint51(
|
|
9792
|
+
compose10(realToScreenTransform, transformFromSymbolToReal),
|
|
9509
9793
|
[bounds.maxX, bounds.maxY]
|
|
9510
9794
|
);
|
|
9511
9795
|
const rectHeight = Math.abs(screenMaxY - screenMinY);
|
|
@@ -9533,8 +9817,8 @@ var createSvgObjectsFromSchematicComponentWithSymbol = ({
|
|
|
9533
9817
|
name: "path",
|
|
9534
9818
|
attributes: {
|
|
9535
9819
|
d: points.map((p, i) => {
|
|
9536
|
-
const [x, y] =
|
|
9537
|
-
|
|
9820
|
+
const [x, y] = applyToPoint51(
|
|
9821
|
+
compose10(realToScreenTransform, transformFromSymbolToReal),
|
|
9538
9822
|
[p.x, p.y]
|
|
9539
9823
|
);
|
|
9540
9824
|
return `${i === 0 ? "M" : "L"} ${x} ${y}`;
|
|
@@ -9549,8 +9833,8 @@ var createSvgObjectsFromSchematicComponentWithSymbol = ({
|
|
|
9549
9833
|
});
|
|
9550
9834
|
}
|
|
9551
9835
|
for (const text of texts) {
|
|
9552
|
-
const screenTextPos =
|
|
9553
|
-
|
|
9836
|
+
const screenTextPos = applyToPoint51(
|
|
9837
|
+
compose10(realToScreenTransform, transformFromSymbolToReal),
|
|
9554
9838
|
text
|
|
9555
9839
|
);
|
|
9556
9840
|
let textValue = "";
|
|
@@ -9601,11 +9885,11 @@ var createSvgObjectsFromSchematicComponentWithSymbol = ({
|
|
|
9601
9885
|
});
|
|
9602
9886
|
}
|
|
9603
9887
|
for (const box of boxes) {
|
|
9604
|
-
const screenBoxPos =
|
|
9605
|
-
|
|
9888
|
+
const screenBoxPos = applyToPoint51(
|
|
9889
|
+
compose10(realToScreenTransform, transformFromSymbolToReal),
|
|
9606
9890
|
box
|
|
9607
9891
|
);
|
|
9608
|
-
const symbolToScreenScale =
|
|
9892
|
+
const symbolToScreenScale = compose10(
|
|
9609
9893
|
realToScreenTransform,
|
|
9610
9894
|
transformFromSymbolToReal
|
|
9611
9895
|
).a;
|
|
@@ -9625,8 +9909,8 @@ var createSvgObjectsFromSchematicComponentWithSymbol = ({
|
|
|
9625
9909
|
}
|
|
9626
9910
|
for (const port of symbol.ports) {
|
|
9627
9911
|
if (connectedSymbolPorts.has(port)) continue;
|
|
9628
|
-
const screenPortPos =
|
|
9629
|
-
|
|
9912
|
+
const screenPortPos = applyToPoint51(
|
|
9913
|
+
compose10(realToScreenTransform, transformFromSymbolToReal),
|
|
9630
9914
|
port
|
|
9631
9915
|
);
|
|
9632
9916
|
svgObjects.push({
|
|
@@ -9645,8 +9929,8 @@ var createSvgObjectsFromSchematicComponentWithSymbol = ({
|
|
|
9645
9929
|
});
|
|
9646
9930
|
}
|
|
9647
9931
|
for (const circle of circles) {
|
|
9648
|
-
const screenCirclePos =
|
|
9649
|
-
|
|
9932
|
+
const screenCirclePos = applyToPoint51(
|
|
9933
|
+
compose10(realToScreenTransform, transformFromSymbolToReal),
|
|
9650
9934
|
circle
|
|
9651
9935
|
);
|
|
9652
9936
|
const screenRadius = Math.abs(circle.radius * realToScreenTransform.a);
|
|
@@ -9672,14 +9956,14 @@ var createSvgObjectsFromSchematicComponentWithSymbol = ({
|
|
|
9672
9956
|
import { su as su10 } from "@tscircuit/circuit-json-util";
|
|
9673
9957
|
import "schematic-symbols";
|
|
9674
9958
|
import "svgson";
|
|
9675
|
-
import { applyToPoint as
|
|
9959
|
+
import { applyToPoint as applyToPoint57 } from "transformation-matrix";
|
|
9676
9960
|
|
|
9677
9961
|
// lib/sch/svg-object-fns/create-svg-objects-from-sch-port-on-box.ts
|
|
9678
9962
|
import "transformation-matrix";
|
|
9679
9963
|
import "@tscircuit/circuit-json-util";
|
|
9680
9964
|
|
|
9681
9965
|
// lib/sch/svg-object-fns/create-svg-objects-for-sch-port-box-line.ts
|
|
9682
|
-
import { applyToPoint as
|
|
9966
|
+
import { applyToPoint as applyToPoint52 } from "transformation-matrix";
|
|
9683
9967
|
import { su as su8 } from "@tscircuit/circuit-json-util";
|
|
9684
9968
|
var PIN_CIRCLE_RADIUS_MM = 0.02;
|
|
9685
9969
|
var createArrow = (tip, angle, size, color, strokeWidth) => {
|
|
@@ -9732,8 +10016,8 @@ var createSvgObjectsForSchPortBoxLine = ({
|
|
|
9732
10016
|
realEdgePos.y += realPinLineLength;
|
|
9733
10017
|
break;
|
|
9734
10018
|
}
|
|
9735
|
-
const screenSchPortPos =
|
|
9736
|
-
const screenRealEdgePos =
|
|
10019
|
+
const screenSchPortPos = applyToPoint52(transform, schPort.center);
|
|
10020
|
+
const screenRealEdgePos = applyToPoint52(transform, realEdgePos);
|
|
9737
10021
|
const isConnected = isSourcePortConnected(circuitJson, schPort.source_port_id);
|
|
9738
10022
|
const realLineEnd = { ...schPort.center };
|
|
9739
10023
|
if (!isConnected) {
|
|
@@ -9752,7 +10036,7 @@ var createSvgObjectsForSchPortBoxLine = ({
|
|
|
9752
10036
|
break;
|
|
9753
10037
|
}
|
|
9754
10038
|
}
|
|
9755
|
-
const screenLineEnd =
|
|
10039
|
+
const screenLineEnd = applyToPoint52(transform, realLineEnd);
|
|
9756
10040
|
svgObjects.push({
|
|
9757
10041
|
name: "line",
|
|
9758
10042
|
type: "element",
|
|
@@ -9873,7 +10157,7 @@ var createSvgObjectsForSchPortBoxLine = ({
|
|
|
9873
10157
|
};
|
|
9874
10158
|
|
|
9875
10159
|
// lib/sch/svg-object-fns/create-svg-objects-for-sch-port-pin-number-text.ts
|
|
9876
|
-
import { applyToPoint as
|
|
10160
|
+
import { applyToPoint as applyToPoint53 } from "transformation-matrix";
|
|
9877
10161
|
var createSvgObjectsForSchPortPinNumberText = (params) => {
|
|
9878
10162
|
const svgObjects = [];
|
|
9879
10163
|
const { schPort, schComponent, transform, circuitJson } = params;
|
|
@@ -9891,7 +10175,7 @@ var createSvgObjectsForSchPortPinNumberText = (params) => {
|
|
|
9891
10175
|
} else {
|
|
9892
10176
|
realPinNumberPos.y += 0.02;
|
|
9893
10177
|
}
|
|
9894
|
-
const screenPinNumberTextPos =
|
|
10178
|
+
const screenPinNumberTextPos = applyToPoint53(transform, realPinNumberPos);
|
|
9895
10179
|
svgObjects.push({
|
|
9896
10180
|
name: "text",
|
|
9897
10181
|
type: "element",
|
|
@@ -9921,7 +10205,7 @@ var createSvgObjectsForSchPortPinNumberText = (params) => {
|
|
|
9921
10205
|
};
|
|
9922
10206
|
|
|
9923
10207
|
// lib/sch/svg-object-fns/create-svg-objects-for-sch-port-pin-label.ts
|
|
9924
|
-
import { applyToPoint as
|
|
10208
|
+
import { applyToPoint as applyToPoint54 } from "transformation-matrix";
|
|
9925
10209
|
var LABEL_DIST_FROM_EDGE_MM = 0.1;
|
|
9926
10210
|
var createSvgObjectsForSchPortPinLabel = (params) => {
|
|
9927
10211
|
const svgObjects = [];
|
|
@@ -9935,7 +10219,7 @@ var createSvgObjectsForSchPortPinLabel = (params) => {
|
|
|
9935
10219
|
const realPinEdgeDistance = schPort.distance_from_component_edge ?? 0.4;
|
|
9936
10220
|
realPinNumberPos.x += vecToEdge.x * (realPinEdgeDistance + LABEL_DIST_FROM_EDGE_MM);
|
|
9937
10221
|
realPinNumberPos.y += vecToEdge.y * (realPinEdgeDistance + LABEL_DIST_FROM_EDGE_MM);
|
|
9938
|
-
const screenPinNumberTextPos =
|
|
10222
|
+
const screenPinNumberTextPos = applyToPoint54(transform, realPinNumberPos);
|
|
9939
10223
|
const label = schPort.display_pin_label ?? schComponent.port_labels?.[`${schPort.pin_number}`];
|
|
9940
10224
|
if (!label) return [];
|
|
9941
10225
|
const isNegated = label.startsWith("N_");
|
|
@@ -9983,13 +10267,13 @@ var createSvgObjectsFromSchPortOnBox = (params) => {
|
|
|
9983
10267
|
};
|
|
9984
10268
|
|
|
9985
10269
|
// lib/sch/svg-object-fns/create-svg-objects-for-sch-text.ts
|
|
9986
|
-
import { applyToPoint as
|
|
10270
|
+
import { applyToPoint as applyToPoint56 } from "transformation-matrix";
|
|
9987
10271
|
var createSvgSchText = ({
|
|
9988
10272
|
elm,
|
|
9989
10273
|
transform,
|
|
9990
10274
|
colorMap: colorMap2
|
|
9991
10275
|
}) => {
|
|
9992
|
-
const center =
|
|
10276
|
+
const center = applyToPoint56(transform, elm.position);
|
|
9993
10277
|
const textAnchorMap = {
|
|
9994
10278
|
center: "middle",
|
|
9995
10279
|
center_right: "end",
|
|
@@ -10073,11 +10357,11 @@ var createSvgObjectsFromSchematicComponentWithBox = ({
|
|
|
10073
10357
|
colorMap: colorMap2
|
|
10074
10358
|
}) => {
|
|
10075
10359
|
const svgObjects = [];
|
|
10076
|
-
const componentScreenTopLeft =
|
|
10360
|
+
const componentScreenTopLeft = applyToPoint57(transform, {
|
|
10077
10361
|
x: schComponent.center.x - schComponent.size.width / 2,
|
|
10078
10362
|
y: schComponent.center.y + schComponent.size.height / 2
|
|
10079
10363
|
});
|
|
10080
|
-
const componentScreenBottomRight =
|
|
10364
|
+
const componentScreenBottomRight = applyToPoint57(transform, {
|
|
10081
10365
|
x: schComponent.center.x + schComponent.size.width / 2,
|
|
10082
10366
|
y: schComponent.center.y - schComponent.size.height / 2
|
|
10083
10367
|
});
|
|
@@ -10163,13 +10447,13 @@ function createSvgObjectsFromSchematicComponent(params) {
|
|
|
10163
10447
|
}
|
|
10164
10448
|
|
|
10165
10449
|
// lib/sch/svg-object-fns/create-svg-objects-from-sch-voltage-probe.ts
|
|
10166
|
-
import { applyToPoint as
|
|
10450
|
+
import { applyToPoint as applyToPoint58 } from "transformation-matrix";
|
|
10167
10451
|
function createSvgObjectsFromSchVoltageProbe({
|
|
10168
10452
|
probe,
|
|
10169
10453
|
transform,
|
|
10170
10454
|
colorMap: colorMap2
|
|
10171
10455
|
}) {
|
|
10172
|
-
const [screenX, screenY] =
|
|
10456
|
+
const [screenX, screenY] = applyToPoint58(transform, [
|
|
10173
10457
|
probe.position.x,
|
|
10174
10458
|
probe.position.y
|
|
10175
10459
|
]);
|
|
@@ -10276,17 +10560,17 @@ function createSvgObjectsFromSchVoltageProbe({
|
|
|
10276
10560
|
}
|
|
10277
10561
|
|
|
10278
10562
|
// lib/sch/svg-object-fns/create-svg-objects-from-sch-debug-object.ts
|
|
10279
|
-
import { applyToPoint as
|
|
10563
|
+
import { applyToPoint as applyToPoint59 } from "transformation-matrix";
|
|
10280
10564
|
function createSvgObjectsFromSchDebugObject({
|
|
10281
10565
|
debugObject,
|
|
10282
10566
|
transform
|
|
10283
10567
|
}) {
|
|
10284
10568
|
if (debugObject.shape === "rect") {
|
|
10285
|
-
let [screenLeft, screenTop] =
|
|
10569
|
+
let [screenLeft, screenTop] = applyToPoint59(transform, [
|
|
10286
10570
|
debugObject.center.x - debugObject.size.width / 2,
|
|
10287
10571
|
debugObject.center.y - debugObject.size.height / 2
|
|
10288
10572
|
]);
|
|
10289
|
-
let [screenRight, screenBottom] =
|
|
10573
|
+
let [screenRight, screenBottom] = applyToPoint59(transform, [
|
|
10290
10574
|
debugObject.center.x + debugObject.size.width / 2,
|
|
10291
10575
|
debugObject.center.y + debugObject.size.height / 2
|
|
10292
10576
|
]);
|
|
@@ -10296,7 +10580,7 @@ function createSvgObjectsFromSchDebugObject({
|
|
|
10296
10580
|
];
|
|
10297
10581
|
const width = Math.abs(screenRight - screenLeft);
|
|
10298
10582
|
const height = Math.abs(screenBottom - screenTop);
|
|
10299
|
-
const [screenCenterX, screenCenterY] =
|
|
10583
|
+
const [screenCenterX, screenCenterY] = applyToPoint59(transform, [
|
|
10300
10584
|
debugObject.center.x,
|
|
10301
10585
|
debugObject.center.y
|
|
10302
10586
|
]);
|
|
@@ -10342,11 +10626,11 @@ function createSvgObjectsFromSchDebugObject({
|
|
|
10342
10626
|
];
|
|
10343
10627
|
}
|
|
10344
10628
|
if (debugObject.shape === "line") {
|
|
10345
|
-
const [screenStartX, screenStartY] =
|
|
10629
|
+
const [screenStartX, screenStartY] = applyToPoint59(transform, [
|
|
10346
10630
|
debugObject.start.x,
|
|
10347
10631
|
debugObject.start.y
|
|
10348
10632
|
]);
|
|
10349
|
-
const [screenEndX, screenEndY] =
|
|
10633
|
+
const [screenEndX, screenEndY] = applyToPoint59(transform, [
|
|
10350
10634
|
debugObject.end.x,
|
|
10351
10635
|
debugObject.end.y
|
|
10352
10636
|
]);
|
|
@@ -10396,7 +10680,7 @@ function createSvgObjectsFromSchDebugObject({
|
|
|
10396
10680
|
}
|
|
10397
10681
|
|
|
10398
10682
|
// lib/sch/svg-object-fns/create-svg-objects-from-sch-trace.ts
|
|
10399
|
-
import { applyToPoint as
|
|
10683
|
+
import { applyToPoint as applyToPoint60 } from "transformation-matrix";
|
|
10400
10684
|
function createSchematicTrace({
|
|
10401
10685
|
trace,
|
|
10402
10686
|
transform,
|
|
@@ -10410,11 +10694,11 @@ function createSchematicTrace({
|
|
|
10410
10694
|
for (let edgeIndex = 0; edgeIndex < edges.length; edgeIndex++) {
|
|
10411
10695
|
const edge = edges[edgeIndex];
|
|
10412
10696
|
if (edge.is_crossing) continue;
|
|
10413
|
-
const [screenFromX, screenFromY] =
|
|
10697
|
+
const [screenFromX, screenFromY] = applyToPoint60(transform, [
|
|
10414
10698
|
edge.from.x,
|
|
10415
10699
|
edge.from.y
|
|
10416
10700
|
]);
|
|
10417
|
-
const [screenToX, screenToY] =
|
|
10701
|
+
const [screenToX, screenToY] = applyToPoint60(transform, [
|
|
10418
10702
|
edge.to.x,
|
|
10419
10703
|
edge.to.y
|
|
10420
10704
|
]);
|
|
@@ -10458,11 +10742,11 @@ function createSchematicTrace({
|
|
|
10458
10742
|
}
|
|
10459
10743
|
for (const edge of edges) {
|
|
10460
10744
|
if (!edge.is_crossing) continue;
|
|
10461
|
-
const [screenFromX, screenFromY] =
|
|
10745
|
+
const [screenFromX, screenFromY] = applyToPoint60(transform, [
|
|
10462
10746
|
edge.from.x,
|
|
10463
10747
|
edge.from.y
|
|
10464
10748
|
]);
|
|
10465
|
-
const [screenToX, screenToY] =
|
|
10749
|
+
const [screenToX, screenToY] = applyToPoint60(transform, [
|
|
10466
10750
|
edge.to.x,
|
|
10467
10751
|
edge.to.y
|
|
10468
10752
|
]);
|
|
@@ -10506,7 +10790,7 @@ function createSchematicTrace({
|
|
|
10506
10790
|
}
|
|
10507
10791
|
if (trace.junctions) {
|
|
10508
10792
|
for (const junction of trace.junctions) {
|
|
10509
|
-
const [screenX, screenY] =
|
|
10793
|
+
const [screenX, screenY] = applyToPoint60(transform, [
|
|
10510
10794
|
junction.x,
|
|
10511
10795
|
junction.y
|
|
10512
10796
|
]);
|
|
@@ -10560,6 +10844,15 @@ function createSchematicTrace({
|
|
|
10560
10844
|
}
|
|
10561
10845
|
|
|
10562
10846
|
// lib/sch/svg-object-fns/create-svg-objects-for-sch-net-label.ts
|
|
10847
|
+
import {
|
|
10848
|
+
applyToPoint as applyToPoint62,
|
|
10849
|
+
compose as compose12,
|
|
10850
|
+
rotate as rotate7,
|
|
10851
|
+
scale as scale7,
|
|
10852
|
+
translate as translate12
|
|
10853
|
+
} from "transformation-matrix";
|
|
10854
|
+
|
|
10855
|
+
// lib/sch/svg-object-fns/create-svg-objects-for-sch-net-label-with-symbol.ts
|
|
10563
10856
|
import {
|
|
10564
10857
|
applyToPoint as applyToPoint61,
|
|
10565
10858
|
compose as compose11,
|
|
@@ -10567,15 +10860,6 @@ import {
|
|
|
10567
10860
|
scale as scale6,
|
|
10568
10861
|
translate as translate11
|
|
10569
10862
|
} from "transformation-matrix";
|
|
10570
|
-
|
|
10571
|
-
// lib/sch/svg-object-fns/create-svg-objects-for-sch-net-label-with-symbol.ts
|
|
10572
|
-
import {
|
|
10573
|
-
applyToPoint as applyToPoint60,
|
|
10574
|
-
compose as compose10,
|
|
10575
|
-
rotate as rotate5,
|
|
10576
|
-
scale as scale5,
|
|
10577
|
-
translate as translate10
|
|
10578
|
-
} from "transformation-matrix";
|
|
10579
10863
|
import { symbols as symbols3 } from "schematic-symbols";
|
|
10580
10864
|
var createSvgObjectsForSchNetLabelWithSymbol = ({
|
|
10581
10865
|
schNetLabel,
|
|
@@ -10618,7 +10902,7 @@ var createSvgObjectsForSchNetLabelWithSymbol = ({
|
|
|
10618
10902
|
y: schNetLabel.center.y - realTextGrowthVec.y * fullWidthFsr * fontSizeMm / 2
|
|
10619
10903
|
};
|
|
10620
10904
|
const pathRotation = 0;
|
|
10621
|
-
const rotationMatrix =
|
|
10905
|
+
const rotationMatrix = rotate6(pathRotation / 180 * Math.PI);
|
|
10622
10906
|
const symbolBounds = {
|
|
10623
10907
|
minX: Math.min(
|
|
10624
10908
|
...symbol.primitives.flatMap(
|
|
@@ -10645,22 +10929,22 @@ var createSvgObjectsForSchNetLabelWithSymbol = ({
|
|
|
10645
10929
|
x: symbolBounds.minX,
|
|
10646
10930
|
y: (symbolBounds.minY + symbolBounds.maxY) / 2
|
|
10647
10931
|
};
|
|
10648
|
-
const rotatedSymbolEnd =
|
|
10649
|
-
const symbolToRealTransform =
|
|
10650
|
-
|
|
10932
|
+
const rotatedSymbolEnd = applyToPoint61(rotationMatrix, symbolEndPoint);
|
|
10933
|
+
const symbolToRealTransform = compose11(
|
|
10934
|
+
translate11(
|
|
10651
10935
|
realAnchorPosition.x - rotatedSymbolEnd.x,
|
|
10652
10936
|
realAnchorPosition.y - rotatedSymbolEnd.y
|
|
10653
10937
|
),
|
|
10654
10938
|
rotationMatrix,
|
|
10655
|
-
|
|
10939
|
+
scale6(1)
|
|
10656
10940
|
// Use full symbol size
|
|
10657
10941
|
);
|
|
10658
|
-
const [screenMinX, screenMinY] =
|
|
10659
|
-
|
|
10942
|
+
const [screenMinX, screenMinY] = applyToPoint61(
|
|
10943
|
+
compose11(realToScreenTransform, symbolToRealTransform),
|
|
10660
10944
|
[bounds.minX, bounds.minY]
|
|
10661
10945
|
);
|
|
10662
|
-
const [screenMaxX, screenMaxY] =
|
|
10663
|
-
|
|
10946
|
+
const [screenMaxX, screenMaxY] = applyToPoint61(
|
|
10947
|
+
compose11(realToScreenTransform, symbolToRealTransform),
|
|
10664
10948
|
[bounds.maxX, bounds.maxY]
|
|
10665
10949
|
);
|
|
10666
10950
|
const rectHeight = Math.abs(screenMaxY - screenMinY);
|
|
@@ -10683,8 +10967,8 @@ var createSvgObjectsForSchNetLabelWithSymbol = ({
|
|
|
10683
10967
|
});
|
|
10684
10968
|
for (const path of symbolPaths) {
|
|
10685
10969
|
const symbolPath = path.points.map((p, i) => {
|
|
10686
|
-
const [x, y] =
|
|
10687
|
-
|
|
10970
|
+
const [x, y] = applyToPoint61(
|
|
10971
|
+
compose11(realToScreenTransform, symbolToRealTransform),
|
|
10688
10972
|
[p.x, p.y]
|
|
10689
10973
|
);
|
|
10690
10974
|
return `${i === 0 ? "M" : "L"} ${x} ${y}`;
|
|
@@ -10704,8 +10988,8 @@ var createSvgObjectsForSchNetLabelWithSymbol = ({
|
|
|
10704
10988
|
});
|
|
10705
10989
|
}
|
|
10706
10990
|
for (const text of symbolTexts) {
|
|
10707
|
-
const screenTextPos =
|
|
10708
|
-
|
|
10991
|
+
const screenTextPos = applyToPoint61(
|
|
10992
|
+
compose11(realToScreenTransform, symbolToRealTransform),
|
|
10709
10993
|
text
|
|
10710
10994
|
);
|
|
10711
10995
|
let textValue = text.text;
|
|
@@ -10714,8 +10998,8 @@ var createSvgObjectsForSchNetLabelWithSymbol = ({
|
|
|
10714
10998
|
} else if (textValue === "{VAL}") {
|
|
10715
10999
|
textValue = "";
|
|
10716
11000
|
}
|
|
10717
|
-
const
|
|
10718
|
-
const baseOffset =
|
|
11001
|
+
const scale10 = Math.abs(realToScreenTransform.a);
|
|
11002
|
+
const baseOffset = scale10 * 0.1;
|
|
10719
11003
|
const offsetScreenPos = {
|
|
10720
11004
|
x: screenTextPos.x,
|
|
10721
11005
|
y: screenTextPos.y
|
|
@@ -10746,11 +11030,11 @@ var createSvgObjectsForSchNetLabelWithSymbol = ({
|
|
|
10746
11030
|
});
|
|
10747
11031
|
}
|
|
10748
11032
|
for (const box of symbolBoxes) {
|
|
10749
|
-
const screenBoxPos =
|
|
10750
|
-
|
|
11033
|
+
const screenBoxPos = applyToPoint61(
|
|
11034
|
+
compose11(realToScreenTransform, symbolToRealTransform),
|
|
10751
11035
|
box
|
|
10752
11036
|
);
|
|
10753
|
-
const symbolToScreenScale =
|
|
11037
|
+
const symbolToScreenScale = compose11(
|
|
10754
11038
|
realToScreenTransform,
|
|
10755
11039
|
symbolToRealTransform
|
|
10756
11040
|
).a;
|
|
@@ -10769,11 +11053,11 @@ var createSvgObjectsForSchNetLabelWithSymbol = ({
|
|
|
10769
11053
|
});
|
|
10770
11054
|
}
|
|
10771
11055
|
for (const circle of symbolCircles) {
|
|
10772
|
-
const screenCirclePos =
|
|
10773
|
-
|
|
11056
|
+
const screenCirclePos = applyToPoint61(
|
|
11057
|
+
compose11(realToScreenTransform, symbolToRealTransform),
|
|
10774
11058
|
circle
|
|
10775
11059
|
);
|
|
10776
|
-
const symbolToScreenScale =
|
|
11060
|
+
const symbolToScreenScale = compose11(
|
|
10777
11061
|
realToScreenTransform,
|
|
10778
11062
|
symbolToRealTransform
|
|
10779
11063
|
).a;
|
|
@@ -10814,14 +11098,14 @@ var createSvgObjectsForSchNetLabel = ({
|
|
|
10814
11098
|
const fontSizePx = getSchScreenFontSize(realToScreenTransform, "net_label");
|
|
10815
11099
|
const fontSizeMm = getSchMmFontSize("net_label");
|
|
10816
11100
|
const textWidthFSR = estimateTextWidth(labelText || "");
|
|
10817
|
-
const screenCenter =
|
|
11101
|
+
const screenCenter = applyToPoint62(realToScreenTransform, schNetLabel.center);
|
|
10818
11102
|
const realTextGrowthVec = getUnitVectorFromOutsideToEdge(
|
|
10819
11103
|
schNetLabel.anchor_side
|
|
10820
11104
|
);
|
|
10821
11105
|
const screenTextGrowthVec = { ...realTextGrowthVec };
|
|
10822
11106
|
screenTextGrowthVec.y *= -1;
|
|
10823
11107
|
const fullWidthFsr = textWidthFSR + ARROW_POINT_WIDTH_FSR * 2 + END_PADDING_EXTRA_PER_CHARACTER_FSR * labelText.length + END_PADDING_FSR;
|
|
10824
|
-
const screenAnchorPosition = schNetLabel.anchor_position ?
|
|
11108
|
+
const screenAnchorPosition = schNetLabel.anchor_position ? applyToPoint62(realToScreenTransform, schNetLabel.anchor_position) : {
|
|
10825
11109
|
x: screenCenter.x - screenTextGrowthVec.x * fullWidthFsr * fontSizePx / 2,
|
|
10826
11110
|
y: screenCenter.y - screenTextGrowthVec.y * fullWidthFsr * fontSizePx / 2
|
|
10827
11111
|
};
|
|
@@ -10862,12 +11146,12 @@ var createSvgObjectsForSchNetLabel = ({
|
|
|
10862
11146
|
y: -0.6
|
|
10863
11147
|
}
|
|
10864
11148
|
].map(
|
|
10865
|
-
(fontRelativePoint) =>
|
|
10866
|
-
|
|
11149
|
+
(fontRelativePoint) => applyToPoint62(
|
|
11150
|
+
compose12(
|
|
10867
11151
|
realToScreenTransform,
|
|
10868
|
-
|
|
10869
|
-
|
|
10870
|
-
|
|
11152
|
+
translate12(realAnchorPosition.x, realAnchorPosition.y),
|
|
11153
|
+
scale7(fontSizeMm),
|
|
11154
|
+
rotate7(pathRotation / 180 * Math.PI)
|
|
10871
11155
|
),
|
|
10872
11156
|
fontRelativePoint
|
|
10873
11157
|
)
|
|
@@ -10939,17 +11223,17 @@ var createSvgObjectsForSchNetLabel = ({
|
|
|
10939
11223
|
};
|
|
10940
11224
|
|
|
10941
11225
|
// lib/sch/svg-object-fns/create-svg-objects-from-sch-box.ts
|
|
10942
|
-
import { applyToPoint as
|
|
11226
|
+
import { applyToPoint as applyToPoint63 } from "transformation-matrix";
|
|
10943
11227
|
var createSvgObjectsFromSchematicBox = ({
|
|
10944
11228
|
schematicBox,
|
|
10945
11229
|
transform,
|
|
10946
11230
|
colorMap: colorMap2
|
|
10947
11231
|
}) => {
|
|
10948
|
-
const topLeft =
|
|
11232
|
+
const topLeft = applyToPoint63(transform, {
|
|
10949
11233
|
x: schematicBox.x,
|
|
10950
11234
|
y: schematicBox.y
|
|
10951
11235
|
});
|
|
10952
|
-
const bottomRight =
|
|
11236
|
+
const bottomRight = applyToPoint63(transform, {
|
|
10953
11237
|
x: schematicBox.x + schematicBox.width,
|
|
10954
11238
|
y: schematicBox.y + schematicBox.height
|
|
10955
11239
|
});
|
|
@@ -10985,7 +11269,7 @@ var createSvgObjectsFromSchematicBox = ({
|
|
|
10985
11269
|
};
|
|
10986
11270
|
|
|
10987
11271
|
// lib/sch/svg-object-fns/create-svg-objects-from-sch-table.ts
|
|
10988
|
-
import { applyToPoint as
|
|
11272
|
+
import { applyToPoint as applyToPoint64 } from "transformation-matrix";
|
|
10989
11273
|
var createSvgObjectsFromSchematicTable = ({
|
|
10990
11274
|
schematicTable,
|
|
10991
11275
|
transform,
|
|
@@ -11018,11 +11302,11 @@ var createSvgObjectsFromSchematicTable = ({
|
|
|
11018
11302
|
const svgObjects = [];
|
|
11019
11303
|
const borderStrokeWidth = border_width * Math.abs(transform.a);
|
|
11020
11304
|
const gridStrokeWidth = getSchStrokeSize(transform);
|
|
11021
|
-
const [screenTopLeftX, screenTopLeftY] =
|
|
11305
|
+
const [screenTopLeftX, screenTopLeftY] = applyToPoint64(transform, [
|
|
11022
11306
|
topLeftX,
|
|
11023
11307
|
topLeftY
|
|
11024
11308
|
]);
|
|
11025
|
-
const [screenBottomRightX, screenBottomRightY] =
|
|
11309
|
+
const [screenBottomRightX, screenBottomRightY] = applyToPoint64(transform, [
|
|
11026
11310
|
topLeftX + totalWidth,
|
|
11027
11311
|
topLeftY - totalHeight
|
|
11028
11312
|
]);
|
|
@@ -11054,8 +11338,8 @@ var createSvgObjectsFromSchematicTable = ({
|
|
|
11054
11338
|
(cell) => cell.start_column_index <= i && cell.end_column_index > i && cell.start_row_index <= j && cell.end_row_index >= j
|
|
11055
11339
|
);
|
|
11056
11340
|
if (!isMerged) {
|
|
11057
|
-
const start =
|
|
11058
|
-
const end =
|
|
11341
|
+
const start = applyToPoint64(transform, { x: currentX, y: segmentStartY });
|
|
11342
|
+
const end = applyToPoint64(transform, { x: currentX, y: segmentEndY });
|
|
11059
11343
|
svgObjects.push({
|
|
11060
11344
|
name: "line",
|
|
11061
11345
|
type: "element",
|
|
@@ -11084,11 +11368,11 @@ var createSvgObjectsFromSchematicTable = ({
|
|
|
11084
11368
|
(cell) => cell.start_row_index <= i && cell.end_row_index > i && cell.start_column_index <= j && cell.end_column_index >= j
|
|
11085
11369
|
);
|
|
11086
11370
|
if (!isMerged) {
|
|
11087
|
-
const start =
|
|
11371
|
+
const start = applyToPoint64(transform, {
|
|
11088
11372
|
x: segmentStartX,
|
|
11089
11373
|
y: currentY
|
|
11090
11374
|
});
|
|
11091
|
-
const end =
|
|
11375
|
+
const end = applyToPoint64(transform, { x: segmentEndX, y: currentY });
|
|
11092
11376
|
svgObjects.push({
|
|
11093
11377
|
name: "line",
|
|
11094
11378
|
type: "element",
|
|
@@ -11130,7 +11414,7 @@ var createSvgObjectsFromSchematicTable = ({
|
|
|
11130
11414
|
} else if (vertical_align === "bottom") {
|
|
11131
11415
|
realTextAnchorPos.y = cellTopLeftY - cellHeight + cell_padding;
|
|
11132
11416
|
}
|
|
11133
|
-
const screenTextAnchorPos =
|
|
11417
|
+
const screenTextAnchorPos = applyToPoint64(transform, realTextAnchorPos);
|
|
11134
11418
|
const fontSize = getSchScreenFontSize(
|
|
11135
11419
|
transform,
|
|
11136
11420
|
"reference_designator",
|
|
@@ -11186,13 +11470,13 @@ var createSvgObjectsFromSchematicTable = ({
|
|
|
11186
11470
|
|
|
11187
11471
|
// lib/sch/svg-object-fns/create-svg-objects-for-sch-port-hover.ts
|
|
11188
11472
|
import { su as su11 } from "@tscircuit/circuit-json-util";
|
|
11189
|
-
import { applyToPoint as
|
|
11473
|
+
import { applyToPoint as applyToPoint65 } from "transformation-matrix";
|
|
11190
11474
|
var PIN_CIRCLE_RADIUS_MM2 = 0.02;
|
|
11191
11475
|
var createSvgObjectsForSchPortHover = ({
|
|
11192
11476
|
schPort,
|
|
11193
11477
|
transform
|
|
11194
11478
|
}) => {
|
|
11195
|
-
const screenSchPortPos =
|
|
11479
|
+
const screenSchPortPos = applyToPoint65(transform, schPort.center);
|
|
11196
11480
|
const pinRadiusPx = Math.abs(transform.a) * PIN_CIRCLE_RADIUS_MM2 * 2;
|
|
11197
11481
|
return [
|
|
11198
11482
|
{
|
|
@@ -11237,14 +11521,14 @@ var createSvgObjectsForSchComponentPortHovers = ({
|
|
|
11237
11521
|
};
|
|
11238
11522
|
|
|
11239
11523
|
// lib/sch/svg-object-fns/create-svg-objects-from-sch-line.ts
|
|
11240
|
-
import { applyToPoint as
|
|
11524
|
+
import { applyToPoint as applyToPoint66 } from "transformation-matrix";
|
|
11241
11525
|
function createSvgObjectsFromSchematicLine({
|
|
11242
11526
|
schLine,
|
|
11243
11527
|
transform,
|
|
11244
11528
|
colorMap: colorMap2
|
|
11245
11529
|
}) {
|
|
11246
|
-
const p1 =
|
|
11247
|
-
const p2 =
|
|
11530
|
+
const p1 = applyToPoint66(transform, { x: schLine.x1, y: schLine.y1 });
|
|
11531
|
+
const p2 = applyToPoint66(transform, { x: schLine.x2, y: schLine.y2 });
|
|
11248
11532
|
const strokeWidth = schLine.stroke_width ?? 0.02;
|
|
11249
11533
|
const transformedStrokeWidth = Math.abs(transform.a) * strokeWidth;
|
|
11250
11534
|
return [
|
|
@@ -11273,13 +11557,13 @@ function createSvgObjectsFromSchematicLine({
|
|
|
11273
11557
|
}
|
|
11274
11558
|
|
|
11275
11559
|
// lib/sch/svg-object-fns/create-svg-objects-from-sch-circle.ts
|
|
11276
|
-
import { applyToPoint as
|
|
11560
|
+
import { applyToPoint as applyToPoint67 } from "transformation-matrix";
|
|
11277
11561
|
function createSvgObjectsFromSchematicCircle({
|
|
11278
11562
|
schCircle,
|
|
11279
11563
|
transform,
|
|
11280
11564
|
colorMap: colorMap2
|
|
11281
11565
|
}) {
|
|
11282
|
-
const center =
|
|
11566
|
+
const center = applyToPoint67(transform, schCircle.center);
|
|
11283
11567
|
const transformedRadius = Math.abs(transform.a) * schCircle.radius;
|
|
11284
11568
|
const strokeWidth = schCircle.stroke_width ?? 0.02;
|
|
11285
11569
|
const transformedStrokeWidth = Math.abs(transform.a) * strokeWidth;
|
|
@@ -11309,13 +11593,13 @@ function createSvgObjectsFromSchematicCircle({
|
|
|
11309
11593
|
}
|
|
11310
11594
|
|
|
11311
11595
|
// lib/sch/svg-object-fns/create-svg-objects-from-sch-rect.ts
|
|
11312
|
-
import { applyToPoint as
|
|
11596
|
+
import { applyToPoint as applyToPoint68 } from "transformation-matrix";
|
|
11313
11597
|
function createSvgObjectsFromSchematicRect({
|
|
11314
11598
|
schRect,
|
|
11315
11599
|
transform,
|
|
11316
11600
|
colorMap: colorMap2
|
|
11317
11601
|
}) {
|
|
11318
|
-
const center =
|
|
11602
|
+
const center = applyToPoint68(transform, schRect.center);
|
|
11319
11603
|
const transformedWidth = Math.abs(transform.a) * schRect.width;
|
|
11320
11604
|
const transformedHeight = Math.abs(transform.d) * schRect.height;
|
|
11321
11605
|
const strokeWidth = schRect.stroke_width ?? 0.02;
|
|
@@ -11351,13 +11635,13 @@ function createSvgObjectsFromSchematicRect({
|
|
|
11351
11635
|
}
|
|
11352
11636
|
|
|
11353
11637
|
// lib/sch/svg-object-fns/create-svg-objects-from-sch-arc.ts
|
|
11354
|
-
import { applyToPoint as
|
|
11638
|
+
import { applyToPoint as applyToPoint69 } from "transformation-matrix";
|
|
11355
11639
|
function createSvgObjectsFromSchematicArc({
|
|
11356
11640
|
schArc,
|
|
11357
11641
|
transform,
|
|
11358
11642
|
colorMap: colorMap2
|
|
11359
11643
|
}) {
|
|
11360
|
-
const center =
|
|
11644
|
+
const center = applyToPoint69(transform, schArc.center);
|
|
11361
11645
|
const transformedRadius = Math.abs(transform.a) * schArc.radius;
|
|
11362
11646
|
const strokeWidth = schArc.stroke_width ?? 0.02;
|
|
11363
11647
|
const transformedStrokeWidth = Math.abs(transform.a) * strokeWidth;
|
|
@@ -12364,9 +12648,9 @@ function convertCircuitJsonToSchematicSimulationSvg({
|
|
|
12364
12648
|
const rawSchematicHeight = Math.max(1, height * clampedRatio);
|
|
12365
12649
|
const rawSimulationHeight = Math.max(1, height - rawSchematicHeight);
|
|
12366
12650
|
const totalRawHeight = rawSchematicHeight + rawSimulationHeight;
|
|
12367
|
-
const
|
|
12368
|
-
const schematicHeight = rawSchematicHeight *
|
|
12369
|
-
const simulationHeight = rawSimulationHeight *
|
|
12651
|
+
const scale10 = totalRawHeight === 0 ? 1 : height / totalRawHeight;
|
|
12652
|
+
const schematicHeight = rawSchematicHeight * scale10;
|
|
12653
|
+
const simulationHeight = rawSimulationHeight * scale10;
|
|
12370
12654
|
const schematicSvg = convertCircuitJsonToSchematicSvg(schematicElements, {
|
|
12371
12655
|
...schematicOptions,
|
|
12372
12656
|
width,
|
|
@@ -12458,21 +12742,21 @@ function formatNumber2(value) {
|
|
|
12458
12742
|
}
|
|
12459
12743
|
|
|
12460
12744
|
// lib/pcb/convert-circuit-json-to-solder-paste-mask.ts
|
|
12461
|
-
import { distance as
|
|
12745
|
+
import { distance as distance3 } from "circuit-json";
|
|
12462
12746
|
import { stringify as stringify7 } from "svgson";
|
|
12463
12747
|
import {
|
|
12464
|
-
applyToPoint as
|
|
12465
|
-
compose as
|
|
12466
|
-
scale as
|
|
12467
|
-
translate as
|
|
12748
|
+
applyToPoint as applyToPoint72,
|
|
12749
|
+
compose as compose15,
|
|
12750
|
+
scale as scale9,
|
|
12751
|
+
translate as translate15
|
|
12468
12752
|
} from "transformation-matrix";
|
|
12469
12753
|
|
|
12470
12754
|
// lib/pcb/svg-object-fns/convert-circuit-json-to-solder-paste-mask.ts
|
|
12471
|
-
import { applyToPoint as
|
|
12755
|
+
import { applyToPoint as applyToPoint71 } from "transformation-matrix";
|
|
12472
12756
|
function createSvgObjectsFromSolderPaste(solderPaste, ctx) {
|
|
12473
12757
|
const { transform, layer: layerFilter } = ctx;
|
|
12474
12758
|
if (layerFilter && solderPaste.layer !== layerFilter) return [];
|
|
12475
|
-
const [x, y] =
|
|
12759
|
+
const [x, y] = applyToPoint71(transform, [solderPaste.x, solderPaste.y]);
|
|
12476
12760
|
if (solderPaste.shape === "rect" || solderPaste.shape === "rotated_rect") {
|
|
12477
12761
|
const width = solderPaste.width * Math.abs(transform.a);
|
|
12478
12762
|
const height = solderPaste.height * Math.abs(transform.d);
|
|
@@ -12576,8 +12860,8 @@ function convertCircuitJsonToSolderPasteMask(circuitJson, options) {
|
|
|
12576
12860
|
}
|
|
12577
12861
|
} else if (item.type === "pcb_panel") {
|
|
12578
12862
|
const panel = item;
|
|
12579
|
-
const width =
|
|
12580
|
-
const height =
|
|
12863
|
+
const width = distance3.parse(panel.width);
|
|
12864
|
+
const height = distance3.parse(panel.height);
|
|
12581
12865
|
if (width !== void 0 && height !== void 0) {
|
|
12582
12866
|
const center = panel.center ?? { x: width / 2, y: height / 2 };
|
|
12583
12867
|
updateBounds(center, width, height);
|
|
@@ -12596,12 +12880,12 @@ function convertCircuitJsonToSolderPasteMask(circuitJson, options) {
|
|
|
12596
12880
|
const scaleFactor = Math.min(scaleX, scaleY);
|
|
12597
12881
|
const offsetX = (svgWidth - circuitWidth * scaleFactor) / 2;
|
|
12598
12882
|
const offsetY = (svgHeight - circuitHeight * scaleFactor) / 2;
|
|
12599
|
-
const transform =
|
|
12600
|
-
|
|
12883
|
+
const transform = compose15(
|
|
12884
|
+
translate15(
|
|
12601
12885
|
offsetX - minX * scaleFactor + padding * scaleFactor,
|
|
12602
12886
|
svgHeight - offsetY + minY * scaleFactor - padding * scaleFactor
|
|
12603
12887
|
),
|
|
12604
|
-
|
|
12888
|
+
scale9(scaleFactor, -scaleFactor)
|
|
12605
12889
|
// Flip in y-direction
|
|
12606
12890
|
);
|
|
12607
12891
|
const ctx = {
|
|
@@ -12698,8 +12982,8 @@ function createSvgObjects4({ elm, ctx }) {
|
|
|
12698
12982
|
}
|
|
12699
12983
|
}
|
|
12700
12984
|
function createSvgObjectFromPcbBoundary2(transform, minX, minY, maxX, maxY) {
|
|
12701
|
-
const [x1, y1] =
|
|
12702
|
-
const [x2, y2] =
|
|
12985
|
+
const [x1, y1] = applyToPoint72(transform, [minX, minY]);
|
|
12986
|
+
const [x2, y2] = applyToPoint72(transform, [maxX, maxY]);
|
|
12703
12987
|
const width = Math.abs(x2 - x1);
|
|
12704
12988
|
const height = Math.abs(y2 - y1);
|
|
12705
12989
|
const x = Math.min(x1, x2);
|