@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.
Files changed (46) hide show
  1. package/README.md +325 -0
  2. package/bin/svg-matrix.js +994 -378
  3. package/bin/svglinter.cjs +4172 -433
  4. package/bin/svgm.js +744 -184
  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 +404 -0
  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 +48 -19
  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 +16411 -3298
  34. package/src/svg2-polyfills.js +114 -245
  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
@@ -13,25 +13,25 @@
13
13
  * @module svg-boolean-ops
14
14
  */
15
15
 
16
- import Decimal from 'decimal.js';
17
- import { PolygonClip } from './index.js';
16
+ import Decimal from "decimal.js";
17
+ import * as PolygonClip from "./polygon-clip.js";
18
18
 
19
19
  Decimal.set({ precision: 80 });
20
20
 
21
- const D = x => (x instanceof Decimal ? x : new Decimal(x));
22
- const EPSILON = new Decimal('1e-40');
21
+ const D = (x) => (x instanceof Decimal ? x : new Decimal(x));
22
+ const EPSILON = new Decimal("1e-40");
23
23
 
24
24
  const {
25
25
  point,
26
- pointsEqual,
26
+ pointsEqual: _pointsEqual,
27
27
  cross,
28
- polygonArea,
28
+ polygonArea: _polygonArea,
29
29
  polygonIntersection,
30
30
  polygonUnion,
31
31
  polygonDifference,
32
- isCounterClockwise,
33
- ensureCCW,
34
- segmentIntersection
32
+ isCounterClockwise: _isCounterClockwise,
33
+ ensureCCW: _ensureCCW,
34
+ segmentIntersection: _segmentIntersection,
35
35
  } = PolygonClip;
36
36
 
37
37
  // ============================================================================
