circuit-to-svg 0.0.258 → 0.0.260

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 CHANGED
@@ -1,4 +1,5 @@
1
1
  // lib/pcb/convert-circuit-json-to-pcb-svg.ts
2
+ import { distance } from "circuit-json";
2
3
  import { stringify } from "svgson";
3
4
  import {
4
5
  applyToPoint as applyToPoint31,
@@ -537,7 +538,8 @@ function createSvgObjectsFromPcbFabricationNoteRect(fabricationNoteRect, ctx) {
537
538
  color,
538
539
  layer = "top",
539
540
  pcb_component_id,
540
- pcb_fabrication_note_rect_id
541
+ pcb_fabrication_note_rect_id,
542
+ corner_radius
541
543
  } = fabricationNoteRect;
542
544
  if (layerFilter && layer !== layerFilter) return [];
543
545
  if (!center || typeof center.x !== "number" || typeof center.y !== "number" || typeof width !== "number" || typeof height !== "number") {
@@ -565,6 +567,9 @@ function createSvgObjectsFromPcbFabricationNoteRect(fabricationNoteRect, ctx) {
565
567
  const baseStrokeWidth = typeof stroke_width === "number" ? stroke_width : 0;
566
568
  const transformedStrokeWidth = baseStrokeWidth * Math.abs(transform.a);
567
569
  const overlayStrokeColor = color ?? DEFAULT_OVERLAY_STROKE_COLOR;
570
+ const baseCornerRadius = typeof corner_radius === "number" && corner_radius > 0 ? corner_radius : 0;
571
+ const transformedCornerRadiusX = baseCornerRadius * Math.abs(transform.a);
572
+ const transformedCornerRadiusY = baseCornerRadius * Math.abs(transform.d);
568
573
  const attributes = {
569
574
  x: rectX.toString(),
570
575
  y: rectY.toString(),
@@ -578,6 +583,12 @@ function createSvgObjectsFromPcbFabricationNoteRect(fabricationNoteRect, ctx) {
578
583
  if (pcb_component_id !== void 0) {
579
584
  attributes["data-pcb-component-id"] = pcb_component_id;
580
585
  }
586
+ if (transformedCornerRadiusX > 0) {
587
+ attributes.rx = transformedCornerRadiusX.toString();
588
+ }
589
+ if (transformedCornerRadiusY > 0) {
590
+ attributes.ry = transformedCornerRadiusY.toString();
591
+ }
581
592
  if (is_filled) {
582
593
  attributes.fill = color ?? DEFAULT_OVERLAY_FILL_COLOR;
583
594
  } else {
@@ -1410,7 +1421,8 @@ function createSvgObjectsFromPcbNoteRect(noteRect, ctx) {
1410
1421
  is_filled,
1411
1422
  has_stroke,
1412
1423
  is_stroke_dashed,
1413
- color
1424
+ color,
1425
+ corner_radius
1414
1426
  } = noteRect;
1415
1427
  if (!center || typeof center.x !== "number" || typeof center.y !== "number" || typeof width !== "number" || typeof height !== "number") {
1416
1428
  console.error("Invalid pcb_note_rect data", { center, width, height });
@@ -1432,6 +1444,9 @@ function createSvgObjectsFromPcbNoteRect(noteRect, ctx) {
1432
1444
  const rectHeight = Math.abs(bottomRightY - topLeftY);
1433
1445
  const baseStrokeWidth = typeof stroke_width === "number" ? stroke_width : 0;
1434
1446
  const transformedStrokeWidth = baseStrokeWidth * Math.abs(transform.a);
1447
+ const baseCornerRadius = typeof corner_radius === "number" && corner_radius > 0 ? corner_radius : 0;
1448
+ const transformedCornerRadiusX = baseCornerRadius * Math.abs(transform.a);
1449
+ const transformedCornerRadiusY = baseCornerRadius * Math.abs(transform.d);
1435
1450
  const overlayColor = color ?? DEFAULT_OVERLAY_COLOR2;
1436
1451
  const attributes = {
1437
1452
  x: rectX.toString(),
@@ -1443,6 +1458,12 @@ function createSvgObjectsFromPcbNoteRect(noteRect, ctx) {
1443
1458
  "data-pcb-note-rect-id": noteRect.pcb_note_rect_id,
1444
1459
  "data-pcb-layer": "overlay"
1445
1460
  };
1461
+ if (transformedCornerRadiusX > 0) {
1462
+ attributes.rx = transformedCornerRadiusX.toString();
1463
+ }
1464
+ if (transformedCornerRadiusY > 0) {
1465
+ attributes.ry = transformedCornerRadiusY.toString();
1466
+ }
1446
1467
  if (is_filled) {
1447
1468
  attributes.fill = color ?? DEFAULT_FILL_COLOR;
1448
1469
  } else {
@@ -2066,7 +2087,8 @@ function createSvgObjectsFromPcbSilkscreenRect(pcbSilkscreenRect, ctx) {
2066
2087
  stroke_width,
2067
2088
  is_filled,
2068
2089
  has_stroke,
2069
- is_stroke_dashed
2090
+ is_stroke_dashed,
2091
+ corner_radius
2070
2092
  } = pcbSilkscreenRect;
2071
2093
  if (layerFilter && layer !== layerFilter) return [];
2072
2094
  if (!center || typeof center.x !== "number" || typeof center.y !== "number" || typeof width !== "number" || typeof height !== "number") {
@@ -2077,6 +2099,9 @@ function createSvgObjectsFromPcbSilkscreenRect(pcbSilkscreenRect, ctx) {
2077
2099
  center.x,
2078
2100
  center.y
2079
2101
  ]);
2102
+ const baseCornerRadius = typeof corner_radius === "number" && corner_radius > 0 ? corner_radius : 0;
2103
+ const transformedCornerRadiusX = baseCornerRadius * Math.abs(transform.a);
2104
+ const transformedCornerRadiusY = baseCornerRadius * Math.abs(transform.d);
2080
2105
  const transformedWidth = width * Math.abs(transform.a);
2081
2106
  const transformedHeight = height * Math.abs(transform.d);
2082
2107
  const transformedStrokeWidth = stroke_width * Math.abs(transform.a);
@@ -2091,6 +2116,12 @@ function createSvgObjectsFromPcbSilkscreenRect(pcbSilkscreenRect, ctx) {
2091
2116
  "data-type": "pcb_silkscreen_rect",
2092
2117
  "data-pcb-layer": layer
2093
2118
  };
2119
+ if (transformedCornerRadiusX > 0) {
2120
+ attributes.rx = transformedCornerRadiusX.toString();
2121
+ }
2122
+ if (transformedCornerRadiusY > 0) {
2123
+ attributes.ry = transformedCornerRadiusY.toString();
2124
+ }
2094
2125
  attributes.fill = is_filled ? color : "none";
2095
2126
  let actualHasStroke;
2096
2127
  if (has_stroke === void 0) {
@@ -2902,9 +2933,9 @@ var findNearestPointInNet = (sourcePoint, netId, connectivity, circuitJson) => {
2902
2933
  if (pos) {
2903
2934
  const dx = sourcePoint.x - pos.x;
2904
2935
  const dy = sourcePoint.y - pos.y;
2905
- const distance = Math.sqrt(dx * dx + dy * dy);
2906
- if (distance > 0 && distance < minDistance) {
2907
- minDistance = distance;
2936
+ const distance3 = Math.sqrt(dx * dx + dy * dy);
2937
+ if (distance3 > 0 && distance3 < minDistance) {
2938
+ minDistance = distance3;
2908
2939
  nearestPoint = pos;
2909
2940
  }
2910
2941
  }
@@ -3471,7 +3502,7 @@ function getSoftwareUsedString(circuitJson) {
3471
3502
  var package_default = {
3472
3503
  name: "circuit-to-svg",
3473
3504
  type: "module",
3474
- version: "0.0.257",
3505
+ version: "0.0.259",
3475
3506
  description: "Convert Circuit JSON to SVG",
3476
3507
  main: "dist/index.js",
3477
3508
  files: [
@@ -3495,12 +3526,12 @@ var package_default = {
3495
3526
  "bun-match-svg": "^0.0.12",
3496
3527
  esbuild: "^0.20.2",
3497
3528
  "performance-now": "^2.1.0",
3498
- "circuit-json": "^0.0.292",
3529
+ "circuit-json": "^0.0.297",
3499
3530
  react: "19.1.0",
3500
3531
  "react-cosmos": "7.0.0",
3501
3532
  "react-cosmos-plugin-vite": "7.0.0",
3502
3533
  "react-dom": "19.1.0",
3503
- tscircuit: "^0.0.743",
3534
+ tscircuit: "^0.0.827",
3504
3535
  tsup: "^8.0.2",
3505
3536
  typescript: "^5.4.5",
3506
3537
  "vite-tsconfig-paths": "^5.0.1"
@@ -3640,14 +3671,13 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
3640
3671
  for (const circuitJsonElm of circuitJson) {
3641
3672
  if (circuitJsonElm.type === "pcb_panel") {
3642
3673
  const panel = circuitJsonElm;
3643
- const width = toNumeric(panel.width);
3644
- const height = toNumeric(panel.height);
3674
+ const width = distance.parse(panel.width);
3675
+ const height = distance.parse(panel.height);
3645
3676
  if (width === void 0 || height === void 0) {
3646
3677
  continue;
3647
3678
  }
3648
3679
  const center = { x: width / 2, y: height / 2 };
3649
3680
  updateBounds(center, width, height);
3650
- updateBoardBounds(center, width, height);
3651
3681
  } else if (circuitJsonElm.type === "pcb_board") {
3652
3682
  if (circuitJsonElm.outline && Array.isArray(circuitJsonElm.outline) && circuitJsonElm.outline.length >= 3) {
3653
3683
  updateBoundsToIncludeOutline(circuitJsonElm.outline);
@@ -3664,20 +3694,20 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
3664
3694
  circuitJsonElm.height
3665
3695
  );
3666
3696
  }
3667
- } else if ("x" in circuitJsonElm && "y" in circuitJsonElm) {
3668
- updateBounds({ x: circuitJsonElm.x, y: circuitJsonElm.y }, 0, 0);
3669
3697
  } else if (circuitJsonElm.type === "pcb_smtpad") {
3670
3698
  const pad = circuitJsonElm;
3671
3699
  if (pad.shape === "rect" || pad.shape === "rotated_rect" || pad.shape === "pill") {
3672
3700
  updateBounds({ x: pad.x, y: pad.y }, pad.width, pad.height);
3673
3701
  } else if (pad.shape === "circle") {
3674
- const radius = toNumeric(pad.radius);
3702
+ const radius = distance.parse(pad.radius);
3675
3703
  if (radius !== void 0) {
3676
3704
  updateBounds({ x: pad.x, y: pad.y }, radius * 2, radius * 2);
3677
3705
  }
3678
3706
  } else if (pad.shape === "polygon") {
3679
3707
  updateTraceBounds(pad.points);
3680
3708
  }
3709
+ } else if ("x" in circuitJsonElm && "y" in circuitJsonElm) {
3710
+ updateBounds({ x: circuitJsonElm.x, y: circuitJsonElm.y }, 0, 0);
3681
3711
  } else if ("route" in circuitJsonElm) {
3682
3712
  updateTraceBounds(circuitJsonElm.route);
3683
3713
  } else if (circuitJsonElm.type === "pcb_note_rect" || circuitJsonElm.type === "pcb_fabrication_note_rect") {
@@ -3691,7 +3721,7 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
3691
3721
  if (cutout.shape === "rect") {
3692
3722
  updateBounds(cutout.center, cutout.width, cutout.height);
3693
3723
  } else if (cutout.shape === "circle") {
3694
- const radius = toNumeric(cutout.radius);
3724
+ const radius = distance.parse(cutout.radius);
3695
3725
  if (radius !== void 0) {
3696
3726
  updateBounds(cutout.center, radius * 2, radius * 2);
3697
3727
  }
@@ -3854,23 +3884,13 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
3854
3884
  console.error("Error stringifying SVG object:", error);
3855
3885
  throw error;
3856
3886
  }
3857
- function toNumeric(value) {
3858
- if (typeof value === "number") {
3859
- return Number.isFinite(value) ? value : void 0;
3860
- }
3861
- if (typeof value === "string") {
3862
- const parsed = Number.parseFloat(value);
3863
- return Number.isFinite(parsed) ? parsed : void 0;
3864
- }
3865
- return void 0;
3866
- }
3867
3887
  function updateBounds(center, width, height) {
3868
3888
  if (!center) return;
3869
- const centerX = toNumeric(center.x);
3870
- const centerY = toNumeric(center.y);
3889
+ const centerX = distance.parse(center.x);
3890
+ const centerY = distance.parse(center.y);
3871
3891
  if (centerX === void 0 || centerY === void 0) return;
3872
- const numericWidth = toNumeric(width) ?? 0;
3873
- const numericHeight = toNumeric(height) ?? 0;
3892
+ const numericWidth = distance.parse(width) ?? 0;
3893
+ const numericHeight = distance.parse(height) ?? 0;
3874
3894
  const halfWidth = numericWidth / 2;
3875
3895
  const halfHeight = numericHeight / 2;
3876
3896
  minX = Math.min(minX, centerX - halfWidth);
@@ -3881,11 +3901,11 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
3881
3901
  }
3882
3902
  function updateBoardBounds(center, width, height) {
3883
3903
  if (!center) return;
3884
- const centerX = toNumeric(center.x);
3885
- const centerY = toNumeric(center.y);
3904
+ const centerX = distance.parse(center.x);
3905
+ const centerY = distance.parse(center.y);
3886
3906
  if (centerX === void 0 || centerY === void 0) return;
3887
- const numericWidth = toNumeric(width) ?? 0;
3888
- const numericHeight = toNumeric(height) ?? 0;
3907
+ const numericWidth = distance.parse(width) ?? 0;
3908
+ const numericHeight = distance.parse(height) ?? 0;
3889
3909
  const halfWidth = numericWidth / 2;
3890
3910
  const halfHeight = numericHeight / 2;
3891
3911
  boardMinX = Math.min(boardMinX, centerX - halfWidth);
@@ -3898,8 +3918,8 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
3898
3918
  function updateBoundsToIncludeOutline(outline) {
3899
3919
  let updated = false;
3900
3920
  for (const point of outline) {
3901
- const x = toNumeric(point.x);
3902
- const y = toNumeric(point.y);
3921
+ const x = distance.parse(point.x);
3922
+ const y = distance.parse(point.y);
3903
3923
  if (x === void 0 || y === void 0) continue;
3904
3924
  minX = Math.min(minX, x);
3905
3925
  minY = Math.min(minY, y);
@@ -3914,8 +3934,8 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
3914
3934
  function updateBoardBoundsToIncludeOutline(outline) {
3915
3935
  let updated = false;
3916
3936
  for (const point of outline) {
3917
- const x = toNumeric(point.x);
3918
- const y = toNumeric(point.y);
3937
+ const x = distance.parse(point.x);
3938
+ const y = distance.parse(point.y);
3919
3939
  if (x === void 0 || y === void 0) continue;
3920
3940
  boardMinX = Math.min(boardMinX, x);
3921
3941
  boardMinY = Math.min(boardMinY, y);
@@ -3931,8 +3951,8 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
3931
3951
  function updateTraceBounds(route) {
3932
3952
  let updated = false;
3933
3953
  for (const point of route) {
3934
- const x = toNumeric(point?.x);
3935
- const y = toNumeric(point?.y);
3954
+ const x = distance.parse(point?.x);
3955
+ const y = distance.parse(point?.y);
3936
3956
  if (x === void 0 || y === void 0) continue;
3937
3957
  minX = Math.min(minX, x);
3938
3958
  minY = Math.min(minY, y);
@@ -3952,7 +3972,7 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
3952
3972
  } else if (item.type === "pcb_silkscreen_rect") {
3953
3973
  updateBounds(item.center, item.width, item.height);
3954
3974
  } else if (item.type === "pcb_silkscreen_circle") {
3955
- const radius = toNumeric(item.radius);
3975
+ const radius = distance.parse(item.radius);
3956
3976
  if (radius !== void 0) {
3957
3977
  updateBounds(item.center, radius * 2, radius * 2);
3958
3978
  }
@@ -3964,7 +3984,7 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
3964
3984
  if (cutout.shape === "rect") {
3965
3985
  updateBounds(cutout.center, cutout.width, cutout.height);
3966
3986
  } else if (cutout.shape === "circle") {
3967
- const radius = toNumeric(cutout.radius);
3987
+ const radius = distance.parse(cutout.radius);
3968
3988
  if (radius !== void 0) {
3969
3989
  updateBounds(cutout.center, radius * 2, radius * 2);
3970
3990
  }
@@ -10558,6 +10578,7 @@ function formatNumber2(value) {
10558
10578
  }
10559
10579
 
10560
10580
  // lib/pcb/convert-circuit-json-to-solder-paste-mask.ts
10581
+ import { distance as distance2 } from "circuit-json";
10561
10582
  import { stringify as stringify7 } from "svgson";
10562
10583
  import {
10563
10584
  applyToPoint as applyToPoint70,
@@ -10664,7 +10685,7 @@ function convertCircuitJsonToSolderPasteMask(circuitJson, options) {
10664
10685
  let maxX = Number.NEGATIVE_INFINITY;
10665
10686
  let maxY = Number.NEGATIVE_INFINITY;
10666
10687
  const filteredCircuitJson = circuitJson.filter(
10667
- (elm) => elm.type === "pcb_board" || elm.type === "pcb_solder_paste" && elm.layer === options.layer
10688
+ (elm) => elm.type === "pcb_board" || elm.type === "pcb_panel" || elm.type === "pcb_solder_paste" && elm.layer === options.layer
10668
10689
  );
10669
10690
  for (const item of filteredCircuitJson) {
10670
10691
  if (item.type === "pcb_board") {
@@ -10673,6 +10694,13 @@ function convertCircuitJsonToSolderPasteMask(circuitJson, options) {
10673
10694
  } else if ("center" in item && "width" in item && "height" in item) {
10674
10695
  updateBounds(item.center, item.width, item.height);
10675
10696
  }
10697
+ } else if (item.type === "pcb_panel") {
10698
+ const panel = item;
10699
+ const width = distance2.parse(panel.width);
10700
+ const height = distance2.parse(panel.height);
10701
+ if (width !== void 0 && height !== void 0) {
10702
+ updateBounds({ x: width / 2, y: height / 2 }, width, height);
10703
+ }
10676
10704
  } else if (item.type === "pcb_solder_paste" && "x" in item && "y" in item) {
10677
10705
  updateBounds({ x: item.x, y: item.y }, 0, 0);
10678
10706
  }