@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.
Files changed (55) hide show
  1. package/bin/svg-matrix.js +7 -6
  2. package/bin/svgm.js +109 -40
  3. package/dist/svg-matrix.min.js +7 -7
  4. package/dist/svg-toolbox.min.js +148 -228
  5. package/dist/svgm.min.js +152 -232
  6. package/dist/version.json +5 -5
  7. package/package.json +1 -1
  8. package/scripts/postinstall.js +72 -41
  9. package/scripts/test-postinstall.js +18 -16
  10. package/scripts/version-sync.js +78 -60
  11. package/src/animation-optimization.js +190 -98
  12. package/src/animation-references.js +11 -3
  13. package/src/arc-length.js +23 -20
  14. package/src/bezier-analysis.js +9 -13
  15. package/src/bezier-intersections.js +18 -4
  16. package/src/browser-verify.js +35 -8
  17. package/src/clip-path-resolver.js +285 -114
  18. package/src/convert-path-data.js +20 -8
  19. package/src/css-specificity.js +33 -9
  20. package/src/douglas-peucker.js +272 -141
  21. package/src/geometry-to-path.js +79 -22
  22. package/src/gjk-collision.js +287 -126
  23. package/src/index.js +56 -21
  24. package/src/inkscape-support.js +122 -101
  25. package/src/logger.js +43 -27
  26. package/src/marker-resolver.js +201 -121
  27. package/src/mask-resolver.js +231 -98
  28. package/src/matrix.js +9 -5
  29. package/src/mesh-gradient.js +22 -14
  30. package/src/off-canvas-detection.js +53 -17
  31. package/src/path-optimization.js +356 -171
  32. package/src/path-simplification.js +671 -256
  33. package/src/pattern-resolver.js +1 -3
  34. package/src/polygon-clip.js +396 -78
  35. package/src/svg-boolean-ops.js +90 -23
  36. package/src/svg-collections.js +1546 -667
  37. package/src/svg-flatten.js +152 -38
  38. package/src/svg-matrix-lib.js +2 -2
  39. package/src/svg-parser.js +5 -1
  40. package/src/svg-rendering-context.js +3 -1
  41. package/src/svg-toolbox-lib.js +2 -2
  42. package/src/svg-toolbox.js +99 -457
  43. package/src/svg-validation-data.js +513 -345
  44. package/src/svg2-polyfills.js +156 -93
  45. package/src/svgm-lib.js +8 -4
  46. package/src/transform-optimization.js +168 -51
  47. package/src/transforms2d.js +73 -40
  48. package/src/transforms3d.js +34 -27
  49. package/src/use-symbol-resolver.js +175 -76
  50. package/src/vector.js +80 -44
  51. package/src/vendor/inkscape-hatch-polyfill.js +143 -108
  52. package/src/vendor/inkscape-hatch-polyfill.min.js +291 -1
  53. package/src/vendor/inkscape-mesh-polyfill.js +953 -766
  54. package/src/vendor/inkscape-mesh-polyfill.min.js +896 -1
  55. package/src/verification.js +3 -4