@@ -42,8 +42,8 @@ const {
42
42
  * Fill rule enumeration matching SVG spec.
43
43
  */
44
44
  export const FillRule = {
45
- NONZERO: 'nonzero',
46
- EVENODD: 'evenodd'
45
+ NONZERO: "nonzero",
46
+ EVENODD: "evenodd",
47
47
  };
48
48
 
49
49
  /**
@@ -54,7 +54,11 @@ export const FillRule = {
54
54
  * @param {string} fillRule - 'nonzero' or 'evenodd'
55
55
  * @returns {number} 1 inside, 0 on boundary, -1 outside
56
56
  */
57
- export function pointInPolygonWithRule(pt, polygon, fillRule = FillRule.NONZERO) {
57
+ export function pointInPolygonWithRule(
58
+ pt,
59
+ polygon,
60
+ fillRule = FillRule.NONZERO,
61
+ ) {
58
62
  const n = polygon.length;
59
63
  if (n < 3) return -1;
60
64
 
@@ -99,6 +103,10 @@ export function pointInPolygonWithRule(pt, polygon, fillRule = FillRule.NONZERO)
99
103
 
100
104
  /**
101
105
  * Check if a point lies on a line segment.
106
+ * @param {Object} pt - Point to test {x, y}
107
+ * @param {Object} a - Segment start point {x, y}
108
+ * @param {Object} b - Segment end point {x, y}
109
+ * @returns {boolean} True if point is on the segment
102
110
  */
103
111
  function pointOnSegment(pt, a, b) {
104
112
  const crossVal = cross(a, b, pt);
@@ -111,8 +119,12 @@ function pointOnSegment(pt, a, b) {
111
119
  const minY = Decimal.min(a.y, b.y);
112
120
  const maxY = Decimal.max(a.y, b.y);
113
121
 
114
- return pt.x.gte(minX.minus(EPSILON)) && pt.x.lte(maxX.plus(EPSILON)) &&
115
- pt.y.gte(minY.minus(EPSILON)) && pt.y.lte(maxY.plus(EPSILON));
122
+ return (
123
+ pt.x.gte(minX.minus(EPSILON)) &&
124
+ pt.x.lte(maxX.plus(EPSILON)) &&
125
+ pt.y.gte(minY.minus(EPSILON)) &&
126
+ pt.y.lte(maxY.plus(EPSILON))
127
+ );
116
128
  }
117
129
 
118
130
  // ============================================================================
@@ -139,7 +151,7 @@ export function rectToPolygon(rect) {
139
151
  point(x, y),
140
152
  point(x.plus(w), y),
141
153
  point(x.plus(w), y.plus(h)),
142
- point(x, y.plus(h))
154
+ point(x, y.plus(h)),
143
155
  ];
144
156
  }
145
157
 
@@ -154,37 +166,57 @@ export function rectToPolygon(rect) {
154
166
  // Top-right corner
155
167
  for (let i = 0; i <= segments; i++) {
156
168
  const angle = Math.PI * 1.5 + (Math.PI / 2) * (i / segments);
157
- vertices.push(point(
158
- x.plus(w).minus(actualRx).plus(actualRx.times(Math.cos(angle))),
159
- y.plus(actualRy).plus(actualRy.times(Math.sin(angle)))
160
- ));
169
+ vertices.push(
170
+ point(
171
+ x
172
+ .plus(w)
173
+ .minus(actualRx)
174
+ .plus(actualRx.times(Math.cos(angle))),
175
+ y.plus(actualRy).plus(actualRy.times(Math.sin(angle))),
176
+ ),
177
+ );
161
178
  }
162
179
 
163
180
  // Bottom-right corner
164
181
  for (let i = 0; i <= segments; i++) {
165
182
  const angle = 0 + (Math.PI / 2) * (i / segments);
166
- vertices.push(point(
167
- x.plus(w).minus(actualRx).plus(actualRx.times(Math.cos(angle))),
168
- y.plus(h).minus(actualRy).plus(actualRy.times(Math.sin(angle)))
169
- ));
183
+ vertices.push(
184
+ point(
185
+ x
186
+ .plus(w)
187
+ .minus(actualRx)
188
+ .plus(actualRx.times(Math.cos(angle))),
189
+ y
190
+ .plus(h)
191
+ .minus(actualRy)
192
+ .plus(actualRy.times(Math.sin(angle))),
193
+ ),
194
+ );
170
195
  }
171
196
 
172
197
  // Bottom-left corner
173
198
  for (let i = 0; i <= segments; i++) {
174
199
  const angle = Math.PI / 2 + (Math.PI / 2) * (i / segments);
175
- vertices.push(point(
176
- x.plus(actualRx).plus(actualRx.times(Math.cos(angle))),
177
- y.plus(h).minus(actualRy).plus(actualRy.times(Math.sin(angle)))
178
- ));
200
+ vertices.push(
201
+ point(
202
+ x.plus(actualRx).plus(actualRx.times(Math.cos(angle))),
203
+ y
204
+ .plus(h)
205
+ .minus(actualRy)
206
+ .plus(actualRy.times(Math.sin(angle))),
207
+ ),
208
+ );
179
209
  }
180
210
 
181
211
  // Top-left corner
182
212
  for (let i = 0; i <= segments; i++) {
183
213
  const angle = Math.PI + (Math.PI / 2) * (i / segments);
184
- vertices.push(point(
185
- x.plus(actualRx).plus(actualRx.times(Math.cos(angle))),
186
- y.plus(actualRy).plus(actualRy.times(Math.sin(angle)))
187
- ));
214
+ vertices.push(
215
+ point(
216
+ x.plus(actualRx).plus(actualRx.times(Math.cos(angle))),
217
+ y.plus(actualRy).plus(actualRy.times(Math.sin(angle))),
218
+ ),
219
+ );
188
220
  }
189
221
 
190
222
  return vertices;
@@ -205,10 +237,12 @@ export function circleToPolygon(circle, segments = 32) {
205
237
  const vertices = [];
206
238
  for (let i = 0; i < segments; i++) {
207
239
  const angle = (2 * Math.PI * i) / segments;
208
- vertices.push(point(
209
- cx.plus(r.times(Math.cos(angle))),
210
- cy.plus(r.times(Math.sin(angle)))
211
- ));
240
+ vertices.push(
241
+ point(
242
+ cx.plus(r.times(Math.cos(angle))),
243
+ cy.plus(r.times(Math.sin(angle))),
244
+ ),
245
+ );
212
246
  }
213
247
 
214
248
  return vertices;
@@ -230,10 +264,12 @@ export function ellipseToPolygon(ellipse, segments = 32) {
230
264
  const vertices = [];
231
265
  for (let i = 0; i < segments; i++) {
232
266
  const angle = (2 * Math.PI * i) / segments;
233
- vertices.push(point(
234
- cx.plus(rx.times(Math.cos(angle))),
235
- cy.plus(ry.times(Math.sin(angle)))
236
- ));
267
+ vertices.push(
268
+ point(
269
+ cx.plus(rx.times(Math.cos(angle))),
270
+ cy.plus(ry.times(Math.sin(angle))),
271
+ ),
272
+ );
237
273
  }
238
274
 
239
275
  return vertices;
@@ -246,7 +282,7 @@ export function ellipseToPolygon(ellipse, segments = 32) {
246
282
  * @param {Object} stroke - {width, linecap}
247
283
  * @returns {Array} Polygon vertices representing stroked line
248
284
  */
249
- export function lineToPolygon(line, stroke = { width: 1, linecap: 'butt' }) {
285
+ export function lineToPolygon(line, stroke = { width: 1, linecap: "butt" }) {
250
286
  const x1 = D(line.x1);
251
287
  const y1 = D(line.y1);
252
288
  const x2 = D(line.x2);
@@ -269,7 +305,7 @@ export function lineToPolygon(line, stroke = { width: 1, linecap: 'butt' }) {
269
305
 
270
306
  const vertices = [];
271
307
 
272
- if (stroke.linecap === 'square') {
308
+ if (stroke.linecap === "square") {
273
309
  // Extend endpoints by half width
274
310
  const ex = dx.div(len).times(halfWidth);
275
311
  const ey = dy.div(len).times(halfWidth);
@@ -278,9 +314,9 @@ export function lineToPolygon(line, stroke = { width: 1, linecap: 'butt' }) {
278
314
  point(x1.minus(ex).minus(nx), y1.minus(ey).minus(ny)),
279
315
  point(x2.plus(ex).minus(nx), y2.plus(ey).minus(ny)),
280
316
  point(x2.plus(ex).plus(nx), y2.plus(ey).plus(ny)),
281
- point(x1.minus(ex).plus(nx), y1.minus(ey).plus(ny))
317
+ point(x1.minus(ex).plus(nx), y1.minus(ey).plus(ny)),
282
318
  );
283
- } else if (stroke.linecap === 'round') {
319
+ } else if (stroke.linecap === "round") {
284
320
  // Add semicircles at endpoints in CCW order
285
321
  // Start from right side of start point, go around start cap, along left side,
286
322
  // around end cap, and back along right side
@@ -290,19 +326,23 @@ export function lineToPolygon(line, stroke = { width: 1, linecap: 'butt' }) {
290
326
  // Start cap (semicircle) - going CCW from right side (-normal) to left side (+normal)
291
327
  for (let i = 0; i <= segments; i++) {
292
328
  const angle = startAngle - Math.PI / 2 - Math.PI * (i / segments);
293
- vertices.push(point(
294
- x1.plus(halfWidth.times(Math.cos(angle))),
295
- y1.plus(halfWidth.times(Math.sin(angle)))
296
- ));
329
+ vertices.push(
330
+ point(
331
+ x1.plus(halfWidth.times(Math.cos(angle))),
332
+ y1.plus(halfWidth.times(Math.sin(angle))),
333
+ ),
334
+ );
297
335
  }
298
336
 
299
337
  // End cap (semicircle) - continuing CCW from left side to right side
300
338
  for (let i = 0; i <= segments; i++) {
301
339
  const angle = startAngle + Math.PI / 2 - Math.PI * (i / segments);
302
- vertices.push(point(
303
- x2.plus(halfWidth.times(Math.cos(angle))),
304
- y2.plus(halfWidth.times(Math.sin(angle)))
305
- ));
340
+ vertices.push(
341
+ point(
342
+ x2.plus(halfWidth.times(Math.cos(angle))),
343
+ y2.plus(halfWidth.times(Math.sin(angle))),
344
+ ),
345
+ );
306
346
  }
307
347
  } else {
308
348
  // butt (default) - simple rectangle
@@ -311,7 +351,7 @@ export function lineToPolygon(line, stroke = { width: 1, linecap: 'butt' }) {
311
351
  point(x1.minus(nx), y1.minus(ny)),
312
352
  point(x2.minus(nx), y2.minus(ny)),
313
353
  point(x2.plus(nx), y2.plus(ny)),
314
- point(x1.plus(nx), y1.plus(ny))
354
+ point(x1.plus(nx), y1.plus(ny)),
315
355
  );
316
356
  }
317
357
 
@@ -326,11 +366,14 @@ export function lineToPolygon(line, stroke = { width: 1, linecap: 'butt' }) {
326
366
  */
327
367
  export function svgPolygonToPolygon(points) {
328
368
  if (Array.isArray(points)) {
329
- return points.map(p => point(p.x, p.y));
369
+ return points.map((p) => point(p.x, p.y));
330
370
  }
331
371
 
332
372
  // Parse SVG points string
333
- const coords = points.trim().split(/[\s,]+/).map(Number);
373
+ const coords = points
374
+ .trim()
375
+ .split(/[\s,]+/)
376
+ .map(Number);
334
377
  const vertices = [];
335
378
  for (let i = 0; i < coords.length; i += 2) {
336
379
  vertices.push(point(coords[i], coords[i + 1]));
@@ -355,7 +398,7 @@ export function svgPolygonToPolygon(points) {
355
398
  */
356
399
  export function offsetPolygon(polygon, distance, options = {}) {
357
400
  const dist = D(distance);
358
- const linejoin = options.linejoin || 'miter';
401
+ const linejoin = options.linejoin || "miter";
359
402
  const miterLimit = D(options.miterLimit || 4);
360
403
 
361
404
  if (polygon.length < 3) {
@@ -416,19 +459,31 @@ export function offsetPolygon(polygon, distance, options = {}) {
416
459
  if (sinHalfAngle.gt(EPSILON)) {
417
460
  const miterDist = dist.div(sinHalfAngle);
418
461
 
419
- if (linejoin === 'miter' && miterDist.lte(dist.times(miterLimit))) {
462
+ if (linejoin === "miter" && miterDist.lte(dist.times(miterLimit))) {
420
463
  actualDist = miterDist;
421
- } else if (linejoin === 'bevel' || miterDist.gt(dist.times(miterLimit))) {
464
+ } else if (linejoin === "bevel" || miterDist.gt(dist.times(miterLimit))) {
422
465
  // Bevel: add two points instead of one
423
- const outerPt1 = point(curr.x.plus(nx1.times(dist)), curr.y.plus(ny1.times(dist)));
424
- const outerPt2 = point(curr.x.plus(nx2.times(dist)), curr.y.plus(ny2.times(dist)));
466
+ const outerPt1 = point(
467
+ curr.x.plus(nx1.times(dist)),
468
+ curr.y.plus(ny1.times(dist)),
469
+ );
470
+ const outerPt2 = point(
471
+ curr.x.plus(nx2.times(dist)),
472
+ curr.y.plus(ny2.times(dist)),
473
+ );
425
474
  outerVertices.push(outerPt1, outerPt2);
426
475
 
427
- const innerPt1 = point(curr.x.minus(nx1.times(dist)), curr.y.minus(ny1.times(dist)));
428
- const innerPt2 = point(curr.x.minus(nx2.times(dist)), curr.y.minus(ny2.times(dist)));
476
+ const innerPt1 = point(
477
+ curr.x.minus(nx1.times(dist)),
478
+ curr.y.minus(ny1.times(dist)),
479
+ );
480
+ const innerPt2 = point(
481
+ curr.x.minus(nx2.times(dist)),
482
+ curr.y.minus(ny2.times(dist)),
483
+ );
429
484
  innerVertices.push(innerPt1, innerPt2);
430
485
  continue;
431
- } else if (linejoin === 'round') {
486
+ } else if (linejoin === "round") {
432
487
  // Round: add arc segments
433
488
  const startAngle = Math.atan2(ny1.toNumber(), nx1.toNumber());
434
489
  const endAngle = Math.atan2(ny2.toNumber(), nx2.toNumber());
@@ -436,30 +491,47 @@ export function offsetPolygon(polygon, distance, options = {}) {
436
491
  if (angleDiff < -Math.PI) angleDiff += 2 * Math.PI;
437
492
  if (angleDiff > Math.PI) angleDiff -= 2 * Math.PI;
438
493
 
439
- const segments = Math.max(2, Math.ceil(Math.abs(angleDiff) / (Math.PI / 8)));
494
+ const segments = Math.max(
495
+ 2,
496
+ Math.ceil(Math.abs(angleDiff) / (Math.PI / 8)),
497
+ );
440
498
  for (let j = 0; j <= segments; j++) {
441
499
  const angle = startAngle + angleDiff * (j / segments);
442
- outerVertices.push(point(
443
- curr.x.plus(dist.times(Math.cos(angle))),
444
- curr.y.plus(dist.times(Math.sin(angle)))
445
- ));
446
- innerVertices.push(point(
447
- curr.x.minus(dist.times(Math.cos(angle))),
448
- curr.y.minus(dist.times(Math.sin(angle)))
449
- ));
500
+ outerVertices.push(
501
+ point(
502
+ curr.x.plus(dist.times(Math.cos(angle))),
503
+ curr.y.plus(dist.times(Math.sin(angle))),
504
+ ),
505
+ );
506
+ innerVertices.push(
507
+ point(
508
+ curr.x.minus(dist.times(Math.cos(angle))),
509
+ curr.y.minus(dist.times(Math.sin(angle))),
510
+ ),
511
+ );
450
512
  }
451
513
  continue;
452
514
  }
453
515
  }
454
516
 
455
517
  // Single offset point
456
- outerVertices.push(point(curr.x.plus(nx.times(actualDist)), curr.y.plus(ny.times(actualDist))));
457
- innerVertices.push(point(curr.x.minus(nx.times(actualDist)), curr.y.minus(ny.times(actualDist))));
518
+ outerVertices.push(
519
+ point(
520
+ curr.x.plus(nx.times(actualDist)),
521
+ curr.y.plus(ny.times(actualDist)),
522
+ ),
523
+ );
524
+ innerVertices.push(
525
+ point(
526
+ curr.x.minus(nx.times(actualDist)),
527
+ curr.y.minus(ny.times(actualDist)),
528
+ ),
529
+ );
458
530
  }
459
531
 
460
532
  return {
461
533
  outer: outerVertices,
462
- inner: innerVertices.reverse() // Reverse for consistent winding
534
+ inner: innerVertices.reverse(), // Reverse for consistent winding
463
535
  };
464
536
  }
465
537
 
@@ -500,9 +572,10 @@ export function applyDashArray(polygon, dashArray, dashOffset = 0) {
500
572
  }
501
573
 
502
574
  // Normalize dash array (must have even length)
503
- const dashes = dashArray.length % 2 === 0
504
- ? dashArray.map(d => D(d))
505
- : [...dashArray, ...dashArray].map(d => D(d));
575
+ const dashes =
576
+ dashArray.length % 2 === 0
577
+ ? dashArray.map((d) => D(d))
578
+ : [...dashArray, ...dashArray].map((d) => D(d));
506
579
 
507
580
  const segments = [];
508
581
  let currentSegment = [];
@@ -544,10 +617,9 @@ export function applyDashArray(polygon, dashArray, dashOffset = 0) {
544
617
  if (remaining.lte(remainingInDash)) {
545
618
  // Rest of edge fits in current dash/gap
546
619
  if (drawing) {
547
- currentSegment.push(point(
548
- p1.x.plus(dx.times(t)),
549
- p1.y.plus(dy.times(t))
550
- ));
620
+ currentSegment.push(
621
+ point(p1.x.plus(dx.times(t)), p1.y.plus(dy.times(t))),
622
+ );
551
623
  currentSegment.push(point(p2.x, p2.y));
552
624
  }
553
625
  remainingInDash = remainingInDash.minus(remaining);
@@ -567,14 +639,12 @@ export function applyDashArray(polygon, dashArray, dashOffset = 0) {
567
639
  const tEnd = t.plus(remainingInDash.div(edgeLen));
568
640
 
569
641
  if (drawing) {
570
- currentSegment.push(point(
571
- p1.x.plus(dx.times(t)),
572
- p1.y.plus(dy.times(t))
573
- ));
574
- currentSegment.push(point(
575
- p1.x.plus(dx.times(tEnd)),
576
- p1.y.plus(dy.times(tEnd))
577
- ));
642
+ currentSegment.push(
643
+ point(p1.x.plus(dx.times(t)), p1.y.plus(dy.times(t))),
644
+ );
645
+ currentSegment.push(
646
+ point(p1.x.plus(dx.times(tEnd)), p1.y.plus(dy.times(tEnd))),
647
+ );
578
648
  segments.push(currentSegment);
579
649
  currentSegment = [];
580
650
  }
@@ -627,40 +697,44 @@ export class SVGRegion {
627
697
  let polygon;
628
698
 
629
699
  switch (type) {
630
- case 'rect':
700
+ case "rect":
631
701
  polygon = rectToPolygon(props);
632
702
  break;
633
- case 'circle':
703
+ case "circle":
634
704
  polygon = circleToPolygon(props);
635
705
  break;
636
- case 'ellipse':
706
+ case "ellipse":
637
707
  polygon = ellipseToPolygon(props);
638
708
  break;
639
- case 'polygon':
709
+ case "polygon":
640
710
  polygon = svgPolygonToPolygon(props.points);
641
711
  break;
642
- case 'line':
712
+ case "line":
643
713
  // Lines have no fill, only stroke
644
714
  polygon = null;
645
715
  break;
646
716
  default:
647
- throw new Error('Unsupported element type: ' + type);
717
+ throw new Error("Unsupported element type: " + type);
648
718
  }
649
719
 
650
720
  const region = new SVGRegion({
651
- fillRule: style.fillRule || FillRule.NONZERO
721
+ fillRule: style.fillRule || FillRule.NONZERO,
652
722
  });
653
723
 
654
724
  // Add fill region if element has fill
655
- if (polygon && style.fill !== 'none') {
725
+ if (polygon && style.fill !== "none") {
656
726
  region.fillPolygons = [polygon];
657
727
  }
658
728
 
659
729
  // Add stroke region if element has stroke
660
- if (style.stroke !== 'none' && style.strokeWidth > 0) {
661
- const sourcePolygon = type === 'line'
662
- ? lineToPolygon(props, { width: style.strokeWidth, linecap: style.strokeLinecap })
663
- : polygon;
730
+ if (style.stroke !== "none" && style.strokeWidth > 0) {
731
+ const sourcePolygon =
732
+ type === "line"
733
+ ? lineToPolygon(props, {
734
+ width: style.strokeWidth,
735
+ linecap: style.strokeLinecap,
736
+ })
737
+ : polygon;
664
738
 
665
739
  if (sourcePolygon) {
666
740
  let strokePolygons;
@@ -670,24 +744,26 @@ export class SVGRegion {
670
744
  const dashedSegments = applyDashArray(
671
745
  sourcePolygon,
672
746
  style.strokeDasharray,
673
- style.strokeDashoffset || 0
747
+ style.strokeDashoffset || 0,
674
748
  );
675
- strokePolygons = dashedSegments.map(seg =>
749
+ strokePolygons = dashedSegments.map((seg) =>
676
750
  strokeToFilledPolygon(seg, {
677
751
  width: style.strokeWidth,
678
752
  linejoin: style.strokeLinejoin,
679
- miterLimit: style.strokeMiterlimit
680
- })
753
+ miterLimit: style.strokeMiterlimit,
754
+ }),
681
755
  );
682
756
  } else {
683
- strokePolygons = [strokeToFilledPolygon(sourcePolygon, {
684
- width: style.strokeWidth,
685
- linejoin: style.strokeLinejoin,
686
- miterLimit: style.strokeMiterlimit
687
- })];
757
+ strokePolygons = [
758
+ strokeToFilledPolygon(sourcePolygon, {
759
+ width: style.strokeWidth,
760
+ linejoin: style.strokeLinejoin,
761
+ miterLimit: style.strokeMiterlimit,
762
+ }),
763
+ ];
688
764
  }
689
765
 
690
- region.strokePolygons = strokePolygons.filter(p => p.length >= 3);
766
+ region.strokePolygons = strokePolygons.filter((p) => p.length >= 3);
691
767
  }
692
768
  }
693
769
 
@@ -758,7 +834,7 @@ export function regionIntersection(regionA, regionB) {
758
834
 
759
835
  return new SVGRegion({
760
836
  fillPolygons: resultPolygons,
761
- fillRule: FillRule.NONZERO // Result is always simple polygons
837
+ fillRule: FillRule.NONZERO, // Result is always simple polygons
762
838
  });
763
839
  }
764
840
 
@@ -770,7 +846,7 @@ export function regionIntersection(regionA, regionB) {
770
846
  * @returns {SVGRegion} Union region
771
847
  */
772
848
  export function regionUnion(regionA, regionB) {
773
- const resultPolygons = [];
849
+ const _resultPolygons = [];
774
850
 
775
851
  const polygonsA = regionA.getAllPolygons();
776
852
  const polygonsB = regionB.getAllPolygons();
@@ -811,7 +887,7 @@ export function regionUnion(regionA, regionB) {
811
887
 
812
888
  return new SVGRegion({
813
889
  fillPolygons: combined,
814
- fillRule: FillRule.NONZERO
890
+ fillRule: FillRule.NONZERO,
815
891
  });
816
892
  }
817
893
 
@@ -823,7 +899,7 @@ export function regionUnion(regionA, regionB) {
823
899
  * @returns {SVGRegion} Difference region
824
900
  */
825
901
  export function regionDifference(regionA, regionB) {
826
- let resultPolygons = regionA.getAllPolygons().map(p => [...p]);
902
+ let resultPolygons = regionA.getAllPolygons().map((p) => [...p]);
827
903
 
828
904
  const polygonsB = regionB.getAllPolygons();
829
905
 
@@ -845,7 +921,7 @@ export function regionDifference(regionA, regionB) {
845
921
 
846
922
  return new SVGRegion({
847
923
  fillPolygons: resultPolygons,
848
- fillRule: FillRule.NONZERO
924
+ fillRule: FillRule.NONZERO,
849
925
  });
850
926
  }
851
927
 
@@ -862,7 +938,7 @@ export function regionXOR(regionA, regionB) {
862
938
 
863
939
  return new SVGRegion({
864
940
  fillPolygons: [...diffAB.fillPolygons, ...diffBA.fillPolygons],
865
- fillRule: FillRule.NONZERO
941
+ fillRule: FillRule.NONZERO,
866
942
  });
867
943
  }
868
944
 
@@ -894,5 +970,5 @@ export default {
894
970
  regionIntersection,
895
971
  regionUnion,
896
972
  regionDifference,
897
- regionXOR
973
+ regionXOR,
898
974
  };