circuit-to-svg 0.0.111 → 0.0.113

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
@@ -3,7 +3,7 @@ import { stringify } from "svgson";
3
3
  import {
4
4
  applyToPoint as applyToPoint16,
5
5
  compose as compose3,
6
- scale,
6
+ scale as scale2,
7
7
  translate as translate3
8
8
  } from "transformation-matrix";
9
9
 
@@ -333,11 +333,67 @@ function createSvgObjectsFromPcbPlatedHole(hole, transform) {
333
333
  }
334
334
  ];
335
335
  }
336
+ if (hole.shape === "pill_hole_with_rect_pad") {
337
+ const scaledRectPadWidth = hole.rect_pad_width * Math.abs(transform.a);
338
+ const scaledRectPadHeight = hole.rect_pad_height * Math.abs(transform.a);
339
+ const scaledHoleHeight = hole.hole_height * Math.abs(transform.a);
340
+ const scaledHoleWidth = hole.hole_width * Math.abs(transform.a);
341
+ const holeRadius = Math.min(scaledHoleHeight, scaledHoleWidth) / 2;
342
+ return [
343
+ {
344
+ name: "g",
345
+ type: "element",
346
+ children: [
347
+ // Rectangular pad (outer shape)
348
+ {
349
+ name: "rect",
350
+ type: "element",
351
+ attributes: {
352
+ class: "pcb-hole-outer-pad",
353
+ fill: "rgb(200, 52, 52)",
354
+ x: (x - scaledRectPadWidth / 2).toString(),
355
+ y: (y - scaledRectPadHeight / 2).toString(),
356
+ width: scaledRectPadWidth.toString(),
357
+ height: scaledRectPadHeight.toString()
358
+ },
359
+ value: "",
360
+ children: []
361
+ },
362
+ // pill hole inside the rectangle
363
+ {
364
+ name: "rect",
365
+ type: "element",
366
+ attributes: {
367
+ class: "pcb-hole-inner",
368
+ fill: "rgb(255, 38, 226)",
369
+ x: (x - scaledHoleWidth / 2).toString(),
370
+ y: (y - scaledHoleHeight / 2).toString(),
371
+ width: scaledHoleWidth.toString(),
372
+ height: scaledHoleHeight.toString(),
373
+ rx: holeRadius.toString(),
374
+ ry: holeRadius.toString()
375
+ },
376
+ value: "",
377
+ children: []
378
+ }
379
+ ],
380
+ value: "",
381
+ attributes: {}
382
+ }
383
+ ];
384
+ }
336
385
  return [];
337
386
  }
338
387
 
339
388
  // lib/pcb/svg-object-fns/create-svg-objects-from-pcb-silkscreen-path.ts
340
389
  import { applyToPoint as applyToPoint5 } from "transformation-matrix";
