@flighthq/path 0.1.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.
Files changed (115) hide show
  1. package/dist/containsPathPoint.d.ts +13 -0
  2. package/dist/containsPathPoint.d.ts.map +1 -0
  3. package/dist/containsPathPoint.js +194 -0
  4. package/dist/containsPathPoint.js.map +1 -0
  5. package/dist/copyPath.d.ts +4 -0
  6. package/dist/copyPath.d.ts.map +1 -0
  7. package/dist/copyPath.js +28 -0
  8. package/dist/copyPath.js.map +1 -0
  9. package/dist/dashPath.d.ts +3 -0
  10. package/dist/dashPath.d.ts.map +1 -0
  11. package/dist/dashPath.js +105 -0
  12. package/dist/dashPath.js.map +1 -0
  13. package/dist/fitPathCurves.d.ts +3 -0
  14. package/dist/fitPathCurves.d.ts.map +1 -0
  15. package/dist/fitPathCurves.js +222 -0
  16. package/dist/fitPathCurves.js.map +1 -0
  17. package/dist/flattenPath.d.ts +3 -0
  18. package/dist/flattenPath.d.ts.map +1 -0
  19. package/dist/flattenPath.js +145 -0
  20. package/dist/flattenPath.js.map +1 -0
  21. package/dist/forEachPathSegment.d.ts +3 -0
  22. package/dist/forEachPathSegment.d.ts.map +1 -0
  23. package/dist/forEachPathSegment.js +66 -0
  24. package/dist/forEachPathSegment.js.map +1 -0
  25. package/dist/getPathBounds.d.ts +3 -0
  26. package/dist/getPathBounds.d.ts.map +1 -0
  27. package/dist/getPathBounds.js +167 -0
  28. package/dist/getPathBounds.js.map +1 -0
  29. package/dist/getPathContourLengths.d.ts +3 -0
  30. package/dist/getPathContourLengths.d.ts.map +1 -0
  31. package/dist/getPathContourLengths.js +21 -0
  32. package/dist/getPathContourLengths.js.map +1 -0
  33. package/dist/getPathLength.d.ts +3 -0
  34. package/dist/getPathLength.d.ts.map +1 -0
  35. package/dist/getPathLength.js +23 -0
  36. package/dist/getPathLength.js.map +1 -0
  37. package/dist/getPathNearestPoint.d.ts +3 -0
  38. package/dist/getPathNearestPoint.d.ts.map +1 -0
  39. package/dist/getPathNearestPoint.js +47 -0
  40. package/dist/getPathNearestPoint.js.map +1 -0
  41. package/dist/getPathPointAtDistance.d.ts +5 -0
  42. package/dist/getPathPointAtDistance.d.ts.map +1 -0
  43. package/dist/getPathPointAtDistance.js +100 -0
  44. package/dist/getPathPointAtDistance.js.map +1 -0
  45. package/dist/getPathSegmentAtParameter.d.ts +8 -0
  46. package/dist/getPathSegmentAtParameter.d.ts.map +1 -0
  47. package/dist/getPathSegmentAtParameter.js +163 -0
  48. package/dist/getPathSegmentAtParameter.js.map +1 -0
  49. package/dist/getPathSignedArea.d.ts +4 -0
  50. package/dist/getPathSignedArea.d.ts.map +1 -0
  51. package/dist/getPathSignedArea.js +43 -0
  52. package/dist/getPathSignedArea.js.map +1 -0
  53. package/dist/index.d.ts +23 -0
  54. package/dist/index.d.ts.map +1 -0
  55. package/dist/index.js +23 -0
  56. package/dist/index.js.map +1 -0
  57. package/dist/offsetPath.d.ts +3 -0
  58. package/dist/offsetPath.d.ts.map +1 -0
  59. package/dist/offsetPath.js +146 -0
  60. package/dist/offsetPath.js.map +1 -0
  61. package/dist/path.d.ts +17 -0
  62. package/dist/path.d.ts.map +1 -0
  63. package/dist/path.js +293 -0
  64. package/dist/path.js.map +1 -0
  65. package/dist/pathMeshPool.d.ts +6 -0
  66. package/dist/pathMeshPool.d.ts.map +1 -0
  67. package/dist/pathMeshPool.js +58 -0
  68. package/dist/pathMeshPool.js.map +1 -0
  69. package/dist/reversePath.d.ts +3 -0
  70. package/dist/reversePath.d.ts.map +1 -0
  71. package/dist/reversePath.js +95 -0
  72. package/dist/reversePath.js.map +1 -0
  73. package/dist/simplifyPath.d.ts +3 -0
  74. package/dist/simplifyPath.d.ts.map +1 -0
  75. package/dist/simplifyPath.js +78 -0
  76. package/dist/simplifyPath.js.map +1 -0
  77. package/dist/strokePath.d.ts +4 -0
  78. package/dist/strokePath.d.ts.map +1 -0
  79. package/dist/strokePath.js +458 -0
  80. package/dist/strokePath.js.map +1 -0
  81. package/dist/tessellatePath.d.ts +3 -0
  82. package/dist/tessellatePath.d.ts.map +1 -0
  83. package/dist/tessellatePath.js +107 -0
  84. package/dist/tessellatePath.js.map +1 -0
  85. package/dist/tessellatePathTyped.d.ts +3 -0
  86. package/dist/tessellatePathTyped.d.ts.map +1 -0
  87. package/dist/tessellatePathTyped.js +12 -0
  88. package/dist/tessellatePathTyped.js.map +1 -0
  89. package/dist/transformPath.d.ts +4 -0
  90. package/dist/transformPath.d.ts.map +1 -0
  91. package/dist/transformPath.js +62 -0
  92. package/dist/transformPath.js.map +1 -0
  93. package/package.json +37 -0
  94. package/src/containsPathPoint.test.ts +125 -0
  95. package/src/copyPath.test.ts +56 -0
  96. package/src/dashPath.test.ts +76 -0
  97. package/src/fitPathCurves.test.ts +65 -0
  98. package/src/flattenPath.test.ts +87 -0
  99. package/src/forEachPathSegment.test.ts +82 -0
  100. package/src/getPathBounds.test.ts +84 -0
  101. package/src/getPathContourLengths.test.ts +51 -0
  102. package/src/getPathLength.test.ts +33 -0
  103. package/src/getPathNearestPoint.test.ts +64 -0
  104. package/src/getPathPointAtDistance.test.ts +94 -0
  105. package/src/getPathSegmentAtParameter.test.ts +178 -0
  106. package/src/getPathSignedArea.test.ts +45 -0
  107. package/src/offsetPath.test.ts +78 -0
  108. package/src/path.test.ts +376 -0
  109. package/src/pathMeshPool.test.ts +78 -0
  110. package/src/reversePath.test.ts +51 -0
  111. package/src/simplifyPath.test.ts +69 -0
  112. package/src/strokePath.test.ts +150 -0
  113. package/src/tessellatePath.test.ts +62 -0
  114. package/src/tessellatePathTyped.test.ts +26 -0
  115. package/src/transformPath.test.ts +79 -0
