@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/geometry-to-path.js
CHANGED
|
@@ -81,11 +81,15 @@ export function getKappaForArc(thetaRadians) {
|
|
|
81
81
|
*/
|
|
82
82
|
export function circleToPathDataHP(cx, cy, r, arcs = 8, precision = 6) {
|
|
83
83
|
if (cx == null || cy == null || r == null) {
|
|
84
|
-
throw new Error(
|
|
84
|
+
throw new Error(
|
|
85
|
+
"circleToPathDataHP: cx, cy, and r parameters are required",
|
|
86
|
+
);
|
|
85
87
|
}
|
|
86
88
|
const rD = D(r);
|
|
87
89
|
if (!rD.isFinite() || rD.isNegative()) {
|
|
88
|
-
throw new Error(
|
|
90
|
+
throw new Error(
|
|
91
|
+
"circleToPathDataHP: radius must be finite and non-negative",
|
|
92
|
+
);
|
|
89
93
|
}
|
|
90
94
|
if (rD.isZero()) {
|
|
91
95
|
return ""; // Zero-radius circle produces no visible path
|
|
@@ -116,7 +120,9 @@ export function circleToPathDataHP(cx, cy, r, arcs = 8, precision = 6) {
|
|
|
116
120
|
*/
|
|
117
121
|
export function ellipseToPathDataHP(cx, cy, rx, ry, arcs = 8, precision = 6) {
|
|
118
122
|
if (cx == null || cy == null || rx == null || ry == null) {
|
|
119
|
-
throw new Error(
|
|
123
|
+
throw new Error(
|
|
124
|
+
"ellipseToPathDataHP: cx, cy, rx, and ry parameters are required",
|
|
125
|
+
);
|
|
120
126
|
}
|
|
121
127
|
if (!Number.isFinite(arcs) || arcs <= 0) {
|
|
122
128
|
throw new Error("ellipseToPathDataHP: arcs must be a positive number");
|
|
@@ -284,7 +290,9 @@ export function circleToPathData(cx, cy, r, precision = 6) {
|
|
|
284
290
|
*/
|
|
285
291
|
export function ellipseToPathData(cx, cy, rx, ry, precision = 6) {
|
|
286
292
|
if (cx == null || cy == null || rx == null || ry == null) {
|
|
287
|
-
throw new Error(
|
|
293
|
+
throw new Error(
|
|
294
|
+
"ellipseToPathData: cx, cy, rx, and ry parameters are required",
|
|
295
|
+
);
|
|
288
296
|
}
|
|
289
297
|
if (!Number.isFinite(precision) || precision < 0) {
|
|
290
298
|
throw new Error("ellipseToPathData: precision must be non-negative");
|
|
@@ -356,7 +364,9 @@ export function rectToPathData(
|
|
|
356
364
|
precision = 6,
|
|
357
365
|
) {
|
|
358
366
|
if (x == null || y == null || width == null || height == null) {
|
|
359
|
-
throw new Error(
|
|
367
|
+
throw new Error(
|
|
368
|
+
"rectToPathData: x, y, width, and height parameters are required",
|
|
369
|
+
);
|
|
360
370
|
}
|
|
361
371
|
if (!Number.isFinite(precision) || precision < 0) {
|
|
362
372
|
throw new Error("rectToPathData: precision must be non-negative");
|
|
@@ -430,13 +440,23 @@ export function rectToPathData(
|
|
|
430
440
|
*/
|
|
431
441
|
export function lineToPathData(x1, y1, x2, y2, precision = 6) {
|
|
432
442
|
if (x1 == null || y1 == null || x2 == null || y2 == null) {
|
|
433
|
-
throw new Error(
|
|
443
|
+
throw new Error(
|
|
444
|
+
"lineToPathData: x1, y1, x2, and y2 parameters are required",
|
|
445
|
+
);
|
|
434
446
|
}
|
|
435
447
|
if (!Number.isFinite(precision) || precision < 0) {
|
|
436
448
|
throw new Error("lineToPathData: precision must be non-negative");
|
|
437
449
|
}
|
|
438
|
-
const x1D = D(x1),
|
|
439
|
-
|
|
450
|
+
const x1D = D(x1),
|
|
451
|
+
y1D = D(y1),
|
|
452
|
+
x2D = D(x2),
|
|
453
|
+
y2D = D(y2);
|
|
454
|
+
if (
|
|
455
|
+
!x1D.isFinite() ||
|
|
456
|
+
!y1D.isFinite() ||
|
|
457
|
+
!x2D.isFinite() ||
|
|
458
|
+
!y2D.isFinite()
|
|
459
|
+
) {
|
|
440
460
|
throw new Error("lineToPathData: all coordinates must be finite");
|
|
441
461
|
}
|
|
442
462
|
const f = (v) => formatNumber(v, precision);
|
|
@@ -627,7 +647,9 @@ export function pathArrayToString(commands, precision = 6) {
|
|
|
627
647
|
return commands
|
|
628
648
|
.map((cmd) => {
|
|
629
649
|
if (!cmd || typeof cmd.command !== "string" || !Array.isArray(cmd.args)) {
|
|
630
|
-
throw new Error(
|
|
650
|
+
throw new Error(
|
|
651
|
+
"pathArrayToString: each command must have 'command' (string) and 'args' (array) properties",
|
|
652
|
+
);
|
|
631
653
|
}
|
|
632
654
|
const { command, args } = cmd;
|
|
633
655
|
const argsStr = args.map((a) => formatNumber(a, precision)).join(" ");
|
|
@@ -803,8 +825,18 @@ export function transformArcParams(
|
|
|
803
825
|
endY,
|
|
804
826
|
matrix,
|
|
805
827
|
) {
|
|
806
|
-
if (
|
|
807
|
-
|
|
828
|
+
if (
|
|
829
|
+
rx == null ||
|
|
830
|
+
ry == null ||
|
|
831
|
+
xAxisRotation == null ||
|
|
832
|
+
largeArc == null ||
|
|
833
|
+
sweep == null ||
|
|
834
|
+
endX == null ||
|
|
835
|
+
endY == null
|
|
836
|
+
) {
|
|
837
|
+
throw new Error(
|
|
838
|
+
"transformArcParams: all parameters (rx, ry, xAxisRotation, largeArc, sweep, endX, endY) are required",
|
|
839
|
+
);
|
|
808
840
|
}
|
|
809
841
|
if (matrix == null) {
|
|
810
842
|
throw new Error("transformArcParams: matrix parameter is required");
|
|
@@ -812,9 +844,14 @@ export function transformArcParams(
|
|
|
812
844
|
if (!matrix.data || !Array.isArray(matrix.data) || matrix.data.length !== 3) {
|
|
813
845
|
throw new Error("transformArcParams: matrix must be 3x3");
|
|
814
846
|
}
|
|
815
|
-
if (
|
|
816
|
-
|
|
817
|
-
|
|
847
|
+
if (
|
|
848
|
+
!Array.isArray(matrix.data[0]) ||
|
|
849
|
+
matrix.data[0].length < 2 ||
|
|
850
|
+
!Array.isArray(matrix.data[1]) ||
|
|
851
|
+
matrix.data[1].length < 2 ||
|
|
852
|
+
!Array.isArray(matrix.data[2]) ||
|
|
853
|
+
matrix.data[2].length < 1
|
|
854
|
+
) {
|
|
818
855
|
throw new Error("transformArcParams: matrix must have valid 3x3 structure");
|
|
819
856
|
}
|
|
820
857
|
const rxD = D(rx),
|
|
@@ -828,7 +865,9 @@ export function transformArcParams(
|
|
|
828
865
|
const transformedEnd = matrix.mul(endPoint);
|
|
829
866
|
const w = transformedEnd.data[2][0];
|
|
830
867
|
if (w.isZero()) {
|
|
831
|
-
throw new Error(
|
|
868
|
+
throw new Error(
|
|
869
|
+
"transformArcParams: division by zero in homogeneous coordinate transformation",
|
|
870
|
+
);
|
|
832
871
|
}
|
|
833
872
|
const newEndX = transformedEnd.data[0][0].div(w);
|
|
834
873
|
const newEndY = transformedEnd.data[1][0].div(w);
|
|
@@ -897,9 +936,14 @@ export function transformPathData(pathData, matrix, precision = 6) {
|
|
|
897
936
|
if (!matrix.data || !Array.isArray(matrix.data) || matrix.data.length !== 3) {
|
|
898
937
|
throw new Error("transformPathData: matrix must be 3x3");
|
|
899
938
|
}
|
|
900
|
-
if (
|
|
901
|
-
|
|
902
|
-
|
|
939
|
+
if (
|
|
940
|
+
!Array.isArray(matrix.data[0]) ||
|
|
941
|
+
matrix.data[0].length < 2 ||
|
|
942
|
+
!Array.isArray(matrix.data[1]) ||
|
|
943
|
+
matrix.data[1].length < 2 ||
|
|
944
|
+
!Array.isArray(matrix.data[2]) ||
|
|
945
|
+
matrix.data[2].length < 1
|
|
946
|
+
) {
|
|
903
947
|
throw new Error("transformPathData: matrix must have valid 3x3 structure");
|
|
904
948
|
}
|
|
905
949
|
if (!Number.isFinite(precision) || precision < 0) {
|
|
@@ -915,7 +959,9 @@ export function transformPathData(pathData, matrix, precision = 6) {
|
|
|
915
959
|
const transformed = matrix.mul(pt);
|
|
916
960
|
const w = transformed.data[2][0];
|
|
917
961
|
if (w.isZero()) {
|
|
918
|
-
throw new Error(
|
|
962
|
+
throw new Error(
|
|
963
|
+
"transformPathData: division by zero in homogeneous coordinate transformation",
|
|
964
|
+
);
|
|
919
965
|
}
|
|
920
966
|
const x = transformed.data[0][0].div(w);
|
|
921
967
|
const y = transformed.data[1][0].div(w);
|
|
@@ -928,7 +974,9 @@ export function transformPathData(pathData, matrix, precision = 6) {
|
|
|
928
974
|
const transformed = matrix.mul(pt);
|
|
929
975
|
const w = transformed.data[2][0];
|
|
930
976
|
if (w.isZero()) {
|
|
931
|
-
throw new Error(
|
|
977
|
+
throw new Error(
|
|
978
|
+
"transformPathData: division by zero in homogeneous coordinate transformation",
|
|
979
|
+
);
|
|
932
980
|
}
|
|
933
981
|
transformedArgs.push(transformed.data[0][0].div(w));
|
|
934
982
|
transformedArgs.push(transformed.data[1][0].div(w));
|
|
@@ -969,8 +1017,17 @@ export function transformPathData(pathData, matrix, precision = 6) {
|
|
|
969
1017
|
* @returns {Array<Decimal>} Cubic Bezier control points [cp1x, cp1y, cp2x, cp2y, x2, y2]
|
|
970
1018
|
*/
|
|
971
1019
|
function quadraticToCubic(x0, y0, x1, y1, x2, y2) {
|
|
972
|
-
if (
|
|
973
|
-
|
|
1020
|
+
if (
|
|
1021
|
+
x0 == null ||
|
|
1022
|
+
y0 == null ||
|
|
1023
|
+
x1 == null ||
|
|
1024
|
+
y1 == null ||
|
|
1025
|
+
x2 == null ||
|
|
1026
|
+
y2 == null
|
|
1027
|
+
) {
|
|
1028
|
+
throw new Error(
|
|
1029
|
+
"quadraticToCubic: all parameters (x0, y0, x1, y1, x2, y2) are required",
|
|
1030
|
+
);
|
|
974
1031
|
}
|
|
975
1032
|
const twoThirds = new Decimal(2).div(3);
|
|
976
1033
|
const cp1x = x0.plus(twoThirds.mul(x1.minus(x0)));
|