@flighthq/shape 0.3.0-next.1297.43a5ef8 → 0.3.0-next.1315.1d4eb64

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.
@@ -0,0 +1,3 @@
1
+ import type { Path, StrokeStyle } from '@flighthq/types/contract';
2
+ export declare function compactStrokePath(path: Readonly<Path>, style: Readonly<StrokeStyle>, tolerance?: number): Path;
3
+ //# sourceMappingURL=compactStrokePath.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compactStrokePath.d.ts","sourceRoot":"","sources":["../src/compactStrokePath.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAalE,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,SAAO,GAAG,IAAI,CAsB5G"}
@@ -0,0 +1,462 @@
1
+ import { appendPathClose } from '@flighthq/path/contract';
2
+ import { PathCommand } from '@flighthq/types/contract';
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 compactStrokePath(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
+ // Miter point = intersection of the two left-side offset lines. Each passes through its
121
+ // offset endpoint along the segment tangent — perpendicular to that segment's normal, so
122
+ // tangent0 = (ny0, -nx0). Advancing along the NORMAL (nx0, ny0) instead collapsed a symmetric
123
+ // corner's miter onto the centerline vertex, yielding a self-intersecting (untessellatable)
124
+ // outline. Solve P0 + s·T0 = P1 + u·T1 for the left miter, then mirror through the vertex.
125
+ const dx = lx1 - lx0;
126
+ const dy = ly1 - ly0;
127
+ const t = -(dx * nx1 + dy * ny1) / cross;
128
+ const mx = lx0 + t * ny0;
129
+ const my = ly0 - t * nx0;
130
+ const miterLen = Math.sqrt((mx - px) * (mx - px) + (my - py) * (my - py));
131
+ if (miterLen <= halfWidth * miterLimit) {
132
+ left.push(mx, my);
133
+ // Miter on the other side (mirror through center).
134
+ const rmx = px * 2 - mx;
135
+ const rmy = py * 2 - my;
136
+ right.push(rmx, rmy);
137
+ }
138
+ else {
139
+ // Degrade to bevel.
140
+ left.push(lx0, ly0, lx1, ly1);
141
+ right.push(rx0, ry0, rx1, ry1);
142
+ }
143
+ }
144
+ }
145
+ else if (join === 'round') {
146
+ // Round join: arc from (lx0,ly0) to (lx1,ly1) around the outer side.
147
+ left.push(lx0, ly0);
148
+ addArcPoints(px, py, halfWidth, Math.atan2(ny0, nx0), Math.atan2(ny1, nx1), true, tolerance, left);
149
+ left.push(lx1, ly1);
150
+ right.push(rx0, ry0);
151
+ addArcPoints(px, py, halfWidth, Math.atan2(-ny0, -nx0), Math.atan2(-ny1, -nx1), false, tolerance, right);
152
+ right.push(rx1, ry1);
153
+ }
154
+ else {
155
+ // Bevel: two points per side.
156
+ left.push(lx0, ly0, lx1, ly1);
157
+ right.push(rx0, ry0, rx1, ry1);
158
+ }
159
+ }
160
+ // Splits a subpath into dash segments based on the dash pattern.
161
+ function applyDash(pts, closed, dash, dashOffset) {
162
+ const result = [];
163
+ if (dash.length === 0) {
164
+ result.push({ points: pts, closed });
165
+ return result;
166
+ }
167
+ const totalDashLength = dash.reduce((s, d) => s + d, 0);
168
+ if (totalDashLength <= 0) {
169
+ result.push({ points: pts, closed });
170
+ return result;
171
+ }
172
+ // Normalize offset into the pattern.
173
+ const offset = ((dashOffset % totalDashLength) + totalDashLength) % totalDashLength;
174
+ // Find starting dash index and remaining length in that dash.
175
+ let dashIndex = 0;
176
+ let remaining = 0;
177
+ let isOn = true;
178
+ {
179
+ let acc = 0;
180
+ for (let i = 0; i < dash.length; i++) {
181
+ if (acc + dash[i] > offset) {
182
+ dashIndex = i;
183
+ remaining = dash[i] - (offset - acc);
184
+ isOn = i % 2 === 0;
185
+ break;
186
+ }
187
+ acc += dash[i];
188
+ }
189
+ }
190
+ let current = null;
191
+ const n = pts.length >> 1;
192
+ for (let i = 0; i < n - 1; i++) {
193
+ const x0 = pts[i * 2];
194
+ const y0 = pts[i * 2 + 1];
195
+ const x1 = pts[(i + 1) * 2];
196
+ const y1 = pts[(i + 1) * 2 + 1];
197
+ const dx = x1 - x0;
198
+ const dy = y1 - y0;
199
+ const segLen = Math.sqrt(dx * dx + dy * dy);
200
+ if (isOn && current === null) {
201
+ current = [x0, y0];
202
+ }
203
+ let consumed = 0;
204
+ while (consumed < segLen) {
205
+ const step = Math.min(remaining, segLen - consumed);
206
+ const t = (consumed + step) / segLen;
207
+ const ix = x0 + t * dx;
208
+ const iy = y0 + t * dy;
209
+ if (isOn) {
210
+ if (current === null)
211
+ current = [x0 + (consumed / segLen) * dx, y0 + (consumed / segLen) * dy];
212
+ current.push(ix, iy);
213
+ }
214
+ else {
215
+ if (current !== null) {
216
+ if (current.length >= 4)
217
+ result.push({ points: current, closed: false });
218
+ current = null;
219
+ }
220
+ if (step >= remaining) {
221
+ current = [ix, iy];
222
+ }
223
+ }
224
+ consumed += step;
225
+ remaining -= step;
226
+ if (remaining <= 1e-10) {
227
+ dashIndex = (dashIndex + 1) % dash.length;
228
+ remaining = dash[dashIndex];
229
+ isOn = dashIndex % 2 === 0;
230
+ if (isOn && current === null) {
231
+ current = [ix, iy];
232
+ }
233
+ else if (!isOn && current !== null) {
234
+ if (current.length >= 4)
235
+ result.push({ points: current, closed: false });
236
+ current = null;
237
+ }
238
+ }
239
+ }
240
+ }
241
+ if (current !== null && current.length >= 4) {
242
+ result.push({ points: current, closed: false });
243
+ }
244
+ return result;
245
+ }
246
+ function decodeSubpaths(path, tolerance) {
247
+ // Use the flattenPath internal logic (re-implemented here to track closed-ness per subpath
248
+ // and to avoid returning separate contours without their closed flag).
249
+ const commands = path.commands;
250
+ const data = path.data;
251
+ const toleranceSq = tolerance * tolerance;
252
+ const subpaths = [];
253
+ let current = null;
254
+ let x = 0;
255
+ let y = 0;
256
+ let contourStartX = 0;
257
+ let contourStartY = 0;
258
+ let di = 0;
259
+ const ensureCurrent = () => {
260
+ if (current === null) {
261
+ current = { points: [0, 0], closed: false };
262
+ subpaths.push(current);
263
+ x = 0;
264
+ y = 0;
265
+ }
266
+ return current;
267
+ };
268
+ for (let ci = 0; ci < commands.length; ci++) {
269
+ const command = commands[ci];
270
+ if (command === PathCommand.MOVE_TO) {
271
+ x = data[di];
272
+ y = data[di + 1];
273
+ di += 2;
274
+ contourStartX = x;
275
+ contourStartY = y;
276
+ current = { points: [x, y], closed: false };
277
+ subpaths.push(current);
278
+ }
279
+ else if (command === PathCommand.WIDE_MOVE_TO) {
280
+ x = data[di + 2];
281
+ y = data[di + 3];
282
+ di += 4;
283
+ contourStartX = x;
284
+ contourStartY = y;
285
+ current = { points: [x, y], closed: false };
286
+ subpaths.push(current);
287
+ }
288
+ else if (command === PathCommand.LINE_TO) {
289
+ const sp = ensureCurrent();
290
+ x = data[di];
291
+ y = data[di + 1];
292
+ di += 2;
293
+ sp.points.push(x, y);
294
+ }
295
+ else if (command === PathCommand.WIDE_LINE_TO) {
296
+ const sp = ensureCurrent();
297
+ x = data[di + 2];
298
+ y = data[di + 3];
299
+ di += 4;
300
+ sp.points.push(x, y);
301
+ }
302
+ else if (command === PathCommand.CURVE_TO) {
303
+ const sp = ensureCurrent();
304
+ flattenQuadratic(sp.points, x, y, data[di], data[di + 1], data[di + 2], data[di + 3], toleranceSq, 0);
305
+ x = data[di + 2];
306
+ y = data[di + 3];
307
+ di += 4;
308
+ }
309
+ else if (command === PathCommand.CUBIC_CURVE_TO) {
310
+ const sp = ensureCurrent();
311
+ flattenCubic(sp.points, x, y, data[di], data[di + 1], data[di + 2], data[di + 3], data[di + 4], data[di + 5], toleranceSq, 0);
312
+ x = data[di + 4];
313
+ y = data[di + 5];
314
+ di += 6;
315
+ }
316
+ else if (command === PathCommand.CLOSE) {
317
+ if (current !== null) {
318
+ current.closed = true;
319
+ x = contourStartX;
320
+ y = contourStartY;
321
+ current = null;
322
+ }
323
+ }
324
+ }
325
+ return subpaths;
326
+ }
327
+ function distChordSq(px, py, x0, y0, x1, y1) {
328
+ const dx = x1 - x0;
329
+ const dy = y1 - y0;
330
+ const lenSq = dx * dx + dy * dy;
331
+ if (lenSq === 0) {
332
+ const ax = px - x0;
333
+ const ay = py - y0;
334
+ return ax * ax + ay * ay;
335
+ }
336
+ const cross = dx * (y0 - py) - dy * (x0 - px);
337
+ return (cross * cross) / lenSq;
338
+ }
339
+ function flattenCubic(out, x0, y0, c1x, c1y, c2x, c2y, x1, y1, toleranceSq, depth) {
340
+ const dxc1 = distChordSq(c1x, c1y, x0, y0, x1, y1);
341
+ const dxc2 = distChordSq(c2x, c2y, x0, y0, x1, y1);
342
+ if (depth >= MAX_SUBDIVISION_DEPTH || (dxc1 <= toleranceSq && dxc2 <= toleranceSq)) {
343
+ out.push(x1, y1);
344
+ return;
345
+ }
346
+ const x01 = (x0 + c1x) / 2;
347
+ const y01 = (y0 + c1y) / 2;
348
+ const x12 = (c1x + c2x) / 2;
349
+ const y12 = (c1y + c2y) / 2;
350
+ const x23 = (c2x + x1) / 2;
351
+ const y23 = (c2y + y1) / 2;
352
+ const x012 = (x01 + x12) / 2;
353
+ const y012 = (y01 + y12) / 2;
354
+ const x123 = (x12 + x23) / 2;
355
+ const y123 = (y12 + y23) / 2;
356
+ const xm = (x012 + x123) / 2;
357
+ const ym = (y012 + y123) / 2;
358
+ flattenCubic(out, x0, y0, x01, y01, x012, y012, xm, ym, toleranceSq, depth + 1);
359
+ flattenCubic(out, xm, ym, x123, y123, x23, y23, x1, y1, toleranceSq, depth + 1);
360
+ }
361
+ function flattenQuadratic(out, x0, y0, cx, cy, x1, y1, toleranceSq, depth) {
362
+ const dx = x1 - x0;
363
+ const dy = y1 - y0;
364
+ const lengthSq = dx * dx + dy * dy;
365
+ let distSq;
366
+ if (lengthSq === 0) {
367
+ const ax = cx - x0;
368
+ const ay = cy - y0;
369
+ distSq = ax * ax + ay * ay;
370
+ }
371
+ else {
372
+ const cross = dx * (y0 - cy) - dy * (x0 - cx);
373
+ distSq = (cross * cross) / lengthSq;
374
+ }
375
+ if (depth >= MAX_SUBDIVISION_DEPTH || distSq <= toleranceSq) {
376
+ out.push(x1, y1);
377
+ return;
378
+ }
379
+ const x01 = (x0 + cx) / 2;
380
+ const y01 = (y0 + cy) / 2;
381
+ const x12 = (cx + x1) / 2;
382
+ const y12 = (cy + y1) / 2;
383
+ const xm = (x01 + x12) / 2;
384
+ const ym = (y01 + y12) / 2;
385
+ flattenQuadratic(out, x0, y0, x01, y01, xm, ym, toleranceSq, depth + 1);
386
+ flattenQuadratic(out, xm, ym, x12, y12, x1, y1, toleranceSq, depth + 1);
387
+ }
388
+ // Generates the stroke outline for one subpath polyline.
389
+ function strokeSubpath(pts, closed, halfWidth, join, cap, miterLimit, out, tolerance) {
390
+ const n = pts.length >> 1;
391
+ if (n < 2)
392
+ return;
393
+ // Build left and right offset contours.
394
+ const left = [];
395
+ const right = [];
396
+ // Normals for each segment.
397
+ const normals = new Array((n - 1) * 2);
398
+ for (let i = 0; i < n - 1; i++) {
399
+ const dx = pts[(i + 1) * 2] - pts[i * 2];
400
+ const dy = pts[(i + 1) * 2 + 1] - pts[i * 2 + 1];
401
+ const len = Math.sqrt(dx * dx + dy * dy);
402
+ if (len > 0) {
403
+ normals[i * 2] = -dy / len;
404
+ normals[i * 2 + 1] = dx / len;
405
+ }
406
+ else {
407
+ normals[i * 2] = i > 0 ? normals[(i - 1) * 2] : 0;
408
+ normals[i * 2 + 1] = i > 0 ? normals[(i - 1) * 2 + 1] : 1;
409
+ }
410
+ }
411
+ if (closed) {
412
+ // For closed paths: add join at every vertex.
413
+ for (let i = 0; i < n - 1; i++) {
414
+ const prev = (i + n - 2) % (n - 1);
415
+ const curr = i;
416
+ const nx0 = normals[prev * 2];
417
+ const ny0 = normals[prev * 2 + 1];
418
+ const nx1 = normals[curr * 2];
419
+ const ny1 = normals[curr * 2 + 1];
420
+ addJoin(pts[i * 2], pts[i * 2 + 1], nx0, ny0, nx1, ny1, halfWidth, join, miterLimit, left, right, tolerance);
421
+ }
422
+ }
423
+ else {
424
+ // Start cap. The segment direction for the first segment points "forward"; for the start cap we
425
+ // need the perpendicular (left normal at the first point) and the segment direction itself so
426
+ // square/round caps can extend outward.
427
+ const sn0x = normals[0];
428
+ const sn0y = normals[1];
429
+ // Segment direction (forward): perpendicular to left normal = (sn0y, -sn0x).
430
+ // But for start cap we extend BACKWARD: (-sn0y, sn0x).
431
+ addCap(pts[0], pts[1], sn0x, sn0y, -sn0y, sn0x, halfWidth, cap, left, right, tolerance, true);
432
+ // Inner joins.
433
+ for (let i = 1; i < n - 1; i++) {
434
+ const nx0 = normals[(i - 1) * 2];
435
+ const ny0 = normals[(i - 1) * 2 + 1];
436
+ const nx1 = normals[i * 2];
437
+ const ny1 = normals[i * 2 + 1];
438
+ addJoin(pts[i * 2], pts[i * 2 + 1], nx0, ny0, nx1, ny1, halfWidth, join, miterLimit, left, right, tolerance);
439
+ }
440
+ // End cap. Extend FORWARD: (sn_last_y, -sn_last_x).
441
+ const snLx = normals[(n - 2) * 2];
442
+ const snLy = normals[(n - 2) * 2 + 1];
443
+ addCap(pts[(n - 1) * 2], pts[(n - 1) * 2 + 1], snLx, snLy, snLy, -snLx, halfWidth, cap, left, right, tolerance, false);
444
+ }
445
+ // Emit the outline as a single closed path: left side forward, right side backward.
446
+ if (left.length < 4)
447
+ return;
448
+ out.commands.push(PathCommand.MOVE_TO);
449
+ out.data.push(left[0], left[1]);
450
+ for (let i = 2; i < left.length; i += 2) {
451
+ out.commands.push(PathCommand.LINE_TO);
452
+ out.data.push(left[i], left[i + 1]);
453
+ }
454
+ // Traverse right side in reverse.
455
+ for (let i = right.length - 2; i >= 0; i -= 2) {
456
+ out.commands.push(PathCommand.LINE_TO);
457
+ out.data.push(right[i], right[i + 1]);
458
+ }
459
+ appendPathClose(out);
460
+ }
461
+ const MAX_SUBDIVISION_DEPTH = 16;
462
+ //# sourceMappingURL=compactStrokePath.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compactStrokePath.js","sourceRoot":"","sources":["../src/compactStrokePath.ts"],"names":[],"mappings":"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"}
@@ -3,6 +3,7 @@ export * from './shape';
3
3
  export * from './shapeCommands';
