@emasoft/svg-matrix 1.1.0 → 1.2.0
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/bin/svg-matrix.js +7 -6
- package/bin/svgm.js +109 -40
- package/dist/svg-matrix.min.js +7 -7
- package/dist/svg-toolbox.min.js +148 -228
- package/dist/svgm.min.js +152 -232
- package/dist/version.json +5 -5
- package/package.json +1 -1
- package/scripts/postinstall.js +72 -41
- package/scripts/test-postinstall.js +18 -16
- package/scripts/version-sync.js +78 -60
- package/src/animation-optimization.js +190 -98
- package/src/animation-references.js +11 -3
- package/src/arc-length.js +23 -20
- package/src/bezier-analysis.js +9 -13
- package/src/bezier-intersections.js +18 -4
- package/src/browser-verify.js +35 -8
- package/src/clip-path-resolver.js +285 -114
- package/src/convert-path-data.js +20 -8
- package/src/css-specificity.js +33 -9
- package/src/douglas-peucker.js +272 -141
- package/src/geometry-to-path.js +79 -22
- package/src/gjk-collision.js +287 -126
- package/src/index.js +56 -21
- package/src/inkscape-support.js +122 -101
- package/src/logger.js +43 -27
- package/src/marker-resolver.js +201 -121
- package/src/mask-resolver.js +231 -98
- package/src/matrix.js +9 -5
- package/src/mesh-gradient.js +22 -14
- package/src/off-canvas-detection.js +53 -17
- package/src/path-optimization.js +356 -171
- package/src/path-simplification.js +671 -256
- package/src/pattern-resolver.js +1 -3
- package/src/polygon-clip.js +396 -78
- package/src/svg-boolean-ops.js +90 -23
- package/src/svg-collections.js +1546 -667
- package/src/svg-flatten.js +152 -38
- package/src/svg-matrix-lib.js +2 -2
- package/src/svg-parser.js +5 -1
- package/src/svg-rendering-context.js +3 -1
- package/src/svg-toolbox-lib.js +2 -2
- package/src/svg-toolbox.js +99 -457
- package/src/svg-validation-data.js +513 -345
- package/src/svg2-polyfills.js +156 -93
- package/src/svgm-lib.js +8 -4
- package/src/transform-optimization.js +168 -51
- package/src/transforms2d.js +73 -40
- package/src/transforms3d.js +34 -27
- package/src/use-symbol-resolver.js +175 -76
- package/src/vector.js +80 -44
- package/src/vendor/inkscape-hatch-polyfill.js +143 -108
- package/src/vendor/inkscape-hatch-polyfill.min.js +291 -1
- package/src/vendor/inkscape-mesh-polyfill.js +953 -766
- package/src/vendor/inkscape-mesh-polyfill.min.js +896 -1
- package/src/verification.js +3 -4
package/src/svg-flatten.js
CHANGED
|
@@ -70,7 +70,11 @@ Decimal.set({ precision: 80 });
|
|
|
70
70
|
*/
|
|
71
71
|
export function parseViewBox(viewBoxStr) {
|
|
72
72
|
// Validate input type and content
|
|
73
|
-
if (
|
|
73
|
+
if (
|
|
74
|
+
!viewBoxStr ||
|
|
75
|
+
typeof viewBoxStr !== "string" ||
|
|
76
|
+
viewBoxStr.trim() === ""
|
|
77
|
+
) {
|
|
74
78
|
return null;
|
|
75
79
|
}
|
|
76
80
|
|
|
@@ -93,7 +97,9 @@ export function parseViewBox(viewBoxStr) {
|
|
|
93
97
|
// Validate all parsed values are finite numbers (not NaN)
|
|
94
98
|
for (let i = 0; i < 4; i++) {
|
|
95
99
|
if (!parts[i].isFinite()) {
|
|
96
|
-
console.warn(
|
|
100
|
+
console.warn(
|
|
101
|
+
`Invalid viewBox (non-finite value at index ${i}): ${viewBoxStr}`,
|
|
102
|
+
);
|
|
97
103
|
return null;
|
|
98
104
|
}
|
|
99
105
|
}
|
|
@@ -170,11 +176,24 @@ export function parsePreserveAspectRatio(parStr) {
|
|
|
170
176
|
|
|
171
177
|
// Alignment value - validate against SVG spec
|
|
172
178
|
if (parts[idx]) {
|
|
173
|
-
const validAlignValues = [
|
|
179
|
+
const validAlignValues = [
|
|
180
|
+
"none",
|
|
181
|
+
"xMinYMin",
|
|
182
|
+
"xMinYMid",
|
|
183
|
+
"xMinYMax",
|
|
184
|
+
"xMidYMin",
|
|
185
|
+
"xMidYMid",
|
|
186
|
+
"xMidYMax",
|
|
187
|
+
"xMaxYMin",
|
|
188
|
+
"xMaxYMid",
|
|
189
|
+
"xMaxYMax",
|
|
190
|
+
];
|
|
174
191
|
if (validAlignValues.includes(parts[idx])) {
|
|
175
192
|
result.align = parts[idx];
|
|
176
193
|
} else {
|
|
177
|
-
console.warn(
|
|
194
|
+
console.warn(
|
|
195
|
+
`Invalid preserveAspectRatio align value "${parts[idx]}", using default "xMidYMid"`,
|
|
196
|
+
);
|
|
178
197
|
}
|
|
179
198
|
idx++;
|
|
180
199
|
}
|
|
@@ -185,7 +204,9 @@ export function parsePreserveAspectRatio(parStr) {
|
|
|
185
204
|
if (meetOrSlice === "meet" || meetOrSlice === "slice") {
|
|
186
205
|
result.meetOrSlice = meetOrSlice;
|
|
187
206
|
} else {
|
|
188
|
-
console.warn(
|
|
207
|
+
console.warn(
|
|
208
|
+
`Invalid preserveAspectRatio meetOrSlice value "${parts[idx]}", using default "meet"`,
|
|
209
|
+
);
|
|
189
210
|
}
|
|
190
211
|
}
|
|
191
212
|
|
|
@@ -272,7 +293,12 @@ export function computeViewBoxTransform(
|
|
|
272
293
|
console.warn("Invalid viewport dimensions (must be positive)");
|
|
273
294
|
return Matrix.identity(3);
|
|
274
295
|
}
|
|
275
|
-
if (
|
|
296
|
+
if (
|
|
297
|
+
!vbW.isFinite() ||
|
|
298
|
+
!vbH.isFinite() ||
|
|
299
|
+
!vpW.isFinite() ||
|
|
300
|
+
!vpH.isFinite()
|
|
301
|
+
) {
|
|
276
302
|
console.warn("Invalid dimensions (must be finite)");
|
|
277
303
|
return Matrix.identity(3);
|
|
278
304
|
}
|
|
@@ -602,7 +628,9 @@ export function resolveLength(value, referenceSize, dpi = 96) {
|
|
|
602
628
|
// Validate dpi parameter
|
|
603
629
|
let validDpi = dpi;
|
|
604
630
|
if (typeof validDpi !== "number" || validDpi <= 0 || !isFinite(validDpi)) {
|
|
605
|
-
console.warn(
|
|
631
|
+
console.warn(
|
|
632
|
+
"resolveLength: invalid dpi (must be positive finite number), using default 96",
|
|
633
|
+
);
|
|
606
634
|
validDpi = 96;
|
|
607
635
|
}
|
|
608
636
|
|
|
@@ -760,12 +788,16 @@ export function objectBoundingBoxTransform(
|
|
|
760
788
|
|
|
761
789
|
// Validate all parameters are finite
|
|
762
790
|
if (!xD.isFinite() || !yD.isFinite() || !wD.isFinite() || !hD.isFinite()) {
|
|
763
|
-
throw new Error(
|
|
791
|
+
throw new Error(
|
|
792
|
+
"objectBoundingBoxTransform: all parameters must be finite",
|
|
793
|
+
);
|
|
764
794
|
}
|
|
765
795
|
|
|
766
796
|
// Validate dimensions are positive (zero is technically valid for degenerate case, but warn)
|
|
767
797
|
if (wD.lte(0) || hD.lte(0)) {
|
|
768
|
-
console.warn(
|
|
798
|
+
console.warn(
|
|
799
|
+
"objectBoundingBoxTransform: zero or negative dimensions create degenerate transform",
|
|
800
|
+
);
|
|
769
801
|
// Return identity for degenerate case to avoid division by zero
|
|
770
802
|
return Matrix.identity(3);
|
|
771
803
|
}
|
|
@@ -842,7 +874,12 @@ export function ellipseToPath(cx, cy, rx, ry) {
|
|
|
842
874
|
ryD = D(ry);
|
|
843
875
|
|
|
844
876
|
// Validate parameters are finite first
|
|
845
|
-
if (
|
|
877
|
+
if (
|
|
878
|
+
!rxD.isFinite() ||
|
|
879
|
+
!ryD.isFinite() ||
|
|
880
|
+
!cxD.isFinite() ||
|
|
881
|
+
!cyD.isFinite()
|
|
882
|
+
) {
|
|
846
883
|
throw new Error("Ellipse parameters must be finite");
|
|
847
884
|
}
|
|
848
885
|
|
|
@@ -998,7 +1035,12 @@ export function lineToPath(x1, y1, x2, y2) {
|
|
|
998
1035
|
const y2D = D(y2);
|
|
999
1036
|
|
|
1000
1037
|
// Validate all parameters are finite
|
|
1001
|
-
if (
|
|
1038
|
+
if (
|
|
1039
|
+
!x1D.isFinite() ||
|
|
1040
|
+
!y1D.isFinite() ||
|
|
1041
|
+
!x2D.isFinite() ||
|
|
1042
|
+
!y2D.isFinite()
|
|
1043
|
+
) {
|
|
1002
1044
|
throw new Error("lineToPath: all parameters must be finite");
|
|
1003
1045
|
}
|
|
1004
1046
|
|
|
@@ -1117,7 +1159,9 @@ function parsePointPairs(points) {
|
|
|
1117
1159
|
|
|
1118
1160
|
// Validate even number of coordinates
|
|
1119
1161
|
if (coords.length % 2 !== 0) {
|
|
1120
|
-
console.warn(
|
|
1162
|
+
console.warn(
|
|
1163
|
+
"parsePointPairs: odd number of coordinates, ignoring last value",
|
|
1164
|
+
);
|
|
1121
1165
|
coords = coords.slice(0, -1); // Remove last element to ensure even length
|
|
1122
1166
|
}
|
|
1123
1167
|
|
|
@@ -1215,7 +1259,12 @@ export function transformArc(
|
|
|
1215
1259
|
const NEAR_ZERO = D("1e-16");
|
|
1216
1260
|
|
|
1217
1261
|
// Validate inputs
|
|
1218
|
-
if (
|
|
1262
|
+
if (
|
|
1263
|
+
!matrix ||
|
|
1264
|
+
!matrix.data ||
|
|
1265
|
+
!Array.isArray(matrix.data) ||
|
|
1266
|
+
matrix.data.length < 3
|
|
1267
|
+
) {
|
|
1219
1268
|
throw new Error("transformArc: invalid matrix");
|
|
1220
1269
|
}
|
|
1221
1270
|
|
|
@@ -1224,7 +1273,9 @@ export function transformArc(
|
|
|
1224
1273
|
|
|
1225
1274
|
// Validate radii are positive
|
|
1226
1275
|
if (rxD.lte(0) || ryD.lte(0)) {
|
|
1227
|
-
console.warn(
|
|
1276
|
+
console.warn(
|
|
1277
|
+
"transformArc: radii must be positive, returning degenerate arc",
|
|
1278
|
+
);
|
|
1228
1279
|
return {
|
|
1229
1280
|
rx: 0,
|
|
1230
1281
|
ry: 0,
|
|
@@ -1238,12 +1289,20 @@ export function transformArc(
|
|
|
1238
1289
|
|
|
1239
1290
|
// Validate and normalize flags to 0 or 1
|
|
1240
1291
|
let validLargeArcFlag = largeArcFlag;
|
|
1241
|
-
if (
|
|
1242
|
-
|
|
1292
|
+
if (
|
|
1293
|
+
typeof validLargeArcFlag !== "number" ||
|
|
1294
|
+
(validLargeArcFlag !== 0 && validLargeArcFlag !== 1)
|
|
1295
|
+
) {
|
|
1296
|
+
console.warn(
|
|
1297
|
+
`transformArc: largeArcFlag must be 0 or 1, got ${largeArcFlag}`,
|
|
1298
|
+
);
|
|
1243
1299
|
validLargeArcFlag = validLargeArcFlag ? 1 : 0;
|
|
1244
1300
|
}
|
|
1245
1301
|
let validSweepFlag = sweepFlag;
|
|
1246
|
-
if (
|
|
1302
|
+
if (
|
|
1303
|
+
typeof validSweepFlag !== "number" ||
|
|
1304
|
+
(validSweepFlag !== 0 && validSweepFlag !== 1)
|
|
1305
|
+
) {
|
|
1247
1306
|
console.warn(`transformArc: sweepFlag must be 0 or 1, got ${sweepFlag}`);
|
|
1248
1307
|
validSweepFlag = validSweepFlag ? 1 : 0;
|
|
1249
1308
|
}
|
|
@@ -1443,8 +1502,15 @@ export function parseTransformFunction(func, args) {
|
|
|
1443
1502
|
if (args.length >= 3) {
|
|
1444
1503
|
// rotate(angle, cx, cy) - rotation around point
|
|
1445
1504
|
// Validate cx and cy are valid finite numbers
|
|
1446
|
-
if (
|
|
1447
|
-
|
|
1505
|
+
if (
|
|
1506
|
+
args[1] === undefined ||
|
|
1507
|
+
args[2] === undefined ||
|
|
1508
|
+
!isFinite(args[1]) ||
|
|
1509
|
+
!isFinite(args[2])
|
|
1510
|
+
) {
|
|
1511
|
+
console.warn(
|
|
1512
|
+
"parseTransformFunction: rotate(angle, cx, cy) has invalid cx or cy, using origin rotation",
|
|
1513
|
+
);
|
|
1448
1514
|
return Transforms2D.rotate(angleRad);
|
|
1449
1515
|
}
|
|
1450
1516
|
const cx = args[1];
|
|
@@ -1473,10 +1539,14 @@ export function parseTransformFunction(func, args) {
|
|
|
1473
1539
|
// | b d f |
|
|
1474
1540
|
// | 0 0 1 |
|
|
1475
1541
|
if (args.length < 6) {
|
|
1476
|
-
console.warn(
|
|
1542
|
+
console.warn(
|
|
1543
|
+
`parseTransformFunction: matrix() requires 6 arguments, got ${args.length}`,
|
|
1544
|
+
);
|
|
1477
1545
|
return Matrix.identity(3);
|
|
1478
1546
|
}
|
|
1479
|
-
const [a, b, c, d, e, f] = args
|
|
1547
|
+
const [a, b, c, d, e, f] = args
|
|
1548
|
+
.slice(0, 6)
|
|
1549
|
+
.map((x) => D(x !== undefined ? x : 0));
|
|
1480
1550
|
return Matrix.from([
|
|
1481
1551
|
[a, c, e],
|
|
1482
1552
|
[b, d, f],
|
|
@@ -1554,7 +1624,9 @@ export function parseTransformAttribute(transformStr) {
|
|
|
1554
1624
|
.map((s) => {
|
|
1555
1625
|
const val = parseFloat(s);
|
|
1556
1626
|
if (isNaN(val)) {
|
|
1557
|
-
console.warn(
|
|
1627
|
+
console.warn(
|
|
1628
|
+
`parseTransformAttribute: invalid numeric argument "${s}" in ${func}(), using 0`,
|
|
1629
|
+
);
|
|
1558
1630
|
return 0;
|
|
1559
1631
|
}
|
|
1560
1632
|
return val;
|
|
@@ -1731,7 +1803,11 @@ export function toSVGMatrix(ctm, precision = 6) {
|
|
|
1731
1803
|
|
|
1732
1804
|
// Validate precision
|
|
1733
1805
|
let validPrecision = precision;
|
|
1734
|
-
if (
|
|
1806
|
+
if (
|
|
1807
|
+
typeof validPrecision !== "number" ||
|
|
1808
|
+
validPrecision < 0 ||
|
|
1809
|
+
validPrecision > 20
|
|
1810
|
+
) {
|
|
1735
1811
|
console.warn("toSVGMatrix: invalid precision, using default 6");
|
|
1736
1812
|
validPrecision = 6;
|
|
1737
1813
|
}
|
|
@@ -1884,7 +1960,12 @@ export function transformPathData(pathData, ctm, options = {}) {
|
|
|
1884
1960
|
|
|
1885
1961
|
// Validate precision and use default if invalid
|
|
1886
1962
|
let validPrecision = precision;
|
|
1887
|
-
if (
|
|
1963
|
+
if (
|
|
1964
|
+
typeof validPrecision !== "number" ||
|
|
1965
|
+
validPrecision < 0 ||
|
|
1966
|
+
validPrecision > 20 ||
|
|
1967
|
+
!isFinite(validPrecision)
|
|
1968
|
+
) {
|
|
1888
1969
|
console.warn("transformPathData: invalid precision, using default 6");
|
|
1889
1970
|
validPrecision = 6;
|
|
1890
1971
|
}
|
|
@@ -1914,7 +1995,9 @@ export function transformPathData(pathData, ctm, options = {}) {
|
|
|
1914
1995
|
const transformed = [];
|
|
1915
1996
|
// Validate args length is multiple of 2
|
|
1916
1997
|
if (args.length % 2 !== 0) {
|
|
1917
|
-
console.warn(
|
|
1998
|
+
console.warn(
|
|
1999
|
+
`transformPathData: M command has ${args.length} args, expected multiple of 2`,
|
|
2000
|
+
);
|
|
1918
2001
|
}
|
|
1919
2002
|
for (let i = 0; i + 1 < args.length; i += 2) {
|
|
1920
2003
|
let x = D(args[i]),
|
|
@@ -1925,7 +2008,10 @@ export function transformPathData(pathData, ctm, options = {}) {
|
|
|
1925
2008
|
}
|
|
1926
2009
|
|
|
1927
2010
|
const pt = applyToPoint(ctm, x, y);
|
|
1928
|
-
transformed.push(
|
|
2011
|
+
transformed.push(
|
|
2012
|
+
pt.x.toFixed(validPrecision),
|
|
2013
|
+
pt.y.toFixed(validPrecision),
|
|
2014
|
+
);
|
|
1929
2015
|
|
|
1930
2016
|
curX = x;
|
|
1931
2017
|
curY = y;
|
|
@@ -1942,7 +2028,9 @@ export function transformPathData(pathData, ctm, options = {}) {
|
|
|
1942
2028
|
const transformed = [];
|
|
1943
2029
|
// Validate args length is multiple of 2
|
|
1944
2030
|
if (args.length % 2 !== 0) {
|
|
1945
|
-
console.warn(
|
|
2031
|
+
console.warn(
|
|
2032
|
+
`transformPathData: L command has ${args.length} args, expected multiple of 2`,
|
|
2033
|
+
);
|
|
1946
2034
|
}
|
|
1947
2035
|
for (let i = 0; i + 1 < args.length; i += 2) {
|
|
1948
2036
|
let x = D(args[i]),
|
|
@@ -1953,7 +2041,10 @@ export function transformPathData(pathData, ctm, options = {}) {
|
|
|
1953
2041
|
}
|
|
1954
2042
|
|
|
1955
2043
|
const pt = applyToPoint(ctm, x, y);
|
|
1956
|
-
transformed.push(
|
|
2044
|
+
transformed.push(
|
|
2045
|
+
pt.x.toFixed(validPrecision),
|
|
2046
|
+
pt.y.toFixed(validPrecision),
|
|
2047
|
+
);
|
|
1957
2048
|
|
|
1958
2049
|
curX = x;
|
|
1959
2050
|
curY = y;
|
|
@@ -1966,7 +2057,9 @@ export function transformPathData(pathData, ctm, options = {}) {
|
|
|
1966
2057
|
// Horizontal line becomes L after transform (may have Y component)
|
|
1967
2058
|
// H can take multiple x values
|
|
1968
2059
|
if (args.length < 1) {
|
|
1969
|
-
console.warn(
|
|
2060
|
+
console.warn(
|
|
2061
|
+
"transformPathData: H command requires at least 1 argument",
|
|
2062
|
+
);
|
|
1970
2063
|
break;
|
|
1971
2064
|
}
|
|
1972
2065
|
|
|
@@ -1979,7 +2072,10 @@ export function transformPathData(pathData, ctm, options = {}) {
|
|
|
1979
2072
|
|
|
1980
2073
|
const pt = applyToPoint(ctm, x, y);
|
|
1981
2074
|
result.push(
|
|
1982
|
-
"L " +
|
|
2075
|
+
"L " +
|
|
2076
|
+
pt.x.toFixed(validPrecision) +
|
|
2077
|
+
" " +
|
|
2078
|
+
pt.y.toFixed(validPrecision),
|
|
1983
2079
|
);
|
|
1984
2080
|
|
|
1985
2081
|
curX = x;
|
|
@@ -1991,7 +2087,9 @@ export function transformPathData(pathData, ctm, options = {}) {
|
|
|
1991
2087
|
// Vertical line becomes L after transform (may have X component)
|
|
1992
2088
|
// V can take multiple y values
|
|
1993
2089
|
if (args.length < 1) {
|
|
1994
|
-
console.warn(
|
|
2090
|
+
console.warn(
|
|
2091
|
+
"transformPathData: V command requires at least 1 argument",
|
|
2092
|
+
);
|
|
1995
2093
|
break;
|
|
1996
2094
|
}
|
|
1997
2095
|
|
|
@@ -2004,7 +2102,10 @@ export function transformPathData(pathData, ctm, options = {}) {
|
|
|
2004
2102
|
|
|
2005
2103
|
const pt = applyToPoint(ctm, x, y);
|
|
2006
2104
|
result.push(
|
|
2007
|
-
"L " +
|
|
2105
|
+
"L " +
|
|
2106
|
+
pt.x.toFixed(validPrecision) +
|
|
2107
|
+
" " +
|
|
2108
|
+
pt.y.toFixed(validPrecision),
|
|
2008
2109
|
);
|
|
2009
2110
|
|
|
2010
2111
|
curY = y;
|
|
@@ -2016,7 +2117,9 @@ export function transformPathData(pathData, ctm, options = {}) {
|
|
|
2016
2117
|
const transformed = [];
|
|
2017
2118
|
// Validate args length is multiple of 6
|
|
2018
2119
|
if (args.length % 6 !== 0) {
|
|
2019
|
-
console.warn(
|
|
2120
|
+
console.warn(
|
|
2121
|
+
`transformPathData: C command has ${args.length} args, expected multiple of 6`,
|
|
2122
|
+
);
|
|
2020
2123
|
}
|
|
2021
2124
|
for (let i = 0; i + 5 < args.length; i += 6) {
|
|
2022
2125
|
let x1 = D(args[i]),
|
|
@@ -2059,7 +2162,9 @@ export function transformPathData(pathData, ctm, options = {}) {
|
|
|
2059
2162
|
const transformed = [];
|
|
2060
2163
|
// Validate args length is multiple of 4
|
|
2061
2164
|
if (args.length % 4 !== 0) {
|
|
2062
|
-
console.warn(
|
|
2165
|
+
console.warn(
|
|
2166
|
+
`transformPathData: S command has ${args.length} args, expected multiple of 4`,
|
|
2167
|
+
);
|
|
2063
2168
|
}
|
|
2064
2169
|
for (let i = 0; i + 3 < args.length; i += 4) {
|
|
2065
2170
|
let x2 = D(args[i]),
|
|
@@ -2095,7 +2200,9 @@ export function transformPathData(pathData, ctm, options = {}) {
|
|
|
2095
2200
|
const transformed = [];
|
|
2096
2201
|
// Validate args length is multiple of 4
|
|
2097
2202
|
if (args.length % 4 !== 0) {
|
|
2098
|
-
console.warn(
|
|
2203
|
+
console.warn(
|
|
2204
|
+
`transformPathData: Q command has ${args.length} args, expected multiple of 4`,
|
|
2205
|
+
);
|
|
2099
2206
|
}
|
|
2100
2207
|
for (let i = 0; i + 3 < args.length; i += 4) {
|
|
2101
2208
|
let x1 = D(args[i]),
|
|
@@ -2131,7 +2238,9 @@ export function transformPathData(pathData, ctm, options = {}) {
|
|
|
2131
2238
|
const transformed = [];
|
|
2132
2239
|
// Validate args length is multiple of 2
|
|
2133
2240
|
if (args.length % 2 !== 0) {
|
|
2134
|
-
console.warn(
|
|
2241
|
+
console.warn(
|
|
2242
|
+
`transformPathData: T command has ${args.length} args, expected multiple of 2`,
|
|
2243
|
+
);
|
|
2135
2244
|
}
|
|
2136
2245
|
for (let i = 0; i + 1 < args.length; i += 2) {
|
|
2137
2246
|
let x = D(args[i]),
|
|
@@ -2142,7 +2251,10 @@ export function transformPathData(pathData, ctm, options = {}) {
|
|
|
2142
2251
|
}
|
|
2143
2252
|
|
|
2144
2253
|
const pt = applyToPoint(ctm, x, y);
|
|
2145
|
-
transformed.push(
|
|
2254
|
+
transformed.push(
|
|
2255
|
+
pt.x.toFixed(validPrecision),
|
|
2256
|
+
pt.y.toFixed(validPrecision),
|
|
2257
|
+
);
|
|
2146
2258
|
|
|
2147
2259
|
curX = x;
|
|
2148
2260
|
curY = y;
|
|
@@ -2156,7 +2268,9 @@ export function transformPathData(pathData, ctm, options = {}) {
|
|
|
2156
2268
|
const transformed = [];
|
|
2157
2269
|
// Validate args length is multiple of 7
|
|
2158
2270
|
if (args.length % 7 !== 0) {
|
|
2159
|
-
console.warn(
|
|
2271
|
+
console.warn(
|
|
2272
|
+
`transformPathData: Arc command has ${args.length} args, expected multiple of 7`,
|
|
2273
|
+
);
|
|
2160
2274
|
}
|
|
2161
2275
|
for (let i = 0; i + 6 < args.length; i += 7) {
|
|
2162
2276
|
const rx = args[i];
|
package/src/svg-matrix-lib.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Works in both Node.js and browser environments.
|
|
6
6
|
*
|
|
7
7
|
* @module svg-matrix-lib
|
|
8
|
-
* @version 1.
|
|
8
|
+
* @version 1.2.0
|
|
9
9
|
* @license MIT
|
|
10
10
|
*
|
|
11
11
|
* @example Browser usage:
|
|
@@ -32,7 +32,7 @@ Decimal.set({ precision: 80 });
|
|
|
32
32
|
/**
|
|
33
33
|
* Library version
|
|
34
34
|
*/
|
|
35
|
-
export const VERSION = "1.
|
|
35
|
+
export const VERSION = "1.2.0";
|
|
36
36
|
|
|
37
37
|
// Export core classes
|
|
38
38
|
export { Decimal, Matrix, Vector };
|
package/src/svg-parser.js
CHANGED
|
@@ -104,7 +104,11 @@ class SVGDocument {
|
|
|
104
104
|
*/
|
|
105
105
|
createElementNS(namespace, tagName) {
|
|
106
106
|
// Validation: Ensure namespace is a string (though unused, for API compatibility)
|
|
107
|
-
if (
|
|
107
|
+
if (
|
|
108
|
+
namespace !== null &&
|
|
109
|
+
namespace !== undefined &&
|
|
110
|
+
typeof namespace !== "string"
|
|
111
|
+
) {
|
|
108
112
|
throw new Error("createElementNS: namespace must be a string");
|
|
109
113
|
}
|
|
110
114
|
return this.createElement(tagName);
|
|
@@ -171,7 +171,9 @@ export class SVGRenderingContext {
|
|
|
171
171
|
_extractProperties(element, inherited) {
|
|
172
172
|
// Validate inherited is an object or null - Why: prevent spreading non-objects
|
|
173
173
|
if (inherited !== null && typeof inherited !== "object") {
|
|
174
|
-
throw new Error(
|
|
174
|
+
throw new Error(
|
|
175
|
+
"_extractProperties: inherited must be an object or null",
|
|
176
|
+
);
|
|
175
177
|
}
|
|
176
178
|
|
|
177
179
|
const props = { ...SVG_DEFAULTS, ...(inherited || {}) };
|
package/src/svg-toolbox-lib.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Provides 69+ operations for cleaning, optimizing, and transforming SVG files.
|
|
6
6
|
*
|
|
7
7
|
* @module svg-toolbox-lib
|
|
8
|
-
* @version 1.
|
|
8
|
+
* @version 1.2.0
|
|
9
9
|
* @license MIT
|
|
10
10
|
*
|
|
11
11
|
* @example Browser usage:
|
|
@@ -34,7 +34,7 @@ import * as SVGToolboxModule from "./svg-toolbox.js";
|
|
|
34
34
|
/**
|
|
35
35
|
* Library version
|
|
36
36
|
*/
|
|
37
|
-
export const VERSION = "1.
|
|
37
|
+
export const VERSION = "1.2.0";
|
|
38
38
|
|
|
39
39
|
/**
|
|
40
40
|
* Default export for browser global (window.SVGToolbox)
|