@emasoft/svg-matrix 1.0.28 → 1.0.30

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 (46) hide show
  1. package/README.md +325 -0
  2. package/bin/svg-matrix.js +985 -378
  3. package/bin/svglinter.cjs +4172 -433
  4. package/bin/svgm.js +723 -180
  5. package/package.json +16 -4
  6. package/src/animation-references.js +71 -52
  7. package/src/arc-length.js +160 -96
  8. package/src/bezier-analysis.js +257 -117
  9. package/src/bezier-intersections.js +411 -148
  10. package/src/browser-verify.js +240 -100
  11. package/src/clip-path-resolver.js +350 -142
  12. package/src/convert-path-data.js +279 -134
  13. package/src/css-specificity.js +78 -70
  14. package/src/flatten-pipeline.js +751 -263
  15. package/src/geometry-to-path.js +511 -182
  16. package/src/index.js +191 -46
  17. package/src/inkscape-support.js +18 -7
  18. package/src/marker-resolver.js +278 -164
  19. package/src/mask-resolver.js +209 -98
  20. package/src/matrix.js +147 -67
  21. package/src/mesh-gradient.js +187 -96
  22. package/src/off-canvas-detection.js +201 -104
  23. package/src/path-analysis.js +187 -107
  24. package/src/path-data-plugins.js +628 -167
  25. package/src/path-simplification.js +0 -1
  26. package/src/pattern-resolver.js +125 -88
  27. package/src/polygon-clip.js +111 -66
  28. package/src/svg-boolean-ops.js +194 -118
  29. package/src/svg-collections.js +22 -18
  30. package/src/svg-flatten.js +282 -164
  31. package/src/svg-parser.js +427 -200
  32. package/src/svg-rendering-context.js +147 -104
  33. package/src/svg-toolbox.js +16381 -3370
  34. package/src/svg2-polyfills.js +93 -224
  35. package/src/transform-decomposition.js +46 -41
  36. package/src/transform-optimization.js +89 -68
  37. package/src/transforms2d.js +49 -16
  38. package/src/transforms3d.js +58 -22
  39. package/src/use-symbol-resolver.js +150 -110
  40. package/src/vector.js +67 -15
  41. package/src/vendor/README.md +110 -0
  42. package/src/vendor/inkscape-hatch-polyfill.js +401 -0
  43. package/src/vendor/inkscape-hatch-polyfill.min.js +8 -0
  44. package/src/vendor/inkscape-mesh-polyfill.js +843 -0
  45. package/src/vendor/inkscape-mesh-polyfill.min.js +8 -0
  46. package/src/verification.js +288 -124
@@ -1,12 +1,27 @@
1
- import Decimal from 'decimal.js';
2
- import { Matrix } from './matrix.js';
1
+ import Decimal from "decimal.js";
2
+ import { Matrix } from "./matrix.js";
3
3
 
4
4
  /**
5
5
  * Helper to convert any numeric input to Decimal.
6
6
  * @param {number|string|Decimal} x - The value to convert
7
7
  * @returns {Decimal} The Decimal representation
8
8
  */
9
- const D = x => (x instanceof Decimal ? x : new Decimal(x));
9
+ const D = (x) => (x instanceof Decimal ? x : new Decimal(x));
10
+
11
+ /**
12
+ * Validates that a value is a valid numeric type (number, string, or Decimal).
13
+ * @param {*} value - The value to validate
14
+ * @param {string} name - The parameter name for error messages
15
+ * @throws {Error} If value is null, undefined, or not a valid numeric type
16
+ */
17
+ function validateNumeric(value, name) {
18
+ if (value === undefined || value === null) {
19
+ throw new Error(`${name} is required`);
20
+ }
21
+ if (typeof value !== 'number' && typeof value !== 'string' && !(value instanceof Decimal)) {
22
+ throw new Error(`${name} must be a number, string, or Decimal`);
23
+ }
24
+ }
10
25
 
11
26
  /**
12
27
  * 3D Affine Transforms using 4x4 homogeneous matrices.
@@ -85,11 +100,14 @@ const D = x => (x instanceof Decimal ? x : new Decimal(x));
85
100
  * // First translates by (10,0,0), then rotates around Z
86
101
  */
87
102
  export function translation(tx, ty, tz) {
103
+ validateNumeric(tx, 'tx');
104
+ validateNumeric(ty, 'ty');
105
+ validateNumeric(tz, 'tz');
88
106
  return Matrix.from([
89
107
  [new Decimal(1), new Decimal(0), new Decimal(0), D(tx)],
90
108
  [new Decimal(0), new Decimal(1), new Decimal(0), D(ty)],
91
109
  [new Decimal(0), new Decimal(0), new Decimal(1), D(tz)],
92
- [new Decimal(0), new Decimal(0), new Decimal(0), new Decimal(1)]
110
+ [new Decimal(0), new Decimal(0), new Decimal(0), new Decimal(1)],
93
111
  ]);
94
112
  }
