@weasel-js/labkit 1.0.0 → 1.0.1
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/_dts/{DrawCommand-BwRCZYuo.d.ts → DrawCommand-CitWPxMY.d.ts} +8 -1
- package/dist/{chunk-HNXVLKBG.js → chunk-EXBV7A6X.js} +3 -3
- package/dist/{chunk-HNXVLKBG.js.map → chunk-EXBV7A6X.js.map} +1 -1
- package/dist/{chunk-XVBXYKFJ.js → chunk-ISEK5LXT.js} +642 -226
- package/dist/chunk-ISEK5LXT.js.map +1 -0
- package/dist/chunk-NRD3TDNQ.js +5946 -0
- package/dist/chunk-NRD3TDNQ.js.map +1 -0
- package/dist/index.js +22 -22
- package/dist/index.js.map +1 -1
- package/dist/passthrough/weasel-canvas.d.ts +29 -6
- package/dist/passthrough/weasel-canvas.js +1 -1
- package/dist/passthrough/weasel-ui.d.ts +73 -11
- package/dist/passthrough/weasel-ui.js +2 -2
- package/dist/ui/layers/index.js +3 -3
- package/package.json +1 -1
- package/src/lab/Lab.tsx +2 -2
- package/src/lab/LabShell.tsx +1 -1
- package/src/passthrough/weasel-ui.ts +4 -0
- package/src/theme/Interstellar.stories.tsx +1 -1
- package/src/theme/interstellar.test.ts +1 -1
- package/src/ui/properties/PropertyPanel.stories.tsx +0 -1
- package/dist/chunk-FP5LYDVX.js +0 -6039
- package/dist/chunk-FP5LYDVX.js.map +0 -1
- package/dist/chunk-XVBXYKFJ.js.map +0 -1
|
@@ -400,32 +400,53 @@ function affordanceKindOf(target) {
|
|
|
400
400
|
const k = target.kind;
|
|
401
401
|
return typeof k === "string" ? k : void 0;
|
|
402
402
|
}
|
|
403
|
-
function
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
403
|
+
function hasPrefix(s, prefix) {
|
|
404
|
+
return s.startsWith(prefix);
|
|
405
|
+
}
|
|
406
|
+
function parseTargetSpec(spec) {
|
|
407
|
+
if (typeof spec === "object") {
|
|
408
|
+
return spec !== null && typeof spec.kindOf === "function" ? { form: "predicate", kindOf: spec.kindOf } : null;
|
|
407
409
|
}
|
|
408
|
-
if (typeof
|
|
409
|
-
if (
|
|
410
|
-
|
|
411
|
-
return bodyTarget === specTarget;
|
|
410
|
+
if (typeof spec !== "string") return null;
|
|
411
|
+
if (spec === "empty" || spec === "selected-body" || spec === "unselected-body") {
|
|
412
|
+
return { form: "body", body: spec };
|
|
412
413
|
}
|
|
413
|
-
if (
|
|
414
|
-
|
|
415
|
-
|
|
414
|
+
if (hasPrefix(spec, "affordance:")) {
|
|
415
|
+
return { form: "affordance", kind: spec.slice("affordance:".length) };
|
|
416
|
+
}
|
|
417
|
+
if (hasPrefix(spec, "kind:")) {
|
|
418
|
+
const rest = spec.slice("kind:".length);
|
|
419
|
+
const requireSelected = rest.endsWith(":selected");
|
|
420
|
+
return {
|
|
421
|
+
form: "kind",
|
|
422
|
+
kind: requireSelected ? rest.slice(0, -":selected".length) : rest,
|
|
423
|
+
requireSelected
|
|
424
|
+
};
|
|
416
425
|
}
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
426
|
+
return null;
|
|
427
|
+
}
|
|
428
|
+
function matchTarget(target, specTarget, bodyTarget, bodyKind) {
|
|
429
|
+
if (specTarget === void 0) return true;
|
|
430
|
+
const form = parseTargetSpec(specTarget);
|
|
431
|
+
if (form === null) return false;
|
|
432
|
+
switch (form.form) {
|
|
433
|
+
// Receives the raw target (affordance hit for drag, e.target otherwise)
|
|
434
|
+
// plus the bodyTarget classification.
|
|
435
|
+
case "predicate":
|
|
436
|
+
return form.kindOf(target, bodyTarget);
|
|
437
|
+
// Resolved from the `classifyTarget` result packed into the event's
|
|
438
|
+
// `bodyTarget`. Unwired classifyTarget → absent → no match.
|
|
439
|
+
case "body":
|
|
440
|
+
return bodyTarget !== void 0 && bodyTarget === form.body;
|
|
441
|
+
case "affordance":
|
|
442
|
+
return affordanceKindOf(target) === form.kind;
|
|
443
|
+
case "kind":
|
|
444
|
+
if (bodyKind === void 0 || bodyKind !== form.kind) return false;
|
|
445
|
+
return form.requireSelected ? bodyTarget === "selected-body" : true;
|
|
446
|
+
default: {
|
|
447
|
+
return false;
|
|
424
448
|
}
|
|
425
|
-
if (bodyKind !== wanted) return false;
|
|
426
|
-
return requireSelected ? bodyTarget === "selected-body" : true;
|
|
427
449
|
}
|
|
428
|
-
return false;
|
|
429
450
|
}
|
|
430
451
|
function normalizePhase(spec) {
|
|
431
452
|
if (typeof spec === "string") {
|
|
@@ -3456,7 +3477,7 @@ function serialToEntry(se, custom, logger) {
|
|
|
3456
3477
|
};
|
|
3457
3478
|
}
|
|
3458
3479
|
|
|
3459
|
-
// ../core/dist/chunk-
|
|
3480
|
+
// ../core/dist/chunk-FVNWK7U3.js
|
|
3460
3481
|
function worldToScreen(worldX, worldY, view) {
|
|
3461
3482
|
return [view.panX + worldX * view.zoom.x, view.panY + worldY * view.zoom.y];
|
|
3462
3483
|
}
|
|
@@ -5548,7 +5569,7 @@ function warnMissingGlyphOnce(family, cp) {
|
|
|
5548
5569
|
`weasel layoutRuns: no glyph for U+${cp.toString(16).toUpperCase().padStart(4, "0")} (${JSON.stringify(ch)}) in "${family}", and the dynamic tier could not rasterize it \u2014 skipping the character. Bake it into the atlas, or call registerCanvasFont("${family}") to serve missing codepoints from installed fonts.`
|
|
5549
5570
|
);
|
|
5550
5571
|
}
|
|
5551
|
-
function layoutRuns(runs, opts
|
|
5572
|
+
function layoutRuns(runs, opts) {
|
|
5552
5573
|
const ctx = { groups: /* @__PURE__ */ new Map() };
|
|
5553
5574
|
const entries = [];
|
|
5554
5575
|
let prevCp;
|
|
@@ -5718,7 +5739,7 @@ function layoutRuns(runs, opts, origin) {
|
|
|
5718
5739
|
}
|
|
5719
5740
|
}
|
|
5720
5741
|
const lineBoxes = [];
|
|
5721
|
-
let penY =
|
|
5742
|
+
let penY = 0;
|
|
5722
5743
|
let maxLineWidth = 0;
|
|
5723
5744
|
const finiteWidth = Number.isFinite(opts.maxWidth) ? opts.maxWidth : 0;
|
|
5724
5745
|
for (const line of lines) {
|
|
@@ -5730,7 +5751,7 @@ function layoutRuns(runs, opts, origin) {
|
|
|
5730
5751
|
const slack = finiteWidth - line.width;
|
|
5731
5752
|
return opts.align === "center" ? slack / 2 : slack;
|
|
5732
5753
|
})();
|
|
5733
|
-
const lineX0 =
|
|
5754
|
+
const lineX0 = alignShift;
|
|
5734
5755
|
const baselineSource = line.entries[0] ?? line.blank;
|
|
5735
5756
|
const lineBaselineY = baselineSource ? penY + baselineSource.font.common.base * (baselineSource.fontSize / baselineSource.font.info.size) : penY;
|
|
5736
5757
|
let penX = lineX0;
|
|
@@ -5804,7 +5825,7 @@ function layoutRuns(runs, opts, origin) {
|
|
|
5804
5825
|
groups: [...ctx.groups.values()],
|
|
5805
5826
|
decorations,
|
|
5806
5827
|
lines: lineBoxes,
|
|
5807
|
-
bounds: { width: maxLineWidth, height: penY
|
|
5828
|
+
bounds: { width: maxLineWidth, height: penY }
|
|
5808
5829
|
};
|
|
5809
5830
|
}
|
|
5810
5831
|
var LAYOUT_CACHE_VARIANT_LIMIT = 8;
|
|
@@ -5817,10 +5838,10 @@ function outlineBucket(runs, min) {
|
|
|
5817
5838
|
for (const size of sizes) if (size >= min) n++;
|
|
5818
5839
|
return n;
|
|
5819
5840
|
}
|
|
5820
|
-
function variantKey2(runs, opts
|
|
5821
|
-
return `${opts.maxWidth}|${opts.lineHeight}|${opts.align}|${outlineBucket(runs, opts.outlineMinSize)}
|
|
5841
|
+
function variantKey2(runs, opts) {
|
|
5842
|
+
return `${opts.maxWidth}|${opts.lineHeight}|${opts.align}|${outlineBucket(runs, opts.outlineMinSize)}`;
|
|
5822
5843
|
}
|
|
5823
|
-
function cachedLayoutRuns(runs, opts
|
|
5844
|
+
function cachedLayoutRuns(runs, opts) {
|
|
5824
5845
|
const fonts = glyphGeneration();
|
|
5825
5846
|
let entry = cache2.get(runs);
|
|
5826
5847
|
if (entry === void 0) {
|
|
@@ -5830,10 +5851,10 @@ function cachedLayoutRuns(runs, opts, origin) {
|
|
|
5830
5851
|
entry.generation = fonts;
|
|
5831
5852
|
entry.byVariant.clear();
|
|
5832
5853
|
}
|
|
5833
|
-
const key = variantKey2(runs, opts
|
|
5854
|
+
const key = variantKey2(runs, opts);
|
|
5834
5855
|
const hit = entry.byVariant.get(key);
|
|
5835
5856
|
if (hit !== void 0) return hit;
|
|
5836
|
-
const laid = layoutRuns(runs, opts
|
|
5857
|
+
const laid = layoutRuns(runs, opts);
|
|
5837
5858
|
if (entry.byVariant.size >= LAYOUT_CACHE_VARIANT_LIMIT) entry.byVariant.clear();
|
|
5838
5859
|
entry.byVariant.set(key, laid);
|
|
5839
5860
|
return laid;
|
|
@@ -6141,25 +6162,264 @@ function outlineStrokeMesh(glyphKey, d, emWidth, stroke) {
|
|
|
6141
6162
|
cache4.set(key, mesh);
|
|
6142
6163
|
return mesh.indices.length === 0 ? null : mesh;
|
|
6143
6164
|
}
|
|
6144
|
-
|
|
6145
|
-
|
|
6146
|
-
|
|
6147
|
-
|
|
6148
|
-
|
|
6149
|
-
|
|
6150
|
-
|
|
6165
|
+
var MAX_VERTICES_PER_BATCH = 32768;
|
|
6166
|
+
var FLOATS_PER_VERTEX = 6;
|
|
6167
|
+
var INITIAL_VERTICES = 256;
|
|
6168
|
+
var INITIAL_INDICES = 384;
|
|
6169
|
+
var SolidBatch = class {
|
|
6170
|
+
gl;
|
|
6171
|
+
vao;
|
|
6172
|
+
vbo;
|
|
6173
|
+
ibo;
|
|
6174
|
+
verts = new Float32Array(INITIAL_VERTICES * FLOATS_PER_VERTEX);
|
|
6175
|
+
idx = new Uint32Array(INITIAL_INDICES);
|
|
6176
|
+
nVerts = 0;
|
|
6177
|
+
nIdx = 0;
|
|
6178
|
+
/** What the GPU buffers are currently sized for. */
|
|
6179
|
+
vboVerts = 0;
|
|
6180
|
+
iboIdx = 0;
|
|
6181
|
+
constructor(gl, prog) {
|
|
6182
|
+
const aPos = prog.attribute("a_position");
|
|
6183
|
+
const aColor = prog.attribute("a_vertexColor");
|
|
6184
|
+
if (aPos === void 0 || aColor === void 0) {
|
|
6185
|
+
throw new Error("SolidBatch: vertex-color program is missing a_position / a_vertexColor");
|
|
6186
|
+
}
|
|
6187
|
+
const vao = gl.createVertexArray();
|
|
6188
|
+
const vbo = gl.createBuffer();
|
|
6189
|
+
const ibo = gl.createBuffer();
|
|
6190
|
+
if (!vao || !vbo || !ibo) throw new Error("SolidBatch: failed to create GL objects");
|
|
6191
|
+
this.gl = gl;
|
|
6192
|
+
this.vao = vao;
|
|
6193
|
+
this.vbo = vbo;
|
|
6194
|
+
this.ibo = ibo;
|
|
6195
|
+
const stride = FLOATS_PER_VERTEX * 4;
|
|
6196
|
+
gl.bindVertexArray(vao);
|
|
6197
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
|
|
6198
|
+
gl.enableVertexAttribArray(aPos);
|
|
6199
|
+
gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, stride, 0);
|
|
6200
|
+
gl.enableVertexAttribArray(aColor);
|
|
6201
|
+
gl.vertexAttribPointer(aColor, 4, gl.FLOAT, false, stride, 8);
|
|
6202
|
+
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, ibo);
|
|
6203
|
+
gl.bindVertexArray(null);
|
|
6204
|
+
this.growGpu(INITIAL_VERTICES, INITIAL_INDICES);
|
|
6205
|
+
}
|
|
6206
|
+
get length() {
|
|
6207
|
+
return this.nIdx;
|
|
6208
|
+
}
|
|
6209
|
+
/** Whether staging `vertices` more would put the run past the per-flush cap. */
|
|
6210
|
+
wouldOverflow(vertices) {
|
|
6211
|
+
return this.nVerts + vertices > MAX_VERTICES_PER_BATCH;
|
|
6212
|
+
}
|
|
6213
|
+
/**
|
|
6214
|
+
* Append one rect's four corners through `m`, all carrying `rgba` (straight
|
|
6215
|
+
* alpha). An affine maps a rect to a parallelogram, so two triangles still
|
|
6216
|
+
* cover it and the batch draws at `u_model` identity.
|
|
6217
|
+
*/
|
|
6218
|
+
pushRect(x, y, w, h, m, r, g, b, a) {
|
|
6219
|
+
this.reserve(4, 6);
|
|
6220
|
+
const v = this.verts;
|
|
6221
|
+
let i = this.nVerts * FLOATS_PER_VERTEX;
|
|
6222
|
+
const ma = m[0], mb = m[1], mc = m[3], md = m[4], mtx = m[6], mty = m[7];
|
|
6223
|
+
const x1 = x + w;
|
|
6224
|
+
const y1 = y + h;
|
|
6225
|
+
const ax = ma * x + mc * y + mtx, ay = mb * x + md * y + mty;
|
|
6226
|
+
const bx = ma * x1 + mc * y + mtx, by = mb * x1 + md * y + mty;
|
|
6227
|
+
const cx = ma * x1 + mc * y1 + mtx, cy = mb * x1 + md * y1 + mty;
|
|
6228
|
+
const dx = ma * x + mc * y1 + mtx, dy = mb * x + md * y1 + mty;
|
|
6229
|
+
v[i++] = ax;
|
|
6230
|
+
v[i++] = ay;
|
|
6231
|
+
v[i++] = r;
|
|
6232
|
+
v[i++] = g;
|
|
6233
|
+
v[i++] = b;
|
|
6234
|
+
v[i++] = a;
|
|
6235
|
+
v[i++] = bx;
|
|
6236
|
+
v[i++] = by;
|
|
6237
|
+
v[i++] = r;
|
|
6238
|
+
v[i++] = g;
|
|
6239
|
+
v[i++] = b;
|
|
6240
|
+
v[i++] = a;
|
|
6241
|
+
v[i++] = cx;
|
|
6242
|
+
v[i++] = cy;
|
|
6243
|
+
v[i++] = r;
|
|
6244
|
+
v[i++] = g;
|
|
6245
|
+
v[i++] = b;
|
|
6246
|
+
v[i++] = a;
|
|
6247
|
+
v[i++] = dx;
|
|
6248
|
+
v[i++] = dy;
|
|
6249
|
+
v[i++] = r;
|
|
6250
|
+
v[i++] = g;
|
|
6251
|
+
v[i++] = b;
|
|
6252
|
+
v[i++] = a;
|
|
6253
|
+
const base = this.nVerts;
|
|
6254
|
+
let j = this.nIdx;
|
|
6255
|
+
this.idx[j++] = base;
|
|
6256
|
+
this.idx[j++] = base + 1;
|
|
6257
|
+
this.idx[j++] = base + 2;
|
|
6258
|
+
this.idx[j++] = base;
|
|
6259
|
+
this.idx[j++] = base + 2;
|
|
6260
|
+
this.idx[j++] = base + 3;
|
|
6261
|
+
this.nVerts += 4;
|
|
6262
|
+
this.nIdx += 6;
|
|
6263
|
+
}
|
|
6264
|
+
/**
|
|
6265
|
+
* Append a tessellated mesh through `m`, all vertices carrying `rgba`. The
|
|
6266
|
+
* mesh's own indices are rebased onto the staged vertices, which is why the
|
|
6267
|
+
* index buffer is uploaded per flush rather than written once.
|
|
6268
|
+
*/
|
|
6269
|
+
pushMesh(mesh, m, r, g, b, a) {
|
|
6270
|
+
const src = mesh.vertices;
|
|
6271
|
+
const srcIdx = mesh.indices;
|
|
6272
|
+
const n = src.length >> 1;
|
|
6273
|
+
this.reserve(n, srcIdx.length);
|
|
6274
|
+
const v = this.verts;
|
|
6275
|
+
let i = this.nVerts * FLOATS_PER_VERTEX;
|
|
6276
|
+
const ma = m[0], mb = m[1], mc = m[3], md = m[4], mtx = m[6], mty = m[7];
|
|
6277
|
+
for (let k = 0; k < n; k++) {
|
|
6278
|
+
const x = src[k * 2];
|
|
6279
|
+
const y = src[k * 2 + 1];
|
|
6280
|
+
v[i++] = ma * x + mc * y + mtx;
|
|
6281
|
+
v[i++] = mb * x + md * y + mty;
|
|
6282
|
+
v[i++] = r;
|
|
6283
|
+
v[i++] = g;
|
|
6284
|
+
v[i++] = b;
|
|
6285
|
+
v[i++] = a;
|
|
6286
|
+
}
|
|
6287
|
+
const base = this.nVerts;
|
|
6288
|
+
const out = this.idx;
|
|
6289
|
+
let j = this.nIdx;
|
|
6290
|
+
for (let k = 0; k < srcIdx.length; k++) out[j++] = base + srcIdx[k];
|
|
6291
|
+
this.nVerts += n;
|
|
6292
|
+
this.nIdx += srcIdx.length;
|
|
6293
|
+
}
|
|
6294
|
+
/** Upload the staged geometry and bind the batch VAO. Returns the index
|
|
6295
|
+
* count for the caller's `drawElements`. */
|
|
6296
|
+
uploadAndBind() {
|
|
6297
|
+
const gl = this.gl;
|
|
6298
|
+
if (this.nVerts > this.vboVerts || this.nIdx > this.iboIdx) {
|
|
6299
|
+
this.growGpu(this.nVerts, this.nIdx);
|
|
6151
6300
|
}
|
|
6301
|
+
gl.bindVertexArray(this.vao);
|
|
6302
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, this.vbo);
|
|
6303
|
+
gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.verts, 0, this.nVerts * FLOATS_PER_VERTEX);
|
|
6304
|
+
gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, 0, this.idx, 0, this.nIdx);
|
|
6305
|
+
return this.nIdx;
|
|
6152
6306
|
}
|
|
6307
|
+
reset() {
|
|
6308
|
+
this.nVerts = 0;
|
|
6309
|
+
this.nIdx = 0;
|
|
6310
|
+
}
|
|
6311
|
+
dispose() {
|
|
6312
|
+
const gl = this.gl;
|
|
6313
|
+
gl.deleteBuffer(this.vbo);
|
|
6314
|
+
gl.deleteBuffer(this.ibo);
|
|
6315
|
+
gl.deleteVertexArray(this.vao);
|
|
6316
|
+
}
|
|
6317
|
+
/** Grow the CPU arrays so `vertices` / `indices` more fit. */
|
|
6318
|
+
reserve(vertices, indices) {
|
|
6319
|
+
const needVerts = (this.nVerts + vertices) * FLOATS_PER_VERTEX;
|
|
6320
|
+
if (needVerts > this.verts.length) {
|
|
6321
|
+
let len = this.verts.length;
|
|
6322
|
+
while (len < needVerts) len *= 2;
|
|
6323
|
+
const grown = new Float32Array(len);
|
|
6324
|
+
grown.set(this.verts);
|
|
6325
|
+
this.verts = grown;
|
|
6326
|
+
}
|
|
6327
|
+
const needIdx = this.nIdx + indices;
|
|
6328
|
+
if (needIdx > this.idx.length) {
|
|
6329
|
+
let len = this.idx.length;
|
|
6330
|
+
while (len < needIdx) len *= 2;
|
|
6331
|
+
const grown = new Uint32Array(len);
|
|
6332
|
+
grown.set(this.idx);
|
|
6333
|
+
this.idx = grown;
|
|
6334
|
+
}
|
|
6335
|
+
}
|
|
6336
|
+
/** Size both GPU buffers for at least what is staged, doubling to amortize. */
|
|
6337
|
+
growGpu(vertices, indices) {
|
|
6338
|
+
const gl = this.gl;
|
|
6339
|
+
if (vertices > this.vboVerts) {
|
|
6340
|
+
let capacity = Math.max(this.vboVerts, INITIAL_VERTICES);
|
|
6341
|
+
while (capacity < vertices) capacity *= 2;
|
|
6342
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, this.vbo);
|
|
6343
|
+
gl.bufferData(gl.ARRAY_BUFFER, capacity * FLOATS_PER_VERTEX * 4, gl.DYNAMIC_DRAW);
|
|
6344
|
+
this.vboVerts = capacity;
|
|
6345
|
+
}
|
|
6346
|
+
if (indices > this.iboIdx) {
|
|
6347
|
+
let capacity = Math.max(this.iboIdx, INITIAL_INDICES);
|
|
6348
|
+
while (capacity < indices) capacity *= 2;
|
|
6349
|
+
gl.bindVertexArray(this.vao);
|
|
6350
|
+
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.ibo);
|
|
6351
|
+
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, capacity * 4, gl.DYNAMIC_DRAW);
|
|
6352
|
+
gl.bindVertexArray(null);
|
|
6353
|
+
this.iboIdx = capacity;
|
|
6354
|
+
}
|
|
6355
|
+
}
|
|
6356
|
+
};
|
|
6357
|
+
var FRAME_UPLOADS = /* @__PURE__ */ new WeakMap();
|
|
6358
|
+
var FRAME_PROJ = /* @__PURE__ */ new WeakMap();
|
|
6359
|
+
function uploadedFor(ctx, prog) {
|
|
6360
|
+
let byProgram = FRAME_UPLOADS.get(ctx);
|
|
6361
|
+
if (!byProgram) {
|
|
6362
|
+
byProgram = /* @__PURE__ */ new WeakMap();
|
|
6363
|
+
FRAME_UPLOADS.set(ctx, byProgram);
|
|
6364
|
+
}
|
|
6365
|
+
let uploaded = byProgram.get(prog);
|
|
6366
|
+
if (!uploaded) {
|
|
6367
|
+
uploaded = {};
|
|
6368
|
+
byProgram.set(prog, uploaded);
|
|
6369
|
+
}
|
|
6370
|
+
return uploaded;
|
|
6371
|
+
}
|
|
6372
|
+
function sameValues(prev, next) {
|
|
6373
|
+
if (prev === void 0 || prev.length !== next.length) return false;
|
|
6374
|
+
for (let i = 0; i < prev.length; i++) if (prev[i] !== next[i]) return false;
|
|
6375
|
+
return true;
|
|
6376
|
+
}
|
|
6377
|
+
var BATCH_MODEL = mat3.identity();
|
|
6378
|
+
function projFor(ctx) {
|
|
6379
|
+
let proj = FRAME_PROJ.get(ctx);
|
|
6380
|
+
if (!proj) {
|
|
6381
|
+
proj = mat3.screenToClip(ctx.widthCss, ctx.heightCss);
|
|
6382
|
+
FRAME_PROJ.set(ctx, proj);
|
|
6383
|
+
}
|
|
6384
|
+
return proj;
|
|
6385
|
+
}
|
|
6386
|
+
var COLOR_MATRIX_SCRATCH = new Float32Array(16);
|
|
6387
|
+
function setColorMatrixUniforms(ctx, prog, cm = ctx.state.colorMatrix) {
|
|
6388
|
+
const gl = ctx.gl;
|
|
6389
|
+
const uploaded = uploadedFor(ctx, prog);
|
|
6153
6390
|
const mLoc = prog.uniform("u_colorMatrix");
|
|
6391
|
+
if (mLoc !== void 0) {
|
|
6392
|
+
for (let row = 0; row < 4; row++) {
|
|
6393
|
+
for (let col = 0; col < 4; col++) {
|
|
6394
|
+
COLOR_MATRIX_SCRATCH[col * 4 + row] = cm[row * 5 + col];
|
|
6395
|
+
}
|
|
6396
|
+
}
|
|
6397
|
+
if (!sameValues(uploaded.colorMatrix, COLOR_MATRIX_SCRATCH)) {
|
|
6398
|
+
gl.uniformMatrix4fv(mLoc, false, COLOR_MATRIX_SCRATCH);
|
|
6399
|
+
uploaded.colorMatrix = Float32Array.from(COLOR_MATRIX_SCRATCH);
|
|
6400
|
+
}
|
|
6401
|
+
}
|
|
6154
6402
|
const bLoc = prog.uniform("u_colorBias");
|
|
6155
|
-
if (
|
|
6156
|
-
|
|
6403
|
+
if (bLoc !== void 0) {
|
|
6404
|
+
const bias = [cm[4], cm[9], cm[14], cm[19]];
|
|
6405
|
+
if (!sameValues(uploaded.colorBias, bias)) {
|
|
6406
|
+
gl.uniform4f(bLoc, bias[0], bias[1], bias[2], bias[3]);
|
|
6407
|
+
uploaded.colorBias = Float32Array.from(bias);
|
|
6408
|
+
}
|
|
6409
|
+
}
|
|
6157
6410
|
}
|
|
6158
|
-
function
|
|
6411
|
+
function fillMesh(ctx, path) {
|
|
6159
6412
|
if (ctx.flattenTolerance !== void 0) {
|
|
6160
|
-
return
|
|
6413
|
+
return tessellate(path, { flattenTolerance: ctx.flattenTolerance });
|
|
6161
6414
|
}
|
|
6162
|
-
return
|
|
6415
|
+
return getMesh(path);
|
|
6416
|
+
}
|
|
6417
|
+
function meshHandle(ctx, mesh) {
|
|
6418
|
+
if (ctx.flattenTolerance !== void 0) return ctx.meshCache.uploadTransient(mesh);
|
|
6419
|
+
return ctx.meshCache.handleFor(mesh);
|
|
6420
|
+
}
|
|
6421
|
+
function fillMeshHandle(ctx, path) {
|
|
6422
|
+
return meshHandle(ctx, fillMesh(ctx, path));
|
|
6163
6423
|
}
|
|
6164
6424
|
function dispatch(ctx, cmd) {
|
|
6165
6425
|
switch (cmd.kind) {
|
|
@@ -6168,10 +6428,13 @@ function dispatch(ctx, cmd) {
|
|
|
6168
6428
|
case "path":
|
|
6169
6429
|
return drawPath(ctx, cmd);
|
|
6170
6430
|
case "text":
|
|
6431
|
+
flushSolids(ctx);
|
|
6171
6432
|
return drawText(ctx, cmd);
|
|
6172
6433
|
case "image":
|
|
6434
|
+
flushSolids(ctx);
|
|
6173
6435
|
return drawImage(ctx, cmd);
|
|
6174
6436
|
case "shader":
|
|
6437
|
+
flushSolids(ctx);
|
|
6175
6438
|
return drawShader(ctx, cmd);
|
|
6176
6439
|
}
|
|
6177
6440
|
}
|
|
@@ -6300,11 +6563,13 @@ function drawGroup(ctx, cmd) {
|
|
|
6300
6563
|
"weasel: clip nesting depth exceeded (max 7). You can't nest more than 7 levels of clipped containers in a single draw tree. Flatten the hierarchy or compose poses outside the scene graph."
|
|
6301
6564
|
);
|
|
6302
6565
|
}
|
|
6566
|
+
flushSolids(ctx);
|
|
6303
6567
|
pushClip(ctx, cmd.clip, newDepth);
|
|
6304
6568
|
ctx.clipDepth = newDepth;
|
|
6305
6569
|
}
|
|
6306
6570
|
for (const child of cmd.children) dispatch(ctx, child);
|
|
6307
6571
|
if (cmd.clip) {
|
|
6572
|
+
flushSolids(ctx);
|
|
6308
6573
|
popClip(ctx, cmd.clip, ctx.clipDepth - 1);
|
|
6309
6574
|
ctx.clipDepth -= 1;
|
|
6310
6575
|
}
|
|
@@ -6313,38 +6578,98 @@ function drawGroup(ctx, cmd) {
|
|
|
6313
6578
|
function drawPath(ctx, cmd) {
|
|
6314
6579
|
if (!cmd.fill && !cmd.stroke) return;
|
|
6315
6580
|
if (cmd.fill) {
|
|
6316
|
-
const
|
|
6317
|
-
|
|
6318
|
-
|
|
6581
|
+
const batchablePaint = (cmd.fill.fill === void 0 || cmd.fill.fill === "solid") && (!cmd.vertexColors || cmd.vertexColors.length === 0);
|
|
6582
|
+
const solid = cmd.fill;
|
|
6583
|
+
if (batchablePaint && cmd.path.kind === "rect") {
|
|
6584
|
+
pushRect(ctx, cmd.path, solid);
|
|
6319
6585
|
} else {
|
|
6320
|
-
const
|
|
6321
|
-
if (
|
|
6322
|
-
|
|
6323
|
-
} else if (handle.requiresStencil) {
|
|
6324
|
-
drawPathFillStencil(ctx, cmd.fill, handle);
|
|
6586
|
+
const mesh = fillMesh(ctx, cmd.path);
|
|
6587
|
+
if (batchablePaint && canBatchMesh(mesh)) {
|
|
6588
|
+
pushMesh(ctx, mesh, solid);
|
|
6325
6589
|
} else {
|
|
6326
|
-
|
|
6590
|
+
flushSolids(ctx);
|
|
6591
|
+
const handle = meshHandle(ctx, mesh);
|
|
6592
|
+
if (cmd.vertexColors && cmd.vertexColors.length > 0 && (cmd.fill.fill === void 0 || cmd.fill.fill === "solid")) {
|
|
6593
|
+
drawPathFillVColor(ctx, cmd, solid, handle);
|
|
6594
|
+
} else if (handle.requiresStencil) {
|
|
6595
|
+
drawPathFillStencil(ctx, cmd.fill, handle);
|
|
6596
|
+
} else {
|
|
6597
|
+
drawPathFillByKind(ctx, cmd.fill, handle);
|
|
6598
|
+
}
|
|
6327
6599
|
}
|
|
6328
6600
|
}
|
|
6329
6601
|
}
|
|
6330
|
-
if (cmd.stroke)
|
|
6331
|
-
|
|
6602
|
+
if (cmd.stroke) drawPathStroke(ctx, cmd);
|
|
6603
|
+
}
|
|
6604
|
+
function isIdentityColorMatrix(cm) {
|
|
6605
|
+
return cm === IDENTITY_COLOR_MATRIX || sameValues(IDENTITY_COLOR_MATRIX, cm);
|
|
6606
|
+
}
|
|
6607
|
+
function stagedStateIsLive(ctx, staged) {
|
|
6608
|
+
if (staged.clipDepth !== ctx.clipDepth) return false;
|
|
6609
|
+
if (!staged.foldsAlpha && staged.alpha !== ctx.state.alpha) return false;
|
|
6610
|
+
const colorMatrix = ctx.state.colorMatrix;
|
|
6611
|
+
return staged.colorMatrix === colorMatrix || sameValues(staged.colorMatrix, colorMatrix);
|
|
6612
|
+
}
|
|
6613
|
+
var MAX_BATCHED_MESH_VERTICES = 256;
|
|
6614
|
+
function canBatchMesh(mesh) {
|
|
6615
|
+
return !mesh.requiresStencil && mesh.vertices.length >> 1 <= MAX_BATCHED_MESH_VERTICES;
|
|
6616
|
+
}
|
|
6617
|
+
function stageSolid(ctx, vertices) {
|
|
6618
|
+
if (ctx.solidState !== void 0 && !stagedStateIsLive(ctx, ctx.solidState)) flushSolids(ctx);
|
|
6619
|
+
if (ctx.solidBatch.wouldOverflow(vertices)) flushSolids(ctx);
|
|
6620
|
+
if (ctx.solidState === void 0) {
|
|
6621
|
+
const colorMatrix = ctx.state.colorMatrix;
|
|
6622
|
+
const foldsAlpha = isIdentityColorMatrix(colorMatrix);
|
|
6623
|
+
ctx.solidState = {
|
|
6624
|
+
alpha: foldsAlpha ? 1 : ctx.state.alpha,
|
|
6625
|
+
colorMatrix,
|
|
6626
|
+
clipDepth: ctx.clipDepth,
|
|
6627
|
+
foldsAlpha
|
|
6628
|
+
};
|
|
6332
6629
|
}
|
|
6630
|
+
return ctx.solidState;
|
|
6631
|
+
}
|
|
6632
|
+
function stagedColor(ctx, staged, paint) {
|
|
6633
|
+
const [r, g, b, a] = resolveColor(paint.color);
|
|
6634
|
+
return [r, g, b, a * (paint.opacity ?? 1) * (staged.foldsAlpha ? ctx.state.alpha : 1)];
|
|
6635
|
+
}
|
|
6636
|
+
function pushRect(ctx, rect, fill) {
|
|
6637
|
+
const staged = stageSolid(ctx, 4);
|
|
6638
|
+
const [r, g, b, a] = stagedColor(ctx, staged, fill);
|
|
6639
|
+
ctx.solidBatch.pushRect(
|
|
6640
|
+
rect.x,
|
|
6641
|
+
rect.y,
|
|
6642
|
+
rect.width,
|
|
6643
|
+
rect.height,
|
|
6644
|
+
ctx.state.transform,
|
|
6645
|
+
r,
|
|
6646
|
+
g,
|
|
6647
|
+
b,
|
|
6648
|
+
a
|
|
6649
|
+
);
|
|
6333
6650
|
}
|
|
6334
|
-
function
|
|
6651
|
+
function pushMesh(ctx, mesh, paint) {
|
|
6652
|
+
const staged = stageSolid(ctx, mesh.vertices.length >> 1);
|
|
6653
|
+
const [r, g, b, a] = stagedColor(ctx, staged, paint);
|
|
6654
|
+
ctx.solidBatch.pushMesh(mesh, ctx.state.transform, r, g, b, a);
|
|
6655
|
+
}
|
|
6656
|
+
function flushSolids(ctx) {
|
|
6657
|
+
const batch = ctx.solidBatch;
|
|
6658
|
+
const staged = ctx.solidState;
|
|
6659
|
+
if (batch.length === 0 || staged === void 0) return;
|
|
6335
6660
|
const gl = ctx.gl;
|
|
6336
|
-
const
|
|
6337
|
-
|
|
6338
|
-
|
|
6339
|
-
|
|
6340
|
-
gl.
|
|
6341
|
-
gl.
|
|
6342
|
-
|
|
6343
|
-
|
|
6344
|
-
|
|
6345
|
-
applyClipTest(ctx);
|
|
6346
|
-
gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_INT, 0);
|
|
6661
|
+
const prog = ctx.pathFillVColor;
|
|
6662
|
+
gl.useProgram(prog.handle);
|
|
6663
|
+
const indexCount = batch.uploadAndBind();
|
|
6664
|
+
setProjAndModel(ctx, prog, BATCH_MODEL);
|
|
6665
|
+
gl.uniform4f(prog.uniform("u_color"), 1, 1, 1, 1);
|
|
6666
|
+
gl.uniform1f(prog.uniform("u_alpha"), staged.alpha);
|
|
6667
|
+
setColorMatrixUniforms(ctx, prog, staged.colorMatrix);
|
|
6668
|
+
applyClipTest(ctx, staged.clipDepth);
|
|
6669
|
+
gl.drawElements(gl.TRIANGLES, indexCount, gl.UNSIGNED_INT, 0);
|
|
6347
6670
|
gl.bindVertexArray(null);
|
|
6671
|
+
batch.reset();
|
|
6672
|
+
ctx.solidState = void 0;
|
|
6348
6673
|
}
|
|
6349
6674
|
function expandAnchorColors(perAnchor, handle) {
|
|
6350
6675
|
const aA = handle.anchorA;
|
|
@@ -6389,11 +6714,18 @@ function drawPathFillVColor(ctx, cmd, fill, handle) {
|
|
|
6389
6714
|
gl.bindVertexArray(null);
|
|
6390
6715
|
gl.deleteBuffer(colorVbo);
|
|
6391
6716
|
}
|
|
6392
|
-
function setProjAndModel(ctx, prog) {
|
|
6717
|
+
function setProjAndModel(ctx, prog, model = ctx.state.transform) {
|
|
6393
6718
|
const gl = ctx.gl;
|
|
6394
|
-
const
|
|
6395
|
-
|
|
6396
|
-
|
|
6719
|
+
const uploaded = uploadedFor(ctx, prog);
|
|
6720
|
+
const proj = projFor(ctx);
|
|
6721
|
+
if (!sameValues(uploaded.proj, proj)) {
|
|
6722
|
+
gl.uniformMatrix3fv(prog.uniform("u_proj"), false, proj);
|
|
6723
|
+
uploaded.proj = Float32Array.from(proj);
|
|
6724
|
+
}
|
|
6725
|
+
if (!sameValues(uploaded.model, model)) {
|
|
6726
|
+
gl.uniformMatrix3fv(prog.uniform("u_model"), false, model);
|
|
6727
|
+
uploaded.model = Float32Array.from(model);
|
|
6728
|
+
}
|
|
6397
6729
|
}
|
|
6398
6730
|
function setSolidPaintUniforms(ctx, prog, color, opacity) {
|
|
6399
6731
|
const gl = ctx.gl;
|
|
@@ -6500,9 +6832,8 @@ function drawPathFillGradient(ctx, fill, handle) {
|
|
|
6500
6832
|
gl.drawElements(gl.TRIANGLES, handle.indexCount, gl.UNSIGNED_INT, 0);
|
|
6501
6833
|
gl.bindVertexArray(null);
|
|
6502
6834
|
}
|
|
6503
|
-
function applyClipTest(ctx) {
|
|
6835
|
+
function applyClipTest(ctx, depth = ctx.clipDepth) {
|
|
6504
6836
|
const gl = ctx.gl;
|
|
6505
|
-
const depth = ctx.clipDepth;
|
|
6506
6837
|
if (depth === 0) {
|
|
6507
6838
|
gl.disable(gl.STENCIL_TEST);
|
|
6508
6839
|
return;
|
|
@@ -6586,6 +6917,7 @@ function drawPathStroke(ctx, cmd) {
|
|
|
6586
6917
|
}
|
|
6587
6918
|
const align = stroke.align ?? "center";
|
|
6588
6919
|
if (cmd.path.kind === "polygon" && align !== "center") {
|
|
6920
|
+
flushSolids(ctx);
|
|
6589
6921
|
drawPathStrokeStenciled(ctx, cmd, align);
|
|
6590
6922
|
return;
|
|
6591
6923
|
}
|
|
@@ -6596,6 +6928,12 @@ function drawPathStrokeUnclipped(ctx, cmd) {
|
|
|
6596
6928
|
const solid = stroke.paint;
|
|
6597
6929
|
const mesh = tessellateStroke(cmd.path, stroke, { flattenTolerance: ctx.flattenTolerance });
|
|
6598
6930
|
if (mesh.indices.length === 0) return;
|
|
6931
|
+
const hasVColors = !!(stroke.vertexColors && stroke.vertexColors.length > 0);
|
|
6932
|
+
if (!hasVColors && canBatchMesh(mesh)) {
|
|
6933
|
+
pushMesh(ctx, mesh, solid);
|
|
6934
|
+
return;
|
|
6935
|
+
}
|
|
6936
|
+
flushSolids(ctx);
|
|
6599
6937
|
const handle = ctx.meshCache.uploadTransient(mesh);
|
|
6600
6938
|
const gl = ctx.gl;
|
|
6601
6939
|
if (stroke.vertexColors && stroke.vertexColors.length > 0) {
|
|
@@ -6693,20 +7031,17 @@ function drawText(ctx, cmd) {
|
|
|
6693
7031
|
const maxWidth = cmd.maxWidth ?? Infinity;
|
|
6694
7032
|
const minScreen = ctx.textOutlineMinScreenSize ?? OUTLINE_MIN_SCREEN_PX;
|
|
6695
7033
|
const outlineMinSize = Number.isFinite(minScreen) ? minScreen / modelScale(ctx.state.transform) : void 0;
|
|
6696
|
-
const laid = cachedLayoutRuns(
|
|
6697
|
-
cmd.runs,
|
|
6698
|
-
{ maxWidth, lineHeight, align, outlineMinSize },
|
|
6699
|
-
{ x: cmd.x, y: cmd.y }
|
|
6700
|
-
);
|
|
7034
|
+
const laid = cachedLayoutRuns(cmd.runs, { maxWidth, lineHeight, align, outlineMinSize });
|
|
6701
7035
|
if (laid.groups.length === 0 && laid.decorations.length === 0) return;
|
|
6702
|
-
const
|
|
7036
|
+
const dx = cmd.x;
|
|
7037
|
+
const dy = cmd.y + verticalAlignOffset(cmd.verticalAlign, cmd.height, laid.bounds.height);
|
|
6703
7038
|
const gl = ctx.gl;
|
|
6704
7039
|
applyClipTest(ctx);
|
|
6705
7040
|
const preparedPrograms = /* @__PURE__ */ new Set();
|
|
6706
7041
|
let currentProg = null;
|
|
6707
7042
|
for (const group of laid.groups) {
|
|
6708
7043
|
if (group.source === "outline") {
|
|
6709
|
-
drawTextOutlineGroup(ctx, group, dy);
|
|
7044
|
+
drawTextOutlineGroup(ctx, group, dx, dy);
|
|
6710
7045
|
currentProg = null;
|
|
6711
7046
|
continue;
|
|
6712
7047
|
}
|
|
@@ -6721,31 +7056,31 @@ function drawText(ctx, cmd) {
|
|
|
6721
7056
|
setColorMatrixUniforms(ctx, prog);
|
|
6722
7057
|
gl.uniform1f(prog.uniform("u_alpha"), ctx.state.alpha);
|
|
6723
7058
|
}
|
|
6724
|
-
drawTextGroup(ctx, group, prog, dy);
|
|
7059
|
+
drawTextGroup(ctx, group, prog, dx, dy);
|
|
6725
7060
|
}
|
|
6726
|
-
drawTextDecorations(ctx, laid.decorations, dy);
|
|
7061
|
+
drawTextDecorations(ctx, laid.decorations, dx, dy);
|
|
6727
7062
|
}
|
|
6728
7063
|
var SYNTHETIC_ITALIC_RADIANS = 0.2094;
|
|
6729
|
-
function drawTextOutlineGroup(ctx, group, dy) {
|
|
6730
|
-
const mesh = outlineGroupMesh(group, dy);
|
|
7064
|
+
function drawTextOutlineGroup(ctx, group, dx, dy) {
|
|
7065
|
+
const mesh = outlineGroupMesh(group, dx, dy);
|
|
6731
7066
|
if (mesh) drawPathFillByKind(ctx, group.fill, ctx.meshCache.uploadTransient(mesh));
|
|
6732
7067
|
if (!group.stroke) return;
|
|
6733
|
-
const strokeMesh = outlineGroupStrokeMesh(group, dy);
|
|
7068
|
+
const strokeMesh = outlineGroupStrokeMesh(group, dx, dy);
|
|
6734
7069
|
if (strokeMesh) {
|
|
6735
7070
|
drawPathFillByKind(ctx, group.stroke.paint, ctx.meshCache.uploadTransient(strokeMesh));
|
|
6736
7071
|
}
|
|
6737
7072
|
}
|
|
6738
|
-
function outlineGroupMesh(group, dy) {
|
|
6739
|
-
return mergeGlyphMeshes(group, dy, (glyph) => outlineMesh(glyph.key, glyph.d));
|
|
7073
|
+
function outlineGroupMesh(group, dx, dy) {
|
|
7074
|
+
return mergeGlyphMeshes(group, dx, dy, (glyph) => outlineMesh(glyph.key, glyph.d));
|
|
6740
7075
|
}
|
|
6741
|
-
function outlineGroupStrokeMesh(group, dy) {
|
|
7076
|
+
function outlineGroupStrokeMesh(group, dx, dy) {
|
|
6742
7077
|
const stroke = group.stroke;
|
|
6743
7078
|
if (!stroke) return null;
|
|
6744
7079
|
const width = stroke.width ?? 1;
|
|
6745
7080
|
if (!(width > 0)) return null;
|
|
6746
|
-
return mergeGlyphMeshes(group, dy, (glyph) => glyph.scale > 0 ? outlineStrokeMesh(glyph.key, glyph.d, quantizeEmWidth(width / glyph.scale), stroke) : null);
|
|
7081
|
+
return mergeGlyphMeshes(group, dx, dy, (glyph) => glyph.scale > 0 ? outlineStrokeMesh(glyph.key, glyph.d, quantizeEmWidth(width / glyph.scale), stroke) : null);
|
|
6747
7082
|
}
|
|
6748
|
-
function mergeGlyphMeshes(group, dy, meshFor) {
|
|
7083
|
+
function mergeGlyphMeshes(group, dx, dy, meshFor) {
|
|
6749
7084
|
const parts = [];
|
|
6750
7085
|
let vertexFloats = 0;
|
|
6751
7086
|
let indexCount = 0;
|
|
@@ -6768,7 +7103,7 @@ function mergeGlyphMeshes(group, dy, meshFor) {
|
|
|
6768
7103
|
for (let k = 0; k < mesh.vertices.length; k += 2) {
|
|
6769
7104
|
const ex = mesh.vertices[k];
|
|
6770
7105
|
const ey = mesh.vertices[k + 1];
|
|
6771
|
-
vertices[vi++] = x + (ex - ey * shear) * scale2;
|
|
7106
|
+
vertices[vi++] = x + dx + (ex - ey * shear) * scale2;
|
|
6772
7107
|
vertices[vi++] = baselineY + dy + ey * scale2;
|
|
6773
7108
|
}
|
|
6774
7109
|
for (let k = 0; k < mesh.indices.length; k++) indices[ii++] = base + mesh.indices[k];
|
|
@@ -6776,7 +7111,7 @@ function mergeGlyphMeshes(group, dy, meshFor) {
|
|
|
6776
7111
|
}
|
|
6777
7112
|
return { vertices, indices };
|
|
6778
7113
|
}
|
|
6779
|
-
function drawTextDecorations(ctx, decorations, dy) {
|
|
7114
|
+
function drawTextDecorations(ctx, decorations, dx, dy) {
|
|
6780
7115
|
if (decorations.length === 0) return;
|
|
6781
7116
|
const batches = /* @__PURE__ */ new Map();
|
|
6782
7117
|
for (const d of decorations) {
|
|
@@ -6799,14 +7134,15 @@ function drawTextDecorations(ctx, decorations, dy) {
|
|
|
6799
7134
|
const vertices = new Float32Array(rects.length * 4 * 2);
|
|
6800
7135
|
let vi = 0;
|
|
6801
7136
|
for (const d of rects) {
|
|
7137
|
+
const dx0 = d.x0 + dx, dx1 = d.x1 + dx;
|
|
6802
7138
|
const dy0 = d.y0 + dy, dy1 = d.y1 + dy;
|
|
6803
|
-
vertices[vi++] =
|
|
7139
|
+
vertices[vi++] = dx0;
|
|
6804
7140
|
vertices[vi++] = dy0;
|
|
6805
|
-
vertices[vi++] =
|
|
7141
|
+
vertices[vi++] = dx1;
|
|
6806
7142
|
vertices[vi++] = dy0;
|
|
6807
|
-
vertices[vi++] =
|
|
7143
|
+
vertices[vi++] = dx0;
|
|
6808
7144
|
vertices[vi++] = dy1;
|
|
6809
|
-
vertices[vi++] =
|
|
7145
|
+
vertices[vi++] = dx1;
|
|
6810
7146
|
vertices[vi++] = dy1;
|
|
6811
7147
|
}
|
|
6812
7148
|
const indices = new Uint32Array(rects.length * 6);
|
|
@@ -6845,7 +7181,7 @@ function drawTextDecorations(ctx, decorations, dy) {
|
|
|
6845
7181
|
gl.deleteBuffer(ibo);
|
|
6846
7182
|
}
|
|
6847
7183
|
}
|
|
6848
|
-
function drawTextGroup(ctx, group, prog, dy) {
|
|
7184
|
+
function drawTextGroup(ctx, group, prog, dx, dy) {
|
|
6849
7185
|
if (group.source === "canvas") {
|
|
6850
7186
|
if (!syncDynamicPageTexture(ctx.textureCache, group.page)) return;
|
|
6851
7187
|
} else {
|
|
@@ -6856,23 +7192,24 @@ function drawTextGroup(ctx, group, prog, dy) {
|
|
|
6856
7192
|
const vertices = new Float32Array(group.quads.length * 4 * 5);
|
|
6857
7193
|
let vi = 0;
|
|
6858
7194
|
for (const q of group.quads) {
|
|
7195
|
+
const x0 = q.x0 + dx, x1 = q.x1 + dx;
|
|
6859
7196
|
const y0 = q.y0 + dy, y1 = q.y1 + dy, by = q.baselineY + dy;
|
|
6860
|
-
vertices[vi++] =
|
|
7197
|
+
vertices[vi++] = x0;
|
|
6861
7198
|
vertices[vi++] = y0;
|
|
6862
7199
|
vertices[vi++] = q.u0;
|
|
6863
7200
|
vertices[vi++] = q.v0;
|
|
6864
7201
|
vertices[vi++] = by;
|
|
6865
|
-
vertices[vi++] =
|
|
7202
|
+
vertices[vi++] = x1;
|
|
6866
7203
|
vertices[vi++] = y0;
|
|
6867
7204
|
vertices[vi++] = q.u1;
|
|
6868
7205
|
vertices[vi++] = q.v0;
|
|
6869
7206
|
vertices[vi++] = by;
|
|
6870
|
-
vertices[vi++] =
|
|
7207
|
+
vertices[vi++] = x0;
|
|
6871
7208
|
vertices[vi++] = y1;
|
|
6872
7209
|
vertices[vi++] = q.u0;
|
|
6873
7210
|
vertices[vi++] = q.v1;
|
|
6874
7211
|
vertices[vi++] = by;
|
|
6875
|
-
vertices[vi++] =
|
|
7212
|
+
vertices[vi++] = x1;
|
|
6876
7213
|
vertices[vi++] = y1;
|
|
6877
7214
|
vertices[vi++] = q.u1;
|
|
6878
7215
|
vertices[vi++] = q.v1;
|
|
@@ -7085,10 +7422,7 @@ var WeaselRenderer = class {
|
|
|
7085
7422
|
programRegistry = /* @__PURE__ */ new Map();
|
|
7086
7423
|
quadVbo = null;
|
|
7087
7424
|
quadIbo = null;
|
|
7088
|
-
|
|
7089
|
-
rectVao = null;
|
|
7090
|
-
rectVbo = null;
|
|
7091
|
-
rectIbo = null;
|
|
7425
|
+
solidBatch;
|
|
7092
7426
|
groupState = new GroupState();
|
|
7093
7427
|
widthCss;
|
|
7094
7428
|
heightCss;
|
|
@@ -7163,31 +7497,7 @@ var WeaselRenderer = class {
|
|
|
7163
7497
|
this.imageCache = new GLImageCache(this.gl, this.imageMinification);
|
|
7164
7498
|
this.gradRampCache = new GradientRampCache(this.gl);
|
|
7165
7499
|
this.uploadQuadGeometry();
|
|
7166
|
-
this.
|
|
7167
|
-
}
|
|
7168
|
-
/** Allocate the shared rect VAO + dynamic VBO (4 verts × 2 floats) + static
|
|
7169
|
-
* IBO (6 indices). drawRectFast bufferSubData's the 4 corner coords each
|
|
7170
|
-
* draw, avoiding per-rect buffer allocation in animated demos. */
|
|
7171
|
-
uploadRectGeometry(aPositionLoc) {
|
|
7172
|
-
const gl = this.gl;
|
|
7173
|
-
this.rectVao = gl.createVertexArray();
|
|
7174
|
-
this.rectVbo = gl.createBuffer();
|
|
7175
|
-
this.rectIbo = gl.createBuffer();
|
|
7176
|
-
if (!this.rectVao || !this.rectVbo || !this.rectIbo) {
|
|
7177
|
-
throw new Error("WeaselRenderer: failed to create rect-fast geometry");
|
|
7178
|
-
}
|
|
7179
|
-
gl.bindVertexArray(this.rectVao);
|
|
7180
|
-
gl.bindBuffer(gl.ARRAY_BUFFER, this.rectVbo);
|
|
7181
|
-
gl.bufferData(gl.ARRAY_BUFFER, 8 * 4, gl.DYNAMIC_DRAW);
|
|
7182
|
-
gl.enableVertexAttribArray(aPositionLoc);
|
|
7183
|
-
gl.vertexAttribPointer(aPositionLoc, 2, gl.FLOAT, false, 0, 0);
|
|
7184
|
-
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.rectIbo);
|
|
7185
|
-
gl.bufferData(
|
|
7186
|
-
gl.ELEMENT_ARRAY_BUFFER,
|
|
7187
|
-
new Uint32Array([0, 1, 2, 0, 2, 3]),
|
|
7188
|
-
gl.STATIC_DRAW
|
|
7189
|
-
);
|
|
7190
|
-
gl.bindVertexArray(null);
|
|
7500
|
+
this.solidBatch = new SolidBatch(this.gl, this.pathFillVColor);
|
|
7191
7501
|
}
|
|
7192
7502
|
uploadQuadGeometry() {
|
|
7193
7503
|
const gl = this.gl;
|
|
@@ -7274,7 +7584,7 @@ var WeaselRenderer = class {
|
|
|
7274
7584
|
this.imageCache = new GLImageCache(this.gl, this.imageMinification);
|
|
7275
7585
|
this.gradRampCache = new GradientRampCache(this.gl);
|
|
7276
7586
|
this.uploadQuadGeometry();
|
|
7277
|
-
this.
|
|
7587
|
+
this.solidBatch = new SolidBatch(this.gl, this.pathFillVColor);
|
|
7278
7588
|
for (const id of this.programRegistry.keys()) {
|
|
7279
7589
|
const src = getProgramSource(id);
|
|
7280
7590
|
if (!src) continue;
|
|
@@ -7334,9 +7644,7 @@ var WeaselRenderer = class {
|
|
|
7334
7644
|
this.gradRampCache.free();
|
|
7335
7645
|
if (this.quadVbo) gl.deleteBuffer(this.quadVbo);
|
|
7336
7646
|
if (this.quadIbo) gl.deleteBuffer(this.quadIbo);
|
|
7337
|
-
|
|
7338
|
-
if (this.rectIbo) gl.deleteBuffer(this.rectIbo);
|
|
7339
|
-
if (this.rectVao) gl.deleteVertexArray(this.rectVao);
|
|
7647
|
+
this.solidBatch.dispose();
|
|
7340
7648
|
}
|
|
7341
7649
|
/**
|
|
7342
7650
|
* Draw one frame.
|
|
@@ -7369,8 +7677,7 @@ var WeaselRenderer = class {
|
|
|
7369
7677
|
programRegistry: this.programRegistry,
|
|
7370
7678
|
quadVbo: this.quadVbo,
|
|
7371
7679
|
quadIbo: this.quadIbo,
|
|
7372
|
-
|
|
7373
|
-
rectVbo: this.rectVbo,
|
|
7680
|
+
solidBatch: this.solidBatch,
|
|
7374
7681
|
state: this.groupState,
|
|
7375
7682
|
widthCss: this.widthCss,
|
|
7376
7683
|
heightCss: this.heightCss,
|
|
@@ -7380,6 +7687,7 @@ var WeaselRenderer = class {
|
|
|
7380
7687
|
viewMatrix
|
|
7381
7688
|
};
|
|
7382
7689
|
for (const cmd of commands) dispatch(ctx, cmd);
|
|
7690
|
+
flushSolids(ctx);
|
|
7383
7691
|
this.meshCache.freeTransient();
|
|
7384
7692
|
}
|
|
7385
7693
|
resize(dims) {
|
|
@@ -7409,6 +7717,10 @@ var WeaselRenderer = class {
|
|
|
7409
7717
|
return this.pathFillVColor;
|
|
7410
7718
|
}
|
|
7411
7719
|
/** @internal */
|
|
7720
|
+
_solidBatch() {
|
|
7721
|
+
return this.solidBatch;
|
|
7722
|
+
}
|
|
7723
|
+
/** @internal */
|
|
7412
7724
|
_textSdf() {
|
|
7413
7725
|
return this.textSdf;
|
|
7414
7726
|
}
|
|
@@ -7794,12 +8106,7 @@ function moveGestureAdapter(scene) {
|
|
|
7794
8106
|
return {
|
|
7795
8107
|
getNode: (id) => scene.get(asNodeId(id)),
|
|
7796
8108
|
getNodes: () => {
|
|
7797
|
-
|
|
7798
|
-
for (const id of scene.renderOrder()) {
|
|
7799
|
-
const n = scene.get(id);
|
|
7800
|
-
if (n) out.push(n);
|
|
7801
|
-
}
|
|
7802
|
-
return out;
|
|
8109
|
+
return [...scene.renderOrderNodes()];
|
|
7803
8110
|
},
|
|
7804
8111
|
getPose: (id) => scene.get(asNodeId(id)).pose,
|
|
7805
8112
|
getParent: (id) => scene.get(asNodeId(id))?.parent ?? null,
|
|
@@ -8365,12 +8672,7 @@ function defaultCommitAdapter(scene) {
|
|
|
8365
8672
|
return {
|
|
8366
8673
|
getNode: (id) => scene.get(asNodeId(id)),
|
|
8367
8674
|
getNodes: () => {
|
|
8368
|
-
|
|
8369
|
-
for (const id of scene.renderOrder()) {
|
|
8370
|
-
const n = scene.get(id);
|
|
8371
|
-
if (n) out.push(n);
|
|
8372
|
-
}
|
|
8373
|
-
return out;
|
|
8675
|
+
return [...scene.renderOrderNodes()];
|
|
8374
8676
|
},
|
|
8375
8677
|
getPose: (id) => scene.get(asNodeId(id)).pose,
|
|
8376
8678
|
getParent: (id) => scene.get(asNodeId(id))?.parent ?? null,
|
|
@@ -12851,18 +13153,39 @@ function modsCount(mods) {
|
|
|
12851
13153
|
}
|
|
12852
13154
|
function targetRank(target) {
|
|
12853
13155
|
if (target === void 0) return 0;
|
|
12854
|
-
|
|
12855
|
-
if (
|
|
12856
|
-
|
|
12857
|
-
|
|
13156
|
+
const form = parseTargetSpec(target);
|
|
13157
|
+
if (form === null) return 1;
|
|
13158
|
+
switch (form.form) {
|
|
13159
|
+
case "kind":
|
|
13160
|
+
return form.requireSelected ? 3 : 2;
|
|
13161
|
+
case "affordance":
|
|
13162
|
+
return 2;
|
|
13163
|
+
case "body":
|
|
13164
|
+
return 1;
|
|
13165
|
+
case "predicate":
|
|
13166
|
+
return 1;
|
|
13167
|
+
default: {
|
|
13168
|
+
return 1;
|
|
13169
|
+
}
|
|
13170
|
+
}
|
|
12858
13171
|
}
|
|
12859
13172
|
function targetConsultsAffordance(specTarget) {
|
|
12860
13173
|
if (specTarget === void 0) return false;
|
|
12861
|
-
|
|
12862
|
-
|
|
12863
|
-
|
|
13174
|
+
const form = parseTargetSpec(specTarget);
|
|
13175
|
+
if (form === null) return false;
|
|
13176
|
+
switch (form.form) {
|
|
13177
|
+
case "predicate":
|
|
13178
|
+
return form.kindOf.readsAffordance !== false;
|
|
13179
|
+
case "affordance":
|
|
13180
|
+
return true;
|
|
13181
|
+
case "body":
|
|
13182
|
+
return false;
|
|
13183
|
+
case "kind":
|
|
13184
|
+
return false;
|
|
13185
|
+
default: {
|
|
13186
|
+
return false;
|
|
13187
|
+
}
|
|
12864
13188
|
}
|
|
12865
|
-
return typeof specTarget === "string" && specTarget.startsWith("affordance:");
|
|
12866
13189
|
}
|
|
12867
13190
|
function specTargetOf(spec) {
|
|
12868
13191
|
return "target" in spec ? spec.target : void 0;
|
|
@@ -12905,7 +13228,7 @@ function reportDeadClaim(owner, warn) {
|
|
|
12905
13228
|
);
|
|
12906
13229
|
}
|
|
12907
13230
|
function specificity(spec) {
|
|
12908
|
-
const t = targetRank(
|
|
13231
|
+
const t = targetRank(specTargetOf(spec));
|
|
12909
13232
|
const mods = "mods" in spec ? spec.mods : void 0;
|
|
12910
13233
|
const m = modsCount(mods);
|
|
12911
13234
|
const p = "phase" in spec && spec.phase !== void 0 ? 1 : 0;
|
|
@@ -15439,21 +15762,18 @@ function textLineBoxes(pose, opts = {}) {
|
|
|
15439
15762
|
const style = resolveTextStyle(pose.style);
|
|
15440
15763
|
const source = pose.runs && pose.runs.length > 0 ? pose.runs : pose.text;
|
|
15441
15764
|
const runs = resolveRuns(toRuns(source), style);
|
|
15442
|
-
const laid = layoutRuns(
|
|
15443
|
-
|
|
15444
|
-
|
|
15445
|
-
|
|
15446
|
-
|
|
15447
|
-
|
|
15448
|
-
|
|
15449
|
-
{ x: pose.x, y: pose.y }
|
|
15450
|
-
);
|
|
15451
|
-
const dy = verticalAlignOffset(pose.verticalAlign, pose.height, laid.bounds.height);
|
|
15765
|
+
const laid = layoutRuns(runs, {
|
|
15766
|
+
maxWidth: opts.maxWidth ?? pose.width,
|
|
15767
|
+
lineHeight: style.lineHeight,
|
|
15768
|
+
align: style.align
|
|
15769
|
+
});
|
|
15770
|
+
const dx = pose.x;
|
|
15771
|
+
const dy = pose.y + verticalAlignOffset(pose.verticalAlign, pose.height, laid.bounds.height);
|
|
15452
15772
|
const out = [];
|
|
15453
15773
|
for (const line of laid.lines) {
|
|
15454
15774
|
if (!opts.includeEmpty && line.x1 <= line.x0) continue;
|
|
15455
15775
|
out.push({
|
|
15456
|
-
x: line.x0 - padding,
|
|
15776
|
+
x: line.x0 + dx - padding,
|
|
15457
15777
|
y: line.y0 + dy - padding,
|
|
15458
15778
|
width: line.x1 - line.x0 + padding * 2,
|
|
15459
15779
|
height: line.y1 - line.y0 + padding * 2
|
|
@@ -18168,6 +18488,13 @@ function wrapWithPoseRotation(cmds, pose) {
|
|
|
18168
18488
|
children: cmds
|
|
18169
18489
|
}];
|
|
18170
18490
|
}
|
|
18491
|
+
function wrapNodeOutput(cmds, pose, alpha) {
|
|
18492
|
+
const rotated = wrapWithPoseRotation(cmds, pose);
|
|
18493
|
+
if (alpha !== 1 && rotated.length > 0) {
|
|
18494
|
+
return [{ kind: "group", alpha, children: rotated }];
|
|
18495
|
+
}
|
|
18496
|
+
return rotated;
|
|
18497
|
+
}
|
|
18171
18498
|
function CursorCoordsHud({ canvasRef, viewRef, offset }) {
|
|
18172
18499
|
const [state, setState] = useState({
|
|
18173
18500
|
client: { x: 0, y: 0 },
|
|
@@ -18415,12 +18742,7 @@ function buildSceneLayer(cfg, adapter, debugSink, boundsOfFn, hideIds, slot) {
|
|
|
18415
18742
|
const oy = pose.y ?? (b ? b.y : 0);
|
|
18416
18743
|
debugSink.recordOrigin(obj.id, { x: ox, y: oy });
|
|
18417
18744
|
}
|
|
18418
|
-
|
|
18419
|
-
const alpha = cfg.alphaFor ? cfg.alphaFor(obj.id) : 1;
|
|
18420
|
-
if (alpha !== 1 && rotated.length > 0) {
|
|
18421
|
-
return [{ kind: "group", alpha, children: rotated }];
|
|
18422
|
-
}
|
|
18423
|
-
return rotated;
|
|
18745
|
+
return wrapNodeOutput(cmds, pose, cfg.alphaFor ? cfg.alphaFor(obj.id) : 1);
|
|
18424
18746
|
};
|
|
18425
18747
|
const hierarchicalAdapter = cfg.toPose ? {
|
|
18426
18748
|
...a,
|
|
@@ -18444,13 +18766,8 @@ function buildSceneLayer(cfg, adapter, debugSink, boundsOfFn, hideIds, slot) {
|
|
|
18444
18766
|
const pose = toPose(obj);
|
|
18445
18767
|
if (drawOne) {
|
|
18446
18768
|
const cmds = drawOne(obj, pose, view);
|
|
18447
|
-
const
|
|
18448
|
-
const
|
|
18449
|
-
if (alpha !== 1 && rotated.length > 0) {
|
|
18450
|
-
children.push({ kind: "group", alpha, children: rotated });
|
|
18451
|
-
} else {
|
|
18452
|
-
for (const cmd of rotated) children.push(cmd);
|
|
18453
|
-
}
|
|
18769
|
+
const wrapped = wrapNodeOutput(cmds, pose, cfg.alphaFor ? cfg.alphaFor(obj.id) : 1);
|
|
18770
|
+
for (const cmd of wrapped) children.push(cmd);
|
|
18454
18771
|
}
|
|
18455
18772
|
if (debugSink) {
|
|
18456
18773
|
const b = boundsOfFn ? boundsOfFn(obj.id) : null;
|
|
@@ -19164,6 +19481,7 @@ function createScene(options) {
|
|
|
19164
19481
|
return i;
|
|
19165
19482
|
}
|
|
19166
19483
|
function rebuildLayerIndex() {
|
|
19484
|
+
invalidateOrder();
|
|
19167
19485
|
state.layerIndex.clear();
|
|
19168
19486
|
for (let i = 0; i < state.layers.length; i++) {
|
|
19169
19487
|
state.layerIndex.set(state.layers[i].id, i);
|
|
@@ -19189,6 +19507,7 @@ function createScene(options) {
|
|
|
19189
19507
|
const idx = sibs.indexOf(id);
|
|
19190
19508
|
if (idx < 0) throw new Error(`Scene: node "${id}" not found in its parent's children`);
|
|
19191
19509
|
sibs.splice(idx, 1);
|
|
19510
|
+
invalidateOrder();
|
|
19192
19511
|
return { parent: node.parent, index: idx };
|
|
19193
19512
|
}
|
|
19194
19513
|
function attach(id, parent, index) {
|
|
@@ -19197,6 +19516,7 @@ function createScene(options) {
|
|
|
19197
19516
|
sibs.splice(i, 0, id);
|
|
19198
19517
|
const node = requireNode(id);
|
|
19199
19518
|
node.parent = parent;
|
|
19519
|
+
invalidateOrder();
|
|
19200
19520
|
}
|
|
19201
19521
|
function descendants(id, out) {
|
|
19202
19522
|
const n = state.nodes.get(id);
|
|
@@ -19276,9 +19596,11 @@ function createScene(options) {
|
|
|
19276
19596
|
apply: (p) => {
|
|
19277
19597
|
requireLayerIndex(p.to);
|
|
19278
19598
|
requireNode(p.id).layer = p.to;
|
|
19599
|
+
invalidateOrder();
|
|
19279
19600
|
},
|
|
19280
19601
|
revert: (p) => {
|
|
19281
19602
|
requireNode(p.id).layer = p.from;
|
|
19603
|
+
invalidateOrder();
|
|
19282
19604
|
}
|
|
19283
19605
|
});
|
|
19284
19606
|
registerKitOp("kit:move", {
|
|
@@ -19417,21 +19739,98 @@ function createScene(options) {
|
|
|
19417
19739
|
registered.set(k, h);
|
|
19418
19740
|
}
|
|
19419
19741
|
}
|
|
19420
|
-
function
|
|
19421
|
-
|
|
19422
|
-
|
|
19423
|
-
|
|
19424
|
-
|
|
19425
|
-
|
|
19426
|
-
|
|
19427
|
-
|
|
19428
|
-
|
|
19429
|
-
|
|
19430
|
-
|
|
19431
|
-
|
|
19742
|
+
function renderOrderInternal() {
|
|
19743
|
+
return state.layers.length === 1 ? renderOrderFlat() : renderOrderBucketed();
|
|
19744
|
+
}
|
|
19745
|
+
function renderOrderNodesInternal() {
|
|
19746
|
+
return state.layers.length === 1 ? renderOrderNodesFlat() : renderOrderNodesBucketed();
|
|
19747
|
+
}
|
|
19748
|
+
let structureGeneration = 0;
|
|
19749
|
+
let orderCache = { gen: 0 };
|
|
19750
|
+
function invalidateOrder() {
|
|
19751
|
+
structureGeneration++;
|
|
19752
|
+
}
|
|
19753
|
+
function currentOrderCache() {
|
|
19754
|
+
if (orderCache.gen !== structureGeneration) {
|
|
19755
|
+
orderCache = { gen: structureGeneration };
|
|
19756
|
+
}
|
|
19757
|
+
return orderCache;
|
|
19758
|
+
}
|
|
19759
|
+
function renderOrderFlat() {
|
|
19760
|
+
const only = state.layers[0].id;
|
|
19761
|
+
const out = [];
|
|
19762
|
+
const stack = [...state.roots].reverse();
|
|
19763
|
+
while (stack.length > 0) {
|
|
19764
|
+
const id = stack.pop();
|
|
19765
|
+
const node = state.nodes.get(id);
|
|
19766
|
+
if (!node) continue;
|
|
19767
|
+
if (node.layer === only) out.push(id);
|
|
19768
|
+
if (node.kind === "container") {
|
|
19769
|
+
for (let i = node.children.length - 1; i >= 0; i--) {
|
|
19770
|
+
stack.push(node.children[i]);
|
|
19771
|
+
}
|
|
19772
|
+
}
|
|
19773
|
+
}
|
|
19774
|
+
return out;
|
|
19775
|
+
}
|
|
19776
|
+
function renderOrderNodesFlat() {
|
|
19777
|
+
const only = state.layers[0].id;
|
|
19778
|
+
const out = [];
|
|
19779
|
+
const stack = [...state.roots].reverse();
|
|
19780
|
+
while (stack.length > 0) {
|
|
19781
|
+
const id = stack.pop();
|
|
19782
|
+
const node = state.nodes.get(id);
|
|
19783
|
+
if (!node) continue;
|
|
19784
|
+
if (node.layer === only) out.push(node);
|
|
19785
|
+
if (node.kind === "container") {
|
|
19786
|
+
for (let i = node.children.length - 1; i >= 0; i--) {
|
|
19787
|
+
stack.push(node.children[i]);
|
|
19432
19788
|
}
|
|
19433
19789
|
}
|
|
19434
19790
|
}
|
|
19791
|
+
return out;
|
|
19792
|
+
}
|
|
19793
|
+
function renderOrderBucketed() {
|
|
19794
|
+
const buckets = state.layers.map(() => []);
|
|
19795
|
+
const stack = [...state.roots].reverse();
|
|
19796
|
+
while (stack.length > 0) {
|
|
19797
|
+
const id = stack.pop();
|
|
19798
|
+
const node = state.nodes.get(id);
|
|
19799
|
+
if (!node) continue;
|
|
19800
|
+
const bucket = buckets[state.layerIndex.get(node.layer) ?? -1];
|
|
19801
|
+
if (bucket) bucket.push(id);
|
|
19802
|
+
if (node.kind === "container") {
|
|
19803
|
+
for (let i = node.children.length - 1; i >= 0; i--) {
|
|
19804
|
+
stack.push(node.children[i]);
|
|
19805
|
+
}
|
|
19806
|
+
}
|
|
19807
|
+
}
|
|
19808
|
+
const out = [];
|
|
19809
|
+
for (const bucket of buckets) {
|
|
19810
|
+
for (const id of bucket) out.push(id);
|
|
19811
|
+
}
|
|
19812
|
+
return out;
|
|
19813
|
+
}
|
|
19814
|
+
function renderOrderNodesBucketed() {
|
|
19815
|
+
const buckets = state.layers.map(() => []);
|
|
19816
|
+
const stack = [...state.roots].reverse();
|
|
19817
|
+
while (stack.length > 0) {
|
|
19818
|
+
const id = stack.pop();
|
|
19819
|
+
const node = state.nodes.get(id);
|
|
19820
|
+
if (!node) continue;
|
|
19821
|
+
const bucket = buckets[state.layerIndex.get(node.layer) ?? -1];
|
|
19822
|
+
if (bucket) bucket.push(node);
|
|
19823
|
+
if (node.kind === "container") {
|
|
19824
|
+
for (let i = node.children.length - 1; i >= 0; i--) {
|
|
19825
|
+
stack.push(node.children[i]);
|
|
19826
|
+
}
|
|
19827
|
+
}
|
|
19828
|
+
}
|
|
19829
|
+
const out = [];
|
|
19830
|
+
for (const bucket of buckets) {
|
|
19831
|
+
for (const node of bucket) out.push(node);
|
|
19832
|
+
}
|
|
19833
|
+
return out;
|
|
19435
19834
|
}
|
|
19436
19835
|
const scene = {
|
|
19437
19836
|
get nodes() {
|
|
@@ -19460,7 +19859,12 @@ function createScene(options) {
|
|
|
19460
19859
|
return out;
|
|
19461
19860
|
},
|
|
19462
19861
|
renderOrder() {
|
|
19463
|
-
|
|
19862
|
+
const c = currentOrderCache();
|
|
19863
|
+
return c.ids ??= renderOrderInternal();
|
|
19864
|
+
},
|
|
19865
|
+
renderOrderNodes() {
|
|
19866
|
+
const c = currentOrderCache();
|
|
19867
|
+
return c.nodes ??= renderOrderNodesInternal();
|
|
19464
19868
|
},
|
|
19465
19869
|
add(spec) {
|
|
19466
19870
|
const id = spec.id ?? generateId();
|
|
@@ -19768,9 +20172,8 @@ function createScene(options) {
|
|
|
19768
20172
|
},
|
|
19769
20173
|
toJSON() {
|
|
19770
20174
|
const nodes = [];
|
|
19771
|
-
for (const
|
|
19772
|
-
const
|
|
19773
|
-
if (!n) continue;
|
|
20175
|
+
for (const n of renderOrderNodesInternal()) {
|
|
20176
|
+
const id = n.id;
|
|
19774
20177
|
const out = {
|
|
19775
20178
|
id,
|
|
19776
20179
|
kind: n.kind,
|
|
@@ -19804,6 +20207,7 @@ function createScene(options) {
|
|
|
19804
20207
|
state.roots.length = 0;
|
|
19805
20208
|
state.layers.length = 0;
|
|
19806
20209
|
state.layerIndex.clear();
|
|
20210
|
+
invalidateOrder();
|
|
19807
20211
|
for (let i = 0; i < json.systemLayers.length; i++) {
|
|
19808
20212
|
const spec = json.systemLayers[i];
|
|
19809
20213
|
if (state.layerIndex.has(spec.id)) {
|
|
@@ -20072,9 +20476,8 @@ function sceneToAdapter(scene, options = {}) {
|
|
|
20072
20476
|
getNodes() {
|
|
20073
20477
|
const visible = visibleLayers();
|
|
20074
20478
|
const out = [];
|
|
20075
|
-
for (const
|
|
20076
|
-
|
|
20077
|
-
if (n && visible.has(n.layer)) out.push(n);
|
|
20479
|
+
for (const n of scene.renderOrderNodes()) {
|
|
20480
|
+
if (visible.has(n.layer)) out.push(n);
|
|
20078
20481
|
}
|
|
20079
20482
|
return out;
|
|
20080
20483
|
},
|
|
@@ -20405,9 +20808,7 @@ function useSceneSelectTool(args) {
|
|
|
20405
20808
|
// path descriptor for a tighter test.
|
|
20406
20809
|
hitTestArea: (rect) => {
|
|
20407
20810
|
const hits = [];
|
|
20408
|
-
for (const
|
|
20409
|
-
const n = scene.get(nid);
|
|
20410
|
-
if (!n) continue;
|
|
20811
|
+
for (const n of scene.renderOrderNodes()) {
|
|
20411
20812
|
if (isPathLike2(n.pose) && pathPoseDescriptor.intersectsRect) {
|
|
20412
20813
|
if (pathPoseDescriptor.intersectsRect(n.pose, rect)) hits.push(n.id);
|
|
20413
20814
|
continue;
|
|
@@ -20445,9 +20846,8 @@ function useSceneSelectTool(args) {
|
|
|
20445
20846
|
}
|
|
20446
20847
|
const tolerance = pickTolerancePx / meanScale(getView?.()?.scale ?? { x: 1, y: 1 });
|
|
20447
20848
|
const out = [];
|
|
20448
|
-
for (const
|
|
20449
|
-
|
|
20450
|
-
if (!n || !poseContainsRotated(n.pose, wx, wy, tolerance)) continue;
|
|
20849
|
+
for (const n of scene.renderOrderNodes()) {
|
|
20850
|
+
if (!poseContainsRotated(n.pose, wx, wy, tolerance)) continue;
|
|
20451
20851
|
if (shapePicking && !shapeCoversPoint(n, n.pose, wx, wy, { tolerance })) continue;
|
|
20452
20852
|
out.push(n.id);
|
|
20453
20853
|
}
|
|
@@ -21564,23 +21964,25 @@ function hitTestAreaPolygon(scene, area, areaBounds) {
|
|
|
21564
21964
|
const ab = areaBounds ?? boundsOf(area);
|
|
21565
21965
|
if (!ab) return [];
|
|
21566
21966
|
const hits = [];
|
|
21567
|
-
|
|
21568
|
-
|
|
21569
|
-
|
|
21967
|
+
const order = scene.renderOrderNodes();
|
|
21968
|
+
for (let i = 0; i < order.length; i++) {
|
|
21969
|
+
const node = order[i];
|
|
21970
|
+
if (node.kind === "container") continue;
|
|
21570
21971
|
const pose = node.pose;
|
|
21571
|
-
const
|
|
21972
|
+
const silhouette = pose !== null && typeof pose === "object" && pose.kind === "polygon";
|
|
21973
|
+
const b = silhouette ? nodeMemo(node, "aabb", pose, () => aabbOfPose(pose)) : aabbOfPose(pose);
|
|
21572
21974
|
if (!Number.isFinite(b.x) || !Number.isFinite(b.y) || !Number.isFinite(b.width) || !Number.isFinite(b.height)) {
|
|
21573
21975
|
continue;
|
|
21574
21976
|
}
|
|
21575
21977
|
if (b.x >= ab.x + ab.width || b.x + b.width <= ab.x || b.y >= ab.y + ab.height || b.y + b.height <= ab.y) {
|
|
21576
21978
|
continue;
|
|
21577
21979
|
}
|
|
21578
|
-
if (!
|
|
21579
|
-
hits.push(id);
|
|
21980
|
+
if (!silhouette) {
|
|
21981
|
+
hits.push(node.id);
|
|
21580
21982
|
continue;
|
|
21581
21983
|
}
|
|
21582
21984
|
if (silhouetteOverlapsArea(pose.coords, area)) {
|
|
21583
|
-
hits.push(id);
|
|
21985
|
+
hits.push(node.id);
|
|
21584
21986
|
}
|
|
21585
21987
|
}
|
|
21586
21988
|
return hits;
|
|
@@ -23735,14 +24137,25 @@ inferredNodeRouting.map((e) => ({
|
|
|
23735
24137
|
schema: shapeSchema({ text: e.name === "text" })
|
|
23736
24138
|
}));
|
|
23737
24139
|
var RENDERER_CACHE = /* @__PURE__ */ new WeakMap();
|
|
23738
|
-
function
|
|
23739
|
-
|
|
23740
|
-
|
|
23741
|
-
|
|
23742
|
-
|
|
23743
|
-
|
|
23744
|
-
|
|
23745
|
-
|
|
24140
|
+
function sceneAsHierarchy(scene) {
|
|
24141
|
+
return {
|
|
24142
|
+
getLayers: () => scene.layers.map((l) => ({ id: l.id, visible: l.visible })),
|
|
24143
|
+
getNode: (id) => scene.get(id),
|
|
24144
|
+
getChildren: (parentId) => {
|
|
24145
|
+
if (parentId === null) return scene.roots;
|
|
24146
|
+
const node = scene.get(parentId);
|
|
24147
|
+
return node && node.kind === "container" ? node.children : [];
|
|
24148
|
+
},
|
|
24149
|
+
getPose: (id) => scene.get(id).pose
|
|
24150
|
+
};
|
|
24151
|
+
}
|
|
24152
|
+
function buildSceneViewCommands(scene, view, drawOne, extraCommands, alphaFor) {
|
|
24153
|
+
const wrappedDrawOne = (node, pose, v) => wrapNodeOutput(drawOne(node, pose, v), pose, alphaFor ? alphaFor(node.id) : 1);
|
|
24154
|
+
const children = buildSceneTree(
|
|
24155
|
+
sceneAsHierarchy(scene),
|
|
24156
|
+
wrappedDrawOne,
|
|
24157
|
+
view
|
|
24158
|
+
);
|
|
23746
24159
|
if (extraCommands && extraCommands.length > 0) {
|
|
23747
24160
|
for (const cmd of extraCommands) children.push(cmd);
|
|
23748
24161
|
}
|
|
@@ -23753,7 +24166,7 @@ function buildSceneViewCommands(scene, view, drawOne, extraCommands) {
|
|
|
23753
24166
|
}];
|
|
23754
24167
|
}
|
|
23755
24168
|
function renderSceneToCanvas(args) {
|
|
23756
|
-
const { canvas, scene, view, width, height, drawOne, extraCommands } = args;
|
|
24169
|
+
const { canvas, scene, view, width, height, drawOne, extraCommands, alphaFor } = args;
|
|
23757
24170
|
const dpr = args.dpr ?? (typeof window !== "undefined" ? window.devicePixelRatio || 1 : 1);
|
|
23758
24171
|
let entry = RENDERER_CACHE.get(canvas);
|
|
23759
24172
|
if (!entry) {
|
|
@@ -23781,11 +24194,11 @@ function renderSceneToCanvas(args) {
|
|
|
23781
24194
|
entry.height = height;
|
|
23782
24195
|
entry.dpr = dpr;
|
|
23783
24196
|
}
|
|
23784
|
-
const commands = buildSceneViewCommands(scene, view, drawOne, extraCommands);
|
|
24197
|
+
const commands = buildSceneViewCommands(scene, view, drawOne, extraCommands, alphaFor);
|
|
23785
24198
|
entry.renderer.render(commands, viewToMat3(view));
|
|
23786
24199
|
}
|
|
23787
24200
|
function SceneViewCanvasInner(props) {
|
|
23788
|
-
const { scene, view, width, height, drawOne, extraCommands, className, canvasRef } = props;
|
|
24201
|
+
const { scene, view, width, height, drawOne, extraCommands, alphaFor, className, canvasRef } = props;
|
|
23789
24202
|
useSyncExternalStore(scene.subscribe, scene.getVersion, scene.getVersion);
|
|
23790
24203
|
const localRef = useRef(null);
|
|
23791
24204
|
const setCanvasRef = (el) => {
|
|
@@ -23806,7 +24219,8 @@ function SceneViewCanvasInner(props) {
|
|
|
23806
24219
|
width,
|
|
23807
24220
|
height,
|
|
23808
24221
|
drawOne,
|
|
23809
|
-
extraCommands
|
|
24222
|
+
extraCommands,
|
|
24223
|
+
alphaFor
|
|
23810
24224
|
});
|
|
23811
24225
|
});
|
|
23812
24226
|
return /* @__PURE__ */ jsx(
|
|
@@ -23903,6 +24317,7 @@ function MinimapCanvasInner(props) {
|
|
|
23903
24317
|
width,
|
|
23904
24318
|
height,
|
|
23905
24319
|
drawOne,
|
|
24320
|
+
alphaFor,
|
|
23906
24321
|
fit = "scene",
|
|
23907
24322
|
poseBounds,
|
|
23908
24323
|
indicatorStyle,
|
|
@@ -24014,6 +24429,7 @@ function MinimapCanvasInner(props) {
|
|
|
24014
24429
|
height,
|
|
24015
24430
|
drawOne,
|
|
24016
24431
|
extraCommands,
|
|
24432
|
+
alphaFor,
|
|
24017
24433
|
className,
|
|
24018
24434
|
canvasRef: setCanvasRef
|
|
24019
24435
|
}
|
|
@@ -24157,5 +24573,5 @@ function oklchToOklab(L, C, h) {
|
|
|
24157
24573
|
}
|
|
24158
24574
|
|
|
24159
24575
|
export { FALLBACK_FIT_VIEW, MinimapCanvas, SceneViewCanvas, UnknownIcon, buildSceneViewCommands, computeFitView2, computeIndicatorCommand, eligibleContribution, evaluateEnabled, oklabToSrgbU8, oklchToOklab, renderSceneToCanvas, rgbaToHex, useActionsRegistry, useOptionalDepRegistry };
|
|
24160
|
-
//# sourceMappingURL=chunk-
|
|
24161
|
-
//# sourceMappingURL=chunk-
|
|
24576
|
+
//# sourceMappingURL=chunk-ISEK5LXT.js.map
|
|
24577
|
+
//# sourceMappingURL=chunk-ISEK5LXT.js.map
|