@@ -0,0 +1,458 @@
1
+ import { PathCommand } from '@flighthq/types';
2
+ import { appendPathClose } from './path';
3
+ // Converts the centerline `path` into a fillable outline `Path` by offsetting both sides by
4
+ // half the stroke width, joining corners per `style.join`, and capping open endpoints per
5
+ // `style.cap`. The result is a collection of closed contours suitable for `tessellatePath`.
6
+ //
7
+ // Curves are pre-flattened to `tolerance` path units before offsetting; the offset contours are
8
+ // themselves composed of straight segments (the flattenPath route means no new curve math is
9
+ // needed at the outline layer). Pass a tight tolerance for smooth rounded joins/caps.
10
+ //
11
+ // This is the direct route to stroke fill; the renderer's stencil-then-cover route for hairline
12
+ // precision is outside this function's scope.
13
+ export function strokePath(path, style, tolerance = 0.25) {
14
+ const width = style.width ?? 1;
15
+ const join = style.join ?? 'miter';
16
+ const cap = style.cap ?? 'butt';
17
+ const miterLimit = style.miterLimit ?? 4;
18
+ const halfWidth = width / 2;
19
+ const result = { commands: [], data: [], winding: 'nonZero' };
20
+ // Decode path into flat subpath polylines, respecting the closed flag.
21
+ const subpaths = decodeSubpaths(path, tolerance);
22
+ const dash = style.dash && style.dash.length > 0 ? style.dash : null;
23
+ const dashOffset = style.dashOffset ?? 0;
24
+ for (const subpath of subpaths) {
25
+ if (subpath.points.length < 2)
26
+ continue;
27
+ const segments = dash
28
+ ? applyDash(subpath.points, subpath.closed, dash, dashOffset)
29
+ : [{ points: subpath.points, closed: subpath.closed }];
30
+ for (const seg of segments) {
31
+ if (seg.points.length < 2)
32
+ continue;
33
+ strokeSubpath(seg.points, seg.closed, halfWidth, join, cap, miterLimit, result, tolerance);
34
+ }
35
+ }
36
+ return result;
37
+ }
38
+ // Adds arc sample points from `startAngle` to `endAngle` around center (cx,cy) at radius `r`
39
+ // into `out`. `ccw=true` goes counter-clockwise (decreasing angle in standard math convention).
40
+ function addArcPoints(cx, cy, r, startAngle, endAngle, ccw, tolerance, out) {
41
+ // Number of steps from tolerance: the chord error for n steps is r*(1-cos(π/n)) ≤ tolerance.
42
+ // n ≥ π / acos(1 - tolerance/r). Clamp to a sensible minimum (4).
43
+ const ratio = Math.max(0, Math.min(1, tolerance / r));
44
+ const n = Math.max(4, Math.ceil(Math.PI / Math.acos(1 - ratio)));
45
+ let delta = endAngle - startAngle;
46
+ if (ccw) {
47
+ if (delta > 0)
48
+ delta -= Math.PI * 2;
49
+ }
50
+ else {
51
+ if (delta < 0)
52
+ delta += Math.PI * 2;
53
+ }
54
+ const steps = Math.ceil(Math.abs(delta) / ((Math.PI * 2) / n));
55
+ if (steps <= 1)
56
+ return;
57
+ const stepAngle = delta / steps;
58
+ for (let i = 1; i < steps; i++) {
59
+ const angle = startAngle + i * stepAngle;
60
+ out.push(cx + Math.cos(angle) * r, cy + Math.sin(angle) * r);
61
+ }
62
+ }
63
+ // Adds a start or end cap for an open subpath.
64
+ // `nx, ny` = left normal of the adjacent segment (perpendicular, pointing left of travel).
65
+ // `edx, edy` = extension direction: the direction to extend the cap outward from the endpoint.
66
+ // For start cap: extend backward (-segment direction).
67
+ // For end cap: extend forward (+segment direction).
68
+ function addCap(px, py, nx, ny, edx, edy, halfWidth, cap, left, right, tolerance, isStart) {
69
+ // Left side offset (in direction of left normal), right side offset (opposite).
70
+ const lx = px + nx * halfWidth;
71
+ const ly = py + ny * halfWidth;
72
+ const rx = px - nx * halfWidth;
73
+ const ry = py - ny * halfWidth;
74
+ if (cap === 'butt') {
75
+ left.push(lx, ly);
76
+ right.push(rx, ry);
77
+ }
78
+ else if (cap === 'square') {
79
+ // Extend by halfWidth in the cap extension direction.
80
+ left.push(lx + edx * halfWidth, ly + edy * halfWidth);
81
+ right.push(rx + edx * halfWidth, ry + edy * halfWidth);
82
+ }
83
+ else {
84
+ // Round cap: semicircle spanning the full width, centered at the endpoint.
85
+ if (isStart) {
86
+ left.push(lx, ly);
87
+ right.push(rx, ry);
88
+ // Arc from right side angle to left side angle in the extension direction.
89
+ const startAngle = Math.atan2(-ny, -nx);
90
+ const endAngle = Math.atan2(ny, nx);
91
+ addArcPoints(px, py, halfWidth, startAngle, endAngle, false, tolerance, right);
92
+ }
93
+ else {
94
+ left.push(lx, ly);
95
+ addArcPoints(px, py, halfWidth, Math.atan2(ny, nx), Math.atan2(-ny, -nx), true, tolerance, left);
96
+ right.push(rx, ry);
97
+ }
98
+ }
99
+ }
100
+ // Adds a join (corner) between two adjacent segments to the left and right offset arrays.
101
+ function addJoin(px, py, nx0, ny0, nx1, ny1, halfWidth, join, miterLimit, left, right, tolerance) {
102
+ // Left side: offset by +normal, Right side: offset by -normal.
103
+ const lx0 = px + nx0 * halfWidth;
104
+ const ly0 = py + ny0 * halfWidth;
105
+ const rx0 = px - nx0 * halfWidth;
106
+ const ry0 = py - ny0 * halfWidth;
107
+ const lx1 = px + nx1 * halfWidth;
108
+ const ly1 = py + ny1 * halfWidth;
109
+ const rx1 = px - nx1 * halfWidth;
110
+ const ry1 = py - ny1 * halfWidth;
111
+ if (join === 'miter') {
112
+ // Miter join: intersect the offset lines. Fall back to bevel if miter length exceeds limit.
113
+ const cross = nx0 * ny1 - ny0 * nx1;
114
+ if (Math.abs(cross) < 1e-8) {
115
+ // Parallel segments: simple bevel (just two points each side).
116
+ left.push(lx0, ly0);
117
+ right.push(rx0, ry0);
118
+ }
119
+ else {
120
+ // Find the miter intersection point.
121
+ const dx = lx1 - lx0;
122
+ const dy = ly1 - ly0;
123
+ const t = (dx * ny1 - dy * nx1) / cross;
124
+ const mx = lx0 + t * nx0;
125
+ const my = ly0 + t * ny0;
126
+ const miterLen = Math.sqrt((mx - px) * (mx - px) + (my - py) * (my - py));
127
+ if (miterLen <= halfWidth * miterLimit) {
128
+ left.push(mx, my);
129
+ // Miter on the other side (mirror through center).
130
+ const rmx = px * 2 - mx;
131
+ const rmy = py * 2 - my;
132
+ right.push(rmx, rmy);
133
+ }
134
+ else {
135
+ // Degrade to bevel.
136
+ left.push(lx0, ly0, lx1, ly1);
137
+ right.push(rx0, ry0, rx1, ry1);
138
+ }
139
+ }
140
+ }
141
+ else if (join === 'round') {
142
+ // Round join: arc from (lx0,ly0) to (lx1,ly1) around the outer side.
143
+ left.push(lx0, ly0);
144
+ addArcPoints(px, py, halfWidth, Math.atan2(ny0, nx0), Math.atan2(ny1, nx1), true, tolerance, left);
145
+ left.push(lx1, ly1);
146
+ right.push(rx0, ry0);
147
+ addArcPoints(px, py, halfWidth, Math.atan2(-ny0, -nx0), Math.atan2(-ny1, -nx1), false, tolerance, right);
148
+ right.push(rx1, ry1);
149
+ }
150
+ else {
151
+ // Bevel: two points per side.
152
+ left.push(lx0, ly0, lx1, ly1);
153
+ right.push(rx0, ry0, rx1, ry1);
154
+ }
155
+ }
156
+ // Splits a subpath into dash segments based on the dash pattern.
157
+ function applyDash(pts, closed, dash, dashOffset) {
158
+ const result = [];
159
+ if (dash.length === 0) {
160
+ result.push({ points: pts, closed });
161
+ return result;
162
+ }
163
+ const totalDashLength = dash.reduce((s, d) => s + d, 0);
164
+ if (totalDashLength <= 0) {
165
+ result.push({ points: pts, closed });
166
+ return result;
167
+ }
168
+ // Normalize offset into the pattern.
169
+ const offset = ((dashOffset % totalDashLength) + totalDashLength) % totalDashLength;
170
+ // Find starting dash index and remaining length in that dash.
171
+ let dashIndex = 0;
172
+ let remaining = 0;
173
+ let isOn = true;
174
+ {
175
+ let acc = 0;
176
+ for (let i = 0; i < dash.length; i++) {
177
+ if (acc + dash[i] > offset) {
178
+ dashIndex = i;
179
+ remaining = dash[i] - (offset - acc);
180
+ isOn = i % 2 === 0;
181
+ break;
182
+ }
183
+ acc += dash[i];
184
+ }
185
+ }
186
+ let current = null;
187
+ const n = pts.length >> 1;
188
+ for (let i = 0; i < n - 1; i++) {
189
+ const x0 = pts[i * 2];
190
+ const y0 = pts[i * 2 + 1];
191
+ const x1 = pts[(i + 1) * 2];
192
+ const y1 = pts[(i + 1) * 2 + 1];
193
+ const dx = x1 - x0;
194
+ const dy = y1 - y0;
195
+ const segLen = Math.sqrt(dx * dx + dy * dy);
196
+ if (isOn && current === null) {
197
+ current = [x0, y0];
198
+ }
199
+ let consumed = 0;
200
+ while (consumed < segLen) {
201
+ const step = Math.min(remaining, segLen - consumed);
202
+ const t = (consumed + step) / segLen;
203
+ const ix = x0 + t * dx;
204
+ const iy = y0 + t * dy;
205
+ if (isOn) {
206
+ if (current === null)
207
+ current = [x0 + (consumed / segLen) * dx, y0 + (consumed / segLen) * dy];
208
+ current.push(ix, iy);
209
+ }
210
+ else {
211
+ if (current !== null) {
212
+ if (current.length >= 4)
213
+ result.push({ points: current, closed: false });
214
+ current = null;
215
+ }
216
+ if (step >= remaining) {
217
+ current = [ix, iy];
218
+ }
219
+ }
220
+ consumed += step;
221
+ remaining -= step;
222
+ if (remaining <= 1e-10) {
223
+ dashIndex = (dashIndex + 1) % dash.length;
224
+ remaining = dash[dashIndex];
225
+ isOn = dashIndex % 2 === 0;
226
+ if (isOn && current === null) {
227
+ current = [ix, iy];
228
+ }
229
+ else if (!isOn && current !== null) {
230
+ if (current.length >= 4)
231
+ result.push({ points: current, closed: false });
232
+ current = null;
233
+ }
234
+ }
235
+ }
236
+ }
237
+ if (current !== null && current.length >= 4) {
238
+ result.push({ points: current, closed: false });
239
+ }
240
+ return result;
241
+ }
242
+ function decodeSubpaths(path, tolerance) {
243
+ // Use the flattenPath internal logic (re-implemented here to track closed-ness per subpath
244
+ // and to avoid returning separate contours without their closed flag).
245
+ const commands = path.commands;
246
+ const data = path.data;
247
+ const toleranceSq = tolerance * tolerance;
248
+ const subpaths = [];
249
+ let current = null;
250
+ let x = 0;
251
+ let y = 0;
252
+ let contourStartX = 0;
253
+ let contourStartY = 0;
254
+ let di = 0;
255
+ const ensureCurrent = () => {
256
+ if (current === null) {
257
+ current = { points: [0, 0], closed: false };
258
+ subpaths.push(current);
259
+ x = 0;
260
+ y = 0;
261
+ }
262
+ return current;
263
+ };
264
+ for (let ci = 0; ci < commands.length; ci++) {
265
+ const command = commands[ci];
266
+ if (command === PathCommand.MOVE_TO) {
267
+ x = data[di];
268
+ y = data[di + 1];
269
+ di += 2;
270
+ contourStartX = x;
271
+ contourStartY = y;
272
+ current = { points: [x, y], closed: false };
273
+ subpaths.push(current);
274
+ }
275
+ else if (command === PathCommand.WIDE_MOVE_TO) {
276
+ x = data[di + 2];
277
+ y = data[di + 3];
278
+ di += 4;
279
+ contourStartX = x;
280
+ contourStartY = y;
281
+ current = { points: [x, y], closed: false };
282
+ subpaths.push(current);
283
+ }
284
+ else if (command === PathCommand.LINE_TO) {
285
+ const sp = ensureCurrent();
286
+ x = data[di];
287
+ y = data[di + 1];
288
+ di += 2;
289
+ sp.points.push(x, y);
290
+ }
291
+ else if (command === PathCommand.WIDE_LINE_TO) {
292
+ const sp = ensureCurrent();
293
+ x = data[di + 2];
294
+ y = data[di + 3];
295
+ di += 4;
296
+ sp.points.push(x, y);
297
+ }
298
+ else if (command === PathCommand.CURVE_TO) {
299
+ const sp = ensureCurrent();
300
+ flattenQuadratic(sp.points, x, y, data[di], data[di + 1], data[di + 2], data[di + 3], toleranceSq, 0);
301
+ x = data[di + 2];
302
+ y = data[di + 3];
303
+ di += 4;
304
+ }
305
+ else if (command === PathCommand.CUBIC_CURVE_TO) {
306
+ const sp = ensureCurrent();
307
+ flattenCubic(sp.points, x, y, data[di], data[di + 1], data[di + 2], data[di + 3], data[di + 4], data[di + 5], toleranceSq, 0);
308
+ x = data[di + 4];
309
+ y = data[di + 5];
310
+ di += 6;
311
+ }
312
+ else if (command === PathCommand.CLOSE) {
313
+ if (current !== null) {
314
+ current.closed = true;
315
+ x = contourStartX;
316
+ y = contourStartY;
317
+ current = null;
318
+ }
319
+ }
320
+ }
321
+ return subpaths;
322
+ }
323
+ function distChordSq(px, py, x0, y0, x1, y1) {
324
+ const dx = x1 - x0;
325
+ const dy = y1 - y0;
326
+ const lenSq = dx * dx + dy * dy;
327
+ if (lenSq === 0) {
328
+ const ax = px - x0;
329
+ const ay = py - y0;
330
+ return ax * ax + ay * ay;
331
+ }
332
+ const cross = dx * (y0 - py) - dy * (x0 - px);
333
+ return (cross * cross) / lenSq;
334
+ }
335
+ function flattenCubic(out, x0, y0, c1x, c1y, c2x, c2y, x1, y1, toleranceSq, depth) {
336
+ const dxc1 = distChordSq(c1x, c1y, x0, y0, x1, y1);
337
+ const dxc2 = distChordSq(c2x, c2y, x0, y0, x1, y1);
338
+ if (depth >= MAX_SUBDIVISION_DEPTH || (dxc1 <= toleranceSq && dxc2 <= toleranceSq)) {
339
+ out.push(x1, y1);
340
+ return;
341
+ }
342
+ const x01 = (x0 + c1x) / 2;
343
+ const y01 = (y0 + c1y) / 2;
344
+ const x12 = (c1x + c2x) / 2;
345
+ const y12 = (c1y + c2y) / 2;
346
+ const x23 = (c2x + x1) / 2;
347
+ const y23 = (c2y + y1) / 2;
348
+ const x012 = (x01 + x12) / 2;
349
+ const y012 = (y01 + y12) / 2;
350
+ const x123 = (x12 + x23) / 2;
351
+ const y123 = (y12 + y23) / 2;
352
+ const xm = (x012 + x123) / 2;
353
+ const ym = (y012 + y123) / 2;
354
+ flattenCubic(out, x0, y0, x01, y01, x012, y012, xm, ym, toleranceSq, depth + 1);
355
+ flattenCubic(out, xm, ym, x123, y123, x23, y23, x1, y1, toleranceSq, depth + 1);
356
+ }
357
+ function flattenQuadratic(out, x0, y0, cx, cy, x1, y1, toleranceSq, depth) {
358
+ const dx = x1 - x0;
359
+ const dy = y1 - y0;
360
+ const lengthSq = dx * dx + dy * dy;
361
+ let distSq;
362
+ if (lengthSq === 0) {
363
+ const ax = cx - x0;
364
+ const ay = cy - y0;
365
+ distSq = ax * ax + ay * ay;
366
+ }
367
+ else {
368
+ const cross = dx * (y0 - cy) - dy * (x0 - cx);
369
+ distSq = (cross * cross) / lengthSq;
370
+ }
371
+ if (depth >= MAX_SUBDIVISION_DEPTH || distSq <= toleranceSq) {
372
+ out.push(x1, y1);
373
+ return;
374
+ }
375
+ const x01 = (x0 + cx) / 2;
376
+ const y01 = (y0 + cy) / 2;
377
+ const x12 = (cx + x1) / 2;
378
+ const y12 = (cy + y1) / 2;
379
+ const xm = (x01 + x12) / 2;
380
+ const ym = (y01 + y12) / 2;
381
+ flattenQuadratic(out, x0, y0, x01, y01, xm, ym, toleranceSq, depth + 1);
382
+ flattenQuadratic(out, xm, ym, x12, y12, x1, y1, toleranceSq, depth + 1);
383
+ }
384
+ // Generates the stroke outline for one subpath polyline.
385
+ function strokeSubpath(pts, closed, halfWidth, join, cap, miterLimit, out, tolerance) {
386
+ const n = pts.length >> 1;
387
+ if (n < 2)
388
+ return;
389
+ // Build left and right offset contours.
390
+ const left = [];
391
+ const right = [];
392
+ // Normals for each segment.
393
+ const normals = new Array((n - 1) * 2);
394
+ for (let i = 0; i < n - 1; i++) {
395
+ const dx = pts[(i + 1) * 2] - pts[i * 2];
396
+ const dy = pts[(i + 1) * 2 + 1] - pts[i * 2 + 1];
397
+ const len = Math.sqrt(dx * dx + dy * dy);
398
+ if (len > 0) {
399
+ normals[i * 2] = -dy / len;
400
+ normals[i * 2 + 1] = dx / len;
401
+ }
402
+ else {
403
+ normals[i * 2] = i > 0 ? normals[(i - 1) * 2] : 0;
404
+ normals[i * 2 + 1] = i > 0 ? normals[(i - 1) * 2 + 1] : 1;
405
+ }
406
+ }
407
+ if (closed) {
408
+ // For closed paths: add join at every vertex.
409
+ for (let i = 0; i < n - 1; i++) {
410
+ const prev = (i + n - 2) % (n - 1);
411
+ const curr = i;
412
+ const nx0 = normals[prev * 2];
413
+ const ny0 = normals[prev * 2 + 1];
414
+ const nx1 = normals[curr * 2];
415
+ const ny1 = normals[curr * 2 + 1];
416
+ addJoin(pts[i * 2], pts[i * 2 + 1], nx0, ny0, nx1, ny1, halfWidth, join, miterLimit, left, right, tolerance);
417
+ }
418
+ }
419
+ else {
420
+ // Start cap. The segment direction for the first segment points "forward"; for the start cap we
421
+ // need the perpendicular (left normal at the first point) and the segment direction itself so
422
+ // square/round caps can extend outward.
423
+ const sn0x = normals[0];
424
+ const sn0y = normals[1];
425
+ // Segment direction (forward): perpendicular to left normal = (sn0y, -sn0x).
426
+ // But for start cap we extend BACKWARD: (-sn0y, sn0x).
427
+ addCap(pts[0], pts[1], sn0x, sn0y, -sn0y, sn0x, halfWidth, cap, left, right, tolerance, true);
428
+ // Inner joins.
429
+ for (let i = 1; i < n - 1; i++) {
430
+ const nx0 = normals[(i - 1) * 2];
431
+ const ny0 = normals[(i - 1) * 2 + 1];
432
+ const nx1 = normals[i * 2];
433
+ const ny1 = normals[i * 2 + 1];
434
+ addJoin(pts[i * 2], pts[i * 2 + 1], nx0, ny0, nx1, ny1, halfWidth, join, miterLimit, left, right, tolerance);
435
+ }
436
+ // End cap. Extend FORWARD: (sn_last_y, -sn_last_x).
437
+ const snLx = normals[(n - 2) * 2];
438
+ const snLy = normals[(n - 2) * 2 + 1];
439
+ addCap(pts[(n - 1) * 2], pts[(n - 1) * 2 + 1], snLx, snLy, snLy, -snLx, halfWidth, cap, left, right, tolerance, false);
440
+ }
441
+ // Emit the outline as a single closed path: left side forward, right side backward.
442
+ if (left.length < 4)
443
+ return;
444
+ out.commands.push(PathCommand.MOVE_TO);
445
+ out.data.push(left[0], left[1]);
446
+ for (let i = 2; i < left.length; i += 2) {
447
+ out.commands.push(PathCommand.LINE_TO);
448
+ out.data.push(left[i], left[i + 1]);
449
+ }
450
+ // Traverse right side in reverse.
451
+ for (let i = right.length - 2; i >= 0; i -= 2) {
452
+ out.commands.push(PathCommand.LINE_TO);
453
+ out.data.push(right[i], right[i + 1]);
454
+ }
455
+ appendPathClose(out);
456
+ }
457
+ const MAX_SUBDIVISION_DEPTH = 16;
458
+ //# sourceMappingURL=strokePath.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"strokePath.js","sourceRoot":"","sources":["../src/strokePath.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Path, PathMesh } from '@flighthq/types';
2
+ export declare function tessellatePath(path: Readonly<Path>, tolerance?: number): PathMesh;
3
+ //# sourceMappingURL=tessellatePath.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tessellatePath.d.ts","sourceRoot":"","sources":["../src/tessellatePath.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAStD,wBAAgB,cAAc,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,SAAO,GAAG,QAAQ,CAQ/E"}
@@ -0,0 +1,107 @@
1
+ import { flattenPath } from './flattenPath';
2
+ // Triangulates a path's fill into a PathMesh by flattening its curves, then ear-clipping each contour.
3
+ // This is the direct-fill route (draw the mesh, MSAA the edges) — the parallel to flatten + stencil
4
+ // cover. Each contour is triangulated independently as a simple polygon: concave outlines are handled,
5
+ // but holes/overlap/self-intersection are NOT subtracted here (a hole contour fills solid). Use the
6
+ // flatten + stencil-then-cover route for those. Winding rule is not consulted by this triangulator.
7
+ export function tessellatePath(path, tolerance = 0.25) {
8
+ const contours = flattenPath(path, tolerance);
9
+ const vertices = [];
10
+ const indices = [];
11
+ for (let i = 0; i < contours.length; i++) {
12
+ tessellateContour(contours[i], vertices, indices);
13
+ }
14
+ return { vertices, indices };
15
+ }
16
+ // Ear-clips one simple polygon contour (flat x,y pairs) into the shared vertex/index buffers. Vertices
17
+ // are appended in source order; the working order is normalized to CCW for the convexity test.
18
+ function tessellateContour(source, vertices, indices) {
19
+ // Drop coincident consecutive points (zero-length edges) into `pts` first. A duplicate vertex makes a
20
+ // degenerate corner that is never a valid ear, which stalls the clip loop and leaves the polygon only
21
+ // partly triangulated — common when an outline repeats its start point (moveTo P then lineTo P).
22
+ const pts = [];
23
+ for (let i = 0; i < source.length; i += 2) {
24
+ const x = source[i];
25
+ const y = source[i + 1];
26
+ if (pts.length >= 2 && pts[pts.length - 2] === x && pts[pts.length - 1] === y)
27
+ continue;
28
+ pts.push(x, y);
29
+ }
30
+ const contour = pts;
31
+ let count = contour.length >> 1;
32
+ // Drop a trailing point coincident with the first (an explicitly closed contour).
33
+ if (count >= 2 && contour[0] === contour[(count - 1) * 2] && contour[1] === contour[(count - 1) * 2 + 1]) {
34
+ count -= 1;
35
+ }
36
+ if (count < 3)
37
+ return;
38
+ const base = vertices.length >> 1;
39
+ for (let i = 0; i < count; i++) {
40
+ vertices.push(contour[i * 2], contour[i * 2 + 1]);
41
+ }
42
+ let twiceArea = 0;
43
+ for (let i = 0; i < count; i++) {
44
+ const j = (i + 1) % count;
45
+ twiceArea += contour[i * 2] * contour[j * 2 + 1] - contour[j * 2] * contour[i * 2 + 1];
46
+ }
47
+ // Working ring of contour-vertex indices, normalized to counter-clockwise so a positive cross
48
+ // product means a convex (ear-candidate) vertex.
49
+ const ring = [];
50
+ if (twiceArea < 0) {
51
+ for (let i = count - 1; i >= 0; i--)
52
+ ring.push(i);
53
+ }
54
+ else {
55
+ for (let i = 0; i < count; i++)
56
+ ring.push(i);
57
+ }
58
+ let guard = ring.length * ring.length;
59
+ while (ring.length > 3 && guard-- > 0) {
60
+ let clipped = false;
61
+ for (let i = 0; i < ring.length; i++) {
62
+ const a = ring[(i + ring.length - 1) % ring.length];
63
+ const b = ring[i];
64
+ const c = ring[(i + 1) % ring.length];
65
+ if (isEar(contour, ring, a, b, c)) {
66
+ indices.push(base + a, base + b, base + c);
67
+ ring.splice(i, 1);
68
+ clipped = true;
69
+ break;
70
+ }
71
+ }
72
+ if (!clipped)
73
+ break; // degenerate (e.g. self-intersection); stop rather than spin
74
+ }
75
+ if (ring.length === 3) {
76
+ indices.push(base + ring[0], base + ring[1], base + ring[2]);
77
+ }
78
+ }
79
+ // True when triangle (a,b,c) is a convex corner (CCW) containing no other ring vertex.
80
+ function isEar(contour, ring, a, b, c) {
81
+ const ax = contour[a * 2];
82
+ const ay = contour[a * 2 + 1];
83
+ const bx = contour[b * 2];
84
+ const by = contour[b * 2 + 1];
85
+ const cx = contour[c * 2];
86
+ const cy = contour[c * 2 + 1];
87
+ // Reflex or collinear corner is not an ear.
88
+ if ((bx - ax) * (cy - by) - (by - ay) * (cx - bx) <= 0)
89
+ return false;
90
+ for (let i = 0; i < ring.length; i++) {
91
+ const p = ring[i];
92
+ if (p === a || p === b || p === c)
93
+ continue;
94
+ if (isPointInTriangle(contour[p * 2], contour[p * 2 + 1], ax, ay, bx, by, cx, cy))
95
+ return false;
96
+ }
97
+ return true;
98
+ }
99
+ function isPointInTriangle(px, py, ax, ay, bx, by, cx, cy) {
100
+ const d1 = (px - bx) * (ay - by) - (ax - bx) * (py - by);
101
+ const d2 = (px - cx) * (by - cy) - (bx - cx) * (py - cy);
102
+ const d3 = (px - ax) * (cy - ay) - (cx - ax) * (py - ay);
103
+ const hasNegative = d1 < 0 || d2 < 0 || d3 < 0;
104
+ const hasPositive = d1 > 0 || d2 > 0 || d3 > 0;
105
+ return !(hasNegative && hasPositive);
106
+ }
107
+ //# sourceMappingURL=tessellatePath.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tessellatePath.js","sourceRoot":"","sources":["../src/tessellatePath.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Path, PathMeshTyped } from '@flighthq/types';
2
+ export declare function tessellatePathTyped(path: Readonly<Path>, tolerance?: number): PathMeshTyped;
3
+ //# sourceMappingURL=tessellatePathTyped.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tessellatePathTyped.d.ts","sourceRoot":"","sources":["../src/tessellatePathTyped.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAO3D,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,SAAO,GAAG,aAAa,CAMzF"}
@@ -0,0 +1,12 @@
1
+ import { tessellatePath } from './tessellatePath';
2
+ // Triangulates a path's fill into a `PathMeshTyped` using `Float32Array` vertices and `Uint32Array`
3
+ // indices, ready for zero-copy GPU buffer upload. Internally delegates to `tessellatePath` and
4
+ // copies the result into typed arrays. Use `tessellatePath` directly if `number[]` buffers suffice.
5
+ export function tessellatePathTyped(path, tolerance = 0.25) {
6
+ const mesh = tessellatePath(path, tolerance);
7
+ return {
8
+ vertices: new Float32Array(mesh.vertices),
9
+ indices: new Uint32Array(mesh.indices),
10
+ };
11
+ }
12
+ //# sourceMappingURL=tessellatePathTyped.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tessellatePathTyped.js","sourceRoot":"","sources":["../src/tessellatePathTyped.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,oGAAoG;AACpG,+FAA+F;AAC/F,oGAAoG;AACpG,MAAM,UAAU,mBAAmB,CAAC,IAAoB,EAAE,SAAS,GAAG,IAAI;IACxE,MAAM,IAAI,GAAG,cAAc,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAC7C,OAAO;QACL,QAAQ,EAAE,IAAI,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC;QACzC,OAAO,EAAE,IAAI,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC;KACvC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { MatrixLike, Path } from '@flighthq/types';
2
+ export declare function transformPath(source: Readonly<Path>, matrix: Readonly<MatrixLike>, out: Path): void;
3
+ export declare function translatePath(source: Readonly<Path>, dx: number, dy: number, out: Path): void;
4
+ //# sourceMappingURL=transformPath.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transformPath.d.ts","sourceRoot":"","sources":["../src/transformPath.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAWxD,wBAAgB,aAAa,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,EAAE,GAAG,EAAE,IAAI,GAAG,IAAI,CA4CnG;AAID,wBAAgB,aAAa,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,GAAG,IAAI,CAE7F"}