95
113
 
@@ -131,13 +149,20 @@ export function translation(tx, ty, tz) {
131
149
  * const mirror = scale(-1, 1, 1); // Flip X axis
132
150
  */
133
151
  export function scale(sx, sy = null, sz = null) {
134
- if (sy === null) sy = sx;
135
- if (sz === null) sz = sx;
152
+ validateNumeric(sx, 'sx');
153
+ if (sy !== null) {
154
+ validateNumeric(sy, 'sy');
155
+ }
156
+ if (sz !== null) {
157
+ validateNumeric(sz, 'sz');
158
+ }
159
+ const syValue = sy === null ? sx : sy;
160
+ const szValue = sz === null ? sx : sz;
136
161
  return Matrix.from([
137
162
  [D(sx), new Decimal(0), new Decimal(0), new Decimal(0)],
138
- [new Decimal(0), D(sy), new Decimal(0), new Decimal(0)],
139
- [new Decimal(0), new Decimal(0), D(sz), new Decimal(0)],
140
- [new Decimal(0), new Decimal(0), new Decimal(0), new Decimal(1)]
163
+ [new Decimal(0), D(syValue), new Decimal(0), new Decimal(0)],
164
+ [new Decimal(0), new Decimal(0), D(szValue), new Decimal(0)],
165
+ [new Decimal(0), new Decimal(0), new Decimal(0), new Decimal(1)],
141
166
  ]);
142
167
  }
143
168
 
@@ -180,7 +205,7 @@ export function rotateX(theta) {
180
205
  [new Decimal(1), new Decimal(0), new Decimal(0), new Decimal(0)],
181
206
  [new Decimal(0), c, s.negated(), new Decimal(0)],
182
207
  [new Decimal(0), s, c, new Decimal(0)],
183
- [new Decimal(0), new Decimal(0), new Decimal(0), new Decimal(1)]
208
+ [new Decimal(0), new Decimal(0), new Decimal(0), new Decimal(1)],
184
209
  ]);
185
210
  }
186
211
 
@@ -224,7 +249,7 @@ export function rotateY(theta) {
224
249
  [c, new Decimal(0), s, new Decimal(0)],
225
250
  [new Decimal(0), new Decimal(1), new Decimal(0), new Decimal(0)],
226
251
  [s.negated(), new Decimal(0), c, new Decimal(0)],
227
- [new Decimal(0), new Decimal(0), new Decimal(0), new Decimal(1)]
252
+ [new Decimal(0), new Decimal(0), new Decimal(0), new Decimal(1)],
228
253
  ]);
229
254
  }
230
255
 
@@ -269,7 +294,7 @@ export function rotateZ(theta) {
269
294
  [c, s.negated(), new Decimal(0), new Decimal(0)],
270
295
  [s, c, new Decimal(0), new Decimal(0)],
271
296
  [new Decimal(0), new Decimal(0), new Decimal(1), new Decimal(0)],
272
- [new Decimal(0), new Decimal(0), new Decimal(0), new Decimal(1)]
297
+ [new Decimal(0), new Decimal(0), new Decimal(0), new Decimal(1)],
273
298
  ]);
274
299
  }
275
300
 