390
+
391
+ // lib/pcb/colors.ts
392
+ var HOLE_COLOR = "#FF26E2";
393
+ var SILKSCREEN_TOP_COLOR = "#f2eda1";
394
+ var SILKSCREEN_BOTTOM_COLOR = "#5da9e9";
395
+
396
+ // lib/pcb/svg-object-fns/create-svg-objects-from-pcb-silkscreen-path.ts
341
397
  function createSvgObjectsFromPcbSilkscreenPath(silkscreenPath, transform) {
342
398
  if (!silkscreenPath.route || !Array.isArray(silkscreenPath.route)) return [];
343
399
  let path = silkscreenPath.route.map((point, index) => {
@@ -349,15 +405,17 @@ function createSvgObjectsFromPcbSilkscreenPath(silkscreenPath, transform) {
349
405
  if (firstPoint && lastPoint && firstPoint.x === lastPoint.x && firstPoint.y === lastPoint.y) {
350
406
  path += " Z";
351
407
  }
408
+ const layer = silkscreenPath.layer || "top";
409
+ const color = layer === "bottom" ? SILKSCREEN_BOTTOM_COLOR : SILKSCREEN_TOP_COLOR;
352
410
  return [
353
411
  {
354
412
  name: "path",
355
413
  type: "element",
356
414
  attributes: {
357
- class: `pcb-silkscreen pcb-silkscreen-${silkscreenPath.layer}`,
415
+ class: `pcb-silkscreen pcb-silkscreen-${layer}`,
358
416
  d: path,
359
417
  fill: "none",
360
- stroke: "#f2eda1",
418
+ stroke: color,
361
419
  "stroke-width": (silkscreenPath.stroke_width * Math.abs(transform.a)).toString(),
362
420
  "data-pcb-component-id": silkscreenPath.pcb_component_id,
363
421
  "data-pcb-silkscreen-path-id": silkscreenPath.pcb_silkscreen_path_id
@@ -374,6 +432,7 @@ import {
374
432
  compose as compose2,
375
433
  rotate as rotate2,
376
434
  translate as translate2,
435
+ scale,
377
436
  toString as matrixToString2
378
437
  } from "transformation-matrix";
379
438
  function createSvgObjectsFromPcbSilkscreenText(pcbSilkscreenText, transform) {
@@ -382,8 +441,7 @@ function createSvgObjectsFromPcbSilkscreenText(pcbSilkscreenText, transform) {
382
441
  text,
383
442
  font_size = 1,
384
443
  layer = "top",
385
- ccw_rotation = 0,
386
- stroke_width = 0
444
+ ccw_rotation = 0
387
445
  } = pcbSilkscreenText;
388
446
  if (!anchor_position || typeof anchor_position.x !== "number" || typeof anchor_position.y !== "number") {
389
447
  console.error("Invalid anchor_position:", anchor_position);
@@ -394,18 +452,19 @@ function createSvgObjectsFromPcbSilkscreenText(pcbSilkscreenText, transform) {
394
452
  anchor_position.y
395
453
  ]);
396
454
  const transformedFontSize = font_size * Math.abs(transform.a);
397
- const transformedStrokeWidth = stroke_width * Math.abs(transform.a);
398
455
  const textTransform = compose2(
399
456
  translate2(transformedX, transformedY),
400
- rotate2(ccw_rotation * Math.PI / 180)
457
+ rotate2(ccw_rotation * Math.PI / 180),
458
+ ...layer === "bottom" ? [scale(-1, 1)] : []
401
459
  );
460
+ const color = layer === "bottom" ? SILKSCREEN_BOTTOM_COLOR : SILKSCREEN_TOP_COLOR;
402
461
  const svgObject = {
403
462
  name: "text",
404
463
  type: "element",
405
464
  attributes: {
406
465
  x: "0",
407
466
  y: "0",
408
- fill: "#f2eda1",
467
+ fill: color,
409
468
  "font-family": "Arial, sans-serif",
410
469
  "font-size": transformedFontSize.toString(),
411
470
  "text-anchor": "middle",
@@ -413,8 +472,7 @@ function createSvgObjectsFromPcbSilkscreenText(pcbSilkscreenText, transform) {
413
472
  transform: matrixToString2(textTransform),
414
473
  class: `pcb-silkscreen-text pcb-silkscreen-${layer}`,
415
474
  "data-pcb-silkscreen-text-id": pcbSilkscreenText.pcb_component_id,
416
- stroke: "#f2eda1",
417
- "stroke-width": transformedStrokeWidth.toString()
475
+ stroke: color
418
476
  },
419
477
  children: [
420
478
  {
@@ -454,6 +512,7 @@ function createSvgObjectsFromPcbSilkscreenRect(pcbSilkscreenRect, transform) {
454
512
  const transformedWidth = width * Math.abs(transform.a);
455
513
  const transformedHeight = height * Math.abs(transform.d);
456
514
  const transformedStrokeWidth = stroke_width * Math.abs(transform.a);
515
+ const color = layer === "bottom" ? SILKSCREEN_BOTTOM_COLOR : SILKSCREEN_TOP_COLOR;
457
516
  const svgObject = {
458
517
  name: "rect",
459
518
  type: "element",
@@ -464,7 +523,7 @@ function createSvgObjectsFromPcbSilkscreenRect(pcbSilkscreenRect, transform) {
464
523
  height: transformedHeight.toString(),
465
524
  class: `pcb-silkscreen-rect pcb-silkscreen-${layer}`,
466
525
  fill: "none",
467
- stroke: "#f2eda1",
526
+ stroke: color,
468
527
  "stroke-width": transformedStrokeWidth.toString(),
469
528
  "data-pcb-silkscreen-rect-id": pcb_silkscreen_rect_id
470
529
  },
@@ -496,6 +555,7 @@ function createSvgObjectsFromPcbSilkscreenCircle(pcbSilkscreenCircle, transform)
496
555
  ]);
497
556
  const transformedRadius = radius * Math.abs(transform.a);
498
557
  const transformedStrokeWidth = stroke_width * Math.abs(transform.a);
558
+ const color = layer === "bottom" ? SILKSCREEN_BOTTOM_COLOR : SILKSCREEN_TOP_COLOR;
499
559
  const svgObject = {
500
560
  name: "circle",
501
561
  type: "element",
@@ -504,7 +564,7 @@ function createSvgObjectsFromPcbSilkscreenCircle(pcbSilkscreenCircle, transform)
504
564
  cy: transformedY.toString(),
505
565
  r: transformedRadius.toString(),
506
566
  class: `pcb-silkscreen-circle pcb-silkscreen-${layer}`,
507
- stroke: "#f2eda1",
567
+ stroke: color,
508
568
  "stroke-width": transformedStrokeWidth.toString(),
509
569
  "data-pcb-silkscreen-circle-id": pcb_silkscreen_circle_id
510
570
  },
@@ -535,6 +595,7 @@ function createSvgObjectsFromPcbSilkscreenLine(pcbSilkscreenLine, transform) {
535
595
  const [transformedX1, transformedY1] = applyToPoint9(transform, [x1, y1]);
536
596
  const [transformedX2, transformedY2] = applyToPoint9(transform, [x2, y2]);
537
597
  const transformedStrokeWidth = stroke_width * Math.abs(transform.a);
598
+ const color = layer === "bottom" ? SILKSCREEN_BOTTOM_COLOR : SILKSCREEN_TOP_COLOR;
538
599
  return [
539
600
  {
540
601
  name: "line",
@@ -544,7 +605,7 @@ function createSvgObjectsFromPcbSilkscreenLine(pcbSilkscreenLine, transform) {
544
605
  y1: transformedY1.toString(),
545
606
  x2: transformedX2.toString(),
546
607
  y2: transformedY2.toString(),
547
- stroke: "#f2eda1",
608
+ stroke: color,
548
609
  "stroke-width": transformedStrokeWidth.toString(),
549
610
  class: `pcb-silkscreen-line pcb-silkscreen-${layer}`,
550
611
  "data-pcb-silkscreen-line-id": pcb_silkscreen_line_id
@@ -776,11 +837,6 @@ function createSvgObjectsFromPcbVia(hole, transform) {
776
837
 
777
838
  // lib/pcb/svg-object-fns/create-svg-objects-from-pcb-hole.ts
778
839
  import { applyToPoint as applyToPoint14 } from "transformation-matrix";
779
-
780
- // lib/pcb/colors.ts
781
- var HOLE_COLOR = "#FF26E2";
782
-
783
- // lib/pcb/svg-object-fns/create-svg-objects-from-pcb-hole.ts
784
840
  function createSvgObjectsFromPcbHole(hole, transform) {
785
841
  const [x, y] = applyToPoint14(transform, [hole.x, hole.y]);
786
842
  if (hole.hole_shape === "circle" || hole.hole_shape === "square") {
@@ -1011,7 +1067,7 @@ function convertCircuitJsonToPcbSvg(soup, options) {
1011
1067
  offsetX - minX * scaleFactor + padding * scaleFactor,
1012
1068
  svgHeight - offsetY + minY * scaleFactor - padding * scaleFactor
1013
1069
  ),
1014
- scale(scaleFactor, -scaleFactor)
1070
+ scale2(scaleFactor, -scaleFactor)
1015
1071
  // Flip in y-direction
1016
1072
  );
1017
1073
  let svgObjects = soup.sort(
@@ -1220,7 +1276,7 @@ import { su as su3 } from "@tscircuit/soup-util";
1220
1276
  import {
1221
1277
  applyToPoint as applyToPoint20,
1222
1278
  compose as compose4,
1223
- scale as scale2,
1279
+ scale as scale3,
1224
1280
  translate as translate4
1225
1281
  } from "transformation-matrix";
1226
1282
 
@@ -1339,9 +1395,9 @@ function createComponentPath(scaledWidth, scaledHeight, centerX, centerY, pinX,
1339
1395
  };
1340
1396
  }
1341
1397
  function createComponentLabel(scaledWidth, scaledHeight, name, transform) {
1342
- const scale7 = Math.min(scaledWidth, scaledHeight) * 0.4;
1343
- const fontSize = getSchScreenFontSize(transform, "net_label") * (scale7 / 2.5);
1344
- const scaledFontSize = scale7 < 25 ? fontSize : fontSize * 0.6;
1398
+ const scale8 = Math.min(scaledWidth, scaledHeight) * 0.4;
1399
+ const fontSize = getSchScreenFontSize(transform, "net_label") * (scale8 / 2.5);
1400
+ const scaledFontSize = scale8 < 25 ? fontSize : fontSize * 0.6;
1345
1401
  return {
1346
1402
  name: "text",
1347
1403
  type: "element",
@@ -1445,7 +1501,7 @@ function convertCircuitJsonToAssemblySvg(soup, options) {
1445
1501
  offsetX - minX * scaleFactor + padding * scaleFactor,
1446
1502
  svgHeight - offsetY + minY * scaleFactor - padding * scaleFactor
1447
1503
  ),
1448
- scale2(scaleFactor, -scaleFactor)
1504
+ scale3(scaleFactor, -scaleFactor)
1449
1505
  // Flip in y-direction
1450
1506
  );
1451
1507
  const svgObjects = soup.sort(
@@ -2079,7 +2135,7 @@ var matchSchPortsToSymbolPorts = ({
2079
2135
  };
2080
2136
 
2081
2137
  // lib/utils/point-pairs-to-matrix.ts
2082
- import { compose as compose5, scale as scale3, translate as translate5 } from "transformation-matrix";
2138
+ import { compose as compose5, scale as scale4, translate as translate5 } from "transformation-matrix";
2083
2139
  function pointPairsToMatrix(a1, a2, b1, b2) {
2084
2140
  const tx = a2.x - a1.x;
2085
2141
  const ty = a2.y - a1.y;
@@ -2087,7 +2143,7 @@ function pointPairsToMatrix(a1, a2, b1, b2) {
2087
2143
  const transformedDistance = Math.sqrt((b2.x - a2.x) ** 2 + (b2.y - a2.y) ** 2);
2088
2144
  const a = transformedDistance / originalDistance;
2089
2145
  const translateMatrix = translate5(tx, ty);
2090
- const scaleMatrix = scale3(a, a);
2146
+ const scaleMatrix = scale4(a, a);
2091
2147
  return compose5(translateMatrix, scaleMatrix);
2092
2148
  }
2093
2149
 
@@ -2989,7 +3045,7 @@ import {
2989
3045
  applyToPoint as applyToPoint35,
2990
3046
  compose as compose8,
2991
3047
  rotate as rotate4,
2992
- scale as scale5,
3048
+ scale as scale6,
2993
3049
  translate as translate8
2994
3050
  } from "transformation-matrix";
2995
3051
 
@@ -3777,7 +3833,7 @@ import {
3777
3833
  applyToPoint as applyToPoint34,
3778
3834
  compose as compose7,
3779
3835
  rotate as rotate3,
3780
- scale as scale4,
3836
+ scale as scale5,
3781
3837
  translate as translate7
3782
3838
  } from "transformation-matrix";
3783
3839
  import { symbols as symbols3 } from "schematic-symbols";
@@ -3811,8 +3867,8 @@ var ninePointAnchorToDominantBaseline = {
3811
3867
  middle_bottom: "hanging"
3812
3868
  };
3813
3869
  function getTextOffsets(pathRotation, transform) {
3814
- const scale7 = Math.abs(transform.a);
3815
- const baseOffset = scale7 * 0.1;
3870
+ const scale8 = Math.abs(transform.a);
3871
+ const baseOffset = scale8 * 0.1;
3816
3872
  const rotationOffsetMap = {
3817
3873
  "0": { x: baseOffset * 0.8, y: -baseOffset },
3818
3874
  // Left
@@ -3901,7 +3957,7 @@ var createSvgObjectsForSchNetLabelWithSymbol = (schNetLabel, realToScreenTransfo
3901
3957
  realAnchorPosition.y - rotatedSymbolEnd.y
3902
3958
  ),
3903
3959
  rotationMatrix,
3904
- scale4(1)
3960
+ scale5(1)
3905
3961
  // Use full symbol size
3906
3962
  );
3907
3963
  const [screenMinX, screenMinY] = applyToPoint34(
@@ -3962,8 +4018,8 @@ var createSvgObjectsForSchNetLabelWithSymbol = (schNetLabel, realToScreenTransfo
3962
4018
  } else if (textValue === "{VAL}") {
3963
4019
  textValue = "";
3964
4020
  }
3965
- const scale7 = Math.abs(realToScreenTransform.a);
3966
- const baseOffset = scale7 * 0.1;
4021
+ const scale8 = Math.abs(realToScreenTransform.a);
4022
+ const baseOffset = scale8 * 0.1;
3967
4023
  const rotationOffset = getTextOffsets(pathRotation, realToScreenTransform);
3968
4024
  const offsetScreenPos = {
3969
4025
  x: screenTextPos.x + rotationOffset.x,
@@ -4108,7 +4164,7 @@ var createSvgObjectsForSchNetLabel = (schNetLabel, realToScreenTransform) => {
4108
4164
  compose8(
4109
4165
  realToScreenTransform,
4110
4166
  translate8(realAnchorPosition.x, realAnchorPosition.y),
4111
- scale5(fontSizeMm),
4167
+ scale6(fontSizeMm),
4112
4168
  rotate4(pathRotation / 180 * Math.PI)
4113
4169
  ),
4114
4170
  fontRelativePoint