circuit-to-svg 0.0.304 → 0.0.306
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 +310 -215
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// lib/pcb/convert-circuit-json-to-pcb-svg.ts
|
|
2
|
-
import
|
|
2
|
+
import "circuit-json";
|
|
3
3
|
import { stringify } from "svgson";
|
|
4
4
|
import {
|
|
5
5
|
applyToPoint as applyToPoint37,
|
|
@@ -2646,7 +2646,8 @@ function createSvgObjectsFromPcbSilkscreenRect(pcbSilkscreenRect, ctx) {
|
|
|
2646
2646
|
is_filled,
|
|
2647
2647
|
has_stroke,
|
|
2648
2648
|
is_stroke_dashed,
|
|
2649
|
-
corner_radius
|
|
2649
|
+
corner_radius,
|
|
2650
|
+
ccw_rotation = 0
|
|
2650
2651
|
} = pcbSilkscreenRect;
|
|
2651
2652
|
if (layerFilter && layer !== layerFilter) return [];
|
|
2652
2653
|
if (!center || typeof center.x !== "number" || typeof center.y !== "number" || typeof width !== "number" || typeof height !== "number") {
|
|
@@ -2665,8 +2666,8 @@ function createSvgObjectsFromPcbSilkscreenRect(pcbSilkscreenRect, ctx) {
|
|
|
2665
2666
|
const transformedStrokeWidth = stroke_width * Math.abs(transform.a);
|
|
2666
2667
|
const color = layer === "bottom" ? colorMap2.silkscreen.bottom : colorMap2.silkscreen.top;
|
|
2667
2668
|
const attributes = {
|
|
2668
|
-
x: (
|
|
2669
|
-
y: (
|
|
2669
|
+
x: (-transformedWidth / 2).toString(),
|
|
2670
|
+
y: (-transformedHeight / 2).toString(),
|
|
2670
2671
|
width: transformedWidth.toString(),
|
|
2671
2672
|
height: transformedHeight.toString(),
|
|
2672
2673
|
class: `pcb-silkscreen-rect pcb-silkscreen-${layer}`,
|
|
@@ -2674,6 +2675,12 @@ function createSvgObjectsFromPcbSilkscreenRect(pcbSilkscreenRect, ctx) {
|
|
|
2674
2675
|
"data-type": "pcb_silkscreen_rect",
|
|
2675
2676
|
"data-pcb-layer": layer
|
|
2676
2677
|
};
|
|
2678
|
+
if (typeof ccw_rotation === "number" && ccw_rotation !== 0) {
|
|
2679
|
+
attributes.transform = `translate(${transformedX} ${transformedY}) rotate(${-ccw_rotation})`;
|
|
2680
|
+
} else {
|
|
2681
|
+
attributes.x = (transformedX - transformedWidth / 2).toString();
|
|
2682
|
+
attributes.y = (transformedY - transformedHeight / 2).toString();
|
|
2683
|
+
}
|
|
2677
2684
|
if (transformedCornerRadiusX > 0) {
|
|
2678
2685
|
attributes.rx = transformedCornerRadiusX.toString();
|
|
2679
2686
|
}
|
|
@@ -3827,10 +3834,10 @@ function createSvgObjectsFromSmtPad(pad, ctx) {
|
|
|
3827
3834
|
maskPoints = points.map(([px, py]) => {
|
|
3828
3835
|
const dx = px - centroidX;
|
|
3829
3836
|
const dy = py - centroidY;
|
|
3830
|
-
const
|
|
3831
|
-
if (
|
|
3832
|
-
const normalizedDx = dx /
|
|
3833
|
-
const normalizedDy = dy /
|
|
3837
|
+
const distance5 = Math.sqrt(dx * dx + dy * dy);
|
|
3838
|
+
if (distance5 === 0) return [px, py];
|
|
3839
|
+
const normalizedDx = dx / distance5;
|
|
3840
|
+
const normalizedDy = dy / distance5;
|
|
3834
3841
|
return [
|
|
3835
3842
|
px + normalizedDx * soldermaskMargin,
|
|
3836
3843
|
py + normalizedDy * soldermaskMargin
|
|
@@ -4036,11 +4043,11 @@ function createAnchorOffsetIndicators(params) {
|
|
|
4036
4043
|
function getTrimmedConnectorLine(x1, y1, x2, y2) {
|
|
4037
4044
|
const dx = x2 - x1;
|
|
4038
4045
|
const dy = y2 - y1;
|
|
4039
|
-
const
|
|
4046
|
+
const distance5 = Math.hypot(dx, dy);
|
|
4040
4047
|
const totalTrim = CONNECTOR_GROUP_GAP_PX + CONNECTOR_COMPONENT_GAP_PX;
|
|
4041
|
-
if (!(
|
|
4042
|
-
const ux = dx /
|
|
4043
|
-
const uy = dy /
|
|
4048
|
+
if (!(distance5 > totalTrim)) return { x1, y1, x2, y2 };
|
|
4049
|
+
const ux = dx / distance5;
|
|
4050
|
+
const uy = dy / distance5;
|
|
4044
4051
|
return {
|
|
4045
4052
|
x1: x1 + ux * CONNECTOR_GROUP_GAP_PX,
|
|
4046
4053
|
y1: y1 + uy * CONNECTOR_GROUP_GAP_PX,
|
|
@@ -4997,9 +5004,9 @@ var findNearestPointInNet = (sourcePoint, netId, connectivity, circuitJson) => {
|
|
|
4997
5004
|
if (pos) {
|
|
4998
5005
|
const dx = sourcePoint.x - pos.x;
|
|
4999
5006
|
const dy = sourcePoint.y - pos.y;
|
|
5000
|
-
const
|
|
5001
|
-
if (
|
|
5002
|
-
minDistance =
|
|
5007
|
+
const distance5 = Math.sqrt(dx * dx + dy * dy);
|
|
5008
|
+
if (distance5 > 0 && distance5 < minDistance) {
|
|
5009
|
+
minDistance = distance5;
|
|
5003
5010
|
nearestPoint = pos;
|
|
5004
5011
|
}
|
|
5005
5012
|
}
|
|
@@ -5877,7 +5884,7 @@ function getSoftwareUsedString(circuitJson) {
|
|
|
5877
5884
|
var package_default = {
|
|
5878
5885
|
name: "circuit-to-svg",
|
|
5879
5886
|
type: "module",
|
|
5880
|
-
version: "0.0.
|
|
5887
|
+
version: "0.0.305",
|
|
5881
5888
|
description: "Convert Circuit JSON to SVG",
|
|
5882
5889
|
main: "dist/index.js",
|
|
5883
5890
|
files: [
|
|
@@ -6059,49 +6066,9 @@ function createErrorTextOverlay(circuitJson, dataType = "error_text_overlay") {
|
|
|
6059
6066
|
return textBlock;
|
|
6060
6067
|
}
|
|
6061
6068
|
|
|
6062
|
-
// lib/pcb/
|
|
6063
|
-
|
|
6064
|
-
|
|
6065
|
-
const layer = options?.layer;
|
|
6066
|
-
const colorOverrides = options?.colorOverrides;
|
|
6067
|
-
const copperColors = {
|
|
6068
|
-
...DEFAULT_PCB_COLOR_MAP.copper
|
|
6069
|
-
};
|
|
6070
|
-
if (colorOverrides?.copper) {
|
|
6071
|
-
for (const [layerName, color] of Object.entries(colorOverrides.copper)) {
|
|
6072
|
-
if (color !== void 0) {
|
|
6073
|
-
copperColors[layerName] = color;
|
|
6074
|
-
}
|
|
6075
|
-
}
|
|
6076
|
-
}
|
|
6077
|
-
const colorMap2 = {
|
|
6078
|
-
copper: copperColors,
|
|
6079
|
-
drill: colorOverrides?.drill ?? DEFAULT_PCB_COLOR_MAP.drill,
|
|
6080
|
-
silkscreen: {
|
|
6081
|
-
top: colorOverrides?.silkscreen?.top ?? DEFAULT_PCB_COLOR_MAP.silkscreen.top,
|
|
6082
|
-
bottom: colorOverrides?.silkscreen?.bottom ?? DEFAULT_PCB_COLOR_MAP.silkscreen.bottom
|
|
6083
|
-
},
|
|
6084
|
-
boardOutline: colorOverrides?.boardOutline ?? DEFAULT_PCB_COLOR_MAP.boardOutline,
|
|
6085
|
-
soldermask: {
|
|
6086
|
-
top: colorOverrides?.soldermask?.top ?? DEFAULT_PCB_COLOR_MAP.soldermask.top,
|
|
6087
|
-
bottom: colorOverrides?.soldermask?.bottom ?? DEFAULT_PCB_COLOR_MAP.soldermask.bottom
|
|
6088
|
-
},
|
|
6089
|
-
soldermaskOverCopper: {
|
|
6090
|
-
top: colorOverrides?.soldermaskOverCopper?.top ?? DEFAULT_PCB_COLOR_MAP.soldermaskOverCopper.top,
|
|
6091
|
-
bottom: colorOverrides?.soldermaskOverCopper?.bottom ?? DEFAULT_PCB_COLOR_MAP.soldermaskOverCopper.bottom
|
|
6092
|
-
},
|
|
6093
|
-
soldermaskWithCopperUnderneath: {
|
|
6094
|
-
top: colorOverrides?.soldermaskWithCopperUnderneath?.top ?? DEFAULT_PCB_COLOR_MAP.soldermaskWithCopperUnderneath.top,
|
|
6095
|
-
bottom: colorOverrides?.soldermaskWithCopperUnderneath?.bottom ?? DEFAULT_PCB_COLOR_MAP.soldermaskWithCopperUnderneath.bottom
|
|
6096
|
-
},
|
|
6097
|
-
substrate: colorOverrides?.substrate ?? DEFAULT_PCB_COLOR_MAP.substrate,
|
|
6098
|
-
courtyard: colorOverrides?.courtyard ?? DEFAULT_PCB_COLOR_MAP.courtyard,
|
|
6099
|
-
keepout: colorOverrides?.keepout ?? DEFAULT_PCB_COLOR_MAP.keepout,
|
|
6100
|
-
debugComponent: {
|
|
6101
|
-
fill: colorOverrides?.debugComponent?.fill ?? DEFAULT_PCB_COLOR_MAP.debugComponent.fill,
|
|
6102
|
-
stroke: colorOverrides?.debugComponent?.stroke ?? DEFAULT_PCB_COLOR_MAP.debugComponent.stroke
|
|
6103
|
-
}
|
|
6104
|
-
};
|
|
6069
|
+
// lib/pcb/get-pcb-bounds-from-circuit-json.ts
|
|
6070
|
+
import { distance as distance2 } from "circuit-json";
|
|
6071
|
+
function getPcbBoundsFromCircuitJson(circuitJson) {
|
|
6105
6072
|
let minX = Number.POSITIVE_INFINITY;
|
|
6106
6073
|
let minY = Number.POSITIVE_INFINITY;
|
|
6107
6074
|
let maxX = Number.NEGATIVE_INFINITY;
|
|
@@ -6121,53 +6088,73 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
|
|
|
6121
6088
|
continue;
|
|
6122
6089
|
}
|
|
6123
6090
|
const center = panel.center ?? { x: width / 2, y: height / 2 };
|
|
6124
|
-
updateBounds(center, width, height);
|
|
6091
|
+
updateBounds({ center, width, height });
|
|
6125
6092
|
} else if (circuitJsonElm.type === "pcb_board") {
|
|
6126
6093
|
if (circuitJsonElm.outline && Array.isArray(circuitJsonElm.outline) && circuitJsonElm.outline.length >= 3) {
|
|
6127
6094
|
updateBoundsToIncludeOutline(circuitJsonElm.outline);
|
|
6128
6095
|
updateBoardBoundsToIncludeOutline(circuitJsonElm.outline);
|
|
6129
6096
|
} else if ("center" in circuitJsonElm && "width" in circuitJsonElm && "height" in circuitJsonElm) {
|
|
6130
|
-
updateBounds(
|
|
6131
|
-
circuitJsonElm.center,
|
|
6132
|
-
circuitJsonElm.width,
|
|
6133
|
-
circuitJsonElm.height
|
|
6134
|
-
);
|
|
6135
|
-
updateBoardBounds(
|
|
6136
|
-
circuitJsonElm.center,
|
|
6137
|
-
circuitJsonElm.width,
|
|
6138
|
-
circuitJsonElm.height
|
|
6139
|
-
);
|
|
6097
|
+
updateBounds({
|
|
6098
|
+
center: circuitJsonElm.center,
|
|
6099
|
+
width: circuitJsonElm.width,
|
|
6100
|
+
height: circuitJsonElm.height
|
|
6101
|
+
});
|
|
6102
|
+
updateBoardBounds({
|
|
6103
|
+
center: circuitJsonElm.center,
|
|
6104
|
+
width: circuitJsonElm.width,
|
|
6105
|
+
height: circuitJsonElm.height
|
|
6106
|
+
});
|
|
6140
6107
|
}
|
|
6141
6108
|
} else if (circuitJsonElm.type === "pcb_smtpad") {
|
|
6142
6109
|
const pad = circuitJsonElm;
|
|
6143
6110
|
if (pad.shape === "rect" || pad.shape === "rotated_rect" || pad.shape === "pill") {
|
|
6144
|
-
updateBounds({
|
|
6111
|
+
updateBounds({
|
|
6112
|
+
center: { x: pad.x, y: pad.y },
|
|
6113
|
+
width: pad.width,
|
|
6114
|
+
height: pad.height
|
|
6115
|
+
});
|
|
6145
6116
|
} else if (pad.shape === "circle") {
|
|
6146
6117
|
const radius = distance2.parse(pad.radius);
|
|
6147
6118
|
if (radius !== void 0) {
|
|
6148
|
-
updateBounds({
|
|
6119
|
+
updateBounds({
|
|
6120
|
+
center: { x: pad.x, y: pad.y },
|
|
6121
|
+
width: radius * 2,
|
|
6122
|
+
height: radius * 2
|
|
6123
|
+
});
|
|
6149
6124
|
}
|
|
6150
6125
|
} else if (pad.shape === "polygon") {
|
|
6151
6126
|
updateTraceBounds(pad.points);
|
|
6152
6127
|
}
|
|
6153
6128
|
} else if ("x" in circuitJsonElm && "y" in circuitJsonElm) {
|
|
6154
|
-
updateBounds({
|
|
6129
|
+
updateBounds({
|
|
6130
|
+
center: { x: circuitJsonElm.x, y: circuitJsonElm.y },
|
|
6131
|
+
width: 0,
|
|
6132
|
+
height: 0
|
|
6133
|
+
});
|
|
6155
6134
|
} else if ("route" in circuitJsonElm) {
|
|
6156
6135
|
updateTraceBounds(circuitJsonElm.route);
|
|
6157
6136
|
} else if (circuitJsonElm.type === "pcb_note_rect" || circuitJsonElm.type === "pcb_fabrication_note_rect") {
|
|
6158
|
-
updateBounds(
|
|
6159
|
-
circuitJsonElm.center,
|
|
6160
|
-
circuitJsonElm.width,
|
|
6161
|
-
circuitJsonElm.height
|
|
6162
|
-
);
|
|
6137
|
+
updateBounds({
|
|
6138
|
+
center: circuitJsonElm.center,
|
|
6139
|
+
width: circuitJsonElm.width,
|
|
6140
|
+
height: circuitJsonElm.height
|
|
6141
|
+
});
|
|
6163
6142
|
} else if (circuitJsonElm.type === "pcb_cutout") {
|
|
6164
6143
|
const cutout = circuitJsonElm;
|
|
6165
6144
|
if (cutout.shape === "rect") {
|
|
6166
|
-
updateBounds(
|
|
6145
|
+
updateBounds({
|
|
6146
|
+
center: cutout.center,
|
|
6147
|
+
width: cutout.width,
|
|
6148
|
+
height: cutout.height
|
|
6149
|
+
});
|
|
6167
6150
|
} else if (cutout.shape === "circle") {
|
|
6168
6151
|
const radius = distance2.parse(cutout.radius);
|
|
6169
6152
|
if (radius !== void 0) {
|
|
6170
|
-
updateBounds(
|
|
6153
|
+
updateBounds({
|
|
6154
|
+
center: cutout.center,
|
|
6155
|
+
width: radius * 2,
|
|
6156
|
+
height: radius * 2
|
|
6157
|
+
});
|
|
6171
6158
|
}
|
|
6172
6159
|
} else if (cutout.shape === "polygon") {
|
|
6173
6160
|
updateTraceBounds(cutout.points);
|
|
@@ -6180,34 +6167,262 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
|
|
|
6180
6167
|
} else if (circuitJsonElm.type === "pcb_keepout") {
|
|
6181
6168
|
const keepout = circuitJsonElm;
|
|
6182
6169
|
if (keepout.shape === "rect") {
|
|
6183
|
-
updateBounds(
|
|
6170
|
+
updateBounds({
|
|
6171
|
+
center: keepout.center,
|
|
6172
|
+
width: keepout.width,
|
|
6173
|
+
height: keepout.height
|
|
6174
|
+
});
|
|
6184
6175
|
} else if (keepout.shape === "circle") {
|
|
6185
6176
|
const radius = typeof keepout.radius === "number" ? keepout.radius : distance2.parse(keepout.radius) ?? 0;
|
|
6186
6177
|
if (radius > 0) {
|
|
6187
|
-
updateBounds(
|
|
6178
|
+
updateBounds({
|
|
6179
|
+
center: keepout.center,
|
|
6180
|
+
width: radius * 2,
|
|
6181
|
+
height: radius * 2
|
|
6182
|
+
});
|
|
6188
6183
|
}
|
|
6189
6184
|
}
|
|
6190
6185
|
} else if (circuitJsonElm.type === "pcb_silkscreen_text" || circuitJsonElm.type === "pcb_silkscreen_rect" || circuitJsonElm.type === "pcb_silkscreen_circle" || circuitJsonElm.type === "pcb_silkscreen_line" || circuitJsonElm.type === "pcb_silkscreen_oval") {
|
|
6191
6186
|
updateSilkscreenBounds(circuitJsonElm);
|
|
6192
6187
|
} else if (circuitJsonElm.type === "pcb_copper_text") {
|
|
6193
|
-
updateBounds(
|
|
6188
|
+
updateBounds({
|
|
6189
|
+
center: circuitJsonElm.anchor_position,
|
|
6190
|
+
width: 0,
|
|
6191
|
+
height: 0
|
|
6192
|
+
});
|
|
6194
6193
|
} else if (circuitJsonElm.type === "pcb_copper_pour") {
|
|
6195
6194
|
if (circuitJsonElm.shape === "rect") {
|
|
6196
|
-
updateBounds(
|
|
6197
|
-
circuitJsonElm.center,
|
|
6198
|
-
circuitJsonElm.width,
|
|
6199
|
-
circuitJsonElm.height
|
|
6200
|
-
);
|
|
6195
|
+
updateBounds({
|
|
6196
|
+
center: circuitJsonElm.center,
|
|
6197
|
+
width: circuitJsonElm.width,
|
|
6198
|
+
height: circuitJsonElm.height
|
|
6199
|
+
});
|
|
6201
6200
|
} else if (circuitJsonElm.shape === "polygon") {
|
|
6202
6201
|
updateTraceBounds(circuitJsonElm.points);
|
|
6203
6202
|
}
|
|
6204
6203
|
}
|
|
6205
6204
|
}
|
|
6205
|
+
return {
|
|
6206
|
+
minX,
|
|
6207
|
+
minY,
|
|
6208
|
+
maxX,
|
|
6209
|
+
maxY,
|
|
6210
|
+
boardMinX,
|
|
6211
|
+
boardMinY,
|
|
6212
|
+
boardMaxX,
|
|
6213
|
+
boardMaxY,
|
|
6214
|
+
hasBounds,
|
|
6215
|
+
hasBoardBounds
|
|
6216
|
+
};
|
|
6217
|
+
function updateBounds({
|
|
6218
|
+
center,
|
|
6219
|
+
width,
|
|
6220
|
+
height
|
|
6221
|
+
}) {
|
|
6222
|
+
if (!center) return;
|
|
6223
|
+
const centerX = distance2.parse(center.x);
|
|
6224
|
+
const centerY = distance2.parse(center.y);
|
|
6225
|
+
if (centerX === void 0 || centerY === void 0) return;
|
|
6226
|
+
const numericWidth = distance2.parse(width) ?? 0;
|
|
6227
|
+
const numericHeight = distance2.parse(height) ?? 0;
|
|
6228
|
+
const halfWidth = numericWidth / 2;
|
|
6229
|
+
const halfHeight = numericHeight / 2;
|
|
6230
|
+
minX = Math.min(minX, centerX - halfWidth);
|
|
6231
|
+
minY = Math.min(minY, centerY - halfHeight);
|
|
6232
|
+
maxX = Math.max(maxX, centerX + halfWidth);
|
|
6233
|
+
maxY = Math.max(maxY, centerY + halfHeight);
|
|
6234
|
+
hasBounds = true;
|
|
6235
|
+
}
|
|
6236
|
+
function updateBoardBounds({
|
|
6237
|
+
center,
|
|
6238
|
+
width,
|
|
6239
|
+
height
|
|
6240
|
+
}) {
|
|
6241
|
+
if (!center) return;
|
|
6242
|
+
const centerX = distance2.parse(center.x);
|
|
6243
|
+
const centerY = distance2.parse(center.y);
|
|
6244
|
+
if (centerX === void 0 || centerY === void 0) return;
|
|
6245
|
+
const numericWidth = distance2.parse(width) ?? 0;
|
|
6246
|
+
const numericHeight = distance2.parse(height) ?? 0;
|
|
6247
|
+
const halfWidth = numericWidth / 2;
|
|
6248
|
+
const halfHeight = numericHeight / 2;
|
|
6249
|
+
boardMinX = Math.min(boardMinX, centerX - halfWidth);
|
|
6250
|
+
boardMinY = Math.min(boardMinY, centerY - halfHeight);
|
|
6251
|
+
boardMaxX = Math.max(boardMaxX, centerX + halfWidth);
|
|
6252
|
+
boardMaxY = Math.max(boardMaxY, centerY + halfHeight);
|
|
6253
|
+
hasBounds = true;
|
|
6254
|
+
hasBoardBounds = true;
|
|
6255
|
+
}
|
|
6256
|
+
function updateBoundsToIncludeOutline(outline) {
|
|
6257
|
+
let updated = false;
|
|
6258
|
+
for (const point of outline) {
|
|
6259
|
+
const x = distance2.parse(point.x);
|
|
6260
|
+
const y = distance2.parse(point.y);
|
|
6261
|
+
if (x === void 0 || y === void 0) continue;
|
|
6262
|
+
minX = Math.min(minX, x);
|
|
6263
|
+
minY = Math.min(minY, y);
|
|
6264
|
+
maxX = Math.max(maxX, x);
|
|
6265
|
+
maxY = Math.max(maxY, y);
|
|
6266
|
+
updated = true;
|
|
6267
|
+
}
|
|
6268
|
+
if (updated) {
|
|
6269
|
+
hasBounds = true;
|
|
6270
|
+
}
|
|
6271
|
+
}
|
|
6272
|
+
function updateBoardBoundsToIncludeOutline(outline) {
|
|
6273
|
+
let updated = false;
|
|
6274
|
+
for (const point of outline) {
|
|
6275
|
+
const x = distance2.parse(point.x);
|
|
6276
|
+
const y = distance2.parse(point.y);
|
|
6277
|
+
if (x === void 0 || y === void 0) continue;
|
|
6278
|
+
boardMinX = Math.min(boardMinX, x);
|
|
6279
|
+
boardMinY = Math.min(boardMinY, y);
|
|
6280
|
+
boardMaxX = Math.max(boardMaxX, x);
|
|
6281
|
+
boardMaxY = Math.max(boardMaxY, y);
|
|
6282
|
+
updated = true;
|
|
6283
|
+
}
|
|
6284
|
+
if (updated) {
|
|
6285
|
+
hasBounds = true;
|
|
6286
|
+
hasBoardBounds = true;
|
|
6287
|
+
}
|
|
6288
|
+
}
|
|
6289
|
+
function updateTraceBounds(route) {
|
|
6290
|
+
let updated = false;
|
|
6291
|
+
for (const point of route) {
|
|
6292
|
+
const x = distance2.parse(point?.x);
|
|
6293
|
+
const y = distance2.parse(point?.y);
|
|
6294
|
+
if (x === void 0 || y === void 0) continue;
|
|
6295
|
+
minX = Math.min(minX, x);
|
|
6296
|
+
minY = Math.min(minY, y);
|
|
6297
|
+
maxX = Math.max(maxX, x);
|
|
6298
|
+
maxY = Math.max(maxY, y);
|
|
6299
|
+
updated = true;
|
|
6300
|
+
}
|
|
6301
|
+
if (updated) {
|
|
6302
|
+
hasBounds = true;
|
|
6303
|
+
}
|
|
6304
|
+
}
|
|
6305
|
+
function updateSilkscreenBounds(item) {
|
|
6306
|
+
if (item.type === "pcb_silkscreen_text") {
|
|
6307
|
+
updateBounds({ center: item.anchor_position, width: 0, height: 0 });
|
|
6308
|
+
} else if (item.type === "pcb_silkscreen_path") {
|
|
6309
|
+
updateTraceBounds(item.route);
|
|
6310
|
+
} else if (item.type === "pcb_silkscreen_rect") {
|
|
6311
|
+
updateBounds({
|
|
6312
|
+
center: item.center,
|
|
6313
|
+
width: item.width,
|
|
6314
|
+
height: item.height
|
|
6315
|
+
});
|
|
6316
|
+
} else if (item.type === "pcb_silkscreen_circle") {
|
|
6317
|
+
const radius = distance2.parse(item.radius);
|
|
6318
|
+
if (radius !== void 0) {
|
|
6319
|
+
updateBounds({
|
|
6320
|
+
center: item.center,
|
|
6321
|
+
width: radius * 2,
|
|
6322
|
+
height: radius * 2
|
|
6323
|
+
});
|
|
6324
|
+
}
|
|
6325
|
+
} else if (item.type === "pcb_silkscreen_line") {
|
|
6326
|
+
updateBounds({ center: { x: item.x1, y: item.y1 }, width: 0, height: 0 });
|
|
6327
|
+
updateBounds({ center: { x: item.x2, y: item.y2 }, width: 0, height: 0 });
|
|
6328
|
+
} else if (item.type === "pcb_silkscreen_oval") {
|
|
6329
|
+
const radiusX = distance2.parse(item.radius_x);
|
|
6330
|
+
const radiusY = distance2.parse(item.radius_y);
|
|
6331
|
+
if (radiusX !== void 0 && radiusY !== void 0) {
|
|
6332
|
+
updateBounds({
|
|
6333
|
+
center: item.center,
|
|
6334
|
+
width: radiusX * 2,
|
|
6335
|
+
height: radiusY * 2
|
|
6336
|
+
});
|
|
6337
|
+
}
|
|
6338
|
+
} else if (item.type === "pcb_cutout") {
|
|
6339
|
+
const cutout = item;
|
|
6340
|
+
if (cutout.shape === "rect") {
|
|
6341
|
+
updateBounds({
|
|
6342
|
+
center: cutout.center,
|
|
6343
|
+
width: cutout.width,
|
|
6344
|
+
height: cutout.height
|
|
6345
|
+
});
|
|
6346
|
+
} else if (cutout.shape === "circle") {
|
|
6347
|
+
const radius = distance2.parse(cutout.radius);
|
|
6348
|
+
if (radius !== void 0) {
|
|
6349
|
+
updateBounds({
|
|
6350
|
+
center: cutout.center,
|
|
6351
|
+
width: radius * 2,
|
|
6352
|
+
height: radius * 2
|
|
6353
|
+
});
|
|
6354
|
+
}
|
|
6355
|
+
} else if (cutout.shape === "polygon") {
|
|
6356
|
+
updateTraceBounds(cutout.points);
|
|
6357
|
+
} else if (cutout.shape === "path") {
|
|
6358
|
+
const cutoutPath = cutout;
|
|
6359
|
+
if (cutoutPath.route && Array.isArray(cutoutPath.route)) {
|
|
6360
|
+
updateTraceBounds(cutoutPath.route);
|
|
6361
|
+
}
|
|
6362
|
+
}
|
|
6363
|
+
}
|
|
6364
|
+
}
|
|
6365
|
+
}
|
|
6366
|
+
|
|
6367
|
+
// lib/pcb/convert-circuit-json-to-pcb-svg.ts
|
|
6368
|
+
function convertCircuitJsonToPcbSvg(circuitJson, options) {
|
|
6369
|
+
const drawPaddingOutsideBoard = options?.drawPaddingOutsideBoard ?? true;
|
|
6370
|
+
const layer = options?.layer;
|
|
6371
|
+
const colorOverrides = options?.colorOverrides;
|
|
6372
|
+
const copperColors = {
|
|
6373
|
+
...DEFAULT_PCB_COLOR_MAP.copper
|
|
6374
|
+
};
|
|
6375
|
+
if (colorOverrides?.copper) {
|
|
6376
|
+
for (const [layerName, color] of Object.entries(colorOverrides.copper)) {
|
|
6377
|
+
if (color !== void 0) {
|
|
6378
|
+
copperColors[layerName] = color;
|
|
6379
|
+
}
|
|
6380
|
+
}
|
|
6381
|
+
}
|
|
6382
|
+
const colorMap2 = {
|
|
6383
|
+
copper: copperColors,
|
|
6384
|
+
drill: colorOverrides?.drill ?? DEFAULT_PCB_COLOR_MAP.drill,
|
|
6385
|
+
silkscreen: {
|
|
6386
|
+
top: colorOverrides?.silkscreen?.top ?? DEFAULT_PCB_COLOR_MAP.silkscreen.top,
|
|
6387
|
+
bottom: colorOverrides?.silkscreen?.bottom ?? DEFAULT_PCB_COLOR_MAP.silkscreen.bottom
|
|
6388
|
+
},
|
|
6389
|
+
boardOutline: colorOverrides?.boardOutline ?? DEFAULT_PCB_COLOR_MAP.boardOutline,
|
|
6390
|
+
soldermask: {
|
|
6391
|
+
top: colorOverrides?.soldermask?.top ?? DEFAULT_PCB_COLOR_MAP.soldermask.top,
|
|
6392
|
+
bottom: colorOverrides?.soldermask?.bottom ?? DEFAULT_PCB_COLOR_MAP.soldermask.bottom
|
|
6393
|
+
},
|
|
6394
|
+
soldermaskOverCopper: {
|
|
6395
|
+
top: colorOverrides?.soldermaskOverCopper?.top ?? DEFAULT_PCB_COLOR_MAP.soldermaskOverCopper.top,
|
|
6396
|
+
bottom: colorOverrides?.soldermaskOverCopper?.bottom ?? DEFAULT_PCB_COLOR_MAP.soldermaskOverCopper.bottom
|
|
6397
|
+
},
|
|
6398
|
+
soldermaskWithCopperUnderneath: {
|
|
6399
|
+
top: colorOverrides?.soldermaskWithCopperUnderneath?.top ?? DEFAULT_PCB_COLOR_MAP.soldermaskWithCopperUnderneath.top,
|
|
6400
|
+
bottom: colorOverrides?.soldermaskWithCopperUnderneath?.bottom ?? DEFAULT_PCB_COLOR_MAP.soldermaskWithCopperUnderneath.bottom
|
|
6401
|
+
},
|
|
6402
|
+
substrate: colorOverrides?.substrate ?? DEFAULT_PCB_COLOR_MAP.substrate,
|
|
6403
|
+
courtyard: colorOverrides?.courtyard ?? DEFAULT_PCB_COLOR_MAP.courtyard,
|
|
6404
|
+
keepout: colorOverrides?.keepout ?? DEFAULT_PCB_COLOR_MAP.keepout,
|
|
6405
|
+
debugComponent: {
|
|
6406
|
+
fill: colorOverrides?.debugComponent?.fill ?? DEFAULT_PCB_COLOR_MAP.debugComponent.fill,
|
|
6407
|
+
stroke: colorOverrides?.debugComponent?.stroke ?? DEFAULT_PCB_COLOR_MAP.debugComponent.stroke
|
|
6408
|
+
}
|
|
6409
|
+
};
|
|
6410
|
+
const {
|
|
6411
|
+
minX,
|
|
6412
|
+
minY,
|
|
6413
|
+
maxX,
|
|
6414
|
+
maxY,
|
|
6415
|
+
boardMinX,
|
|
6416
|
+
boardMinY,
|
|
6417
|
+
boardMaxX,
|
|
6418
|
+
boardMaxY,
|
|
6419
|
+
hasBoardBounds
|
|
6420
|
+
} = getPcbBoundsFromCircuitJson(circuitJson);
|
|
6206
6421
|
const padding = drawPaddingOutsideBoard ? 1 : 0;
|
|
6207
|
-
const boundsMinX = drawPaddingOutsideBoard || !
|
|
6208
|
-
const boundsMinY = drawPaddingOutsideBoard || !
|
|
6209
|
-
const boundsMaxX = drawPaddingOutsideBoard || !
|
|
6210
|
-
const boundsMaxY = drawPaddingOutsideBoard || !
|
|
6422
|
+
const boundsMinX = drawPaddingOutsideBoard || !hasBoardBounds ? minX : boardMinX;
|
|
6423
|
+
const boundsMinY = drawPaddingOutsideBoard || !hasBoardBounds ? minY : boardMinY;
|
|
6424
|
+
const boundsMaxX = drawPaddingOutsideBoard || !hasBoardBounds ? maxX : boardMaxX;
|
|
6425
|
+
const boundsMaxY = drawPaddingOutsideBoard || !hasBoardBounds ? maxY : boardMaxY;
|
|
6211
6426
|
const circuitWidth = boundsMaxX - boundsMinX + 2 * padding;
|
|
6212
6427
|
const circuitHeight = boundsMaxY - boundsMinY + 2 * padding;
|
|
6213
6428
|
let svgWidth = options?.width ?? 800;
|
|
@@ -6356,126 +6571,6 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
|
|
|
6356
6571
|
console.error("Error stringifying SVG object:", error);
|
|
6357
6572
|
throw error;
|
|
6358
6573
|
}
|
|
6359
|
-
function updateBounds(center, width, height) {
|
|
6360
|
-
if (!center) return;
|
|
6361
|
-
const centerX = distance2.parse(center.x);
|
|
6362
|
-
const centerY = distance2.parse(center.y);
|
|
6363
|
-
if (centerX === void 0 || centerY === void 0) return;
|
|
6364
|
-
const numericWidth = distance2.parse(width) ?? 0;
|
|
6365
|
-
const numericHeight = distance2.parse(height) ?? 0;
|
|
6366
|
-
const halfWidth = numericWidth / 2;
|
|
6367
|
-
const halfHeight = numericHeight / 2;
|
|
6368
|
-
minX = Math.min(minX, centerX - halfWidth);
|
|
6369
|
-
minY = Math.min(minY, centerY - halfHeight);
|
|
6370
|
-
maxX = Math.max(maxX, centerX + halfWidth);
|
|
6371
|
-
maxY = Math.max(maxY, centerY + halfHeight);
|
|
6372
|
-
hasBounds = true;
|
|
6373
|
-
}
|
|
6374
|
-
function updateBoardBounds(center, width, height) {
|
|
6375
|
-
if (!center) return;
|
|
6376
|
-
const centerX = distance2.parse(center.x);
|
|
6377
|
-
const centerY = distance2.parse(center.y);
|
|
6378
|
-
if (centerX === void 0 || centerY === void 0) return;
|
|
6379
|
-
const numericWidth = distance2.parse(width) ?? 0;
|
|
6380
|
-
const numericHeight = distance2.parse(height) ?? 0;
|
|
6381
|
-
const halfWidth = numericWidth / 2;
|
|
6382
|
-
const halfHeight = numericHeight / 2;
|
|
6383
|
-
boardMinX = Math.min(boardMinX, centerX - halfWidth);
|
|
6384
|
-
boardMinY = Math.min(boardMinY, centerY - halfHeight);
|
|
6385
|
-
boardMaxX = Math.max(boardMaxX, centerX + halfWidth);
|
|
6386
|
-
boardMaxY = Math.max(boardMaxY, centerY + halfHeight);
|
|
6387
|
-
hasBounds = true;
|
|
6388
|
-
hasBoardBounds = true;
|
|
6389
|
-
}
|
|
6390
|
-
function updateBoundsToIncludeOutline(outline) {
|
|
6391
|
-
let updated = false;
|
|
6392
|
-
for (const point of outline) {
|
|
6393
|
-
const x = distance2.parse(point.x);
|
|
6394
|
-
const y = distance2.parse(point.y);
|
|
6395
|
-
if (x === void 0 || y === void 0) continue;
|
|
6396
|
-
minX = Math.min(minX, x);
|
|
6397
|
-
minY = Math.min(minY, y);
|
|
6398
|
-
maxX = Math.max(maxX, x);
|
|
6399
|
-
maxY = Math.max(maxY, y);
|
|
6400
|
-
updated = true;
|
|
6401
|
-
}
|
|
6402
|
-
if (updated) {
|
|
6403
|
-
hasBounds = true;
|
|
6404
|
-
}
|
|
6405
|
-
}
|
|
6406
|
-
function updateBoardBoundsToIncludeOutline(outline) {
|
|
6407
|
-
let updated = false;
|
|
6408
|
-
for (const point of outline) {
|
|
6409
|
-
const x = distance2.parse(point.x);
|
|
6410
|
-
const y = distance2.parse(point.y);
|
|
6411
|
-
if (x === void 0 || y === void 0) continue;
|
|
6412
|
-
boardMinX = Math.min(boardMinX, x);
|
|
6413
|
-
boardMinY = Math.min(boardMinY, y);
|
|
6414
|
-
boardMaxX = Math.max(boardMaxX, x);
|
|
6415
|
-
boardMaxY = Math.max(boardMaxY, y);
|
|
6416
|
-
updated = true;
|
|
6417
|
-
}
|
|
6418
|
-
if (updated) {
|
|
6419
|
-
hasBounds = true;
|
|
6420
|
-
hasBoardBounds = true;
|
|
6421
|
-
}
|
|
6422
|
-
}
|
|
6423
|
-
function updateTraceBounds(route) {
|
|
6424
|
-
let updated = false;
|
|
6425
|
-
for (const point of route) {
|
|
6426
|
-
const x = distance2.parse(point?.x);
|
|
6427
|
-
const y = distance2.parse(point?.y);
|
|
6428
|
-
if (x === void 0 || y === void 0) continue;
|
|
6429
|
-
minX = Math.min(minX, x);
|
|
6430
|
-
minY = Math.min(minY, y);
|
|
6431
|
-
maxX = Math.max(maxX, x);
|
|
6432
|
-
maxY = Math.max(maxY, y);
|
|
6433
|
-
updated = true;
|
|
6434
|
-
}
|
|
6435
|
-
if (updated) {
|
|
6436
|
-
hasBounds = true;
|
|
6437
|
-
}
|
|
6438
|
-
}
|
|
6439
|
-
function updateSilkscreenBounds(item) {
|
|
6440
|
-
if (item.type === "pcb_silkscreen_text") {
|
|
6441
|
-
updateBounds(item.anchor_position, 0, 0);
|
|
6442
|
-
} else if (item.type === "pcb_silkscreen_path") {
|
|
6443
|
-
updateTraceBounds(item.route);
|
|
6444
|
-
} else if (item.type === "pcb_silkscreen_rect") {
|
|
6445
|
-
updateBounds(item.center, item.width, item.height);
|
|
6446
|
-
} else if (item.type === "pcb_silkscreen_circle") {
|
|
6447
|
-
const radius = distance2.parse(item.radius);
|
|
6448
|
-
if (radius !== void 0) {
|
|
6449
|
-
updateBounds(item.center, radius * 2, radius * 2);
|
|
6450
|
-
}
|
|
6451
|
-
} else if (item.type === "pcb_silkscreen_line") {
|
|
6452
|
-
updateBounds({ x: item.x1, y: item.y1 }, 0, 0);
|
|
6453
|
-
updateBounds({ x: item.x2, y: item.y2 }, 0, 0);
|
|
6454
|
-
} else if (item.type === "pcb_silkscreen_oval") {
|
|
6455
|
-
const radiusX = distance2.parse(item.radius_x);
|
|
6456
|
-
const radiusY = distance2.parse(item.radius_y);
|
|
6457
|
-
if (radiusX !== void 0 && radiusY !== void 0) {
|
|
6458
|
-
updateBounds(item.center, radiusX * 2, radiusY * 2);
|
|
6459
|
-
}
|
|
6460
|
-
} else if (item.type === "pcb_cutout") {
|
|
6461
|
-
const cutout = item;
|
|
6462
|
-
if (cutout.shape === "rect") {
|
|
6463
|
-
updateBounds(cutout.center, cutout.width, cutout.height);
|
|
6464
|
-
} else if (cutout.shape === "circle") {
|
|
6465
|
-
const radius = distance2.parse(cutout.radius);
|
|
6466
|
-
if (radius !== void 0) {
|
|
6467
|
-
updateBounds(cutout.center, radius * 2, radius * 2);
|
|
6468
|
-
}
|
|
6469
|
-
} else if (cutout.shape === "polygon") {
|
|
6470
|
-
updateTraceBounds(cutout.points);
|
|
6471
|
-
} else if (cutout.shape === "path") {
|
|
6472
|
-
const cutoutPath = cutout;
|
|
6473
|
-
if (cutoutPath.route && Array.isArray(cutoutPath.route)) {
|
|
6474
|
-
updateTraceBounds(cutoutPath.route);
|
|
6475
|
-
}
|
|
6476
|
-
}
|
|
6477
|
-
}
|
|
6478
|
-
}
|
|
6479
6574
|
}
|
|
6480
6575
|
function createSvgObjects({
|
|
6481
6576
|
elm,
|
|
@@ -13271,7 +13366,7 @@ function formatNumber2(value) {
|
|
|
13271
13366
|
}
|
|
13272
13367
|
|
|
13273
13368
|
// lib/pcb/convert-circuit-json-to-solder-paste-mask.ts
|
|
13274
|
-
import { distance as
|
|
13369
|
+
import { distance as distance4 } from "circuit-json";
|
|
13275
13370
|
import { stringify as stringify7 } from "svgson";
|
|
13276
13371
|
import {
|
|
13277
13372
|
applyToPoint as applyToPoint76,
|
|
@@ -13389,8 +13484,8 @@ function convertCircuitJsonToSolderPasteMask(circuitJson, options) {
|
|
|
13389
13484
|
}
|
|
13390
13485
|
} else if (item.type === "pcb_panel") {
|
|
13391
13486
|
const panel = item;
|
|
13392
|
-
const width =
|
|
13393
|
-
const height =
|
|
13487
|
+
const width = distance4.parse(panel.width);
|
|
13488
|
+
const height = distance4.parse(panel.height);
|
|
13394
13489
|
if (width !== void 0 && height !== void 0) {
|
|
13395
13490
|
const center = panel.center ?? { x: width / 2, y: height / 2 };
|
|
13396
13491
|
updateBounds(center, width, height);
|