4
4
  export * from './shapeFill';
5
5
  export * from './shapeStroke';
6
+ export * from './shapeStrokeOutline';
6
7
  export * from './shapeHitTestBuiltins';
7
8
  export * from './shapeHitTestRegistry';
8
9
  //# sourceMappingURL=contract.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,SAAS,CAAC;AACxB,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC"}
1
+ {"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,SAAS,CAAC;AACxB,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC"}
package/dist/contract.js CHANGED
@@ -3,6 +3,7 @@ export * from './shape';
3
3
  export * from './shapeCommands';
4
4
  export * from './shapeFill';
5
5
  export * from './shapeStroke';
6
+ export * from './shapeStrokeOutline';
6
7
  export * from './shapeHitTestBuiltins';
7
8
  export * from './shapeHitTestRegistry';
8
9
  //# sourceMappingURL=contract.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"contract.js","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,SAAS,CAAC;AACxB,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC"}
1
+ {"version":3,"file":"contract.js","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,SAAS,CAAC;AACxB,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export { PathCommand, appendShapeArc, appendShapeArcTo, appendShapeBeginTextureFill, appendShapeBeginFill, appendShapeBeginGradientFill, appendShapeCircle, appendShapeCubicCurveTo, appendShapeCurveTo, appendShapeDrawTriangles, appendShapeEllipse, appendShapeEndFill, appendShapeGeometryCommand, appendShapeLineTextureStyle, appendShapeLineGradientStyle, appendShapeLineStyle, appendShapeLineTo, appendShapeMoveTo, appendShapePath, appendShapePolygon, appendShapePolyline, appendShapeRectangle, appendShapeRoundRectangle, appendShapeRoundRectangleVarying, clearShapeCommands, computeShapeLocalBoundsRectangle, copyShapeCommands, createScale9Shape, createShape, enableShapeHitTesting, getPathCommandOperandCount, getShapeBounds, getShapeCommandCount, getShapeFillRegions, getShapeStrokeRegions, hasNonSolidShapeFill, hasNonSolidShapeStroke, hasShapeFill, hitTestShapeCommandPoint, isShapeEmpty, registerShapeHitTestCommand, } from './contract';
1
+ export { PathCommand, appendShapeArc, appendShapeArcTo, appendShapeBeginTextureFill, appendShapeBeginFill, appendShapeBeginGradientFill, appendShapeCircle, appendShapeCubicCurveTo, appendShapeCurveTo, appendShapeDrawTriangles, appendShapeEllipse, appendShapeEndFill, appendShapeGeometryCommand, appendShapeLineTextureStyle, appendShapeLineGradientStyle, appendShapeLineStyle, appendShapeLineTo, appendShapeMoveTo, appendShapePath, appendShapePolygon, appendShapePolyline, appendShapeRectangle, appendShapeRoundRectangle, appendShapeRoundRectangleVarying, clearShapeCommands, computeShapeLocalBoundsRectangle, copyShapeCommands, createScale9Shape, createShape, enableShapeHitTesting, getPathCommandOperandCount, getShapeBounds, getShapeCommandCount, getShapeFillRegions, getShapeStrokeRegions, getShapeStrokeOutlineRegions, hasNonSolidShapeFill, hasNonSolidShapeStroke, hasShapeFill, hitTestShapeCommandPoint, isShapeEmpty, registerShapeHitTestCommand, } from './contract';
2
2
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,cAAc,EACd,gBAAgB,EAChB,2BAA2B,EAC3B,oBAAoB,EACpB,4BAA4B,EAC5B,iBAAiB,EACjB,uBAAuB,EACvB,kBAAkB,EAClB,wBAAwB,EACxB,kBAAkB,EAClB,kBAAkB,EAClB,0BAA0B,EAC1B,2BAA2B,EAC3B,4BAA4B,EAC5B,oBAAoB,EACpB,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,EACpB,yBAAyB,EACzB,gCAAgC,EAChC,kBAAkB,EAClB,gCAAgC,EAChC,iBAAiB,EACjB,iBAAiB,EACjB,WAAW,EACX,qBAAqB,EACrB,0BAA0B,EAC1B,cAAc,EACd,oBAAoB,EACpB,mBAAmB,EACnB,qBAAqB,EACrB,oBAAoB,EACpB,sBAAsB,EACtB,YAAY,EACZ,wBAAwB,EACxB,YAAY,EACZ,2BAA2B,GAC5B,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,cAAc,EACd,gBAAgB,EAChB,2BAA2B,EAC3B,oBAAoB,EACpB,4BAA4B,EAC5B,iBAAiB,EACjB,uBAAuB,EACvB,kBAAkB,EAClB,wBAAwB,EACxB,kBAAkB,EAClB,kBAAkB,EAClB,0BAA0B,EAC1B,2BAA2B,EAC3B,4BAA4B,EAC5B,oBAAoB,EACpB,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,EACpB,yBAAyB,EACzB,gCAAgC,EAChC,kBAAkB,EAClB,gCAAgC,EAChC,iBAAiB,EACjB,iBAAiB,EACjB,WAAW,EACX,qBAAqB,EACrB,0BAA0B,EAC1B,cAAc,EACd,oBAAoB,EACpB,mBAAmB,EACnB,qBAAqB,EACrB,4BAA4B,EAC5B,oBAAoB,EACpB,sBAAsB,EACtB,YAAY,EACZ,wBAAwB,EACxB,YAAY,EACZ,2BAA2B,GAC5B,MAAM,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- export { PathCommand, appendShapeArc, appendShapeArcTo, appendShapeBeginTextureFill, appendShapeBeginFill, appendShapeBeginGradientFill, appendShapeCircle, appendShapeCubicCurveTo, appendShapeCurveTo, appendShapeDrawTriangles, appendShapeEllipse, appendShapeEndFill, appendShapeGeometryCommand, appendShapeLineTextureStyle, appendShapeLineGradientStyle, appendShapeLineStyle, appendShapeLineTo, appendShapeMoveTo, appendShapePath, appendShapePolygon, appendShapePolyline, appendShapeRectangle, appendShapeRoundRectangle, appendShapeRoundRectangleVarying, clearShapeCommands, computeShapeLocalBoundsRectangle, copyShapeCommands, createScale9Shape, createShape, enableShapeHitTesting, getPathCommandOperandCount, getShapeBounds, getShapeCommandCount, getShapeFillRegions, getShapeStrokeRegions, hasNonSolidShapeFill, hasNonSolidShapeStroke, hasShapeFill, hitTestShapeCommandPoint, isShapeEmpty, registerShapeHitTestCommand, } from './contract';
1
+ export { PathCommand, appendShapeArc, appendShapeArcTo, appendShapeBeginTextureFill, appendShapeBeginFill, appendShapeBeginGradientFill, appendShapeCircle, appendShapeCubicCurveTo, appendShapeCurveTo, appendShapeDrawTriangles, appendShapeEllipse, appendShapeEndFill, appendShapeGeometryCommand, appendShapeLineTextureStyle, appendShapeLineGradientStyle, appendShapeLineStyle, appendShapeLineTo, appendShapeMoveTo, appendShapePath, appendShapePolygon, appendShapePolyline, appendShapeRectangle, appendShapeRoundRectangle, appendShapeRoundRectangleVarying, clearShapeCommands, computeShapeLocalBoundsRectangle, copyShapeCommands, createScale9Shape, createShape, enableShapeHitTesting, getPathCommandOperandCount, getShapeBounds, getShapeCommandCount, getShapeFillRegions, getShapeStrokeRegions, getShapeStrokeOutlineRegions, hasNonSolidShapeFill, hasNonSolidShapeStroke, hasShapeFill, hitTestShapeCommandPoint, isShapeEmpty, registerShapeHitTestCommand, } from './contract';
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,cAAc,EACd,gBAAgB,EAChB,2BAA2B,EAC3B,oBAAoB,EACpB,4BAA4B,EAC5B,iBAAiB,EACjB,uBAAuB,EACvB,kBAAkB,EAClB,wBAAwB,EACxB,kBAAkB,EAClB,kBAAkB,EAClB,0BAA0B,EAC1B,2BAA2B,EAC3B,4BAA4B,EAC5B,oBAAoB,EACpB,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,EACpB,yBAAyB,EACzB,gCAAgC,EAChC,kBAAkB,EAClB,gCAAgC,EAChC,iBAAiB,EACjB,iBAAiB,EACjB,WAAW,EACX,qBAAqB,EACrB,0BAA0B,EAC1B,cAAc,EACd,oBAAoB,EACpB,mBAAmB,EACnB,qBAAqB,EACrB,oBAAoB,EACpB,sBAAsB,EACtB,YAAY,EACZ,wBAAwB,EACxB,YAAY,EACZ,2BAA2B,GAC5B,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,cAAc,EACd,gBAAgB,EAChB,2BAA2B,EAC3B,oBAAoB,EACpB,4BAA4B,EAC5B,iBAAiB,EACjB,uBAAuB,EACvB,kBAAkB,EAClB,wBAAwB,EACxB,kBAAkB,EAClB,kBAAkB,EAClB,0BAA0B,EAC1B,2BAA2B,EAC3B,4BAA4B,EAC5B,oBAAoB,EACpB,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,EACpB,yBAAyB,EACzB,gCAAgC,EAChC,kBAAkB,EAClB,gCAAgC,EAChC,iBAAiB,EACjB,iBAAiB,EACjB,WAAW,EACX,qBAAqB,EACrB,0BAA0B,EAC1B,cAAc,EACd,oBAAoB,EACpB,mBAAmB,EACnB,qBAAqB,EACrB,4BAA4B,EAC5B,oBAAoB,EACpB,sBAAsB,EACtB,YAAY,EACZ,wBAAwB,EACxB,YAAY,EACZ,2BAA2B,GAC5B,MAAM,YAAY,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { ShapeCommandToken, ShapeFillRegion } from '@flighthq/types/contract';
2
+ export declare function getShapeStrokeOutlineRegions(commands: readonly ShapeCommandToken[]): ShapeFillRegion[] | null;
3
+ //# sourceMappingURL=shapeStrokeOutline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shapeStrokeOutline.d.ts","sourceRoot":"","sources":["../src/shapeStrokeOutline.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,iBAAiB,EAAE,eAAe,EAAe,MAAM,0BAA0B,CAAC;AAwBtG,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,SAAS,iBAAiB,EAAE,GAAG,eAAe,EAAE,GAAG,IAAI,CA4E7G"}
@@ -0,0 +1,164 @@
1
+ import { PathCommand } from '@flighthq/types/contract';
2
+ import { compactStrokePath } from './compactStrokePath';
3
+ import { appendShapeGeometryCommand, getPathCommandOperandCount } from './shapeFill';
4
+ // Resolves a Shape's drawing-command stream into stroke OUTLINE regions for the GPU fill path: each
5
+ // `lineStyle` span's centerline geometry is offset by the compact open-stroke kernel (real
6
+ // miter/bevel/round joins, butt/round/square caps, and dashing), emitted as a
7
+ // `ShapeFillRegion` so the renderer tessellates + fills it with the same flat-color mesh path solid
8
+ // fills use. This replaces the offscreen Canvas-2D raster-to-texture stroke fallback with
9
+ // GPU-tessellated, resolution-independent geometry (sharp when scaled, no per-shape offscreen cost,
10
+ // and no bounds-clipped miter spikes) without retaining the larger closed-ring validation kernel.
11
+ //
12
+ // Returns `null` when the shape uses a stroke the direct-fill outline route cannot express, so the
13
+ // caller falls back to the raster path: a gradient/bitmap stroke (non-solid color), or a CLOSED stroke.
14
+ // A closed stroke offsets into a hollow RING, and the tessellator fills each contour solid with no hole
15
+ // subtraction, so a ring can't be direct-filled — only an OPEN stroke's outline is a simple fillable
16
+ // polygon. Closure is decided geometrically on the accumulated centerline (a CLOSE verb, or a subpath
17
+ // whose end returns to its start — which covers self-closing rect/ellipse/circle/round-rect primitives,
18
+ // `appendShapePolygon`, a manual return-to-start polyline, and a `drawPath` carrying either), so it is
19
+ // stroke-span-aware: only geometry drawn under an active `lineStyle` reaches a centerline, so an
20
+ // unstroked closed primitive never forces the fallback. Solid open strokes only; the backend's
21
+ // explicit stroke-path-tessellation feature owns the closed-ring strip route.
22
+ export function getShapeStrokeOutlineRegions(commands) {
23
+ if (hasNonSolidShapeStroke(commands))
24
+ return null;
25
+ const regions = [];
26
+ let centerline = null; // accumulated centerline for the active stroke span
27
+ let style = null;
28
+ let color = 0;
29
+ let alpha = 1;
30
+ let penX = 0;
31
+ let penY = 0;
32
+ let deferred = false; // a stroked span closed into a ring the direct-fill route can't express
33
+ const flush = () => {
34
+ if (style === null || centerline === null || centerline.commands.length === 0)
35
+ return;
36
+ if (isCenterlineClosed(centerline)) {
37
+ deferred = true;
38
+ return;
39
+ }
40
+ const outline = compactStrokePath(centerline, style);
41
+ if (outline.commands.length > 0)
42
+ regions.push({ path: outline, color, alpha });
43
+ };
44
+ let i = 0;
45
+ while (i < commands.length) {
46
+ const name = commands[i];
47
+ const argCount = commands[i + 1];
48
+ const a = i + 2;
49
+ i = a + argCount;
50
+ if (name === 'lineStyle') {
51
+ // A new stroke style ends the previous span's outline and opens a fresh centerline.
52
+ flush();
53
+ const thickness = commands[a];
54
+ if (thickness > 0) {
55
+ color = commands[a + 1];
56
+ alpha = commands[a + 2];
57
+ const caps = commands[a + 5];
58
+ const joints = commands[a + 6];
59
+ style = {
60
+ width: thickness,
61
+ // Shape's CapsStyle 'none' is Canvas/`strokeStyle`'s 'butt'; round/square pass through.
62
+ cap: caps === 'none' ? 'butt' : caps,
63
+ join: joints,
64
+ miterLimit: commands[a + 7],
65
+ };
66
+ centerline = { commands: [], data: [], winding: 'nonZero' };
67
+ }
68
+ else {
69
+ style = null;
70
+ centerline = null;
71
+ }
72
+ }
73
+ else if (isShapeGeometryCommand(name)) {
74
+ if (centerline !== null) {
75
+ // A span whose first geometry is a lineTo/curve (no leading moveTo) begins from the current pen
76
+ // position, matching Canvas 2D stroking the running path.
77
+ if (centerline.commands.length === 0 && name !== 'moveTo') {
78
+ centerline.commands.push(PathCommand.MOVE_TO);
79
+ centerline.data.push(penX, penY);
80
+ }
81
+ appendShapeGeometryCommand(centerline, name, commands, a);
82
+ }
83
+ // Track the pen off the polyline verbs so the next span can seed from it (primitives self-start).
84
+ if (name === 'moveTo' || name === 'lineTo') {
85
+ penX = commands[a];
86
+ penY = commands[a + 1];
87
+ }
88
+ else if (name === 'curveTo') {
89
+ penX = commands[a + 2];
90
+ penY = commands[a + 3];
91
+ }
92
+ else if (name === 'cubicCurveTo') {
93
+ penX = commands[a + 4];
94
+ penY = commands[a + 5];
95
+ }
96
+ }
97
+ // Fill-style + other non-geometry commands do not affect the stroke centerline.
98
+ }
99
+ flush();
100
+ return deferred ? null : regions;
101
+ }
102
+ // True if the stream uses a stroke the GPU outline path cannot express (a gradient or bitmap stroke),
103
+ // so the caller must fall back to the raster path. A solid `lineStyle` is expressible.
104
+ function hasNonSolidShapeStroke(commands) {
105
+ let i = 0;
106
+ while (i < commands.length) {
107
+ const name = commands[i];
108
+ if (name === 'lineGradientStyle' || name === 'lineTextureStyle')
109
+ return true;
110
+ i += 2 + commands[i + 1];
111
+ }
112
+ return false;
113
+ }
114
+ // True if the centerline encloses a region — a CLOSE verb, or any subpath whose end returns to its
115
+ // start (≥2 segments so it bounds area). Such a stroke offsets into a hollow ring the direct-fill
116
+ // tessellator cannot express, so the caller defers the whole shape to raster. Walks the verb/data
117
+ // stream with getPathCommandOperandCount so CLOSE/WIDE verbs keep the data cursor aligned.
118
+ function isCenterlineClosed(path) {
119
+ const { commands, data } = path;
120
+ let d = 0;
121
+ let subStartX = 0;
122
+ let subStartY = 0;
123
+ let lastX = 0;
124
+ let lastY = 0;
125
+ let segments = 0;
126
+ const subpathReturnsToStart = () => segments >= 2 && Math.abs(lastX - subStartX) < CLOSE_EPSILON && Math.abs(lastY - subStartY) < CLOSE_EPSILON;
127
+ for (let c = 0; c < commands.length; c++) {
128
+ const verb = commands[c];
129
+ if (verb === PathCommand.CLOSE)
130
+ return true;
131
+ const n = getPathCommandOperandCount(verb);
132
+ if (verb === PathCommand.MOVE_TO || verb === PathCommand.WIDE_MOVE_TO) {
133
+ if (subpathReturnsToStart())
134
+ return true;
135
+ // A WIDE_MOVE_TO's real endpoint is its trailing (x,y) pair; MOVE_TO's is its only pair.
136
+ lastX = subStartX = data[d + n - 2];
137
+ lastY = subStartY = data[d + n - 1];
138
+ segments = 0;
139
+ }
140
+ else if (n >= 2) {
141
+ // The endpoint of LINE/CURVE/CUBIC/WIDE_LINE is its trailing (x,y) pair.
142
+ lastX = data[d + n - 2];
143
+ lastY = data[d + n - 1];
144
+ segments++;
145
+ }
146
+ d += n;
147
+ }
148
+ return subpathReturnsToStart();
149
+ }
150
+ function isShapeGeometryCommand(name) {
151
+ return (name === 'moveTo' ||
152
+ name === 'lineTo' ||
153
+ name === 'curveTo' ||
154
+ name === 'cubicCurveTo' ||
155
+ name === 'drawCircle' ||
156
+ name === 'drawEllipse' ||
157
+ name === 'drawRectangle' ||
158
+ name === 'drawRoundRectangle' ||
159
+ name === 'drawPath');
160
+ }
161
+ // Endpoint-coincidence tolerance for return-to-start closure. Authored primitives (rect/ellipse) and
162
+ // polygons re-emit their start coordinate exactly, so this only absorbs trivial float noise.
163
+ const CLOSE_EPSILON = 1e-6;
164
+ //# sourceMappingURL=shapeStrokeOutline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shapeStrokeOutline.js","sourceRoot":"","sources":["../src/shapeStrokeOutline.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flighthq/shape",
3
- "version": "0.3.0-next.1297.43a5ef8",
3
+ "version": "0.3.0-next.1315.1d4eb64",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/flighthq/flight.git",
@@ -36,11 +36,11 @@
36
36
  "clean:dist": "tsx ../../scripts/clean-package-dist.ts"
37
37
  },