@@ -328,9 +353,13 @@ export function rotateZ(theta) {
328
353
  * // Equivalent to rotateX(Math.PI / 2)
329
354
  */
330
355
  export function rotateAroundAxis(ux, uy, uz, theta) {
356
+ validateNumeric(ux, 'ux');
357
+ validateNumeric(uy, 'uy');
358
+ validateNumeric(uz, 'uz');
359
+ validateNumeric(theta, 'theta');
331
360
  const u = [D(ux), D(uy), D(uz)];
332
- let norm = u[0].mul(u[0]).plus(u[1].mul(u[1])).plus(u[2].mul(u[2])).sqrt();
333
- if (norm.isZero()) throw new Error('Rotation axis cannot be zero vector');
361
+ const norm = u[0].mul(u[0]).plus(u[1].mul(u[1])).plus(u[2].mul(u[2])).sqrt();
362
+ if (norm.isZero()) throw new Error("Rotation axis cannot be zero vector");
334
363
  // Normalize axis
335
364
  u[0] = u[0].div(norm);
336
365
  u[1] = u[1].div(norm);
@@ -342,7 +371,9 @@ export function rotateAroundAxis(ux, uy, uz, theta) {
342
371
  const one = new Decimal(1);
343
372
 
344
373
  // Rodrigues' rotation formula components
345
- const ux2 = u[0].mul(u[0]), uy2 = u[1].mul(u[1]), uz2 = u[2].mul(u[2]);
374
+ const ux2 = u[0].mul(u[0]),
375
+ uy2 = u[1].mul(u[1]),
376
+ uz2 = u[2].mul(u[2]);
346
377
  const m00 = ux2.plus(c.mul(one.minus(ux2)));
347
378
  const m01 = u[0].mul(u[1]).mul(one.minus(c)).minus(u[2].mul(s));
348
379
  const m02 = u[0].mul(u[2]).mul(one.minus(c)).plus(u[1].mul(s));
@@ -357,7 +388,7 @@ export function rotateAroundAxis(ux, uy, uz, theta) {
357
388
  [m00, m01, m02, new Decimal(0)],
358
389
  [m10, m11, m12, new Decimal(0)],
359
390
  [m20, m21, m22, new Decimal(0)],
360
- [new Decimal(0), new Decimal(0), new Decimal(0), new Decimal(1)]
391
+ [new Decimal(0), new Decimal(0), new Decimal(0), new Decimal(1)],
361
392
  ]);
362
393
  }
363
394
 
@@ -404,7 +435,9 @@ export function rotateAroundAxis(ux, uy, uz, theta) {
404
435
  * // Complex rotation around axis (1,1,1) passing through (10,20,30)
405
436
  */
406
437
  export function rotateAroundPoint(ux, uy, uz, theta, px, py, pz) {
407
- const pxD = D(px), pyD = D(py), pzD = D(pz);
438
+ const pxD = D(px),
439
+ pyD = D(py),
440
+ pzD = D(pz);
408
441
  return translation(pxD, pyD, pzD)
409
442
  .mul(rotateAroundAxis(ux, uy, uz, theta))
410
443
  .mul(translation(pxD.negated(), pyD.negated(), pzD.negated()));
@@ -458,7 +491,10 @@ export function rotateAroundPoint(ux, uy, uz, theta, px, py, pz) {
458
491
  export function applyTransform(M, x, y, z) {
459
492
  const P = Matrix.from([[D(x)], [D(y)], [D(z)], [new Decimal(1)]]);
460
493
  const R = M.mul(P);
461
- const rx = R.data[0][0], ry = R.data[1][0], rz = R.data[2][0], rw = R.data[3][0];
494
+ const rx = R.data[0][0],
495
+ ry = R.data[1][0],
496
+ rz = R.data[2][0],
497
+ rw = R.data[3][0];
462
498
  // Perspective division (for affine transforms, rw is always 1)
463
499
  return [rx.div(rw), ry.div(rw), rz.div(rw)];
464
500
  }
@@ -499,7 +535,7 @@ export function reflectXY() {
499
535
  [new Decimal(1), new Decimal(0), new Decimal(0), new Decimal(0)],
500
536
  [new Decimal(0), new Decimal(1), new Decimal(0), new Decimal(0)],
501
537
  [new Decimal(0), new Decimal(0), new Decimal(-1), new Decimal(0)],
502
- [new Decimal(0), new Decimal(0), new Decimal(0), new Decimal(1)]
538
+ [new Decimal(0), new Decimal(0), new Decimal(0), new Decimal(1)],
503
539
  ]);
504
540
  }
505
541
 
@@ -538,7 +574,7 @@ export function reflectXZ() {
538
574
  [new Decimal(1), new Decimal(0), new Decimal(0), new Decimal(0)],
539
575
  [new Decimal(0), new Decimal(-1), new Decimal(0), new Decimal(0)],
540
576
  [new Decimal(0), new Decimal(0), new Decimal(1), new Decimal(0)],
541
- [new Decimal(0), new Decimal(0), new Decimal(0), new Decimal(1)]
577
+ [new Decimal(0), new Decimal(0), new Decimal(0), new Decimal(1)],
542
578
  ]);
543
579
  }
544
580
 
@@ -577,7 +613,7 @@ export function reflectYZ() {
577
613
  [new Decimal(-1), new Decimal(0), new Decimal(0), new Decimal(0)],
578
614
  [new Decimal(0), new Decimal(1), new Decimal(0), new Decimal(0)],
579
615
  [new Decimal(0), new Decimal(0), new Decimal(1), new Decimal(0)],
580
- [new Decimal(0), new Decimal(0), new Decimal(0), new Decimal(1)]
616
+ [new Decimal(0), new Decimal(0), new Decimal(0), new Decimal(1)],
581
617
  ]);
582
618
  }
583
619
 
@@ -627,6 +663,6 @@ export function reflectOrigin() {
627
663
  [new Decimal(-1), new Decimal(0), new Decimal(0), new Decimal(0)],
628
664
  [new Decimal(0), new Decimal(-1), new Decimal(0), new Decimal(0)],
629
665
  [new Decimal(0), new Decimal(0), new Decimal(-1), new Decimal(0)],
630
- [new Decimal(0), new Decimal(0), new Decimal(0), new Decimal(1)]
666
+ [new Decimal(0), new Decimal(0), new Decimal(0), new Decimal(1)],
631
667
  ]);
632
668
  }