lbrnts 0.0.12 → 0.0.14
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 +2 -0
- package/dist/index.js +298 -4
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -317,8 +317,10 @@ declare class ShapeText extends ShapeBase {
|
|
|
317
317
|
declare class ShapeGroup extends ShapeBase {
|
|
318
318
|
children: LightBurnBaseElement[];
|
|
319
319
|
constructor();
|
|
320
|
+
getXmlAttributes(): Record<string, string | number | boolean | undefined>;
|
|
320
321
|
static fromXmlJson(node: XmlJsonElement): ShapeGroup;
|
|
321
322
|
getChildren(): LightBurnBaseElement[];
|
|
323
|
+
toXml(indent?: number): string;
|
|
322
324
|
}
|
|
323
325
|
|
|
324
326
|
declare class ShapeBitmap extends ShapeBase {
|
package/dist/index.js
CHANGED
|
@@ -1080,11 +1080,17 @@ var ShapeGroup = class _ShapeGroup extends ShapeBase {
|
|
|
1080
1080
|
super();
|
|
1081
1081
|
this.token = "Shape.Group";
|
|
1082
1082
|
}
|
|
1083
|
+
getXmlAttributes() {
|
|
1084
|
+
return {
|
|
1085
|
+
Type: "Group",
|
|
1086
|
+
...this.getShapeXmlAttributes()
|
|
1087
|
+
};
|
|
1088
|
+
}
|
|
1083
1089
|
static fromXmlJson(node) {
|
|
1084
1090
|
const group = new _ShapeGroup();
|
|
1085
1091
|
const common = ShapeBase.readCommon(node);
|
|
1086
1092
|
Object.assign(group, common);
|
|
1087
|
-
const shapes = node.Shape;
|
|
1093
|
+
const shapes = node.Children?.Shape || node.Shape;
|
|
1088
1094
|
if (shapes) {
|
|
1089
1095
|
if (Array.isArray(shapes)) {
|
|
1090
1096
|
for (const shape of shapes) {
|
|
@@ -1104,6 +1110,32 @@ var ShapeGroup = class _ShapeGroup extends ShapeBase {
|
|
|
1104
1110
|
const baseChildren = super.getChildren();
|
|
1105
1111
|
return [...baseChildren, ...this.children];
|
|
1106
1112
|
}
|
|
1113
|
+
toXml(indent = 0) {
|
|
1114
|
+
const indentStr = " ".repeat(indent);
|
|
1115
|
+
const tag = this.getXmlTag();
|
|
1116
|
+
const attrs = this.getXmlAttributes();
|
|
1117
|
+
const attrPairs = [];
|
|
1118
|
+
for (const [key, value] of Object.entries(attrs)) {
|
|
1119
|
+
if (value !== void 0 && value !== null) {
|
|
1120
|
+
if (typeof value === "boolean") {
|
|
1121
|
+
attrPairs.push(`${key}="${value ? "True" : "False"}"`);
|
|
1122
|
+
} else {
|
|
1123
|
+
attrPairs.push(`${key}="${value}"`);
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1127
|
+
const attrStr = attrPairs.length > 0 ? " " + attrPairs.join(" ") : "";
|
|
1128
|
+
const lines = [`${indentStr}<${tag}${attrStr}>`];
|
|
1129
|
+
const xformXml = super.getChildren()[0].toXml(indent + 1);
|
|
1130
|
+
lines.push(xformXml);
|
|
1131
|
+
lines.push(`${" ".repeat(indent + 1)}<Children>`);
|
|
1132
|
+
for (const child of this.children) {
|
|
1133
|
+
lines.push(child.toXml(indent + 2));
|
|
1134
|
+
}
|
|
1135
|
+
lines.push(`${" ".repeat(indent + 1)}</Children>`);
|
|
1136
|
+
lines.push(`${indentStr}</${tag}>`);
|
|
1137
|
+
return lines.join("\n");
|
|
1138
|
+
}
|
|
1107
1139
|
};
|
|
1108
1140
|
LightBurnBaseElement.register("Shape.Group", ShapeGroup);
|
|
1109
1141
|
|
|
@@ -1345,6 +1377,9 @@ function arrayToMatrix(arr) {
|
|
|
1345
1377
|
function apply(m, p) {
|
|
1346
1378
|
return applyToPoint(m, p);
|
|
1347
1379
|
}
|
|
1380
|
+
function mul(m1, m2) {
|
|
1381
|
+
return compose(m1, m2);
|
|
1382
|
+
}
|
|
1348
1383
|
function matToSvg(m) {
|
|
1349
1384
|
return toSVG(m);
|
|
1350
1385
|
}
|
|
@@ -1678,16 +1713,275 @@ var ellipseRenderer = {
|
|
|
1678
1713
|
}
|
|
1679
1714
|
};
|
|
1680
1715
|
|
|
1716
|
+
// lib/svg-gen/path-data.ts
|
|
1717
|
+
function transformPoint(pt, matrix) {
|
|
1718
|
+
return apply(matrix, pt);
|
|
1719
|
+
}
|
|
1720
|
+
function shapePathToPathData(path) {
|
|
1721
|
+
const matrix = path.xform ? arrayToMatrix(path.xform) : identity();
|
|
1722
|
+
let d = "";
|
|
1723
|
+
for (let i = 0; i < path.prims.length; i++) {
|
|
1724
|
+
const prim = path.prims[i];
|
|
1725
|
+
const startV = path.verts[i];
|
|
1726
|
+
const endV = path.verts[(i + 1) % path.verts.length];
|
|
1727
|
+
const startPt = transformPoint({ x: startV.x, y: startV.y }, matrix);
|
|
1728
|
+
if (i === 0) {
|
|
1729
|
+
d += `M ${startPt.x} ${startPt.y}`;
|
|
1730
|
+
}
|
|
1731
|
+
if (prim.type === 0) {
|
|
1732
|
+
const endPt = transformPoint({ x: endV.x, y: endV.y }, matrix);
|
|
1733
|
+
d += ` L ${endPt.x} ${endPt.y}`;
|
|
1734
|
+
} else if (prim.type === 1) {
|
|
1735
|
+
const c0x = startV.c0x ?? startV.x;
|
|
1736
|
+
const c0y = startV.c0y ?? startV.y;
|
|
1737
|
+
const c1x = endV.c1x ?? endV.x;
|
|
1738
|
+
const c1y = endV.c1y ?? endV.y;
|
|
1739
|
+
const cp0 = transformPoint({ x: c0x, y: c0y }, matrix);
|
|
1740
|
+
const cp1 = transformPoint({ x: c1x, y: c1y }, matrix);
|
|
1741
|
+
const endPt = transformPoint({ x: endV.x, y: endV.y }, matrix);
|
|
1742
|
+
d += ` C ${cp0.x} ${cp0.y} ${cp1.x} ${cp1.y} ${endPt.x} ${endPt.y}`;
|
|
1743
|
+
}
|
|
1744
|
+
}
|
|
1745
|
+
if (d.length > 0 && path.isClosed) {
|
|
1746
|
+
d += " Z";
|
|
1747
|
+
}
|
|
1748
|
+
return d;
|
|
1749
|
+
}
|
|
1750
|
+
function rectToPathData(rect) {
|
|
1751
|
+
const matrix = rect.xform ? arrayToMatrix(rect.xform) : identity();
|
|
1752
|
+
const w = rect.w || 0;
|
|
1753
|
+
const h = rect.h || 0;
|
|
1754
|
+
const cr = rect.cr || 0;
|
|
1755
|
+
if (cr > 0) {
|
|
1756
|
+
const r = Math.min(cr, w / 2, h / 2);
|
|
1757
|
+
const p02 = transformPoint({ x: r, y: 0 }, matrix);
|
|
1758
|
+
const p12 = transformPoint({ x: w - r, y: 0 }, matrix);
|
|
1759
|
+
const p22 = transformPoint({ x: w, y: r }, matrix);
|
|
1760
|
+
const p32 = transformPoint({ x: w, y: h - r }, matrix);
|
|
1761
|
+
const p4 = transformPoint({ x: w - r, y: h }, matrix);
|
|
1762
|
+
const p5 = transformPoint({ x: r, y: h }, matrix);
|
|
1763
|
+
const p6 = transformPoint({ x: 0, y: h - r }, matrix);
|
|
1764
|
+
const p7 = transformPoint({ x: 0, y: r }, matrix);
|
|
1765
|
+
const k = 0.5522847498;
|
|
1766
|
+
const cp_tr1 = transformPoint({ x: w - r + r * k, y: 0 }, matrix);
|
|
1767
|
+
const cp_tr2 = transformPoint({ x: w, y: r - r * k }, matrix);
|
|
1768
|
+
const cp_br1 = transformPoint({ x: w, y: h - r + r * k }, matrix);
|
|
1769
|
+
const cp_br2 = transformPoint({ x: w - r + r * k, y: h }, matrix);
|
|
1770
|
+
const cp_bl1 = transformPoint({ x: r - r * k, y: h }, matrix);
|
|
1771
|
+
const cp_bl2 = transformPoint({ x: 0, y: h - r + r * k }, matrix);
|
|
1772
|
+
const cp_tl1 = transformPoint({ x: 0, y: r - r * k }, matrix);
|
|
1773
|
+
const cp_tl2 = transformPoint({ x: r - r * k, y: 0 }, matrix);
|
|
1774
|
+
return `M ${p02.x} ${p02.y} L ${p12.x} ${p12.y} C ${cp_tr1.x} ${cp_tr1.y} ${cp_tr2.x} ${cp_tr2.y} ${p22.x} ${p22.y} L ${p32.x} ${p32.y} C ${cp_br1.x} ${cp_br1.y} ${cp_br2.x} ${cp_br2.y} ${p4.x} ${p4.y} L ${p5.x} ${p5.y} C ${cp_bl1.x} ${cp_bl1.y} ${cp_bl2.x} ${cp_bl2.y} ${p6.x} ${p6.y} L ${p7.x} ${p7.y} C ${cp_tl1.x} ${cp_tl1.y} ${cp_tl2.x} ${cp_tl2.y} ${p02.x} ${p02.y} Z`;
|
|
1775
|
+
}
|
|
1776
|
+
const p0 = transformPoint({ x: 0, y: 0 }, matrix);
|
|
1777
|
+
const p1 = transformPoint({ x: w, y: 0 }, matrix);
|
|
1778
|
+
const p2 = transformPoint({ x: w, y: h }, matrix);
|
|
1779
|
+
const p3 = transformPoint({ x: 0, y: h }, matrix);
|
|
1780
|
+
return `M ${p0.x} ${p0.y} L ${p1.x} ${p1.y} L ${p2.x} ${p2.y} L ${p3.x} ${p3.y} Z`;
|
|
1781
|
+
}
|
|
1782
|
+
function ellipseToPathData(ellipse) {
|
|
1783
|
+
const matrix = ellipse.xform ? arrayToMatrix(ellipse.xform) : identity();
|
|
1784
|
+
const rx = ellipse.rx || 0;
|
|
1785
|
+
const ry = ellipse.ry || 0;
|
|
1786
|
+
const k = 0.5522847498;
|
|
1787
|
+
const p0 = transformPoint({ x: rx, y: 0 }, matrix);
|
|
1788
|
+
const p1 = transformPoint({ x: 0, y: ry }, matrix);
|
|
1789
|
+
const p2 = transformPoint({ x: -rx, y: 0 }, matrix);
|
|
1790
|
+
const p3 = transformPoint({ x: 0, y: -ry }, matrix);
|
|
1791
|
+
const cp0_1a = transformPoint({ x: rx, y: ry * k }, matrix);
|
|
1792
|
+
const cp0_1b = transformPoint({ x: rx * k, y: ry }, matrix);
|
|
1793
|
+
const cp1_2a = transformPoint({ x: -rx * k, y: ry }, matrix);
|
|
1794
|
+
const cp1_2b = transformPoint({ x: -rx, y: ry * k }, matrix);
|
|
1795
|
+
const cp2_3a = transformPoint({ x: -rx, y: -ry * k }, matrix);
|
|
1796
|
+
const cp2_3b = transformPoint({ x: -rx * k, y: -ry }, matrix);
|
|
1797
|
+
const cp3_0a = transformPoint({ x: rx * k, y: -ry }, matrix);
|
|
1798
|
+
const cp3_0b = transformPoint({ x: rx, y: -ry * k }, matrix);
|
|
1799
|
+
return `M ${p0.x} ${p0.y} C ${cp0_1a.x} ${cp0_1a.y} ${cp0_1b.x} ${cp0_1b.y} ${p1.x} ${p1.y} C ${cp1_2a.x} ${cp1_2a.y} ${cp1_2b.x} ${cp1_2b.y} ${p2.x} ${p2.y} C ${cp2_3a.x} ${cp2_3a.y} ${cp2_3b.x} ${cp2_3b.y} ${p3.x} ${p3.y} C ${cp3_0a.x} ${cp3_0a.y} ${cp3_0b.x} ${cp3_0b.y} ${p0.x} ${p0.y} Z`;
|
|
1800
|
+
}
|
|
1801
|
+
|
|
1681
1802
|
// lib/svg-gen/registry/shape-group.ts
|
|
1803
|
+
function isClosedPathShape(shape) {
|
|
1804
|
+
if (shape instanceof ShapePath) {
|
|
1805
|
+
return shape.isClosed;
|
|
1806
|
+
}
|
|
1807
|
+
if (shape instanceof ShapeRect || shape instanceof ShapeEllipse) {
|
|
1808
|
+
return true;
|
|
1809
|
+
}
|
|
1810
|
+
return false;
|
|
1811
|
+
}
|
|
1812
|
+
function getPathDataForShape(shape, groupMatrix) {
|
|
1813
|
+
if (shape instanceof ShapePath && shape.isClosed) {
|
|
1814
|
+
const originalXform = shape.xform;
|
|
1815
|
+
if (originalXform) {
|
|
1816
|
+
const shapeMatrix = arrayToMatrix(originalXform);
|
|
1817
|
+
const combinedMatrix = mul(groupMatrix, shapeMatrix);
|
|
1818
|
+
shape.xform = [
|
|
1819
|
+
combinedMatrix.a,
|
|
1820
|
+
combinedMatrix.b,
|
|
1821
|
+
combinedMatrix.c,
|
|
1822
|
+
combinedMatrix.d,
|
|
1823
|
+
combinedMatrix.e,
|
|
1824
|
+
combinedMatrix.f
|
|
1825
|
+
];
|
|
1826
|
+
const pathData2 = shapePathToPathData(shape);
|
|
1827
|
+
shape.xform = originalXform;
|
|
1828
|
+
return pathData2;
|
|
1829
|
+
}
|
|
1830
|
+
shape.xform = [
|
|
1831
|
+
groupMatrix.a,
|
|
1832
|
+
groupMatrix.b,
|
|
1833
|
+
groupMatrix.c,
|
|
1834
|
+
groupMatrix.d,
|
|
1835
|
+
groupMatrix.e,
|
|
1836
|
+
groupMatrix.f
|
|
1837
|
+
];
|
|
1838
|
+
const pathData = shapePathToPathData(shape);
|
|
1839
|
+
shape.xform = originalXform;
|
|
1840
|
+
return pathData;
|
|
1841
|
+
}
|
|
1842
|
+
if (shape instanceof ShapeRect) {
|
|
1843
|
+
const originalXform = shape.xform;
|
|
1844
|
+
if (originalXform) {
|
|
1845
|
+
const shapeMatrix = arrayToMatrix(originalXform);
|
|
1846
|
+
const combinedMatrix = mul(groupMatrix, shapeMatrix);
|
|
1847
|
+
shape.xform = [
|
|
1848
|
+
combinedMatrix.a,
|
|
1849
|
+
combinedMatrix.b,
|
|
1850
|
+
combinedMatrix.c,
|
|
1851
|
+
combinedMatrix.d,
|
|
1852
|
+
combinedMatrix.e,
|
|
1853
|
+
combinedMatrix.f
|
|
1854
|
+
];
|
|
1855
|
+
const pathData2 = rectToPathData(shape);
|
|
1856
|
+
shape.xform = originalXform;
|
|
1857
|
+
return pathData2;
|
|
1858
|
+
}
|
|
1859
|
+
shape.xform = [
|
|
1860
|
+
groupMatrix.a,
|
|
1861
|
+
groupMatrix.b,
|
|
1862
|
+
groupMatrix.c,
|
|
1863
|
+
groupMatrix.d,
|
|
1864
|
+
groupMatrix.e,
|
|
1865
|
+
groupMatrix.f
|
|
1866
|
+
];
|
|
1867
|
+
const pathData = rectToPathData(shape);
|
|
1868
|
+
shape.xform = originalXform;
|
|
1869
|
+
return pathData;
|
|
1870
|
+
}
|
|
1871
|
+
if (shape instanceof ShapeEllipse) {
|
|
1872
|
+
const originalXform = shape.xform;
|
|
1873
|
+
if (originalXform) {
|
|
1874
|
+
const shapeMatrix = arrayToMatrix(originalXform);
|
|
1875
|
+
const combinedMatrix = mul(groupMatrix, shapeMatrix);
|
|
1876
|
+
shape.xform = [
|
|
1877
|
+
combinedMatrix.a,
|
|
1878
|
+
combinedMatrix.b,
|
|
1879
|
+
combinedMatrix.c,
|
|
1880
|
+
combinedMatrix.d,
|
|
1881
|
+
combinedMatrix.e,
|
|
1882
|
+
combinedMatrix.f
|
|
1883
|
+
];
|
|
1884
|
+
const pathData2 = ellipseToPathData(shape);
|
|
1885
|
+
shape.xform = originalXform;
|
|
1886
|
+
return pathData2;
|
|
1887
|
+
}
|
|
1888
|
+
shape.xform = [
|
|
1889
|
+
groupMatrix.a,
|
|
1890
|
+
groupMatrix.b,
|
|
1891
|
+
groupMatrix.c,
|
|
1892
|
+
groupMatrix.d,
|
|
1893
|
+
groupMatrix.e,
|
|
1894
|
+
groupMatrix.f
|
|
1895
|
+
];
|
|
1896
|
+
const pathData = ellipseToPathData(shape);
|
|
1897
|
+
shape.xform = originalXform;
|
|
1898
|
+
return pathData;
|
|
1899
|
+
}
|
|
1900
|
+
return null;
|
|
1901
|
+
}
|
|
1682
1902
|
var groupRenderer = {
|
|
1683
1903
|
match: (s) => s instanceof ShapeGroup,
|
|
1684
1904
|
bbox: (grp) => {
|
|
1685
1905
|
return grp.children.filter((c) => c instanceof ShapeBase).reduce((bb, c) => boxUnion(bb, bboxOfShape(c)), emptyBox());
|
|
1686
1906
|
},
|
|
1687
1907
|
toSvg: (grp, cutSettings, options) => {
|
|
1688
|
-
const
|
|
1689
|
-
const transform = matToSvg(
|
|
1690
|
-
const
|
|
1908
|
+
const groupMatrix = grp.xform ? arrayToMatrix(grp.xform) : identity();
|
|
1909
|
+
const transform = matToSvg(groupMatrix);
|
|
1910
|
+
const shapeChildren = grp.children.filter(
|
|
1911
|
+
(c) => c instanceof ShapeBase
|
|
1912
|
+
);
|
|
1913
|
+
const allClosedPaths = shapeChildren.every((c) => isClosedPathShape(c));
|
|
1914
|
+
if (allClosedPaths && shapeChildren.length > 0) {
|
|
1915
|
+
const pathDataParts = [];
|
|
1916
|
+
for (const child of shapeChildren) {
|
|
1917
|
+
const pathData = getPathDataForShape(child, groupMatrix);
|
|
1918
|
+
if (pathData) {
|
|
1919
|
+
pathDataParts.push(pathData);
|
|
1920
|
+
}
|
|
1921
|
+
}
|
|
1922
|
+
if (pathDataParts.length > 0) {
|
|
1923
|
+
const combinedPathData = pathDataParts.join(" ");
|
|
1924
|
+
const children2 = [];
|
|
1925
|
+
const firstChild = shapeChildren[0];
|
|
1926
|
+
const cutIndex = firstChild.cutIndex;
|
|
1927
|
+
const stroke = colorForCutIndex(cutIndex);
|
|
1928
|
+
const cutSetting = cutIndex !== void 0 ? cutSettings.get(cutIndex) : void 0;
|
|
1929
|
+
const shouldShowFill = cutSetting && (cutSetting.type === "Scan" || cutSetting.type === "Scan+Cut");
|
|
1930
|
+
if (shouldShowFill && cutSetting) {
|
|
1931
|
+
const bbox = shapeChildren.reduce(
|
|
1932
|
+
(bb, c) => boxUnion(bb, bboxOfShape(c)),
|
|
1933
|
+
emptyBox()
|
|
1934
|
+
);
|
|
1935
|
+
const fillSettings = {
|
|
1936
|
+
interval: cutSetting.interval || 0.1,
|
|
1937
|
+
angle: cutSetting.angle || 0,
|
|
1938
|
+
crossHatch: cutSetting.crossHatch || false
|
|
1939
|
+
};
|
|
1940
|
+
const fillLines = generateScanLines(
|
|
1941
|
+
bbox,
|
|
1942
|
+
fillSettings,
|
|
1943
|
+
stroke,
|
|
1944
|
+
options.strokeWidth
|
|
1945
|
+
);
|
|
1946
|
+
const clipId = `clip-${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;
|
|
1947
|
+
const clipPath = {
|
|
1948
|
+
name: "clipPath",
|
|
1949
|
+
type: "element",
|
|
1950
|
+
value: "",
|
|
1951
|
+
attributes: { id: clipId },
|
|
1952
|
+
children: [
|
|
1953
|
+
leaf("path", {
|
|
1954
|
+
d: combinedPathData,
|
|
1955
|
+
"fill-rule": "nonzero",
|
|
1956
|
+
"clip-rule": "nonzero"
|
|
1957
|
+
})
|
|
1958
|
+
]
|
|
1959
|
+
};
|
|
1960
|
+
const clippedGroup = {
|
|
1961
|
+
name: "g",
|
|
1962
|
+
type: "element",
|
|
1963
|
+
value: "",
|
|
1964
|
+
attributes: { "clip-path": `url(#${clipId})` },
|
|
1965
|
+
children: fillLines
|
|
1966
|
+
};
|
|
1967
|
+
children2.push(clipPath);
|
|
1968
|
+
children2.push(clippedGroup);
|
|
1969
|
+
}
|
|
1970
|
+
children2.push(
|
|
1971
|
+
leaf("path", {
|
|
1972
|
+
d: combinedPathData,
|
|
1973
|
+
fill: "none",
|
|
1974
|
+
"fill-rule": "nonzero",
|
|
1975
|
+
stroke,
|
|
1976
|
+
"stroke-width": String(options.strokeWidth)
|
|
1977
|
+
})
|
|
1978
|
+
);
|
|
1979
|
+
return g({}, children2);
|
|
1980
|
+
}
|
|
1981
|
+
}
|
|
1982
|
+
const children = shapeChildren.map(
|
|
1983
|
+
(c) => svgForShape(c, cutSettings, options)
|
|
1984
|
+
);
|
|
1691
1985
|
return g({ transform }, children);
|
|
1692
1986
|
}
|
|
1693
1987
|
};
|