@weasel-js/stroke 1.14.1 → 1.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +75 -21
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -443,7 +443,7 @@ function makeSeg(ax, ay, bx, by, posA, negA, posB, negB) {
|
|
|
443
443
|
len
|
|
444
444
|
};
|
|
445
445
|
}
|
|
446
|
-
function emitJoin(segs, segBaseIdx, j, join, miterLimit, varyingThreshold, verts, idx, anchorA, anchorB, anchorT, segSrcIdx, plA, plB, plT) {
|
|
446
|
+
function emitJoin(segs, segBaseIdx, j, join, miterLimit, varyingThreshold, verts, idx, anchorA, anchorB, anchorT, segSrcIdx, plA, plB, plT, inner = -1) {
|
|
447
447
|
const a = segs[j];
|
|
448
448
|
const b = segs[(j + 1) % segs.length];
|
|
449
449
|
const aBase = segBaseIdx[j];
|
|
@@ -467,7 +467,7 @@ function emitJoin(segs, segBaseIdx, j, join, miterLimit, varyingThreshold, verts
|
|
|
467
467
|
const taperB = Math.max(...outerB) / Math.max(1e-9, Math.min(...outerB));
|
|
468
468
|
const forceBevelForVarying = taperA > varyingThreshold || taperB > varyingThreshold;
|
|
469
469
|
if (join === "bevel" || forceBevelForVarying) {
|
|
470
|
-
emitBevel(a, aOuterEnd, bOuterStart, onPositive, verts, idx, anchorA, anchorB, anchorT, cornerA, cornerB, cornerT);
|
|
470
|
+
emitBevel(a, aOuterEnd, bOuterStart, onPositive, verts, idx, anchorA, anchorB, anchorT, cornerA, cornerB, cornerT, inner);
|
|
471
471
|
return;
|
|
472
472
|
}
|
|
473
473
|
if (join === "miter") {
|
|
@@ -475,12 +475,12 @@ function emitJoin(segs, segBaseIdx, j, join, miterLimit, varyingThreshold, verts
|
|
|
475
475
|
const bOX = verts[bOuterStart * 2], bOY = verts[bOuterStart * 2 + 1];
|
|
476
476
|
const apex = lineLineIntersect(aOX, aOY, adx, ady, bOX, bOY, -bdx, -bdy);
|
|
477
477
|
if (!apex) {
|
|
478
|
-
emitBevel(a, aOuterEnd, bOuterStart, onPositive, verts, idx, anchorA, anchorB, anchorT, cornerA, cornerB, cornerT);
|
|
478
|
+
emitBevel(a, aOuterEnd, bOuterStart, onPositive, verts, idx, anchorA, anchorB, anchorT, cornerA, cornerB, cornerT, inner);
|
|
479
479
|
return;
|
|
480
480
|
}
|
|
481
481
|
const miterLen = Math.hypot(apex[0] - a.bx, apex[1] - a.by);
|
|
482
482
|
if (miterLen > miterLimit * halfAtCorner) {
|
|
483
|
-
emitBevel(a, aOuterEnd, bOuterStart, onPositive, verts, idx, anchorA, anchorB, anchorT, cornerA, cornerB, cornerT);
|
|
483
|
+
emitBevel(a, aOuterEnd, bOuterStart, onPositive, verts, idx, anchorA, anchorB, anchorT, cornerA, cornerB, cornerT, inner);
|
|
484
484
|
return;
|
|
485
485
|
}
|
|
486
486
|
const apexIdx = verts.length / 2;
|
|
@@ -488,11 +488,7 @@ function emitJoin(segs, segBaseIdx, j, join, miterLimit, varyingThreshold, verts
|
|
|
488
488
|
anchorA.push(cornerA);
|
|
489
489
|
anchorB.push(cornerB);
|
|
490
490
|
anchorT.push(cornerT);
|
|
491
|
-
const jIdx = verts
|
|
492
|
-
verts.push(a.bx, a.by);
|
|
493
|
-
anchorA.push(cornerA);
|
|
494
|
-
anchorB.push(cornerB);
|
|
495
|
-
anchorT.push(cornerT);
|
|
491
|
+
const jIdx = inner >= 0 ? inner : cornerVertex(a, verts, anchorA, anchorB, anchorT, cornerA, cornerB, cornerT);
|
|
496
492
|
if (onPositive) {
|
|
497
493
|
idx.push(aOuterEnd, apexIdx, bOuterStart);
|
|
498
494
|
idx.push(aOuterEnd, bOuterStart, jIdx);
|
|
@@ -503,18 +499,14 @@ function emitJoin(segs, segBaseIdx, j, join, miterLimit, varyingThreshold, verts
|
|
|
503
499
|
return;
|
|
504
500
|
}
|
|
505
501
|
if (join === "round") {
|
|
506
|
-
emitRoundJoin(a, aOuterEnd, bOuterStart, onPositive, verts, idx, anchorA, anchorB, anchorT, cornerA, cornerB, cornerT);
|
|
502
|
+
emitRoundJoin(a, aOuterEnd, bOuterStart, onPositive, verts, idx, anchorA, anchorB, anchorT, cornerA, cornerB, cornerT, inner);
|
|
507
503
|
return;
|
|
508
504
|
}
|
|
509
505
|
}
|
|
510
506
|
var ROUND_STEP_RAD = 10 * Math.PI / 180;
|
|
511
|
-
function emitRoundJoin(a, aOuterEnd, bOuterStart, onPositive, verts, idx, anchorA, anchorB, anchorT, cornerA, cornerB, cornerT) {
|
|
507
|
+
function emitRoundJoin(a, aOuterEnd, bOuterStart, onPositive, verts, idx, anchorA, anchorB, anchorT, cornerA, cornerB, cornerT, inner) {
|
|
512
508
|
const cx = a.bx, cy = a.by;
|
|
513
|
-
const pivotIdx = verts
|
|
514
|
-
verts.push(cx, cy);
|
|
515
|
-
anchorA.push(cornerA);
|
|
516
|
-
anchorB.push(cornerB);
|
|
517
|
-
anchorT.push(cornerT);
|
|
509
|
+
const pivotIdx = inner >= 0 ? inner : cornerVertex(a, verts, anchorA, anchorB, anchorT, cornerA, cornerB, cornerT);
|
|
518
510
|
const startX = verts[aOuterEnd * 2] - cx;
|
|
519
511
|
const startY = verts[aOuterEnd * 2 + 1] - cy;
|
|
520
512
|
const endX = verts[bOuterStart * 2] - cx;
|
|
@@ -543,14 +535,18 @@ function emitRoundJoin(a, aOuterEnd, bOuterStart, onPositive, verts, idx, anchor
|
|
|
543
535
|
if (onPositive) idx.push(prevIdx, pivotIdx, bOuterStart);
|
|
544
536
|
else idx.push(prevIdx, bOuterStart, pivotIdx);
|
|
545
537
|
}
|
|
546
|
-
function emitBevel(a, aOuterEnd, bOuterStart, onPositive, verts, idx, anchorA, anchorB, anchorT, cornerA, cornerB, cornerT) {
|
|
547
|
-
const jIdx = verts
|
|
538
|
+
function emitBevel(a, aOuterEnd, bOuterStart, onPositive, verts, idx, anchorA, anchorB, anchorT, cornerA, cornerB, cornerT, inner) {
|
|
539
|
+
const jIdx = inner >= 0 ? inner : cornerVertex(a, verts, anchorA, anchorB, anchorT, cornerA, cornerB, cornerT);
|
|
540
|
+
if (onPositive) idx.push(aOuterEnd, jIdx, bOuterStart);
|
|
541
|
+
else idx.push(aOuterEnd, bOuterStart, jIdx);
|
|
542
|
+
}
|
|
543
|
+
function cornerVertex(a, verts, anchorA, anchorB, anchorT, cornerA, cornerB, cornerT) {
|
|
544
|
+
const at = verts.length / 2;
|
|
548
545
|
verts.push(a.bx, a.by);
|
|
549
546
|
anchorA.push(cornerA);
|
|
550
547
|
anchorB.push(cornerB);
|
|
551
548
|
anchorT.push(cornerT);
|
|
552
|
-
|
|
553
|
-
else idx.push(aOuterEnd, bOuterStart, jIdx);
|
|
549
|
+
return at;
|
|
554
550
|
}
|
|
555
551
|
function lineLineIntersect(apx, apy, adx, ady, bpx, bpy, bdx, bdy) {
|
|
556
552
|
const denom = adx * bdy - ady * bdx;
|
|
@@ -559,6 +555,63 @@ function lineLineIntersect(apx, apy, adx, ady, bpx, bpy, bdx, bdy) {
|
|
|
559
555
|
return [apx + t * adx, apy + t * ady];
|
|
560
556
|
}
|
|
561
557
|
|
|
558
|
+
// src/tessellate/innerJoins.ts
|
|
559
|
+
function meetInnerEdges(segs, segBaseIdx, closed, verts) {
|
|
560
|
+
const n = segs.length;
|
|
561
|
+
const joins = closed ? n : n - 1;
|
|
562
|
+
const meets = [];
|
|
563
|
+
for (let j = 0; j < joins; j++) meets.push(meetAt(segs, segBaseIdx, j, verts));
|
|
564
|
+
for (let changed = true; changed; ) {
|
|
565
|
+
changed = false;
|
|
566
|
+
for (let k = 0; k < n; k++) {
|
|
567
|
+
const before = k > 0 || closed ? meets[(k - 1 + n) % n] ?? null : null;
|
|
568
|
+
const after = k < joins ? meets[k] : null;
|
|
569
|
+
if (before && after && before.side === after.side && before.u > after.s) {
|
|
570
|
+
meets[(k - 1 + n) % n] = null;
|
|
571
|
+
meets[k] = null;
|
|
572
|
+
changed = true;
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
const pivots = [];
|
|
577
|
+
for (let j = 0; j < joins; j++) {
|
|
578
|
+
const m = meets[j];
|
|
579
|
+
if (!m) {
|
|
580
|
+
pivots.push(-1);
|
|
581
|
+
continue;
|
|
582
|
+
}
|
|
583
|
+
const aEnd = segBaseIdx[j] + 2 + m.side;
|
|
584
|
+
const bStart = segBaseIdx[(j + 1) % n] + m.side;
|
|
585
|
+
verts[aEnd * 2] = m.x;
|
|
586
|
+
verts[aEnd * 2 + 1] = m.y;
|
|
587
|
+
verts[bStart * 2] = m.x;
|
|
588
|
+
verts[bStart * 2 + 1] = m.y;
|
|
589
|
+
pivots.push(aEnd);
|
|
590
|
+
}
|
|
591
|
+
return pivots;
|
|
592
|
+
}
|
|
593
|
+
function meetAt(segs, segBaseIdx, j, verts) {
|
|
594
|
+
const a = segs[j];
|
|
595
|
+
const b = segs[(j + 1) % segs.length];
|
|
596
|
+
const cross = (a.bx - a.ax) * (b.by - b.ay) - (a.by - a.ay) * (b.bx - b.ax);
|
|
597
|
+
if (cross === 0) return null;
|
|
598
|
+
const side = cross > 0 ? 0 : 1;
|
|
599
|
+
const aBase = segBaseIdx[j], bBase = segBaseIdx[(j + 1) % segs.length];
|
|
600
|
+
const p0x = verts[(aBase + side) * 2], p0y = verts[(aBase + side) * 2 + 1];
|
|
601
|
+
const p1x = verts[(aBase + 2 + side) * 2], p1y = verts[(aBase + 2 + side) * 2 + 1];
|
|
602
|
+
const q0x = verts[(bBase + side) * 2], q0y = verts[(bBase + side) * 2 + 1];
|
|
603
|
+
const q1x = verts[(bBase + 2 + side) * 2], q1y = verts[(bBase + 2 + side) * 2 + 1];
|
|
604
|
+
const rx = p1x - p0x, ry = p1y - p0y;
|
|
605
|
+
const qx = q1x - q0x, qy = q1y - q0y;
|
|
606
|
+
const den = rx * qy - ry * qx;
|
|
607
|
+
if (den === 0) return null;
|
|
608
|
+
const dx = q0x - p0x, dy = q0y - p0y;
|
|
609
|
+
const s = (dx * qy - dy * qx) / den;
|
|
610
|
+
const u = (dx * ry - dy * rx) / den;
|
|
611
|
+
if (!(s > 0 && s <= 1 && u >= 0 && u < 1)) return null;
|
|
612
|
+
return { side, x: p0x + rx * s, y: p0y + ry * s, s, u };
|
|
613
|
+
}
|
|
614
|
+
|
|
562
615
|
// src/tessellate/stroke.ts
|
|
563
616
|
var EMPTY_MESH = {
|
|
564
617
|
vertices: new Float32Array(0),
|
|
@@ -676,8 +729,9 @@ function expandPolyline(pl, width, join, cap, miterLimit, varyingThreshold, vert
|
|
|
676
729
|
idx.push(base, base + 1, base + 2, base + 1, base + 3, base + 2);
|
|
677
730
|
}
|
|
678
731
|
const joinCount = pl.closed ? segs.length : segs.length - 1;
|
|
732
|
+
const inner = meetInnerEdges(segs, segBaseIdx, pl.closed, verts);
|
|
679
733
|
for (let j = 0; j < joinCount; j++) {
|
|
680
|
-
emitJoin(segs, segBaseIdx, j, join, miterLimit, varyingThreshold, verts, idx, anchorA, anchorB, anchorT, segSrcIdx, plA, plB, plT);
|
|
734
|
+
emitJoin(segs, segBaseIdx, j, join, miterLimit, varyingThreshold, verts, idx, anchorA, anchorB, anchorT, segSrcIdx, plA, plB, plT, inner[j]);
|
|
681
735
|
}
|
|
682
736
|
if (!pl.closed && cap !== "butt") {
|
|
683
737
|
const first = segs[0];
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/tessellate/dash.ts","../src/tessellate/nib.ts","../src/tessellate/vertexWidths.ts","../src/tessellate/flattening.ts","../src/tessellate/metric.ts","../src/tessellate/insets.ts","../src/tessellate/ribbon.ts","../src/tessellate/stroke.ts","../src/markerInset.ts","../src/markerSites.ts","../src/markerHeads.ts","../src/strokeEdge.ts","../src/strokeToPath.ts","../src/offsetPath.ts"],"names":["len","extractPolylines","resolveScreenLength","reach","j","pathUnion","pathSubtract"],"mappings":"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","file":"index.js","sourcesContent":["import type { Path } from '@weasel-js/geom';\nimport { anchorParamsBetween, extractPolylines, type Polyline } from '@weasel-js/geom/tessellate';\nimport { dashPattern } from '@weasel-js/paint';\n\n/** One \"on\" run being collected: points with their anchor params and, when\n * the source carries them, widths. */\ninterface Run {\n pts: number[];\n a: number[];\n b: number[];\n t: number[];\n w: number[] | null;\n o: number[] | null;\n}\n\n/** One point of the source walk, or a point between two of them. */\ninterface At {\n x: number; y: number;\n a: number; b: number; t: number;\n w: number;\n o: number;\n}\n\nfunction runFrom(p: At, widths: boolean, offsets: boolean): Run {\n return { pts: [p.x, p.y], a: [p.a], b: [p.b], t: [p.t], w: widths ? [p.w] : null, o: offsets ? [p.o] : null };\n}\n\nfunction extend(run: Run, p: At): void {\n run.pts.push(p.x, p.y); run.a.push(p.a); run.b.push(p.b); run.t.push(p.t);\n run.w?.push(p.w);\n run.o?.push(p.o);\n}\n\nfunction toPolyline(run: Run, closed = false): Polyline {\n const pl: Polyline = {\n points: run.pts,\n closed,\n anchorA: new Uint32Array(run.a),\n anchorB: new Uint32Array(run.b),\n anchorT: new Float32Array(run.t),\n };\n if (run.w) pl.widths = new Float32Array(run.w);\n if (run.o) pl.offsets = new Float32Array(run.o);\n return pl;\n}\n\n/**\n * The dashed runs of every polyline of one path. Whether the pattern is too\n * fine to dash is decided once for the whole path, as a PDF reader's own\n * stroke operator would, so no subpath goes solid while its neighbor dashes.\n */\nexport function dashPolylines(polylines: readonly Polyline[], pattern: readonly number[] | undefined): Polyline[] {\n const dash = dashPattern(pattern, totalLength(polylines));\n if (dash === 'solid') return [...polylines];\n if (dash === 'non-finite') return [];\n return polylines.flatMap((pl) => splitForDash(pl, dash));\n}\n\n/**\n * The length a dash pattern runs along `path`, every subpath included: what a\n * writer handing the dash to another stroker passes to `dashPattern`.\n */\nexport function dashLength(path: Path): number {\n return totalLength(extractPolylines(path));\n}\n\nfunction totalLength(polylines: readonly Polyline[]): number {\n return polylines.reduce((sum, pl) => sum + polylineLength(pl), 0);\n}\n\n/** The length `splitForDash` walks, the closing segment included. */\nfunction polylineLength(pl: Polyline): number {\n const p = pl.points;\n const n = p.length / 2;\n let len = 0;\n for (let i = 1; i < n; i++) len += Math.hypot(p[i * 2] - p[i * 2 - 2], p[i * 2 + 1] - p[i * 2 - 1]);\n if (pl.closed && n > 1) len += Math.hypot(p[0] - p[n * 2 - 2], p[1] - p[n * 2 - 1]);\n return len;\n}\n\n/**\n * Split a polyline into open sub-polylines for the \"on\" portions of a dash\n * pattern. Each output sub-polyline gets caps from the stroke's `cap` setting.\n * The \"off\" portions become invisible gaps. Anchor params and per-point\n * widths and offsets are carried through: a dash boundary landing mid-segment takes\n * {@link anchorParamsBetween}'s params and the width interpolated there.\n * A dash {@link dashPattern} reads as solid along `pl` returns `pl` whole,\n * and a non-finite one returns nothing.\n */\nexport function splitForDash(pl: Polyline, pattern: readonly number[]): Polyline[] {\n const dash = dashPattern(pattern, polylineLength(pl));\n if (dash === 'solid') return [pl];\n if (dash === 'non-finite') return [];\n const out: Polyline[] = [];\n const ptCount = pl.points.length / 2;\n const plA = pl.anchorA ?? new Uint32Array(ptCount);\n const plB = pl.anchorB ?? new Uint32Array(ptCount);\n const plT = pl.anchorT ?? new Float32Array(ptCount);\n const W = pl.widths;\n const O = pl.offsets;\n const pointAt = (i: number): At => ({\n x: pl.points[i * 2], y: pl.points[i * 2 + 1], a: plA[i], b: plB[i], t: plT[i], w: W ? W[i] : 0, o: O ? O[i] : 0,\n });\n\n let dashIdx = 0;\n let dashRemaining = dash[0];\n let onPhase = true;\n let cur: Run | null = runFrom(pointAt(0), !!W, !!O);\n\n const flushAndAdvance = (at: At) => {\n if (cur && cur.pts.length >= 4) out.push(toPolyline(cur));\n dashIdx = (dashIdx + 1) % dash.length;\n dashRemaining = dash[dashIdx];\n onPhase = !onPhase;\n cur = onPhase ? runFrom(at, !!W, !!O) : null;\n };\n\n let prevX = pl.points[0], prevY = pl.points[1];\n const segCount = pl.closed ? ptCount : ptCount - 1;\n\n for (let i = 0; i < segCount; i++) {\n const start = pointAt(i);\n const end = pointAt((i + 1) % ptCount);\n const segFullLen = Math.hypot(end.x - prevX, end.y - prevY);\n // A coincident point still carries its width, as a nib's corner does.\n if (segFullLen <= 1e-9) {\n if (onPhase && cur) extend(cur, end);\n continue;\n }\n let segLen = segFullLen;\n let traveled = 0;\n\n while (segLen > 1e-9) {\n if (segLen <= dashRemaining) {\n if (onPhase && cur) extend(cur, end);\n dashRemaining -= segLen;\n prevX = end.x; prevY = end.y;\n segLen = 0;\n if (dashRemaining <= 1e-9) flushAndAdvance(end);\n } else {\n traveled += dashRemaining;\n const frac = traveled / segFullLen;\n const [a, b, t] = anchorParamsBetween(start.a, start.b, start.t, end.a, end.b, end.t, frac);\n const mid: At = {\n x: start.x + (end.x - start.x) * frac, y: start.y + (end.y - start.y) * frac,\n a, b, t, w: start.w + (end.w - start.w) * frac, o: start.o + (end.o - start.o) * frac,\n };\n if (onPhase && cur) extend(cur, mid);\n prevX = mid.x; prevY = mid.y;\n segLen = Math.hypot(end.x - prevX, end.y - prevY);\n flushAndAdvance(mid);\n }\n }\n }\n\n const tail: Run | null = cur;\n if (tail && tail.pts.length >= 4) closeOut(pl, tail, out);\n return out;\n}\n\n/**\n * Push the run still open at the end of the walk. A closed subpath's walk ends\n * at the vertex it started from, so the run still open there and the run that\n * started there are one dash. Pushed separately they are two butt-capped\n * ribbons meeting at the seam — the visible artifact whenever the pattern\n * doesn't divide the perimeter.\n */\nfunction closeOut(pl: Polyline, tail: Run, out: Polyline[]): void {\n const tx = tail.pts[tail.pts.length - 2], ty = tail.pts[tail.pts.length - 1];\n const meets = (x: number, y: number) => Math.hypot(tx - x, ty - y) <= 1e-9;\n if (pl.closed && out.length > 0 && meets(out[0].points[0], out[0].points[1])) {\n out[0] = joinAtSeam(toPolyline(tail), out[0]);\n } else if (pl.closed && out.length === 0 && meets(tail.pts[0], tail.pts[1])) {\n // Every gap fell outside the perimeter: the dash is the whole loop, and\n // a loop stroked as an open run seams at its own start vertex too.\n out.push(toPolyline({\n pts: tail.pts.slice(0, -2), a: tail.a.slice(0, -1), b: tail.b.slice(0, -1), t: tail.t.slice(0, -1),\n w: tail.w ? tail.w.slice(0, -1) : null, o: tail.o ? tail.o.slice(0, -1) : null,\n }, true));\n } else {\n out.push(toPolyline(tail));\n }\n}\n\n/** `tail` continued by `head`, which starts where `tail` ends — the shared\n * vertex is carried once. */\nfunction joinAtSeam(tail: Polyline, head: Polyline): Polyline {\n const pl: Polyline = {\n points: [...tail.points, ...head.points.slice(2)],\n closed: false,\n anchorA: Uint32Array.from([...tail.anchorA!, ...head.anchorA!.subarray(1)]),\n anchorB: Uint32Array.from([...tail.anchorB!, ...head.anchorB!.subarray(1)]),\n anchorT: Float32Array.from([...tail.anchorT!, ...head.anchorT!.subarray(1)]),\n };\n if (tail.widths && head.widths) pl.widths = Float32Array.from([...tail.widths, ...head.widths.subarray(1)]);\n if (tail.offsets && head.offsets) pl.offsets = Float32Array.from([...tail.offsets, ...head.offsets.subarray(1)]);\n return pl;\n}\n","import type { Polyline } from '@weasel-js/geom/tessellate';\nimport type { StrokeNib } from '@weasel-js/paint';\nimport type { WidthScale } from './vertexWidths';\n\n/**\n * What a nib does to a stroke's width moving along the unit direction\n * `(tx, ty)`: an elliptical pen whose long axis is the nib's edge, `1` moving\n * across it and `nib.ratio` moving along it. `angle` is counterclockwise on a\n * y-down screen, so the edge points along `(cos, -sin)`.\n */\nexport function nibWidthScale(nib: StrokeNib): WidthScale {\n const ex = Math.cos(nib.angle), ey = -Math.sin(nib.angle);\n const r = Math.min(1, Math.max(0, nib.ratio));\n return (tx, ty) => {\n const across = ex * ty - ey * tx;\n const along = ex * tx + ey * ty;\n return Math.sqrt(across * across + r * r * along * along);\n };\n}\n\n/**\n * Scale `pl`'s widths (its own, or `base` where it has none), and each side's\n * share of them, by the nib at\n * each segment's direction. A corner takes two coincident points, the end of\n * the segment into it and the start of the one out, so each side of a join\n * keeps its own width; the ribbon drops the zero-length span between them.\n * Mutates `pl`.\n */\nexport function applyNib(pl: Polyline, nib: StrokeNib, base: number): void {\n const n = pl.points.length / 2;\n if (n < 2) return;\n const P = pl.points;\n const scale = nibWidthScale(nib);\n const segCount = pl.closed ? n : n - 1;\n const factors: number[] = [];\n for (let i = 0; i < segCount; i++) {\n const j = (i + 1) % n;\n const dx = P[j * 2] - P[i * 2], dy = P[j * 2 + 1] - P[i * 2 + 1];\n const len = Math.hypot(dx, dy);\n factors.push(len > 0 ? scale(dx / len, dy / len) : NaN);\n }\n // A zero-length segment takes the direction of the one before it.\n for (let i = 0; i < segCount; i++) {\n if (Number.isNaN(factors[i])) factors[i] = i > 0 ? factors[i - 1] : (factors.find((f) => !Number.isNaN(f)) ?? 1);\n }\n const A = pl.anchorA, B = pl.anchorB, T = pl.anchorT, W = pl.widths, O = pl.offsets;\n const pts: number[] = [], aA: number[] = [], aB: number[] = [], aT: number[] = [], ws: number[] = [], os: number[] = [];\n const push = (i: number, factor: number) => {\n pts.push(P[i * 2], P[i * 2 + 1]);\n aA.push(A ? A[i] : 0); aB.push(B ? B[i] : 0); aT.push(T ? T[i] : 0);\n ws.push((W ? W[i] : base) * factor);\n if (O) os.push(O[i] * factor);\n };\n push(0, factors[0]);\n for (let i = 1; i < n; i++) {\n push(i, factors[i - 1]);\n if (i < segCount) push(i, factors[i]);\n }\n if (pl.closed) push(0, factors[segCount - 1]);\n pl.points = pts;\n pl.anchorA = Uint32Array.from(aA);\n pl.anchorB = Uint32Array.from(aB);\n pl.anchorT = Float32Array.from(aT);\n pl.widths = Float32Array.from(ws);\n if (O) pl.offsets = Float32Array.from(os);\n}\n","import type { Polyline } from '@weasel-js/geom/tessellate';\nimport { type StrokeNib, type VertexWidth, vertexHalfWidths, widestHalfWidth } from '@weasel-js/paint';\nimport { applyNib } from './nib';\n\n/** What one unit of a `vertexWidths` entry measures across the line at a\n * point whose unit tangent, in the polyline's own space, is `(tx, ty)`. */\nexport type WidthScale = (tx: number, ty: number) => number;\n\n/** Fill `pl.widths` by interpolating `vertexWidths` across each point's\n * (anchorA, anchorB, anchorT), each side of the path on its own, and\n * `pl.offsets` where the two sides differ. Anchor-aligned points (A === B)\n * read the anchor's value directly. Entries resolve through\n * `vertexHalfWidths`, so a missing one takes `fallbackWidth`. Given `scale`,\n * each entry is scaled at the point that reads it, and the fallback is not. */\nexport function populatePolylineWidths(\n pl: Polyline,\n vertexWidths: readonly VertexWidth[],\n fallbackWidth: number,\n scale?: WidthScale,\n): void {\n const ptCount = pl.points.length / 2;\n if (ptCount === 0) return;\n const aA = pl.anchorA ?? new Uint32Array(ptCount);\n const aB = pl.anchorB ?? new Uint32Array(ptCount);\n const aT = pl.anchorT ?? new Float32Array(ptCount);\n const widths = new Float32Array(ptCount);\n const offsets = new Float32Array(ptCount);\n let sided = false;\n const fallback = fallbackWidth / 2;\n let k = 1;\n // A fallback side is not scaled: it is the stroke's own width.\n const sides = (i: number): [number, number] => {\n const h = vertexHalfWidths(vertexWidths[i], NaN);\n return [Number.isNaN(h.left) ? fallback : h.left * k, Number.isNaN(h.right) ? fallback : h.right * k];\n };\n for (let i = 0; i < ptCount; i++) {\n if (scale) k = scaleAt(pl, i, scale);\n const a = aA[i], b = aB[i], t = aT[i];\n let [left, right] = sides(a);\n if (a !== b) {\n const [lb, rb] = sides(b);\n left += (lb - left) * t;\n right += (rb - right) * t;\n }\n widths[i] = left + right;\n offsets[i] = (right - left) / 2;\n if (offsets[i] !== 0) sided = true;\n }\n pl.widths = widths;\n if (sided) pl.offsets = offsets;\n}\n\n/** The widest a stroke of `width` draws: twice the farthest any edge sits\n * from the path. A nib only ever narrows it. */\nexport function widestStrokeWidth(width: number, vertexWidths: readonly VertexWidth[] | undefined): number {\n return 2 * widestHalfWidth(width, vertexWidths);\n}\n\n/** Fill `pl.widths` from whichever of `vertexWidths` and `nib` a stroke\n * sets, the nib's factor multiplying the per-vertex width. Leaves them unset\n * for a stroke of one width. */\nexport function populateWidths(\n pl: Polyline,\n vertexWidths: readonly VertexWidth[] | null,\n nib: StrokeNib | undefined,\n width: number,\n scale?: WidthScale,\n): void {\n if (vertexWidths) populatePolylineWidths(pl, vertexWidths, width, scale);\n if (nib) applyNib(pl, nib, width);\n}\n\n/** `scale` along the line's direction at point `i`: the bisector of the\n * segments either side, or the one segment at an open end. */\nfunction scaleAt(pl: Polyline, i: number, scale: WidthScale): number {\n const pts = pl.points;\n const n = pts.length / 2;\n let tx = 0, ty = 0;\n const add = (from: number, to: number) => {\n const dx = pts[to * 2] - pts[from * 2], dy = pts[to * 2 + 1] - pts[from * 2 + 1];\n const len = Math.hypot(dx, dy);\n if (len > 0) { tx += dx / len; ty += dy / len; }\n };\n if (i > 0) add(i - 1, i);\n else if (pl.closed && n > 1) add(n - 1, 0);\n if (i < n - 1) add(i, i + 1);\n else if (pl.closed && n > 1) add(n - 1, 0);\n const len = Math.hypot(tx, ty);\n return len > 0 ? scale(tx / len, ty / len) : 1;\n}\n","import { DEFAULT_FLATTEN_TOLERANCE } from '@weasel-js/geom';\nimport type { VertexWidth } from '@weasel-js/paint';\nimport type { ExtractOptions } from '@weasel-js/geom/tessellate';\nimport { widestStrokeWidth } from './vertexWidths';\n\n/**\n * How a stroke flattens its path. Every flattened vertex is a join on edges\n * half a width out, so the edges are held to the tolerance as well as the\n * path: a bend the path's tolerance passes in 40° steps reads as facets once\n * the stroke is thick. A stroke no wider than twice the tolerance keeps the\n * fill's vertices exactly: finer ones could leave a gap between its inner edge\n * and the fill's chords, which a wider one covers.\n */\nexport function strokeFlattening(\n flattenTolerance: number | undefined,\n width: number,\n vertexWidths?: readonly VertexWidth[],\n): ExtractOptions {\n const tolerance = flattenTolerance ?? DEFAULT_FLATTEN_TOLERANCE;\n const widest = widestStrokeWidth(width, vertexWidths);\n return widest / 2 > tolerance ? { flattenTolerance, offset: widest / 2 } : { flattenTolerance };\n}\n","/**\n * The space a screen-pixel stroke is built in.\n *\n * A `{ px }` stroke is exact on screen only when its ribbon is offset in a\n * space that measures lengths the way the screen does. The transform's linear\n * part is `scale · R · P`: a uniform scale, a rotation (or reflection) that\n * moves no lengths, and `P`, the symmetric unit-determinant stretch left over.\n * Offsetting the ribbon after `P` and mapping it back through `P⁻¹` gives a\n * world-space mesh that the full transform turns into a ribbon of exactly\n * `width · scale` pixels in every direction — and keeps the mesh drawable by\n * every path that draws a world-space ribbon.\n *\n * `P` depends only on the lengths the transform induces (`LᵀL`), not on any\n * rotation applied after it, so a view that only pans or zooms uniformly keeps\n * the same metric and the ribbon cache keeps hitting.\n */\nimport type { Polyline } from '@weasel-js/geom/tessellate';\n\n/** `P` = [[p, q], [q, r]], with `pr − q² = 1`. */\nexport interface StrokeMetric {\n readonly p: number;\n readonly q: number;\n readonly r: number;\n}\n\n/** A space a screen-sized part of a stroke is built in: the metric, and how\n * many screen pixels one of its units is. */\nexport interface ScreenSpace {\n readonly metric: StrokeMetric;\n readonly pxPerUnit: number;\n}\n\n/**\n * Where each part of a stroke is built. An absent part is built in world:\n * everything is under a similarity, and otherwise a part whose size is a world\n * length. The ribbon is screen-sized for a `{ px }` width; a head for a\n * `{ px }` size, or for no size on a screen-sized ribbon, since it then takes\n * the stroke width.\n */\nexport interface StrokeSpaces {\n readonly ribbon?: ScreenSpace;\n readonly start?: ScreenSpace;\n readonly mid?: ScreenSpace;\n readonly end?: ScreenSpace;\n}\n\n/** A cache-key fragment naming `space`; empty for world. */\nexport function screenSpaceKey(space: ScreenSpace | undefined): string {\n return space === undefined ? '' : `${metricKey(space.metric)}@${space.pxPerUnit}`;\n}\n\n/** Below this, a stretch is a rounding error and the transform a similarity. */\nconst CONFORMAL_EPSILON = 1e-9;\n\n/**\n * Split the linear map `x' = a·x + c·y, y' = b·x + d·y` — a GL `mat3`'s\n * `m[0], m[1], m[3], m[4]` — into its geometric-mean scale and its stroke\n * metric. `metric` is `null` when the map is a similarity, where world space\n * already measures like the screen; `scale` is `0` for a singular map.\n */\nexport function strokeSpaceOf(\n a: number, b: number, c: number, d: number,\n): { scale: number; metric: StrokeMetric | null } {\n const det2 = Math.abs(a * d - b * c);\n const scale = Math.sqrt(det2);\n if (!(det2 > 0) || !Number.isFinite(det2)) return { scale: 0, metric: null };\n // G = LᵀL / det, whose determinant is 1, so √G = (G + I) / √(tr G + 2).\n const g11 = (a * a + b * b) / det2;\n const g12 = (a * c + b * d) / det2;\n const g22 = (c * c + d * d) / det2;\n const s = Math.sqrt(g11 + g22 + 2);\n const p = (g11 + 1) / s;\n const q = g12 / s;\n const r = (g22 + 1) / s;\n if (Math.abs(q) < CONFORMAL_EPSILON && Math.abs(p - r) < CONFORMAL_EPSILON) {\n return { scale, metric: null };\n }\n return { scale, metric: { p, q, r } };\n}\n\n/** A cache-key fragment naming `metric`; empty for none. */\nexport function metricKey(metric: StrokeMetric | undefined): string {\n return metric === undefined ? '' : `${metric.p},${metric.q},${metric.r}`;\n}\n\n/** Map `pl`'s points through `P`, in place. */\nexport function polylineIntoMetric(pl: Polyline, m: StrokeMetric): void {\n const pts = pl.points;\n for (let i = 0; i < pts.length; i += 2) {\n const x = pts[i], y = pts[i + 1];\n pts[i] = m.p * x + m.q * y;\n pts[i + 1] = m.q * x + m.r * y;\n }\n}\n\n/** Map `pl`'s points back out through `P⁻¹`, in place. */\nexport function polylineOutOfMetric(pl: Polyline, m: StrokeMetric): void {\n const pts = pl.points;\n for (let i = 0; i < pts.length; i += 2) {\n const x = pts[i], y = pts[i + 1];\n pts[i] = m.r * x - m.q * y;\n pts[i + 1] = m.p * y - m.q * x;\n }\n}\n\n/** Whether two spaces are the same — world being `null`. */\nexport function sameMetric(a: StrokeMetric | null, b: StrokeMetric | null): boolean {\n if (a === b) return true;\n return a !== null && b !== null && a.p === b.p && a.q === b.q && a.r === b.r;\n}\n\n/**\n * What one world unit of width, across a line running along the unit\n * direction `(tx, ty)` of the metric's own space, measures in that space.\n * `P` keeps areas, so a strip keeps its area while its length stretches by\n * `|P u|` (`u` the line's world direction): its width shrinks by the same,\n * and `1 / |P u|` is `|P⁻¹ t|`.\n */\nexport function worldWidthInMetric(m: StrokeMetric, tx: number, ty: number): number {\n return Math.hypot(m.r * tx - m.q * ty, m.p * ty - m.q * tx);\n}\n\n/** The same, for a line running along the unit world direction `(ux, uy)`. */\nexport function worldWidthInMetricAlongWorld(m: StrokeMetric, ux: number, uy: number): number {\n return 1 / Math.hypot(m.p * ux + m.q * uy, m.q * ux + m.r * uy);\n}\n\n/** Map interleaved x,y pairs back out through `P⁻¹` = [[r, −q], [−q, p]], in\n * place. */\nexport function coordsOutOfMetric(coords: Float32Array, m: StrokeMetric): void {\n for (let i = 0; i < coords.length; i += 2) {\n const x = coords[i], y = coords[i + 1];\n coords[i] = m.r * x - m.q * y;\n coords[i + 1] = m.p * y - m.q * x;\n }\n}\n\n/** Whether `P` takes an axis-aligned rect to another one. */\nexport function metricKeepsRects(m: StrokeMetric): boolean {\n return m.q === 0;\n}\n\n/** `rect` in the metric's space, while `P` keeps it axis-aligned; otherwise\n * `null`, and the rect has to be carried as a polygon. */\nexport function rectIntoMetric(\n rect: { x: number; y: number; width: number; height: number },\n m: StrokeMetric,\n): { kind: 'rect'; x: number; y: number; width: number; height: number } | null {\n if (!metricKeepsRects(m)) return null;\n return { kind: 'rect', x: m.p * rect.x, y: m.r * rect.y, width: m.p * rect.width, height: m.r * rect.height };\n}\n","/**\n * Trimming a stroke's ends where each inset is measured.\n *\n * A head stops the line by a length in the head's own space, which need not be\n * the ribbon's: a world-sized head on a `{ px }` stroke stops it a world\n * distance short, a `{ px }` head on a world-width stroke a screen distance.\n * Under a stretching view one length means different distances in the two\n * spaces depending on which way the line runs, so each end is trimmed in its\n * own space rather than converted.\n */\nimport { type Polyline, trimPolyline } from '@weasel-js/geom/tessellate';\nimport {\n type StrokeMetric, polylineIntoMetric, polylineOutOfMetric, sameMetric,\n} from './metric';\n\n/** A length along the line measured in `metric`'s space, or in world where\n * `metric` is `null`. */\nexport interface MeasuredLength {\n readonly length: number;\n readonly metric: StrokeMetric | null;\n}\n\n/** A plain number is a length in the ribbon's own space. */\nexport type InsetLength = number | MeasuredLength;\n\ninterface Trim {\n length: number;\n metric: StrokeMetric | null;\n}\n\nconst trimOf = (inset: InsetLength | undefined, ribbon: StrokeMetric | null): Trim =>\n inset === undefined ? { length: 0, metric: ribbon }\n : typeof inset === 'number' ? { length: inset, metric: ribbon }\n : inset;\n\n/**\n * `pl`, whose points are in `from`'s space, trimmed by `start` and `end` and\n * carried into `ribbon`'s — `null` for world in both. `pl` may be mapped in\n * place. Returns `null` when the insets consume the whole run.\n */\nexport function trimInSpace(\n pl: Polyline,\n from: StrokeMetric | null,\n ribbon: StrokeMetric | null,\n start: InsetLength | undefined,\n end: InsetLength | undefined,\n): Polyline | null {\n const s = trimOf(start, ribbon);\n const e = trimOf(end, ribbon);\n let cur: Polyline | null = pl;\n let space = from;\n const moveTo = (to: StrokeMetric | null) => {\n if (cur === null || sameMetric(space, to)) return;\n if (space !== null) polylineOutOfMetric(cur, space);\n if (to !== null) polylineIntoMetric(cur, to);\n space = to;\n };\n if (s.length > 0 || e.length > 0) {\n if (sameMetric(s.metric, e.metric)) {\n moveTo(s.metric);\n cur = trimPolyline(cur, s.length, e.length);\n } else {\n for (const [len, metric, atStart] of [[s.length, s.metric, true], [e.length, e.metric, false]] as const) {\n if (!(len > 0) || cur === null) continue;\n moveTo(metric);\n cur = trimPolyline(cur, atStart ? len : 0, atStart ? 0 : len);\n }\n }\n }\n moveTo(ribbon);\n return cur;\n}\n","/**\n * The pieces of a stroke ribbon: one straight segment with each edge its own\n * distance from the path at either end, and the caps and joins drawn from\n * those edges.\n */\n\nexport type Cap = 'butt' | 'round' | 'square';\nexport type Join = 'miter' | 'round' | 'bevel';\n\n/** Per-segment data the join code needs. */\nexport interface Seg {\n ax: number; ay: number;\n bx: number; by: number;\n /** Unit perpendicular (rotated 90° CCW from direction). */\n nxUnit: number; nyUnit: number;\n /** How far the edge on the +n side (`pos`) and the −n side (`neg`) sits\n * from the path at the start (a) and end (b). All equal for a uniform\n * stroke; they differ when the polyline carries per-point widths or\n * offsets. */\n posA: number; negA: number;\n posB: number; negB: number;\n len: number;\n}\n\nconst ROUND_CAP_STEP_RAD = (10 * Math.PI) / 180;\n\n/**\n * Emit a cap at one end of a segment. `leftIdx`/`rightIdx` are the buffer\n * indices of the L (perpendicular +n) and R (perpendicular -n) vertices at\n * the segment endpoint where the cap attaches, `pos` and `neg` from the path.\n * `atEnd` chooses which end of the segment to extend from (and which\n * cap-direction sign to use). The cap is centered between the two edges.\n */\nexport function emitCap(\n seg: Seg, leftIdx: number, rightIdx: number, atEnd: boolean,\n pos: number, neg: number, cap: Cap,\n verts: number[], idx: number[],\n anchorA: number[], anchorB: number[], anchorT: number[],\n endA: number, endB: number, endT: number,\n): void {\n // Outward direction = forward at end, backward at start.\n const sign = atEnd ? 1 : -1;\n const dx = (seg.bx - seg.ax) / seg.len * sign;\n const dy = (seg.by - seg.ay) / seg.len * sign;\n const half = (pos + neg) / 2;\n const shift = (pos - neg) / 2;\n const cx = (atEnd ? seg.bx : seg.ax) + seg.nxUnit * shift;\n const cy = (atEnd ? seg.by : seg.ay) + seg.nyUnit * shift;\n\n const nx = seg.nxUnit * half;\n const ny = seg.nyUnit * half;\n\n if (cap === 'square') {\n const ox = cx + dx * half;\n const oy = cy + dy * half;\n const lOut = verts.length / 2;\n verts.push(ox + nx, oy + ny);\n anchorA.push(endA); anchorB.push(endB); anchorT.push(endT);\n const rOut = verts.length / 2;\n verts.push(ox - nx, oy - ny);\n anchorA.push(endA); anchorB.push(endB); anchorT.push(endT);\n // Two triangles forming the cap rectangle. Wind so triangles are CCW\n // viewed from the front; orientation symmetric for start vs. end caps.\n if (atEnd) {\n idx.push(leftIdx, lOut, rOut, leftIdx, rOut, rightIdx);\n } else {\n idx.push(leftIdx, rOut, lOut, leftIdx, rightIdx, rOut);\n }\n return;\n }\n\n if (cap === 'round') {\n // Pivot vertex at the endpoint center; fan from L through the outward\n // 180° arc to R.\n const pivotIdx = verts.length / 2;\n verts.push(cx, cy);\n anchorA.push(endA); anchorB.push(endB); anchorT.push(endT);\n\n // Starting angle: direction from pivot to L (= +n direction).\n const startAngle = Math.atan2(ny, nx);\n // Sweep 180° toward the outward direction. The outward unit is (dx, dy);\n // we rotate from +n to -n the \"outward\" way. The dot product of (dx, dy)\n // with the perpendicular tells us which way around the arc to go.\n // A start-cap (sign = -1) sweeps backward; end-cap (sign = +1) sweeps forward.\n const sweep = atEnd ? -Math.PI : Math.PI;\n const steps = Math.max(1, Math.ceil(Math.abs(sweep) / ROUND_CAP_STEP_RAD));\n const stepAngle = sweep / steps;\n\n let prevIdx = leftIdx;\n for (let i = 1; i < steps; i++) {\n const ang = startAngle + i * stepAngle;\n const fx = cx + Math.cos(ang) * half;\n const fy = cy + Math.sin(ang) * half;\n const newIdx = verts.length / 2;\n verts.push(fx, fy);\n anchorA.push(endA); anchorB.push(endB); anchorT.push(endT);\n if (atEnd) idx.push(prevIdx, newIdx, pivotIdx);\n else idx.push(prevIdx, pivotIdx, newIdx);\n prevIdx = newIdx;\n }\n if (atEnd) idx.push(prevIdx, rightIdx, pivotIdx);\n else idx.push(prevIdx, pivotIdx, rightIdx);\n }\n}\n\nexport function makeSeg(\n ax: number, ay: number, bx: number, by: number,\n posA: number, negA: number, posB: number, negB: number,\n): Seg | null {\n const dx = bx - ax, dy = by - ay;\n const len = Math.hypot(dx, dy);\n if (len === 0) return null;\n return {\n ax, ay, bx, by,\n nxUnit: -dy / len, nyUnit: dx / len,\n posA, negA, posB, negB,\n len,\n };\n}\n\nexport function emitJoin(\n segs: Seg[], segBaseIdx: number[], j: number, join: Join,\n miterLimit: number,\n varyingThreshold: number,\n verts: number[], idx: number[],\n anchorA: number[], anchorB: number[], anchorT: number[],\n segSrcIdx: number[],\n plA: Uint32Array, plB: Uint32Array, plT: Float32Array,\n): void {\n const a = segs[j];\n const b = segs[(j + 1) % segs.length];\n const aBase = segBaseIdx[j];\n const bBase = segBaseIdx[(j + 1) % segs.length];\n\n const adx = a.bx - a.ax, ady = a.by - a.ay;\n const bdx = b.bx - b.ax, bdy = b.by - b.ay;\n const cross = adx * bdy - ady * bdx;\n if (cross === 0) return; // straight (collinear), no wedge\n const onPositive = cross > 0;\n\n const aOuterEnd = onPositive ? aBase + 3 : aBase + 2;\n const bOuterStart = onPositive ? bBase + 1 : bBase + 0;\n\n // The corner of join `j` is the start of segment `j+1` (which is the END of\n // segment `j` — they share the same polyline point). For the wraparound join\n // on a closed polyline, j+1 wraps to segment 0 whose start is the closer\n // segment's endpoint, which is polyline point 0.\n const nextSeg = (j + 1) % segs.length;\n // The corner anchor is the start of the next segment (shared endpoint).\n // For a closed path's final join, nextSeg wraps to 0, whose start is\n // polyline point 0 — correct.\n const cornerSrc = segSrcIdx[nextSeg];\n const cornerA = plA[cornerSrc];\n const cornerB = plB[cornerSrc];\n const cornerT = plT[cornerSrc];\n // The join is drawn on the outer edge: the −n side when turning toward +n.\n // Both segments agree on it at the shared corner, so either sizes the\n // miter limit. Force bevel when that edge tapers along either adjacent\n // segment by more than `varyingThreshold` — the miter apex math computes\n // against outer edges parallel to the segment direction, an assumption\n // that breaks on tapered trapezoids (outer edges fan in/out).\n const outerA = onPositive ? [a.negA, a.negB] : [a.posA, a.posB];\n const outerB = onPositive ? [b.negA, b.negB] : [b.posA, b.posB];\n const halfAtCorner = outerA[1];\n const taperA = Math.max(...outerA) / Math.max(1e-9, Math.min(...outerA));\n const taperB = Math.max(...outerB) / Math.max(1e-9, Math.min(...outerB));\n const forceBevelForVarying = taperA > varyingThreshold || taperB > varyingThreshold;\n\n if (join === 'bevel' || forceBevelForVarying) {\n emitBevel(a, aOuterEnd, bOuterStart, onPositive, verts, idx, anchorA, anchorB, anchorT, cornerA, cornerB, cornerT);\n return;\n }\n\n if (join === 'miter') {\n // Compute apex: intersection of A's outer edge extended forward and\n // B's outer edge extended backward. If miter length > MITER_LIMIT * half,\n // fall back to bevel.\n const aOX = verts[aOuterEnd * 2], aOY = verts[aOuterEnd * 2 + 1];\n const bOX = verts[bOuterStart * 2], bOY = verts[bOuterStart * 2 + 1];\n const apex = lineLineIntersect(aOX, aOY, adx, ady, bOX, bOY, -bdx, -bdy);\n if (!apex) {\n emitBevel(a, aOuterEnd, bOuterStart, onPositive, verts, idx, anchorA, anchorB, anchorT, cornerA, cornerB, cornerT);\n return;\n }\n const miterLen = Math.hypot(apex[0] - a.bx, apex[1] - a.by);\n if (miterLen > miterLimit * halfAtCorner) {\n emitBevel(a, aOuterEnd, bOuterStart, onPositive, verts, idx, anchorA, anchorB, anchorT, cornerA, cornerB, cornerT);\n return;\n }\n // A miter join's outer face is a kite quadrilateral with vertices\n // (R1, apex, R0, J) — covered by TWO triangles. The bevel inner half\n // (R1, R0, J) fills the area between the joint corner and the diagonal\n // hypotenuse R0-R1; the outer extension (R1, apex, R0) fills from the\n // hypotenuse to the apex point. Without the bevel half, an \"inverted\n // triangle\" gap opens at every miter corner.\n const apexIdx = verts.length / 2;\n verts.push(apex[0], apex[1]);\n anchorA.push(cornerA); anchorB.push(cornerB); anchorT.push(cornerT);\n const jIdx = verts.length / 2;\n verts.push(a.bx, a.by);\n anchorA.push(cornerA); anchorB.push(cornerB); anchorT.push(cornerT);\n if (onPositive) {\n idx.push(aOuterEnd, apexIdx, bOuterStart);\n idx.push(aOuterEnd, bOuterStart, jIdx);\n } else {\n idx.push(aOuterEnd, bOuterStart, apexIdx);\n idx.push(aOuterEnd, jIdx, bOuterStart);\n }\n return;\n }\n\n if (join === 'round') {\n emitRoundJoin(a, aOuterEnd, bOuterStart, onPositive, verts, idx, anchorA, anchorB, anchorT, cornerA, cornerB, cornerT);\n return;\n }\n}\n\nconst ROUND_STEP_RAD = (10 * Math.PI) / 180; // ~10° per fan triangle\n\nfunction emitRoundJoin(\n a: Seg, aOuterEnd: number, bOuterStart: number, onPositive: boolean,\n verts: number[], idx: number[],\n anchorA: number[], anchorB: number[], anchorT: number[],\n cornerA: number, cornerB: number, cornerT: number,\n): void {\n // Pivot = joint center; emit fresh vertex.\n const cx = a.bx, cy = a.by;\n const pivotIdx = verts.length / 2;\n verts.push(cx, cy);\n anchorA.push(cornerA); anchorB.push(cornerB); anchorT.push(cornerT);\n\n const startX = verts[aOuterEnd * 2] - cx;\n const startY = verts[aOuterEnd * 2 + 1] - cy;\n const endX = verts[bOuterStart * 2] - cx;\n const endY = verts[bOuterStart * 2 + 1] - cy;\n const r0 = Math.hypot(startX, startY), r1 = Math.hypot(endX, endY);\n\n const startAngle = Math.atan2(startY, startX);\n const endAngle = Math.atan2(endY, endX);\n // Outer-side sweep: for CCW turns (cross > 0, onPositive true) outer is on\n // the -n side and the arc sweeps from R1 (south of joint) clockwise to R0\n // (east of joint) — i.e., negative sweep. For CW turns, sweep is positive.\n // Pick the SHORT arc that crosses the outer wedge. For onPositive=true\n // (CW turn in screen coords with y-down), the outer wedge sits where the\n // natural sweep is positive; for onPositive=false, where it is negative.\n // If the natural sweep has the wrong sign, wrap by ±2π.\n let sweep = endAngle - startAngle;\n if (onPositive && sweep < 0) sweep += 2 * Math.PI;\n else if (!onPositive && sweep > 0) sweep -= 2 * Math.PI;\n\n const steps = Math.max(1, Math.ceil(Math.abs(sweep) / ROUND_STEP_RAD));\n const stepAngle = sweep / steps;\n\n let prevIdx = aOuterEnd;\n for (let i = 1; i < steps; i++) {\n const ang = startAngle + i * stepAngle;\n // Each side of a join can have its own width; the arc runs between them.\n const r = r0 + ((r1 - r0) * i) / steps;\n verts.push(cx + Math.cos(ang) * r, cy + Math.sin(ang) * r);\n const newIdx = verts.length / 2 - 1;\n anchorA.push(cornerA); anchorB.push(cornerB); anchorT.push(cornerT);\n if (onPositive) idx.push(prevIdx, pivotIdx, newIdx);\n else idx.push(prevIdx, newIdx, pivotIdx);\n prevIdx = newIdx;\n }\n if (onPositive) idx.push(prevIdx, pivotIdx, bOuterStart);\n else idx.push(prevIdx, bOuterStart, pivotIdx);\n}\n\nfunction emitBevel(\n a: Seg, aOuterEnd: number, bOuterStart: number, onPositive: boolean,\n verts: number[], idx: number[],\n anchorA: number[], anchorB: number[], anchorT: number[],\n cornerA: number, cornerB: number, cornerT: number,\n): void {\n const jIdx = verts.length / 2;\n verts.push(a.bx, a.by);\n anchorA.push(cornerA); anchorB.push(cornerB); anchorT.push(cornerT);\n if (onPositive) idx.push(aOuterEnd, jIdx, bOuterStart);\n else idx.push(aOuterEnd, bOuterStart, jIdx);\n}\n\n/**\n * Solve for the intersection of line A (point ap, direction ad) with line B\n * (point bp, direction bd). Returns null if parallel or near-parallel.\n */\nfunction lineLineIntersect(\n apx: number, apy: number, adx: number, ady: number,\n bpx: number, bpy: number, bdx: number, bdy: number,\n): [number, number] | null {\n const denom = adx * bdy - ady * bdx;\n if (Math.abs(denom) < 1e-9) return null;\n const t = ((bpx - apx) * bdy - (bpy - apy) * bdx) / denom;\n return [apx + t * adx, apy + t * ady];\n}\n","import { remapPerAnchor, resolveCornersWithSources, type Path } from '@weasel-js/geom';\nimport type { ScreenLength, Stroke } from '@weasel-js/paint';\nimport { alignedStrokeRect, resolveScreenLength } from '@weasel-js/paint';\nimport { type Mesh, extractPolylines, type Polyline } from '@weasel-js/geom/tessellate';\nimport { dashPolylines } from './dash';\nimport { strokeFlattening } from './flattening';\nimport { populateWidths, type WidthScale } from './vertexWidths';\nimport { type InsetLength, trimInSpace } from './insets';\nimport { type Cap, emitCap, emitJoin, type Join, makeSeg, type Seg } from './ribbon';\nimport {\n type StrokeMetric, coordsOutOfMetric, rectIntoMetric, worldWidthInMetric, worldWidthInMetricAlongWorld,\n} from './metric';\n\n/** Options for stroke tessellation. */\nexport interface StrokeOptions {\n flattenTolerance?: number;\n /**\n * Shorten each open subpath by this much at its start / end: a length in\n * the ribbon's space, or one measured in a space of its own. Stroke markers\n * use this so a filled head is not speared by its own line; the caller\n * resolves the distance, because this layer knows nothing about the marker\n * registry.\n */\n startInset?: InsetLength;\n endInset?: InsetLength;\n /**\n * Build the ribbon in this metric's space and map it back out, so the\n * transform it was derived from draws it at an exact screen width — see\n * `./metric`. Width and dash are then lengths in that space; `vertexWidths`\n * stay world widths. The path is flattened in world first, so the ribbon\n * follows the same vertices its fill does.\n */\n metric?: StrokeMetric;\n}\n\nconst EMPTY_MESH: Mesh = {\n vertices: new Float32Array(0),\n indices: new Uint32Array(0),\n anchorA: new Uint32Array(0),\n anchorB: new Uint32Array(0),\n anchorT: new Float32Array(0),\n};\n\n\n/** Resolve a stroke width to world units. A number is already world units;\n * `{ px }` is screen pixels divided by the accumulated scale, so it holds its\n * on-screen thickness as the view zooms. */\nexport function resolveStrokeWidth(width: ScreenLength, scale: number): number {\n return resolveScreenLength(width, scale);\n}\n\n/**\n * Build a triangle-mesh ribbon from a stroked Path.\n *\n * Supports:\n * - cap: 'butt' | 'round' | 'square'\n * - join: 'miter' | 'round' | 'bevel'\n * - center alignment directly; RectPath inner/outer alignment via a\n * pre-shifted rect; PolygonPath inner/outer alignment via stencil at the\n * renderer level\n * - dash splitting\n */\nexport function tessellateStroke(\n path: Path,\n stroke: Stroke,\n opts: StrokeOptions = {},\n): Mesh {\n // The renderer resolves `{ px }` against the accumulated transform before it\n // gets here; a stroke that reaches the tessellator unresolved is read at\n // scale 1, matching what the ribbon cache keys it under.\n const width = resolveStrokeWidth(stroke.width ?? 1, 1);\n if (width <= 0) return EMPTY_MESH;\n const join: Join = stroke.join ?? 'miter';\n const cap: Cap = stroke.cap ?? 'butt';\n const align = stroke.align ?? 'center';\n const miterLimit = stroke.miterLimit ?? DEFAULT_MITER_LIMIT;\n const varyingThreshold = stroke.varyingWidthJoinThreshold ?? DEFAULT_VARYING_WIDTH_JOIN_THRESHOLD;\n\n // RectPath fast path for inner/outer alignment: shift the rect by half-width\n // so the ribbon's center alignment lands the stroke on the desired side of\n // the original geometric edge. Arbitrary paths handle alignment via stencil\n // clipping at the renderer level (not here).\n const metric = opts.metric;\n const rectInMetric = metric && path.kind === 'rect' ? rectIntoMetric(path, metric) : null;\n let workingPath: Path = rectInMetric ?? path;\n if (workingPath.kind === 'rect' && align !== 'center') {\n workingPath = { kind: 'rect', ...alignedStrokeRect(workingPath, align, width) };\n }\n\n // Per-point widths come first, in the space the points are in, so a trim\n // interpolates them rather than re-reading an anchor's.\n // Expanded here rather than inside `extractPolylines`, so each width moves\n // to the anchors its corner's cut leaves.\n const resolved = workingPath.kind === 'polygon' ? resolveCornersWithSources(workingPath) : null;\n if (resolved) workingPath = resolved.path;\n const given = stroke.vertexWidths && stroke.vertexWidths.length > 0 ? stroke.vertexWidths : null;\n const vertexWidths = given && resolved?.anchorSources ? remapPerAnchor(given, resolved.anchorSources, 1) : given;\n const polylines = extractPolylines(workingPath, strokeFlattening(opts.flattenTolerance, width, vertexWidths ?? undefined));\n const scale: WidthScale | undefined = !metric ? undefined\n : rectInMetric ? (tx, ty) => worldWidthInMetric(metric, tx, ty)\n : (ux, uy) => worldWidthInMetricAlongWorld(metric, ux, uy);\n const verts: number[] = [];\n const idx: number[] = [];\n const anchorA: number[] = [];\n const anchorB: number[] = [];\n const anchorT: number[] = [];\n\n // Trim before dashing, so the dash pattern fits the visible line rather than\n // running off under a marker head.\n const ribbonSpace = metric ?? null;\n const trimmed: Polyline[] = [];\n for (const pl of polylines) {\n populateWidths(pl, vertexWidths, stroke.nib, width, scale);\n const t = trimInSpace(pl, rectInMetric ? ribbonSpace : null, ribbonSpace, opts.startInset, opts.endInset);\n if (t !== null) trimmed.push(t);\n }\n for (const sub of dashPolylines(trimmed, stroke.dash)) {\n expandPolyline(sub, width, join, cap, miterLimit, varyingThreshold, verts, idx, anchorA, anchorB, anchorT);\n }\n\n const vertices = new Float32Array(verts);\n if (metric) coordsOutOfMetric(vertices, metric);\n return {\n vertices,\n indices: new Uint32Array(idx),\n anchorA: new Uint32Array(anchorA),\n anchorB: new Uint32Array(anchorB),\n anchorT: new Float32Array(anchorT),\n ...(path.kind === 'polygon' && path.origin ? { origin: path.origin } : {}),\n };\n}\n\nfunction expandPolyline(\n pl: Polyline,\n width: number,\n join: Join,\n cap: Cap,\n miterLimit: number,\n varyingThreshold: number,\n verts: number[],\n idx: number[],\n anchorA: number[],\n anchorB: number[],\n anchorT: number[],\n): void {\n const half = width / 2;\n const pts = pl.points;\n const ptCount = pts.length / 2;\n const segCount = ptCount - 1;\n if (segCount < 1) return;\n\n // Anchor params per polyline point (set by extractPolylines; splitForDash\n // re-derives them on dash boundaries). Default to A=B=0,t=0 if missing.\n const plA = pl.anchorA ?? new Uint32Array(ptCount);\n const plB = pl.anchorB ?? new Uint32Array(ptCount);\n const plT = pl.anchorT ?? new Float32Array(ptCount);\n // Per-point distance to each edge: derived from pl.widths and pl.offsets\n // if present, else the uniform half. Indexing matches `pts`.\n const W = pl.widths, O = pl.offsets;\n const pos = (i: number) => (W ? W[i] / 2 : half) + (O ? O[i] : 0);\n const neg = (i: number) => (W ? W[i] / 2 : half) - (O ? O[i] : 0);\n\n const segs: Seg[] = [];\n const segSrcIdx: number[] = []; // For each seg, the polyline-point index of its start.\n for (let s = 0; s < segCount; s++) {\n const seg = makeSeg(pts[s * 2], pts[s * 2 + 1], pts[(s + 1) * 2], pts[(s + 1) * 2 + 1], pos(s), neg(s), pos(s + 1), neg(s + 1));\n if (seg) {\n segs.push(seg);\n segSrcIdx.push(s);\n }\n }\n let closerSrcIdx = -1;\n if (pl.closed && segs.length >= 1) {\n const last = segs[segs.length - 1];\n const first = segs[0];\n // Closer: from last point back to point 0, with the edges resolved at\n // those source indices.\n const closer = makeSeg(last.bx, last.by, first.ax, first.ay, pos(ptCount - 1), neg(ptCount - 1), pos(0), neg(0));\n if (closer) {\n segs.push(closer);\n closerSrcIdx = ptCount - 1; // start is the last polyline point.\n segSrcIdx.push(closerSrcIdx);\n }\n }\n if (segs.length === 0) return;\n\n // Emit ribbon quads. For each emitted vertex, record the (A, B, t) of the\n // source polyline point that the geometric vertex sits at. Per-end\n // half-widths produce trapezoidal segments when the stroke tapers.\n const segBaseIdx: number[] = [];\n for (let s = 0; s < segs.length; s++) {\n const seg = segs[s];\n const startSrc = segSrcIdx[s];\n // End-source index for the seg. For closer (closed-path wraparound), end is point 0.\n const endSrc = (s === segs.length - 1 && pl.closed && closerSrcIdx >= 0) ? 0 : startSrc + 1;\n const base = verts.length / 2;\n segBaseIdx.push(base);\n const { nxUnit: nx, nyUnit: ny } = seg;\n // L0, R0 — at seg.ax/ay, the +n and −n edges.\n verts.push(seg.ax + nx * seg.posA, seg.ay + ny * seg.posA);\n anchorA.push(plA[startSrc]); anchorB.push(plB[startSrc]); anchorT.push(plT[startSrc]);\n verts.push(seg.ax - nx * seg.negA, seg.ay - ny * seg.negA);\n anchorA.push(plA[startSrc]); anchorB.push(plB[startSrc]); anchorT.push(plT[startSrc]);\n // L1, R1 — at seg.bx/by.\n verts.push(seg.bx + nx * seg.posB, seg.by + ny * seg.posB);\n anchorA.push(plA[endSrc]); anchorB.push(plB[endSrc]); anchorT.push(plT[endSrc]);\n verts.push(seg.bx - nx * seg.negB, seg.by - ny * seg.negB);\n anchorA.push(plA[endSrc]); anchorB.push(plB[endSrc]); anchorT.push(plT[endSrc]);\n idx.push(base, base + 1, base + 2, base + 1, base + 3, base + 2);\n }\n\n // Joins between consecutive segments.\n const joinCount = pl.closed ? segs.length : segs.length - 1;\n for (let j = 0; j < joinCount; j++) {\n emitJoin(segs, segBaseIdx, j, join, miterLimit, varyingThreshold, verts, idx, anchorA, anchorB, anchorT, segSrcIdx, plA, plB, plT);\n }\n\n // Caps, from the local edges at each end.\n if (!pl.closed && cap !== 'butt') {\n const first = segs[0];\n const firstBase = segBaseIdx[0];\n emitCap(first, firstBase + 0, firstBase + 1, false, first.posA, first.negA, cap, verts, idx, anchorA, anchorB, anchorT, plA[0], plB[0], plT[0]);\n\n const last = segs[segs.length - 1];\n const lastBase = segBaseIdx[segs.length - 1];\n const lastSrc = segSrcIdx[segs.length - 1] + 1;\n emitCap(last, lastBase + 2, lastBase + 3, true, last.posB, last.negB, cap, verts, idx, anchorA, anchorB, anchorT, plA[lastSrc], plB[lastSrc], plT[lastSrc]);\n }\n}\n\n/**\n * Miter limit for a stroke that does not set one. SVG's default, not\n * Canvas2D's 10, because the serializer omits the attribute when the field is\n * unset — so a kit stroke exported to SVG is read back by every other renderer\n * as 4, and a kit that used 10 would disagree with its own export. 10 also\n * lets an acute corner throw a spike four times the half-width, which is what\n * a glyph outline's sharpest vertices do.\n */\nconst DEFAULT_MITER_LIMIT = 4;\n/** Default `Stroke.varyingWidthJoinThreshold`. */\nconst DEFAULT_VARYING_WIDTH_JOIN_THRESHOLD = 1.5;\n","/**\n * Resolving a `MarkerRef` to the distance the ribbon must stop short.\n *\n * The tessellation layer takes these as plain numbers and knows nothing about\n * the registry — keeping that layer free of upward dependencies is deliberate.\n * The ribbon cache, the SVG serializer and `inkReach` all resolve through here,\n * so the ribbon, the export and the hit region cannot disagree about where the\n * line ends.\n */\n\nimport { resolveScreenLength, type MarkerRef, type Stroke } from '@weasel-js/paint';\nimport { getMarker } from './strokeMarkers';\n\n/** The size of one marker unit, in the same world units as `strokeWidth`.\n * `scale` is the view scale a `{ px }` size resolves against, as a `{ px }`\n * stroke width does. */\nexport function resolveMarkerSize(ref: MarkerRef, strokeWidth: number, scale = 1): number {\n if (typeof ref === 'string' || ref.size === undefined) return strokeWidth;\n return resolveScreenLength(ref.size, scale);\n}\n\n/** The registry key a `MarkerRef` names, whether given bare or with a size. */\nexport function markerKeyOf(ref: MarkerRef): string {\n return typeof ref === 'string' ? ref : ref.key;\n}\n\n/**\n * How far back the ribbon stops for `ref`, in world units. Zero for an absent\n * marker, an unregistered key, or an open head — never throws, because an\n * unknown key is a data problem and dropping the head is the graceful answer.\n */\nexport function markerInset(ref: MarkerRef | undefined, strokeWidth: number, scale = 1): number {\n if (ref === undefined) return 0;\n const entry = getMarker(markerKeyOf(ref));\n if (entry === undefined) return 0;\n return (entry.inset ?? 0) * resolveMarkerSize(ref, strokeWidth, scale);\n}\n\n/** The start and end insets a stroke asks for. `markerMid` never insets —\n * trimming at an interior vertex would cut the line in two. */\nexport function strokeInsets(stroke: Stroke, strokeWidth: number): { start: number; end: number } {\n return {\n start: markerInset(stroke.markerStart, strokeWidth),\n end: markerInset(stroke.markerEnd, strokeWidth),\n };\n}\n","/**\n * Where a stroke's markers sit and which way they point.\n *\n * Computed from the *untrimmed* polyline: trimming moves the endpoint, and a\n * marker anchors to where the line was authored to end, not to where the\n * ribbon was cut.\n */\n\nimport type { Polyline } from '@weasel-js/geom/tessellate';\n\n/** One marker placement, in the polyline's own coordinates. */\nexport interface MarkerSite {\n x: number;\n y: number;\n /** Radians. The direction the marker's +X axis should point — outward at a\n * start or end, along the bisector at an interior vertex. */\n angle: number;\n role: 'start' | 'mid' | 'end';\n}\n\n/** Which marker roles to place. `start` and `end` are ignored on a closed polyline. */\nexport interface MarkerSiteRequest {\n start: boolean;\n mid: boolean;\n end: boolean;\n}\n\nconst EPS = 1e-9;\n\n/** Unit direction from point `i` to point `j`, or null if they coincide. */\nfunction dir(pl: Polyline, i: number, j: number): { x: number; y: number } | null {\n const dx = pl.points[j * 2] - pl.points[i * 2];\n const dy = pl.points[j * 2 + 1] - pl.points[i * 2 + 1];\n const len = Math.hypot(dx, dy);\n if (len < EPS) return null;\n return { x: dx / len, y: dy / len };\n}\n\n/** The first index after `i` whose point differs from `i`'s. */\nfunction nextDistinct(pl: Polyline, i: number, n: number): number {\n for (let k = i + 1; k < n; k++) if (dir(pl, i, k)) return k;\n return -1;\n}\nfunction prevDistinct(pl: Polyline, i: number): number {\n for (let k = i - 1; k >= 0; k--) if (dir(pl, k, i)) return k;\n return -1;\n}\n\n/**\n * Where each requested marker sits on `pl` and the angle it points at.\n * Mid sites fall only on authored vertices, never on flattened curve samples,\n * and need the polyline to carry anchor data; without it no mid sites are returned.\n */\nexport function markerSites(pl: Polyline, want: MarkerSiteRequest): MarkerSite[] {\n const out: MarkerSite[] = [];\n const n = pl.points.length / 2;\n if (n < 2) return out;\n\n if (want.start && !pl.closed) {\n const j = nextDistinct(pl, 0, n);\n const d = j >= 0 ? dir(pl, 0, j) : null;\n if (d) {\n // Reversed, so a start head points away from the line body the way an\n // end head does. SVG spells this `auto-start-reverse`; here it is the\n // only behavior.\n out.push({ x: pl.points[0], y: pl.points[1], angle: Math.atan2(-d.y, -d.x), role: 'start' });\n }\n }\n\n if (want.mid) {\n const A = pl.anchorA, B = pl.anchorB, T = pl.anchorT;\n if (A && B && T) {\n for (let i = 1; i < n - 1; i++) {\n // An authored anchor, not a flattened curve sample.\n if (A[i] !== B[i] || T[i] !== 0) continue;\n const p = prevDistinct(pl, i);\n const q = nextDistinct(pl, i, n);\n if (p < 0 || q < 0) continue;\n const inDir = dir(pl, p, i)!;\n const outDir = dir(pl, i, q)!;\n let bx = inDir.x + outDir.x;\n let by = inDir.y + outDir.y;\n // A 180° reversal leaves no bisector; fall back to the arriving direction.\n if (Math.hypot(bx, by) < EPS) { bx = inDir.x; by = inDir.y; }\n out.push({ x: pl.points[i * 2], y: pl.points[i * 2 + 1], angle: Math.atan2(by, bx), role: 'mid' });\n }\n }\n }\n\n if (want.end && !pl.closed) {\n const last = n - 1;\n const p = prevDistinct(pl, last);\n const d = p >= 0 ? dir(pl, p, last) : null;\n if (d) {\n out.push({ x: pl.points[last * 2], y: pl.points[last * 2 + 1], angle: Math.atan2(d.y, d.x), role: 'end' });\n }\n }\n\n return out;\n}\n","/**\n * A stroke's marker heads as placed geometry, and how far they reach.\n */\n\nimport type { MarkerRef, Stroke } from '@weasel-js/paint';\nimport { type Path, type PolygonPath, boundsOfPath } from '@weasel-js/geom';\nimport { extractPolylines } from '@weasel-js/geom/tessellate';\nimport { getMarker, type MarkerEntry } from './strokeMarkers';\nimport { markerKeyOf, resolveMarkerSize } from './markerInset';\nimport { markerSites, type MarkerSite } from './markerSites';\nimport { strokeFlattening } from './tessellate/flattening';\nimport {\n coordsOutOfMetric, polylineIntoMetric, type ScreenSpace, type StrokeSpaces,\n} from './tessellate/metric';\n\n/** Rotate + translate a marker's geometry onto its site, measured from\n * `origin`, the stroked path's, as the site is. */\nfunction placed(path: Path, site: MarkerSite, origin: PolygonPath['origin']): PolygonPath {\n const { origin: _own, ...src } = path as PolygonPath;\n const cos = Math.cos(site.angle);\n const sin = Math.sin(site.angle);\n const coords = new Float32Array(src.coords.length);\n for (let i = 0; i < src.coords.length; i += 2) {\n const x = src.coords[i], y = src.coords[i + 1];\n coords[i] = site.x + x * cos - y * sin;\n coords[i + 1] = site.y + x * sin + y * cos;\n }\n return origin ? { ...src, coords, origin } : { ...src, coords };\n}\n\n/** One head's placed geometry, before any paint is applied. */\nexport interface MarkerHead {\n readonly entry: MarkerEntry;\n readonly path: PolygonPath;\n readonly size: number;\n /** Where it was built, when not in world — `size` is in this space's units. */\n readonly space?: ScreenSpace;\n}\n\n/**\n * Every marker head for `path` under `stroke`, placed but unpainted.\n * `strokeWidth` is the already width-resolved stroke width; `flattenTolerance`\n * matches what the ribbon used, so heads land on the same flattened vertices\n * the stroke did. A head `spaces` puts in a screen space is placed and sized\n * there and comes back in world units, so it meets the line it caps.\n */\nexport function markerHeads(\n path: Path,\n stroke: Stroke,\n strokeWidth: number,\n flattenTolerance: number | undefined,\n spaces: StrokeSpaces = {},\n): MarkerHead[] {\n const refs = { start: stroke.markerStart, mid: stroke.markerMid, end: stroke.markerEnd };\n if (refs.start === undefined && refs.mid === undefined && refs.end === undefined) return [];\n\n // Heads sharing a space share one pass over the polyline mapped into it.\n const groups = new Map<ScreenSpace | undefined, { start: boolean; mid: boolean; end: boolean }>();\n for (const role of ['start', 'mid', 'end'] as const) {\n if (refs[role] === undefined) continue;\n const space = spaces[role];\n let want = groups.get(space);\n if (want === undefined) groups.set(space, (want = { start: false, mid: false, end: false }));\n want[role] = true;\n }\n\n const out: MarkerHead[] = [];\n const origin = path.kind === 'polygon' ? path.origin : undefined;\n for (const pl of extractPolylines(path, strokeFlattening(flattenTolerance, strokeWidth, stroke.vertexWidths))) {\n for (const [space, want] of groups) {\n const inSpace = space ? { ...pl, points: pl.points.slice() } : pl;\n if (space) polylineIntoMetric(inSpace, space.metric);\n for (const site of markerSites(inSpace, want)) {\n const ref: MarkerRef | undefined = refs[site.role];\n if (ref === undefined) continue;\n const entry = getMarker(markerKeyOf(ref));\n if (entry === undefined) continue;\n const size = resolveMarkerSize(ref, strokeWidth);\n const angle = entry.orient === undefined || entry.orient === 'auto' ? site.angle : entry.orient;\n const head = placed(entry.path({ size, stroke }), { ...site, angle }, origin);\n if (space) coordsOutOfMetric(head.coords, space.metric);\n out.push(space ? { entry, size, path: head, space } : { entry, size, path: head });\n }\n }\n }\n return out;\n}\n\n/**\n * A key for the stroke fields `entry`'s geometry reads, or `null` when the\n * entry does not say which it reads and only the stroke's identity can stand\n * in for them.\n */\nexport function markerReadsKey(entry: MarkerEntry, stroke: Stroke): string | null {\n if (entry.reads === undefined) return null;\n let key = '';\n for (const field of entry.reads) key += `${JSON.stringify(stroke[field]) ?? ''}|`;\n return key;\n}\n\n/** Distinct stroke readings kept per entry before its map is dropped. */\nconst READINGS_PER_ENTRY = 64;\n\n/** Each entry's farthest reach from its anchor at `size` 1, outline included,\n * per value of the fields it reads — or per stroke object, when it does not\n * say which. */\nconst REACH_BY_READING = new WeakMap<MarkerEntry, Map<string, number>>();\nconst REACH_BY_STROKE = new WeakMap<MarkerEntry, WeakMap<Stroke, number>>();\n\nfunction measureUnitReach(entry: MarkerEntry, stroke: Stroke): number {\n const b = boundsOfPath(entry.path({ size: 1, stroke }));\n return Math.max(Math.abs(b.x), Math.abs(b.x + b.width), Math.abs(b.y), Math.abs(b.y + b.height))\n + (entry.outline ? entry.outline.width / 2 : 0);\n}\n\nfunction unitReach(entry: MarkerEntry, stroke: Stroke): number {\n const key = markerReadsKey(entry, stroke);\n if (key === null) {\n let byStroke = REACH_BY_STROKE.get(entry);\n if (byStroke === undefined) REACH_BY_STROKE.set(entry, (byStroke = new WeakMap()));\n let reach = byStroke.get(stroke);\n if (reach === undefined) byStroke.set(stroke, (reach = measureUnitReach(entry, stroke)));\n return reach;\n }\n let byReading = REACH_BY_READING.get(entry);\n if (byReading === undefined) REACH_BY_READING.set(entry, (byReading = new Map()));\n let reach = byReading.get(key);\n if (reach === undefined) {\n if (byReading.size >= READINGS_PER_ENTRY) byReading.clear();\n byReading.set(key, (reach = measureUnitReach(entry, stroke)));\n }\n return reach;\n}\n\n/**\n * How far `stroke`'s markers can paint from the vertex each sits on, split by\n * where each is built: `world` in world units for a head with a world size,\n * `px` in screen pixels for one with a `{ px }` size. A head with no size\n * takes the stroke width, and with it the width's units. Culling and a path\n * node's grab reach both measure through here.\n */\nexport function markerReach(stroke: Stroke): { world: number; px: number } {\n const reach = { world: 0, px: 0 };\n const width = stroke.width ?? 1;\n for (const ref of [stroke.markerStart, stroke.markerMid, stroke.markerEnd]) {\n if (ref === undefined) continue;\n const entry = getMarker(markerKeyOf(ref));\n if (entry === undefined) continue;\n const size = typeof ref === 'string' || ref.size === undefined ? width : ref.size;\n const unit = unitReach(entry, stroke);\n if (typeof size === 'number') reach.world = Math.max(reach.world, unit * size);\n else reach.px = Math.max(reach.px, unit * size.px);\n }\n return reach;\n}\n","/**\n * Where a stroke's outline edge runs near a point: what an editor that drags a\n * stroke's edge hit-tests and measures against.\n */\nimport { pointInPath, type Path } from '@weasel-js/geom';\nimport { extractPolylines } from '@weasel-js/geom/tessellate';\nimport type { Stroke } from '@weasel-js/paint';\nimport { strokeFlattening } from './tessellate/flattening';\nimport { nibWidthScale } from './tessellate/nib';\nimport { resolveStrokeWidth } from './tessellate/stroke';\nimport { populateWidths } from './tessellate/vertexWidths';\n\n/** One side of a stroke's ribbon, as `VertexWidth` names them. */\nexport type StrokeSide = 'left' | 'right';\n\n/** A stroke's edge nearest a point, as {@link strokeEdgeNear} finds it. */\nexport interface StrokeEdgeHit {\n /** The point on the path's flattening the edge is measured from. */\n x: number;\n y: number;\n /** The unit normal there, pointing from the path toward the edge. */\n nx: number;\n ny: number;\n /** Which edge this is. */\n side: StrokeSide;\n /** How far each edge sits from the path there, as drawn: per-vertex widths,\n * the nib, and alignment applied. An inner or outer stroke draws one side\n * only, the other being the path itself, at 0. */\n left: number;\n right: number;\n /** How far the query point lies outside the edge; negative inside the ink. */\n gap: number;\n /** What a stored half-width is multiplied by to give the edge's distance\n * there: the nib's factor, doubled for an inner or outer stroke. */\n factor: number;\n}\n\n/** Options for {@link strokeEdgeNear}. */\nexport interface StrokeEdgeOptions {\n /** Screen pixels per world unit, for a `{ px }` width. Default 1. */\n scale?: number;\n flattenTolerance?: number;\n}\n\n/**\n * The edge of `stroke`, drawn along `path`, that passes nearest `(x, y)`,\n * measured along the path's normal: either side of a centered stroke, with\n * per-vertex widths (each side of a pair on its own) and the nib applied. An\n * inner or outer stroke is a centered one twice as wide cut to one side of the\n * path's fill, so its edge is the one on that side, at twice the distance, and\n * a point on the far side is measured to it across the ink. Caps, joins, and\n * markers are not considered. `null` when the path has no segment of any length.\n */\nexport function strokeEdgeNear(\n path: Path, stroke: Stroke, x: number, y: number, opts: StrokeEdgeOptions = {},\n): StrokeEdgeHit | null {\n const width = resolveStrokeWidth(stroke.width ?? 1, opts.scale ?? 1);\n const vw = stroke.vertexWidths && stroke.vertexWidths.length > 0 ? stroke.vertexWidths : null;\n const nibScale = stroke.nib ? nibWidthScale(stroke.nib) : null;\n const align = stroke.align ?? 'center';\n let best: StrokeEdgeHit | null = null;\n for (const pl of extractPolylines(path, strokeFlattening(opts.flattenTolerance, width, vw ?? undefined))) {\n populateWidths(pl, vw, stroke.nib, width);\n const P = pl.points, W = pl.widths, O = pl.offsets;\n const n = P.length / 2;\n const segCount = pl.closed ? n : n - 1;\n const inked = align === 'center' ? null : inkedSide(path, P, segCount, align === 'inner');\n for (let i = 0; i < segCount; i++) {\n const j = (i + 1) % n;\n const ax = P[i * 2], ay = P[i * 2 + 1];\n const dx = P[j * 2] - ax, dy = P[j * 2 + 1] - ay;\n const len2 = dx * dx + dy * dy;\n if (len2 === 0) continue;\n const len = Math.sqrt(len2);\n const f = Math.min(1, Math.max(0, ((x - ax) * dx + (y - ay) * dy) / len2));\n const fx = ax + dx * f, fy = ay + dy * f;\n const rx = -dy / len, ry = dx / len;\n const d = (x - fx) * rx + (y - fy) * ry;\n const w = W ? W[i] + (W[j] - W[i]) * f : width;\n const o = O ? O[i] + (O[j] - O[i]) * f : 0;\n const side: StrokeSide = inked ?? (d >= 0 ? 'right' : 'left');\n const scale = inked ? 2 : 1;\n const left = inked === 'right' ? 0 : scale * (w / 2 - o);\n const right = inked === 'left' ? 0 : scale * (w / 2 + o);\n const edge = side === 'right' ? right : left;\n // Past a segment's end the point is off its normal, so the gap is the\n // straight distance, not the distance across the line.\n const off = Math.hypot(x - fx, y - fy);\n const gap = inked && (d >= 0) !== (inked === 'right') ? off + edge : off - edge;\n if (best !== null && Math.abs(gap) >= Math.abs(best.gap)) continue;\n const sign = side === 'right' ? 1 : -1;\n best = {\n x: fx, y: fy, nx: rx * sign, ny: ry * sign, side, left, right, gap,\n factor: scale * (nibScale ? nibScale(dx / len, dy / len) : 1),\n };\n }\n }\n return best;\n}\n\n/** The side of a flattened subpath an aligned stroke inks: the one inside\n * `path`'s fill for an inner stroke, outside for an outer. Read once, beside\n * the longest segment, since a subpath that does not cross itself keeps its\n * fill on one side. */\nfunction inkedSide(path: Path, P: ArrayLike<number>, segCount: number, inner: boolean): StrokeSide {\n const n = P.length / 2;\n let at = -1, longest = 0;\n for (let i = 0; i < segCount; i++) {\n const j = (i + 1) % n;\n const l = Math.hypot(P[j * 2] - P[i * 2], P[j * 2 + 1] - P[i * 2 + 1]);\n if (l > longest) { longest = l; at = i; }\n }\n if (at < 0) return inner ? 'right' : 'left';\n const j = (at + 1) % n;\n const dx = P[j * 2] - P[at * 2], dy = P[j * 2 + 1] - P[at * 2 + 1];\n const probe = Math.min(longest, 1) * 1e-3;\n const mx = (P[at * 2] + P[j * 2]) / 2 - (dy / longest) * probe;\n const my = (P[at * 2 + 1] + P[j * 2 + 1]) / 2 + (dx / longest) * probe;\n return pointInPath(path, mx, my) === inner ? 'right' : 'left';\n}\n","/**\n * A stroke as geometry: the region its ink covers, as a fillable path.\n *\n * The ribbon the renderer draws already has the joins, caps, dashes, and\n * marker trims; unioning its triangles gives the silhouette with every\n * self-overlap resolved, so the outline and the drawn stroke cannot disagree.\n */\nimport { scaleVertexWidth, type Stroke } from '@weasel-js/paint';\nimport { invert, transformPath, type Affine, type Path, type PolygonPath } from '@weasel-js/geom';\nimport { pathIntersect, pathSubtract, pathUnion, trianglesToPath } from '@weasel-js/geom/booleans';\nimport { strokeInsets } from './markerInset';\nimport { resolveStrokeWidth, tessellateStroke } from './tessellate/stroke';\nimport { markerHeads } from './markerHeads';\n\n/** Options for {@link strokeToPath}. */\nexport interface StrokeToPathOptions {\n /** Screen pixels per world unit, for a `{ px }` width or marker size.\n * Default 1. */\n scale?: number;\n /** Flatness tolerance for curves, in the path's units. */\n flattenTolerance?: number;\n /**\n * The frame the stroke is drawn in, as the matrix taking that frame to the\n * path's coordinates: a node's `poseFrameOf`. A frame that skews or\n * stretches does the same to the stroke, as it does on the canvas. For a\n * `{ px }` width under a view that scales each axis apart, the frame is the\n * screen: the inverse of the view's scale, with `scale` left at 1.\n */\n frame?: Affine;\n}\n\nconst EMPTY: PolygonPath = {\n kind: 'polygon', commands: new Uint8Array(0), coords: new Float32Array(0), fillRule: 'nonzero',\n};\n\n/**\n * The region `stroke` covers when drawn along `path`, as a path to fill:\n * width, cap, join, miter limit, dash, alignment, per-vertex widths, and\n * marker heads all included. Curves are flattened, so the result holds only\n * M/L/Z. A stroke with no width answers an empty path, and so does one drawn\n * in a `frame` that flattens it.\n */\nexport function strokeToPath(path: Path, stroke: Stroke, opts: StrokeToPathOptions = {}): PolygonPath {\n const { frame, ...drawn } = opts;\n if (!frame) return outlineOf(path, stroke, drawn);\n const back = invert(frame);\n if (!back) return EMPTY;\n return transformPath(outlineOf(transformPath(path, back), stroke, drawn), frame) as PolygonPath;\n}\n\nfunction outlineOf(path: Path, stroke: Stroke, opts: StrokeToPathOptions): PolygonPath {\n // The ribbon, the heads and the booleans all work in the path's own offsets.\n if (path.kind === 'polygon' && path.origin) {\n const { origin, ...offsets } = path;\n const out = outlineOf(offsets, stroke, opts);\n return out.coords.length === 0 ? out : { ...out, origin };\n }\n const width = resolveStrokeWidth(stroke.width ?? 1, opts.scale ?? 1);\n if (!(width > 0)) return EMPTY;\n const tolerance = opts.flattenTolerance;\n const sized: Stroke = { ...stroke, width };\n const insets = strokeInsets(sized, width);\n const align = stroke.align ?? 'center';\n // A rect's aligned ribbon is built in place. Any other path gets a centered\n // ribbon twice as wide, cut to the side of the path it belongs on.\n const cut = align !== 'center' && path.kind !== 'rect';\n const ribbonStroke: Stroke = cut\n ? { ...sized, width: width * 2, align: 'center', vertexWidths: stroke.vertexWidths?.map((w) => scaleVertexWidth(w, 2)) }\n : sized;\n const mesh = tessellateStroke(path, ribbonStroke, {\n flattenTolerance: tolerance, startInset: insets.start, endInset: insets.end,\n });\n let ribbon = trianglesToPath(mesh.vertices, mesh.indices);\n if (cut) ribbon = align === 'inner' ? pathIntersect(ribbon, path) : pathSubtract(ribbon, path);\n\n const heads: PolygonPath[] = [];\n for (const { entry, path: head, size } of markerHeads(path, sized, width, tolerance)) {\n if ((entry.fill ?? 'line') !== 'none') heads.push(head);\n if (entry.outline && (entry.outline.paint ?? 'line') !== 'none') {\n heads.push(strokeToPath(head, { width: entry.outline.width * size, cap: 'round', join: 'round' }, opts));\n }\n }\n return heads.length === 0 ? ribbon : pathUnion(ribbon, ...heads);\n}\n","import {\n anchorsToPath, offsetCornerTraces, pathToAnchors, resolveCorners, restoreCorners, simplifyPath,\n type Path, type PolygonPath,\n} from '@weasel-js/geom';\nimport { pathSubtract, pathUnion } from '@weasel-js/geom/booleans';\nimport { strokeToPath } from './strokeToPath';\n\n/** Options for {@link offsetPath}. */\nexport interface OffsetPathOptions {\n /** How the offset outline turns a corner. Default `'miter'`. */\n join?: 'miter' | 'round' | 'bevel';\n /** Past this ratio of miter length to distance a miter corner is beveled.\n * Default 4. */\n miterLimit?: number;\n /** How closely curves are followed, in the path's units. Default 0.1. */\n tolerance?: number;\n /** Refit the outline's flattened curves as cubics (`simplifyPath` at\n * `tolerance`). Default true; false leaves a polygon. */\n refit?: boolean;\n}\n\n/**\n * The outline of the region `path` fills, grown by `distance` (shrunk by a\n * negative one), as a path to fill. Every subpath counts as closed. The\n * outline is where a stroke of twice `distance` centered on the path has its\n * outer (or inner) edge, so it takes that stroke's joins; overlaps resolve\n * the way a union does, and a region shrunk past its own width is gone.\n * Returns an empty path when nothing is left.\n */\nexport function offsetPath(path: Path, distance: number, opts: OffsetPathOptions = {}): PolygonPath {\n if (distance === 0) return closedRegion(path);\n const region = closedRegion(resolveCorners(path));\n const tolerance = opts.tolerance ?? 0.1;\n const band = strokeToPath(region, {\n width: Math.abs(distance) * 2,\n join: opts.join ?? 'miter',\n miterLimit: opts.miterLimit ?? 4,\n }, { flattenTolerance: tolerance });\n const cut = distance > 0 ? pathUnion(region, band) : pathSubtract(region, band);\n const corners = offsetCornerTraces(path, distance);\n // Tried before the refit, which can move a cut's ends off its anchors, and\n // after it, which can clear what the union left beside the cut.\n const grown = restoreCorners(cut, corners, tolerance);\n if (opts.refit === false || grown.commands.length === 0) return grown;\n return restoreCorners(simplifyPath(grown, tolerance), corners, tolerance);\n}\n\n/** `path` with every subpath closed. */\nfunction closedRegion(path: Path): PolygonPath {\n if (path.kind === 'rect') {\n const { x, y, width: w, height: h } = path;\n return anchorsToPath([[{ x, y }, { x: x + w, y }, { x: x + w, y: y + h }, { x, y: y + h }]], [true]);\n }\n const { anchors, closed } = pathToAnchors(path);\n if (closed.every(Boolean)) return path;\n return anchorsToPath(anchors, closed.map(() => true), path);\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/tessellate/dash.ts","../src/tessellate/nib.ts","../src/tessellate/vertexWidths.ts","../src/tessellate/flattening.ts","../src/tessellate/metric.ts","../src/tessellate/insets.ts","../src/tessellate/ribbon.ts","../src/tessellate/innerJoins.ts","../src/tessellate/stroke.ts","../src/markerInset.ts","../src/markerSites.ts","../src/markerHeads.ts","../src/strokeEdge.ts","../src/strokeToPath.ts","../src/offsetPath.ts"],"names":["len","extractPolylines","resolveScreenLength","reach","j","pathUnion","pathSubtract"],"mappings":"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","file":"index.js","sourcesContent":["import type { Path } from '@weasel-js/geom';\nimport { anchorParamsBetween, extractPolylines, type Polyline } from '@weasel-js/geom/tessellate';\nimport { dashPattern } from '@weasel-js/paint';\n\n/** One \"on\" run being collected: points with their anchor params and, when\n * the source carries them, widths. */\ninterface Run {\n pts: number[];\n a: number[];\n b: number[];\n t: number[];\n w: number[] | null;\n o: number[] | null;\n}\n\n/** One point of the source walk, or a point between two of them. */\ninterface At {\n x: number; y: number;\n a: number; b: number; t: number;\n w: number;\n o: number;\n}\n\nfunction runFrom(p: At, widths: boolean, offsets: boolean): Run {\n return { pts: [p.x, p.y], a: [p.a], b: [p.b], t: [p.t], w: widths ? [p.w] : null, o: offsets ? [p.o] : null };\n}\n\nfunction extend(run: Run, p: At): void {\n run.pts.push(p.x, p.y); run.a.push(p.a); run.b.push(p.b); run.t.push(p.t);\n run.w?.push(p.w);\n run.o?.push(p.o);\n}\n\nfunction toPolyline(run: Run, closed = false): Polyline {\n const pl: Polyline = {\n points: run.pts,\n closed,\n anchorA: new Uint32Array(run.a),\n anchorB: new Uint32Array(run.b),\n anchorT: new Float32Array(run.t),\n };\n if (run.w) pl.widths = new Float32Array(run.w);\n if (run.o) pl.offsets = new Float32Array(run.o);\n return pl;\n}\n\n/**\n * The dashed runs of every polyline of one path. Whether the pattern is too\n * fine to dash is decided once for the whole path, as a PDF reader's own\n * stroke operator would, so no subpath goes solid while its neighbor dashes.\n */\nexport function dashPolylines(polylines: readonly Polyline[], pattern: readonly number[] | undefined): Polyline[] {\n const dash = dashPattern(pattern, totalLength(polylines));\n if (dash === 'solid') return [...polylines];\n if (dash === 'non-finite') return [];\n return polylines.flatMap((pl) => splitForDash(pl, dash));\n}\n\n/**\n * The length a dash pattern runs along `path`, every subpath included: what a\n * writer handing the dash to another stroker passes to `dashPattern`.\n */\nexport function dashLength(path: Path): number {\n return totalLength(extractPolylines(path));\n}\n\nfunction totalLength(polylines: readonly Polyline[]): number {\n return polylines.reduce((sum, pl) => sum + polylineLength(pl), 0);\n}\n\n/** The length `splitForDash` walks, the closing segment included. */\nfunction polylineLength(pl: Polyline): number {\n const p = pl.points;\n const n = p.length / 2;\n let len = 0;\n for (let i = 1; i < n; i++) len += Math.hypot(p[i * 2] - p[i * 2 - 2], p[i * 2 + 1] - p[i * 2 - 1]);\n if (pl.closed && n > 1) len += Math.hypot(p[0] - p[n * 2 - 2], p[1] - p[n * 2 - 1]);\n return len;\n}\n\n/**\n * Split a polyline into open sub-polylines for the \"on\" portions of a dash\n * pattern. Each output sub-polyline gets caps from the stroke's `cap` setting.\n * The \"off\" portions become invisible gaps. Anchor params and per-point\n * widths and offsets are carried through: a dash boundary landing mid-segment takes\n * {@link anchorParamsBetween}'s params and the width interpolated there.\n * A dash {@link dashPattern} reads as solid along `pl` returns `pl` whole,\n * and a non-finite one returns nothing.\n */\nexport function splitForDash(pl: Polyline, pattern: readonly number[]): Polyline[] {\n const dash = dashPattern(pattern, polylineLength(pl));\n if (dash === 'solid') return [pl];\n if (dash === 'non-finite') return [];\n const out: Polyline[] = [];\n const ptCount = pl.points.length / 2;\n const plA = pl.anchorA ?? new Uint32Array(ptCount);\n const plB = pl.anchorB ?? new Uint32Array(ptCount);\n const plT = pl.anchorT ?? new Float32Array(ptCount);\n const W = pl.widths;\n const O = pl.offsets;\n const pointAt = (i: number): At => ({\n x: pl.points[i * 2], y: pl.points[i * 2 + 1], a: plA[i], b: plB[i], t: plT[i], w: W ? W[i] : 0, o: O ? O[i] : 0,\n });\n\n let dashIdx = 0;\n let dashRemaining = dash[0];\n let onPhase = true;\n let cur: Run | null = runFrom(pointAt(0), !!W, !!O);\n\n const flushAndAdvance = (at: At) => {\n if (cur && cur.pts.length >= 4) out.push(toPolyline(cur));\n dashIdx = (dashIdx + 1) % dash.length;\n dashRemaining = dash[dashIdx];\n onPhase = !onPhase;\n cur = onPhase ? runFrom(at, !!W, !!O) : null;\n };\n\n let prevX = pl.points[0], prevY = pl.points[1];\n const segCount = pl.closed ? ptCount : ptCount - 1;\n\n for (let i = 0; i < segCount; i++) {\n const start = pointAt(i);\n const end = pointAt((i + 1) % ptCount);\n const segFullLen = Math.hypot(end.x - prevX, end.y - prevY);\n // A coincident point still carries its width, as a nib's corner does.\n if (segFullLen <= 1e-9) {\n if (onPhase && cur) extend(cur, end);\n continue;\n }\n let segLen = segFullLen;\n let traveled = 0;\n\n while (segLen > 1e-9) {\n if (segLen <= dashRemaining) {\n if (onPhase && cur) extend(cur, end);\n dashRemaining -= segLen;\n prevX = end.x; prevY = end.y;\n segLen = 0;\n if (dashRemaining <= 1e-9) flushAndAdvance(end);\n } else {\n traveled += dashRemaining;\n const frac = traveled / segFullLen;\n const [a, b, t] = anchorParamsBetween(start.a, start.b, start.t, end.a, end.b, end.t, frac);\n const mid: At = {\n x: start.x + (end.x - start.x) * frac, y: start.y + (end.y - start.y) * frac,\n a, b, t, w: start.w + (end.w - start.w) * frac, o: start.o + (end.o - start.o) * frac,\n };\n if (onPhase && cur) extend(cur, mid);\n prevX = mid.x; prevY = mid.y;\n segLen = Math.hypot(end.x - prevX, end.y - prevY);\n flushAndAdvance(mid);\n }\n }\n }\n\n const tail: Run | null = cur;\n if (tail && tail.pts.length >= 4) closeOut(pl, tail, out);\n return out;\n}\n\n/**\n * Push the run still open at the end of the walk. A closed subpath's walk ends\n * at the vertex it started from, so the run still open there and the run that\n * started there are one dash. Pushed separately they are two butt-capped\n * ribbons meeting at the seam — the visible artifact whenever the pattern\n * doesn't divide the perimeter.\n */\nfunction closeOut(pl: Polyline, tail: Run, out: Polyline[]): void {\n const tx = tail.pts[tail.pts.length - 2], ty = tail.pts[tail.pts.length - 1];\n const meets = (x: number, y: number) => Math.hypot(tx - x, ty - y) <= 1e-9;\n if (pl.closed && out.length > 0 && meets(out[0].points[0], out[0].points[1])) {\n out[0] = joinAtSeam(toPolyline(tail), out[0]);\n } else if (pl.closed && out.length === 0 && meets(tail.pts[0], tail.pts[1])) {\n // Every gap fell outside the perimeter: the dash is the whole loop, and\n // a loop stroked as an open run seams at its own start vertex too.\n out.push(toPolyline({\n pts: tail.pts.slice(0, -2), a: tail.a.slice(0, -1), b: tail.b.slice(0, -1), t: tail.t.slice(0, -1),\n w: tail.w ? tail.w.slice(0, -1) : null, o: tail.o ? tail.o.slice(0, -1) : null,\n }, true));\n } else {\n out.push(toPolyline(tail));\n }\n}\n\n/** `tail` continued by `head`, which starts where `tail` ends — the shared\n * vertex is carried once. */\nfunction joinAtSeam(tail: Polyline, head: Polyline): Polyline {\n const pl: Polyline = {\n points: [...tail.points, ...head.points.slice(2)],\n closed: false,\n anchorA: Uint32Array.from([...tail.anchorA!, ...head.anchorA!.subarray(1)]),\n anchorB: Uint32Array.from([...tail.anchorB!, ...head.anchorB!.subarray(1)]),\n anchorT: Float32Array.from([...tail.anchorT!, ...head.anchorT!.subarray(1)]),\n };\n if (tail.widths && head.widths) pl.widths = Float32Array.from([...tail.widths, ...head.widths.subarray(1)]);\n if (tail.offsets && head.offsets) pl.offsets = Float32Array.from([...tail.offsets, ...head.offsets.subarray(1)]);\n return pl;\n}\n","import type { Polyline } from '@weasel-js/geom/tessellate';\nimport type { StrokeNib } from '@weasel-js/paint';\nimport type { WidthScale } from './vertexWidths';\n\n/**\n * What a nib does to a stroke's width moving along the unit direction\n * `(tx, ty)`: an elliptical pen whose long axis is the nib's edge, `1` moving\n * across it and `nib.ratio` moving along it. `angle` is counterclockwise on a\n * y-down screen, so the edge points along `(cos, -sin)`.\n */\nexport function nibWidthScale(nib: StrokeNib): WidthScale {\n const ex = Math.cos(nib.angle), ey = -Math.sin(nib.angle);\n const r = Math.min(1, Math.max(0, nib.ratio));\n return (tx, ty) => {\n const across = ex * ty - ey * tx;\n const along = ex * tx + ey * ty;\n return Math.sqrt(across * across + r * r * along * along);\n };\n}\n\n/**\n * Scale `pl`'s widths (its own, or `base` where it has none), and each side's\n * share of them, by the nib at\n * each segment's direction. A corner takes two coincident points, the end of\n * the segment into it and the start of the one out, so each side of a join\n * keeps its own width; the ribbon drops the zero-length span between them.\n * Mutates `pl`.\n */\nexport function applyNib(pl: Polyline, nib: StrokeNib, base: number): void {\n const n = pl.points.length / 2;\n if (n < 2) return;\n const P = pl.points;\n const scale = nibWidthScale(nib);\n const segCount = pl.closed ? n : n - 1;\n const factors: number[] = [];\n for (let i = 0; i < segCount; i++) {\n const j = (i + 1) % n;\n const dx = P[j * 2] - P[i * 2], dy = P[j * 2 + 1] - P[i * 2 + 1];\n const len = Math.hypot(dx, dy);\n factors.push(len > 0 ? scale(dx / len, dy / len) : NaN);\n }\n // A zero-length segment takes the direction of the one before it.\n for (let i = 0; i < segCount; i++) {\n if (Number.isNaN(factors[i])) factors[i] = i > 0 ? factors[i - 1] : (factors.find((f) => !Number.isNaN(f)) ?? 1);\n }\n const A = pl.anchorA, B = pl.anchorB, T = pl.anchorT, W = pl.widths, O = pl.offsets;\n const pts: number[] = [], aA: number[] = [], aB: number[] = [], aT: number[] = [], ws: number[] = [], os: number[] = [];\n const push = (i: number, factor: number) => {\n pts.push(P[i * 2], P[i * 2 + 1]);\n aA.push(A ? A[i] : 0); aB.push(B ? B[i] : 0); aT.push(T ? T[i] : 0);\n ws.push((W ? W[i] : base) * factor);\n if (O) os.push(O[i] * factor);\n };\n push(0, factors[0]);\n for (let i = 1; i < n; i++) {\n push(i, factors[i - 1]);\n if (i < segCount) push(i, factors[i]);\n }\n if (pl.closed) push(0, factors[segCount - 1]);\n pl.points = pts;\n pl.anchorA = Uint32Array.from(aA);\n pl.anchorB = Uint32Array.from(aB);\n pl.anchorT = Float32Array.from(aT);\n pl.widths = Float32Array.from(ws);\n if (O) pl.offsets = Float32Array.from(os);\n}\n","import type { Polyline } from '@weasel-js/geom/tessellate';\nimport { type StrokeNib, type VertexWidth, vertexHalfWidths, widestHalfWidth } from '@weasel-js/paint';\nimport { applyNib } from './nib';\n\n/** What one unit of a `vertexWidths` entry measures across the line at a\n * point whose unit tangent, in the polyline's own space, is `(tx, ty)`. */\nexport type WidthScale = (tx: number, ty: number) => number;\n\n/** Fill `pl.widths` by interpolating `vertexWidths` across each point's\n * (anchorA, anchorB, anchorT), each side of the path on its own, and\n * `pl.offsets` where the two sides differ. Anchor-aligned points (A === B)\n * read the anchor's value directly. Entries resolve through\n * `vertexHalfWidths`, so a missing one takes `fallbackWidth`. Given `scale`,\n * each entry is scaled at the point that reads it, and the fallback is not. */\nexport function populatePolylineWidths(\n pl: Polyline,\n vertexWidths: readonly VertexWidth[],\n fallbackWidth: number,\n scale?: WidthScale,\n): void {\n const ptCount = pl.points.length / 2;\n if (ptCount === 0) return;\n const aA = pl.anchorA ?? new Uint32Array(ptCount);\n const aB = pl.anchorB ?? new Uint32Array(ptCount);\n const aT = pl.anchorT ?? new Float32Array(ptCount);\n const widths = new Float32Array(ptCount);\n const offsets = new Float32Array(ptCount);\n let sided = false;\n const fallback = fallbackWidth / 2;\n let k = 1;\n // A fallback side is not scaled: it is the stroke's own width.\n const sides = (i: number): [number, number] => {\n const h = vertexHalfWidths(vertexWidths[i], NaN);\n return [Number.isNaN(h.left) ? fallback : h.left * k, Number.isNaN(h.right) ? fallback : h.right * k];\n };\n for (let i = 0; i < ptCount; i++) {\n if (scale) k = scaleAt(pl, i, scale);\n const a = aA[i], b = aB[i], t = aT[i];\n let [left, right] = sides(a);\n if (a !== b) {\n const [lb, rb] = sides(b);\n left += (lb - left) * t;\n right += (rb - right) * t;\n }\n widths[i] = left + right;\n offsets[i] = (right - left) / 2;\n if (offsets[i] !== 0) sided = true;\n }\n pl.widths = widths;\n if (sided) pl.offsets = offsets;\n}\n\n/** The widest a stroke of `width` draws: twice the farthest any edge sits\n * from the path. A nib only ever narrows it. */\nexport function widestStrokeWidth(width: number, vertexWidths: readonly VertexWidth[] | undefined): number {\n return 2 * widestHalfWidth(width, vertexWidths);\n}\n\n/** Fill `pl.widths` from whichever of `vertexWidths` and `nib` a stroke\n * sets, the nib's factor multiplying the per-vertex width. Leaves them unset\n * for a stroke of one width. */\nexport function populateWidths(\n pl: Polyline,\n vertexWidths: readonly VertexWidth[] | null,\n nib: StrokeNib | undefined,\n width: number,\n scale?: WidthScale,\n): void {\n if (vertexWidths) populatePolylineWidths(pl, vertexWidths, width, scale);\n if (nib) applyNib(pl, nib, width);\n}\n\n/** `scale` along the line's direction at point `i`: the bisector of the\n * segments either side, or the one segment at an open end. */\nfunction scaleAt(pl: Polyline, i: number, scale: WidthScale): number {\n const pts = pl.points;\n const n = pts.length / 2;\n let tx = 0, ty = 0;\n const add = (from: number, to: number) => {\n const dx = pts[to * 2] - pts[from * 2], dy = pts[to * 2 + 1] - pts[from * 2 + 1];\n const len = Math.hypot(dx, dy);\n if (len > 0) { tx += dx / len; ty += dy / len; }\n };\n if (i > 0) add(i - 1, i);\n else if (pl.closed && n > 1) add(n - 1, 0);\n if (i < n - 1) add(i, i + 1);\n else if (pl.closed && n > 1) add(n - 1, 0);\n const len = Math.hypot(tx, ty);\n return len > 0 ? scale(tx / len, ty / len) : 1;\n}\n","import { DEFAULT_FLATTEN_TOLERANCE } from '@weasel-js/geom';\nimport type { VertexWidth } from '@weasel-js/paint';\nimport type { ExtractOptions } from '@weasel-js/geom/tessellate';\nimport { widestStrokeWidth } from './vertexWidths';\n\n/**\n * How a stroke flattens its path. Every flattened vertex is a join on edges\n * half a width out, so the edges are held to the tolerance as well as the\n * path: a bend the path's tolerance passes in 40° steps reads as facets once\n * the stroke is thick. A stroke no wider than twice the tolerance keeps the\n * fill's vertices exactly: finer ones could leave a gap between its inner edge\n * and the fill's chords, which a wider one covers.\n */\nexport function strokeFlattening(\n flattenTolerance: number | undefined,\n width: number,\n vertexWidths?: readonly VertexWidth[],\n): ExtractOptions {\n const tolerance = flattenTolerance ?? DEFAULT_FLATTEN_TOLERANCE;\n const widest = widestStrokeWidth(width, vertexWidths);\n return widest / 2 > tolerance ? { flattenTolerance, offset: widest / 2 } : { flattenTolerance };\n}\n","/**\n * The space a screen-pixel stroke is built in.\n *\n * A `{ px }` stroke is exact on screen only when its ribbon is offset in a\n * space that measures lengths the way the screen does. The transform's linear\n * part is `scale · R · P`: a uniform scale, a rotation (or reflection) that\n * moves no lengths, and `P`, the symmetric unit-determinant stretch left over.\n * Offsetting the ribbon after `P` and mapping it back through `P⁻¹` gives a\n * world-space mesh that the full transform turns into a ribbon of exactly\n * `width · scale` pixels in every direction — and keeps the mesh drawable by\n * every path that draws a world-space ribbon.\n *\n * `P` depends only on the lengths the transform induces (`LᵀL`), not on any\n * rotation applied after it, so a view that only pans or zooms uniformly keeps\n * the same metric and the ribbon cache keeps hitting.\n */\nimport type { Polyline } from '@weasel-js/geom/tessellate';\n\n/** `P` = [[p, q], [q, r]], with `pr − q² = 1`. */\nexport interface StrokeMetric {\n readonly p: number;\n readonly q: number;\n readonly r: number;\n}\n\n/** A space a screen-sized part of a stroke is built in: the metric, and how\n * many screen pixels one of its units is. */\nexport interface ScreenSpace {\n readonly metric: StrokeMetric;\n readonly pxPerUnit: number;\n}\n\n/**\n * Where each part of a stroke is built. An absent part is built in world:\n * everything is under a similarity, and otherwise a part whose size is a world\n * length. The ribbon is screen-sized for a `{ px }` width; a head for a\n * `{ px }` size, or for no size on a screen-sized ribbon, since it then takes\n * the stroke width.\n */\nexport interface StrokeSpaces {\n readonly ribbon?: ScreenSpace;\n readonly start?: ScreenSpace;\n readonly mid?: ScreenSpace;\n readonly end?: ScreenSpace;\n}\n\n/** A cache-key fragment naming `space`; empty for world. */\nexport function screenSpaceKey(space: ScreenSpace | undefined): string {\n return space === undefined ? '' : `${metricKey(space.metric)}@${space.pxPerUnit}`;\n}\n\n/** Below this, a stretch is a rounding error and the transform a similarity. */\nconst CONFORMAL_EPSILON = 1e-9;\n\n/**\n * Split the linear map `x' = a·x + c·y, y' = b·x + d·y` — a GL `mat3`'s\n * `m[0], m[1], m[3], m[4]` — into its geometric-mean scale and its stroke\n * metric. `metric` is `null` when the map is a similarity, where world space\n * already measures like the screen; `scale` is `0` for a singular map.\n */\nexport function strokeSpaceOf(\n a: number, b: number, c: number, d: number,\n): { scale: number; metric: StrokeMetric | null } {\n const det2 = Math.abs(a * d - b * c);\n const scale = Math.sqrt(det2);\n if (!(det2 > 0) || !Number.isFinite(det2)) return { scale: 0, metric: null };\n // G = LᵀL / det, whose determinant is 1, so √G = (G + I) / √(tr G + 2).\n const g11 = (a * a + b * b) / det2;\n const g12 = (a * c + b * d) / det2;\n const g22 = (c * c + d * d) / det2;\n const s = Math.sqrt(g11 + g22 + 2);\n const p = (g11 + 1) / s;\n const q = g12 / s;\n const r = (g22 + 1) / s;\n if (Math.abs(q) < CONFORMAL_EPSILON && Math.abs(p - r) < CONFORMAL_EPSILON) {\n return { scale, metric: null };\n }\n return { scale, metric: { p, q, r } };\n}\n\n/** A cache-key fragment naming `metric`; empty for none. */\nexport function metricKey(metric: StrokeMetric | undefined): string {\n return metric === undefined ? '' : `${metric.p},${metric.q},${metric.r}`;\n}\n\n/** Map `pl`'s points through `P`, in place. */\nexport function polylineIntoMetric(pl: Polyline, m: StrokeMetric): void {\n const pts = pl.points;\n for (let i = 0; i < pts.length; i += 2) {\n const x = pts[i], y = pts[i + 1];\n pts[i] = m.p * x + m.q * y;\n pts[i + 1] = m.q * x + m.r * y;\n }\n}\n\n/** Map `pl`'s points back out through `P⁻¹`, in place. */\nexport function polylineOutOfMetric(pl: Polyline, m: StrokeMetric): void {\n const pts = pl.points;\n for (let i = 0; i < pts.length; i += 2) {\n const x = pts[i], y = pts[i + 1];\n pts[i] = m.r * x - m.q * y;\n pts[i + 1] = m.p * y - m.q * x;\n }\n}\n\n/** Whether two spaces are the same — world being `null`. */\nexport function sameMetric(a: StrokeMetric | null, b: StrokeMetric | null): boolean {\n if (a === b) return true;\n return a !== null && b !== null && a.p === b.p && a.q === b.q && a.r === b.r;\n}\n\n/**\n * What one world unit of width, across a line running along the unit\n * direction `(tx, ty)` of the metric's own space, measures in that space.\n * `P` keeps areas, so a strip keeps its area while its length stretches by\n * `|P u|` (`u` the line's world direction): its width shrinks by the same,\n * and `1 / |P u|` is `|P⁻¹ t|`.\n */\nexport function worldWidthInMetric(m: StrokeMetric, tx: number, ty: number): number {\n return Math.hypot(m.r * tx - m.q * ty, m.p * ty - m.q * tx);\n}\n\n/** The same, for a line running along the unit world direction `(ux, uy)`. */\nexport function worldWidthInMetricAlongWorld(m: StrokeMetric, ux: number, uy: number): number {\n return 1 / Math.hypot(m.p * ux + m.q * uy, m.q * ux + m.r * uy);\n}\n\n/** Map interleaved x,y pairs back out through `P⁻¹` = [[r, −q], [−q, p]], in\n * place. */\nexport function coordsOutOfMetric(coords: Float32Array, m: StrokeMetric): void {\n for (let i = 0; i < coords.length; i += 2) {\n const x = coords[i], y = coords[i + 1];\n coords[i] = m.r * x - m.q * y;\n coords[i + 1] = m.p * y - m.q * x;\n }\n}\n\n/** Whether `P` takes an axis-aligned rect to another one. */\nexport function metricKeepsRects(m: StrokeMetric): boolean {\n return m.q === 0;\n}\n\n/** `rect` in the metric's space, while `P` keeps it axis-aligned; otherwise\n * `null`, and the rect has to be carried as a polygon. */\nexport function rectIntoMetric(\n rect: { x: number; y: number; width: number; height: number },\n m: StrokeMetric,\n): { kind: 'rect'; x: number; y: number; width: number; height: number } | null {\n if (!metricKeepsRects(m)) return null;\n return { kind: 'rect', x: m.p * rect.x, y: m.r * rect.y, width: m.p * rect.width, height: m.r * rect.height };\n}\n","/**\n * Trimming a stroke's ends where each inset is measured.\n *\n * A head stops the line by a length in the head's own space, which need not be\n * the ribbon's: a world-sized head on a `{ px }` stroke stops it a world\n * distance short, a `{ px }` head on a world-width stroke a screen distance.\n * Under a stretching view one length means different distances in the two\n * spaces depending on which way the line runs, so each end is trimmed in its\n * own space rather than converted.\n */\nimport { type Polyline, trimPolyline } from '@weasel-js/geom/tessellate';\nimport {\n type StrokeMetric, polylineIntoMetric, polylineOutOfMetric, sameMetric,\n} from './metric';\n\n/** A length along the line measured in `metric`'s space, or in world where\n * `metric` is `null`. */\nexport interface MeasuredLength {\n readonly length: number;\n readonly metric: StrokeMetric | null;\n}\n\n/** A plain number is a length in the ribbon's own space. */\nexport type InsetLength = number | MeasuredLength;\n\ninterface Trim {\n length: number;\n metric: StrokeMetric | null;\n}\n\nconst trimOf = (inset: InsetLength | undefined, ribbon: StrokeMetric | null): Trim =>\n inset === undefined ? { length: 0, metric: ribbon }\n : typeof inset === 'number' ? { length: inset, metric: ribbon }\n : inset;\n\n/**\n * `pl`, whose points are in `from`'s space, trimmed by `start` and `end` and\n * carried into `ribbon`'s — `null` for world in both. `pl` may be mapped in\n * place. Returns `null` when the insets consume the whole run.\n */\nexport function trimInSpace(\n pl: Polyline,\n from: StrokeMetric | null,\n ribbon: StrokeMetric | null,\n start: InsetLength | undefined,\n end: InsetLength | undefined,\n): Polyline | null {\n const s = trimOf(start, ribbon);\n const e = trimOf(end, ribbon);\n let cur: Polyline | null = pl;\n let space = from;\n const moveTo = (to: StrokeMetric | null) => {\n if (cur === null || sameMetric(space, to)) return;\n if (space !== null) polylineOutOfMetric(cur, space);\n if (to !== null) polylineIntoMetric(cur, to);\n space = to;\n };\n if (s.length > 0 || e.length > 0) {\n if (sameMetric(s.metric, e.metric)) {\n moveTo(s.metric);\n cur = trimPolyline(cur, s.length, e.length);\n } else {\n for (const [len, metric, atStart] of [[s.length, s.metric, true], [e.length, e.metric, false]] as const) {\n if (!(len > 0) || cur === null) continue;\n moveTo(metric);\n cur = trimPolyline(cur, atStart ? len : 0, atStart ? 0 : len);\n }\n }\n }\n moveTo(ribbon);\n return cur;\n}\n","/**\n * The pieces of a stroke ribbon: one straight segment with each edge its own\n * distance from the path at either end, and the caps and joins drawn from\n * those edges.\n */\n\nexport type Cap = 'butt' | 'round' | 'square';\nexport type Join = 'miter' | 'round' | 'bevel';\n\n/** Per-segment data the join code needs. */\nexport interface Seg {\n ax: number; ay: number;\n bx: number; by: number;\n /** Unit perpendicular (rotated 90° CCW from direction). */\n nxUnit: number; nyUnit: number;\n /** How far the edge on the +n side (`pos`) and the −n side (`neg`) sits\n * from the path at the start (a) and end (b). All equal for a uniform\n * stroke; they differ when the polyline carries per-point widths or\n * offsets. */\n posA: number; negA: number;\n posB: number; negB: number;\n len: number;\n}\n\nconst ROUND_CAP_STEP_RAD = (10 * Math.PI) / 180;\n\n/**\n * Emit a cap at one end of a segment. `leftIdx`/`rightIdx` are the buffer\n * indices of the L (perpendicular +n) and R (perpendicular -n) vertices at\n * the segment endpoint where the cap attaches, `pos` and `neg` from the path.\n * `atEnd` chooses which end of the segment to extend from (and which\n * cap-direction sign to use). The cap is centered between the two edges.\n */\nexport function emitCap(\n seg: Seg, leftIdx: number, rightIdx: number, atEnd: boolean,\n pos: number, neg: number, cap: Cap,\n verts: number[], idx: number[],\n anchorA: number[], anchorB: number[], anchorT: number[],\n endA: number, endB: number, endT: number,\n): void {\n // Outward direction = forward at end, backward at start.\n const sign = atEnd ? 1 : -1;\n const dx = (seg.bx - seg.ax) / seg.len * sign;\n const dy = (seg.by - seg.ay) / seg.len * sign;\n const half = (pos + neg) / 2;\n const shift = (pos - neg) / 2;\n const cx = (atEnd ? seg.bx : seg.ax) + seg.nxUnit * shift;\n const cy = (atEnd ? seg.by : seg.ay) + seg.nyUnit * shift;\n\n const nx = seg.nxUnit * half;\n const ny = seg.nyUnit * half;\n\n if (cap === 'square') {\n const ox = cx + dx * half;\n const oy = cy + dy * half;\n const lOut = verts.length / 2;\n verts.push(ox + nx, oy + ny);\n anchorA.push(endA); anchorB.push(endB); anchorT.push(endT);\n const rOut = verts.length / 2;\n verts.push(ox - nx, oy - ny);\n anchorA.push(endA); anchorB.push(endB); anchorT.push(endT);\n // Two triangles forming the cap rectangle. Wind so triangles are CCW\n // viewed from the front; orientation symmetric for start vs. end caps.\n if (atEnd) {\n idx.push(leftIdx, lOut, rOut, leftIdx, rOut, rightIdx);\n } else {\n idx.push(leftIdx, rOut, lOut, leftIdx, rightIdx, rOut);\n }\n return;\n }\n\n if (cap === 'round') {\n // Pivot vertex at the endpoint center; fan from L through the outward\n // 180° arc to R.\n const pivotIdx = verts.length / 2;\n verts.push(cx, cy);\n anchorA.push(endA); anchorB.push(endB); anchorT.push(endT);\n\n // Starting angle: direction from pivot to L (= +n direction).\n const startAngle = Math.atan2(ny, nx);\n // Sweep 180° toward the outward direction. The outward unit is (dx, dy);\n // we rotate from +n to -n the \"outward\" way. The dot product of (dx, dy)\n // with the perpendicular tells us which way around the arc to go.\n // A start-cap (sign = -1) sweeps backward; end-cap (sign = +1) sweeps forward.\n const sweep = atEnd ? -Math.PI : Math.PI;\n const steps = Math.max(1, Math.ceil(Math.abs(sweep) / ROUND_CAP_STEP_RAD));\n const stepAngle = sweep / steps;\n\n let prevIdx = leftIdx;\n for (let i = 1; i < steps; i++) {\n const ang = startAngle + i * stepAngle;\n const fx = cx + Math.cos(ang) * half;\n const fy = cy + Math.sin(ang) * half;\n const newIdx = verts.length / 2;\n verts.push(fx, fy);\n anchorA.push(endA); anchorB.push(endB); anchorT.push(endT);\n if (atEnd) idx.push(prevIdx, newIdx, pivotIdx);\n else idx.push(prevIdx, pivotIdx, newIdx);\n prevIdx = newIdx;\n }\n if (atEnd) idx.push(prevIdx, rightIdx, pivotIdx);\n else idx.push(prevIdx, pivotIdx, rightIdx);\n }\n}\n\nexport function makeSeg(\n ax: number, ay: number, bx: number, by: number,\n posA: number, negA: number, posB: number, negB: number,\n): Seg | null {\n const dx = bx - ax, dy = by - ay;\n const len = Math.hypot(dx, dy);\n if (len === 0) return null;\n return {\n ax, ay, bx, by,\n nxUnit: -dy / len, nyUnit: dx / len,\n posA, negA, posB, negB,\n len,\n };\n}\n\nexport function emitJoin(\n segs: Seg[], segBaseIdx: number[], j: number, join: Join,\n miterLimit: number,\n varyingThreshold: number,\n verts: number[], idx: number[],\n anchorA: number[], anchorB: number[], anchorT: number[],\n segSrcIdx: number[],\n plA: Uint32Array, plB: Uint32Array, plT: Float32Array,\n inner = -1,\n): void {\n const a = segs[j];\n const b = segs[(j + 1) % segs.length];\n const aBase = segBaseIdx[j];\n const bBase = segBaseIdx[(j + 1) % segs.length];\n\n const adx = a.bx - a.ax, ady = a.by - a.ay;\n const bdx = b.bx - b.ax, bdy = b.by - b.ay;\n const cross = adx * bdy - ady * bdx;\n if (cross === 0) return; // straight (collinear), no wedge\n const onPositive = cross > 0;\n\n const aOuterEnd = onPositive ? aBase + 3 : aBase + 2;\n const bOuterStart = onPositive ? bBase + 1 : bBase + 0;\n\n // The corner of join `j` is the start of segment `j+1` (which is the END of\n // segment `j` — they share the same polyline point). For the wraparound join\n // on a closed polyline, j+1 wraps to segment 0 whose start is the closer\n // segment's endpoint, which is polyline point 0.\n const nextSeg = (j + 1) % segs.length;\n // The corner anchor is the start of the next segment (shared endpoint).\n // For a closed path's final join, nextSeg wraps to 0, whose start is\n // polyline point 0 — correct.\n const cornerSrc = segSrcIdx[nextSeg];\n const cornerA = plA[cornerSrc];\n const cornerB = plB[cornerSrc];\n const cornerT = plT[cornerSrc];\n // The join is drawn on the outer edge: the −n side when turning toward +n.\n // Both segments agree on it at the shared corner, so either sizes the\n // miter limit. Force bevel when that edge tapers along either adjacent\n // segment by more than `varyingThreshold` — the miter apex math computes\n // against outer edges parallel to the segment direction, an assumption\n // that breaks on tapered trapezoids (outer edges fan in/out).\n const outerA = onPositive ? [a.negA, a.negB] : [a.posA, a.posB];\n const outerB = onPositive ? [b.negA, b.negB] : [b.posA, b.posB];\n const halfAtCorner = outerA[1];\n const taperA = Math.max(...outerA) / Math.max(1e-9, Math.min(...outerA));\n const taperB = Math.max(...outerB) / Math.max(1e-9, Math.min(...outerB));\n const forceBevelForVarying = taperA > varyingThreshold || taperB > varyingThreshold;\n\n if (join === 'bevel' || forceBevelForVarying) {\n emitBevel(a, aOuterEnd, bOuterStart, onPositive, verts, idx, anchorA, anchorB, anchorT, cornerA, cornerB, cornerT, inner);\n return;\n }\n\n if (join === 'miter') {\n // Compute apex: intersection of A's outer edge extended forward and\n // B's outer edge extended backward. If miter length > MITER_LIMIT * half,\n // fall back to bevel.\n const aOX = verts[aOuterEnd * 2], aOY = verts[aOuterEnd * 2 + 1];\n const bOX = verts[bOuterStart * 2], bOY = verts[bOuterStart * 2 + 1];\n const apex = lineLineIntersect(aOX, aOY, adx, ady, bOX, bOY, -bdx, -bdy);\n if (!apex) {\n emitBevel(a, aOuterEnd, bOuterStart, onPositive, verts, idx, anchorA, anchorB, anchorT, cornerA, cornerB, cornerT, inner);\n return;\n }\n const miterLen = Math.hypot(apex[0] - a.bx, apex[1] - a.by);\n if (miterLen > miterLimit * halfAtCorner) {\n emitBevel(a, aOuterEnd, bOuterStart, onPositive, verts, idx, anchorA, anchorB, anchorT, cornerA, cornerB, cornerT, inner);\n return;\n }\n // A miter join's outer face is a kite quadrilateral with vertices\n // (R1, apex, R0, J) — covered by TWO triangles. The bevel inner half\n // (R1, R0, J) fills the area between the joint corner and the diagonal\n // hypotenuse R0-R1; the outer extension (R1, apex, R0) fills from the\n // hypotenuse to the apex point. Without the bevel half, an \"inverted\n // triangle\" gap opens at every miter corner.\n const apexIdx = verts.length / 2;\n verts.push(apex[0], apex[1]);\n anchorA.push(cornerA); anchorB.push(cornerB); anchorT.push(cornerT);\n const jIdx = inner >= 0 ? inner : cornerVertex(a, verts, anchorA, anchorB, anchorT, cornerA, cornerB, cornerT);\n if (onPositive) {\n idx.push(aOuterEnd, apexIdx, bOuterStart);\n idx.push(aOuterEnd, bOuterStart, jIdx);\n } else {\n idx.push(aOuterEnd, bOuterStart, apexIdx);\n idx.push(aOuterEnd, jIdx, bOuterStart);\n }\n return;\n }\n\n if (join === 'round') {\n emitRoundJoin(a, aOuterEnd, bOuterStart, onPositive, verts, idx, anchorA, anchorB, anchorT, cornerA, cornerB, cornerT, inner);\n return;\n }\n}\n\nconst ROUND_STEP_RAD = (10 * Math.PI) / 180; // ~10° per fan triangle\n\nfunction emitRoundJoin(\n a: Seg, aOuterEnd: number, bOuterStart: number, onPositive: boolean,\n verts: number[], idx: number[],\n anchorA: number[], anchorB: number[], anchorT: number[],\n cornerA: number, cornerB: number, cornerT: number,\n inner: number,\n): void {\n // The arc is about the joint; the fan is drawn from the inner corner the\n // segments meet at, where they meet there, else from the joint itself.\n const cx = a.bx, cy = a.by;\n const pivotIdx = inner >= 0 ? inner : cornerVertex(a, verts, anchorA, anchorB, anchorT, cornerA, cornerB, cornerT);\n\n const startX = verts[aOuterEnd * 2] - cx;\n const startY = verts[aOuterEnd * 2 + 1] - cy;\n const endX = verts[bOuterStart * 2] - cx;\n const endY = verts[bOuterStart * 2 + 1] - cy;\n const r0 = Math.hypot(startX, startY), r1 = Math.hypot(endX, endY);\n\n const startAngle = Math.atan2(startY, startX);\n const endAngle = Math.atan2(endY, endX);\n // Outer-side sweep: for CCW turns (cross > 0, onPositive true) outer is on\n // the -n side and the arc sweeps from R1 (south of joint) clockwise to R0\n // (east of joint) — i.e., negative sweep. For CW turns, sweep is positive.\n // Pick the SHORT arc that crosses the outer wedge. For onPositive=true\n // (CW turn in screen coords with y-down), the outer wedge sits where the\n // natural sweep is positive; for onPositive=false, where it is negative.\n // If the natural sweep has the wrong sign, wrap by ±2π.\n let sweep = endAngle - startAngle;\n if (onPositive && sweep < 0) sweep += 2 * Math.PI;\n else if (!onPositive && sweep > 0) sweep -= 2 * Math.PI;\n\n const steps = Math.max(1, Math.ceil(Math.abs(sweep) / ROUND_STEP_RAD));\n const stepAngle = sweep / steps;\n\n let prevIdx = aOuterEnd;\n for (let i = 1; i < steps; i++) {\n const ang = startAngle + i * stepAngle;\n // Each side of a join can have its own width; the arc runs between them.\n const r = r0 + ((r1 - r0) * i) / steps;\n verts.push(cx + Math.cos(ang) * r, cy + Math.sin(ang) * r);\n const newIdx = verts.length / 2 - 1;\n anchorA.push(cornerA); anchorB.push(cornerB); anchorT.push(cornerT);\n if (onPositive) idx.push(prevIdx, pivotIdx, newIdx);\n else idx.push(prevIdx, newIdx, pivotIdx);\n prevIdx = newIdx;\n }\n if (onPositive) idx.push(prevIdx, pivotIdx, bOuterStart);\n else idx.push(prevIdx, bOuterStart, pivotIdx);\n}\n\nfunction emitBevel(\n a: Seg, aOuterEnd: number, bOuterStart: number, onPositive: boolean,\n verts: number[], idx: number[],\n anchorA: number[], anchorB: number[], anchorT: number[],\n cornerA: number, cornerB: number, cornerT: number,\n inner: number,\n): void {\n const jIdx = inner >= 0 ? inner : cornerVertex(a, verts, anchorA, anchorB, anchorT, cornerA, cornerB, cornerT);\n if (onPositive) idx.push(aOuterEnd, jIdx, bOuterStart);\n else idx.push(aOuterEnd, bOuterStart, jIdx);\n}\n\n/** A fresh vertex at the joint, `a`'s end. */\nfunction cornerVertex(\n a: Seg, verts: number[], anchorA: number[], anchorB: number[], anchorT: number[],\n cornerA: number, cornerB: number, cornerT: number,\n): number {\n const at = verts.length / 2;\n verts.push(a.bx, a.by);\n anchorA.push(cornerA); anchorB.push(cornerB); anchorT.push(cornerT);\n return at;\n}\n\n/**\n * Solve for the intersection of line A (point ap, direction ad) with line B\n * (point bp, direction bd). Returns null if parallel or near-parallel.\n */\nfunction lineLineIntersect(\n apx: number, apy: number, adx: number, ady: number,\n bpx: number, bpy: number, bdx: number, bdy: number,\n): [number, number] | null {\n const denom = adx * bdy - ady * bdx;\n if (Math.abs(denom) < 1e-9) return null;\n const t = ((bpx - apx) * bdy - (bpy - apy) * bdx) / denom;\n return [apx + t * adx, apy + t * ady];\n}\n","/**\n * Where two segments of a ribbon meet on the inside of a turn, their quads\n * overlap past the corner, and a translucent stroke drawn from them blends\n * twice there. This moves the inner corner of each pair to where their inner\n * edges cross, so the quads meet along one edge instead, and the join is\n * drawn as a fan from that point.\n *\n * Where the crossing lies past either segment's far end, or would carry a\n * segment's inner edge past where its other end's join already moved it, the\n * pair keeps its corners and still overlaps: a stroke turning tighter than\n * its own half-width covers that ground twice by construction.\n */\nimport type { Seg } from './ribbon';\n\n/** `segs[k]`'s inner edge on the side `side` (0 the +n edge, 1 the −n) runs\n * from vertex `base + side` to `base + 2 + side`. */\ninterface Meet {\n side: 0 | 1;\n x: number;\n y: number;\n /** How far along `a`'s inner edge the crossing lies, 0 at its start. */\n s: number;\n /** How far along `b`'s, 0 at its start. */\n u: number;\n}\n\n/**\n * For each join `j` (between `segs[j]` and the next), the index of the vertex\n * its fan is drawn from, both inner corners having been moved onto it in\n * `verts`, or -1 where the corners were left alone.\n */\nexport function meetInnerEdges(segs: Seg[], segBaseIdx: number[], closed: boolean, verts: number[]): number[] {\n const n = segs.length;\n const joins = closed ? n : n - 1;\n const meets: (Meet | null)[] = [];\n for (let j = 0; j < joins; j++) meets.push(meetAt(segs, segBaseIdx, j, verts));\n\n // A segment whose two ends were both moved along the same edge must not\n // have them pass each other; drop the join on either side until none do.\n for (let changed = true; changed;) {\n changed = false;\n for (let k = 0; k < n; k++) {\n const before = k > 0 || closed ? meets[(k - 1 + n) % n] ?? null : null;\n const after = k < joins ? meets[k] : null;\n if (before && after && before.side === after.side && before.u > after.s) {\n meets[(k - 1 + n) % n] = null;\n meets[k] = null;\n changed = true;\n }\n }\n }\n\n const pivots: number[] = [];\n for (let j = 0; j < joins; j++) {\n const m = meets[j];\n if (!m) { pivots.push(-1); continue; }\n const aEnd = segBaseIdx[j] + 2 + m.side;\n const bStart = segBaseIdx[(j + 1) % n] + m.side;\n verts[aEnd * 2] = m.x; verts[aEnd * 2 + 1] = m.y;\n verts[bStart * 2] = m.x; verts[bStart * 2 + 1] = m.y;\n pivots.push(aEnd);\n }\n return pivots;\n}\n\nfunction meetAt(segs: Seg[], segBaseIdx: number[], j: number, verts: number[]): Meet | null {\n const a = segs[j];\n const b = segs[(j + 1) % segs.length];\n const cross = (a.bx - a.ax) * (b.by - b.ay) - (a.by - a.ay) * (b.bx - b.ax);\n if (cross === 0) return null;\n // Turning toward +n, the inside of the turn is the +n edge.\n const side: 0 | 1 = cross > 0 ? 0 : 1;\n const aBase = segBaseIdx[j], bBase = segBaseIdx[(j + 1) % segs.length];\n const p0x = verts[(aBase + side) * 2], p0y = verts[(aBase + side) * 2 + 1];\n const p1x = verts[(aBase + 2 + side) * 2], p1y = verts[(aBase + 2 + side) * 2 + 1];\n const q0x = verts[(bBase + side) * 2], q0y = verts[(bBase + side) * 2 + 1];\n const q1x = verts[(bBase + 2 + side) * 2], q1y = verts[(bBase + 2 + side) * 2 + 1];\n const rx = p1x - p0x, ry = p1y - p0y;\n const qx = q1x - q0x, qy = q1y - q0y;\n const den = rx * qy - ry * qx;\n if (den === 0) return null;\n const dx = q0x - p0x, dy = q0y - p0y;\n const s = (dx * qy - dy * qx) / den;\n const u = (dx * ry - dy * rx) / den;\n if (!(s > 0 && s <= 1 && u >= 0 && u < 1)) return null;\n return { side, x: p0x + rx * s, y: p0y + ry * s, s, u };\n}\n","import { remapPerAnchor, resolveCornersWithSources, type Path } from '@weasel-js/geom';\nimport type { ScreenLength, Stroke } from '@weasel-js/paint';\nimport { alignedStrokeRect, resolveScreenLength } from '@weasel-js/paint';\nimport { type Mesh, extractPolylines, type Polyline } from '@weasel-js/geom/tessellate';\nimport { dashPolylines } from './dash';\nimport { strokeFlattening } from './flattening';\nimport { populateWidths, type WidthScale } from './vertexWidths';\nimport { type InsetLength, trimInSpace } from './insets';\nimport { type Cap, emitCap, emitJoin, type Join, makeSeg, type Seg } from './ribbon';\nimport { meetInnerEdges } from './innerJoins';\nimport {\n type StrokeMetric, coordsOutOfMetric, rectIntoMetric, worldWidthInMetric, worldWidthInMetricAlongWorld,\n} from './metric';\n\n/** Options for stroke tessellation. */\nexport interface StrokeOptions {\n flattenTolerance?: number;\n /**\n * Shorten each open subpath by this much at its start / end: a length in\n * the ribbon's space, or one measured in a space of its own. Stroke markers\n * use this so a filled head is not speared by its own line; the caller\n * resolves the distance, because this layer knows nothing about the marker\n * registry.\n */\n startInset?: InsetLength;\n endInset?: InsetLength;\n /**\n * Build the ribbon in this metric's space and map it back out, so the\n * transform it was derived from draws it at an exact screen width — see\n * `./metric`. Width and dash are then lengths in that space; `vertexWidths`\n * stay world widths. The path is flattened in world first, so the ribbon\n * follows the same vertices its fill does.\n */\n metric?: StrokeMetric;\n}\n\nconst EMPTY_MESH: Mesh = {\n vertices: new Float32Array(0),\n indices: new Uint32Array(0),\n anchorA: new Uint32Array(0),\n anchorB: new Uint32Array(0),\n anchorT: new Float32Array(0),\n};\n\n\n/** Resolve a stroke width to world units. A number is already world units;\n * `{ px }` is screen pixels divided by the accumulated scale, so it holds its\n * on-screen thickness as the view zooms. */\nexport function resolveStrokeWidth(width: ScreenLength, scale: number): number {\n return resolveScreenLength(width, scale);\n}\n\n/**\n * Build a triangle-mesh ribbon from a stroked Path.\n *\n * Supports:\n * - cap: 'butt' | 'round' | 'square'\n * - join: 'miter' | 'round' | 'bevel'\n * - center alignment directly; RectPath inner/outer alignment via a\n * pre-shifted rect; PolygonPath inner/outer alignment via stencil at the\n * renderer level\n * - dash splitting\n */\nexport function tessellateStroke(\n path: Path,\n stroke: Stroke,\n opts: StrokeOptions = {},\n): Mesh {\n // The renderer resolves `{ px }` against the accumulated transform before it\n // gets here; a stroke that reaches the tessellator unresolved is read at\n // scale 1, matching what the ribbon cache keys it under.\n const width = resolveStrokeWidth(stroke.width ?? 1, 1);\n if (width <= 0) return EMPTY_MESH;\n const join: Join = stroke.join ?? 'miter';\n const cap: Cap = stroke.cap ?? 'butt';\n const align = stroke.align ?? 'center';\n const miterLimit = stroke.miterLimit ?? DEFAULT_MITER_LIMIT;\n const varyingThreshold = stroke.varyingWidthJoinThreshold ?? DEFAULT_VARYING_WIDTH_JOIN_THRESHOLD;\n\n // RectPath fast path for inner/outer alignment: shift the rect by half-width\n // so the ribbon's center alignment lands the stroke on the desired side of\n // the original geometric edge. Arbitrary paths handle alignment via stencil\n // clipping at the renderer level (not here).\n const metric = opts.metric;\n const rectInMetric = metric && path.kind === 'rect' ? rectIntoMetric(path, metric) : null;\n let workingPath: Path = rectInMetric ?? path;\n if (workingPath.kind === 'rect' && align !== 'center') {\n workingPath = { kind: 'rect', ...alignedStrokeRect(workingPath, align, width) };\n }\n\n // Per-point widths come first, in the space the points are in, so a trim\n // interpolates them rather than re-reading an anchor's.\n // Expanded here rather than inside `extractPolylines`, so each width moves\n // to the anchors its corner's cut leaves.\n const resolved = workingPath.kind === 'polygon' ? resolveCornersWithSources(workingPath) : null;\n if (resolved) workingPath = resolved.path;\n const given = stroke.vertexWidths && stroke.vertexWidths.length > 0 ? stroke.vertexWidths : null;\n const vertexWidths = given && resolved?.anchorSources ? remapPerAnchor(given, resolved.anchorSources, 1) : given;\n const polylines = extractPolylines(workingPath, strokeFlattening(opts.flattenTolerance, width, vertexWidths ?? undefined));\n const scale: WidthScale | undefined = !metric ? undefined\n : rectInMetric ? (tx, ty) => worldWidthInMetric(metric, tx, ty)\n : (ux, uy) => worldWidthInMetricAlongWorld(metric, ux, uy);\n const verts: number[] = [];\n const idx: number[] = [];\n const anchorA: number[] = [];\n const anchorB: number[] = [];\n const anchorT: number[] = [];\n\n // Trim before dashing, so the dash pattern fits the visible line rather than\n // running off under a marker head.\n const ribbonSpace = metric ?? null;\n const trimmed: Polyline[] = [];\n for (const pl of polylines) {\n populateWidths(pl, vertexWidths, stroke.nib, width, scale);\n const t = trimInSpace(pl, rectInMetric ? ribbonSpace : null, ribbonSpace, opts.startInset, opts.endInset);\n if (t !== null) trimmed.push(t);\n }\n for (const sub of dashPolylines(trimmed, stroke.dash)) {\n expandPolyline(sub, width, join, cap, miterLimit, varyingThreshold, verts, idx, anchorA, anchorB, anchorT);\n }\n\n const vertices = new Float32Array(verts);\n if (metric) coordsOutOfMetric(vertices, metric);\n return {\n vertices,\n indices: new Uint32Array(idx),\n anchorA: new Uint32Array(anchorA),\n anchorB: new Uint32Array(anchorB),\n anchorT: new Float32Array(anchorT),\n ...(path.kind === 'polygon' && path.origin ? { origin: path.origin } : {}),\n };\n}\n\nfunction expandPolyline(\n pl: Polyline,\n width: number,\n join: Join,\n cap: Cap,\n miterLimit: number,\n varyingThreshold: number,\n verts: number[],\n idx: number[],\n anchorA: number[],\n anchorB: number[],\n anchorT: number[],\n): void {\n const half = width / 2;\n const pts = pl.points;\n const ptCount = pts.length / 2;\n const segCount = ptCount - 1;\n if (segCount < 1) return;\n\n // Anchor params per polyline point (set by extractPolylines; splitForDash\n // re-derives them on dash boundaries). Default to A=B=0,t=0 if missing.\n const plA = pl.anchorA ?? new Uint32Array(ptCount);\n const plB = pl.anchorB ?? new Uint32Array(ptCount);\n const plT = pl.anchorT ?? new Float32Array(ptCount);\n // Per-point distance to each edge: derived from pl.widths and pl.offsets\n // if present, else the uniform half. Indexing matches `pts`.\n const W = pl.widths, O = pl.offsets;\n const pos = (i: number) => (W ? W[i] / 2 : half) + (O ? O[i] : 0);\n const neg = (i: number) => (W ? W[i] / 2 : half) - (O ? O[i] : 0);\n\n const segs: Seg[] = [];\n const segSrcIdx: number[] = []; // For each seg, the polyline-point index of its start.\n for (let s = 0; s < segCount; s++) {\n const seg = makeSeg(pts[s * 2], pts[s * 2 + 1], pts[(s + 1) * 2], pts[(s + 1) * 2 + 1], pos(s), neg(s), pos(s + 1), neg(s + 1));\n if (seg) {\n segs.push(seg);\n segSrcIdx.push(s);\n }\n }\n let closerSrcIdx = -1;\n if (pl.closed && segs.length >= 1) {\n const last = segs[segs.length - 1];\n const first = segs[0];\n // Closer: from last point back to point 0, with the edges resolved at\n // those source indices.\n const closer = makeSeg(last.bx, last.by, first.ax, first.ay, pos(ptCount - 1), neg(ptCount - 1), pos(0), neg(0));\n if (closer) {\n segs.push(closer);\n closerSrcIdx = ptCount - 1; // start is the last polyline point.\n segSrcIdx.push(closerSrcIdx);\n }\n }\n if (segs.length === 0) return;\n\n // Emit ribbon quads. For each emitted vertex, record the (A, B, t) of the\n // source polyline point that the geometric vertex sits at. Per-end\n // half-widths produce trapezoidal segments when the stroke tapers.\n const segBaseIdx: number[] = [];\n for (let s = 0; s < segs.length; s++) {\n const seg = segs[s];\n const startSrc = segSrcIdx[s];\n // End-source index for the seg. For closer (closed-path wraparound), end is point 0.\n const endSrc = (s === segs.length - 1 && pl.closed && closerSrcIdx >= 0) ? 0 : startSrc + 1;\n const base = verts.length / 2;\n segBaseIdx.push(base);\n const { nxUnit: nx, nyUnit: ny } = seg;\n // L0, R0 — at seg.ax/ay, the +n and −n edges.\n verts.push(seg.ax + nx * seg.posA, seg.ay + ny * seg.posA);\n anchorA.push(plA[startSrc]); anchorB.push(plB[startSrc]); anchorT.push(plT[startSrc]);\n verts.push(seg.ax - nx * seg.negA, seg.ay - ny * seg.negA);\n anchorA.push(plA[startSrc]); anchorB.push(plB[startSrc]); anchorT.push(plT[startSrc]);\n // L1, R1 — at seg.bx/by.\n verts.push(seg.bx + nx * seg.posB, seg.by + ny * seg.posB);\n anchorA.push(plA[endSrc]); anchorB.push(plB[endSrc]); anchorT.push(plT[endSrc]);\n verts.push(seg.bx - nx * seg.negB, seg.by - ny * seg.negB);\n anchorA.push(plA[endSrc]); anchorB.push(plB[endSrc]); anchorT.push(plT[endSrc]);\n idx.push(base, base + 1, base + 2, base + 1, base + 3, base + 2);\n }\n\n // Joins between consecutive segments.\n const joinCount = pl.closed ? segs.length : segs.length - 1;\n const inner = meetInnerEdges(segs, segBaseIdx, pl.closed, verts);\n for (let j = 0; j < joinCount; j++) {\n emitJoin(segs, segBaseIdx, j, join, miterLimit, varyingThreshold, verts, idx, anchorA, anchorB, anchorT, segSrcIdx, plA, plB, plT, inner[j]);\n }\n\n // Caps, from the local edges at each end.\n if (!pl.closed && cap !== 'butt') {\n const first = segs[0];\n const firstBase = segBaseIdx[0];\n emitCap(first, firstBase + 0, firstBase + 1, false, first.posA, first.negA, cap, verts, idx, anchorA, anchorB, anchorT, plA[0], plB[0], plT[0]);\n\n const last = segs[segs.length - 1];\n const lastBase = segBaseIdx[segs.length - 1];\n const lastSrc = segSrcIdx[segs.length - 1] + 1;\n emitCap(last, lastBase + 2, lastBase + 3, true, last.posB, last.negB, cap, verts, idx, anchorA, anchorB, anchorT, plA[lastSrc], plB[lastSrc], plT[lastSrc]);\n }\n}\n\n/**\n * Miter limit for a stroke that does not set one. SVG's default, not\n * Canvas2D's 10, because the serializer omits the attribute when the field is\n * unset — so a kit stroke exported to SVG is read back by every other renderer\n * as 4, and a kit that used 10 would disagree with its own export. 10 also\n * lets an acute corner throw a spike four times the half-width, which is what\n * a glyph outline's sharpest vertices do.\n */\nconst DEFAULT_MITER_LIMIT = 4;\n/** Default `Stroke.varyingWidthJoinThreshold`. */\nconst DEFAULT_VARYING_WIDTH_JOIN_THRESHOLD = 1.5;\n","/**\n * Resolving a `MarkerRef` to the distance the ribbon must stop short.\n *\n * The tessellation layer takes these as plain numbers and knows nothing about\n * the registry — keeping that layer free of upward dependencies is deliberate.\n * The ribbon cache, the SVG serializer and `inkReach` all resolve through here,\n * so the ribbon, the export and the hit region cannot disagree about where the\n * line ends.\n */\n\nimport { resolveScreenLength, type MarkerRef, type Stroke } from '@weasel-js/paint';\nimport { getMarker } from './strokeMarkers';\n\n/** The size of one marker unit, in the same world units as `strokeWidth`.\n * `scale` is the view scale a `{ px }` size resolves against, as a `{ px }`\n * stroke width does. */\nexport function resolveMarkerSize(ref: MarkerRef, strokeWidth: number, scale = 1): number {\n if (typeof ref === 'string' || ref.size === undefined) return strokeWidth;\n return resolveScreenLength(ref.size, scale);\n}\n\n/** The registry key a `MarkerRef` names, whether given bare or with a size. */\nexport function markerKeyOf(ref: MarkerRef): string {\n return typeof ref === 'string' ? ref : ref.key;\n}\n\n/**\n * How far back the ribbon stops for `ref`, in world units. Zero for an absent\n * marker, an unregistered key, or an open head — never throws, because an\n * unknown key is a data problem and dropping the head is the graceful answer.\n */\nexport function markerInset(ref: MarkerRef | undefined, strokeWidth: number, scale = 1): number {\n if (ref === undefined) return 0;\n const entry = getMarker(markerKeyOf(ref));\n if (entry === undefined) return 0;\n return (entry.inset ?? 0) * resolveMarkerSize(ref, strokeWidth, scale);\n}\n\n/** The start and end insets a stroke asks for. `markerMid` never insets —\n * trimming at an interior vertex would cut the line in two. */\nexport function strokeInsets(stroke: Stroke, strokeWidth: number): { start: number; end: number } {\n return {\n start: markerInset(stroke.markerStart, strokeWidth),\n end: markerInset(stroke.markerEnd, strokeWidth),\n };\n}\n","/**\n * Where a stroke's markers sit and which way they point.\n *\n * Computed from the *untrimmed* polyline: trimming moves the endpoint, and a\n * marker anchors to where the line was authored to end, not to where the\n * ribbon was cut.\n */\n\nimport type { Polyline } from '@weasel-js/geom/tessellate';\n\n/** One marker placement, in the polyline's own coordinates. */\nexport interface MarkerSite {\n x: number;\n y: number;\n /** Radians. The direction the marker's +X axis should point — outward at a\n * start or end, along the bisector at an interior vertex. */\n angle: number;\n role: 'start' | 'mid' | 'end';\n}\n\n/** Which marker roles to place. `start` and `end` are ignored on a closed polyline. */\nexport interface MarkerSiteRequest {\n start: boolean;\n mid: boolean;\n end: boolean;\n}\n\nconst EPS = 1e-9;\n\n/** Unit direction from point `i` to point `j`, or null if they coincide. */\nfunction dir(pl: Polyline, i: number, j: number): { x: number; y: number } | null {\n const dx = pl.points[j * 2] - pl.points[i * 2];\n const dy = pl.points[j * 2 + 1] - pl.points[i * 2 + 1];\n const len = Math.hypot(dx, dy);\n if (len < EPS) return null;\n return { x: dx / len, y: dy / len };\n}\n\n/** The first index after `i` whose point differs from `i`'s. */\nfunction nextDistinct(pl: Polyline, i: number, n: number): number {\n for (let k = i + 1; k < n; k++) if (dir(pl, i, k)) return k;\n return -1;\n}\nfunction prevDistinct(pl: Polyline, i: number): number {\n for (let k = i - 1; k >= 0; k--) if (dir(pl, k, i)) return k;\n return -1;\n}\n\n/**\n * Where each requested marker sits on `pl` and the angle it points at.\n * Mid sites fall only on authored vertices, never on flattened curve samples,\n * and need the polyline to carry anchor data; without it no mid sites are returned.\n */\nexport function markerSites(pl: Polyline, want: MarkerSiteRequest): MarkerSite[] {\n const out: MarkerSite[] = [];\n const n = pl.points.length / 2;\n if (n < 2) return out;\n\n if (want.start && !pl.closed) {\n const j = nextDistinct(pl, 0, n);\n const d = j >= 0 ? dir(pl, 0, j) : null;\n if (d) {\n // Reversed, so a start head points away from the line body the way an\n // end head does. SVG spells this `auto-start-reverse`; here it is the\n // only behavior.\n out.push({ x: pl.points[0], y: pl.points[1], angle: Math.atan2(-d.y, -d.x), role: 'start' });\n }\n }\n\n if (want.mid) {\n const A = pl.anchorA, B = pl.anchorB, T = pl.anchorT;\n if (A && B && T) {\n for (let i = 1; i < n - 1; i++) {\n // An authored anchor, not a flattened curve sample.\n if (A[i] !== B[i] || T[i] !== 0) continue;\n const p = prevDistinct(pl, i);\n const q = nextDistinct(pl, i, n);\n if (p < 0 || q < 0) continue;\n const inDir = dir(pl, p, i)!;\n const outDir = dir(pl, i, q)!;\n let bx = inDir.x + outDir.x;\n let by = inDir.y + outDir.y;\n // A 180° reversal leaves no bisector; fall back to the arriving direction.\n if (Math.hypot(bx, by) < EPS) { bx = inDir.x; by = inDir.y; }\n out.push({ x: pl.points[i * 2], y: pl.points[i * 2 + 1], angle: Math.atan2(by, bx), role: 'mid' });\n }\n }\n }\n\n if (want.end && !pl.closed) {\n const last = n - 1;\n const p = prevDistinct(pl, last);\n const d = p >= 0 ? dir(pl, p, last) : null;\n if (d) {\n out.push({ x: pl.points[last * 2], y: pl.points[last * 2 + 1], angle: Math.atan2(d.y, d.x), role: 'end' });\n }\n }\n\n return out;\n}\n","/**\n * A stroke's marker heads as placed geometry, and how far they reach.\n */\n\nimport type { MarkerRef, Stroke } from '@weasel-js/paint';\nimport { type Path, type PolygonPath, boundsOfPath } from '@weasel-js/geom';\nimport { extractPolylines } from '@weasel-js/geom/tessellate';\nimport { getMarker, type MarkerEntry } from './strokeMarkers';\nimport { markerKeyOf, resolveMarkerSize } from './markerInset';\nimport { markerSites, type MarkerSite } from './markerSites';\nimport { strokeFlattening } from './tessellate/flattening';\nimport {\n coordsOutOfMetric, polylineIntoMetric, type ScreenSpace, type StrokeSpaces,\n} from './tessellate/metric';\n\n/** Rotate + translate a marker's geometry onto its site, measured from\n * `origin`, the stroked path's, as the site is. */\nfunction placed(path: Path, site: MarkerSite, origin: PolygonPath['origin']): PolygonPath {\n const { origin: _own, ...src } = path as PolygonPath;\n const cos = Math.cos(site.angle);\n const sin = Math.sin(site.angle);\n const coords = new Float32Array(src.coords.length);\n for (let i = 0; i < src.coords.length; i += 2) {\n const x = src.coords[i], y = src.coords[i + 1];\n coords[i] = site.x + x * cos - y * sin;\n coords[i + 1] = site.y + x * sin + y * cos;\n }\n return origin ? { ...src, coords, origin } : { ...src, coords };\n}\n\n/** One head's placed geometry, before any paint is applied. */\nexport interface MarkerHead {\n readonly entry: MarkerEntry;\n readonly path: PolygonPath;\n readonly size: number;\n /** Where it was built, when not in world — `size` is in this space's units. */\n readonly space?: ScreenSpace;\n}\n\n/**\n * Every marker head for `path` under `stroke`, placed but unpainted.\n * `strokeWidth` is the already width-resolved stroke width; `flattenTolerance`\n * matches what the ribbon used, so heads land on the same flattened vertices\n * the stroke did. A head `spaces` puts in a screen space is placed and sized\n * there and comes back in world units, so it meets the line it caps.\n */\nexport function markerHeads(\n path: Path,\n stroke: Stroke,\n strokeWidth: number,\n flattenTolerance: number | undefined,\n spaces: StrokeSpaces = {},\n): MarkerHead[] {\n const refs = { start: stroke.markerStart, mid: stroke.markerMid, end: stroke.markerEnd };\n if (refs.start === undefined && refs.mid === undefined && refs.end === undefined) return [];\n\n // Heads sharing a space share one pass over the polyline mapped into it.\n const groups = new Map<ScreenSpace | undefined, { start: boolean; mid: boolean; end: boolean }>();\n for (const role of ['start', 'mid', 'end'] as const) {\n if (refs[role] === undefined) continue;\n const space = spaces[role];\n let want = groups.get(space);\n if (want === undefined) groups.set(space, (want = { start: false, mid: false, end: false }));\n want[role] = true;\n }\n\n const out: MarkerHead[] = [];\n const origin = path.kind === 'polygon' ? path.origin : undefined;\n for (const pl of extractPolylines(path, strokeFlattening(flattenTolerance, strokeWidth, stroke.vertexWidths))) {\n for (const [space, want] of groups) {\n const inSpace = space ? { ...pl, points: pl.points.slice() } : pl;\n if (space) polylineIntoMetric(inSpace, space.metric);\n for (const site of markerSites(inSpace, want)) {\n const ref: MarkerRef | undefined = refs[site.role];\n if (ref === undefined) continue;\n const entry = getMarker(markerKeyOf(ref));\n if (entry === undefined) continue;\n const size = resolveMarkerSize(ref, strokeWidth);\n const angle = entry.orient === undefined || entry.orient === 'auto' ? site.angle : entry.orient;\n const head = placed(entry.path({ size, stroke }), { ...site, angle }, origin);\n if (space) coordsOutOfMetric(head.coords, space.metric);\n out.push(space ? { entry, size, path: head, space } : { entry, size, path: head });\n }\n }\n }\n return out;\n}\n\n/**\n * A key for the stroke fields `entry`'s geometry reads, or `null` when the\n * entry does not say which it reads and only the stroke's identity can stand\n * in for them.\n */\nexport function markerReadsKey(entry: MarkerEntry, stroke: Stroke): string | null {\n if (entry.reads === undefined) return null;\n let key = '';\n for (const field of entry.reads) key += `${JSON.stringify(stroke[field]) ?? ''}|`;\n return key;\n}\n\n/** Distinct stroke readings kept per entry before its map is dropped. */\nconst READINGS_PER_ENTRY = 64;\n\n/** Each entry's farthest reach from its anchor at `size` 1, outline included,\n * per value of the fields it reads — or per stroke object, when it does not\n * say which. */\nconst REACH_BY_READING = new WeakMap<MarkerEntry, Map<string, number>>();\nconst REACH_BY_STROKE = new WeakMap<MarkerEntry, WeakMap<Stroke, number>>();\n\nfunction measureUnitReach(entry: MarkerEntry, stroke: Stroke): number {\n const b = boundsOfPath(entry.path({ size: 1, stroke }));\n return Math.max(Math.abs(b.x), Math.abs(b.x + b.width), Math.abs(b.y), Math.abs(b.y + b.height))\n + (entry.outline ? entry.outline.width / 2 : 0);\n}\n\nfunction unitReach(entry: MarkerEntry, stroke: Stroke): number {\n const key = markerReadsKey(entry, stroke);\n if (key === null) {\n let byStroke = REACH_BY_STROKE.get(entry);\n if (byStroke === undefined) REACH_BY_STROKE.set(entry, (byStroke = new WeakMap()));\n let reach = byStroke.get(stroke);\n if (reach === undefined) byStroke.set(stroke, (reach = measureUnitReach(entry, stroke)));\n return reach;\n }\n let byReading = REACH_BY_READING.get(entry);\n if (byReading === undefined) REACH_BY_READING.set(entry, (byReading = new Map()));\n let reach = byReading.get(key);\n if (reach === undefined) {\n if (byReading.size >= READINGS_PER_ENTRY) byReading.clear();\n byReading.set(key, (reach = measureUnitReach(entry, stroke)));\n }\n return reach;\n}\n\n/**\n * How far `stroke`'s markers can paint from the vertex each sits on, split by\n * where each is built: `world` in world units for a head with a world size,\n * `px` in screen pixels for one with a `{ px }` size. A head with no size\n * takes the stroke width, and with it the width's units. Culling and a path\n * node's grab reach both measure through here.\n */\nexport function markerReach(stroke: Stroke): { world: number; px: number } {\n const reach = { world: 0, px: 0 };\n const width = stroke.width ?? 1;\n for (const ref of [stroke.markerStart, stroke.markerMid, stroke.markerEnd]) {\n if (ref === undefined) continue;\n const entry = getMarker(markerKeyOf(ref));\n if (entry === undefined) continue;\n const size = typeof ref === 'string' || ref.size === undefined ? width : ref.size;\n const unit = unitReach(entry, stroke);\n if (typeof size === 'number') reach.world = Math.max(reach.world, unit * size);\n else reach.px = Math.max(reach.px, unit * size.px);\n }\n return reach;\n}\n","/**\n * Where a stroke's outline edge runs near a point: what an editor that drags a\n * stroke's edge hit-tests and measures against.\n */\nimport { pointInPath, type Path } from '@weasel-js/geom';\nimport { extractPolylines } from '@weasel-js/geom/tessellate';\nimport type { Stroke } from '@weasel-js/paint';\nimport { strokeFlattening } from './tessellate/flattening';\nimport { nibWidthScale } from './tessellate/nib';\nimport { resolveStrokeWidth } from './tessellate/stroke';\nimport { populateWidths } from './tessellate/vertexWidths';\n\n/** One side of a stroke's ribbon, as `VertexWidth` names them. */\nexport type StrokeSide = 'left' | 'right';\n\n/** A stroke's edge nearest a point, as {@link strokeEdgeNear} finds it. */\nexport interface StrokeEdgeHit {\n /** The point on the path's flattening the edge is measured from. */\n x: number;\n y: number;\n /** The unit normal there, pointing from the path toward the edge. */\n nx: number;\n ny: number;\n /** Which edge this is. */\n side: StrokeSide;\n /** How far each edge sits from the path there, as drawn: per-vertex widths,\n * the nib, and alignment applied. An inner or outer stroke draws one side\n * only, the other being the path itself, at 0. */\n left: number;\n right: number;\n /** How far the query point lies outside the edge; negative inside the ink. */\n gap: number;\n /** What a stored half-width is multiplied by to give the edge's distance\n * there: the nib's factor, doubled for an inner or outer stroke. */\n factor: number;\n}\n\n/** Options for {@link strokeEdgeNear}. */\nexport interface StrokeEdgeOptions {\n /** Screen pixels per world unit, for a `{ px }` width. Default 1. */\n scale?: number;\n flattenTolerance?: number;\n}\n\n/**\n * The edge of `stroke`, drawn along `path`, that passes nearest `(x, y)`,\n * measured along the path's normal: either side of a centered stroke, with\n * per-vertex widths (each side of a pair on its own) and the nib applied. An\n * inner or outer stroke is a centered one twice as wide cut to one side of the\n * path's fill, so its edge is the one on that side, at twice the distance, and\n * a point on the far side is measured to it across the ink. Caps, joins, and\n * markers are not considered. `null` when the path has no segment of any length.\n */\nexport function strokeEdgeNear(\n path: Path, stroke: Stroke, x: number, y: number, opts: StrokeEdgeOptions = {},\n): StrokeEdgeHit | null {\n const width = resolveStrokeWidth(stroke.width ?? 1, opts.scale ?? 1);\n const vw = stroke.vertexWidths && stroke.vertexWidths.length > 0 ? stroke.vertexWidths : null;\n const nibScale = stroke.nib ? nibWidthScale(stroke.nib) : null;\n const align = stroke.align ?? 'center';\n let best: StrokeEdgeHit | null = null;\n for (const pl of extractPolylines(path, strokeFlattening(opts.flattenTolerance, width, vw ?? undefined))) {\n populateWidths(pl, vw, stroke.nib, width);\n const P = pl.points, W = pl.widths, O = pl.offsets;\n const n = P.length / 2;\n const segCount = pl.closed ? n : n - 1;\n const inked = align === 'center' ? null : inkedSide(path, P, segCount, align === 'inner');\n for (let i = 0; i < segCount; i++) {\n const j = (i + 1) % n;\n const ax = P[i * 2], ay = P[i * 2 + 1];\n const dx = P[j * 2] - ax, dy = P[j * 2 + 1] - ay;\n const len2 = dx * dx + dy * dy;\n if (len2 === 0) continue;\n const len = Math.sqrt(len2);\n const f = Math.min(1, Math.max(0, ((x - ax) * dx + (y - ay) * dy) / len2));\n const fx = ax + dx * f, fy = ay + dy * f;\n const rx = -dy / len, ry = dx / len;\n const d = (x - fx) * rx + (y - fy) * ry;\n const w = W ? W[i] + (W[j] - W[i]) * f : width;\n const o = O ? O[i] + (O[j] - O[i]) * f : 0;\n const side: StrokeSide = inked ?? (d >= 0 ? 'right' : 'left');\n const scale = inked ? 2 : 1;\n const left = inked === 'right' ? 0 : scale * (w / 2 - o);\n const right = inked === 'left' ? 0 : scale * (w / 2 + o);\n const edge = side === 'right' ? right : left;\n // Past a segment's end the point is off its normal, so the gap is the\n // straight distance, not the distance across the line.\n const off = Math.hypot(x - fx, y - fy);\n const gap = inked && (d >= 0) !== (inked === 'right') ? off + edge : off - edge;\n if (best !== null && Math.abs(gap) >= Math.abs(best.gap)) continue;\n const sign = side === 'right' ? 1 : -1;\n best = {\n x: fx, y: fy, nx: rx * sign, ny: ry * sign, side, left, right, gap,\n factor: scale * (nibScale ? nibScale(dx / len, dy / len) : 1),\n };\n }\n }\n return best;\n}\n\n/** The side of a flattened subpath an aligned stroke inks: the one inside\n * `path`'s fill for an inner stroke, outside for an outer. Read once, beside\n * the longest segment, since a subpath that does not cross itself keeps its\n * fill on one side. */\nfunction inkedSide(path: Path, P: ArrayLike<number>, segCount: number, inner: boolean): StrokeSide {\n const n = P.length / 2;\n let at = -1, longest = 0;\n for (let i = 0; i < segCount; i++) {\n const j = (i + 1) % n;\n const l = Math.hypot(P[j * 2] - P[i * 2], P[j * 2 + 1] - P[i * 2 + 1]);\n if (l > longest) { longest = l; at = i; }\n }\n if (at < 0) return inner ? 'right' : 'left';\n const j = (at + 1) % n;\n const dx = P[j * 2] - P[at * 2], dy = P[j * 2 + 1] - P[at * 2 + 1];\n const probe = Math.min(longest, 1) * 1e-3;\n const mx = (P[at * 2] + P[j * 2]) / 2 - (dy / longest) * probe;\n const my = (P[at * 2 + 1] + P[j * 2 + 1]) / 2 + (dx / longest) * probe;\n return pointInPath(path, mx, my) === inner ? 'right' : 'left';\n}\n","/**\n * A stroke as geometry: the region its ink covers, as a fillable path.\n *\n * The ribbon the renderer draws already has the joins, caps, dashes, and\n * marker trims; unioning its triangles gives the silhouette with every\n * self-overlap resolved, so the outline and the drawn stroke cannot disagree.\n */\nimport { scaleVertexWidth, type Stroke } from '@weasel-js/paint';\nimport { invert, transformPath, type Affine, type Path, type PolygonPath } from '@weasel-js/geom';\nimport { pathIntersect, pathSubtract, pathUnion, trianglesToPath } from '@weasel-js/geom/booleans';\nimport { strokeInsets } from './markerInset';\nimport { resolveStrokeWidth, tessellateStroke } from './tessellate/stroke';\nimport { markerHeads } from './markerHeads';\n\n/** Options for {@link strokeToPath}. */\nexport interface StrokeToPathOptions {\n /** Screen pixels per world unit, for a `{ px }` width or marker size.\n * Default 1. */\n scale?: number;\n /** Flatness tolerance for curves, in the path's units. */\n flattenTolerance?: number;\n /**\n * The frame the stroke is drawn in, as the matrix taking that frame to the\n * path's coordinates: a node's `poseFrameOf`. A frame that skews or\n * stretches does the same to the stroke, as it does on the canvas. For a\n * `{ px }` width under a view that scales each axis apart, the frame is the\n * screen: the inverse of the view's scale, with `scale` left at 1.\n */\n frame?: Affine;\n}\n\nconst EMPTY: PolygonPath = {\n kind: 'polygon', commands: new Uint8Array(0), coords: new Float32Array(0), fillRule: 'nonzero',\n};\n\n/**\n * The region `stroke` covers when drawn along `path`, as a path to fill:\n * width, cap, join, miter limit, dash, alignment, per-vertex widths, and\n * marker heads all included. Curves are flattened, so the result holds only\n * M/L/Z. A stroke with no width answers an empty path, and so does one drawn\n * in a `frame` that flattens it.\n */\nexport function strokeToPath(path: Path, stroke: Stroke, opts: StrokeToPathOptions = {}): PolygonPath {\n const { frame, ...drawn } = opts;\n if (!frame) return outlineOf(path, stroke, drawn);\n const back = invert(frame);\n if (!back) return EMPTY;\n return transformPath(outlineOf(transformPath(path, back), stroke, drawn), frame) as PolygonPath;\n}\n\nfunction outlineOf(path: Path, stroke: Stroke, opts: StrokeToPathOptions): PolygonPath {\n // The ribbon, the heads and the booleans all work in the path's own offsets.\n if (path.kind === 'polygon' && path.origin) {\n const { origin, ...offsets } = path;\n const out = outlineOf(offsets, stroke, opts);\n return out.coords.length === 0 ? out : { ...out, origin };\n }\n const width = resolveStrokeWidth(stroke.width ?? 1, opts.scale ?? 1);\n if (!(width > 0)) return EMPTY;\n const tolerance = opts.flattenTolerance;\n const sized: Stroke = { ...stroke, width };\n const insets = strokeInsets(sized, width);\n const align = stroke.align ?? 'center';\n // A rect's aligned ribbon is built in place. Any other path gets a centered\n // ribbon twice as wide, cut to the side of the path it belongs on.\n const cut = align !== 'center' && path.kind !== 'rect';\n const ribbonStroke: Stroke = cut\n ? { ...sized, width: width * 2, align: 'center', vertexWidths: stroke.vertexWidths?.map((w) => scaleVertexWidth(w, 2)) }\n : sized;\n const mesh = tessellateStroke(path, ribbonStroke, {\n flattenTolerance: tolerance, startInset: insets.start, endInset: insets.end,\n });\n let ribbon = trianglesToPath(mesh.vertices, mesh.indices);\n if (cut) ribbon = align === 'inner' ? pathIntersect(ribbon, path) : pathSubtract(ribbon, path);\n\n const heads: PolygonPath[] = [];\n for (const { entry, path: head, size } of markerHeads(path, sized, width, tolerance)) {\n if ((entry.fill ?? 'line') !== 'none') heads.push(head);\n if (entry.outline && (entry.outline.paint ?? 'line') !== 'none') {\n heads.push(strokeToPath(head, { width: entry.outline.width * size, cap: 'round', join: 'round' }, opts));\n }\n }\n return heads.length === 0 ? ribbon : pathUnion(ribbon, ...heads);\n}\n","import {\n anchorsToPath, offsetCornerTraces, pathToAnchors, resolveCorners, restoreCorners, simplifyPath,\n type Path, type PolygonPath,\n} from '@weasel-js/geom';\nimport { pathSubtract, pathUnion } from '@weasel-js/geom/booleans';\nimport { strokeToPath } from './strokeToPath';\n\n/** Options for {@link offsetPath}. */\nexport interface OffsetPathOptions {\n /** How the offset outline turns a corner. Default `'miter'`. */\n join?: 'miter' | 'round' | 'bevel';\n /** Past this ratio of miter length to distance a miter corner is beveled.\n * Default 4. */\n miterLimit?: number;\n /** How closely curves are followed, in the path's units. Default 0.1. */\n tolerance?: number;\n /** Refit the outline's flattened curves as cubics (`simplifyPath` at\n * `tolerance`). Default true; false leaves a polygon. */\n refit?: boolean;\n}\n\n/**\n * The outline of the region `path` fills, grown by `distance` (shrunk by a\n * negative one), as a path to fill. Every subpath counts as closed. The\n * outline is where a stroke of twice `distance` centered on the path has its\n * outer (or inner) edge, so it takes that stroke's joins; overlaps resolve\n * the way a union does, and a region shrunk past its own width is gone.\n * Returns an empty path when nothing is left.\n */\nexport function offsetPath(path: Path, distance: number, opts: OffsetPathOptions = {}): PolygonPath {\n if (distance === 0) return closedRegion(path);\n const region = closedRegion(resolveCorners(path));\n const tolerance = opts.tolerance ?? 0.1;\n const band = strokeToPath(region, {\n width: Math.abs(distance) * 2,\n join: opts.join ?? 'miter',\n miterLimit: opts.miterLimit ?? 4,\n }, { flattenTolerance: tolerance });\n const cut = distance > 0 ? pathUnion(region, band) : pathSubtract(region, band);\n const corners = offsetCornerTraces(path, distance);\n // Tried before the refit, which can move a cut's ends off its anchors, and\n // after it, which can clear what the union left beside the cut.\n const grown = restoreCorners(cut, corners, tolerance);\n if (opts.refit === false || grown.commands.length === 0) return grown;\n return restoreCorners(simplifyPath(grown, tolerance), corners, tolerance);\n}\n\n/** `path` with every subpath closed. */\nfunction closedRegion(path: Path): PolygonPath {\n if (path.kind === 'rect') {\n const { x, y, width: w, height: h } = path;\n return anchorsToPath([[{ x, y }, { x: x + w, y }, { x: x + w, y: y + h }, { x, y: y + h }]], [true]);\n }\n const { anchors, closed } = pathToAnchors(path);\n if (closed.every(Boolean)) return path;\n return anchorsToPath(anchors, closed.map(() => true), path);\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@weasel-js/stroke",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.15.0",
|
|
4
4
|
"description": "A stroke as geometry: the ribbon mesh with joins, caps, dashes and per-vertex widths, the marker registry and its placed heads, and a stroke's outline as a path. No scene graph, no React.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -20,9 +20,9 @@
|
|
|
20
20
|
"./package.json": "./package.json"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@weasel-js/geom": "1.
|
|
24
|
-
"@weasel-js/paint": "1.
|
|
25
|
-
"@weasel-js/registry": "1.
|
|
23
|
+
"@weasel-js/geom": "1.15.0",
|
|
24
|
+
"@weasel-js/paint": "1.15.0",
|
|
25
|
+
"@weasel-js/registry": "1.15.0"
|
|
26
26
|
},
|
|
27
27
|
"author": "orochi235",
|
|
28
28
|
"homepage": "https://orochi235.github.io/weasel/",
|