@emasoft/svg-matrix 1.0.27 → 1.0.29
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/README.md +325 -0
- package/bin/svg-matrix.js +994 -378
- package/bin/svglinter.cjs +4172 -433
- package/bin/svgm.js +744 -184
- package/package.json +16 -4
- package/src/animation-references.js +71 -52
- package/src/arc-length.js +160 -96
- package/src/bezier-analysis.js +257 -117
- package/src/bezier-intersections.js +411 -148
- package/src/browser-verify.js +240 -100
- package/src/clip-path-resolver.js +350 -142
- package/src/convert-path-data.js +279 -134
- package/src/css-specificity.js +78 -70
- package/src/flatten-pipeline.js +751 -263
- package/src/geometry-to-path.js +511 -182
- package/src/index.js +191 -46
- package/src/inkscape-support.js +404 -0
- package/src/marker-resolver.js +278 -164
- package/src/mask-resolver.js +209 -98
- package/src/matrix.js +147 -67
- package/src/mesh-gradient.js +187 -96
- package/src/off-canvas-detection.js +201 -104
- package/src/path-analysis.js +187 -107
- package/src/path-data-plugins.js +628 -167
- package/src/path-simplification.js +0 -1
- package/src/pattern-resolver.js +125 -88
- package/src/polygon-clip.js +111 -66
- package/src/svg-boolean-ops.js +194 -118
- package/src/svg-collections.js +48 -19
- package/src/svg-flatten.js +282 -164
- package/src/svg-parser.js +427 -200
- package/src/svg-rendering-context.js +147 -104
- package/src/svg-toolbox.js +16411 -3298
- package/src/svg2-polyfills.js +114 -245
- package/src/transform-decomposition.js +46 -41
- package/src/transform-optimization.js +89 -68
- package/src/transforms2d.js +49 -16
- package/src/transforms3d.js +58 -22
- package/src/use-symbol-resolver.js +150 -110
- package/src/vector.js +67 -15
- package/src/vendor/README.md +110 -0
- package/src/vendor/inkscape-hatch-polyfill.js +401 -0
- package/src/vendor/inkscape-hatch-polyfill.min.js +8 -0
- package/src/vendor/inkscape-mesh-polyfill.js +843 -0
- package/src/vendor/inkscape-mesh-polyfill.min.js +8 -0
- package/src/verification.js +288 -124
|
@@ -31,20 +31,20 @@
|
|
|
31
31
|
* @module transform-decomposition
|
|
32
32
|
*/
|
|
33
33
|
|
|
34
|
-
import Decimal from
|
|
35
|
-
import { Matrix } from
|
|
34
|
+
import Decimal from "decimal.js";
|
|
35
|
+
import { Matrix } from "./matrix.js";
|
|
36
36
|
|
|
37
37
|
// Set high precision for all calculations
|
|
38
38
|
Decimal.set({ precision: 80 });
|
|
39
39
|
|
|
40
40
|
// Helper to convert to Decimal
|
|
41
|
-
const D = x => (x instanceof Decimal ? x : new Decimal(x));
|
|
41
|
+
const D = (x) => (x instanceof Decimal ? x : new Decimal(x));
|
|
42
42
|
|
|
43
43
|
// Near-zero threshold for comparisons
|
|
44
|
-
const EPSILON = new Decimal(
|
|
44
|
+
const EPSILON = new Decimal("1e-40");
|
|
45
45
|
|
|
46
46
|
// Verification tolerance (larger than EPSILON for practical use)
|
|
47
|
-
const VERIFICATION_TOLERANCE = new Decimal(
|
|
47
|
+
const VERIFICATION_TOLERANCE = new Decimal("1e-30");
|
|
48
48
|
|
|
49
49
|
// ============================================================================
|
|
50
50
|
// Matrix Utilities
|
|
@@ -68,7 +68,7 @@ export function translationMatrix(tx, ty) {
|
|
|
68
68
|
return Matrix.from([
|
|
69
69
|
[1, 0, D(tx)],
|
|
70
70
|
[0, 1, D(ty)],
|
|
71
|
-
[0, 0, 1]
|
|
71
|
+
[0, 0, 1],
|
|
72
72
|
]);
|
|
73
73
|
}
|
|
74
74
|
|
|
@@ -84,7 +84,7 @@ export function rotationMatrix(angle) {
|
|
|
84
84
|
return Matrix.from([
|
|
85
85
|
[cos, sin.neg(), 0],
|
|
86
86
|
[sin, cos, 0],
|
|
87
|
-
[0, 0, 1]
|
|
87
|
+
[0, 0, 1],
|
|
88
88
|
]);
|
|
89
89
|
}
|
|
90
90
|
|
|
@@ -98,7 +98,7 @@ export function scaleMatrix(sx, sy) {
|
|
|
98
98
|
return Matrix.from([
|
|
99
99
|
[D(sx), 0, 0],
|
|
100
100
|
[0, D(sy), 0],
|
|
101
|
-
[0, 0, 1]
|
|
101
|
+
[0, 0, 1],
|
|
102
102
|
]);
|
|
103
103
|
}
|
|
104
104
|
|
|
@@ -112,7 +112,7 @@ export function skewXMatrix(angle) {
|
|
|
112
112
|
return Matrix.from([
|
|
113
113
|
[1, tan, 0],
|
|
114
114
|
[0, 1, 0],
|
|
115
|
-
[0, 0, 1]
|
|
115
|
+
[0, 0, 1],
|
|
116
116
|
]);
|
|
117
117
|
}
|
|
118
118
|
|
|
@@ -126,7 +126,7 @@ export function skewYMatrix(angle) {
|
|
|
126
126
|
return Matrix.from([
|
|
127
127
|
[1, 0, 0],
|
|
128
128
|
[tan, 1, 0],
|
|
129
|
-
[0, 0, 1]
|
|
129
|
+
[0, 0, 1],
|
|
130
130
|
]);
|
|
131
131
|
}
|
|
132
132
|
|
|
@@ -141,7 +141,7 @@ export function extractLinearPart(matrix) {
|
|
|
141
141
|
a: data[0][0],
|
|
142
142
|
b: data[1][0],
|
|
143
143
|
c: data[0][1],
|
|
144
|
-
d: data[1][1]
|
|
144
|
+
d: data[1][1],
|
|
145
145
|
};
|
|
146
146
|
}
|
|
147
147
|
|
|
@@ -154,7 +154,7 @@ export function extractTranslation(matrix) {
|
|
|
154
154
|
const data = matrix.data;
|
|
155
155
|
return {
|
|
156
156
|
tx: data[0][2],
|
|
157
|
-
ty: data[1][2]
|
|
157
|
+
ty: data[1][2],
|
|
158
158
|
};
|
|
159
159
|
}
|
|
160
160
|
|
|
@@ -209,12 +209,12 @@ export function decomposeMatrix(matrix) {
|
|
|
209
209
|
skewX: D(0),
|
|
210
210
|
skewY: D(0),
|
|
211
211
|
verified: false,
|
|
212
|
-
verificationError: D(
|
|
213
|
-
singular: true
|
|
212
|
+
verificationError: D("Infinity"),
|
|
213
|
+
singular: true, // Flag to indicate singular matrix
|
|
214
214
|
};
|
|
215
215
|
}
|
|
216
216
|
|
|
217
|
-
|
|
217
|
+
const scaleY = det.div(scaleX);
|
|
218
218
|
|
|
219
219
|
// Handle reflection (negative determinant)
|
|
220
220
|
// We put the reflection in scaleX
|
|
@@ -250,9 +250,9 @@ export function decomposeMatrix(matrix) {
|
|
|
250
250
|
|
|
251
251
|
// Rotate back to get the scale+skew matrix
|
|
252
252
|
const aPrime = a.mul(cosTheta).plus(b.mul(sinTheta));
|
|
253
|
-
const
|
|
253
|
+
const _bPrime = a.neg().mul(sinTheta).plus(b.mul(cosTheta));
|
|
254
254
|
const cPrime = c.mul(cosTheta).plus(d.mul(sinTheta));
|
|
255
|
-
const
|
|
255
|
+
const _dPrime = c.neg().mul(sinTheta).plus(d.mul(cosTheta));
|
|
256
256
|
|
|
257
257
|
// Now [aPrime cPrime] should be [scaleX, scaleX*tan(skewX)]
|
|
258
258
|
// [bPrime dPrime] [0, scaleY ]
|
|
@@ -291,7 +291,7 @@ export function decomposeMatrix(matrix) {
|
|
|
291
291
|
scaleX,
|
|
292
292
|
scaleY,
|
|
293
293
|
skewX,
|
|
294
|
-
skewY: D(0)
|
|
294
|
+
skewY: D(0),
|
|
295
295
|
});
|
|
296
296
|
|
|
297
297
|
const maxError = matrixMaxDifference(matrix, recomposed);
|
|
@@ -306,7 +306,7 @@ export function decomposeMatrix(matrix) {
|
|
|
306
306
|
skewX,
|
|
307
307
|
skewY,
|
|
308
308
|
verified,
|
|
309
|
-
maxError
|
|
309
|
+
maxError,
|
|
310
310
|
};
|
|
311
311
|
}
|
|
312
312
|
|
|
@@ -352,7 +352,7 @@ export function decomposeMatrixNoSkew(matrix) {
|
|
|
352
352
|
translateY: ty,
|
|
353
353
|
rotation,
|
|
354
354
|
scaleX,
|
|
355
|
-
scaleY
|
|
355
|
+
scaleY,
|
|
356
356
|
});
|
|
357
357
|
|
|
358
358
|
const maxError = matrixMaxDifference(matrix, recomposed);
|
|
@@ -365,7 +365,7 @@ export function decomposeMatrixNoSkew(matrix) {
|
|
|
365
365
|
scaleX,
|
|
366
366
|
scaleY,
|
|
367
367
|
verified,
|
|
368
|
-
maxError
|
|
368
|
+
maxError,
|
|
369
369
|
};
|
|
370
370
|
}
|
|
371
371
|
|
|
@@ -434,7 +434,7 @@ export function composeTransform(components) {
|
|
|
434
434
|
scaleX,
|
|
435
435
|
scaleY,
|
|
436
436
|
skewX,
|
|
437
|
-
skewY = 0
|
|
437
|
+
skewY = 0,
|
|
438
438
|
} = components;
|
|
439
439
|
|
|
440
440
|
// Build matrices
|
|
@@ -521,7 +521,7 @@ export function verifyDecomposition(original, decomposition) {
|
|
|
521
521
|
const maxError = matrixMaxDifference(original, recomposed);
|
|
522
522
|
return {
|
|
523
523
|
verified: maxError.lessThan(VERIFICATION_TOLERANCE),
|
|
524
|
-
maxError
|
|
524
|
+
maxError,
|
|
525
525
|
};
|
|
526
526
|
}
|
|
527
527
|
|
|
@@ -549,7 +549,7 @@ export function matrixFromSVGValues(a, b, c, d, e, f) {
|
|
|
549
549
|
return Matrix.from([
|
|
550
550
|
[D(a), D(c), D(e)],
|
|
551
551
|
[D(b), D(d), D(f)],
|
|
552
|
-
[0, 0, 1]
|
|
552
|
+
[0, 0, 1],
|
|
553
553
|
]);
|
|
554
554
|
}
|
|
555
555
|
|
|
@@ -568,7 +568,7 @@ export function matrixToSVGValues(matrix, precision = 6) {
|
|
|
568
568
|
c: data[0][1].toFixed(precision),
|
|
569
569
|
d: data[1][1].toFixed(precision),
|
|
570
570
|
e: data[0][2].toFixed(precision),
|
|
571
|
-
f: data[1][2].toFixed(precision)
|
|
571
|
+
f: data[1][2].toFixed(precision),
|
|
572
572
|
};
|
|
573
573
|
}
|
|
574
574
|
|
|
@@ -580,13 +580,19 @@ export function matrixToSVGValues(matrix, precision = 6) {
|
|
|
580
580
|
* @returns {string} SVG transform string
|
|
581
581
|
*/
|
|
582
582
|
export function decompositionToSVGString(decomposition, precision = 6) {
|
|
583
|
-
const { translateX, translateY, rotation, scaleX, scaleY, skewX, skewY } =
|
|
583
|
+
const { translateX, translateY, rotation, scaleX, scaleY, skewX, skewY } =
|
|
584
|
+
decomposition;
|
|
584
585
|
|
|
585
586
|
const parts = [];
|
|
586
587
|
|
|
587
588
|
// Add translate if non-zero
|
|
588
|
-
if (
|
|
589
|
-
|
|
589
|
+
if (
|
|
590
|
+
!D(translateX).abs().lessThan(EPSILON) ||
|
|
591
|
+
!D(translateY).abs().lessThan(EPSILON)
|
|
592
|
+
) {
|
|
593
|
+
parts.push(
|
|
594
|
+
`translate(${D(translateX).toFixed(precision)}, ${D(translateY).toFixed(precision)})`,
|
|
595
|
+
);
|
|
590
596
|
}
|
|
591
597
|
|
|
592
598
|
// Add rotate if non-zero
|
|
@@ -616,11 +622,13 @@ export function decompositionToSVGString(decomposition, precision = 6) {
|
|
|
616
622
|
if (D(scaleX).minus(D(scaleY)).abs().lessThan(EPSILON)) {
|
|
617
623
|
parts.push(`scale(${D(scaleX).toFixed(precision)})`);
|
|
618
624
|
} else {
|
|
619
|
-
parts.push(
|
|
625
|
+
parts.push(
|
|
626
|
+
`scale(${D(scaleX).toFixed(precision)}, ${D(scaleY).toFixed(precision)})`,
|
|
627
|
+
);
|
|
620
628
|
}
|
|
621
629
|
}
|
|
622
630
|
|
|
623
|
-
return parts.length > 0 ? parts.join(
|
|
631
|
+
return parts.length > 0 ? parts.join(" ") : "";
|
|
624
632
|
}
|
|
625
633
|
|
|
626
634
|
/**
|
|
@@ -636,7 +644,7 @@ export function matrixToMinimalSVGTransform(matrix, precision = 6) {
|
|
|
636
644
|
// Check if identity
|
|
637
645
|
const identity = Matrix.identity(3);
|
|
638
646
|
if (matricesEqual(matrix, identity, EPSILON)) {
|
|
639
|
-
return { transform:
|
|
647
|
+
return { transform: "", isIdentity: true, verified: true };
|
|
640
648
|
}
|
|
641
649
|
|
|
642
650
|
// Decompose
|
|
@@ -648,7 +656,7 @@ export function matrixToMinimalSVGTransform(matrix, precision = 6) {
|
|
|
648
656
|
return {
|
|
649
657
|
transform,
|
|
650
658
|
isIdentity: false,
|
|
651
|
-
verified: decomposition.verified
|
|
659
|
+
verified: decomposition.verified,
|
|
652
660
|
};
|
|
653
661
|
}
|
|
654
662
|
|
|
@@ -675,7 +683,7 @@ export function isPureTranslation(matrix) {
|
|
|
675
683
|
return {
|
|
676
684
|
isTranslation: isIdentityLinear,
|
|
677
685
|
tx,
|
|
678
|
-
ty
|
|
686
|
+
ty,
|
|
679
687
|
};
|
|
680
688
|
}
|
|
681
689
|
|
|
@@ -700,7 +708,8 @@ export function isPureRotation(matrix) {
|
|
|
700
708
|
// Check unit columns: a² + b² = 1, c² + d² = 1
|
|
701
709
|
const col1Norm = a.mul(a).plus(b.mul(b));
|
|
702
710
|
const col2Norm = c.mul(c).plus(d.mul(d));
|
|
703
|
-
const unitNorm =
|
|
711
|
+
const unitNorm =
|
|
712
|
+
col1Norm.minus(1).abs().lessThan(EPSILON) &&
|
|
704
713
|
col2Norm.minus(1).abs().lessThan(EPSILON);
|
|
705
714
|
|
|
706
715
|
// Check determinant = 1 (no reflection)
|
|
@@ -741,7 +750,7 @@ export function isPureScale(matrix) {
|
|
|
741
750
|
isScale: true,
|
|
742
751
|
scaleX: a,
|
|
743
752
|
scaleY: d,
|
|
744
|
-
isUniform
|
|
753
|
+
isUniform,
|
|
745
754
|
};
|
|
746
755
|
}
|
|
747
756
|
|
|
@@ -760,11 +769,7 @@ export function isIdentityMatrix(matrix) {
|
|
|
760
769
|
// Exports
|
|
761
770
|
// ============================================================================
|
|
762
771
|
|
|
763
|
-
export {
|
|
764
|
-
EPSILON,
|
|
765
|
-
VERIFICATION_TOLERANCE,
|
|
766
|
-
D
|
|
767
|
-
};
|
|
772
|
+
export { EPSILON, VERIFICATION_TOLERANCE, D };
|
|
768
773
|
|
|
769
774
|
export default {
|
|
770
775
|
// Matrix utilities
|
|
@@ -806,5 +811,5 @@ export default {
|
|
|
806
811
|
|
|
807
812
|
// Constants
|
|
808
813
|
EPSILON,
|
|
809
|
-
VERIFICATION_TOLERANCE
|
|
814
|
+
VERIFICATION_TOLERANCE,
|
|
810
815
|
};
|