@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.
- package/README.md +325 -0
- package/bin/svg-matrix.js +985 -378
- package/bin/svglinter.cjs +4172 -433
- package/bin/svgm.js +723 -180
- 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 +18 -7
- 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 +22 -18
- 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 +16381 -3370
- package/src/svg2-polyfills.js +93 -224
- 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
|
@@ -52,7 +52,6 @@ const DEFAULT_TOLERANCE = new Decimal('1e-10');
|
|
|
52
52
|
/**
|
|
53
53
|
* Implementation of atan2 using Decimal.js (which doesn't provide it natively).
|
|
54
54
|
* Returns the angle in radians between the positive x-axis and the ray from (0,0) to (x,y).
|
|
55
|
-
*
|
|
56
55
|
* @param {Decimal} y - Y coordinate
|
|
57
56
|
* @param {Decimal} x - X coordinate
|
|
58
57
|
* @returns {Decimal} Angle in radians (-π to π)
|
package/src/pattern-resolver.js
CHANGED
|
@@ -14,15 +14,15 @@
|
|
|
14
14
|
* @module pattern-resolver
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import Decimal from
|
|
18
|
-
import { Matrix } from
|
|
19
|
-
import * as Transforms2D from
|
|
20
|
-
import * as PolygonClip from
|
|
21
|
-
import * as ClipPathResolver from
|
|
17
|
+
import Decimal from "decimal.js";
|
|
18
|
+
import { Matrix } from "./matrix.js";
|
|
19
|
+
import * as Transforms2D from "./transforms2d.js";
|
|
20
|
+
import * as PolygonClip from "./polygon-clip.js";
|
|
21
|
+
import * as ClipPathResolver from "./clip-path-resolver.js";
|
|
22
22
|
|
|
23
23
|
Decimal.set({ precision: 80 });
|
|
24
24
|
|
|
25
|
-
const D = x => (x instanceof Decimal ? x : new Decimal(x));
|
|
25
|
+
const D = (x) => (x instanceof Decimal ? x : new Decimal(x));
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
28
|
* Parse pattern element to structured data
|
|
@@ -72,19 +72,24 @@ const D = x => (x instanceof Decimal ? x : new Decimal(x));
|
|
|
72
72
|
*/
|
|
73
73
|
export function parsePatternElement(patternElement) {
|
|
74
74
|
const data = {
|
|
75
|
-
id: patternElement.getAttribute(
|
|
76
|
-
patternUnits:
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
75
|
+
id: patternElement.getAttribute("id") || "",
|
|
76
|
+
patternUnits:
|
|
77
|
+
patternElement.getAttribute("patternUnits") || "objectBoundingBox",
|
|
78
|
+
patternContentUnits:
|
|
79
|
+
patternElement.getAttribute("patternContentUnits") || "userSpaceOnUse",
|
|
80
|
+
patternTransform: patternElement.getAttribute("patternTransform") || null,
|
|
81
|
+
x: patternElement.getAttribute("x"),
|
|
82
|
+
y: patternElement.getAttribute("y"),
|
|
83
|
+
width: patternElement.getAttribute("width"),
|
|
84
|
+
height: patternElement.getAttribute("height"),
|
|
85
|
+
viewBox: patternElement.getAttribute("viewBox") || null,
|
|
86
|
+
preserveAspectRatio:
|
|
87
|
+
patternElement.getAttribute("preserveAspectRatio") || "xMidYMid meet",
|
|
88
|
+
href:
|
|
89
|
+
patternElement.getAttribute("href") ||
|
|
90
|
+
patternElement.getAttribute("xlink:href") ||
|
|
91
|
+
null,
|
|
92
|
+
children: [],
|
|
88
93
|
};
|
|
89
94
|
|
|
90
95
|
// Parse numeric values
|
|
@@ -95,13 +100,16 @@ export function parsePatternElement(patternElement) {
|
|
|
95
100
|
|
|
96
101
|
// Parse viewBox if present
|
|
97
102
|
if (data.viewBox) {
|
|
98
|
-
const parts = data.viewBox
|
|
103
|
+
const parts = data.viewBox
|
|
104
|
+
.trim()
|
|
105
|
+
.split(/[\s,]+/)
|
|
106
|
+
.map(Number);
|
|
99
107
|
if (parts.length === 4) {
|
|
100
108
|
data.viewBoxParsed = {
|
|
101
109
|
x: parts[0],
|
|
102
110
|
y: parts[1],
|
|
103
111
|
width: parts[2],
|
|
104
|
-
height: parts[3]
|
|
112
|
+
height: parts[3],
|
|
105
113
|
};
|
|
106
114
|
}
|
|
107
115
|
}
|
|
@@ -111,62 +119,62 @@ export function parsePatternElement(patternElement) {
|
|
|
111
119
|
const tagName = child.tagName.toLowerCase();
|
|
112
120
|
const childData = {
|
|
113
121
|
type: tagName,
|
|
114
|
-
fill: child.getAttribute(
|
|
115
|
-
stroke: child.getAttribute(
|
|
116
|
-
strokeWidth: parseFloat(child.getAttribute(
|
|
117
|
-
opacity: parseFloat(child.getAttribute(
|
|
118
|
-
transform: child.getAttribute(
|
|
122
|
+
fill: child.getAttribute("fill") || "black",
|
|
123
|
+
stroke: child.getAttribute("stroke") || "none",
|
|
124
|
+
strokeWidth: parseFloat(child.getAttribute("stroke-width") || "1"),
|
|
125
|
+
opacity: parseFloat(child.getAttribute("opacity") || "1"),
|
|
126
|
+
transform: child.getAttribute("transform") || null,
|
|
119
127
|
};
|
|
120
128
|
|
|
121
129
|
// Parse shape-specific attributes
|
|
122
130
|
switch (tagName) {
|
|
123
|
-
case
|
|
124
|
-
childData.x = parseFloat(child.getAttribute(
|
|
125
|
-
childData.y = parseFloat(child.getAttribute(
|
|
126
|
-
childData.width = parseFloat(child.getAttribute(
|
|
127
|
-
childData.height = parseFloat(child.getAttribute(
|
|
128
|
-
childData.rx = parseFloat(child.getAttribute(
|
|
129
|
-
childData.ry = parseFloat(child.getAttribute(
|
|
131
|
+
case "rect":
|
|
132
|
+
childData.x = parseFloat(child.getAttribute("x") || "0");
|
|
133
|
+
childData.y = parseFloat(child.getAttribute("y") || "0");
|
|
134
|
+
childData.width = parseFloat(child.getAttribute("width") || "0");
|
|
135
|
+
childData.height = parseFloat(child.getAttribute("height") || "0");
|
|
136
|
+
childData.rx = parseFloat(child.getAttribute("rx") || "0");
|
|
137
|
+
childData.ry = parseFloat(child.getAttribute("ry") || "0");
|
|
130
138
|
break;
|
|
131
|
-
case
|
|
132
|
-
childData.cx = parseFloat(child.getAttribute(
|
|
133
|
-
childData.cy = parseFloat(child.getAttribute(
|
|
134
|
-
childData.r = parseFloat(child.getAttribute(
|
|
139
|
+
case "circle":
|
|
140
|
+
childData.cx = parseFloat(child.getAttribute("cx") || "0");
|
|
141
|
+
childData.cy = parseFloat(child.getAttribute("cy") || "0");
|
|
142
|
+
childData.r = parseFloat(child.getAttribute("r") || "0");
|
|
135
143
|
break;
|
|
136
|
-
case
|
|
137
|
-
childData.cx = parseFloat(child.getAttribute(
|
|
138
|
-
childData.cy = parseFloat(child.getAttribute(
|
|
139
|
-
childData.rx = parseFloat(child.getAttribute(
|
|
140
|
-
childData.ry = parseFloat(child.getAttribute(
|
|
144
|
+
case "ellipse":
|
|
145
|
+
childData.cx = parseFloat(child.getAttribute("cx") || "0");
|
|
146
|
+
childData.cy = parseFloat(child.getAttribute("cy") || "0");
|
|
147
|
+
childData.rx = parseFloat(child.getAttribute("rx") || "0");
|
|
148
|
+
childData.ry = parseFloat(child.getAttribute("ry") || "0");
|
|
141
149
|
break;
|
|
142
|
-
case
|
|
143
|
-
childData.d = child.getAttribute(
|
|
150
|
+
case "path":
|
|
151
|
+
childData.d = child.getAttribute("d") || "";
|
|
144
152
|
break;
|
|
145
|
-
case
|
|
146
|
-
childData.points = child.getAttribute(
|
|
153
|
+
case "polygon":
|
|
154
|
+
childData.points = child.getAttribute("points") || "";
|
|
147
155
|
break;
|
|
148
|
-
case
|
|
149
|
-
childData.points = child.getAttribute(
|
|
156
|
+
case "polyline":
|
|
157
|
+
childData.points = child.getAttribute("points") || "";
|
|
150
158
|
break;
|
|
151
|
-
case
|
|
152
|
-
childData.x1 = parseFloat(child.getAttribute(
|
|
153
|
-
childData.y1 = parseFloat(child.getAttribute(
|
|
154
|
-
childData.x2 = parseFloat(child.getAttribute(
|
|
155
|
-
childData.y2 = parseFloat(child.getAttribute(
|
|
159
|
+
case "line":
|
|
160
|
+
childData.x1 = parseFloat(child.getAttribute("x1") || "0");
|
|
161
|
+
childData.y1 = parseFloat(child.getAttribute("y1") || "0");
|
|
162
|
+
childData.x2 = parseFloat(child.getAttribute("x2") || "0");
|
|
163
|
+
childData.y2 = parseFloat(child.getAttribute("y2") || "0");
|
|
156
164
|
break;
|
|
157
|
-
case
|
|
158
|
-
childData.href =
|
|
159
|
-
|
|
160
|
-
childData.x = parseFloat(child.getAttribute(
|
|
161
|
-
childData.y = parseFloat(child.getAttribute(
|
|
165
|
+
case "use":
|
|
166
|
+
childData.href =
|
|
167
|
+
child.getAttribute("href") || child.getAttribute("xlink:href") || "";
|
|
168
|
+
childData.x = parseFloat(child.getAttribute("x") || "0");
|
|
169
|
+
childData.y = parseFloat(child.getAttribute("y") || "0");
|
|
162
170
|
break;
|
|
163
|
-
case
|
|
171
|
+
case "g":
|
|
164
172
|
// Groups can contain nested shapes
|
|
165
173
|
childData.children = [];
|
|
166
174
|
for (const gc of child.children) {
|
|
167
175
|
childData.children.push({
|
|
168
176
|
type: gc.tagName.toLowerCase(),
|
|
169
|
-
fill: gc.getAttribute(
|
|
177
|
+
fill: gc.getAttribute("fill") || "inherit",
|
|
170
178
|
});
|
|
171
179
|
}
|
|
172
180
|
break;
|
|
@@ -225,13 +233,13 @@ export function parsePatternElement(patternElement) {
|
|
|
225
233
|
* // Tile uses absolute coordinates, bbox is ignored
|
|
226
234
|
*/
|
|
227
235
|
export function getPatternTile(patternData, targetBBox) {
|
|
228
|
-
if (patternData.patternUnits ===
|
|
236
|
+
if (patternData.patternUnits === "objectBoundingBox") {
|
|
229
237
|
// Dimensions are fractions of target bbox
|
|
230
238
|
return {
|
|
231
239
|
x: D(targetBBox.x).plus(D(patternData.x).mul(targetBBox.width)),
|
|
232
240
|
y: D(targetBBox.y).plus(D(patternData.y).mul(targetBBox.height)),
|
|
233
241
|
width: D(patternData.width).mul(targetBBox.width),
|
|
234
|
-
height: D(patternData.height).mul(targetBBox.height)
|
|
242
|
+
height: D(patternData.height).mul(targetBBox.height),
|
|
235
243
|
};
|
|
236
244
|
}
|
|
237
245
|
|
|
@@ -240,7 +248,7 @@ export function getPatternTile(patternData, targetBBox) {
|
|
|
240
248
|
x: D(patternData.x),
|
|
241
249
|
y: D(patternData.y),
|
|
242
250
|
width: D(patternData.width),
|
|
243
|
-
height: D(patternData.height)
|
|
251
|
+
height: D(patternData.height),
|
|
244
252
|
};
|
|
245
253
|
}
|
|
246
254
|
|
|
@@ -319,12 +327,14 @@ export function getPatternContentTransform(patternData, tile, targetBBox) {
|
|
|
319
327
|
const offsetX = (tileWidth - vb.width * scale) / 2;
|
|
320
328
|
const offsetY = (tileHeight - vb.height * scale) / 2;
|
|
321
329
|
|
|
322
|
-
M = M.mul(
|
|
330
|
+
M = M.mul(
|
|
331
|
+
Transforms2D.translation(offsetX - vb.x * scale, offsetY - vb.y * scale),
|
|
332
|
+
);
|
|
323
333
|
M = M.mul(Transforms2D.scale(scale, scale));
|
|
324
334
|
}
|
|
325
335
|
|
|
326
336
|
// Apply objectBoundingBox scaling if needed
|
|
327
|
-
if (patternData.patternContentUnits ===
|
|
337
|
+
if (patternData.patternContentUnits === "objectBoundingBox") {
|
|
328
338
|
M = M.mul(Transforms2D.translation(targetBBox.x, targetBBox.y));
|
|
329
339
|
M = M.mul(Transforms2D.scale(targetBBox.width, targetBBox.height));
|
|
330
340
|
}
|
|
@@ -361,7 +371,7 @@ export function patternChildToPolygon(child, transform = null, samples = 20) {
|
|
|
361
371
|
const element = {
|
|
362
372
|
type: child.type,
|
|
363
373
|
...child,
|
|
364
|
-
transform: child.transform
|
|
374
|
+
transform: child.transform,
|
|
365
375
|
};
|
|
366
376
|
|
|
367
377
|
// Get polygon using ClipPathResolver
|
|
@@ -369,7 +379,7 @@ export function patternChildToPolygon(child, transform = null, samples = 20) {
|
|
|
369
379
|
|
|
370
380
|
// Apply additional transform if provided
|
|
371
381
|
if (transform && polygon.length > 0) {
|
|
372
|
-
polygon = polygon.map(p => {
|
|
382
|
+
polygon = polygon.map((p) => {
|
|
373
383
|
const [x, y] = Transforms2D.applyTransform(transform, p.x, p.y);
|
|
374
384
|
return { x, y };
|
|
375
385
|
});
|
|
@@ -432,7 +442,7 @@ export function getTilePositions(tile, coverBBox) {
|
|
|
432
442
|
for (let j = startJ; j < endJ; j++) {
|
|
433
443
|
positions.push({
|
|
434
444
|
x: D(tileX).plus(D(tileW).mul(i)),
|
|
435
|
-
y: D(tileY).plus(D(tileH).mul(j))
|
|
445
|
+
y: D(tileY).plus(D(tileH).mul(j)),
|
|
436
446
|
});
|
|
437
447
|
}
|
|
438
448
|
}
|
|
@@ -489,7 +499,11 @@ export function resolvePattern(patternData, targetBBox, options = {}) {
|
|
|
489
499
|
}
|
|
490
500
|
|
|
491
501
|
// Get content transform
|
|
492
|
-
const contentTransform = getPatternContentTransform(
|
|
502
|
+
const contentTransform = getPatternContentTransform(
|
|
503
|
+
patternData,
|
|
504
|
+
tile,
|
|
505
|
+
targetBBox,
|
|
506
|
+
);
|
|
493
507
|
|
|
494
508
|
// Get tile positions
|
|
495
509
|
const positions = getTilePositions(tile, targetBBox);
|
|
@@ -503,9 +517,9 @@ export function resolvePattern(patternData, targetBBox, options = {}) {
|
|
|
503
517
|
|
|
504
518
|
for (const child of patternData.children) {
|
|
505
519
|
// Combine transforms: tile position + content transform + child transform
|
|
506
|
-
|
|
520
|
+
const M = tileTranslate.mul(contentTransform);
|
|
507
521
|
|
|
508
|
-
|
|
522
|
+
const polygon = patternChildToPolygon(child, M, samples);
|
|
509
523
|
|
|
510
524
|
if (polygon.length >= 3) {
|
|
511
525
|
result.push({
|
|
@@ -513,7 +527,7 @@ export function resolvePattern(patternData, targetBBox, options = {}) {
|
|
|
513
527
|
fill: child.fill,
|
|
514
528
|
stroke: child.stroke,
|
|
515
529
|
strokeWidth: child.strokeWidth,
|
|
516
|
-
opacity: child.opacity
|
|
530
|
+
opacity: child.opacity,
|
|
517
531
|
});
|
|
518
532
|
}
|
|
519
533
|
}
|
|
@@ -558,21 +572,29 @@ export function resolvePattern(patternData, targetBBox, options = {}) {
|
|
|
558
572
|
* const clippedParts = applyPattern(circlePolygon, patternData, bbox);
|
|
559
573
|
* // Returns only the stripe portions visible within the circle
|
|
560
574
|
*/
|
|
561
|
-
export function applyPattern(
|
|
575
|
+
export function applyPattern(
|
|
576
|
+
targetPolygon,
|
|
577
|
+
patternData,
|
|
578
|
+
targetBBox,
|
|
579
|
+
options = {},
|
|
580
|
+
) {
|
|
562
581
|
const patternPolygons = resolvePattern(patternData, targetBBox, options);
|
|
563
582
|
const result = [];
|
|
564
583
|
|
|
565
584
|
for (const { polygon, fill, opacity } of patternPolygons) {
|
|
566
585
|
if (opacity <= 0) continue;
|
|
567
586
|
|
|
568
|
-
const intersection = PolygonClip.polygonIntersection(
|
|
587
|
+
const intersection = PolygonClip.polygonIntersection(
|
|
588
|
+
targetPolygon,
|
|
589
|
+
polygon,
|
|
590
|
+
);
|
|
569
591
|
|
|
570
592
|
for (const clippedPoly of intersection) {
|
|
571
593
|
if (clippedPoly.length >= 3) {
|
|
572
594
|
result.push({
|
|
573
595
|
polygon: clippedPoly,
|
|
574
596
|
fill,
|
|
575
|
-
opacity
|
|
597
|
+
opacity,
|
|
576
598
|
});
|
|
577
599
|
}
|
|
578
600
|
}
|
|
@@ -655,16 +677,16 @@ export function patternToClipPath(patternData, targetBBox, options = {}) {
|
|
|
655
677
|
export function patternToPathData(patternData, targetBBox, options = {}) {
|
|
656
678
|
const polygon = patternToClipPath(patternData, targetBBox, options);
|
|
657
679
|
|
|
658
|
-
if (polygon.length < 3) return
|
|
680
|
+
if (polygon.length < 3) return "";
|
|
659
681
|
|
|
660
|
-
let d =
|
|
682
|
+
let d = "";
|
|
661
683
|
for (let i = 0; i < polygon.length; i++) {
|
|
662
684
|
const p = polygon[i];
|
|
663
685
|
const x = Number(p.x).toFixed(6);
|
|
664
686
|
const y = Number(p.y).toFixed(6);
|
|
665
687
|
d += i === 0 ? `M ${x} ${y}` : ` L ${x} ${y}`;
|
|
666
688
|
}
|
|
667
|
-
d +=
|
|
689
|
+
d += " Z";
|
|
668
690
|
|
|
669
691
|
return d;
|
|
670
692
|
}
|
|
@@ -707,7 +729,7 @@ export function getPatternTileCount(patternData, targetBBox) {
|
|
|
707
729
|
return {
|
|
708
730
|
columns,
|
|
709
731
|
rows,
|
|
710
|
-
total: columns * rows
|
|
732
|
+
total: columns * rows,
|
|
711
733
|
};
|
|
712
734
|
}
|
|
713
735
|
|
|
@@ -751,36 +773,36 @@ export function getPatternContentBBox(patternData) {
|
|
|
751
773
|
let childBBox = null;
|
|
752
774
|
|
|
753
775
|
switch (child.type) {
|
|
754
|
-
case
|
|
776
|
+
case "rect":
|
|
755
777
|
childBBox = {
|
|
756
778
|
x: child.x,
|
|
757
779
|
y: child.y,
|
|
758
780
|
width: child.width,
|
|
759
|
-
height: child.height
|
|
781
|
+
height: child.height,
|
|
760
782
|
};
|
|
761
783
|
break;
|
|
762
|
-
case
|
|
784
|
+
case "circle":
|
|
763
785
|
childBBox = {
|
|
764
786
|
x: child.cx - child.r,
|
|
765
787
|
y: child.cy - child.r,
|
|
766
788
|
width: child.r * 2,
|
|
767
|
-
height: child.r * 2
|
|
789
|
+
height: child.r * 2,
|
|
768
790
|
};
|
|
769
791
|
break;
|
|
770
|
-
case
|
|
792
|
+
case "ellipse":
|
|
771
793
|
childBBox = {
|
|
772
794
|
x: child.cx - child.rx,
|
|
773
795
|
y: child.cy - child.ry,
|
|
774
796
|
width: child.rx * 2,
|
|
775
|
-
height: child.ry * 2
|
|
797
|
+
height: child.ry * 2,
|
|
776
798
|
};
|
|
777
799
|
break;
|
|
778
|
-
case
|
|
800
|
+
case "line":
|
|
779
801
|
childBBox = {
|
|
780
802
|
x: Math.min(child.x1, child.x2),
|
|
781
803
|
y: Math.min(child.y1, child.y2),
|
|
782
804
|
width: Math.abs(child.x2 - child.x1),
|
|
783
|
-
height: Math.abs(child.y2 - child.y1)
|
|
805
|
+
height: Math.abs(child.y2 - child.y1),
|
|
784
806
|
};
|
|
785
807
|
break;
|
|
786
808
|
}
|
|
@@ -801,7 +823,7 @@ export function getPatternContentBBox(patternData) {
|
|
|
801
823
|
x: minX,
|
|
802
824
|
y: minY,
|
|
803
825
|
width: maxX - minX,
|
|
804
|
-
height: maxY - minY
|
|
826
|
+
height: maxY - minY,
|
|
805
827
|
};
|
|
806
828
|
}
|
|
807
829
|
|
|
@@ -842,3 +864,18 @@ export function parsePatternTransform(transformStr) {
|
|
|
842
864
|
// Use ClipPathResolver's transform parser
|
|
843
865
|
return ClipPathResolver.parseTransform(transformStr);
|
|
844
866
|
}
|
|
867
|
+
|
|
868
|
+
export default {
|
|
869
|
+
parsePatternElement,
|
|
870
|
+
getPatternTile,
|
|
871
|
+
getPatternContentTransform,
|
|
872
|
+
patternChildToPolygon,
|
|
873
|
+
getTilePositions,
|
|
874
|
+
resolvePattern,
|
|
875
|
+
applyPattern,
|
|
876
|
+
patternToClipPath,
|
|
877
|
+
patternToPathData,
|
|
878
|
+
getPatternTileCount,
|
|
879
|
+
getPatternContentBBox,
|
|
880
|
+
parsePatternTransform,
|
|
881
|
+
};
|