@@ -49,9 +49,7 @@ function _assertFinite(val, context) {
49
49
  // INPUT VALIDATION: Ensure val is a Decimal instance
50
50
  // WHY: Calling .isFinite() on null/undefined/non-Decimal throws errors
51
51
  if (!val || !(val instanceof Decimal)) {
52
- throw new Error(
53
- `${context}: expected Decimal instance, got ${typeof val}`,
54
- );
52
+ throw new Error(`${context}: expected Decimal instance, got ${typeof val}`);
55
53
  }
56
54
  if (!val.isFinite()) {
57
55
  throw new Error(`${context}: encountered non-finite value ${val}`);
@@ -982,9 +980,7 @@ function findRootsBySubdivision(coeffs, t0, t1, maxDepth) {
982
980
  const t0D = t0 instanceof Decimal ? t0 : D(t0);
983
981
  const t1D = t1 instanceof Decimal ? t1 : D(t1);
984
982
  if (!t0D.isFinite() || !t1D.isFinite()) {
985
- throw new Error(
986
- "findRootsBySubdivision: t0 and t1 must be finite numbers",
987
- );
983
+ throw new Error("findRootsBySubdivision: t0 and t1 must be finite numbers");
988
984
  }
989
985
  if (t1D.lte(t0D)) {
990
986
  throw new Error("findRootsBySubdivision: t1 must be greater than t0");
@@ -1189,14 +1185,10 @@ export function polynomialToBezier(xCoeffs, yCoeffs) {
1189
1185
  // WHY: Arithmetic operations fail on null/undefined values
1190
1186
  for (let i = 0; i < xCoeffs.length; i++) {
1191
1187
  if (xCoeffs[i] == null) {
1192
- throw new Error(
1193
- `polynomialToBezier: xCoeffs[${i}] is null or undefined`,
1194
- );
1188
+ throw new Error(`polynomialToBezier: xCoeffs[${i}] is null or undefined`);
1195
1189
  }
1196
1190
  if (yCoeffs[i] == null) {
1197
- throw new Error(
1198
- `polynomialToBezier: yCoeffs[${i}] is null or undefined`,
1199
- );
1191
+ throw new Error(`polynomialToBezier: yCoeffs[${i}] is null or undefined`);
1200
1192
  }
1201
1193
  }
1202
1194
 
@@ -1686,7 +1678,11 @@ export function verifyBoundingBox(points, samples = 100, tolerance = "1e-40") {
1686
1678
 
1687
1679
  // PARAMETER VALIDATION: Ensure samples is a positive integer
1688
1680
  // WHY: Non-positive or non-integer samples would cause loop errors or division by zero
1689
- if (typeof samples !== "number" || samples < 1 || !Number.isInteger(samples)) {
1681
+ if (
1682
+ typeof samples !== "number" ||
1683
+ samples < 1 ||
1684
+ !Number.isInteger(samples)
1685
+ ) {
1690
1686
  throw new Error(
1691
1687
  `verifyBoundingBox: samples must be a positive integer, got ${samples}`,
1692
1688
  );
@@ -989,7 +989,11 @@ function refineSelfIntersection(bezier, t1Init, t2Init, tol, minSep) {
989
989
  const tryT2 = Decimal.max(D(0), Decimal.min(D(1), t2.plus(dt2)));
990
990
  const [tx1, ty1] = bezierPoint(bezier, tryT1);
991
991
  const [tx2, ty2] = bezierPoint(bezier, tryT2);
992
- const tryError = tx1.minus(tx2).pow(2).plus(ty1.minus(ty2).pow(2)).sqrt();
992
+ const tryError = tx1
993
+ .minus(tx2)
994
+ .pow(2)
995
+ .plus(ty1.minus(ty2).pow(2))
996
+ .sqrt();
993
997
 
994
998
  if (tryError.lt(bestError)) {
995
999
  bestError = tryError;
@@ -1256,7 +1260,11 @@ export function verifyLineLineIntersection(
1256
1260
  if (intersection.t2 === undefined || intersection.t2 === null) {
1257
1261
  return { valid: false, reason: "intersection.t2 is missing" };
1258
1262
  }
1259
- if (!intersection.point || !Array.isArray(intersection.point) || intersection.point.length < 2) {
1263
+ if (
1264
+ !intersection.point ||
1265
+ !Array.isArray(intersection.point) ||
1266
+ intersection.point.length < 2
1267
+ ) {
1260
1268
  return { valid: false, reason: "intersection.point is missing or invalid" };
1261
1269
  }
1262
1270
 
@@ -1386,7 +1394,11 @@ export function verifyBezierLineIntersection(
1386
1394
  if (intersection.t2 === undefined || intersection.t2 === null) {
1387
1395
  return { valid: false, reason: "intersection.t2 is missing" };
1388
1396
  }
1389
- if (!intersection.point || !Array.isArray(intersection.point) || intersection.point.length < 2) {
1397
+ if (
1398
+ !intersection.point ||
1399
+ !Array.isArray(intersection.point) ||
1400
+ intersection.point.length < 2
1401
+ ) {
1390
1402
  return { valid: false, reason: "intersection.point is missing or invalid" };
1391
1403
  }
1392
1404
 
@@ -1754,7 +1766,9 @@ export function verifyPathPathIntersection(
1754
1766
  export function verifyAllIntersectionFunctions(tolerance = "1e-30") {
1755
1767
  // WHY: Validate tolerance parameter to prevent invalid configuration
1756
1768
  if (tolerance === undefined || tolerance === null) {
1757
- throw new Error("verifyAllIntersectionFunctions: tolerance cannot be undefined or null");
1769
+ throw new Error(
1770
+ "verifyAllIntersectionFunctions: tolerance cannot be undefined or null",
1771
+ );
1758
1772
  }
1759
1773
 
1760
1774
  const results = {};
@@ -160,7 +160,9 @@ export class BrowserVerifier {
160
160
  }
161
161
  const ctm = rect.getCTM();
162
162
  if (!ctm) {
163
- throw new Error("getCTM() returned null - element may not be rendered");
163
+ throw new Error(
164
+ "getCTM() returned null - element may not be rendered",
165
+ );
164
166
  }
165
167
  return { a: ctm.a, b: ctm.b, c: ctm.c, d: ctm.d, e: ctm.e, f: ctm.f };
166
168
  } finally {
@@ -309,7 +311,9 @@ export class BrowserVerifier {
309
311
  }
310
312
  const ctm = rect.getCTM();
311
313
  if (!ctm) {
312
- throw new Error("getCTM() returned null - element may not be rendered");
314
+ throw new Error(
315
+ "getCTM() returned null - element may not be rendered",
316
+ );
313
317
  }
314
318
  if (!svg.createSVGPoint || typeof svg.createSVGPoint !== "function") {
315
319
  throw new Error("Browser does not support createSVGPoint API");
@@ -317,7 +321,10 @@ export class BrowserVerifier {
317
321
  const point = svg.createSVGPoint();
318
322
  point.x = px;
319
323
  point.y = py;
320
- if (!point.matrixTransform || typeof point.matrixTransform !== "function") {
324
+ if (
325
+ !point.matrixTransform ||
326
+ typeof point.matrixTransform !== "function"
327
+ ) {
321
328
  throw new Error("Browser does not support matrixTransform API");
322
329
  }
323
330
  const transformed = point.matrixTransform(ctm);
@@ -356,7 +363,11 @@ export class BrowserVerifier {
356
363
  "matrix.data must have at least 2 rows with at least 3 columns each",
357
364
  );
358
365
  }
359
- if (typeof tolerance !== "number" || !isFinite(tolerance) || tolerance < 0) {
366
+ if (
367
+ typeof tolerance !== "number" ||
368
+ !isFinite(tolerance) ||
369
+ tolerance < 0
370
+ ) {
360
371
  throw new Error("tolerance must be a non-negative finite number");
361
372
  }
362
373
  // Validate that matrix.data contains Decimal objects with toNumber() method
@@ -432,7 +443,11 @@ export class BrowserVerifier {
432
443
  ) {
433
444
  throw new Error("preserveAspectRatio must be a non-empty string");
434
445
  }
435
- if (typeof tolerance !== "number" || !isFinite(tolerance) || tolerance < 0) {
446
+ if (
447
+ typeof tolerance !== "number" ||
448
+ !isFinite(tolerance) ||
449
+ tolerance < 0
450
+ ) {
436
451
  throw new Error("tolerance must be a non-negative finite number");
437
452
  }
438
453
 
@@ -476,7 +491,11 @@ export class BrowserVerifier {
476
491
  if (typeof transform !== "string" || transform.trim().length === 0) {
477
492
  throw new Error("transform must be a non-empty string");
478
493
  }
479
- if (typeof tolerance !== "number" || !isFinite(tolerance) || tolerance < 0) {
494
+ if (
495
+ typeof tolerance !== "number" ||
496
+ !isFinite(tolerance) ||
497
+ tolerance < 0
498
+ ) {
480
499
  throw new Error("tolerance must be a non-negative finite number");
481
500
  }
482
501
 
@@ -522,7 +541,11 @@ export class BrowserVerifier {
522
541
  if (!config || typeof config !== "object") {
523
542
  throw new Error("config must be a valid object");
524
543
  }
525
- if (typeof tolerance !== "number" || !isFinite(tolerance) || tolerance < 0) {
544
+ if (
545
+ typeof tolerance !== "number" ||
546
+ !isFinite(tolerance) ||
547
+ tolerance < 0
548
+ ) {
526
549
  throw new Error("tolerance must be a non-negative finite number");
527
550
  }
528
551
 
@@ -568,7 +591,11 @@ export class BrowserVerifier {
568
591
  if (!Array.isArray(testCases)) {
569
592
  throw new Error("testCases must be an array");
570
593
  }
571
- if (typeof tolerance !== "number" || !isFinite(tolerance) || tolerance < 0) {
594
+ if (
595
+ typeof tolerance !== "number" ||
596
+ !isFinite(tolerance) ||
597
+ tolerance < 0
598
+ ) {
572
599
  throw new Error("tolerance must be a non-negative finite number");
573
600
  }
574
601