38
38
  "dependencies": {
39
- "@flighthq/scene2d": "0.3.0-next.1297.43a5ef8",
40
- "@flighthq/geometry": "0.3.0-next.1297.43a5ef8",
41
- "@flighthq/node": "0.3.0-next.1297.43a5ef8",
42
- "@flighthq/path": "0.3.0-next.1297.43a5ef8",
43
- "@flighthq/types": "0.3.0-next.1297.43a5ef8"
39
+ "@flighthq/scene2d": "0.3.0-next.1315.1d4eb64",
40
+ "@flighthq/geometry": "0.3.0-next.1315.1d4eb64",
41
+ "@flighthq/node": "0.3.0-next.1315.1d4eb64",
42
+ "@flighthq/path": "0.3.0-next.1315.1d4eb64",
43
+ "@flighthq/types": "0.3.0-next.1315.1d4eb64"
44
44
  },
45
45
  "devDependencies": {
46
46
  "typescript": "^5.3.0"
@@ -0,0 +1,31 @@
1
+ import type { Path } from '@flighthq/types/contract';
2
+ import { PathCommand } from '@flighthq/types/contract';
3
+
4
+ import { compactStrokePath } from './compactStrokePath';
5
+
6
+ describe('compactStrokePath', () => {
7
+ it('converts an open centerline into a closed fill outline', () => {
8
+ const centerline: Path = {
9
+ commands: [PathCommand.MOVE_TO, PathCommand.LINE_TO],
10
+ data: [0, 0, 20, 0],
11
+ winding: 'nonZero',
12
+ };
13
+
14
+ const outline = compactStrokePath(centerline, { cap: 'square', width: 4 });
15
+
16
+ expect(outline.commands[0]).toBe(PathCommand.MOVE_TO);
17
+ expect(outline.commands.at(-1)).toBe(PathCommand.CLOSE);
18
+ expect(outline.data).toContain(-2);
19
+ expect(outline.data).toContain(22);
20
+ });
21
+
22
+ it('returns an empty path for a centerline without a segment', () => {
23
+ const centerline: Path = {
24
+ commands: [PathCommand.MOVE_TO],
25
+ data: [0, 0],
26
+ winding: 'nonZero',
27
+ };
28
+
29
+ expect(compactStrokePath(centerline, { width: 4 }).commands).toEqual([]);
30
+ });
31
+ });
@@ -0,0 +1,31 @@
1
+ import type { ShapeCommandToken } from '@flighthq/types/contract';
2
+
3
+ import { createShape } from './shape';
4
+ import { appendShapeLineStyle, appendShapeLineTo, appendShapeMoveTo, appendShapeRectangle } from './shapeCommands';
5
+ import { getShapeStrokeOutlineRegions } from './shapeStrokeOutline';
6
+
7
+ describe('getShapeStrokeOutlineRegions', () => {
8
+ it('converts a solid open stroke into a fill region with matching color and alpha', () => {
9
+ const shape = createShape();
10
+ appendShapeLineStyle(shape, 8, 0x123456, 0.5, false, 'normal', 'square', 'bevel', 4);
11
+ appendShapeMoveTo(shape, 0, 0);
12
+ appendShapeLineTo(shape, 20, 0);
13
+
14
+ const regions = getShapeStrokeOutlineRegions(shape.data.commands);
15
+
16
+ expect(regions).not.toBeNull();
17
+ expect(regions).toHaveLength(1);
18
+ expect(regions![0]).toMatchObject({ alpha: 0.5, color: 0x123456 });
19
+ expect(regions![0].path.commands.length).toBeGreaterThan(0);
20
+ });
21
+
22
+ it('defers closed and non-solid strokes to the renderer fallback', () => {
23
+ const closed = createShape();
24
+ appendShapeLineStyle(closed, 8);
25
+ appendShapeRectangle(closed, 0, 0, 20, 10);
26
+ expect(getShapeStrokeOutlineRegions(closed.data.commands)).toBeNull();
27
+
28
+ const gradient: ShapeCommandToken[] = ['lineGradientStyle', 1, 0];
29
+ expect(getShapeStrokeOutlineRegions(gradient)).toBeNull();
30
+ });
31
+ });