circuit-to-svg 0.0.271 → 0.0.273
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 +602 -301
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1580,9 +1580,12 @@ function createSvgObjectsFromPcbNoteLine(noteLine, ctx) {
|
|
|
1580
1580
|
// lib/pcb/svg-object-fns/create-svg-objects-from-pcb-plated-hole.ts
|
|
1581
1581
|
import { applyToPoint as applyToPoint12 } from "transformation-matrix";
|
|
1582
1582
|
function createSvgObjectsFromPcbPlatedHole(hole, ctx) {
|
|
1583
|
-
const { transform, colorMap: colorMap2 } = ctx;
|
|
1583
|
+
const { transform, colorMap: colorMap2, showSolderMask } = ctx;
|
|
1584
1584
|
const [x, y] = applyToPoint12(transform, [hole.x, hole.y]);
|
|
1585
1585
|
const copperLayer = Array.isArray(hole.layers) && hole.layers[0] || hole.layer || "top";
|
|
1586
|
+
const soldermaskMargin = (hole.soldermask_margin ?? 0) * Math.abs(transform.a);
|
|
1587
|
+
const shouldShowSolderMask = showSolderMask && soldermaskMargin !== 0;
|
|
1588
|
+
const solderMaskColor = colorMap2.soldermask.top;
|
|
1586
1589
|
if (hole.shape === "pill") {
|
|
1587
1590
|
const scaledOuterWidth = hole.outer_width * Math.abs(transform.a);
|
|
1588
1591
|
const scaledOuterHeight = hole.outer_height * Math.abs(transform.a);
|
|
@@ -1605,6 +1608,55 @@ function createSvgObjectsFromPcbPlatedHole(hole, ctx) {
|
|
|
1605
1608
|
return `M${-radius},0 a${radius},${radius} 0 0 1 ${width},0 a${radius},${radius} 0 0 1 ${-width},0 z`;
|
|
1606
1609
|
}
|
|
1607
1610
|
};
|
|
1611
|
+
const children = [
|
|
1612
|
+
// Outer pill shape
|
|
1613
|
+
{
|
|
1614
|
+
name: "path",
|
|
1615
|
+
type: "element",
|
|
1616
|
+
attributes: {
|
|
1617
|
+
class: "pcb-hole-outer",
|
|
1618
|
+
fill: colorMap2.copper.top,
|
|
1619
|
+
d: createPillPath(scaledOuterWidth, scaledOuterHeight),
|
|
1620
|
+
transform: outerTransform,
|
|
1621
|
+
"data-type": "pcb_plated_hole",
|
|
1622
|
+
"data-pcb-layer": copperLayer
|
|
1623
|
+
},
|
|
1624
|
+
value: "",
|
|
1625
|
+
children: []
|
|
1626
|
+
},
|
|
1627
|
+
// Inner pill shape
|
|
1628
|
+
{
|
|
1629
|
+
name: "path",
|
|
1630
|
+
type: "element",
|
|
1631
|
+
attributes: {
|
|
1632
|
+
class: "pcb-hole-inner",
|
|
1633
|
+
fill: colorMap2.drill,
|
|
1634
|
+
d: createPillPath(scaledHoleWidth, scaledHoleHeight),
|
|
1635
|
+
transform: innerTransform,
|
|
1636
|
+
"data-type": "pcb_plated_hole_drill",
|
|
1637
|
+
"data-pcb-layer": "drill"
|
|
1638
|
+
},
|
|
1639
|
+
value: "",
|
|
1640
|
+
children: []
|
|
1641
|
+
}
|
|
1642
|
+
];
|
|
1643
|
+
if (shouldShowSolderMask) {
|
|
1644
|
+
const maskWidth = scaledOuterWidth + 2 * soldermaskMargin;
|
|
1645
|
+
const maskHeight = scaledOuterHeight + 2 * soldermaskMargin;
|
|
1646
|
+
children.push({
|
|
1647
|
+
name: "path",
|
|
1648
|
+
type: "element",
|
|
1649
|
+
attributes: {
|
|
1650
|
+
class: "pcb-solder-mask",
|
|
1651
|
+
fill: solderMaskColor,
|
|
1652
|
+
d: createPillPath(maskWidth, maskHeight),
|
|
1653
|
+
transform: outerTransform,
|
|
1654
|
+
"data-type": "pcb_soldermask"
|
|
1655
|
+
},
|
|
1656
|
+
value: "",
|
|
1657
|
+
children: []
|
|
1658
|
+
});
|
|
1659
|
+
}
|
|
1608
1660
|
return [
|
|
1609
1661
|
{
|
|
1610
1662
|
name: "g",
|
|
@@ -1613,38 +1665,7 @@ function createSvgObjectsFromPcbPlatedHole(hole, ctx) {
|
|
|
1613
1665
|
"data-type": "pcb_plated_hole",
|
|
1614
1666
|
"data-pcb-layer": "through"
|
|
1615
1667
|
},
|
|
1616
|
-
children
|
|
1617
|
-
// Outer pill shape
|
|
1618
|
-
{
|
|
1619
|
-
name: "path",
|
|
1620
|
-
type: "element",
|
|
1621
|
-
attributes: {
|
|
1622
|
-
class: "pcb-hole-outer",
|
|
1623
|
-
fill: colorMap2.copper.top,
|
|
1624
|
-
d: createPillPath(scaledOuterWidth, scaledOuterHeight),
|
|
1625
|
-
transform: outerTransform,
|
|
1626
|
-
"data-type": "pcb_plated_hole",
|
|
1627
|
-
"data-pcb-layer": copperLayer
|
|
1628
|
-
},
|
|
1629
|
-
value: "",
|
|
1630
|
-
children: []
|
|
1631
|
-
},
|
|
1632
|
-
// Inner pill shape
|
|
1633
|
-
{
|
|
1634
|
-
name: "path",
|
|
1635
|
-
type: "element",
|
|
1636
|
-
attributes: {
|
|
1637
|
-
class: "pcb-hole-inner",
|
|
1638
|
-
fill: colorMap2.drill,
|
|
1639
|
-
d: createPillPath(scaledHoleWidth, scaledHoleHeight),
|
|
1640
|
-
transform: innerTransform,
|
|
1641
|
-
"data-type": "pcb_plated_hole_drill",
|
|
1642
|
-
"data-pcb-layer": "drill"
|
|
1643
|
-
},
|
|
1644
|
-
value: "",
|
|
1645
|
-
children: []
|
|
1646
|
-
}
|
|
1647
|
-
],
|
|
1668
|
+
children,
|
|
1648
1669
|
value: ""
|
|
1649
1670
|
}
|
|
1650
1671
|
];
|
|
@@ -1656,6 +1677,55 @@ function createSvgObjectsFromPcbPlatedHole(hole, ctx) {
|
|
|
1656
1677
|
const scaledHoleHeight = hole.hole_diameter * Math.abs(transform.a);
|
|
1657
1678
|
const outerRadius = Math.min(scaledOuterWidth, scaledOuterHeight) / 2;
|
|
1658
1679
|
const innerRadius = Math.min(scaledHoleWidth, scaledHoleHeight) / 2;
|
|
1680
|
+
const children = [
|
|
1681
|
+
{
|
|
1682
|
+
name: "circle",
|
|
1683
|
+
type: "element",
|
|
1684
|
+
attributes: {
|
|
1685
|
+
class: "pcb-hole-outer",
|
|
1686
|
+
fill: colorMap2.copper.top,
|
|
1687
|
+
cx: x.toString(),
|
|
1688
|
+
cy: y.toString(),
|
|
1689
|
+
r: outerRadius.toString(),
|
|
1690
|
+
"data-type": "pcb_plated_hole",
|
|
1691
|
+
"data-pcb-layer": copperLayer
|
|
1692
|
+
},
|
|
1693
|
+
value: "",
|
|
1694
|
+
children: []
|
|
1695
|
+
},
|
|
1696
|
+
{
|
|
1697
|
+
name: "circle",
|
|
1698
|
+
type: "element",
|
|
1699
|
+
attributes: {
|
|
1700
|
+
class: "pcb-hole-inner",
|
|
1701
|
+
fill: colorMap2.drill,
|
|
1702
|
+
cx: x.toString(),
|
|
1703
|
+
cy: y.toString(),
|
|
1704
|
+
r: innerRadius.toString(),
|
|
1705
|
+
"data-type": "pcb_plated_hole_drill",
|
|
1706
|
+
"data-pcb-layer": "drill"
|
|
1707
|
+
},
|
|
1708
|
+
value: "",
|
|
1709
|
+
children: []
|
|
1710
|
+
}
|
|
1711
|
+
];
|
|
1712
|
+
if (shouldShowSolderMask) {
|
|
1713
|
+
const maskRadius = outerRadius + soldermaskMargin;
|
|
1714
|
+
children.push({
|
|
1715
|
+
name: "circle",
|
|
1716
|
+
type: "element",
|
|
1717
|
+
attributes: {
|
|
1718
|
+
class: "pcb-solder-mask",
|
|
1719
|
+
fill: solderMaskColor,
|
|
1720
|
+
cx: x.toString(),
|
|
1721
|
+
cy: y.toString(),
|
|
1722
|
+
r: maskRadius.toString(),
|
|
1723
|
+
"data-type": "pcb_soldermask"
|
|
1724
|
+
},
|
|
1725
|
+
value: "",
|
|
1726
|
+
children: []
|
|
1727
|
+
});
|
|
1728
|
+
}
|
|
1659
1729
|
return [
|
|
1660
1730
|
{
|
|
1661
1731
|
name: "g",
|
|
@@ -1664,38 +1734,7 @@ function createSvgObjectsFromPcbPlatedHole(hole, ctx) {
|
|
|
1664
1734
|
"data-type": "pcb_plated_hole",
|
|
1665
1735
|
"data-pcb-layer": "through"
|
|
1666
1736
|
},
|
|
1667
|
-
children
|
|
1668
|
-
{
|
|
1669
|
-
name: "circle",
|
|
1670
|
-
type: "element",
|
|
1671
|
-
attributes: {
|
|
1672
|
-
class: "pcb-hole-outer",
|
|
1673
|
-
fill: colorMap2.copper.top,
|
|
1674
|
-
cx: x.toString(),
|
|
1675
|
-
cy: y.toString(),
|
|
1676
|
-
r: outerRadius.toString(),
|
|
1677
|
-
"data-type": "pcb_plated_hole",
|
|
1678
|
-
"data-pcb-layer": copperLayer
|
|
1679
|
-
},
|
|
1680
|
-
value: "",
|
|
1681
|
-
children: []
|
|
1682
|
-
},
|
|
1683
|
-
{
|
|
1684
|
-
name: "circle",
|
|
1685
|
-
type: "element",
|
|
1686
|
-
attributes: {
|
|
1687
|
-
class: "pcb-hole-inner",
|
|
1688
|
-
fill: colorMap2.drill,
|
|
1689
|
-
cx: x.toString(),
|
|
1690
|
-
cy: y.toString(),
|
|
1691
|
-
r: innerRadius.toString(),
|
|
1692
|
-
"data-type": "pcb_plated_hole_drill",
|
|
1693
|
-
"data-pcb-layer": "drill"
|
|
1694
|
-
},
|
|
1695
|
-
value: "",
|
|
1696
|
-
children: []
|
|
1697
|
-
}
|
|
1698
|
-
],
|
|
1737
|
+
children,
|
|
1699
1738
|
value: ""
|
|
1700
1739
|
}
|
|
1701
1740
|
];
|
|
@@ -1711,6 +1750,69 @@ function createSvgObjectsFromPcbPlatedHole(hole, ctx) {
|
|
|
1711
1750
|
h.x + (h.hole_offset_x ?? 0),
|
|
1712
1751
|
h.y + (h.hole_offset_y ?? 0)
|
|
1713
1752
|
]);
|
|
1753
|
+
const children = [
|
|
1754
|
+
// Rectangular pad (outer shape)
|
|
1755
|
+
{
|
|
1756
|
+
name: "rect",
|
|
1757
|
+
type: "element",
|
|
1758
|
+
attributes: {
|
|
1759
|
+
class: "pcb-hole-outer-pad",
|
|
1760
|
+
fill: colorMap2.copper.top,
|
|
1761
|
+
x: (x - scaledRectPadWidth / 2).toString(),
|
|
1762
|
+
y: (y - scaledRectPadHeight / 2).toString(),
|
|
1763
|
+
width: scaledRectPadWidth.toString(),
|
|
1764
|
+
height: scaledRectPadHeight.toString(),
|
|
1765
|
+
...scaledRectBorderRadius ? {
|
|
1766
|
+
rx: scaledRectBorderRadius.toString(),
|
|
1767
|
+
ry: scaledRectBorderRadius.toString()
|
|
1768
|
+
} : {},
|
|
1769
|
+
"data-type": "pcb_plated_hole",
|
|
1770
|
+
"data-pcb-layer": copperLayer
|
|
1771
|
+
},
|
|
1772
|
+
value: "",
|
|
1773
|
+
children: []
|
|
1774
|
+
},
|
|
1775
|
+
// Circular hole inside the rectangle (with optional offset)
|
|
1776
|
+
{
|
|
1777
|
+
name: "circle",
|
|
1778
|
+
type: "element",
|
|
1779
|
+
attributes: {
|
|
1780
|
+
class: "pcb-hole-inner",
|
|
1781
|
+
fill: colorMap2.drill,
|
|
1782
|
+
cx: holeCx.toString(),
|
|
1783
|
+
cy: holeCy.toString(),
|
|
1784
|
+
r: holeRadius.toString(),
|
|
1785
|
+
"data-type": "pcb_plated_hole_drill",
|
|
1786
|
+
"data-pcb-layer": "drill"
|
|
1787
|
+
},
|
|
1788
|
+
value: "",
|
|
1789
|
+
children: []
|
|
1790
|
+
}
|
|
1791
|
+
];
|
|
1792
|
+
if (shouldShowSolderMask) {
|
|
1793
|
+
const maskWidth = scaledRectPadWidth + 2 * soldermaskMargin;
|
|
1794
|
+
const maskHeight = scaledRectPadHeight + 2 * soldermaskMargin;
|
|
1795
|
+
const maskBorderRadius = scaledRectBorderRadius + soldermaskMargin;
|
|
1796
|
+
children.push({
|
|
1797
|
+
name: "rect",
|
|
1798
|
+
type: "element",
|
|
1799
|
+
attributes: {
|
|
1800
|
+
class: "pcb-solder-mask",
|
|
1801
|
+
fill: solderMaskColor,
|
|
1802
|
+
x: (x - maskWidth / 2).toString(),
|
|
1803
|
+
y: (y - maskHeight / 2).toString(),
|
|
1804
|
+
width: maskWidth.toString(),
|
|
1805
|
+
height: maskHeight.toString(),
|
|
1806
|
+
...scaledRectBorderRadius ? {
|
|
1807
|
+
rx: maskBorderRadius.toString(),
|
|
1808
|
+
ry: maskBorderRadius.toString()
|
|
1809
|
+
} : {},
|
|
1810
|
+
"data-type": "pcb_soldermask"
|
|
1811
|
+
},
|
|
1812
|
+
value: "",
|
|
1813
|
+
children: []
|
|
1814
|
+
});
|
|
1815
|
+
}
|
|
1714
1816
|
return [
|
|
1715
1817
|
{
|
|
1716
1818
|
name: "g",
|
|
@@ -1719,45 +1821,7 @@ function createSvgObjectsFromPcbPlatedHole(hole, ctx) {
|
|
|
1719
1821
|
"data-type": "pcb_plated_hole",
|
|
1720
1822
|
"data-pcb-layer": "through"
|
|
1721
1823
|
},
|
|
1722
|
-
children
|
|
1723
|
-
// Rectangular pad (outer shape)
|
|
1724
|
-
{
|
|
1725
|
-
name: "rect",
|
|
1726
|
-
type: "element",
|
|
1727
|
-
attributes: {
|
|
1728
|
-
class: "pcb-hole-outer-pad",
|
|
1729
|
-
fill: colorMap2.copper.top,
|
|
1730
|
-
x: (x - scaledRectPadWidth / 2).toString(),
|
|
1731
|
-
y: (y - scaledRectPadHeight / 2).toString(),
|
|
1732
|
-
width: scaledRectPadWidth.toString(),
|
|
1733
|
-
height: scaledRectPadHeight.toString(),
|
|
1734
|
-
...scaledRectBorderRadius ? {
|
|
1735
|
-
rx: scaledRectBorderRadius.toString(),
|
|
1736
|
-
ry: scaledRectBorderRadius.toString()
|
|
1737
|
-
} : {},
|
|
1738
|
-
"data-type": "pcb_plated_hole",
|
|
1739
|
-
"data-pcb-layer": copperLayer
|
|
1740
|
-
},
|
|
1741
|
-
value: "",
|
|
1742
|
-
children: []
|
|
1743
|
-
},
|
|
1744
|
-
// Circular hole inside the rectangle (with optional offset)
|
|
1745
|
-
{
|
|
1746
|
-
name: "circle",
|
|
1747
|
-
type: "element",
|
|
1748
|
-
attributes: {
|
|
1749
|
-
class: "pcb-hole-inner",
|
|
1750
|
-
fill: colorMap2.drill,
|
|
1751
|
-
cx: holeCx.toString(),
|
|
1752
|
-
cy: holeCy.toString(),
|
|
1753
|
-
r: holeRadius.toString(),
|
|
1754
|
-
"data-type": "pcb_plated_hole_drill",
|
|
1755
|
-
"data-pcb-layer": "drill"
|
|
1756
|
-
},
|
|
1757
|
-
value: "",
|
|
1758
|
-
children: []
|
|
1759
|
-
}
|
|
1760
|
-
],
|
|
1824
|
+
children,
|
|
1761
1825
|
value: ""
|
|
1762
1826
|
}
|
|
1763
1827
|
];
|
|
@@ -1777,6 +1841,72 @@ function createSvgObjectsFromPcbPlatedHole(hole, ctx) {
|
|
|
1777
1841
|
pillHole.y + holeOffsetY
|
|
1778
1842
|
]);
|
|
1779
1843
|
const holeRadius = Math.min(scaledHoleHeight, scaledHoleWidth) / 2;
|
|
1844
|
+
const children = [
|
|
1845
|
+
// Rectangular pad (outer shape)
|
|
1846
|
+
{
|
|
1847
|
+
name: "rect",
|
|
1848
|
+
type: "element",
|
|
1849
|
+
attributes: {
|
|
1850
|
+
class: "pcb-hole-outer-pad",
|
|
1851
|
+
fill: colorMap2.copper.top,
|
|
1852
|
+
x: (x - scaledRectPadWidth / 2).toString(),
|
|
1853
|
+
y: (y - scaledRectPadHeight / 2).toString(),
|
|
1854
|
+
width: scaledRectPadWidth.toString(),
|
|
1855
|
+
height: scaledRectPadHeight.toString(),
|
|
1856
|
+
...scaledRectBorderRadius ? {
|
|
1857
|
+
rx: scaledRectBorderRadius.toString(),
|
|
1858
|
+
ry: scaledRectBorderRadius.toString()
|
|
1859
|
+
} : {},
|
|
1860
|
+
"data-type": "pcb_plated_hole",
|
|
1861
|
+
"data-pcb-layer": copperLayer
|
|
1862
|
+
},
|
|
1863
|
+
value: "",
|
|
1864
|
+
children: []
|
|
1865
|
+
},
|
|
1866
|
+
// pill hole inside the rectangle
|
|
1867
|
+
{
|
|
1868
|
+
name: "rect",
|
|
1869
|
+
type: "element",
|
|
1870
|
+
attributes: {
|
|
1871
|
+
class: "pcb-hole-inner",
|
|
1872
|
+
fill: colorMap2.drill,
|
|
1873
|
+
x: (holeCenterX - scaledHoleWidth / 2).toString(),
|
|
1874
|
+
y: (holeCenterY - scaledHoleHeight / 2).toString(),
|
|
1875
|
+
width: scaledHoleWidth.toString(),
|
|
1876
|
+
height: scaledHoleHeight.toString(),
|
|
1877
|
+
rx: holeRadius.toString(),
|
|
1878
|
+
ry: holeRadius.toString(),
|
|
1879
|
+
"data-type": "pcb_plated_hole_drill",
|
|
1880
|
+
"data-pcb-layer": "drill"
|
|
1881
|
+
},
|
|
1882
|
+
value: "",
|
|
1883
|
+
children: []
|
|
1884
|
+
}
|
|
1885
|
+
];
|
|
1886
|
+
if (shouldShowSolderMask) {
|
|
1887
|
+
const maskWidth = scaledRectPadWidth + 2 * soldermaskMargin;
|
|
1888
|
+
const maskHeight = scaledRectPadHeight + 2 * soldermaskMargin;
|
|
1889
|
+
const maskBorderRadius = scaledRectBorderRadius + soldermaskMargin;
|
|
1890
|
+
children.push({
|
|
1891
|
+
name: "rect",
|
|
1892
|
+
type: "element",
|
|
1893
|
+
attributes: {
|
|
1894
|
+
class: "pcb-solder-mask",
|
|
1895
|
+
fill: solderMaskColor,
|
|
1896
|
+
x: (x - maskWidth / 2).toString(),
|
|
1897
|
+
y: (y - maskHeight / 2).toString(),
|
|
1898
|
+
width: maskWidth.toString(),
|
|
1899
|
+
height: maskHeight.toString(),
|
|
1900
|
+
...scaledRectBorderRadius ? {
|
|
1901
|
+
rx: maskBorderRadius.toString(),
|
|
1902
|
+
ry: maskBorderRadius.toString()
|
|
1903
|
+
} : {},
|
|
1904
|
+
"data-type": "pcb_soldermask"
|
|
1905
|
+
},
|
|
1906
|
+
value: "",
|
|
1907
|
+
children: []
|
|
1908
|
+
});
|
|
1909
|
+
}
|
|
1780
1910
|
return [
|
|
1781
1911
|
{
|
|
1782
1912
|
name: "g",
|
|
@@ -1785,67 +1915,93 @@ function createSvgObjectsFromPcbPlatedHole(hole, ctx) {
|
|
|
1785
1915
|
"data-type": "pcb_plated_hole",
|
|
1786
1916
|
"data-pcb-layer": "through"
|
|
1787
1917
|
},
|
|
1788
|
-
children
|
|
1789
|
-
// Rectangular pad (outer shape)
|
|
1790
|
-
{
|
|
1791
|
-
name: "rect",
|
|
1792
|
-
type: "element",
|
|
1793
|
-
attributes: {
|
|
1794
|
-
class: "pcb-hole-outer-pad",
|
|
1795
|
-
fill: colorMap2.copper.top,
|
|
1796
|
-
x: (x - scaledRectPadWidth / 2).toString(),
|
|
1797
|
-
y: (y - scaledRectPadHeight / 2).toString(),
|
|
1798
|
-
width: scaledRectPadWidth.toString(),
|
|
1799
|
-
height: scaledRectPadHeight.toString(),
|
|
1800
|
-
...scaledRectBorderRadius ? {
|
|
1801
|
-
rx: scaledRectBorderRadius.toString(),
|
|
1802
|
-
ry: scaledRectBorderRadius.toString()
|
|
1803
|
-
} : {},
|
|
1804
|
-
"data-type": "pcb_plated_hole",
|
|
1805
|
-
"data-pcb-layer": copperLayer
|
|
1806
|
-
},
|
|
1807
|
-
value: "",
|
|
1808
|
-
children: []
|
|
1809
|
-
},
|
|
1810
|
-
// pill hole inside the rectangle
|
|
1811
|
-
{
|
|
1812
|
-
name: "rect",
|
|
1813
|
-
type: "element",
|
|
1814
|
-
attributes: {
|
|
1815
|
-
class: "pcb-hole-inner",
|
|
1816
|
-
fill: colorMap2.drill,
|
|
1817
|
-
x: (holeCenterX - scaledHoleWidth / 2).toString(),
|
|
1818
|
-
y: (holeCenterY - scaledHoleHeight / 2).toString(),
|
|
1819
|
-
width: scaledHoleWidth.toString(),
|
|
1820
|
-
height: scaledHoleHeight.toString(),
|
|
1821
|
-
rx: holeRadius.toString(),
|
|
1822
|
-
ry: holeRadius.toString(),
|
|
1823
|
-
"data-type": "pcb_plated_hole_drill",
|
|
1824
|
-
"data-pcb-layer": "drill"
|
|
1825
|
-
},
|
|
1826
|
-
value: "",
|
|
1827
|
-
children: []
|
|
1828
|
-
}
|
|
1829
|
-
],
|
|
1918
|
+
children,
|
|
1830
1919
|
value: ""
|
|
1831
1920
|
}
|
|
1832
1921
|
];
|
|
1833
|
-
}
|
|
1834
|
-
if (hole.shape === "rotated_pill_hole_with_rect_pad") {
|
|
1835
|
-
const rotatedHole = hole;
|
|
1836
|
-
const scaledRectPadWidth = rotatedHole.rect_pad_width * Math.abs(transform.a);
|
|
1837
|
-
const scaledRectPadHeight = rotatedHole.rect_pad_height * Math.abs(transform.a);
|
|
1838
|
-
const scaledRectBorderRadius = (rotatedHole.rect_border_radius ?? 0) * Math.abs(transform.a);
|
|
1839
|
-
const scaledHoleHeight = rotatedHole.hole_height * Math.abs(transform.a);
|
|
1840
|
-
const scaledHoleWidth = rotatedHole.hole_width * Math.abs(transform.a);
|
|
1841
|
-
const rotatedHoleWithOffsets = rotatedHole;
|
|
1842
|
-
const holeOffsetX = rotatedHoleWithOffsets.hole_offset_x ?? 0;
|
|
1843
|
-
const holeOffsetY = rotatedHoleWithOffsets.hole_offset_y ?? 0;
|
|
1844
|
-
const [holeCenterX, holeCenterY] = applyToPoint12(transform, [
|
|
1845
|
-
rotatedHole.x + holeOffsetX,
|
|
1846
|
-
rotatedHole.y + holeOffsetY
|
|
1847
|
-
]);
|
|
1848
|
-
const holeRadius = Math.min(scaledHoleHeight, scaledHoleWidth) / 2;
|
|
1922
|
+
}
|
|
1923
|
+
if (hole.shape === "rotated_pill_hole_with_rect_pad") {
|
|
1924
|
+
const rotatedHole = hole;
|
|
1925
|
+
const scaledRectPadWidth = rotatedHole.rect_pad_width * Math.abs(transform.a);
|
|
1926
|
+
const scaledRectPadHeight = rotatedHole.rect_pad_height * Math.abs(transform.a);
|
|
1927
|
+
const scaledRectBorderRadius = (rotatedHole.rect_border_radius ?? 0) * Math.abs(transform.a);
|
|
1928
|
+
const scaledHoleHeight = rotatedHole.hole_height * Math.abs(transform.a);
|
|
1929
|
+
const scaledHoleWidth = rotatedHole.hole_width * Math.abs(transform.a);
|
|
1930
|
+
const rotatedHoleWithOffsets = rotatedHole;
|
|
1931
|
+
const holeOffsetX = rotatedHoleWithOffsets.hole_offset_x ?? 0;
|
|
1932
|
+
const holeOffsetY = rotatedHoleWithOffsets.hole_offset_y ?? 0;
|
|
1933
|
+
const [holeCenterX, holeCenterY] = applyToPoint12(transform, [
|
|
1934
|
+
rotatedHole.x + holeOffsetX,
|
|
1935
|
+
rotatedHole.y + holeOffsetY
|
|
1936
|
+
]);
|
|
1937
|
+
const holeRadius = Math.min(scaledHoleHeight, scaledHoleWidth) / 2;
|
|
1938
|
+
const children = [
|
|
1939
|
+
{
|
|
1940
|
+
name: "rect",
|
|
1941
|
+
type: "element",
|
|
1942
|
+
attributes: {
|
|
1943
|
+
class: "pcb-hole-outer-pad",
|
|
1944
|
+
fill: colorMap2.copper.top,
|
|
1945
|
+
x: (-scaledRectPadWidth / 2).toString(),
|
|
1946
|
+
y: (-scaledRectPadHeight / 2).toString(),
|
|
1947
|
+
width: scaledRectPadWidth.toString(),
|
|
1948
|
+
height: scaledRectPadHeight.toString(),
|
|
1949
|
+
transform: `translate(${x} ${y}) rotate(${-rotatedHole.rect_ccw_rotation})`,
|
|
1950
|
+
...scaledRectBorderRadius ? {
|
|
1951
|
+
rx: scaledRectBorderRadius.toString(),
|
|
1952
|
+
ry: scaledRectBorderRadius.toString()
|
|
1953
|
+
} : {},
|
|
1954
|
+
"data-type": "pcb_plated_hole",
|
|
1955
|
+
"data-pcb-layer": copperLayer
|
|
1956
|
+
},
|
|
1957
|
+
value: "",
|
|
1958
|
+
children: []
|
|
1959
|
+
},
|
|
1960
|
+
{
|
|
1961
|
+
name: "rect",
|
|
1962
|
+
type: "element",
|
|
1963
|
+
attributes: {
|
|
1964
|
+
class: "pcb-hole-inner",
|
|
1965
|
+
fill: colorMap2.drill,
|
|
1966
|
+
x: (-scaledHoleWidth / 2).toString(),
|
|
1967
|
+
y: (-scaledHoleHeight / 2).toString(),
|
|
1968
|
+
width: scaledHoleWidth.toString(),
|
|
1969
|
+
height: scaledHoleHeight.toString(),
|
|
1970
|
+
rx: holeRadius.toString(),
|
|
1971
|
+
ry: holeRadius.toString(),
|
|
1972
|
+
transform: `translate(${holeCenterX} ${holeCenterY}) rotate(${-rotatedHole.hole_ccw_rotation})`,
|
|
1973
|
+
"data-type": "pcb_plated_hole_drill",
|
|
1974
|
+
"data-pcb-layer": "drill"
|
|
1975
|
+
},
|
|
1976
|
+
value: "",
|
|
1977
|
+
children: []
|
|
1978
|
+
}
|
|
1979
|
+
];
|
|
1980
|
+
if (shouldShowSolderMask) {
|
|
1981
|
+
const maskWidth = scaledRectPadWidth + 2 * soldermaskMargin;
|
|
1982
|
+
const maskHeight = scaledRectPadHeight + 2 * soldermaskMargin;
|
|
1983
|
+
const maskBorderRadius = scaledRectBorderRadius + soldermaskMargin;
|
|
1984
|
+
children.push({
|
|
1985
|
+
name: "rect",
|
|
1986
|
+
type: "element",
|
|
1987
|
+
attributes: {
|
|
1988
|
+
class: "pcb-solder-mask",
|
|
1989
|
+
fill: solderMaskColor,
|
|
1990
|
+
x: (-maskWidth / 2).toString(),
|
|
1991
|
+
y: (-maskHeight / 2).toString(),
|
|
1992
|
+
width: maskWidth.toString(),
|
|
1993
|
+
height: maskHeight.toString(),
|
|
1994
|
+
transform: `translate(${x} ${y}) rotate(${-rotatedHole.rect_ccw_rotation})`,
|
|
1995
|
+
...scaledRectBorderRadius ? {
|
|
1996
|
+
rx: maskBorderRadius.toString(),
|
|
1997
|
+
ry: maskBorderRadius.toString()
|
|
1998
|
+
} : {},
|
|
1999
|
+
"data-type": "pcb_soldermask"
|
|
2000
|
+
},
|
|
2001
|
+
value: "",
|
|
2002
|
+
children: []
|
|
2003
|
+
});
|
|
2004
|
+
}
|
|
1849
2005
|
return [
|
|
1850
2006
|
{
|
|
1851
2007
|
name: "g",
|
|
@@ -1854,48 +2010,7 @@ function createSvgObjectsFromPcbPlatedHole(hole, ctx) {
|
|
|
1854
2010
|
"data-type": "pcb_plated_hole",
|
|
1855
2011
|
"data-pcb-layer": "through"
|
|
1856
2012
|
},
|
|
1857
|
-
children
|
|
1858
|
-
{
|
|
1859
|
-
name: "rect",
|
|
1860
|
-
type: "element",
|
|
1861
|
-
attributes: {
|
|
1862
|
-
class: "pcb-hole-outer-pad",
|
|
1863
|
-
fill: colorMap2.copper.top,
|
|
1864
|
-
x: (-scaledRectPadWidth / 2).toString(),
|
|
1865
|
-
y: (-scaledRectPadHeight / 2).toString(),
|
|
1866
|
-
width: scaledRectPadWidth.toString(),
|
|
1867
|
-
height: scaledRectPadHeight.toString(),
|
|
1868
|
-
transform: `translate(${x} ${y}) rotate(${-rotatedHole.rect_ccw_rotation})`,
|
|
1869
|
-
...scaledRectBorderRadius ? {
|
|
1870
|
-
rx: scaledRectBorderRadius.toString(),
|
|
1871
|
-
ry: scaledRectBorderRadius.toString()
|
|
1872
|
-
} : {},
|
|
1873
|
-
"data-type": "pcb_plated_hole",
|
|
1874
|
-
"data-pcb-layer": copperLayer
|
|
1875
|
-
},
|
|
1876
|
-
value: "",
|
|
1877
|
-
children: []
|
|
1878
|
-
},
|
|
1879
|
-
{
|
|
1880
|
-
name: "rect",
|
|
1881
|
-
type: "element",
|
|
1882
|
-
attributes: {
|
|
1883
|
-
class: "pcb-hole-inner",
|
|
1884
|
-
fill: colorMap2.drill,
|
|
1885
|
-
x: (-scaledHoleWidth / 2).toString(),
|
|
1886
|
-
y: (-scaledHoleHeight / 2).toString(),
|
|
1887
|
-
width: scaledHoleWidth.toString(),
|
|
1888
|
-
height: scaledHoleHeight.toString(),
|
|
1889
|
-
rx: holeRadius.toString(),
|
|
1890
|
-
ry: holeRadius.toString(),
|
|
1891
|
-
transform: `translate(${holeCenterX} ${holeCenterY}) rotate(${-rotatedHole.hole_ccw_rotation})`,
|
|
1892
|
-
"data-type": "pcb_plated_hole_drill",
|
|
1893
|
-
"data-pcb-layer": "drill"
|
|
1894
|
-
},
|
|
1895
|
-
value: "",
|
|
1896
|
-
children: []
|
|
1897
|
-
}
|
|
1898
|
-
],
|
|
2013
|
+
children,
|
|
1899
2014
|
value: ""
|
|
1900
2015
|
}
|
|
1901
2016
|
];
|
|
@@ -2552,6 +2667,7 @@ function createSvgObjectsFromSmtPad(pad, ctx) {
|
|
|
2552
2667
|
const isCoveredWithSolderMask = Boolean(pad?.is_covered_with_solder_mask);
|
|
2553
2668
|
const shouldshowSolderMask = showSolderMask && isCoveredWithSolderMask;
|
|
2554
2669
|
const solderMaskColor = colorMap2.soldermask[pad.layer] ?? colorMap2.soldermask.top;
|
|
2670
|
+
const soldermaskMargin = (pad.soldermask_margin ?? 0) * Math.abs(transform.a);
|
|
2555
2671
|
if (pad.shape === "rect" || pad.shape === "rotated_rect") {
|
|
2556
2672
|
const width = pad.width * Math.abs(transform.a);
|
|
2557
2673
|
const height = pad.height * Math.abs(transform.d);
|
|
@@ -2583,6 +2699,9 @@ function createSvgObjectsFromSmtPad(pad, ctx) {
|
|
|
2583
2699
|
if (!shouldshowSolderMask) {
|
|
2584
2700
|
return [padElement2];
|
|
2585
2701
|
}
|
|
2702
|
+
const maskWidth2 = width + 2 * soldermaskMargin;
|
|
2703
|
+
const maskHeight2 = height + 2 * soldermaskMargin;
|
|
2704
|
+
const maskBorderRadius2 = scaledBorderRadius ? scaledBorderRadius + soldermaskMargin : 0;
|
|
2586
2705
|
const maskElement2 = {
|
|
2587
2706
|
name: padElement2.name,
|
|
2588
2707
|
type: padElement2.type,
|
|
@@ -2592,7 +2711,15 @@ function createSvgObjectsFromSmtPad(pad, ctx) {
|
|
|
2592
2711
|
...padElement2.attributes,
|
|
2593
2712
|
class: "pcb-solder-mask",
|
|
2594
2713
|
fill: solderMaskColor,
|
|
2595
|
-
"data-type": "pcb_soldermask"
|
|
2714
|
+
"data-type": "pcb_soldermask",
|
|
2715
|
+
x: (-maskWidth2 / 2).toString(),
|
|
2716
|
+
y: (-maskHeight2 / 2).toString(),
|
|
2717
|
+
width: maskWidth2.toString(),
|
|
2718
|
+
height: maskHeight2.toString(),
|
|
2719
|
+
...maskBorderRadius2 > 0 ? {
|
|
2720
|
+
rx: maskBorderRadius2.toString(),
|
|
2721
|
+
ry: maskBorderRadius2.toString()
|
|
2722
|
+
} : {}
|
|
2596
2723
|
}
|
|
2597
2724
|
};
|
|
2598
2725
|
return [padElement2, maskElement2];
|
|
@@ -2620,6 +2747,9 @@ function createSvgObjectsFromSmtPad(pad, ctx) {
|
|
|
2620
2747
|
if (!shouldshowSolderMask) {
|
|
2621
2748
|
return [padElement];
|
|
2622
2749
|
}
|
|
2750
|
+
const maskWidth = width + 2 * soldermaskMargin;
|
|
2751
|
+
const maskHeight = height + 2 * soldermaskMargin;
|
|
2752
|
+
const maskBorderRadius = scaledBorderRadius ? scaledBorderRadius + soldermaskMargin : 0;
|
|
2623
2753
|
const maskElement = {
|
|
2624
2754
|
name: padElement.name,
|
|
2625
2755
|
type: padElement.type,
|
|
@@ -2629,7 +2759,15 @@ function createSvgObjectsFromSmtPad(pad, ctx) {
|
|
|
2629
2759
|
...padElement.attributes,
|
|
2630
2760
|
class: "pcb-solder-mask",
|
|
2631
2761
|
fill: solderMaskColor,
|
|
2632
|
-
"data-type": "pcb_soldermask"
|
|
2762
|
+
"data-type": "pcb_soldermask",
|
|
2763
|
+
x: (x - maskWidth / 2).toString(),
|
|
2764
|
+
y: (y - maskHeight / 2).toString(),
|
|
2765
|
+
width: maskWidth.toString(),
|
|
2766
|
+
height: maskHeight.toString(),
|
|
2767
|
+
...maskBorderRadius > 0 ? {
|
|
2768
|
+
rx: maskBorderRadius.toString(),
|
|
2769
|
+
ry: maskBorderRadius.toString()
|
|
2770
|
+
} : {}
|
|
2633
2771
|
}
|
|
2634
2772
|
};
|
|
2635
2773
|
return [padElement, maskElement];
|
|
@@ -2660,6 +2798,9 @@ function createSvgObjectsFromSmtPad(pad, ctx) {
|
|
|
2660
2798
|
if (!shouldshowSolderMask) {
|
|
2661
2799
|
return [padElement];
|
|
2662
2800
|
}
|
|
2801
|
+
const maskWidth = width + 2 * soldermaskMargin;
|
|
2802
|
+
const maskHeight = height + 2 * soldermaskMargin;
|
|
2803
|
+
const maskRadius = radius + soldermaskMargin;
|
|
2663
2804
|
const maskElement = {
|
|
2664
2805
|
name: padElement.name,
|
|
2665
2806
|
type: padElement.type,
|
|
@@ -2669,7 +2810,13 @@ function createSvgObjectsFromSmtPad(pad, ctx) {
|
|
|
2669
2810
|
...padElement.attributes,
|
|
2670
2811
|
class: "pcb-solder-mask",
|
|
2671
2812
|
fill: solderMaskColor,
|
|
2672
|
-
"data-type": "pcb_soldermask"
|
|
2813
|
+
"data-type": "pcb_soldermask",
|
|
2814
|
+
x: (x - maskWidth / 2).toString(),
|
|
2815
|
+
y: (y - maskHeight / 2).toString(),
|
|
2816
|
+
width: maskWidth.toString(),
|
|
2817
|
+
height: maskHeight.toString(),
|
|
2818
|
+
rx: maskRadius.toString(),
|
|
2819
|
+
ry: maskRadius.toString()
|
|
2673
2820
|
}
|
|
2674
2821
|
};
|
|
2675
2822
|
return [padElement, maskElement];
|
|
@@ -2695,6 +2842,7 @@ function createSvgObjectsFromSmtPad(pad, ctx) {
|
|
|
2695
2842
|
if (!shouldshowSolderMask) {
|
|
2696
2843
|
return [padElement];
|
|
2697
2844
|
}
|
|
2845
|
+
const maskRadius = radius + soldermaskMargin;
|
|
2698
2846
|
const maskElement = {
|
|
2699
2847
|
name: padElement.name,
|
|
2700
2848
|
type: padElement.type,
|
|
@@ -2704,7 +2852,8 @@ function createSvgObjectsFromSmtPad(pad, ctx) {
|
|
|
2704
2852
|
...padElement.attributes,
|
|
2705
2853
|
class: "pcb-solder-mask",
|
|
2706
2854
|
fill: solderMaskColor,
|
|
2707
|
-
"data-type": "pcb_soldermask"
|
|
2855
|
+
"data-type": "pcb_soldermask",
|
|
2856
|
+
r: maskRadius.toString()
|
|
2708
2857
|
}
|
|
2709
2858
|
};
|
|
2710
2859
|
return [padElement, maskElement];
|
|
@@ -2729,6 +2878,23 @@ function createSvgObjectsFromSmtPad(pad, ctx) {
|
|
|
2729
2878
|
if (!shouldshowSolderMask) {
|
|
2730
2879
|
return [padElement];
|
|
2731
2880
|
}
|
|
2881
|
+
let maskPoints = points;
|
|
2882
|
+
if (soldermaskMargin !== 0) {
|
|
2883
|
+
const centroidX = points.reduce((sum, p) => sum + p[0], 0) / points.length;
|
|
2884
|
+
const centroidY = points.reduce((sum, p) => sum + p[1], 0) / points.length;
|
|
2885
|
+
maskPoints = points.map(([px, py]) => {
|
|
2886
|
+
const dx = px - centroidX;
|
|
2887
|
+
const dy = py - centroidY;
|
|
2888
|
+
const distance3 = Math.sqrt(dx * dx + dy * dy);
|
|
2889
|
+
if (distance3 === 0) return [px, py];
|
|
2890
|
+
const normalizedDx = dx / distance3;
|
|
2891
|
+
const normalizedDy = dy / distance3;
|
|
2892
|
+
return [
|
|
2893
|
+
px + normalizedDx * soldermaskMargin,
|
|
2894
|
+
py + normalizedDy * soldermaskMargin
|
|
2895
|
+
];
|
|
2896
|
+
});
|
|
2897
|
+
}
|
|
2732
2898
|
const maskElement = {
|
|
2733
2899
|
name: padElement.name,
|
|
2734
2900
|
type: padElement.type,
|
|
@@ -2738,7 +2904,8 @@ function createSvgObjectsFromSmtPad(pad, ctx) {
|
|
|
2738
2904
|
...padElement.attributes,
|
|
2739
2905
|
class: "pcb-solder-mask",
|
|
2740
2906
|
fill: solderMaskColor,
|
|
2741
|
-
"data-type": "pcb_soldermask"
|
|
2907
|
+
"data-type": "pcb_soldermask",
|
|
2908
|
+
points: maskPoints.map((p) => p.join(",")).join(" ")
|
|
2742
2909
|
}
|
|
2743
2910
|
};
|
|
2744
2911
|
return [padElement, maskElement];
|
|
@@ -2899,94 +3066,170 @@ function createSvgObjectsFromPcbVia(hole, ctx) {
|
|
|
2899
3066
|
// lib/pcb/svg-object-fns/create-svg-objects-from-pcb-hole.ts
|
|
2900
3067
|
import { applyToPoint as applyToPoint24 } from "transformation-matrix";
|
|
2901
3068
|
function createSvgObjectsFromPcbHole(hole, ctx) {
|
|
2902
|
-
const { transform, colorMap: colorMap2 } = ctx;
|
|
3069
|
+
const { transform, colorMap: colorMap2, showSolderMask } = ctx;
|
|
2903
3070
|
const [x, y] = applyToPoint24(transform, [hole.x, hole.y]);
|
|
3071
|
+
const soldermaskMargin = (hole.soldermask_margin ?? 0) * Math.abs(transform.a);
|
|
3072
|
+
const shouldShowSolderMask = showSolderMask && soldermaskMargin !== 0;
|
|
3073
|
+
const solderMaskColor = colorMap2.soldermask.top;
|
|
2904
3074
|
if (hole.hole_shape === "circle" || hole.hole_shape === "square") {
|
|
2905
3075
|
const scaledDiameter = hole.hole_diameter * Math.abs(transform.a);
|
|
2906
3076
|
const radius = scaledDiameter / 2;
|
|
2907
3077
|
if (hole.hole_shape === "circle") {
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
name: "circle",
|
|
2911
|
-
type: "element",
|
|
2912
|
-
attributes: {
|
|
2913
|
-
class: "pcb-hole",
|
|
2914
|
-
cx: x.toString(),
|
|
2915
|
-
cy: y.toString(),
|
|
2916
|
-
r: radius.toString(),
|
|
2917
|
-
fill: colorMap2.drill,
|
|
2918
|
-
"data-type": "pcb_hole",
|
|
2919
|
-
"data-pcb-layer": "drill"
|
|
2920
|
-
},
|
|
2921
|
-
children: [],
|
|
2922
|
-
value: ""
|
|
2923
|
-
}
|
|
2924
|
-
];
|
|
2925
|
-
}
|
|
2926
|
-
return [
|
|
2927
|
-
{
|
|
2928
|
-
name: "rect",
|
|
3078
|
+
const holeElement2 = {
|
|
3079
|
+
name: "circle",
|
|
2929
3080
|
type: "element",
|
|
2930
3081
|
attributes: {
|
|
2931
3082
|
class: "pcb-hole",
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
height: scaledDiameter.toString(),
|
|
3083
|
+
cx: x.toString(),
|
|
3084
|
+
cy: y.toString(),
|
|
3085
|
+
r: radius.toString(),
|
|
2936
3086
|
fill: colorMap2.drill,
|
|
2937
3087
|
"data-type": "pcb_hole",
|
|
2938
3088
|
"data-pcb-layer": "drill"
|
|
2939
3089
|
},
|
|
2940
3090
|
children: [],
|
|
2941
3091
|
value: ""
|
|
3092
|
+
};
|
|
3093
|
+
if (!shouldShowSolderMask) {
|
|
3094
|
+
return [holeElement2];
|
|
2942
3095
|
}
|
|
2943
|
-
|
|
3096
|
+
const maskRadius = radius + soldermaskMargin;
|
|
3097
|
+
const maskElement2 = {
|
|
3098
|
+
name: holeElement2.name,
|
|
3099
|
+
type: holeElement2.type,
|
|
3100
|
+
value: "",
|
|
3101
|
+
children: [],
|
|
3102
|
+
attributes: {
|
|
3103
|
+
...holeElement2.attributes,
|
|
3104
|
+
class: "pcb-solder-mask",
|
|
3105
|
+
fill: solderMaskColor,
|
|
3106
|
+
"data-type": "pcb_soldermask",
|
|
3107
|
+
r: maskRadius.toString()
|
|
3108
|
+
}
|
|
3109
|
+
};
|
|
3110
|
+
return [holeElement2, maskElement2];
|
|
3111
|
+
}
|
|
3112
|
+
const holeElement = {
|
|
3113
|
+
name: "rect",
|
|
3114
|
+
type: "element",
|
|
3115
|
+
attributes: {
|
|
3116
|
+
class: "pcb-hole",
|
|
3117
|
+
x: (x - radius).toString(),
|
|
3118
|
+
y: (y - radius).toString(),
|
|
3119
|
+
width: scaledDiameter.toString(),
|
|
3120
|
+
height: scaledDiameter.toString(),
|
|
3121
|
+
fill: colorMap2.drill,
|
|
3122
|
+
"data-type": "pcb_hole",
|
|
3123
|
+
"data-pcb-layer": "drill"
|
|
3124
|
+
},
|
|
3125
|
+
children: [],
|
|
3126
|
+
value: ""
|
|
3127
|
+
};
|
|
3128
|
+
if (!shouldShowSolderMask) {
|
|
3129
|
+
return [holeElement];
|
|
3130
|
+
}
|
|
3131
|
+
const maskDiameter = scaledDiameter + 2 * soldermaskMargin;
|
|
3132
|
+
const maskElement = {
|
|
3133
|
+
name: holeElement.name,
|
|
3134
|
+
type: holeElement.type,
|
|
3135
|
+
value: "",
|
|
3136
|
+
children: [],
|
|
3137
|
+
attributes: {
|
|
3138
|
+
...holeElement.attributes,
|
|
3139
|
+
class: "pcb-solder-mask",
|
|
3140
|
+
fill: solderMaskColor,
|
|
3141
|
+
"data-type": "pcb_soldermask",
|
|
3142
|
+
x: (x - maskDiameter / 2).toString(),
|
|
3143
|
+
y: (y - maskDiameter / 2).toString(),
|
|
3144
|
+
width: maskDiameter.toString(),
|
|
3145
|
+
height: maskDiameter.toString()
|
|
3146
|
+
}
|
|
3147
|
+
};
|
|
3148
|
+
return [holeElement, maskElement];
|
|
2944
3149
|
}
|
|
2945
3150
|
if (hole.hole_shape === "oval") {
|
|
2946
3151
|
const scaledWidth = hole.hole_width * Math.abs(transform.a);
|
|
2947
3152
|
const scaledHeight = hole.hole_height * Math.abs(transform.a);
|
|
2948
3153
|
const rx = scaledWidth / 2;
|
|
2949
3154
|
const ry = scaledHeight / 2;
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
3155
|
+
const holeElement = {
|
|
3156
|
+
name: "ellipse",
|
|
3157
|
+
type: "element",
|
|
3158
|
+
attributes: {
|
|
3159
|
+
class: "pcb-hole",
|
|
3160
|
+
cx: x.toString(),
|
|
3161
|
+
cy: y.toString(),
|
|
3162
|
+
rx: rx.toString(),
|
|
3163
|
+
ry: ry.toString(),
|
|
3164
|
+
fill: colorMap2.drill,
|
|
3165
|
+
"data-type": "pcb_hole",
|
|
3166
|
+
"data-pcb-layer": "drill"
|
|
3167
|
+
},
|
|
3168
|
+
children: [],
|
|
3169
|
+
value: ""
|
|
3170
|
+
};
|
|
3171
|
+
if (!shouldShowSolderMask) {
|
|
3172
|
+
return [holeElement];
|
|
3173
|
+
}
|
|
3174
|
+
const maskRx = rx + soldermaskMargin;
|
|
3175
|
+
const maskRy = ry + soldermaskMargin;
|
|
3176
|
+
const maskElement = {
|
|
3177
|
+
name: holeElement.name,
|
|
3178
|
+
type: holeElement.type,
|
|
3179
|
+
value: "",
|
|
3180
|
+
children: [],
|
|
3181
|
+
attributes: {
|
|
3182
|
+
...holeElement.attributes,
|
|
3183
|
+
class: "pcb-solder-mask",
|
|
3184
|
+
fill: solderMaskColor,
|
|
3185
|
+
"data-type": "pcb_soldermask",
|
|
3186
|
+
rx: maskRx.toString(),
|
|
3187
|
+
ry: maskRy.toString()
|
|
2966
3188
|
}
|
|
2967
|
-
|
|
3189
|
+
};
|
|
3190
|
+
return [holeElement, maskElement];
|
|
2968
3191
|
}
|
|
2969
3192
|
if (hole.hole_shape === "rect") {
|
|
2970
3193
|
const scaledWidth = hole.hole_width * Math.abs(transform.a);
|
|
2971
3194
|
const scaledHeight = hole.hole_height * Math.abs(transform.a);
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
|
|
2978
|
-
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
|
|
2986
|
-
|
|
2987
|
-
|
|
3195
|
+
const holeElement = {
|
|
3196
|
+
name: "rect",
|
|
3197
|
+
type: "element",
|
|
3198
|
+
attributes: {
|
|
3199
|
+
class: "pcb-hole",
|
|
3200
|
+
x: (x - scaledWidth / 2).toString(),
|
|
3201
|
+
y: (y - scaledHeight / 2).toString(),
|
|
3202
|
+
width: scaledWidth.toString(),
|
|
3203
|
+
height: scaledHeight.toString(),
|
|
3204
|
+
fill: colorMap2.drill,
|
|
3205
|
+
"data-type": "pcb_hole",
|
|
3206
|
+
"data-pcb-layer": "drill"
|
|
3207
|
+
},
|
|
3208
|
+
children: [],
|
|
3209
|
+
value: ""
|
|
3210
|
+
};
|
|
3211
|
+
if (!shouldShowSolderMask) {
|
|
3212
|
+
return [holeElement];
|
|
3213
|
+
}
|
|
3214
|
+
const maskWidth = scaledWidth + 2 * soldermaskMargin;
|
|
3215
|
+
const maskHeight = scaledHeight + 2 * soldermaskMargin;
|
|
3216
|
+
const maskElement = {
|
|
3217
|
+
name: holeElement.name,
|
|
3218
|
+
type: holeElement.type,
|
|
3219
|
+
value: "",
|
|
3220
|
+
children: [],
|
|
3221
|
+
attributes: {
|
|
3222
|
+
...holeElement.attributes,
|
|
3223
|
+
class: "pcb-solder-mask",
|
|
3224
|
+
fill: solderMaskColor,
|
|
3225
|
+
"data-type": "pcb_soldermask",
|
|
3226
|
+
x: (x - maskWidth / 2).toString(),
|
|
3227
|
+
y: (y - maskHeight / 2).toString(),
|
|
3228
|
+
width: maskWidth.toString(),
|
|
3229
|
+
height: maskHeight.toString()
|
|
2988
3230
|
}
|
|
2989
|
-
|
|
3231
|
+
};
|
|
3232
|
+
return [holeElement, maskElement];
|
|
2990
3233
|
}
|
|
2991
3234
|
if (hole.hole_shape === "pill") {
|
|
2992
3235
|
const scaledWidth = hole.hole_width * Math.abs(transform.a);
|
|
@@ -3003,21 +3246,50 @@ function createSvgObjectsFromPcbHole(hole, ctx) {
|
|
|
3003
3246
|
// Vertical pill (taller than wide)
|
|
3004
3247
|
`M${x - radius},${y - straightLength / 2} v${straightLength} a${radius},${radius} 0 0 0 ${scaledWidth},0 v-${straightLength} a${radius},${radius} 0 0 0 -${scaledWidth},0 z`
|
|
3005
3248
|
);
|
|
3006
|
-
|
|
3007
|
-
|
|
3008
|
-
|
|
3009
|
-
|
|
3010
|
-
|
|
3011
|
-
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
|
|
3249
|
+
const holeElement = {
|
|
3250
|
+
name: "path",
|
|
3251
|
+
type: "element",
|
|
3252
|
+
attributes: {
|
|
3253
|
+
class: "pcb-hole",
|
|
3254
|
+
fill: colorMap2.drill,
|
|
3255
|
+
d: pathD,
|
|
3256
|
+
"data-type": "pcb_hole",
|
|
3257
|
+
"data-pcb-layer": "drill"
|
|
3258
|
+
},
|
|
3259
|
+
children: [],
|
|
3260
|
+
value: ""
|
|
3261
|
+
};
|
|
3262
|
+
if (!shouldShowSolderMask) {
|
|
3263
|
+
return [holeElement];
|
|
3264
|
+
}
|
|
3265
|
+
const maskWidth = scaledWidth + 2 * soldermaskMargin;
|
|
3266
|
+
const maskHeight = scaledHeight + 2 * soldermaskMargin;
|
|
3267
|
+
const maskIsHorizontal = maskWidth > maskHeight;
|
|
3268
|
+
const maskRadius = Math.min(maskWidth, maskHeight) / 2;
|
|
3269
|
+
const maskStraightLength = Math.abs(
|
|
3270
|
+
maskIsHorizontal ? maskWidth - maskHeight : maskHeight - maskWidth
|
|
3271
|
+
);
|
|
3272
|
+
const maskPathD = maskIsHorizontal ? (
|
|
3273
|
+
// Horizontal pill (wider than tall)
|
|
3274
|
+
`M${x - maskStraightLength / 2},${y - maskRadius} h${maskStraightLength} a${maskRadius},${maskRadius} 0 0 1 0,${maskHeight} h-${maskStraightLength} a${maskRadius},${maskRadius} 0 0 1 0,-${maskHeight} z`
|
|
3275
|
+
) : (
|
|
3276
|
+
// Vertical pill (taller than wide)
|
|
3277
|
+
`M${x - maskRadius},${y - maskStraightLength / 2} v${maskStraightLength} a${maskRadius},${maskRadius} 0 0 0 ${maskWidth},0 v-${maskStraightLength} a${maskRadius},${maskRadius} 0 0 0 -${maskWidth},0 z`
|
|
3278
|
+
);
|
|
3279
|
+
const maskElement = {
|
|
3280
|
+
name: holeElement.name,
|
|
3281
|
+
type: holeElement.type,
|
|
3282
|
+
value: "",
|
|
3283
|
+
children: [],
|
|
3284
|
+
attributes: {
|
|
3285
|
+
...holeElement.attributes,
|
|
3286
|
+
class: "pcb-solder-mask",
|
|
3287
|
+
fill: solderMaskColor,
|
|
3288
|
+
"data-type": "pcb_soldermask",
|
|
3289
|
+
d: maskPathD
|
|
3019
3290
|
}
|
|
3020
|
-
|
|
3291
|
+
};
|
|
3292
|
+
return [holeElement, maskElement];
|
|
3021
3293
|
}
|
|
3022
3294
|
if (hole.hole_shape === "rotated_pill") {
|
|
3023
3295
|
const scaledWidth = hole.hole_width * Math.abs(transform.a);
|
|
@@ -3035,22 +3307,51 @@ function createSvgObjectsFromPcbHole(hole, ctx) {
|
|
|
3035
3307
|
// Vertical pill (taller than wide)
|
|
3036
3308
|
`M${-radius},${-straightLength / 2} v${straightLength} a${radius},${radius} 0 0 0 ${scaledWidth},0 v-${straightLength} a${radius},${radius} 0 0 0 -${scaledWidth},0 z`
|
|
3037
3309
|
);
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
|
|
3050
|
-
|
|
3051
|
-
|
|
3310
|
+
const holeElement = {
|
|
3311
|
+
name: "path",
|
|
3312
|
+
type: "element",
|
|
3313
|
+
attributes: {
|
|
3314
|
+
class: "pcb-hole",
|
|
3315
|
+
fill: colorMap2.drill,
|
|
3316
|
+
d: pathD,
|
|
3317
|
+
transform: `translate(${x} ${y}) rotate(${-rotation})`,
|
|
3318
|
+
"data-type": "pcb_hole",
|
|
3319
|
+
"data-pcb-layer": "drill"
|
|
3320
|
+
},
|
|
3321
|
+
children: [],
|
|
3322
|
+
value: ""
|
|
3323
|
+
};
|
|
3324
|
+
if (!shouldShowSolderMask) {
|
|
3325
|
+
return [holeElement];
|
|
3326
|
+
}
|
|
3327
|
+
const maskWidth = scaledWidth + 2 * soldermaskMargin;
|
|
3328
|
+
const maskHeight = scaledHeight + 2 * soldermaskMargin;
|
|
3329
|
+
const maskIsHorizontal = maskWidth > maskHeight;
|
|
3330
|
+
const maskRadius = Math.min(maskWidth, maskHeight) / 2;
|
|
3331
|
+
const maskStraightLength = Math.abs(
|
|
3332
|
+
maskIsHorizontal ? maskWidth - maskHeight : maskHeight - maskWidth
|
|
3333
|
+
);
|
|
3334
|
+
const maskPathD = maskIsHorizontal ? (
|
|
3335
|
+
// Horizontal pill (wider than tall)
|
|
3336
|
+
`M${-maskStraightLength / 2},${-maskRadius} h${maskStraightLength} a${maskRadius},${maskRadius} 0 0 1 0,${maskHeight} h-${maskStraightLength} a${maskRadius},${maskRadius} 0 0 1 0,-${maskHeight} z`
|
|
3337
|
+
) : (
|
|
3338
|
+
// Vertical pill (taller than wide)
|
|
3339
|
+
`M${-maskRadius},${-maskStraightLength / 2} v${maskStraightLength} a${maskRadius},${maskRadius} 0 0 0 ${maskWidth},0 v-${maskStraightLength} a${maskRadius},${maskRadius} 0 0 0 -${maskWidth},0 z`
|
|
3340
|
+
);
|
|
3341
|
+
const maskElement = {
|
|
3342
|
+
name: holeElement.name,
|
|
3343
|
+
type: holeElement.type,
|
|
3344
|
+
value: "",
|
|
3345
|
+
children: [],
|
|
3346
|
+
attributes: {
|
|
3347
|
+
...holeElement.attributes,
|
|
3348
|
+
class: "pcb-solder-mask",
|
|
3349
|
+
fill: solderMaskColor,
|
|
3350
|
+
"data-type": "pcb_soldermask",
|
|
3351
|
+
d: maskPathD
|
|
3052
3352
|
}
|
|
3053
|
-
|
|
3353
|
+
};
|
|
3354
|
+
return [holeElement, maskElement];
|
|
3054
3355
|
}
|
|
3055
3356
|
return [];
|
|
3056
3357
|
}
|
|
@@ -3978,7 +4279,7 @@ function getSoftwareUsedString(circuitJson) {
|
|
|
3978
4279
|
var package_default = {
|
|
3979
4280
|
name: "circuit-to-svg",
|
|
3980
4281
|
type: "module",
|
|
3981
|
-
version: "0.0.
|
|
4282
|
+
version: "0.0.272",
|
|
3982
4283
|
description: "Convert Circuit JSON to SVG",
|
|
3983
4284
|
main: "dist/index.js",
|
|
3984
4285
|
files: [
|
|
@@ -4002,7 +4303,7 @@ var package_default = {
|
|
|
4002
4303
|
"bun-match-svg": "^0.0.12",
|
|
4003
4304
|
esbuild: "^0.20.2",
|
|
4004
4305
|
"performance-now": "^2.1.0",
|
|
4005
|
-
"circuit-json": "^0.0.
|
|
4306
|
+
"circuit-json": "^0.0.316",
|
|
4006
4307
|
react: "19.1.0",
|
|
4007
4308
|
"react-cosmos": "7.0.0",
|
|
4008
4309
|
"react-cosmos-plugin-vite": "7.0.0",
|