@weasel-js/geom 1.10.0 → 1.11.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/README.md +140 -16
- package/dist/3d/index.d.ts +29 -2
- package/dist/3d/index.js +49 -1
- package/dist/3d/index.js.map +1 -1
- package/dist/booleans/index.d.ts +34 -10
- package/dist/booleans/index.js +344 -352
- package/dist/booleans/index.js.map +1 -1
- package/dist/{chunk-MDT7F32A.js → chunk-6XSJY3TC.js} +10 -39
- package/dist/chunk-6XSJY3TC.js.map +1 -0
- package/dist/chunk-7KLJZFBY.js +573 -0
- package/dist/chunk-7KLJZFBY.js.map +1 -0
- package/dist/chunk-B53BERKG.js +386 -0
- package/dist/chunk-B53BERKG.js.map +1 -0
- package/dist/chunk-CE7IY7TB.js +104 -0
- package/dist/chunk-CE7IY7TB.js.map +1 -0
- package/dist/chunk-HGF5OVEN.js +129 -0
- package/dist/chunk-HGF5OVEN.js.map +1 -0
- package/dist/chunk-J2O2B54M.js +800 -0
- package/dist/chunk-J2O2B54M.js.map +1 -0
- package/dist/chunk-Q66NA2FU.js +174 -0
- package/dist/chunk-Q66NA2FU.js.map +1 -0
- package/dist/chunk-SASMXDBE.js +443 -0
- package/dist/chunk-SASMXDBE.js.map +1 -0
- package/dist/chunk-UI3FUWXM.js +533 -0
- package/dist/chunk-UI3FUWXM.js.map +1 -0
- package/dist/curvature-PkoLduGc.d.ts +454 -0
- package/dist/curves/index.d.ts +14 -5
- package/dist/curves/index.js +33 -111
- package/dist/curves/index.js.map +1 -1
- package/dist/index.d.ts +1697 -205
- package/dist/index.js +4729 -1308
- package/dist/index.js.map +1 -1
- package/dist/nd/index.d.ts +91 -27
- package/dist/nd/index.js +282 -0
- package/dist/nd/index.js.map +1 -1
- package/dist/path-BW8d_2RY.d.ts +157 -0
- package/dist/portCurve-C5HDWuuV.d.ts +30 -0
- package/dist/tessellate/index.d.ts +18 -4
- package/dist/tessellate/index.js +21 -277
- package/dist/tessellate/index.js.map +1 -1
- package/dist/warp/index.d.ts +252 -0
- package/dist/warp/index.js +1316 -0
- package/dist/warp/index.js.map +1 -0
- package/package.json +5 -1
- package/dist/chunk-MDT7F32A.js.map +0 -1
- package/dist/chunk-OXH3NOXC.js +0 -62
- package/dist/chunk-OXH3NOXC.js.map +0 -1
- package/dist/chunk-URQMDR6Q.js +0 -80
- package/dist/chunk-URQMDR6Q.js.map +0 -1
- package/dist/chunk-WQMYOCFB.js +0 -167
- package/dist/chunk-WQMYOCFB.js.map +0 -1
- package/dist/chunk-XS6ERH3X.js +0 -34
- package/dist/chunk-XS6ERH3X.js.map +0 -1
- package/dist/cubicMath-CFXbq6vp.d.ts +0 -116
- package/dist/path-Bf9KeVxC.d.ts +0 -44
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as Path } from '../path-
|
|
1
|
+
import { a as Path } from '../path-BW8d_2RY.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* A tessellated representation of a Path, ready to upload to GL.
|
|
@@ -51,10 +51,18 @@ interface Polyline {
|
|
|
51
51
|
/** Per-point stroke width, populated by the tessellator when the Stroke
|
|
52
52
|
* carries `vertexWidths`. Undefined means uniform `Stroke.width`. */
|
|
53
53
|
widths?: Float32Array;
|
|
54
|
+
/** Per-point distance the ribbon's middle sits off the path toward the
|
|
55
|
+
* normal `(−dy, dx)` of the direction of travel: half the right edge's
|
|
56
|
+
* distance less the left's. Set alongside `widths` only when the two sides
|
|
57
|
+
* differ somewhere; undefined means centered. */
|
|
58
|
+
offsets?: Float32Array;
|
|
54
59
|
}
|
|
55
60
|
/** Options for `extractPolylines`. */
|
|
56
61
|
interface ExtractOptions {
|
|
57
62
|
flattenTolerance?: number;
|
|
63
|
+
/** Most a curve may turn, in radians, between two flattened vertices.
|
|
64
|
+
* Unbounded when unset. */
|
|
65
|
+
maxTurn?: number;
|
|
58
66
|
}
|
|
59
67
|
/** Flatten each contour of a path to a straight-segment polyline, carrying the
|
|
60
68
|
* anchor parameterization per point. A rect yields one closed contour. */
|
|
@@ -66,8 +74,7 @@ declare function extractPolylines(path: Path, opts?: ExtractOptions): Polyline[]
|
|
|
66
74
|
* stroke — so this is the one place our rendering deliberately differs.
|
|
67
75
|
*
|
|
68
76
|
* Runs before dash splitting, so a dash pattern fits the visible line rather
|
|
69
|
-
* than running off under the head.
|
|
70
|
-
* `splitForDash`'s rule for a boundary landing mid-segment.
|
|
77
|
+
* than running off under the head.
|
|
71
78
|
*/
|
|
72
79
|
|
|
73
80
|
/**
|
|
@@ -80,4 +87,11 @@ declare function extractPolylines(path: Path, opts?: ExtractOptions): Polyline[]
|
|
|
80
87
|
*/
|
|
81
88
|
declare function trimPolyline(pl: Polyline, startInset: number, endInset: number): Polyline | null;
|
|
82
89
|
|
|
83
|
-
|
|
90
|
+
/**
|
|
91
|
+
* The anchor parameters `(A, B, t)` of a point a fraction `frac` of the way
|
|
92
|
+
* from one polyline point to the next: `t` interpolated when both lie between
|
|
93
|
+
* the same two anchors, otherwise the nearer point's own.
|
|
94
|
+
*/
|
|
95
|
+
declare function anchorParamsBetween(a0: number, b0: number, t0: number, a1: number, b1: number, t1: number, frac: number): [number, number, number];
|
|
96
|
+
|
|
97
|
+
export { type ExtractOptions, type Mesh, type Polyline, type TessellateOptions, anchorParamsBetween, extractPolylines, tessellate, trimPolyline };
|
package/dist/tessellate/index.js
CHANGED
|
@@ -1,267 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
export {
|
|
3
|
-
import
|
|
1
|
+
export { extractPolylines } from '../chunk-6XSJY3TC.js';
|
|
2
|
+
export { tessellate } from '../chunk-SASMXDBE.js';
|
|
3
|
+
import '../chunk-J2O2B54M.js';
|
|
4
4
|
import '../chunk-755Y4YZS.js';
|
|
5
|
-
import
|
|
6
|
-
import earcut from 'earcut';
|
|
5
|
+
import '../chunk-B53BERKG.js';
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
return
|
|
11
|
-
|
|
12
|
-
function tessellateRect(p) {
|
|
13
|
-
const { x, y, width: w, height: h } = p;
|
|
14
|
-
return {
|
|
15
|
-
vertices: Float32Array.from(rectToContour(x, y, w, h)),
|
|
16
|
-
indices: new Uint32Array([0, 1, 2, 0, 2, 3]),
|
|
17
|
-
anchorA: new Uint32Array([0, 1, 2, 3]),
|
|
18
|
-
anchorB: new Uint32Array([0, 1, 2, 3]),
|
|
19
|
-
anchorT: new Float32Array([0, 0, 0, 0])
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
function flattenPolygon(p, tolerance) {
|
|
23
|
-
const closed = /* @__PURE__ */ new Set();
|
|
24
|
-
const all = flattenContours(p, tolerance, closed);
|
|
25
|
-
if (fillsOpenSubpaths(p)) return all;
|
|
26
|
-
const kept = { coords: [], contourStarts: [], anchorA: [], anchorB: [], anchorT: [] };
|
|
27
|
-
all.contourStarts.forEach((start, c) => {
|
|
28
|
-
if (!closed.has(c)) return;
|
|
29
|
-
const end = c + 1 < all.contourStarts.length ? all.contourStarts[c + 1] : all.coords.length / 2;
|
|
30
|
-
kept.contourStarts.push(kept.coords.length / 2);
|
|
31
|
-
kept.coords.push(...all.coords.slice(start * 2, end * 2));
|
|
32
|
-
kept.anchorA.push(...all.anchorA.slice(start, end));
|
|
33
|
-
kept.anchorB.push(...all.anchorB.slice(start, end));
|
|
34
|
-
kept.anchorT.push(...all.anchorT.slice(start, end));
|
|
35
|
-
});
|
|
36
|
-
return kept;
|
|
37
|
-
}
|
|
38
|
-
function flattenContours(p, tolerance, closed) {
|
|
39
|
-
const { commands, coords } = p;
|
|
40
|
-
const out = [];
|
|
41
|
-
const anchorA = [];
|
|
42
|
-
const anchorB = [];
|
|
43
|
-
const anchorT = [];
|
|
44
|
-
const contourStarts = [];
|
|
45
|
-
let startAnchor = -1;
|
|
46
|
-
let prevAnchor = -1;
|
|
47
|
-
let anchorCounter = 0;
|
|
48
|
-
const pushCurveAnchors = (anchorStart, arcAccum, total, target) => {
|
|
49
|
-
for (let k = 0; k < arcAccum.length; k++) {
|
|
50
|
-
anchorA.push(prevAnchor);
|
|
51
|
-
anchorB.push(target);
|
|
52
|
-
anchorT.push(total > 0 ? arcAccum[k] / total : 0);
|
|
53
|
-
}
|
|
54
|
-
const lastIdx = anchorStart + arcAccum.length - 1;
|
|
55
|
-
anchorA[lastIdx] = target;
|
|
56
|
-
anchorB[lastIdx] = target;
|
|
57
|
-
anchorT[lastIdx] = 0;
|
|
58
|
-
};
|
|
59
|
-
forEachSegment(commands, coords, (cmd, coordIdx, prevX, prevY, _i, opensSubpath) => {
|
|
60
|
-
if (opensSubpath) {
|
|
61
|
-
const anchor = Math.max(startAnchor, 0);
|
|
62
|
-
contourStarts.push(out.length / 2);
|
|
63
|
-
out.push(prevX, prevY);
|
|
64
|
-
anchorA.push(anchor);
|
|
65
|
-
anchorB.push(anchor);
|
|
66
|
-
anchorT.push(0);
|
|
67
|
-
prevAnchor = anchor;
|
|
68
|
-
}
|
|
69
|
-
switch (cmd) {
|
|
70
|
-
case PATH_M:
|
|
71
|
-
case PATH_L: {
|
|
72
|
-
if (cmd === PATH_M) {
|
|
73
|
-
contourStarts.push(out.length / 2);
|
|
74
|
-
startAnchor = anchorCounter;
|
|
75
|
-
}
|
|
76
|
-
out.push(coords[coordIdx], coords[coordIdx + 1]);
|
|
77
|
-
anchorA.push(anchorCounter);
|
|
78
|
-
anchorB.push(anchorCounter);
|
|
79
|
-
anchorT.push(0);
|
|
80
|
-
prevAnchor = anchorCounter;
|
|
81
|
-
anchorCounter++;
|
|
82
|
-
break;
|
|
83
|
-
}
|
|
84
|
-
case PATH_Q: {
|
|
85
|
-
const target = anchorCounter;
|
|
86
|
-
const arcAccum = [];
|
|
87
|
-
const anchorStart = anchorA.length;
|
|
88
|
-
const total = flattenQuadraticWithArcLen(
|
|
89
|
-
prevX,
|
|
90
|
-
prevY,
|
|
91
|
-
coords[coordIdx],
|
|
92
|
-
coords[coordIdx + 1],
|
|
93
|
-
coords[coordIdx + 2],
|
|
94
|
-
coords[coordIdx + 3],
|
|
95
|
-
tolerance,
|
|
96
|
-
out,
|
|
97
|
-
arcAccum
|
|
98
|
-
);
|
|
99
|
-
pushCurveAnchors(anchorStart, arcAccum, total, target);
|
|
100
|
-
prevAnchor = target;
|
|
101
|
-
anchorCounter++;
|
|
102
|
-
break;
|
|
103
|
-
}
|
|
104
|
-
case PATH_C: {
|
|
105
|
-
const target = anchorCounter;
|
|
106
|
-
const arcAccum = [];
|
|
107
|
-
const anchorStart = anchorA.length;
|
|
108
|
-
const total = flattenCubicWithArcLen(
|
|
109
|
-
prevX,
|
|
110
|
-
prevY,
|
|
111
|
-
coords[coordIdx],
|
|
112
|
-
coords[coordIdx + 1],
|
|
113
|
-
coords[coordIdx + 2],
|
|
114
|
-
coords[coordIdx + 3],
|
|
115
|
-
coords[coordIdx + 4],
|
|
116
|
-
coords[coordIdx + 5],
|
|
117
|
-
tolerance,
|
|
118
|
-
out,
|
|
119
|
-
arcAccum
|
|
120
|
-
);
|
|
121
|
-
pushCurveAnchors(anchorStart, arcAccum, total, target);
|
|
122
|
-
prevAnchor = target;
|
|
123
|
-
anchorCounter++;
|
|
124
|
-
break;
|
|
125
|
-
}
|
|
126
|
-
case PATH_Z:
|
|
127
|
-
closed.add(contourStarts.length - 1);
|
|
128
|
-
prevAnchor = startAnchor;
|
|
129
|
-
break;
|
|
130
|
-
default:
|
|
131
|
-
throw new Error(`tessellate: unknown command code ${cmd}`);
|
|
132
|
-
}
|
|
133
|
-
});
|
|
134
|
-
return { coords: out, contourStarts, anchorA, anchorB, anchorT };
|
|
135
|
-
}
|
|
136
|
-
function tessellatePolygon(p, opts) {
|
|
137
|
-
const tolerance = opts.flattenTolerance ?? DEFAULT_FLATTEN_TOLERANCE;
|
|
138
|
-
const { coords, contourStarts, anchorA, anchorB, anchorT } = flattenPolygon(p, tolerance);
|
|
139
|
-
if (p.fillRule === "evenodd") {
|
|
140
|
-
return tessellateEvenoddWithAnchors(coords, contourStarts, anchorA, anchorB, anchorT);
|
|
141
|
-
}
|
|
142
|
-
const totalVerts = coords.length / 2;
|
|
143
|
-
const contourEnd = (i) => i + 1 < contourStarts.length ? contourStarts[i + 1] : totalVerts;
|
|
144
|
-
if (contourStarts.length <= 1) {
|
|
145
|
-
const tri = earcut(coords);
|
|
146
|
-
return {
|
|
147
|
-
vertices: new Float32Array(coords),
|
|
148
|
-
indices: new Uint32Array(tri),
|
|
149
|
-
anchorA: new Uint32Array(anchorA),
|
|
150
|
-
anchorB: new Uint32Array(anchorB),
|
|
151
|
-
anchorT: new Float32Array(anchorT)
|
|
152
|
-
};
|
|
153
|
-
}
|
|
154
|
-
const areas = contourStarts.map((s, i) => signedArea(coords, s, contourEnd(i)));
|
|
155
|
-
const refSign = Math.sign(areas[0]) || 1;
|
|
156
|
-
const positives = [];
|
|
157
|
-
const negatives = [];
|
|
158
|
-
for (let i = 0; i < contourStarts.length; i++) {
|
|
159
|
-
if (areas[i] === 0) continue;
|
|
160
|
-
if (Math.sign(areas[i]) === refSign) positives.push(i);
|
|
161
|
-
else negatives.push(i);
|
|
162
|
-
}
|
|
163
|
-
if (positives.length === 1 && negatives.length > 0) {
|
|
164
|
-
const holeIndices = contourStarts.slice(1);
|
|
165
|
-
const tri = earcut(coords, holeIndices);
|
|
166
|
-
return {
|
|
167
|
-
vertices: new Float32Array(coords),
|
|
168
|
-
indices: new Uint32Array(tri),
|
|
169
|
-
anchorA: new Uint32Array(anchorA),
|
|
170
|
-
anchorB: new Uint32Array(anchorB),
|
|
171
|
-
anchorT: new Float32Array(anchorT)
|
|
172
|
-
};
|
|
173
|
-
}
|
|
174
|
-
const holesByPositive = /* @__PURE__ */ new Map();
|
|
175
|
-
const orphanPositives = [];
|
|
176
|
-
for (const n of negatives) {
|
|
177
|
-
const px = coords[contourStarts[n] * 2];
|
|
178
|
-
const py = coords[contourStarts[n] * 2 + 1];
|
|
179
|
-
let bestPos = -1;
|
|
180
|
-
let bestAbsArea = Infinity;
|
|
181
|
-
for (const pos of positives) {
|
|
182
|
-
const absArea = Math.abs(areas[pos]);
|
|
183
|
-
if (absArea < bestAbsArea && pointInPolygon(coords, px, py, contourStarts[pos], contourEnd(pos))) {
|
|
184
|
-
bestAbsArea = absArea;
|
|
185
|
-
bestPos = pos;
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
if (bestPos >= 0) {
|
|
189
|
-
const arr = holesByPositive.get(bestPos) ?? [];
|
|
190
|
-
arr.push(n);
|
|
191
|
-
holesByPositive.set(bestPos, arr);
|
|
192
|
-
} else {
|
|
193
|
-
orphanPositives.push(n);
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
const allPositives = [...positives, ...orphanPositives];
|
|
197
|
-
const finalCoords = [];
|
|
198
|
-
const finalAnchorA = [];
|
|
199
|
-
const finalAnchorB = [];
|
|
200
|
-
const finalAnchorT = [];
|
|
201
|
-
const finalIndices = [];
|
|
202
|
-
for (const pos of allPositives) {
|
|
203
|
-
const holes = holesByPositive.get(pos) ?? [];
|
|
204
|
-
const offset = finalCoords.length / 2;
|
|
205
|
-
const groupCoords = [];
|
|
206
|
-
const groupStarts = [0];
|
|
207
|
-
for (let i = contourStarts[pos]; i < contourEnd(pos); i++) {
|
|
208
|
-
groupCoords.push(coords[i * 2], coords[i * 2 + 1]);
|
|
209
|
-
finalAnchorA.push(anchorA[i]);
|
|
210
|
-
finalAnchorB.push(anchorB[i]);
|
|
211
|
-
finalAnchorT.push(anchorT[i]);
|
|
212
|
-
}
|
|
213
|
-
for (const h of holes) {
|
|
214
|
-
groupStarts.push(groupCoords.length / 2);
|
|
215
|
-
for (let i = contourStarts[h]; i < contourEnd(h); i++) {
|
|
216
|
-
groupCoords.push(coords[i * 2], coords[i * 2 + 1]);
|
|
217
|
-
finalAnchorA.push(anchorA[i]);
|
|
218
|
-
finalAnchorB.push(anchorB[i]);
|
|
219
|
-
finalAnchorT.push(anchorT[i]);
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
const tri = earcut(groupCoords, groupStarts.length > 1 ? groupStarts.slice(1) : void 0);
|
|
223
|
-
for (const v of groupCoords) finalCoords.push(v);
|
|
224
|
-
for (const idx of tri) finalIndices.push(idx + offset);
|
|
225
|
-
}
|
|
226
|
-
return {
|
|
227
|
-
vertices: new Float32Array(finalCoords),
|
|
228
|
-
indices: new Uint32Array(finalIndices),
|
|
229
|
-
anchorA: new Uint32Array(finalAnchorA),
|
|
230
|
-
anchorB: new Uint32Array(finalAnchorB),
|
|
231
|
-
anchorT: new Float32Array(finalAnchorT)
|
|
232
|
-
};
|
|
233
|
-
}
|
|
234
|
-
function tessellateEvenoddWithAnchors(coords, contourStarts, anchorA, anchorB, anchorT) {
|
|
235
|
-
const indices = [];
|
|
236
|
-
const totalVerts = coords.length / 2;
|
|
237
|
-
for (let c = 0; c < contourStarts.length; c++) {
|
|
238
|
-
const start = contourStarts[c];
|
|
239
|
-
const end = c + 1 < contourStarts.length ? contourStarts[c + 1] : totalVerts;
|
|
240
|
-
for (let i = start + 1; i < end - 1; i++) {
|
|
241
|
-
indices.push(start, i, i + 1);
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
return {
|
|
245
|
-
vertices: new Float32Array(coords),
|
|
246
|
-
indices: new Uint32Array(indices),
|
|
247
|
-
requiresStencil: true,
|
|
248
|
-
anchorA: new Uint32Array(anchorA),
|
|
249
|
-
anchorB: new Uint32Array(anchorB),
|
|
250
|
-
anchorT: new Float32Array(anchorT)
|
|
251
|
-
};
|
|
252
|
-
}
|
|
253
|
-
function signedArea(coords, start, end) {
|
|
254
|
-
let a = 0;
|
|
255
|
-
for (let i = start; i < end; i++) {
|
|
256
|
-
const j = i + 1 === end ? start : i + 1;
|
|
257
|
-
a += coords[i * 2] * coords[j * 2 + 1] - coords[j * 2] * coords[i * 2 + 1];
|
|
258
|
-
}
|
|
259
|
-
return a * 0.5;
|
|
7
|
+
// src/tessellate/anchorParams.ts
|
|
8
|
+
function anchorParamsBetween(a0, b0, t0, a1, b1, t1, frac) {
|
|
9
|
+
if (a0 === a1 && b0 === b1) return [a0, b0, t0 + (t1 - t0) * frac];
|
|
10
|
+
return frac < 0.5 ? [a0, b0, t0] : [a1, b1, t1];
|
|
260
11
|
}
|
|
261
12
|
|
|
262
13
|
// src/tessellate/trim.ts
|
|
263
14
|
var EPS = 1e-9;
|
|
264
|
-
function sampleAt(pl, cum, A, B, T, W, dist, vertexFollows) {
|
|
15
|
+
function sampleAt(pl, cum, A, B, T, W, O, dist, vertexFollows) {
|
|
265
16
|
const n = cum.length;
|
|
266
17
|
let i = 1;
|
|
267
18
|
while (i < n - 1 && (vertexFollows ? cum[i] <= dist : cum[i] < dist)) i++;
|
|
@@ -270,22 +21,10 @@ function sampleAt(pl, cum, A, B, T, W, dist, vertexFollows) {
|
|
|
270
21
|
const f = segLen > EPS ? (dist - segStart) / segLen : 0;
|
|
271
22
|
const px = pl.points[(i - 1) * 2], py = pl.points[(i - 1) * 2 + 1];
|
|
272
23
|
const qx = pl.points[i * 2], qy = pl.points[i * 2 + 1];
|
|
273
|
-
|
|
274
|
-
if (A[i - 1] === A[i] && B[i - 1] === B[i]) {
|
|
275
|
-
a = A[i - 1];
|
|
276
|
-
b = B[i - 1];
|
|
277
|
-
t = T[i - 1] + (T[i] - T[i - 1]) * f;
|
|
278
|
-
} else if (f < 0.5) {
|
|
279
|
-
a = A[i - 1];
|
|
280
|
-
b = B[i - 1];
|
|
281
|
-
t = T[i - 1];
|
|
282
|
-
} else {
|
|
283
|
-
a = A[i];
|
|
284
|
-
b = B[i];
|
|
285
|
-
t = T[i];
|
|
286
|
-
}
|
|
24
|
+
const [a, b, t] = anchorParamsBetween(A[i - 1], B[i - 1], T[i - 1], A[i], B[i], T[i], f);
|
|
287
25
|
const w = W ? W[i - 1] + (W[i] - W[i - 1]) * f : 0;
|
|
288
|
-
|
|
26
|
+
const o = O ? O[i - 1] + (O[i] - O[i - 1]) * f : 0;
|
|
27
|
+
return { x: px + (qx - px) * f, y: py + (qy - py) * f, a, b, t, w, o, next: i };
|
|
289
28
|
}
|
|
290
29
|
function trimPolyline(pl, startInset, endInset) {
|
|
291
30
|
const from = Math.max(0, startInset);
|
|
@@ -298,6 +37,7 @@ function trimPolyline(pl, startInset, endInset) {
|
|
|
298
37
|
const B = pl.anchorB ?? new Uint32Array(n);
|
|
299
38
|
const T = pl.anchorT ?? new Float32Array(n);
|
|
300
39
|
const W = pl.widths;
|
|
40
|
+
const O = pl.offsets;
|
|
301
41
|
const cum = new Float64Array(n);
|
|
302
42
|
for (let i = 1; i < n; i++) {
|
|
303
43
|
const dx = pl.points[i * 2] - pl.points[(i - 1) * 2];
|
|
@@ -308,35 +48,39 @@ function trimPolyline(pl, startInset, endInset) {
|
|
|
308
48
|
const cutA = from;
|
|
309
49
|
const cutB = total - to;
|
|
310
50
|
if (cutB - cutA <= EPS) return null;
|
|
311
|
-
const head = sampleAt(pl, cum, A, B, T, W, cutA, true);
|
|
312
|
-
const tail = sampleAt(pl, cum, A, B, T, W, cutB, false);
|
|
51
|
+
const head = sampleAt(pl, cum, A, B, T, W, O, cutA, true);
|
|
52
|
+
const tail = sampleAt(pl, cum, A, B, T, W, O, cutB, false);
|
|
313
53
|
const points = [head.x, head.y];
|
|
314
54
|
const aOut = [head.a];
|
|
315
55
|
const bOut = [head.b];
|
|
316
56
|
const tOut = [head.t];
|
|
317
57
|
const wOut = W ? [head.w] : void 0;
|
|
58
|
+
const oOut = O ? [head.o] : void 0;
|
|
318
59
|
for (let i = head.next; i < tail.next; i++) {
|
|
319
60
|
points.push(pl.points[i * 2], pl.points[i * 2 + 1]);
|
|
320
61
|
aOut.push(A[i]);
|
|
321
62
|
bOut.push(B[i]);
|
|
322
63
|
tOut.push(T[i]);
|
|
323
64
|
if (wOut) wOut.push(W[i]);
|
|
65
|
+
if (oOut) oOut.push(O[i]);
|
|
324
66
|
}
|
|
325
67
|
points.push(tail.x, tail.y);
|
|
326
68
|
aOut.push(tail.a);
|
|
327
69
|
bOut.push(tail.b);
|
|
328
70
|
tOut.push(tail.t);
|
|
329
71
|
if (wOut) wOut.push(tail.w);
|
|
72
|
+
if (oOut) oOut.push(tail.o);
|
|
330
73
|
return {
|
|
331
74
|
points,
|
|
332
75
|
closed: false,
|
|
333
76
|
anchorA: new Uint32Array(aOut),
|
|
334
77
|
anchorB: new Uint32Array(bOut),
|
|
335
78
|
anchorT: new Float32Array(tOut),
|
|
336
|
-
...wOut ? { widths: new Float32Array(wOut) } : {}
|
|
79
|
+
...wOut ? { widths: new Float32Array(wOut) } : {},
|
|
80
|
+
...oOut ? { offsets: new Float32Array(oOut) } : {}
|
|
337
81
|
};
|
|
338
82
|
}
|
|
339
83
|
|
|
340
|
-
export {
|
|
84
|
+
export { anchorParamsBetween, trimPolyline };
|
|
341
85
|
//# sourceMappingURL=index.js.map
|
|
342
86
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/tessellate/tessellate.ts","../../src/tessellate/trim.ts"],"names":[],"mappings":";;;;;;;AAuBO,SAAS,UAAA,CAAW,IAAA,EAAY,IAAA,GAA0B,EAAC,EAAS;AACzE,EAAA,IAAI,IAAA,CAAK,IAAA,KAAS,MAAA,EAAQ,OAAO,eAAe,IAAI,CAAA;AACpD,EAAA,OAAO,iBAAA,CAAkB,MAAM,IAAI,CAAA;AACrC;AAEA,SAAS,eAAe,CAAA,EAAmB;AACzC,EAAA,MAAM,EAAE,CAAA,EAAG,CAAA,EAAG,OAAO,CAAA,EAAG,MAAA,EAAQ,GAAE,GAAI,CAAA;AACtC,EAAA,OAAO;AAAA,IACL,QAAA,EAAU,aAAa,IAAA,CAAK,aAAA,CAAc,GAAG,CAAA,EAAG,CAAA,EAAG,CAAC,CAAC,CAAA;AAAA,IACrD,OAAA,EAAS,IAAI,WAAA,CAAY,CAAC,CAAA,EAAG,GAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAC,CAAC,CAAA;AAAA,IAC3C,OAAA,EAAS,IAAI,WAAA,CAAY,CAAC,GAAG,CAAA,EAAG,CAAA,EAAG,CAAC,CAAC,CAAA;AAAA,IACrC,OAAA,EAAS,IAAI,WAAA,CAAY,CAAC,GAAG,CAAA,EAAG,CAAA,EAAG,CAAC,CAAC,CAAA;AAAA,IACrC,OAAA,EAAS,IAAI,YAAA,CAAa,CAAC,GAAG,CAAA,EAAG,CAAA,EAAG,CAAC,CAAC;AAAA,GACxC;AACF;AAWA,SAAS,cAAA,CAAe,GAAgB,SAAA,EAAsC;AAC5E,EAAA,MAAM,MAAA,uBAAa,GAAA,EAAY;AAC/B,EAAA,MAAM,GAAA,GAAM,eAAA,CAAgB,CAAA,EAAG,SAAA,EAAW,MAAM,CAAA;AAChD,EAAA,IAAI,iBAAA,CAAkB,CAAC,CAAA,EAAG,OAAO,GAAA;AACjC,EAAA,MAAM,OAA0B,EAAE,MAAA,EAAQ,EAAC,EAAG,eAAe,EAAC,EAAG,OAAA,EAAS,IAAI,OAAA,EAAS,EAAC,EAAG,OAAA,EAAS,EAAC,EAAE;AACvG,EAAA,GAAA,CAAI,aAAA,CAAc,OAAA,CAAQ,CAAC,KAAA,EAAO,CAAA,KAAM;AACtC,IAAA,IAAI,CAAC,MAAA,CAAO,GAAA,CAAI,CAAC,CAAA,EAAG;AACpB,IAAA,MAAM,GAAA,GAAM,CAAA,GAAI,CAAA,GAAI,GAAA,CAAI,aAAA,CAAc,MAAA,GAAS,GAAA,CAAI,aAAA,CAAc,CAAA,GAAI,CAAC,CAAA,GAAI,GAAA,CAAI,OAAO,MAAA,GAAS,CAAA;AAC9F,IAAA,IAAA,CAAK,aAAA,CAAc,IAAA,CAAK,IAAA,CAAK,MAAA,CAAO,SAAS,CAAC,CAAA;AAC9C,IAAA,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,GAAG,GAAA,CAAI,MAAA,CAAO,MAAM,KAAA,GAAQ,CAAA,EAAG,GAAA,GAAM,CAAC,CAAC,CAAA;AACxD,IAAA,IAAA,CAAK,OAAA,CAAQ,KAAK,GAAG,GAAA,CAAI,QAAQ,KAAA,CAAM,KAAA,EAAO,GAAG,CAAC,CAAA;AAClD,IAAA,IAAA,CAAK,OAAA,CAAQ,KAAK,GAAG,GAAA,CAAI,QAAQ,KAAA,CAAM,KAAA,EAAO,GAAG,CAAC,CAAA;AAClD,IAAA,IAAA,CAAK,OAAA,CAAQ,KAAK,GAAG,GAAA,CAAI,QAAQ,KAAA,CAAM,KAAA,EAAO,GAAG,CAAC,CAAA;AAAA,EACpD,CAAC,CAAA;AACD,EAAA,OAAO,IAAA;AACT;AAGA,SAAS,eAAA,CAAgB,CAAA,EAAgB,SAAA,EAAmB,MAAA,EAAwC;AAClG,EAAA,MAAM,EAAE,QAAA,EAAU,MAAA,EAAO,GAAI,CAAA;AAC7B,EAAA,MAAM,MAAgB,EAAC;AACvB,EAAA,MAAM,UAAoB,EAAC;AAC3B,EAAA,MAAM,UAAoB,EAAC;AAC3B,EAAA,MAAM,UAAoB,EAAC;AAC3B,EAAA,MAAM,gBAA0B,EAAC;AACjC,EAAA,IAAI,WAAA,GAAc,EAAA;AAClB,EAAA,IAAI,UAAA,GAAa,EAAA;AACjB,EAAA,IAAI,aAAA,GAAgB,CAAA;AAIpB,EAAA,MAAM,gBAAA,GAAmB,CAAC,WAAA,EAAqB,QAAA,EAAoB,OAAe,MAAA,KAAyB;AACzG,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,QAAA,CAAS,QAAQ,CAAA,EAAA,EAAK;AACxC,MAAA,OAAA,CAAQ,KAAK,UAAU,CAAA;AACvB,MAAA,OAAA,CAAQ,KAAK,MAAM,CAAA;AACnB,MAAA,OAAA,CAAQ,KAAK,KAAA,GAAQ,CAAA,GAAI,SAAS,CAAC,CAAA,GAAI,QAAQ,CAAC,CAAA;AAAA,IAClD;AACA,IAAA,MAAM,OAAA,GAAU,WAAA,GAAc,QAAA,CAAS,MAAA,GAAS,CAAA;AAChD,IAAA,OAAA,CAAQ,OAAO,CAAA,GAAI,MAAA;AACnB,IAAA,OAAA,CAAQ,OAAO,CAAA,GAAI,MAAA;AACnB,IAAA,OAAA,CAAQ,OAAO,CAAA,GAAI,CAAA;AAAA,EACrB,CAAA;AAEA,EAAA,cAAA,CAAe,QAAA,EAAU,QAAQ,CAAC,GAAA,EAAK,UAAU,KAAA,EAAO,KAAA,EAAO,IAAI,YAAA,KAAiB;AAClF,IAAA,IAAI,YAAA,EAAc;AAChB,MAAA,MAAM,MAAA,GAAS,IAAA,CAAK,GAAA,CAAI,WAAA,EAAa,CAAC,CAAA;AACtC,MAAA,aAAA,CAAc,IAAA,CAAK,GAAA,CAAI,MAAA,GAAS,CAAC,CAAA;AACjC,MAAA,GAAA,CAAI,IAAA,CAAK,OAAO,KAAK,CAAA;AACrB,MAAA,OAAA,CAAQ,KAAK,MAAM,CAAA;AACnB,MAAA,OAAA,CAAQ,KAAK,MAAM,CAAA;AACnB,MAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AACd,MAAA,UAAA,GAAa,MAAA;AAAA,IACf;AACA,IAAA,QAAQ,GAAA;AAAK,MACX,KAAK,MAAA;AAAA,MACL,KAAK,MAAA,EAAQ;AACX,QAAA,IAAI,QAAQ,MAAA,EAAQ;AAClB,UAAA,aAAA,CAAc,IAAA,CAAK,GAAA,CAAI,MAAA,GAAS,CAAC,CAAA;AACjC,UAAA,WAAA,GAAc,aAAA;AAAA,QAChB;AACA,QAAA,GAAA,CAAI,KAAK,MAAA,CAAO,QAAQ,GAAG,MAAA,CAAO,QAAA,GAAW,CAAC,CAAC,CAAA;AAC/C,QAAA,OAAA,CAAQ,KAAK,aAAa,CAAA;AAC1B,QAAA,OAAA,CAAQ,KAAK,aAAa,CAAA;AAC1B,QAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AACd,QAAA,UAAA,GAAa,aAAA;AACb,QAAA,aAAA,EAAA;AACA,QAAA;AAAA,MACF;AAAA,MACA,KAAK,MAAA,EAAQ;AACX,QAAA,MAAM,MAAA,GAAS,aAAA;AACf,QAAA,MAAM,WAAqB,EAAC;AAC5B,QAAA,MAAM,cAAc,OAAA,CAAQ,MAAA;AAC5B,QAAA,MAAM,KAAA,GAAQ,0BAAA;AAAA,UACZ,KAAA;AAAA,UAAO,KAAA;AAAA,UACP,OAAO,QAAQ,CAAA;AAAA,UAAG,MAAA,CAAO,WAAW,CAAC,CAAA;AAAA,UACrC,MAAA,CAAO,WAAW,CAAC,CAAA;AAAA,UAAG,MAAA,CAAO,WAAW,CAAC,CAAA;AAAA,UACzC,SAAA;AAAA,UAAW,GAAA;AAAA,UAAK;AAAA,SAClB;AACA,QAAA,gBAAA,CAAiB,WAAA,EAAa,QAAA,EAAU,KAAA,EAAO,MAAM,CAAA;AACrD,QAAA,UAAA,GAAa,MAAA;AACb,QAAA,aAAA,EAAA;AACA,QAAA;AAAA,MACF;AAAA,MACA,KAAK,MAAA,EAAQ;AACX,QAAA,MAAM,MAAA,GAAS,aAAA;AACf,QAAA,MAAM,WAAqB,EAAC;AAC5B,QAAA,MAAM,cAAc,OAAA,CAAQ,MAAA;AAC5B,QAAA,MAAM,KAAA,GAAQ,sBAAA;AAAA,UACZ,KAAA;AAAA,UAAO,KAAA;AAAA,UACP,OAAO,QAAQ,CAAA;AAAA,UAAG,MAAA,CAAO,WAAW,CAAC,CAAA;AAAA,UACrC,MAAA,CAAO,WAAW,CAAC,CAAA;AAAA,UAAG,MAAA,CAAO,WAAW,CAAC,CAAA;AAAA,UACzC,MAAA,CAAO,WAAW,CAAC,CAAA;AAAA,UAAG,MAAA,CAAO,WAAW,CAAC,CAAA;AAAA,UACzC,SAAA;AAAA,UAAW,GAAA;AAAA,UAAK;AAAA,SAClB;AACA,QAAA,gBAAA,CAAiB,WAAA,EAAa,QAAA,EAAU,KAAA,EAAO,MAAM,CAAA;AACrD,QAAA,UAAA,GAAa,MAAA;AACb,QAAA,aAAA,EAAA;AACA,QAAA;AAAA,MACF;AAAA,MACA,KAAK,MAAA;AACH,QAAA,MAAA,CAAO,GAAA,CAAI,aAAA,CAAc,MAAA,GAAS,CAAC,CAAA;AAInC,QAAA,UAAA,GAAa,WAAA;AACb,QAAA;AAAA,MACF;AACE,QAAA,MAAM,IAAI,KAAA,CAAM,CAAA,iCAAA,EAAoC,GAAG,CAAA,CAAE,CAAA;AAAA;AAC7D,EACF,CAAC,CAAA;AAED,EAAA,OAAO,EAAE,MAAA,EAAQ,GAAA,EAAK,aAAA,EAAe,OAAA,EAAS,SAAS,OAAA,EAAQ;AACjE;AAEA,SAAS,iBAAA,CAAkB,GAAgB,IAAA,EAA+B;AACxE,EAAA,MAAM,SAAA,GAAY,KAAK,gBAAA,IAAoB,yBAAA;AAC3C,EAAA,MAAM,EAAE,QAAQ,aAAA,EAAe,OAAA,EAAS,SAAS,OAAA,EAAQ,GAAI,cAAA,CAAe,CAAA,EAAG,SAAS,CAAA;AAExF,EAAA,IAAI,CAAA,CAAE,aAAa,SAAA,EAAW;AAC5B,IAAA,OAAO,4BAAA,CAA6B,MAAA,EAAQ,aAAA,EAAe,OAAA,EAAS,SAAS,OAAO,CAAA;AAAA,EACtF;AAaA,EAAA,MAAM,UAAA,GAAa,OAAO,MAAA,GAAS,CAAA;AACnC,EAAA,MAAM,UAAA,GAAa,CAAC,CAAA,KAClB,CAAA,GAAI,CAAA,GAAI,cAAc,MAAA,GAAS,aAAA,CAAc,CAAA,GAAI,CAAC,CAAA,GAAI,UAAA;AAExD,EAAA,IAAI,aAAA,CAAc,UAAU,CAAA,EAAG;AAC7B,IAAA,MAAM,GAAA,GAAM,OAAO,MAAM,CAAA;AACzB,IAAA,OAAO;AAAA,MACL,QAAA,EAAU,IAAI,YAAA,CAAa,MAAM,CAAA;AAAA,MACjC,OAAA,EAAS,IAAI,WAAA,CAAY,GAAG,CAAA;AAAA,MAC5B,OAAA,EAAS,IAAI,WAAA,CAAY,OAAO,CAAA;AAAA,MAChC,OAAA,EAAS,IAAI,WAAA,CAAY,OAAO,CAAA;AAAA,MAChC,OAAA,EAAS,IAAI,YAAA,CAAa,OAAO;AAAA,KACnC;AAAA,EACF;AAEA,EAAA,MAAM,KAAA,GAAkB,aAAA,CAAc,GAAA,CAAI,CAAC,CAAA,EAAG,CAAA,KAAM,UAAA,CAAW,MAAA,EAAQ,CAAA,EAAG,UAAA,CAAW,CAAC,CAAC,CAAC,CAAA;AACxF,EAAA,MAAM,UAAU,IAAA,CAAK,IAAA,CAAK,KAAA,CAAM,CAAC,CAAC,CAAA,IAAK,CAAA;AAEvC,EAAA,MAAM,YAAsB,EAAC;AAC7B,EAAA,MAAM,YAAsB,EAAC;AAC7B,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,aAAA,CAAc,QAAQ,CAAA,EAAA,EAAK;AAC7C,IAAA,IAAI,KAAA,CAAM,CAAC,CAAA,KAAM,CAAA,EAAG;AACpB,IAAA,IAAI,IAAA,CAAK,KAAK,KAAA,CAAM,CAAC,CAAC,CAAA,KAAM,OAAA,EAAS,SAAA,CAAU,IAAA,CAAK,CAAC,CAAA;AAAA,SAChD,SAAA,CAAU,KAAK,CAAC,CAAA;AAAA,EACvB;AAEA,EAAA,IAAI,SAAA,CAAU,MAAA,KAAW,CAAA,IAAK,SAAA,CAAU,SAAS,CAAA,EAAG;AAElD,IAAA,MAAM,WAAA,GAAc,aAAA,CAAc,KAAA,CAAM,CAAC,CAAA;AACzC,IAAA,MAAM,GAAA,GAAM,MAAA,CAAO,MAAA,EAAQ,WAAW,CAAA;AACtC,IAAA,OAAO;AAAA,MACL,QAAA,EAAU,IAAI,YAAA,CAAa,MAAM,CAAA;AAAA,MACjC,OAAA,EAAS,IAAI,WAAA,CAAY,GAAG,CAAA;AAAA,MAC5B,OAAA,EAAS,IAAI,WAAA,CAAY,OAAO,CAAA;AAAA,MAChC,OAAA,EAAS,IAAI,WAAA,CAAY,OAAO,CAAA;AAAA,MAChC,OAAA,EAAS,IAAI,YAAA,CAAa,OAAO;AAAA,KACnC;AAAA,EACF;AAKA,EAAA,MAAM,eAAA,uBAAsB,GAAA,EAAsB;AAClD,EAAA,MAAM,kBAA4B,EAAC;AACnC,EAAA,KAAA,MAAW,KAAK,SAAA,EAAW;AACzB,IAAA,MAAM,EAAA,GAAK,MAAA,CAAO,aAAA,CAAc,CAAC,IAAI,CAAC,CAAA;AACtC,IAAA,MAAM,KAAK,MAAA,CAAO,aAAA,CAAc,CAAC,CAAA,GAAI,IAAI,CAAC,CAAA;AAC1C,IAAA,IAAI,OAAA,GAAU,EAAA;AACd,IAAA,IAAI,WAAA,GAAc,QAAA;AAClB,IAAA,KAAA,MAAW,OAAO,SAAA,EAAW;AAC3B,MAAA,MAAM,OAAA,GAAU,IAAA,CAAK,GAAA,CAAI,KAAA,CAAM,GAAG,CAAC,CAAA;AACnC,MAAA,IAAI,OAAA,GAAU,WAAA,IAAe,cAAA,CAAe,MAAA,EAAQ,EAAA,EAAI,EAAA,EAAI,aAAA,CAAc,GAAG,CAAA,EAAG,UAAA,CAAW,GAAG,CAAC,CAAA,EAAG;AAChG,QAAA,WAAA,GAAc,OAAA;AACd,QAAA,OAAA,GAAU,GAAA;AAAA,MACZ;AAAA,IACF;AACA,IAAA,IAAI,WAAW,CAAA,EAAG;AAChB,MAAA,MAAM,GAAA,GAAM,eAAA,CAAgB,GAAA,CAAI,OAAO,KAAK,EAAC;AAC7C,MAAA,GAAA,CAAI,KAAK,CAAC,CAAA;AACV,MAAA,eAAA,CAAgB,GAAA,CAAI,SAAS,GAAG,CAAA;AAAA,IAClC,CAAA,MAAO;AACL,MAAA,eAAA,CAAgB,KAAK,CAAC,CAAA;AAAA,IACxB;AAAA,EACF;AAEA,EAAA,MAAM,YAAA,GAAe,CAAC,GAAG,SAAA,EAAW,GAAG,eAAe,CAAA;AAEtD,EAAA,MAAM,cAAwB,EAAC;AAC/B,EAAA,MAAM,eAAyB,EAAC;AAChC,EAAA,MAAM,eAAyB,EAAC;AAChC,EAAA,MAAM,eAAyB,EAAC;AAChC,EAAA,MAAM,eAAyB,EAAC;AAChC,EAAA,KAAA,MAAW,OAAO,YAAA,EAAc;AAC9B,IAAA,MAAM,KAAA,GAAQ,eAAA,CAAgB,GAAA,CAAI,GAAG,KAAK,EAAC;AAC3C,IAAA,MAAM,MAAA,GAAS,YAAY,MAAA,GAAS,CAAA;AACpC,IAAA,MAAM,cAAwB,EAAC;AAC/B,IAAA,MAAM,WAAA,GAAwB,CAAC,CAAC,CAAA;AAChC,IAAA,KAAA,IAAS,CAAA,GAAI,cAAc,GAAG,CAAA,EAAG,IAAI,UAAA,CAAW,GAAG,GAAG,CAAA,EAAA,EAAK;AACzD,MAAA,WAAA,CAAY,IAAA,CAAK,OAAO,CAAA,GAAI,CAAC,GAAG,MAAA,CAAO,CAAA,GAAI,CAAA,GAAI,CAAC,CAAC,CAAA;AACjD,MAAA,YAAA,CAAa,IAAA,CAAK,OAAA,CAAQ,CAAC,CAAC,CAAA;AAC5B,MAAA,YAAA,CAAa,IAAA,CAAK,OAAA,CAAQ,CAAC,CAAC,CAAA;AAC5B,MAAA,YAAA,CAAa,IAAA,CAAK,OAAA,CAAQ,CAAC,CAAC,CAAA;AAAA,IAC9B;AACA,IAAA,KAAA,MAAW,KAAK,KAAA,EAAO;AACrB,MAAA,WAAA,CAAY,IAAA,CAAK,WAAA,CAAY,MAAA,GAAS,CAAC,CAAA;AACvC,MAAA,KAAA,IAAS,CAAA,GAAI,cAAc,CAAC,CAAA,EAAG,IAAI,UAAA,CAAW,CAAC,GAAG,CAAA,EAAA,EAAK;AACrD,QAAA,WAAA,CAAY,IAAA,CAAK,OAAO,CAAA,GAAI,CAAC,GAAG,MAAA,CAAO,CAAA,GAAI,CAAA,GAAI,CAAC,CAAC,CAAA;AACjD,QAAA,YAAA,CAAa,IAAA,CAAK,OAAA,CAAQ,CAAC,CAAC,CAAA;AAC5B,QAAA,YAAA,CAAa,IAAA,CAAK,OAAA,CAAQ,CAAC,CAAC,CAAA;AAC5B,QAAA,YAAA,CAAa,IAAA,CAAK,OAAA,CAAQ,CAAC,CAAC,CAAA;AAAA,MAC9B;AAAA,IACF;AACA,IAAA,MAAM,GAAA,GAAM,MAAA,CAAO,WAAA,EAAa,WAAA,CAAY,MAAA,GAAS,IAAI,WAAA,CAAY,KAAA,CAAM,CAAC,CAAA,GAAI,MAAS,CAAA;AACzF,IAAA,KAAA,MAAW,CAAA,IAAK,WAAA,EAAa,WAAA,CAAY,IAAA,CAAK,CAAC,CAAA;AAC/C,IAAA,KAAA,MAAW,GAAA,IAAO,GAAA,EAAK,YAAA,CAAa,IAAA,CAAK,MAAM,MAAM,CAAA;AAAA,EACvD;AAEA,EAAA,OAAO;AAAA,IACL,QAAA,EAAU,IAAI,YAAA,CAAa,WAAW,CAAA;AAAA,IACtC,OAAA,EAAS,IAAI,WAAA,CAAY,YAAY,CAAA;AAAA,IACrC,OAAA,EAAS,IAAI,WAAA,CAAY,YAAY,CAAA;AAAA,IACrC,OAAA,EAAS,IAAI,WAAA,CAAY,YAAY,CAAA;AAAA,IACrC,OAAA,EAAS,IAAI,YAAA,CAAa,YAAY;AAAA,GACxC;AACF;AAEA,SAAS,4BAAA,CACP,MAAA,EACA,aAAA,EACA,OAAA,EACA,SACA,OAAA,EACM;AACN,EAAA,MAAM,UAAoB,EAAC;AAC3B,EAAA,MAAM,UAAA,GAAa,OAAO,MAAA,GAAS,CAAA;AACnC,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,aAAA,CAAc,QAAQ,CAAA,EAAA,EAAK;AAC7C,IAAA,MAAM,KAAA,GAAQ,cAAc,CAAC,CAAA;AAC7B,IAAA,MAAM,GAAA,GAAM,IAAI,CAAA,GAAI,aAAA,CAAc,SAAS,aAAA,CAAc,CAAA,GAAI,CAAC,CAAA,GAAI,UAAA;AAClE,IAAA,KAAA,IAAS,IAAI,KAAA,GAAQ,CAAA,EAAG,CAAA,GAAI,GAAA,GAAM,GAAG,CAAA,EAAA,EAAK;AACxC,MAAA,OAAA,CAAQ,IAAA,CAAK,KAAA,EAAO,CAAA,EAAG,CAAA,GAAI,CAAC,CAAA;AAAA,IAC9B;AAAA,EACF;AACA,EAAA,OAAO;AAAA,IACL,QAAA,EAAU,IAAI,YAAA,CAAa,MAAM,CAAA;AAAA,IACjC,OAAA,EAAS,IAAI,WAAA,CAAY,OAAO,CAAA;AAAA,IAChC,eAAA,EAAiB,IAAA;AAAA,IACjB,OAAA,EAAS,IAAI,WAAA,CAAY,OAAO,CAAA;AAAA,IAChC,OAAA,EAAS,IAAI,WAAA,CAAY,OAAO,CAAA;AAAA,IAChC,OAAA,EAAS,IAAI,YAAA,CAAa,OAAO;AAAA,GACnC;AACF;AAEA,SAAS,UAAA,CAAW,MAAA,EAAkB,KAAA,EAAe,GAAA,EAAqB;AACxE,EAAA,IAAI,CAAA,GAAI,CAAA;AACR,EAAA,KAAA,IAAS,CAAA,GAAI,KAAA,EAAO,CAAA,GAAI,GAAA,EAAK,CAAA,EAAA,EAAK;AAChC,IAAA,MAAM,CAAA,GAAI,CAAA,GAAI,CAAA,KAAM,GAAA,GAAM,QAAQ,CAAA,GAAI,CAAA;AACtC,IAAA,CAAA,IAAK,OAAO,CAAA,GAAI,CAAC,CAAA,GAAI,MAAA,CAAO,IAAI,CAAA,GAAI,CAAC,CAAA,GAAI,MAAA,CAAO,IAAI,CAAC,CAAA,GAAI,MAAA,CAAO,CAAA,GAAI,IAAI,CAAC,CAAA;AAAA,EAC3E;AACA,EAAA,OAAO,CAAA,GAAI,GAAA;AACb;;;ACpTA,IAAM,GAAA,GAAM,IAAA;AAUZ,SAAS,QAAA,CACP,IAAc,GAAA,EACd,CAAA,EAAgB,GAAgB,CAAA,EAAiB,CAAA,EACjD,MAGA,aAAA,EACQ;AACR,EAAA,MAAM,IAAI,GAAA,CAAI,MAAA;AACd,EAAA,IAAI,CAAA,GAAI,CAAA;AACR,EAAA,OAAO,CAAA,GAAI,CAAA,GAAI,CAAA,KAAM,aAAA,GAAgB,GAAA,CAAI,CAAC,CAAA,IAAK,IAAA,GAAO,GAAA,CAAI,CAAC,CAAA,GAAI,IAAA,CAAA,EAAO,CAAA,EAAA;AACtE,EAAA,MAAM,QAAA,GAAW,GAAA,CAAI,CAAA,GAAI,CAAC,CAAA;AAC1B,EAAA,MAAM,MAAA,GAAS,GAAA,CAAI,CAAC,CAAA,GAAI,QAAA;AACxB,EAAA,MAAM,CAAA,GAAI,MAAA,GAAS,GAAA,GAAA,CAAO,IAAA,GAAO,YAAY,MAAA,GAAS,CAAA;AAEtD,EAAA,MAAM,EAAA,GAAK,EAAA,CAAG,MAAA,CAAA,CAAQ,CAAA,GAAI,CAAA,IAAK,CAAC,CAAA,EAAG,EAAA,GAAK,EAAA,CAAG,MAAA,CAAA,CAAQ,CAAA,GAAI,CAAA,IAAK,IAAI,CAAC,CAAA;AACjE,EAAA,MAAM,EAAA,GAAK,EAAA,CAAG,MAAA,CAAO,CAAA,GAAI,CAAC,CAAA,EAAG,EAAA,GAAK,EAAA,CAAG,MAAA,CAAO,CAAA,GAAI,CAAA,GAAI,CAAC,CAAA;AAErD,EAAA,IAAI,GAAW,CAAA,EAAW,CAAA;AAC1B,EAAA,IAAI,CAAA,CAAE,CAAA,GAAI,CAAC,CAAA,KAAM,CAAA,CAAE,CAAC,CAAA,IAAK,CAAA,CAAE,CAAA,GAAI,CAAC,CAAA,KAAM,CAAA,CAAE,CAAC,CAAA,EAAG;AAC1C,IAAA,CAAA,GAAI,CAAA,CAAE,IAAI,CAAC,CAAA;AAAG,IAAA,CAAA,GAAI,CAAA,CAAE,IAAI,CAAC,CAAA;AACzB,IAAA,CAAA,GAAI,CAAA,CAAE,CAAA,GAAI,CAAC,CAAA,GAAA,CAAK,CAAA,CAAE,CAAC,CAAA,GAAI,CAAA,CAAE,CAAA,GAAI,CAAC,CAAA,IAAK,CAAA;AAAA,EACrC,CAAA,MAAA,IAAW,IAAI,GAAA,EAAK;AAClB,IAAA,CAAA,GAAI,CAAA,CAAE,IAAI,CAAC,CAAA;AAAG,IAAA,CAAA,GAAI,CAAA,CAAE,IAAI,CAAC,CAAA;AAAG,IAAA,CAAA,GAAI,CAAA,CAAE,IAAI,CAAC,CAAA;AAAA,EACzC,CAAA,MAAO;AACL,IAAA,CAAA,GAAI,EAAE,CAAC,CAAA;AAAG,IAAA,CAAA,GAAI,EAAE,CAAC,CAAA;AAAG,IAAA,CAAA,GAAI,EAAE,CAAC,CAAA;AAAA,EAC7B;AAEA,EAAA,MAAM,CAAA,GAAI,CAAA,GAAI,CAAA,CAAE,CAAA,GAAI,CAAC,CAAA,GAAA,CAAK,CAAA,CAAE,CAAC,CAAA,GAAI,CAAA,CAAE,CAAA,GAAI,CAAC,KAAK,CAAA,GAAI,CAAA;AACjD,EAAA,OAAO,EAAE,CAAA,EAAG,EAAA,GAAA,CAAM,EAAA,GAAK,EAAA,IAAM,GAAG,CAAA,EAAG,EAAA,GAAA,CAAM,EAAA,GAAK,EAAA,IAAM,GAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,MAAM,CAAA,EAAE;AAC7E;AAUO,SAAS,YAAA,CACd,EAAA,EACA,UAAA,EACA,QAAA,EACiB;AACjB,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,UAAU,CAAA;AACnC,EAAA,MAAM,EAAA,GAAK,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,QAAQ,CAAA;AAC/B,EAAA,IAAI,IAAA,IAAQ,CAAA,IAAK,EAAA,IAAM,CAAA,EAAG,OAAO,EAAA;AACjC,EAAA,IAAI,EAAA,CAAG,QAAQ,OAAO,EAAA;AAEtB,EAAA,MAAM,CAAA,GAAI,EAAA,CAAG,MAAA,CAAO,MAAA,GAAS,CAAA;AAC7B,EAAA,IAAI,CAAA,GAAI,GAAG,OAAO,IAAA;AAElB,EAAA,MAAM,CAAA,GAAI,EAAA,CAAG,OAAA,IAAW,IAAI,YAAY,CAAC,CAAA;AACzC,EAAA,MAAM,CAAA,GAAI,EAAA,CAAG,OAAA,IAAW,IAAI,YAAY,CAAC,CAAA;AACzC,EAAA,MAAM,CAAA,GAAI,EAAA,CAAG,OAAA,IAAW,IAAI,aAAa,CAAC,CAAA;AAC1C,EAAA,MAAM,IAAI,EAAA,CAAG,MAAA;AAEb,EAAA,MAAM,GAAA,GAAM,IAAI,YAAA,CAAa,CAAC,CAAA;AAC9B,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,CAAA,EAAA,EAAK;AAC1B,IAAA,MAAM,EAAA,GAAK,EAAA,CAAG,MAAA,CAAO,CAAA,GAAI,CAAC,IAAI,EAAA,CAAG,MAAA,CAAA,CAAQ,CAAA,GAAI,CAAA,IAAK,CAAC,CAAA;AACnD,IAAA,MAAM,EAAA,GAAK,EAAA,CAAG,MAAA,CAAO,CAAA,GAAI,CAAA,GAAI,CAAC,CAAA,GAAI,EAAA,CAAG,MAAA,CAAA,CAAQ,CAAA,GAAI,CAAA,IAAK,CAAA,GAAI,CAAC,CAAA;AAC3D,IAAA,GAAA,CAAI,CAAC,IAAI,GAAA,CAAI,CAAA,GAAI,CAAC,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,EAAA,EAAI,EAAE,CAAA;AAAA,EACzC;AACA,EAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,CAAA,GAAI,CAAC,CAAA;AACvB,EAAA,MAAM,IAAA,GAAO,IAAA;AACb,EAAA,MAAM,OAAO,KAAA,GAAQ,EAAA;AACrB,EAAA,IAAI,IAAA,GAAO,IAAA,IAAQ,GAAA,EAAK,OAAO,IAAA;AAE/B,EAAA,MAAM,IAAA,GAAO,SAAS,EAAA,EAAI,GAAA,EAAK,GAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,IAAA,EAAM,IAAI,CAAA;AACrD,EAAA,MAAM,IAAA,GAAO,SAAS,EAAA,EAAI,GAAA,EAAK,GAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,IAAA,EAAM,KAAK,CAAA;AAEtD,EAAA,MAAM,MAAA,GAAmB,CAAC,IAAA,CAAK,CAAA,EAAG,KAAK,CAAC,CAAA;AACxC,EAAA,MAAM,IAAA,GAAiB,CAAC,IAAA,CAAK,CAAC,CAAA;AAC9B,EAAA,MAAM,IAAA,GAAiB,CAAC,IAAA,CAAK,CAAC,CAAA;AAC9B,EAAA,MAAM,IAAA,GAAiB,CAAC,IAAA,CAAK,CAAC,CAAA;AAC9B,EAAA,MAAM,IAAA,GAA6B,CAAA,GAAI,CAAC,IAAA,CAAK,CAAC,CAAA,GAAI,MAAA;AAElD,EAAA,KAAA,IAAS,IAAI,IAAA,CAAK,IAAA,EAAM,CAAA,GAAI,IAAA,CAAK,MAAM,CAAA,EAAA,EAAK;AAC1C,IAAA,MAAA,CAAO,IAAA,CAAK,EAAA,CAAG,MAAA,CAAO,CAAA,GAAI,CAAC,CAAA,EAAG,EAAA,CAAG,MAAA,CAAO,CAAA,GAAI,CAAA,GAAI,CAAC,CAAC,CAAA;AAClD,IAAA,IAAA,CAAK,IAAA,CAAK,CAAA,CAAE,CAAC,CAAC,CAAA;AAAG,IAAA,IAAA,CAAK,IAAA,CAAK,CAAA,CAAE,CAAC,CAAC,CAAA;AAAG,IAAA,IAAA,CAAK,IAAA,CAAK,CAAA,CAAE,CAAC,CAAC,CAAA;AAChD,IAAA,IAAI,IAAA,EAAM,IAAA,CAAK,IAAA,CAAK,CAAA,CAAG,CAAC,CAAC,CAAA;AAAA,EAC3B;AAEA,EAAA,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,CAAA,EAAG,IAAA,CAAK,CAAC,CAAA;AAC1B,EAAA,IAAA,CAAK,IAAA,CAAK,KAAK,CAAC,CAAA;AAAG,EAAA,IAAA,CAAK,IAAA,CAAK,KAAK,CAAC,CAAA;AAAG,EAAA,IAAA,CAAK,IAAA,CAAK,KAAK,CAAC,CAAA;AACtD,EAAA,IAAI,IAAA,EAAM,IAAA,CAAK,IAAA,CAAK,IAAA,CAAK,CAAC,CAAA;AAE1B,EAAA,OAAO;AAAA,IACL,MAAA;AAAA,IACA,MAAA,EAAQ,KAAA;AAAA,IACR,OAAA,EAAS,IAAI,WAAA,CAAY,IAAI,CAAA;AAAA,IAC7B,OAAA,EAAS,IAAI,WAAA,CAAY,IAAI,CAAA;AAAA,IAC7B,OAAA,EAAS,IAAI,YAAA,CAAa,IAAI,CAAA;AAAA,IAC9B,GAAI,OAAO,EAAE,MAAA,EAAQ,IAAI,YAAA,CAAa,IAAI,CAAA,EAAE,GAAI;AAAC,GACnD;AACF","file":"index.js","sourcesContent":["import earcut from 'earcut';\nimport { forEachSegment, PATH_M, PATH_L, PATH_Z, PATH_C, PATH_Q } from '../commands';\nimport { pointInPolygon } from '../polyline';\nimport { rectToContour } from '../box';\nimport type { Path, PolygonPath, RectPath } from '../path';\nimport { fillsOpenSubpaths } from '../openFill';\nimport {\n DEFAULT_FLATTEN_TOLERANCE,\n flattenCubicWithArcLen,\n flattenQuadraticWithArcLen,\n} from '../flatten';\nimport type { Mesh } from './mesh';\n\n/** Options for `tessellate`. A smaller tolerance means more triangles and\n * smoother curves; it is in path-local units, so callers rendering at a\n * larger scale should tighten it. */\nexport interface TessellateOptions {\n /** Flatness tolerance for bezier subdivision in path-local units. */\n flattenTolerance?: number;\n}\n\n/** Turn a path into a triangle mesh the renderer can draw: curves flattened to\n * line segments, then the resulting polygon triangulated. */\nexport function tessellate(path: Path, opts: TessellateOptions = {}): Mesh {\n if (path.kind === 'rect') return tessellateRect(path);\n return tessellatePolygon(path, opts);\n}\n\nfunction tessellateRect(p: RectPath): Mesh {\n const { x, y, width: w, height: h } = p;\n return {\n vertices: Float32Array.from(rectToContour(x, y, w, h)),\n indices: new Uint32Array([0, 1, 2, 0, 2, 3]),\n anchorA: new Uint32Array([0, 1, 2, 3]),\n anchorB: new Uint32Array([0, 1, 2, 3]),\n anchorT: new Float32Array([0, 0, 0, 0]),\n };\n}\n\ninterface FlattenedContours {\n coords: number[];\n contourStarts: number[];\n anchorA: number[];\n anchorB: number[];\n anchorT: number[];\n}\n\n/** The contours a fill covers: all of them, or only those a `Z` closed. */\nfunction flattenPolygon(p: PolygonPath, tolerance: number): FlattenedContours {\n const closed = new Set<number>();\n const all = flattenContours(p, tolerance, closed);\n if (fillsOpenSubpaths(p)) return all;\n const kept: FlattenedContours = { coords: [], contourStarts: [], anchorA: [], anchorB: [], anchorT: [] };\n all.contourStarts.forEach((start, c) => {\n if (!closed.has(c)) return;\n const end = c + 1 < all.contourStarts.length ? all.contourStarts[c + 1] : all.coords.length / 2;\n kept.contourStarts.push(kept.coords.length / 2);\n kept.coords.push(...all.coords.slice(start * 2, end * 2));\n kept.anchorA.push(...all.anchorA.slice(start, end));\n kept.anchorB.push(...all.anchorB.slice(start, end));\n kept.anchorT.push(...all.anchorT.slice(start, end));\n });\n return kept;\n}\n\n/** Flatten every contour, noting in `closed` the index of each one a `Z` ends. */\nfunction flattenContours(p: PolygonPath, tolerance: number, closed: Set<number>): FlattenedContours {\n const { commands, coords } = p;\n const out: number[] = [];\n const anchorA: number[] = [];\n const anchorB: number[] = [];\n const anchorT: number[] = [];\n const contourStarts: number[] = [];\n let startAnchor = -1;\n let prevAnchor = -1;\n let anchorCounter = 0;\n\n // Anchor bookkeeping for the points a curve just appended: interior points\n // interpolate (prevAnchor → target); the last is pinned anchor-exact.\n const pushCurveAnchors = (anchorStart: number, arcAccum: number[], total: number, target: number): void => {\n for (let k = 0; k < arcAccum.length; k++) {\n anchorA.push(prevAnchor);\n anchorB.push(target);\n anchorT.push(total > 0 ? arcAccum[k] / total : 0);\n }\n const lastIdx = anchorStart + arcAccum.length - 1;\n anchorA[lastIdx] = target;\n anchorB[lastIdx] = target;\n anchorT[lastIdx] = 0;\n };\n\n forEachSegment(commands, coords, (cmd, coordIdx, prevX, prevY, _i, opensSubpath) => {\n if (opensSubpath) {\n const anchor = Math.max(startAnchor, 0);\n contourStarts.push(out.length / 2);\n out.push(prevX, prevY);\n anchorA.push(anchor);\n anchorB.push(anchor);\n anchorT.push(0);\n prevAnchor = anchor;\n }\n switch (cmd) {\n case PATH_M:\n case PATH_L: {\n if (cmd === PATH_M) {\n contourStarts.push(out.length / 2);\n startAnchor = anchorCounter;\n }\n out.push(coords[coordIdx], coords[coordIdx + 1]);\n anchorA.push(anchorCounter);\n anchorB.push(anchorCounter);\n anchorT.push(0);\n prevAnchor = anchorCounter;\n anchorCounter++;\n break;\n }\n case PATH_Q: {\n const target = anchorCounter;\n const arcAccum: number[] = [];\n const anchorStart = anchorA.length;\n const total = flattenQuadraticWithArcLen(\n prevX, prevY,\n coords[coordIdx], coords[coordIdx + 1],\n coords[coordIdx + 2], coords[coordIdx + 3],\n tolerance, out, arcAccum,\n );\n pushCurveAnchors(anchorStart, arcAccum, total, target);\n prevAnchor = target;\n anchorCounter++;\n break;\n }\n case PATH_C: {\n const target = anchorCounter;\n const arcAccum: number[] = [];\n const anchorStart = anchorA.length;\n const total = flattenCubicWithArcLen(\n prevX, prevY,\n coords[coordIdx], coords[coordIdx + 1],\n coords[coordIdx + 2], coords[coordIdx + 3],\n coords[coordIdx + 4], coords[coordIdx + 5],\n tolerance, out, arcAccum,\n );\n pushCurveAnchors(anchorStart, arcAccum, total, target);\n prevAnchor = target;\n anchorCounter++;\n break;\n }\n case PATH_Z:\n closed.add(contourStarts.length - 1);\n // The pen returns to the subpath start (forEachSegment does that); the\n // anchor it carries has to follow, or a curve after the Z interpolates\n // from the wrong end.\n prevAnchor = startAnchor;\n break;\n default:\n throw new Error(`tessellate: unknown command code ${cmd}`);\n }\n });\n\n return { coords: out, contourStarts, anchorA, anchorB, anchorT };\n}\n\nfunction tessellatePolygon(p: PolygonPath, opts: TessellateOptions): Mesh {\n const tolerance = opts.flattenTolerance ?? DEFAULT_FLATTEN_TOLERANCE;\n const { coords, contourStarts, anchorA, anchorB, anchorT } = flattenPolygon(p, tolerance);\n\n if (p.fillRule === 'evenodd') {\n return tessellateEvenoddWithAnchors(coords, contourStarts, anchorA, anchorB, anchorT);\n }\n\n // nonzero compound-path tessellation:\n // - The first contour establishes the reference winding direction.\n // - Subsequent contours with the SAME winding as the first are positives\n // (filled, disjoint shapes).\n // - Subsequent contours with OPPOSITE winding are holes; each is grouped\n // with the smallest positive whose polygon contains its first vertex.\n // - Each (positive, [its holes]) group is earcut'd independently;\n // triangles concatenated.\n // Using shoelace sign relative to the first contour avoids guessing about\n // screen-down vs math-up axis conventions.\n\n const totalVerts = coords.length / 2;\n const contourEnd = (i: number): number =>\n i + 1 < contourStarts.length ? contourStarts[i + 1] : totalVerts;\n\n if (contourStarts.length <= 1) {\n const tri = earcut(coords);\n return {\n vertices: new Float32Array(coords),\n indices: new Uint32Array(tri),\n anchorA: new Uint32Array(anchorA),\n anchorB: new Uint32Array(anchorB),\n anchorT: new Float32Array(anchorT),\n };\n }\n\n const areas: number[] = contourStarts.map((s, i) => signedArea(coords, s, contourEnd(i)));\n const refSign = Math.sign(areas[0]) || 1;\n\n const positives: number[] = [];\n const negatives: number[] = [];\n for (let i = 0; i < contourStarts.length; i++) {\n if (areas[i] === 0) continue;\n if (Math.sign(areas[i]) === refSign) positives.push(i);\n else negatives.push(i);\n }\n\n if (positives.length === 1 && negatives.length > 0) {\n // Classic outer-with-holes pattern; pass directly to earcut.\n const holeIndices = contourStarts.slice(1);\n const tri = earcut(coords, holeIndices);\n return {\n vertices: new Float32Array(coords),\n indices: new Uint32Array(tri),\n anchorA: new Uint32Array(anchorA),\n anchorB: new Uint32Array(anchorB),\n anchorT: new Float32Array(anchorT),\n };\n }\n\n // Orphans (opposite-wound but not inside any positive) get promoted to\n // independent positives — author probably intended them as separate shapes\n // with inconsistent winding.\n const holesByPositive = new Map<number, number[]>();\n const orphanPositives: number[] = [];\n for (const n of negatives) {\n const px = coords[contourStarts[n] * 2];\n const py = coords[contourStarts[n] * 2 + 1];\n let bestPos = -1;\n let bestAbsArea = Infinity;\n for (const pos of positives) {\n const absArea = Math.abs(areas[pos]);\n if (absArea < bestAbsArea && pointInPolygon(coords, px, py, contourStarts[pos], contourEnd(pos))) {\n bestAbsArea = absArea;\n bestPos = pos;\n }\n }\n if (bestPos >= 0) {\n const arr = holesByPositive.get(bestPos) ?? [];\n arr.push(n);\n holesByPositive.set(bestPos, arr);\n } else {\n orphanPositives.push(n);\n }\n }\n\n const allPositives = [...positives, ...orphanPositives];\n\n const finalCoords: number[] = [];\n const finalAnchorA: number[] = [];\n const finalAnchorB: number[] = [];\n const finalAnchorT: number[] = [];\n const finalIndices: number[] = [];\n for (const pos of allPositives) {\n const holes = holesByPositive.get(pos) ?? [];\n const offset = finalCoords.length / 2;\n const groupCoords: number[] = [];\n const groupStarts: number[] = [0];\n for (let i = contourStarts[pos]; i < contourEnd(pos); i++) {\n groupCoords.push(coords[i * 2], coords[i * 2 + 1]);\n finalAnchorA.push(anchorA[i]);\n finalAnchorB.push(anchorB[i]);\n finalAnchorT.push(anchorT[i]);\n }\n for (const h of holes) {\n groupStarts.push(groupCoords.length / 2);\n for (let i = contourStarts[h]; i < contourEnd(h); i++) {\n groupCoords.push(coords[i * 2], coords[i * 2 + 1]);\n finalAnchorA.push(anchorA[i]);\n finalAnchorB.push(anchorB[i]);\n finalAnchorT.push(anchorT[i]);\n }\n }\n const tri = earcut(groupCoords, groupStarts.length > 1 ? groupStarts.slice(1) : undefined);\n for (const v of groupCoords) finalCoords.push(v);\n for (const idx of tri) finalIndices.push(idx + offset);\n }\n\n return {\n vertices: new Float32Array(finalCoords),\n indices: new Uint32Array(finalIndices),\n anchorA: new Uint32Array(finalAnchorA),\n anchorB: new Uint32Array(finalAnchorB),\n anchorT: new Float32Array(finalAnchorT),\n };\n}\n\nfunction tessellateEvenoddWithAnchors(\n coords: number[],\n contourStarts: number[],\n anchorA: number[],\n anchorB: number[],\n anchorT: number[],\n): Mesh {\n const indices: number[] = [];\n const totalVerts = coords.length / 2;\n for (let c = 0; c < contourStarts.length; c++) {\n const start = contourStarts[c];\n const end = c + 1 < contourStarts.length ? contourStarts[c + 1] : totalVerts;\n for (let i = start + 1; i < end - 1; i++) {\n indices.push(start, i, i + 1);\n }\n }\n return {\n vertices: new Float32Array(coords),\n indices: new Uint32Array(indices),\n requiresStencil: true,\n anchorA: new Uint32Array(anchorA),\n anchorB: new Uint32Array(anchorB),\n anchorT: new Float32Array(anchorT),\n };\n}\n\nfunction signedArea(coords: number[], start: number, end: number): number {\n let a = 0;\n for (let i = start; i < end; i++) {\n const j = i + 1 === end ? start : i + 1;\n a += coords[i * 2] * coords[j * 2 + 1] - coords[j * 2] * coords[i * 2 + 1];\n }\n return a * 0.5;\n}\n","/**\n * Shortening a flattened subpath so a filled marker is not speared by its own\n * line. SVG has no equivalent — it paints the marker over a full-length\n * stroke — so this is the one place our rendering deliberately differs.\n *\n * Runs before dash splitting, so a dash pattern fits the visible line rather\n * than running off under the head. The anchor-param interpolation matches\n * `splitForDash`'s rule for a boundary landing mid-segment.\n */\n\nimport type { Polyline } from './polyline';\n\nconst EPS = 1e-9;\n\ninterface Sample {\n x: number; y: number;\n a: number; b: number; t: number;\n w: number;\n /** Index of the first original point at or after this sample. */\n next: number;\n}\n\nfunction sampleAt(\n pl: Polyline, cum: Float64Array,\n A: Uint32Array, B: Uint32Array, T: Float32Array, W: Float32Array | undefined,\n dist: number,\n /** For a cut landing exactly on a vertex: whether the vertex belongs to the\n * run after the sample (a head) or before it (a tail), so it is kept once. */\n vertexFollows: boolean,\n): Sample {\n const n = cum.length;\n let i = 1;\n while (i < n - 1 && (vertexFollows ? cum[i] <= dist : cum[i] < dist)) i++;\n const segStart = cum[i - 1];\n const segLen = cum[i] - segStart;\n const f = segLen > EPS ? (dist - segStart) / segLen : 0;\n\n const px = pl.points[(i - 1) * 2], py = pl.points[(i - 1) * 2 + 1];\n const qx = pl.points[i * 2], qy = pl.points[i * 2 + 1];\n\n let a: number, b: number, t: number;\n if (A[i - 1] === A[i] && B[i - 1] === B[i]) {\n a = A[i - 1]; b = B[i - 1];\n t = T[i - 1] + (T[i] - T[i - 1]) * f;\n } else if (f < 0.5) {\n a = A[i - 1]; b = B[i - 1]; t = T[i - 1];\n } else {\n a = A[i]; b = B[i]; t = T[i];\n }\n\n const w = W ? W[i - 1] + (W[i] - W[i - 1]) * f : 0;\n return { x: px + (qx - px) * f, y: py + (qy - py) * f, a, b, t, w, next: i };\n}\n\n/**\n * Shorten `pl` by `startInset` from its first point and `endInset` from its\n * last, both in the same world units as the points.\n *\n * Returns `pl` itself when there is nothing to do (both insets zero, or the\n * subpath is closed and so has no free ends), and `null` when the insets\n * consume the whole run — a caller should then draw no ribbon at all.\n */\nexport function trimPolyline(\n pl: Polyline,\n startInset: number,\n endInset: number,\n): Polyline | null {\n const from = Math.max(0, startInset);\n const to = Math.max(0, endInset);\n if (from <= 0 && to <= 0) return pl;\n if (pl.closed) return pl;\n\n const n = pl.points.length / 2;\n if (n < 2) return null;\n\n const A = pl.anchorA ?? new Uint32Array(n);\n const B = pl.anchorB ?? new Uint32Array(n);\n const T = pl.anchorT ?? new Float32Array(n);\n const W = pl.widths;\n\n const cum = new Float64Array(n);\n for (let i = 1; i < n; i++) {\n const dx = pl.points[i * 2] - pl.points[(i - 1) * 2];\n const dy = pl.points[i * 2 + 1] - pl.points[(i - 1) * 2 + 1];\n cum[i] = cum[i - 1] + Math.hypot(dx, dy);\n }\n const total = cum[n - 1];\n const cutA = from;\n const cutB = total - to;\n if (cutB - cutA <= EPS) return null;\n\n const head = sampleAt(pl, cum, A, B, T, W, cutA, true);\n const tail = sampleAt(pl, cum, A, B, T, W, cutB, false);\n\n const points: number[] = [head.x, head.y];\n const aOut: number[] = [head.a];\n const bOut: number[] = [head.b];\n const tOut: number[] = [head.t];\n const wOut: number[] | undefined = W ? [head.w] : undefined;\n\n for (let i = head.next; i < tail.next; i++) {\n points.push(pl.points[i * 2], pl.points[i * 2 + 1]);\n aOut.push(A[i]); bOut.push(B[i]); tOut.push(T[i]);\n if (wOut) wOut.push(W![i]);\n }\n\n points.push(tail.x, tail.y);\n aOut.push(tail.a); bOut.push(tail.b); tOut.push(tail.t);\n if (wOut) wOut.push(tail.w);\n\n return {\n points,\n closed: false,\n anchorA: new Uint32Array(aOut),\n anchorB: new Uint32Array(bOut),\n anchorT: new Float32Array(tOut),\n ...(wOut ? { widths: new Float32Array(wOut) } : {}),\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/tessellate/anchorParams.ts","../../src/tessellate/trim.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * The anchor parameters `(A, B, t)` of a point a fraction `frac` of the way\n * from one polyline point to the next: `t` interpolated when both lie between\n * the same two anchors, otherwise the nearer point's own.\n */\nexport function anchorParamsBetween(\n a0: number, b0: number, t0: number,\n a1: number, b1: number, t1: number,\n frac: number,\n): [number, number, number] {\n if (a0 === a1 && b0 === b1) return [a0, b0, t0 + (t1 - t0) * frac];\n return frac < 0.5 ? [a0, b0, t0] : [a1, b1, t1];\n}\n","/**\n * Shortening a flattened subpath so a filled marker is not speared by its own\n * line. SVG has no equivalent — it paints the marker over a full-length\n * stroke — so this is the one place our rendering deliberately differs.\n *\n * Runs before dash splitting, so a dash pattern fits the visible line rather\n * than running off under the head.\n */\n\nimport { anchorParamsBetween } from './anchorParams';\nimport type { Polyline } from './polyline';\n\nconst EPS = 1e-9;\n\ninterface Sample {\n x: number; y: number;\n a: number; b: number; t: number;\n w: number;\n o: number;\n /** Index of the first original point at or after this sample. */\n next: number;\n}\n\nfunction sampleAt(\n pl: Polyline, cum: Float64Array,\n A: Uint32Array, B: Uint32Array, T: Float32Array, W: Float32Array | undefined, O: Float32Array | undefined,\n dist: number,\n /** For a cut landing exactly on a vertex: whether the vertex belongs to the\n * run after the sample (a head) or before it (a tail), so it is kept once. */\n vertexFollows: boolean,\n): Sample {\n const n = cum.length;\n let i = 1;\n while (i < n - 1 && (vertexFollows ? cum[i] <= dist : cum[i] < dist)) i++;\n const segStart = cum[i - 1];\n const segLen = cum[i] - segStart;\n const f = segLen > EPS ? (dist - segStart) / segLen : 0;\n\n const px = pl.points[(i - 1) * 2], py = pl.points[(i - 1) * 2 + 1];\n const qx = pl.points[i * 2], qy = pl.points[i * 2 + 1];\n\n const [a, b, t] = anchorParamsBetween(A[i - 1], B[i - 1], T[i - 1], A[i], B[i], T[i], f);\n\n const w = W ? W[i - 1] + (W[i] - W[i - 1]) * f : 0;\n const o = O ? O[i - 1] + (O[i] - O[i - 1]) * f : 0;\n return { x: px + (qx - px) * f, y: py + (qy - py) * f, a, b, t, w, o, next: i };\n}\n\n/**\n * Shorten `pl` by `startInset` from its first point and `endInset` from its\n * last, both in the same world units as the points.\n *\n * Returns `pl` itself when there is nothing to do (both insets zero, or the\n * subpath is closed and so has no free ends), and `null` when the insets\n * consume the whole run — a caller should then draw no ribbon at all.\n */\nexport function trimPolyline(\n pl: Polyline,\n startInset: number,\n endInset: number,\n): Polyline | null {\n const from = Math.max(0, startInset);\n const to = Math.max(0, endInset);\n if (from <= 0 && to <= 0) return pl;\n if (pl.closed) return pl;\n\n const n = pl.points.length / 2;\n if (n < 2) return null;\n\n const A = pl.anchorA ?? new Uint32Array(n);\n const B = pl.anchorB ?? new Uint32Array(n);\n const T = pl.anchorT ?? new Float32Array(n);\n const W = pl.widths;\n const O = pl.offsets;\n\n const cum = new Float64Array(n);\n for (let i = 1; i < n; i++) {\n const dx = pl.points[i * 2] - pl.points[(i - 1) * 2];\n const dy = pl.points[i * 2 + 1] - pl.points[(i - 1) * 2 + 1];\n cum[i] = cum[i - 1] + Math.hypot(dx, dy);\n }\n const total = cum[n - 1];\n const cutA = from;\n const cutB = total - to;\n if (cutB - cutA <= EPS) return null;\n\n const head = sampleAt(pl, cum, A, B, T, W, O, cutA, true);\n const tail = sampleAt(pl, cum, A, B, T, W, O, cutB, false);\n\n const points: number[] = [head.x, head.y];\n const aOut: number[] = [head.a];\n const bOut: number[] = [head.b];\n const tOut: number[] = [head.t];\n const wOut: number[] | undefined = W ? [head.w] : undefined;\n const oOut: number[] | undefined = O ? [head.o] : undefined;\n\n for (let i = head.next; i < tail.next; i++) {\n points.push(pl.points[i * 2], pl.points[i * 2 + 1]);\n aOut.push(A[i]); bOut.push(B[i]); tOut.push(T[i]);\n if (wOut) wOut.push(W![i]);\n if (oOut) oOut.push(O![i]);\n }\n\n points.push(tail.x, tail.y);\n aOut.push(tail.a); bOut.push(tail.b); tOut.push(tail.t);\n if (wOut) wOut.push(tail.w);\n if (oOut) oOut.push(tail.o);\n\n return {\n points,\n closed: false,\n anchorA: new Uint32Array(aOut),\n anchorB: new Uint32Array(bOut),\n anchorT: new Float32Array(tOut),\n ...(wOut ? { widths: new Float32Array(wOut) } : {}),\n ...(oOut ? { offsets: new Float32Array(oOut) } : {}),\n };\n}\n"]}
|