circuit-to-svg 0.0.277 → 0.0.279
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.d.ts +7 -0
- package/dist/index.js +986 -236
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1586,7 +1586,7 @@ function createSvgObjectsFromPcbPlatedHole(hole, ctx) {
|
|
|
1586
1586
|
const isCoveredWithSolderMask = Boolean(hole.is_covered_with_solder_mask);
|
|
1587
1587
|
const soldermaskMargin = (hole.soldermask_margin ?? 0) * Math.abs(transform.a);
|
|
1588
1588
|
const shouldShowSolderMask = showSolderMask && isCoveredWithSolderMask && soldermaskMargin !== 0;
|
|
1589
|
-
const solderMaskColor = colorMap2.
|
|
1589
|
+
const solderMaskColor = colorMap2.soldermaskWithCopperUnderneath.top;
|
|
1590
1590
|
if (hole.shape === "pill") {
|
|
1591
1591
|
const scaledOuterWidth = hole.outer_width * Math.abs(transform.a);
|
|
1592
1592
|
const scaledOuterHeight = hole.outer_height * Math.abs(transform.a);
|
|
@@ -1609,7 +1609,7 @@ function createSvgObjectsFromPcbPlatedHole(hole, ctx) {
|
|
|
1609
1609
|
return `M${-radius},0 a${radius},${radius} 0 0 1 ${width},0 a${radius},${radius} 0 0 1 ${-width},0 z`;
|
|
1610
1610
|
}
|
|
1611
1611
|
};
|
|
1612
|
-
|
|
1612
|
+
let children = [
|
|
1613
1613
|
// Outer pill shape
|
|
1614
1614
|
{
|
|
1615
1615
|
name: "path",
|
|
@@ -1644,19 +1644,57 @@ function createSvgObjectsFromPcbPlatedHole(hole, ctx) {
|
|
|
1644
1644
|
if (shouldShowSolderMask) {
|
|
1645
1645
|
const maskWidth = scaledOuterWidth + 2 * soldermaskMargin;
|
|
1646
1646
|
const maskHeight = scaledOuterHeight + 2 * soldermaskMargin;
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1647
|
+
if (soldermaskMargin < 0) {
|
|
1648
|
+
children = [
|
|
1649
|
+
// 1. Draw the outer pad in soldermask color (covered)
|
|
1650
|
+
{
|
|
1651
|
+
name: "path",
|
|
1652
|
+
type: "element",
|
|
1653
|
+
attributes: {
|
|
1654
|
+
class: "pcb-hole-outer-covered",
|
|
1655
|
+
fill: solderMaskColor,
|
|
1656
|
+
d: createPillPath(scaledOuterWidth, scaledOuterHeight),
|
|
1657
|
+
transform: outerTransform,
|
|
1658
|
+
"data-type": "pcb_plated_hole",
|
|
1659
|
+
"data-pcb-layer": copperLayer
|
|
1660
|
+
},
|
|
1661
|
+
value: "",
|
|
1662
|
+
children: []
|
|
1663
|
+
},
|
|
1664
|
+
// 2. Draw the exposed opening in copper color
|
|
1665
|
+
{
|
|
1666
|
+
name: "path",
|
|
1667
|
+
type: "element",
|
|
1668
|
+
attributes: {
|
|
1669
|
+
class: "pcb-hole-outer-exposed",
|
|
1670
|
+
fill: colorMap2.copper.top,
|
|
1671
|
+
d: createPillPath(maskWidth, maskHeight),
|
|
1672
|
+
transform: outerTransform,
|
|
1673
|
+
"data-type": "pcb_soldermask"
|
|
1674
|
+
},
|
|
1675
|
+
value: "",
|
|
1676
|
+
children: []
|
|
1677
|
+
},
|
|
1678
|
+
// 3. Draw the drill hole on top
|
|
1679
|
+
children[1]
|
|
1680
|
+
// Original inner hole
|
|
1681
|
+
];
|
|
1682
|
+
} else {
|
|
1683
|
+
children.unshift({
|
|
1684
|
+
name: "path",
|
|
1685
|
+
type: "element",
|
|
1686
|
+
attributes: {
|
|
1687
|
+
class: "pcb-soldermask-cutout",
|
|
1688
|
+
fill: colorMap2.substrate,
|
|
1689
|
+
d: createPillPath(maskWidth, maskHeight),
|
|
1690
|
+
transform: outerTransform,
|
|
1691
|
+
"data-type": "pcb_soldermask_opening",
|
|
1692
|
+
"data-pcb-layer": "soldermask-top"
|
|
1693
|
+
},
|
|
1694
|
+
value: "",
|
|
1695
|
+
children: []
|
|
1696
|
+
});
|
|
1697
|
+
}
|
|
1660
1698
|
}
|
|
1661
1699
|
return [
|
|
1662
1700
|
{
|
|
@@ -1736,7 +1774,7 @@ function createSvgObjectsFromPcbPlatedHole(hole, ctx) {
|
|
|
1736
1774
|
const scaledHoleHeight = hole.hole_diameter * Math.abs(transform.a);
|
|
1737
1775
|
const outerRadius = Math.min(scaledOuterWidth, scaledOuterHeight) / 2;
|
|
1738
1776
|
const innerRadius = Math.min(scaledHoleWidth, scaledHoleHeight) / 2;
|
|
1739
|
-
|
|
1777
|
+
let children = [
|
|
1740
1778
|
{
|
|
1741
1779
|
name: "circle",
|
|
1742
1780
|
type: "element",
|
|
@@ -1770,20 +1808,60 @@ function createSvgObjectsFromPcbPlatedHole(hole, ctx) {
|
|
|
1770
1808
|
];
|
|
1771
1809
|
if (shouldShowSolderMask) {
|
|
1772
1810
|
const maskRadius = outerRadius + soldermaskMargin;
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1811
|
+
if (soldermaskMargin < 0) {
|
|
1812
|
+
children = [
|
|
1813
|
+
// 1. Draw the outer ring in soldermask color (covered)
|
|
1814
|
+
{
|
|
1815
|
+
name: "circle",
|
|
1816
|
+
type: "element",
|
|
1817
|
+
attributes: {
|
|
1818
|
+
class: "pcb-hole-outer-covered",
|
|
1819
|
+
fill: solderMaskColor,
|
|
1820
|
+
cx: x.toString(),
|
|
1821
|
+
cy: y.toString(),
|
|
1822
|
+
r: outerRadius.toString(),
|
|
1823
|
+
"data-type": "pcb_plated_hole",
|
|
1824
|
+
"data-pcb-layer": copperLayer
|
|
1825
|
+
},
|
|
1826
|
+
value: "",
|
|
1827
|
+
children: []
|
|
1828
|
+
},
|
|
1829
|
+
// 2. Draw the exposed opening in copper color
|
|
1830
|
+
{
|
|
1831
|
+
name: "circle",
|
|
1832
|
+
type: "element",
|
|
1833
|
+
attributes: {
|
|
1834
|
+
class: "pcb-hole-outer-exposed",
|
|
1835
|
+
fill: colorMap2.copper.top,
|
|
1836
|
+
cx: x.toString(),
|
|
1837
|
+
cy: y.toString(),
|
|
1838
|
+
r: maskRadius.toString(),
|
|
1839
|
+
"data-type": "pcb_soldermask"
|
|
1840
|
+
},
|
|
1841
|
+
value: "",
|
|
1842
|
+
children: []
|
|
1843
|
+
},
|
|
1844
|
+
// 3. Draw the drill hole on top
|
|
1845
|
+
children[1]
|
|
1846
|
+
// Original inner hole
|
|
1847
|
+
];
|
|
1848
|
+
} else {
|
|
1849
|
+
children.unshift({
|
|
1850
|
+
name: "circle",
|
|
1851
|
+
type: "element",
|
|
1852
|
+
attributes: {
|
|
1853
|
+
class: "pcb-soldermask-cutout",
|
|
1854
|
+
fill: colorMap2.substrate,
|
|
1855
|
+
cx: x.toString(),
|
|
1856
|
+
cy: y.toString(),
|
|
1857
|
+
r: maskRadius.toString(),
|
|
1858
|
+
"data-type": "pcb_soldermask_opening",
|
|
1859
|
+
"data-pcb-layer": "soldermask-top"
|
|
1860
|
+
},
|
|
1861
|
+
value: "",
|
|
1862
|
+
children: []
|
|
1863
|
+
});
|
|
1864
|
+
}
|
|
1787
1865
|
}
|
|
1788
1866
|
return [
|
|
1789
1867
|
{
|
|
@@ -1809,7 +1887,7 @@ function createSvgObjectsFromPcbPlatedHole(hole, ctx) {
|
|
|
1809
1887
|
h.x + (h.hole_offset_x ?? 0),
|
|
1810
1888
|
h.y + (h.hole_offset_y ?? 0)
|
|
1811
1889
|
]);
|
|
1812
|
-
|
|
1890
|
+
let children = [
|
|
1813
1891
|
// Rectangular pad (outer shape)
|
|
1814
1892
|
{
|
|
1815
1893
|
name: "rect",
|
|
@@ -1852,25 +1930,75 @@ function createSvgObjectsFromPcbPlatedHole(hole, ctx) {
|
|
|
1852
1930
|
const maskWidth = scaledRectPadWidth + 2 * soldermaskMargin;
|
|
1853
1931
|
const maskHeight = scaledRectPadHeight + 2 * soldermaskMargin;
|
|
1854
1932
|
const maskBorderRadius = scaledRectBorderRadius + soldermaskMargin;
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1933
|
+
if (soldermaskMargin < 0) {
|
|
1934
|
+
children = [
|
|
1935
|
+
// 1. Draw the outer pad in soldermask color (covered)
|
|
1936
|
+
{
|
|
1937
|
+
name: "rect",
|
|
1938
|
+
type: "element",
|
|
1939
|
+
attributes: {
|
|
1940
|
+
class: "pcb-hole-outer-covered",
|
|
1941
|
+
fill: solderMaskColor,
|
|
1942
|
+
x: (x - scaledRectPadWidth / 2).toString(),
|
|
1943
|
+
y: (y - scaledRectPadHeight / 2).toString(),
|
|
1944
|
+
width: scaledRectPadWidth.toString(),
|
|
1945
|
+
height: scaledRectPadHeight.toString(),
|
|
1946
|
+
...scaledRectBorderRadius ? {
|
|
1947
|
+
rx: scaledRectBorderRadius.toString(),
|
|
1948
|
+
ry: scaledRectBorderRadius.toString()
|
|
1949
|
+
} : {},
|
|
1950
|
+
"data-type": "pcb_plated_hole",
|
|
1951
|
+
"data-pcb-layer": copperLayer
|
|
1952
|
+
},
|
|
1953
|
+
value: "",
|
|
1954
|
+
children: []
|
|
1955
|
+
},
|
|
1956
|
+
// 2. Draw the exposed opening in copper color
|
|
1957
|
+
{
|
|
1958
|
+
name: "rect",
|
|
1959
|
+
type: "element",
|
|
1960
|
+
attributes: {
|
|
1961
|
+
class: "pcb-hole-outer-exposed",
|
|
1962
|
+
fill: colorMap2.copper.top,
|
|
1963
|
+
x: (x - maskWidth / 2).toString(),
|
|
1964
|
+
y: (y - maskHeight / 2).toString(),
|
|
1965
|
+
width: maskWidth.toString(),
|
|
1966
|
+
height: maskHeight.toString(),
|
|
1967
|
+
...maskBorderRadius > 0 ? {
|
|
1968
|
+
rx: maskBorderRadius.toString(),
|
|
1969
|
+
ry: maskBorderRadius.toString()
|
|
1970
|
+
} : {},
|
|
1971
|
+
"data-type": "pcb_soldermask"
|
|
1972
|
+
},
|
|
1973
|
+
value: "",
|
|
1974
|
+
children: []
|
|
1975
|
+
},
|
|
1976
|
+
// 3. Draw the drill hole on top
|
|
1977
|
+
children[1]
|
|
1978
|
+
// Original hole
|
|
1979
|
+
];
|
|
1980
|
+
} else {
|
|
1981
|
+
children.unshift({
|
|
1982
|
+
name: "rect",
|
|
1983
|
+
type: "element",
|
|
1984
|
+
attributes: {
|
|
1985
|
+
class: "pcb-soldermask-cutout",
|
|
1986
|
+
fill: colorMap2.substrate,
|
|
1987
|
+
x: (x - maskWidth / 2).toString(),
|
|
1988
|
+
y: (y - maskHeight / 2).toString(),
|
|
1989
|
+
width: maskWidth.toString(),
|
|
1990
|
+
height: maskHeight.toString(),
|
|
1991
|
+
...scaledRectBorderRadius ? {
|
|
1992
|
+
rx: maskBorderRadius.toString(),
|
|
1993
|
+
ry: maskBorderRadius.toString()
|
|
1994
|
+
} : {},
|
|
1995
|
+
"data-type": "pcb_soldermask_opening",
|
|
1996
|
+
"data-pcb-layer": "soldermask-top"
|
|
1997
|
+
},
|
|
1998
|
+
value: "",
|
|
1999
|
+
children: []
|
|
2000
|
+
});
|
|
2001
|
+
}
|
|
1874
2002
|
}
|
|
1875
2003
|
return [
|
|
1876
2004
|
{
|
|
@@ -1900,7 +2028,7 @@ function createSvgObjectsFromPcbPlatedHole(hole, ctx) {
|
|
|
1900
2028
|
pillHole.y + holeOffsetY
|
|
1901
2029
|
]);
|
|
1902
2030
|
const holeRadius = Math.min(scaledHoleHeight, scaledHoleWidth) / 2;
|
|
1903
|
-
|
|
2031
|
+
let children = [
|
|
1904
2032
|
// Rectangular pad (outer shape)
|
|
1905
2033
|
{
|
|
1906
2034
|
name: "rect",
|
|
@@ -1946,25 +2074,75 @@ function createSvgObjectsFromPcbPlatedHole(hole, ctx) {
|
|
|
1946
2074
|
const maskWidth = scaledRectPadWidth + 2 * soldermaskMargin;
|
|
1947
2075
|
const maskHeight = scaledRectPadHeight + 2 * soldermaskMargin;
|
|
1948
2076
|
const maskBorderRadius = scaledRectBorderRadius + soldermaskMargin;
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
2077
|
+
if (soldermaskMargin < 0) {
|
|
2078
|
+
children = [
|
|
2079
|
+
// 1. Draw the outer pad in soldermask color (covered)
|
|
2080
|
+
{
|
|
2081
|
+
name: "rect",
|
|
2082
|
+
type: "element",
|
|
2083
|
+
attributes: {
|
|
2084
|
+
class: "pcb-hole-outer-covered",
|
|
2085
|
+
fill: solderMaskColor,
|
|
2086
|
+
x: (x - scaledRectPadWidth / 2).toString(),
|
|
2087
|
+
y: (y - scaledRectPadHeight / 2).toString(),
|
|
2088
|
+
width: scaledRectPadWidth.toString(),
|
|
2089
|
+
height: scaledRectPadHeight.toString(),
|
|
2090
|
+
...scaledRectBorderRadius ? {
|
|
2091
|
+
rx: scaledRectBorderRadius.toString(),
|
|
2092
|
+
ry: scaledRectBorderRadius.toString()
|
|
2093
|
+
} : {},
|
|
2094
|
+
"data-type": "pcb_plated_hole",
|
|
2095
|
+
"data-pcb-layer": copperLayer
|
|
2096
|
+
},
|
|
2097
|
+
value: "",
|
|
2098
|
+
children: []
|
|
2099
|
+
},
|
|
2100
|
+
// 2. Draw the exposed opening in copper color
|
|
2101
|
+
{
|
|
2102
|
+
name: "rect",
|
|
2103
|
+
type: "element",
|
|
2104
|
+
attributes: {
|
|
2105
|
+
class: "pcb-hole-outer-exposed",
|
|
2106
|
+
fill: colorMap2.copper.top,
|
|
2107
|
+
x: (x - maskWidth / 2).toString(),
|
|
2108
|
+
y: (y - maskHeight / 2).toString(),
|
|
2109
|
+
width: maskWidth.toString(),
|
|
2110
|
+
height: maskHeight.toString(),
|
|
2111
|
+
...maskBorderRadius > 0 ? {
|
|
2112
|
+
rx: maskBorderRadius.toString(),
|
|
2113
|
+
ry: maskBorderRadius.toString()
|
|
2114
|
+
} : {},
|
|
2115
|
+
"data-type": "pcb_soldermask"
|
|
2116
|
+
},
|
|
2117
|
+
value: "",
|
|
2118
|
+
children: []
|
|
2119
|
+
},
|
|
2120
|
+
// 3. Draw the drill hole on top
|
|
2121
|
+
children[1]
|
|
2122
|
+
// Original hole
|
|
2123
|
+
];
|
|
2124
|
+
} else {
|
|
2125
|
+
children.unshift({
|
|
2126
|
+
name: "rect",
|
|
2127
|
+
type: "element",
|
|
2128
|
+
attributes: {
|
|
2129
|
+
class: "pcb-soldermask-cutout",
|
|
2130
|
+
fill: colorMap2.substrate,
|
|
2131
|
+
x: (x - maskWidth / 2).toString(),
|
|
2132
|
+
y: (y - maskHeight / 2).toString(),
|
|
2133
|
+
width: maskWidth.toString(),
|
|
2134
|
+
height: maskHeight.toString(),
|
|
2135
|
+
...scaledRectBorderRadius ? {
|
|
2136
|
+
rx: maskBorderRadius.toString(),
|
|
2137
|
+
ry: maskBorderRadius.toString()
|
|
2138
|
+
} : {},
|
|
2139
|
+
"data-type": "pcb_soldermask_opening",
|
|
2140
|
+
"data-pcb-layer": "soldermask-top"
|
|
2141
|
+
},
|
|
2142
|
+
value: "",
|
|
2143
|
+
children: []
|
|
2144
|
+
});
|
|
2145
|
+
}
|
|
1968
2146
|
}
|
|
1969
2147
|
return [
|
|
1970
2148
|
{
|
|
@@ -1994,7 +2172,7 @@ function createSvgObjectsFromPcbPlatedHole(hole, ctx) {
|
|
|
1994
2172
|
rotatedHole.y + holeOffsetY
|
|
1995
2173
|
]);
|
|
1996
2174
|
const holeRadius = Math.min(scaledHoleHeight, scaledHoleWidth) / 2;
|
|
1997
|
-
|
|
2175
|
+
let children = [
|
|
1998
2176
|
{
|
|
1999
2177
|
name: "rect",
|
|
2000
2178
|
type: "element",
|
|
@@ -2040,26 +2218,77 @@ function createSvgObjectsFromPcbPlatedHole(hole, ctx) {
|
|
|
2040
2218
|
const maskWidth = scaledRectPadWidth + 2 * soldermaskMargin;
|
|
2041
2219
|
const maskHeight = scaledRectPadHeight + 2 * soldermaskMargin;
|
|
2042
2220
|
const maskBorderRadius = scaledRectBorderRadius + soldermaskMargin;
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2221
|
+
if (soldermaskMargin < 0) {
|
|
2222
|
+
children = [
|
|
2223
|
+
// 1. Draw the outer pad in soldermask color (covered)
|
|
2224
|
+
{
|
|
2225
|
+
name: "rect",
|
|
2226
|
+
type: "element",
|
|
2227
|
+
attributes: {
|
|
2228
|
+
class: "pcb-hole-outer-covered",
|
|
2229
|
+
fill: solderMaskColor,
|
|
2230
|
+
x: (-scaledRectPadWidth / 2).toString(),
|
|
2231
|
+
y: (-scaledRectPadHeight / 2).toString(),
|
|
2232
|
+
width: scaledRectPadWidth.toString(),
|
|
2233
|
+
height: scaledRectPadHeight.toString(),
|
|
2234
|
+
transform: `translate(${x} ${y}) rotate(${-rotatedHole.rect_ccw_rotation})`,
|
|
2235
|
+
...scaledRectBorderRadius ? {
|
|
2236
|
+
rx: scaledRectBorderRadius.toString(),
|
|
2237
|
+
ry: scaledRectBorderRadius.toString()
|
|
2238
|
+
} : {},
|
|
2239
|
+
"data-type": "pcb_plated_hole",
|
|
2240
|
+
"data-pcb-layer": copperLayer
|
|
2241
|
+
},
|
|
2242
|
+
value: "",
|
|
2243
|
+
children: []
|
|
2244
|
+
},
|
|
2245
|
+
// 2. Draw the exposed opening in copper color
|
|
2246
|
+
{
|
|
2247
|
+
name: "rect",
|
|
2248
|
+
type: "element",
|
|
2249
|
+
attributes: {
|
|
2250
|
+
class: "pcb-hole-outer-exposed",
|
|
2251
|
+
fill: colorMap2.copper.top,
|
|
2252
|
+
x: (-maskWidth / 2).toString(),
|
|
2253
|
+
y: (-maskHeight / 2).toString(),
|
|
2254
|
+
width: maskWidth.toString(),
|
|
2255
|
+
height: maskHeight.toString(),
|
|
2256
|
+
transform: `translate(${x} ${y}) rotate(${-rotatedHole.rect_ccw_rotation})`,
|
|
2257
|
+
...maskBorderRadius > 0 ? {
|
|
2258
|
+
rx: maskBorderRadius.toString(),
|
|
2259
|
+
ry: maskBorderRadius.toString()
|
|
2260
|
+
} : {},
|
|
2261
|
+
"data-type": "pcb_soldermask"
|
|
2262
|
+
},
|
|
2263
|
+
value: "",
|
|
2264
|
+
children: []
|
|
2265
|
+
},
|
|
2266
|
+
// 3. Draw the drill hole on top
|
|
2267
|
+
children[1]
|
|
2268
|
+
// Original hole
|
|
2269
|
+
];
|
|
2270
|
+
} else {
|
|
2271
|
+
children.push({
|
|
2272
|
+
name: "rect",
|
|
2273
|
+
type: "element",
|
|
2274
|
+
attributes: {
|
|
2275
|
+
class: "pcb-solder-mask",
|
|
2276
|
+
fill: solderMaskColor,
|
|
2277
|
+
x: (-maskWidth / 2).toString(),
|
|
2278
|
+
y: (-maskHeight / 2).toString(),
|
|
2279
|
+
width: maskWidth.toString(),
|
|
2280
|
+
height: maskHeight.toString(),
|
|
2281
|
+
transform: `translate(${x} ${y}) rotate(${-rotatedHole.rect_ccw_rotation})`,
|
|
2282
|
+
...scaledRectBorderRadius ? {
|
|
2283
|
+
rx: maskBorderRadius.toString(),
|
|
2284
|
+
ry: maskBorderRadius.toString()
|
|
2285
|
+
} : {},
|
|
2286
|
+
"data-type": "pcb_soldermask"
|
|
2287
|
+
},
|
|
2288
|
+
value: "",
|
|
2289
|
+
children: []
|
|
2290
|
+
});
|
|
2291
|
+
}
|
|
2063
2292
|
}
|
|
2064
2293
|
return [
|
|
2065
2294
|
{
|
|
@@ -2603,10 +2832,16 @@ var DEFAULT_PCB_COLOR_MAP = {
|
|
|
2603
2832
|
inner6: "rgb(255, 105, 180)",
|
|
2604
2833
|
bottom: "rgb(77, 127, 196)"
|
|
2605
2834
|
},
|
|
2606
|
-
|
|
2835
|
+
soldermaskWithCopperUnderneath: {
|
|
2607
2836
|
top: "rgb(18, 82, 50)",
|
|
2608
2837
|
bottom: "rgb(77, 127, 196)"
|
|
2609
2838
|
},
|
|
2839
|
+
soldermask: {
|
|
2840
|
+
top: "rgb(12, 55, 33)",
|
|
2841
|
+
bottom: "rgb(52, 87, 136)"
|
|
2842
|
+
},
|
|
2843
|
+
substrate: "rgb(201, 162, 110)",
|
|
2844
|
+
// FR4 substrate color (tan/beige)
|
|
2610
2845
|
drill: "#FF26E2",
|
|
2611
2846
|
silkscreen: {
|
|
2612
2847
|
top: "#f2eda1",
|
|
@@ -2652,7 +2887,7 @@ function createSvgObjectsFromPcbTrace(trace, ctx) {
|
|
|
2652
2887
|
if (!layer) continue;
|
|
2653
2888
|
if (layerFilter && layer !== layerFilter) continue;
|
|
2654
2889
|
const copperColor = layerNameToColor(layer, colorMap2);
|
|
2655
|
-
const maskColor = colorMap2.
|
|
2890
|
+
const maskColor = colorMap2.soldermaskWithCopperUnderneath[layer];
|
|
2656
2891
|
const traceWidth = "width" in start ? start.width : "width" in end ? end.width : null;
|
|
2657
2892
|
const width = traceWidth ? (traceWidth * Math.abs(transform.a)).toString() : "0.3";
|
|
2658
2893
|
if (showSolderMask) {
|
|
@@ -2725,7 +2960,7 @@ function createSvgObjectsFromSmtPad(pad, ctx) {
|
|
|
2725
2960
|
if (layerFilter && pad.layer !== layerFilter) return [];
|
|
2726
2961
|
const isCoveredWithSolderMask = Boolean(pad?.is_covered_with_solder_mask);
|
|
2727
2962
|
const shouldshowSolderMask = showSolderMask && isCoveredWithSolderMask;
|
|
2728
|
-
const
|
|
2963
|
+
const soldermaskWithCopperUnderneathColor = colorMap2.soldermaskWithCopperUnderneath[pad.layer] ?? colorMap2.soldermaskWithCopperUnderneath.top;
|
|
2729
2964
|
const soldermaskMargin = (pad.soldermask_margin ?? 0) * Math.abs(transform.a);
|
|
2730
2965
|
if (pad.shape === "rect" || pad.shape === "rotated_rect") {
|
|
2731
2966
|
const width = pad.width * Math.abs(transform.a);
|
|
@@ -2761,27 +2996,97 @@ function createSvgObjectsFromSmtPad(pad, ctx) {
|
|
|
2761
2996
|
const maskWidth2 = width + 2 * soldermaskMargin;
|
|
2762
2997
|
const maskHeight2 = height + 2 * soldermaskMargin;
|
|
2763
2998
|
const maskBorderRadius2 = scaledBorderRadius ? scaledBorderRadius + soldermaskMargin : 0;
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2999
|
+
if (soldermaskMargin < 0) {
|
|
3000
|
+
const coveredPadElement = {
|
|
3001
|
+
name: "rect",
|
|
3002
|
+
type: "element",
|
|
3003
|
+
value: "",
|
|
3004
|
+
children: [],
|
|
3005
|
+
attributes: {
|
|
3006
|
+
class: "pcb-pad-covered",
|
|
3007
|
+
fill: soldermaskWithCopperUnderneathColor,
|
|
3008
|
+
x: (-width / 2).toString(),
|
|
3009
|
+
y: (-height / 2).toString(),
|
|
3010
|
+
width: width.toString(),
|
|
3011
|
+
height: height.toString(),
|
|
3012
|
+
transform: `translate(${x} ${y}) rotate(${-pad.ccw_rotation})`,
|
|
3013
|
+
"data-type": "pcb_smtpad",
|
|
3014
|
+
"data-pcb-layer": pad.layer,
|
|
3015
|
+
...scaledBorderRadius ? {
|
|
3016
|
+
rx: scaledBorderRadius.toString(),
|
|
3017
|
+
ry: scaledBorderRadius.toString()
|
|
3018
|
+
} : {}
|
|
3019
|
+
}
|
|
3020
|
+
};
|
|
3021
|
+
const exposedOpeningElement = {
|
|
3022
|
+
name: "rect",
|
|
3023
|
+
type: "element",
|
|
3024
|
+
value: "",
|
|
3025
|
+
children: [],
|
|
3026
|
+
attributes: {
|
|
3027
|
+
class: "pcb-pad-exposed",
|
|
3028
|
+
fill: layerNameToColor(pad.layer, colorMap2),
|
|
3029
|
+
x: (-maskWidth2 / 2).toString(),
|
|
3030
|
+
y: (-maskHeight2 / 2).toString(),
|
|
3031
|
+
width: maskWidth2.toString(),
|
|
3032
|
+
height: maskHeight2.toString(),
|
|
3033
|
+
transform: `translate(${x} ${y}) rotate(${-pad.ccw_rotation})`,
|
|
3034
|
+
"data-type": "pcb_soldermask",
|
|
3035
|
+
"data-pcb-layer": pad.layer,
|
|
3036
|
+
...maskBorderRadius2 > 0 ? {
|
|
3037
|
+
rx: maskBorderRadius2.toString(),
|
|
3038
|
+
ry: maskBorderRadius2.toString()
|
|
3039
|
+
} : {}
|
|
3040
|
+
}
|
|
3041
|
+
};
|
|
3042
|
+
return [coveredPadElement, exposedOpeningElement];
|
|
3043
|
+
}
|
|
3044
|
+
if (soldermaskMargin === 0) {
|
|
3045
|
+
const coveredPadElement = {
|
|
3046
|
+
name: "rect",
|
|
3047
|
+
type: "element",
|
|
3048
|
+
value: "",
|
|
3049
|
+
children: [],
|
|
3050
|
+
attributes: {
|
|
3051
|
+
class: "pcb-pad-covered",
|
|
3052
|
+
fill: soldermaskWithCopperUnderneathColor,
|
|
3053
|
+
x: (-width / 2).toString(),
|
|
3054
|
+
y: (-height / 2).toString(),
|
|
3055
|
+
width: width.toString(),
|
|
3056
|
+
height: height.toString(),
|
|
3057
|
+
transform: `translate(${x} ${y}) rotate(${-pad.ccw_rotation})`,
|
|
3058
|
+
"data-type": "pcb_smtpad",
|
|
3059
|
+
"data-pcb-layer": pad.layer,
|
|
3060
|
+
...scaledBorderRadius ? {
|
|
3061
|
+
rx: scaledBorderRadius.toString(),
|
|
3062
|
+
ry: scaledBorderRadius.toString()
|
|
3063
|
+
} : {}
|
|
3064
|
+
}
|
|
3065
|
+
};
|
|
3066
|
+
return [coveredPadElement];
|
|
3067
|
+
}
|
|
3068
|
+
const substrateElement2 = {
|
|
3069
|
+
name: "rect",
|
|
3070
|
+
type: "element",
|
|
2767
3071
|
value: "",
|
|
2768
3072
|
children: [],
|
|
2769
3073
|
attributes: {
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
fill: solderMaskColor,
|
|
2773
|
-
"data-type": "pcb_soldermask",
|
|
3074
|
+
class: "pcb-soldermask-cutout",
|
|
3075
|
+
fill: colorMap2.substrate,
|
|
2774
3076
|
x: (-maskWidth2 / 2).toString(),
|
|
2775
3077
|
y: (-maskHeight2 / 2).toString(),
|
|
2776
3078
|
width: maskWidth2.toString(),
|
|
2777
3079
|
height: maskHeight2.toString(),
|
|
3080
|
+
transform: `translate(${x} ${y}) rotate(${-pad.ccw_rotation})`,
|
|
2778
3081
|
...maskBorderRadius2 > 0 ? {
|
|
2779
3082
|
rx: maskBorderRadius2.toString(),
|
|
2780
3083
|
ry: maskBorderRadius2.toString()
|
|
2781
|
-
} : {}
|
|
3084
|
+
} : {},
|
|
3085
|
+
"data-type": "pcb_soldermask_opening",
|
|
3086
|
+
"data-pcb-layer": `soldermask-${pad.layer}`
|
|
2782
3087
|
}
|
|
2783
3088
|
};
|
|
2784
|
-
return [
|
|
3089
|
+
return [substrateElement2, padElement2];
|
|
2785
3090
|
}
|
|
2786
3091
|
const padElement = {
|
|
2787
3092
|
name: "rect",
|
|
@@ -2809,16 +3114,80 @@ function createSvgObjectsFromSmtPad(pad, ctx) {
|
|
|
2809
3114
|
const maskWidth = width + 2 * soldermaskMargin;
|
|
2810
3115
|
const maskHeight = height + 2 * soldermaskMargin;
|
|
2811
3116
|
const maskBorderRadius = scaledBorderRadius ? scaledBorderRadius + soldermaskMargin : 0;
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
|
|
3117
|
+
if (soldermaskMargin < 0) {
|
|
3118
|
+
const coveredPadElement = {
|
|
3119
|
+
name: "rect",
|
|
3120
|
+
type: "element",
|
|
3121
|
+
value: "",
|
|
3122
|
+
children: [],
|
|
3123
|
+
attributes: {
|
|
3124
|
+
class: "pcb-pad-covered",
|
|
3125
|
+
fill: soldermaskWithCopperUnderneathColor,
|
|
3126
|
+
x: (x - width / 2).toString(),
|
|
3127
|
+
y: (y - height / 2).toString(),
|
|
3128
|
+
width: width.toString(),
|
|
3129
|
+
height: height.toString(),
|
|
3130
|
+
"data-type": "pcb_smtpad",
|
|
3131
|
+
"data-pcb-layer": pad.layer,
|
|
3132
|
+
...scaledBorderRadius ? {
|
|
3133
|
+
rx: scaledBorderRadius.toString(),
|
|
3134
|
+
ry: scaledBorderRadius.toString()
|
|
3135
|
+
} : {}
|
|
3136
|
+
}
|
|
3137
|
+
};
|
|
3138
|
+
const exposedOpeningElement = {
|
|
3139
|
+
name: "rect",
|
|
3140
|
+
type: "element",
|
|
3141
|
+
value: "",
|
|
3142
|
+
children: [],
|
|
3143
|
+
attributes: {
|
|
3144
|
+
class: "pcb-pad-exposed",
|
|
3145
|
+
fill: layerNameToColor(pad.layer, colorMap2),
|
|
3146
|
+
x: (x - maskWidth / 2).toString(),
|
|
3147
|
+
y: (y - maskHeight / 2).toString(),
|
|
3148
|
+
width: maskWidth.toString(),
|
|
3149
|
+
height: maskHeight.toString(),
|
|
3150
|
+
"data-type": "pcb_soldermask",
|
|
3151
|
+
"data-pcb-layer": pad.layer,
|
|
3152
|
+
...maskBorderRadius > 0 ? {
|
|
3153
|
+
rx: maskBorderRadius.toString(),
|
|
3154
|
+
ry: maskBorderRadius.toString()
|
|
3155
|
+
} : {}
|
|
3156
|
+
}
|
|
3157
|
+
};
|
|
3158
|
+
return [coveredPadElement, exposedOpeningElement];
|
|
3159
|
+
}
|
|
3160
|
+
if (soldermaskMargin === 0) {
|
|
3161
|
+
const coveredPadElement = {
|
|
3162
|
+
name: "rect",
|
|
3163
|
+
type: "element",
|
|
3164
|
+
value: "",
|
|
3165
|
+
children: [],
|
|
3166
|
+
attributes: {
|
|
3167
|
+
class: "pcb-pad-covered",
|
|
3168
|
+
fill: soldermaskWithCopperUnderneathColor,
|
|
3169
|
+
x: (x - width / 2).toString(),
|
|
3170
|
+
y: (y - height / 2).toString(),
|
|
3171
|
+
width: width.toString(),
|
|
3172
|
+
height: height.toString(),
|
|
3173
|
+
...maskBorderRadius > 0 ? {
|
|
3174
|
+
rx: scaledBorderRadius.toString(),
|
|
3175
|
+
ry: scaledBorderRadius.toString()
|
|
3176
|
+
} : {},
|
|
3177
|
+
"data-type": "pcb_smtpad",
|
|
3178
|
+
"data-pcb-layer": pad.layer
|
|
3179
|
+
}
|
|
3180
|
+
};
|
|
3181
|
+
return [coveredPadElement];
|
|
3182
|
+
}
|
|
3183
|
+
const substrateElement = {
|
|
3184
|
+
name: "rect",
|
|
3185
|
+
type: "element",
|
|
2815
3186
|
value: "",
|
|
2816
3187
|
children: [],
|
|
2817
3188
|
attributes: {
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
fill: solderMaskColor,
|
|
2821
|
-
"data-type": "pcb_soldermask",
|
|
3189
|
+
class: "pcb-soldermask-cutout",
|
|
3190
|
+
fill: colorMap2.substrate,
|
|
2822
3191
|
x: (x - maskWidth / 2).toString(),
|
|
2823
3192
|
y: (y - maskHeight / 2).toString(),
|
|
2824
3193
|
width: maskWidth.toString(),
|
|
@@ -2826,10 +3195,12 @@ function createSvgObjectsFromSmtPad(pad, ctx) {
|
|
|
2826
3195
|
...maskBorderRadius > 0 ? {
|
|
2827
3196
|
rx: maskBorderRadius.toString(),
|
|
2828
3197
|
ry: maskBorderRadius.toString()
|
|
2829
|
-
} : {}
|
|
3198
|
+
} : {},
|
|
3199
|
+
"data-type": "pcb_soldermask_opening",
|
|
3200
|
+
"data-pcb-layer": `soldermask-${pad.layer}`
|
|
2830
3201
|
}
|
|
2831
3202
|
};
|
|
2832
|
-
return [
|
|
3203
|
+
return [substrateElement, padElement];
|
|
2833
3204
|
}
|
|
2834
3205
|
if (pad.shape === "pill") {
|
|
2835
3206
|
const width = pad.width * Math.abs(transform.a);
|
|
@@ -2857,65 +3228,178 @@ function createSvgObjectsFromSmtPad(pad, ctx) {
|
|
|
2857
3228
|
if (!shouldshowSolderMask) {
|
|
2858
3229
|
return [padElement];
|
|
2859
3230
|
}
|
|
2860
|
-
const maskWidth = width + 2 * soldermaskMargin;
|
|
2861
|
-
const maskHeight = height + 2 * soldermaskMargin;
|
|
2862
|
-
const maskRadius = radius + soldermaskMargin;
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
|
|
2880
|
-
|
|
2881
|
-
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
3231
|
+
const maskWidth = width + 2 * soldermaskMargin;
|
|
3232
|
+
const maskHeight = height + 2 * soldermaskMargin;
|
|
3233
|
+
const maskRadius = radius + soldermaskMargin;
|
|
3234
|
+
if (soldermaskMargin < 0) {
|
|
3235
|
+
const coveredPadElement = {
|
|
3236
|
+
name: "rect",
|
|
3237
|
+
type: "element",
|
|
3238
|
+
value: "",
|
|
3239
|
+
children: [],
|
|
3240
|
+
attributes: {
|
|
3241
|
+
class: "pcb-pad-covered",
|
|
3242
|
+
fill: soldermaskWithCopperUnderneathColor,
|
|
3243
|
+
x: (x - width / 2).toString(),
|
|
3244
|
+
y: (y - height / 2).toString(),
|
|
3245
|
+
width: width.toString(),
|
|
3246
|
+
height: height.toString(),
|
|
3247
|
+
rx: radius.toString(),
|
|
3248
|
+
ry: radius.toString(),
|
|
3249
|
+
"data-type": "pcb_smtpad",
|
|
3250
|
+
"data-pcb-layer": pad.layer
|
|
3251
|
+
}
|
|
3252
|
+
};
|
|
3253
|
+
const exposedOpeningElement = {
|
|
3254
|
+
name: "rect",
|
|
3255
|
+
type: "element",
|
|
3256
|
+
value: "",
|
|
3257
|
+
children: [],
|
|
3258
|
+
attributes: {
|
|
3259
|
+
class: "pcb-pad-exposed",
|
|
3260
|
+
fill: layerNameToColor(pad.layer, colorMap2),
|
|
3261
|
+
x: (x - maskWidth / 2).toString(),
|
|
3262
|
+
y: (y - maskHeight / 2).toString(),
|
|
3263
|
+
width: maskWidth.toString(),
|
|
3264
|
+
height: maskHeight.toString(),
|
|
3265
|
+
rx: maskRadius.toString(),
|
|
3266
|
+
ry: maskRadius.toString(),
|
|
3267
|
+
"data-type": "pcb_soldermask",
|
|
3268
|
+
"data-pcb-layer": pad.layer
|
|
3269
|
+
}
|
|
3270
|
+
};
|
|
3271
|
+
return [coveredPadElement, exposedOpeningElement];
|
|
3272
|
+
}
|
|
3273
|
+
if (soldermaskMargin === 0) {
|
|
3274
|
+
const coveredPadElement = {
|
|
3275
|
+
name: "rect",
|
|
3276
|
+
type: "element",
|
|
3277
|
+
value: "",
|
|
3278
|
+
children: [],
|
|
3279
|
+
attributes: {
|
|
3280
|
+
class: "pcb-pad-covered",
|
|
3281
|
+
fill: soldermaskWithCopperUnderneathColor,
|
|
3282
|
+
x: (x - width / 2).toString(),
|
|
3283
|
+
y: (y - height / 2).toString(),
|
|
3284
|
+
width: width.toString(),
|
|
3285
|
+
height: height.toString(),
|
|
3286
|
+
rx: radius.toString(),
|
|
3287
|
+
ry: radius.toString(),
|
|
3288
|
+
"data-type": "pcb_smtpad",
|
|
3289
|
+
"data-pcb-layer": pad.layer
|
|
3290
|
+
}
|
|
3291
|
+
};
|
|
3292
|
+
return [coveredPadElement];
|
|
3293
|
+
}
|
|
3294
|
+
const substrateElement = {
|
|
3295
|
+
name: "rect",
|
|
3296
|
+
type: "element",
|
|
3297
|
+
value: "",
|
|
3298
|
+
children: [],
|
|
3299
|
+
attributes: {
|
|
3300
|
+
class: "pcb-soldermask-cutout",
|
|
3301
|
+
fill: colorMap2.substrate,
|
|
3302
|
+
x: (x - maskWidth / 2).toString(),
|
|
3303
|
+
y: (y - maskHeight / 2).toString(),
|
|
3304
|
+
width: maskWidth.toString(),
|
|
3305
|
+
height: maskHeight.toString(),
|
|
3306
|
+
rx: maskRadius.toString(),
|
|
3307
|
+
ry: maskRadius.toString(),
|
|
3308
|
+
"data-type": "pcb_soldermask_opening",
|
|
3309
|
+
"data-pcb-layer": `soldermask-${pad.layer}`
|
|
3310
|
+
}
|
|
3311
|
+
};
|
|
3312
|
+
return [substrateElement, padElement];
|
|
3313
|
+
}
|
|
3314
|
+
if (pad.shape === "circle") {
|
|
3315
|
+
const radius = pad.radius * Math.abs(transform.a);
|
|
3316
|
+
const [x, y] = applyToPoint20(transform, [pad.x, pad.y]);
|
|
3317
|
+
const padElement = {
|
|
3318
|
+
name: "circle",
|
|
3319
|
+
type: "element",
|
|
3320
|
+
value: "",
|
|
3321
|
+
children: [],
|
|
3322
|
+
attributes: {
|
|
3323
|
+
class: "pcb-pad",
|
|
3324
|
+
fill: layerNameToColor(pad.layer, colorMap2),
|
|
3325
|
+
cx: x.toString(),
|
|
3326
|
+
cy: y.toString(),
|
|
3327
|
+
r: radius.toString(),
|
|
3328
|
+
"data-type": "pcb_smtpad",
|
|
3329
|
+
"data-pcb-layer": pad.layer
|
|
3330
|
+
}
|
|
3331
|
+
};
|
|
3332
|
+
if (!shouldshowSolderMask) {
|
|
3333
|
+
return [padElement];
|
|
3334
|
+
}
|
|
3335
|
+
const maskRadius = radius + soldermaskMargin;
|
|
3336
|
+
if (soldermaskMargin < 0) {
|
|
3337
|
+
const coveredPadElement = {
|
|
3338
|
+
name: "circle",
|
|
3339
|
+
type: "element",
|
|
3340
|
+
value: "",
|
|
3341
|
+
children: [],
|
|
3342
|
+
attributes: {
|
|
3343
|
+
class: "pcb-pad-covered",
|
|
3344
|
+
fill: soldermaskWithCopperUnderneathColor,
|
|
3345
|
+
cx: x.toString(),
|
|
3346
|
+
cy: y.toString(),
|
|
3347
|
+
r: radius.toString(),
|
|
3348
|
+
"data-type": "pcb_smtpad",
|
|
3349
|
+
"data-pcb-layer": pad.layer
|
|
3350
|
+
}
|
|
3351
|
+
};
|
|
3352
|
+
const exposedOpeningElement = {
|
|
3353
|
+
name: "circle",
|
|
3354
|
+
type: "element",
|
|
3355
|
+
value: "",
|
|
3356
|
+
children: [],
|
|
3357
|
+
attributes: {
|
|
3358
|
+
class: "pcb-pad-exposed",
|
|
3359
|
+
fill: layerNameToColor(pad.layer, colorMap2),
|
|
3360
|
+
cx: x.toString(),
|
|
3361
|
+
cy: y.toString(),
|
|
3362
|
+
r: maskRadius.toString(),
|
|
3363
|
+
"data-type": "pcb_soldermask",
|
|
3364
|
+
"data-pcb-layer": pad.layer
|
|
3365
|
+
}
|
|
3366
|
+
};
|
|
3367
|
+
return [coveredPadElement, exposedOpeningElement];
|
|
3368
|
+
}
|
|
3369
|
+
if (soldermaskMargin === 0) {
|
|
3370
|
+
const coveredPadElement = {
|
|
3371
|
+
name: "circle",
|
|
3372
|
+
type: "element",
|
|
3373
|
+
value: "",
|
|
3374
|
+
children: [],
|
|
3375
|
+
attributes: {
|
|
3376
|
+
class: "pcb-pad-covered",
|
|
3377
|
+
fill: soldermaskWithCopperUnderneathColor,
|
|
3378
|
+
cx: x.toString(),
|
|
3379
|
+
cy: y.toString(),
|
|
3380
|
+
r: radius.toString(),
|
|
3381
|
+
"data-type": "pcb_smtpad",
|
|
3382
|
+
"data-pcb-layer": pad.layer
|
|
3383
|
+
}
|
|
3384
|
+
};
|
|
3385
|
+
return [coveredPadElement];
|
|
3386
|
+
}
|
|
3387
|
+
const substrateElement = {
|
|
2887
3388
|
name: "circle",
|
|
2888
3389
|
type: "element",
|
|
2889
3390
|
value: "",
|
|
2890
3391
|
children: [],
|
|
2891
3392
|
attributes: {
|
|
2892
|
-
class: "pcb-
|
|
2893
|
-
fill:
|
|
3393
|
+
class: "pcb-soldermask-cutout",
|
|
3394
|
+
fill: colorMap2.substrate,
|
|
2894
3395
|
cx: x.toString(),
|
|
2895
3396
|
cy: y.toString(),
|
|
2896
|
-
r:
|
|
2897
|
-
"data-type": "
|
|
2898
|
-
"data-pcb-layer": pad.layer
|
|
2899
|
-
}
|
|
2900
|
-
};
|
|
2901
|
-
if (!shouldshowSolderMask) {
|
|
2902
|
-
return [padElement];
|
|
2903
|
-
}
|
|
2904
|
-
const maskRadius = radius + soldermaskMargin;
|
|
2905
|
-
const maskElement = {
|
|
2906
|
-
name: padElement.name,
|
|
2907
|
-
type: padElement.type,
|
|
2908
|
-
value: "",
|
|
2909
|
-
children: [],
|
|
2910
|
-
attributes: {
|
|
2911
|
-
...padElement.attributes,
|
|
2912
|
-
class: "pcb-solder-mask",
|
|
2913
|
-
fill: solderMaskColor,
|
|
2914
|
-
"data-type": "pcb_soldermask",
|
|
2915
|
-
r: maskRadius.toString()
|
|
3397
|
+
r: maskRadius.toString(),
|
|
3398
|
+
"data-type": "pcb_soldermask_opening",
|
|
3399
|
+
"data-pcb-layer": `soldermask-${pad.layer}`
|
|
2916
3400
|
}
|
|
2917
3401
|
};
|
|
2918
|
-
return [
|
|
3402
|
+
return [substrateElement, padElement];
|
|
2919
3403
|
}
|
|
2920
3404
|
if (pad.shape === "polygon") {
|
|
2921
3405
|
const points = (pad.points ?? []).map(
|
|
@@ -2954,20 +3438,65 @@ function createSvgObjectsFromSmtPad(pad, ctx) {
|
|
|
2954
3438
|
];
|
|
2955
3439
|
});
|
|
2956
3440
|
}
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
3441
|
+
if (soldermaskMargin < 0) {
|
|
3442
|
+
const coveredPadElement = {
|
|
3443
|
+
name: "polygon",
|
|
3444
|
+
type: "element",
|
|
3445
|
+
value: "",
|
|
3446
|
+
children: [],
|
|
3447
|
+
attributes: {
|
|
3448
|
+
class: "pcb-pad-covered",
|
|
3449
|
+
fill: soldermaskWithCopperUnderneathColor,
|
|
3450
|
+
points: points.map((p) => p.join(",")).join(" "),
|
|
3451
|
+
"data-type": "pcb_smtpad",
|
|
3452
|
+
"data-pcb-layer": pad.layer
|
|
3453
|
+
}
|
|
3454
|
+
};
|
|
3455
|
+
const exposedOpeningElement = {
|
|
3456
|
+
name: "polygon",
|
|
3457
|
+
type: "element",
|
|
3458
|
+
value: "",
|
|
3459
|
+
children: [],
|
|
3460
|
+
attributes: {
|
|
3461
|
+
class: "pcb-pad-exposed",
|
|
3462
|
+
fill: layerNameToColor(pad.layer, colorMap2),
|
|
3463
|
+
points: maskPoints.map((p) => p.join(",")).join(" "),
|
|
3464
|
+
"data-type": "pcb_soldermask",
|
|
3465
|
+
"data-pcb-layer": pad.layer
|
|
3466
|
+
}
|
|
3467
|
+
};
|
|
3468
|
+
return [coveredPadElement, exposedOpeningElement];
|
|
3469
|
+
}
|
|
3470
|
+
if (soldermaskMargin === 0) {
|
|
3471
|
+
const coveredPadElement = {
|
|
3472
|
+
name: "polygon",
|
|
3473
|
+
type: "element",
|
|
3474
|
+
value: "",
|
|
3475
|
+
children: [],
|
|
3476
|
+
attributes: {
|
|
3477
|
+
class: "pcb-pad-covered",
|
|
3478
|
+
fill: soldermaskWithCopperUnderneathColor,
|
|
3479
|
+
points: points.map((p) => p.join(",")).join(" "),
|
|
3480
|
+
"data-type": "pcb_smtpad",
|
|
3481
|
+
"data-pcb-layer": pad.layer
|
|
3482
|
+
}
|
|
3483
|
+
};
|
|
3484
|
+
return [coveredPadElement];
|
|
3485
|
+
}
|
|
3486
|
+
const substrateElement = {
|
|
3487
|
+
name: "polygon",
|
|
3488
|
+
type: "element",
|
|
2960
3489
|
value: "",
|
|
2961
3490
|
children: [],
|
|
2962
3491
|
attributes: {
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
"data-type": "
|
|
2967
|
-
|
|
3492
|
+
class: "pcb-soldermask-cutout",
|
|
3493
|
+
fill: colorMap2.substrate,
|
|
3494
|
+
points: maskPoints.map((p) => p.join(",")).join(" "),
|
|
3495
|
+
"data-type": "pcb_soldermask_opening",
|
|
3496
|
+
"data-pcb-layer": `soldermask-${pad.layer}`
|
|
2968
3497
|
}
|
|
2969
3498
|
};
|
|
2970
|
-
return [
|
|
3499
|
+
return [substrateElement, padElement];
|
|
2971
3500
|
}
|
|
2972
3501
|
return [];
|
|
2973
3502
|
}
|
|
@@ -2975,7 +3504,7 @@ function createSvgObjectsFromSmtPad(pad, ctx) {
|
|
|
2975
3504
|
// lib/pcb/svg-object-fns/create-svg-objects-from-pcb-board.ts
|
|
2976
3505
|
import { applyToPoint as applyToPoint21 } from "transformation-matrix";
|
|
2977
3506
|
function createSvgObjectsFromPcbBoard(pcbBoard, ctx) {
|
|
2978
|
-
const { transform, colorMap: colorMap2 } = ctx;
|
|
3507
|
+
const { transform, colorMap: colorMap2, showSolderMask } = ctx;
|
|
2979
3508
|
const { width, height, center, outline } = pcbBoard;
|
|
2980
3509
|
let path;
|
|
2981
3510
|
if (outline && Array.isArray(outline) && outline.length >= 3) {
|
|
@@ -3005,23 +3534,40 @@ function createSvgObjectsFromPcbBoard(pcbBoard, ctx) {
|
|
|
3005
3534
|
path = `M ${topLeft[0]} ${topLeft[1]} L ${topRight[0]} ${topRight[1]} L ${bottomRight[0]} ${bottomRight[1]} L ${bottomLeft[0]} ${bottomLeft[1]}`;
|
|
3006
3535
|
}
|
|
3007
3536
|
path += " Z";
|
|
3008
|
-
|
|
3009
|
-
|
|
3537
|
+
const svgObjects = [];
|
|
3538
|
+
if (showSolderMask) {
|
|
3539
|
+
svgObjects.push({
|
|
3010
3540
|
name: "path",
|
|
3011
3541
|
type: "element",
|
|
3012
3542
|
value: "",
|
|
3013
3543
|
children: [],
|
|
3014
3544
|
attributes: {
|
|
3015
|
-
class: "pcb-board",
|
|
3545
|
+
class: "pcb-board-soldermask",
|
|
3016
3546
|
d: path,
|
|
3017
|
-
fill:
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
"data-type": "
|
|
3021
|
-
"data-pcb-layer": "
|
|
3547
|
+
fill: colorMap2.soldermask.top,
|
|
3548
|
+
"fill-opacity": "0.8",
|
|
3549
|
+
stroke: "none",
|
|
3550
|
+
"data-type": "pcb_soldermask",
|
|
3551
|
+
"data-pcb-layer": "soldermask-top"
|
|
3022
3552
|
}
|
|
3553
|
+
});
|
|
3554
|
+
}
|
|
3555
|
+
svgObjects.push({
|
|
3556
|
+
name: "path",
|
|
3557
|
+
type: "element",
|
|
3558
|
+
value: "",
|
|
3559
|
+
children: [],
|
|
3560
|
+
attributes: {
|
|
3561
|
+
class: "pcb-board",
|
|
3562
|
+
d: path,
|
|
3563
|
+
fill: "none",
|
|
3564
|
+
stroke: colorMap2.boardOutline,
|
|
3565
|
+
"stroke-width": (0.1 * Math.abs(transform.a)).toString(),
|
|
3566
|
+
"data-type": "pcb_board",
|
|
3567
|
+
"data-pcb-layer": "board"
|
|
3023
3568
|
}
|
|
3024
|
-
|
|
3569
|
+
});
|
|
3570
|
+
return svgObjects;
|
|
3025
3571
|
}
|
|
3026
3572
|
|
|
3027
3573
|
// lib/pcb/svg-object-fns/create-svg-objects-from-pcb-panel.ts
|
|
@@ -3154,20 +3700,54 @@ function createSvgObjectsFromPcbHole(hole, ctx) {
|
|
|
3154
3700
|
return [holeElement2];
|
|
3155
3701
|
}
|
|
3156
3702
|
const maskRadius = radius + soldermaskMargin;
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
|
|
3703
|
+
if (soldermaskMargin < 0) {
|
|
3704
|
+
const coveredElement = {
|
|
3705
|
+
name: "circle",
|
|
3706
|
+
type: "element",
|
|
3707
|
+
value: "",
|
|
3708
|
+
children: [],
|
|
3709
|
+
attributes: {
|
|
3710
|
+
class: "pcb-hole-covered",
|
|
3711
|
+
fill: solderMaskColor,
|
|
3712
|
+
cx: x.toString(),
|
|
3713
|
+
cy: y.toString(),
|
|
3714
|
+
r: radius.toString(),
|
|
3715
|
+
"data-type": "pcb_hole",
|
|
3716
|
+
"data-pcb-layer": "drill"
|
|
3717
|
+
}
|
|
3718
|
+
};
|
|
3719
|
+
const exposedElement = {
|
|
3720
|
+
name: "circle",
|
|
3721
|
+
type: "element",
|
|
3722
|
+
value: "",
|
|
3723
|
+
children: [],
|
|
3724
|
+
attributes: {
|
|
3725
|
+
class: "pcb-hole-exposed",
|
|
3726
|
+
fill: colorMap2.drill,
|
|
3727
|
+
cx: x.toString(),
|
|
3728
|
+
cy: y.toString(),
|
|
3729
|
+
r: maskRadius.toString(),
|
|
3730
|
+
"data-type": "pcb_soldermask"
|
|
3731
|
+
}
|
|
3732
|
+
};
|
|
3733
|
+
return [coveredElement, exposedElement];
|
|
3734
|
+
}
|
|
3735
|
+
const substrateElement2 = {
|
|
3736
|
+
name: "circle",
|
|
3737
|
+
type: "element",
|
|
3160
3738
|
value: "",
|
|
3161
3739
|
children: [],
|
|
3162
3740
|
attributes: {
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
r: maskRadius.toString()
|
|
3741
|
+
class: "pcb-soldermask-cutout",
|
|
3742
|
+
fill: colorMap2.substrate,
|
|
3743
|
+
cx: x.toString(),
|
|
3744
|
+
cy: y.toString(),
|
|
3745
|
+
r: maskRadius.toString(),
|
|
3746
|
+
"data-type": "pcb_soldermask_opening",
|
|
3747
|
+
"data-pcb-layer": "soldermask-top"
|
|
3168
3748
|
}
|
|
3169
3749
|
};
|
|
3170
|
-
return [
|
|
3750
|
+
return [substrateElement2, holeElement2];
|
|
3171
3751
|
}
|
|
3172
3752
|
const holeElement = {
|
|
3173
3753
|
name: "rect",
|
|
@@ -3189,23 +3769,57 @@ function createSvgObjectsFromPcbHole(hole, ctx) {
|
|
|
3189
3769
|
return [holeElement];
|
|
3190
3770
|
}
|
|
3191
3771
|
const maskDiameter = scaledDiameter + 2 * soldermaskMargin;
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
|
|
3772
|
+
if (soldermaskMargin < 0) {
|
|
3773
|
+
const coveredElement = {
|
|
3774
|
+
name: "rect",
|
|
3775
|
+
type: "element",
|
|
3776
|
+
value: "",
|
|
3777
|
+
children: [],
|
|
3778
|
+
attributes: {
|
|
3779
|
+
class: "pcb-hole-covered",
|
|
3780
|
+
fill: solderMaskColor,
|
|
3781
|
+
x: (x - radius).toString(),
|
|
3782
|
+
y: (y - radius).toString(),
|
|
3783
|
+
width: scaledDiameter.toString(),
|
|
3784
|
+
height: scaledDiameter.toString(),
|
|
3785
|
+
"data-type": "pcb_hole",
|
|
3786
|
+
"data-pcb-layer": "drill"
|
|
3787
|
+
}
|
|
3788
|
+
};
|
|
3789
|
+
const exposedElement = {
|
|
3790
|
+
name: "rect",
|
|
3791
|
+
type: "element",
|
|
3792
|
+
value: "",
|
|
3793
|
+
children: [],
|
|
3794
|
+
attributes: {
|
|
3795
|
+
class: "pcb-hole-exposed",
|
|
3796
|
+
fill: colorMap2.drill,
|
|
3797
|
+
x: (x - maskDiameter / 2).toString(),
|
|
3798
|
+
y: (y - maskDiameter / 2).toString(),
|
|
3799
|
+
width: maskDiameter.toString(),
|
|
3800
|
+
height: maskDiameter.toString(),
|
|
3801
|
+
"data-type": "pcb_soldermask"
|
|
3802
|
+
}
|
|
3803
|
+
};
|
|
3804
|
+
return [coveredElement, exposedElement];
|
|
3805
|
+
}
|
|
3806
|
+
const substrateElement = {
|
|
3807
|
+
name: "rect",
|
|
3808
|
+
type: "element",
|
|
3195
3809
|
value: "",
|
|
3196
3810
|
children: [],
|
|
3197
3811
|
attributes: {
|
|
3198
|
-
|
|
3199
|
-
|
|
3200
|
-
fill: solderMaskColor,
|
|
3201
|
-
"data-type": "pcb_soldermask",
|
|
3812
|
+
class: "pcb-soldermask-cutout",
|
|
3813
|
+
fill: colorMap2.substrate,
|
|
3202
3814
|
x: (x - maskDiameter / 2).toString(),
|
|
3203
3815
|
y: (y - maskDiameter / 2).toString(),
|
|
3204
3816
|
width: maskDiameter.toString(),
|
|
3205
|
-
height: maskDiameter.toString()
|
|
3817
|
+
height: maskDiameter.toString(),
|
|
3818
|
+
"data-type": "pcb_soldermask_opening",
|
|
3819
|
+
"data-pcb-layer": "soldermask-top"
|
|
3206
3820
|
}
|
|
3207
3821
|
};
|
|
3208
|
-
return [
|
|
3822
|
+
return [substrateElement, holeElement];
|
|
3209
3823
|
}
|
|
3210
3824
|
if (hole.hole_shape === "oval") {
|
|
3211
3825
|
const scaledWidth = hole.hole_width * Math.abs(transform.a);
|
|
@@ -3233,21 +3847,57 @@ function createSvgObjectsFromPcbHole(hole, ctx) {
|
|
|
3233
3847
|
}
|
|
3234
3848
|
const maskRx = rx + soldermaskMargin;
|
|
3235
3849
|
const maskRy = ry + soldermaskMargin;
|
|
3236
|
-
|
|
3237
|
-
|
|
3238
|
-
|
|
3850
|
+
if (soldermaskMargin < 0) {
|
|
3851
|
+
const coveredElement = {
|
|
3852
|
+
name: "ellipse",
|
|
3853
|
+
type: "element",
|
|
3854
|
+
value: "",
|
|
3855
|
+
children: [],
|
|
3856
|
+
attributes: {
|
|
3857
|
+
class: "pcb-hole-covered",
|
|
3858
|
+
fill: solderMaskColor,
|
|
3859
|
+
cx: x.toString(),
|
|
3860
|
+
cy: y.toString(),
|
|
3861
|
+
rx: rx.toString(),
|
|
3862
|
+
ry: ry.toString(),
|
|
3863
|
+
"data-type": "pcb_hole",
|
|
3864
|
+
"data-pcb-layer": "drill"
|
|
3865
|
+
}
|
|
3866
|
+
};
|
|
3867
|
+
const exposedElement = {
|
|
3868
|
+
name: "ellipse",
|
|
3869
|
+
type: "element",
|
|
3870
|
+
value: "",
|
|
3871
|
+
children: [],
|
|
3872
|
+
attributes: {
|
|
3873
|
+
class: "pcb-hole-exposed",
|
|
3874
|
+
fill: colorMap2.drill,
|
|
3875
|
+
cx: x.toString(),
|
|
3876
|
+
cy: y.toString(),
|
|
3877
|
+
rx: maskRx.toString(),
|
|
3878
|
+
ry: maskRy.toString(),
|
|
3879
|
+
"data-type": "pcb_soldermask"
|
|
3880
|
+
}
|
|
3881
|
+
};
|
|
3882
|
+
return [coveredElement, exposedElement];
|
|
3883
|
+
}
|
|
3884
|
+
const substrateElement = {
|
|
3885
|
+
name: "ellipse",
|
|
3886
|
+
type: "element",
|
|
3239
3887
|
value: "",
|
|
3240
3888
|
children: [],
|
|
3241
3889
|
attributes: {
|
|
3242
|
-
|
|
3243
|
-
|
|
3244
|
-
|
|
3245
|
-
|
|
3890
|
+
class: "pcb-soldermask-cutout",
|
|
3891
|
+
fill: colorMap2.substrate,
|
|
3892
|
+
cx: x.toString(),
|
|
3893
|
+
cy: y.toString(),
|
|
3246
3894
|
rx: maskRx.toString(),
|
|
3247
|
-
ry: maskRy.toString()
|
|
3895
|
+
ry: maskRy.toString(),
|
|
3896
|
+
"data-type": "pcb_soldermask_opening",
|
|
3897
|
+
"data-pcb-layer": "soldermask-top"
|
|
3248
3898
|
}
|
|
3249
3899
|
};
|
|
3250
|
-
return [
|
|
3900
|
+
return [substrateElement, holeElement];
|
|
3251
3901
|
}
|
|
3252
3902
|
if (hole.hole_shape === "rect") {
|
|
3253
3903
|
const scaledWidth = hole.hole_width * Math.abs(transform.a);
|
|
@@ -3273,23 +3923,57 @@ function createSvgObjectsFromPcbHole(hole, ctx) {
|
|
|
3273
3923
|
}
|
|
3274
3924
|
const maskWidth = scaledWidth + 2 * soldermaskMargin;
|
|
3275
3925
|
const maskHeight = scaledHeight + 2 * soldermaskMargin;
|
|
3276
|
-
|
|
3277
|
-
|
|
3278
|
-
|
|
3926
|
+
if (soldermaskMargin < 0) {
|
|
3927
|
+
const coveredElement = {
|
|
3928
|
+
name: "rect",
|
|
3929
|
+
type: "element",
|
|
3930
|
+
value: "",
|
|
3931
|
+
children: [],
|
|
3932
|
+
attributes: {
|
|
3933
|
+
class: "pcb-hole-covered",
|
|
3934
|
+
fill: solderMaskColor,
|
|
3935
|
+
x: (x - scaledWidth / 2).toString(),
|
|
3936
|
+
y: (y - scaledHeight / 2).toString(),
|
|
3937
|
+
width: scaledWidth.toString(),
|
|
3938
|
+
height: scaledHeight.toString(),
|
|
3939
|
+
"data-type": "pcb_hole",
|
|
3940
|
+
"data-pcb-layer": "drill"
|
|
3941
|
+
}
|
|
3942
|
+
};
|
|
3943
|
+
const exposedElement = {
|
|
3944
|
+
name: "rect",
|
|
3945
|
+
type: "element",
|
|
3946
|
+
value: "",
|
|
3947
|
+
children: [],
|
|
3948
|
+
attributes: {
|
|
3949
|
+
class: "pcb-hole-exposed",
|
|
3950
|
+
fill: colorMap2.drill,
|
|
3951
|
+
x: (x - maskWidth / 2).toString(),
|
|
3952
|
+
y: (y - maskHeight / 2).toString(),
|
|
3953
|
+
width: maskWidth.toString(),
|
|
3954
|
+
height: maskHeight.toString(),
|
|
3955
|
+
"data-type": "pcb_soldermask"
|
|
3956
|
+
}
|
|
3957
|
+
};
|
|
3958
|
+
return [coveredElement, exposedElement];
|
|
3959
|
+
}
|
|
3960
|
+
const substrateElement = {
|
|
3961
|
+
name: "rect",
|
|
3962
|
+
type: "element",
|
|
3279
3963
|
value: "",
|
|
3280
3964
|
children: [],
|
|
3281
3965
|
attributes: {
|
|
3282
|
-
|
|
3283
|
-
|
|
3284
|
-
fill: solderMaskColor,
|
|
3285
|
-
"data-type": "pcb_soldermask",
|
|
3966
|
+
class: "pcb-soldermask-cutout",
|
|
3967
|
+
fill: colorMap2.substrate,
|
|
3286
3968
|
x: (x - maskWidth / 2).toString(),
|
|
3287
3969
|
y: (y - maskHeight / 2).toString(),
|
|
3288
3970
|
width: maskWidth.toString(),
|
|
3289
|
-
height: maskHeight.toString()
|
|
3971
|
+
height: maskHeight.toString(),
|
|
3972
|
+
"data-type": "pcb_soldermask_opening",
|
|
3973
|
+
"data-pcb-layer": "soldermask-top"
|
|
3290
3974
|
}
|
|
3291
3975
|
};
|
|
3292
|
-
return [
|
|
3976
|
+
return [substrateElement, holeElement];
|
|
3293
3977
|
}
|
|
3294
3978
|
if (hole.hole_shape === "pill") {
|
|
3295
3979
|
const scaledWidth = hole.hole_width * Math.abs(transform.a);
|
|
@@ -3336,20 +4020,48 @@ function createSvgObjectsFromPcbHole(hole, ctx) {
|
|
|
3336
4020
|
// Vertical pill (taller than wide)
|
|
3337
4021
|
`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`
|
|
3338
4022
|
);
|
|
3339
|
-
|
|
3340
|
-
|
|
3341
|
-
|
|
4023
|
+
if (soldermaskMargin < 0) {
|
|
4024
|
+
const coveredElement = {
|
|
4025
|
+
name: "path",
|
|
4026
|
+
type: "element",
|
|
4027
|
+
value: "",
|
|
4028
|
+
children: [],
|
|
4029
|
+
attributes: {
|
|
4030
|
+
class: "pcb-hole-covered",
|
|
4031
|
+
fill: solderMaskColor,
|
|
4032
|
+
d: pathD,
|
|
4033
|
+
"data-type": "pcb_hole",
|
|
4034
|
+
"data-pcb-layer": "drill"
|
|
4035
|
+
}
|
|
4036
|
+
};
|
|
4037
|
+
const exposedElement = {
|
|
4038
|
+
name: "path",
|
|
4039
|
+
type: "element",
|
|
4040
|
+
value: "",
|
|
4041
|
+
children: [],
|
|
4042
|
+
attributes: {
|
|
4043
|
+
class: "pcb-hole-exposed",
|
|
4044
|
+
fill: colorMap2.drill,
|
|
4045
|
+
d: maskPathD,
|
|
4046
|
+
"data-type": "pcb_soldermask"
|
|
4047
|
+
}
|
|
4048
|
+
};
|
|
4049
|
+
return [coveredElement, exposedElement];
|
|
4050
|
+
}
|
|
4051
|
+
const substrateElement = {
|
|
4052
|
+
name: "path",
|
|
4053
|
+
type: "element",
|
|
3342
4054
|
value: "",
|
|
3343
4055
|
children: [],
|
|
3344
4056
|
attributes: {
|
|
3345
|
-
|
|
3346
|
-
|
|
3347
|
-
|
|
3348
|
-
"data-type": "
|
|
3349
|
-
|
|
4057
|
+
class: "pcb-soldermask-cutout",
|
|
4058
|
+
fill: colorMap2.substrate,
|
|
4059
|
+
d: maskPathD,
|
|
4060
|
+
"data-type": "pcb_soldermask_opening",
|
|
4061
|
+
"data-pcb-layer": "soldermask-top"
|
|
3350
4062
|
}
|
|
3351
4063
|
};
|
|
3352
|
-
return [
|
|
4064
|
+
return [substrateElement, holeElement];
|
|
3353
4065
|
}
|
|
3354
4066
|
if (hole.hole_shape === "rotated_pill") {
|
|
3355
4067
|
const scaledWidth = hole.hole_width * Math.abs(transform.a);
|
|
@@ -3398,20 +4110,50 @@ function createSvgObjectsFromPcbHole(hole, ctx) {
|
|
|
3398
4110
|
// Vertical pill (taller than wide)
|
|
3399
4111
|
`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`
|
|
3400
4112
|
);
|
|
3401
|
-
|
|
3402
|
-
|
|
3403
|
-
|
|
4113
|
+
if (soldermaskMargin < 0) {
|
|
4114
|
+
const coveredElement = {
|
|
4115
|
+
name: "path",
|
|
4116
|
+
type: "element",
|
|
4117
|
+
value: "",
|
|
4118
|
+
children: [],
|
|
4119
|
+
attributes: {
|
|
4120
|
+
class: "pcb-hole-covered",
|
|
4121
|
+
fill: solderMaskColor,
|
|
4122
|
+
d: pathD,
|
|
4123
|
+
transform: `translate(${x} ${y}) rotate(${-rotation})`,
|
|
4124
|
+
"data-type": "pcb_hole",
|
|
4125
|
+
"data-pcb-layer": "drill"
|
|
4126
|
+
}
|
|
4127
|
+
};
|
|
4128
|
+
const exposedElement = {
|
|
4129
|
+
name: "path",
|
|
4130
|
+
type: "element",
|
|
4131
|
+
value: "",
|
|
4132
|
+
children: [],
|
|
4133
|
+
attributes: {
|
|
4134
|
+
class: "pcb-hole-exposed",
|
|
4135
|
+
fill: colorMap2.drill,
|
|
4136
|
+
d: maskPathD,
|
|
4137
|
+
transform: `translate(${x} ${y}) rotate(${-rotation})`,
|
|
4138
|
+
"data-type": "pcb_soldermask"
|
|
4139
|
+
}
|
|
4140
|
+
};
|
|
4141
|
+
return [coveredElement, exposedElement];
|
|
4142
|
+
}
|
|
4143
|
+
const substrateElement = {
|
|
4144
|
+
name: "path",
|
|
4145
|
+
type: "element",
|
|
3404
4146
|
value: "",
|
|
3405
4147
|
children: [],
|
|
3406
4148
|
attributes: {
|
|
3407
|
-
|
|
3408
|
-
|
|
3409
|
-
|
|
3410
|
-
"data-type": "
|
|
3411
|
-
|
|
4149
|
+
class: "pcb-soldermask-cutout",
|
|
4150
|
+
fill: colorMap2.substrate,
|
|
4151
|
+
d: maskPathD,
|
|
4152
|
+
"data-type": "pcb_soldermask_opening",
|
|
4153
|
+
"data-pcb-layer": "soldermask-top"
|
|
3412
4154
|
}
|
|
3413
4155
|
};
|
|
3414
|
-
return [
|
|
4156
|
+
return [substrateElement, holeElement];
|
|
3415
4157
|
}
|
|
3416
4158
|
return [];
|
|
3417
4159
|
}
|
|
@@ -4350,7 +5092,7 @@ function getSoftwareUsedString(circuitJson) {
|
|
|
4350
5092
|
var package_default = {
|
|
4351
5093
|
name: "circuit-to-svg",
|
|
4352
5094
|
type: "module",
|
|
4353
|
-
version: "0.0.
|
|
5095
|
+
version: "0.0.278",
|
|
4354
5096
|
description: "Convert Circuit JSON to SVG",
|
|
4355
5097
|
main: "dist/index.js",
|
|
4356
5098
|
files: [
|
|
@@ -4411,6 +5153,7 @@ var TYPE_PRIORITY = {
|
|
|
4411
5153
|
pcb_copper_pour: 35,
|
|
4412
5154
|
pcb_via: 36,
|
|
4413
5155
|
pcb_soldermask: 40,
|
|
5156
|
+
pcb_soldermask_opening: 41,
|
|
4414
5157
|
pcb_solder_paste: 45,
|
|
4415
5158
|
pcb_silkscreen_text: 50,
|
|
4416
5159
|
pcb_silkscreen_path: 50,
|
|
@@ -4457,6 +5200,8 @@ function getLayerPriority(layer) {
|
|
|
4457
5200
|
if (normalized === "global") return -100;
|
|
4458
5201
|
if (normalized === "bottom") return 0;
|
|
4459
5202
|
if (normalized === "board") return 2;
|
|
5203
|
+
if (normalized === "soldermask-top" || normalized === "soldermask-bottom")
|
|
5204
|
+
return 3;
|
|
4460
5205
|
if (normalized.startsWith("inner")) {
|
|
4461
5206
|
const match = normalized.match(/\d+/);
|
|
4462
5207
|
const layerIndex = match ? parseInt(match[0], 10) : 0;
|
|
@@ -4547,6 +5292,11 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
|
|
|
4547
5292
|
top: colorOverrides?.soldermask?.top ?? DEFAULT_PCB_COLOR_MAP.soldermask.top,
|
|
4548
5293
|
bottom: colorOverrides?.soldermask?.bottom ?? DEFAULT_PCB_COLOR_MAP.soldermask.bottom
|
|
4549
5294
|
},
|
|
5295
|
+
soldermaskWithCopperUnderneath: {
|
|
5296
|
+
top: colorOverrides?.soldermaskWithCopperUnderneath?.top ?? DEFAULT_PCB_COLOR_MAP.soldermaskWithCopperUnderneath.top,
|
|
5297
|
+
bottom: colorOverrides?.soldermaskWithCopperUnderneath?.bottom ?? DEFAULT_PCB_COLOR_MAP.soldermaskWithCopperUnderneath.bottom
|
|
5298
|
+
},
|
|
5299
|
+
substrate: colorOverrides?.substrate ?? DEFAULT_PCB_COLOR_MAP.substrate,
|
|
4550
5300
|
courtyard: colorOverrides?.courtyard ?? DEFAULT_PCB_COLOR_MAP.courtyard,
|
|
4551
5301
|
debugComponent: {
|
|
4552
5302
|
fill: colorOverrides?.debugComponent?.fill ?? DEFAULT_PCB_COLOR_MAP.debugComponent.fill,
|