@weasel-js/renderer 1.10.0 → 1.10.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/README.md +1 -1
- package/dist/{chunk-LFD47OV2.js → chunk-K7XCWVQH.js} +63 -45
- package/dist/chunk-K7XCWVQH.js.map +1 -0
- package/dist/{imageCache-DYcWftY8.d.ts → imageCache-DucOxC7l.d.ts} +11 -10
- package/dist/index.d.ts +11 -6
- package/dist/index.js +320 -216
- package/dist/index.js.map +1 -1
- package/dist/patterns-builtin.d.ts +2 -0
- package/dist/patterns-builtin.js.map +1 -1
- package/dist/test-seams.d.ts +1 -3
- package/dist/test-seams.js +1 -1
- package/package.json +7 -7
- package/dist/chunk-LFD47OV2.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { createTilePattern } from './chunk-43YL7HZV.js';
|
|
2
|
-
import { BATCH_ATTRIBUTE_LOCATIONS, BATCH_TEXTURE_SLOTS, registerProgram,
|
|
3
|
-
export { commandFill, commandPaint, commandStroke, fillInPoseFrame, fillToBoundsFrame, getImageBitmap, getPaintDrawKind, getProgramSource, imageStatus, isPaintKindKnown, isVectorImageSrc, paintDrawKindRegistry, programSourceRegistry, registerPaintDrawKind, registerPaintDrawKindLoader, registerProgram, releaseImage, releaseImageSource, resolveFillPattern, resolvePatternSpec, retryImage, setImageCacheBudget, subscribeImageReady, warmPaintKinds } from './chunk-
|
|
2
|
+
import { BATCH_ATTRIBUTE_LOCATIONS, BATCH_TEXTURE_SLOTS, registerProgram, STRAIGHT_RGB_GLSL, BATCH_FILL_ATTRIBUTES, BATCH_FILL_UNIFORMS, BATCH_MATRICES_FRAG_SRC, BATCH_VERT_SRC, GLImageCache, DrawBatch, getProgramSource, commandFill, commandPaint, BATCH_FRAG_SRC, uploadPremultiplied, RAMP_SLOT, withMatrix, cachedMarkerCommands, BATCH_MATRIX_SLOTS, packSlot, WHITE_SLOT, PAINT_MODE_PLAIN, PAINT_MODE_RADIAL, PAINT_MODE_CONIC, getMesh, quantizeStrokeScale, strokeMesh, axisAlignedClipRect, intersectClipRects, getPaintDrawKind, outlineMesh, outlineStrokeMesh, quantizeEmWidth } from './chunk-K7XCWVQH.js';
|
|
3
|
+
export { commandFill, commandPaint, commandStroke, fillInPoseFrame, fillToBoundsFrame, getImageBitmap, getPaintDrawKind, getProgramSource, imageStatus, isPaintKindKnown, isVectorImageSrc, paintDrawKindRegistry, programSourceRegistry, registerPaintDrawKind, registerPaintDrawKindLoader, registerProgram, releaseImage, releaseImageSource, resolveFillPattern, resolvePatternSpec, retryImage, setImageCacheBudget, subscribeImageReady, warmPaintKinds } from './chunk-K7XCWVQH.js';
|
|
4
4
|
import { textureRegistry, getTexture } from './chunk-Q4SIHV7Q.js';
|
|
5
5
|
export { registerTexture, textureRegistry, unregisterTexture } from './chunk-Q4SIHV7Q.js';
|
|
6
6
|
import { DEFAULT_BAKE_BUDGET, markAllFontsNotUploaded, resetBakeBudget, GLYPH_COVERAGE_GLSL, syncColorPageTexture, colorPageTextureId, syncDynamicPageTexture, ensureFontTexture, dynamicPageTextureId, textureCacheKey, GLYPH_MODE_R8, GLYPH_MODE_MSDF, glyphFieldScale } from '@weasel-js/font';
|
|
@@ -229,7 +229,6 @@ uniform mat4 u_colorMatrix;
|
|
|
229
229
|
uniform vec4 u_colorBias;
|
|
230
230
|
uniform float u_opacity;
|
|
231
231
|
uniform int u_gradKind;
|
|
232
|
-
uniform vec2 u_gradP0;
|
|
233
232
|
uniform vec2 u_gradDir;
|
|
234
233
|
uniform float u_gradLen;
|
|
235
234
|
uniform float u_gradRadius;
|
|
@@ -240,12 +239,11 @@ const float PI = 3.14159265358979323846;
|
|
|
240
239
|
vec4 shadePaint(vec2 world) {
|
|
241
240
|
float t;
|
|
242
241
|
if (u_gradKind == 0) {
|
|
243
|
-
|
|
244
|
-
t = dot(d, u_gradDir) / max(u_gradLen, 0.0001);
|
|
242
|
+
t = dot(world, u_gradDir) / max(u_gradLen, 0.0001);
|
|
245
243
|
} else if (u_gradKind == 1) {
|
|
246
|
-
t = length(world
|
|
244
|
+
t = length(world) / max(u_gradRadius, 0.0001);
|
|
247
245
|
} else {
|
|
248
|
-
float a = atan(world.y
|
|
246
|
+
float a = atan(world.y, world.x) - u_gradAngle;
|
|
249
247
|
t = fract(a / (2.0 * PI));
|
|
250
248
|
}
|
|
251
249
|
t = clamp(t, 0.0, 1.0);
|
|
@@ -284,7 +282,6 @@ var GRAD_FILL_UNIFORMS = [
|
|
|
284
282
|
"u_colorMatrix",
|
|
285
283
|
"u_colorBias",
|
|
286
284
|
"u_gradKind",
|
|
287
|
-
"u_gradP0",
|
|
288
285
|
"u_gradDir",
|
|
289
286
|
"u_gradLen",
|
|
290
287
|
"u_gradRadius",
|
|
@@ -355,6 +352,72 @@ var PATTERN_FILL_UNIFORMS = [
|
|
|
355
352
|
"u_colorBias"
|
|
356
353
|
];
|
|
357
354
|
var PATTERN_FILL_ATTRIBUTES = ["a_position"];
|
|
355
|
+
|
|
356
|
+
// src/shaders/builtinPrograms.ts
|
|
357
|
+
var LazyProgram = class {
|
|
358
|
+
constructor(gl, spec) {
|
|
359
|
+
this.gl = gl;
|
|
360
|
+
this.spec = spec;
|
|
361
|
+
}
|
|
362
|
+
gl;
|
|
363
|
+
spec;
|
|
364
|
+
program = null;
|
|
365
|
+
get() {
|
|
366
|
+
if (!this.program) {
|
|
367
|
+
const { vert, frag, uniforms, attributes } = this.spec;
|
|
368
|
+
const program = new ShaderProgram(this.gl, vert, frag);
|
|
369
|
+
program.lookupUniforms(uniforms);
|
|
370
|
+
program.lookupAttributes(attributes);
|
|
371
|
+
this.program = program;
|
|
372
|
+
}
|
|
373
|
+
return this.program;
|
|
374
|
+
}
|
|
375
|
+
/** Delete the program if it was built. It builds again on the next `get`. */
|
|
376
|
+
release() {
|
|
377
|
+
if (this.program) this.gl.deleteProgram(this.program.handle);
|
|
378
|
+
this.program = null;
|
|
379
|
+
}
|
|
380
|
+
/** Forget a program its lost context already took with it. */
|
|
381
|
+
abandon() {
|
|
382
|
+
this.program = null;
|
|
383
|
+
}
|
|
384
|
+
};
|
|
385
|
+
var PATH_FILL_SPEC = {
|
|
386
|
+
vert: VERT_SRC,
|
|
387
|
+
frag: FRAG_SRC,
|
|
388
|
+
uniforms: PATH_FILL_UNIFORMS,
|
|
389
|
+
attributes: PATH_FILL_ATTRIBUTES
|
|
390
|
+
};
|
|
391
|
+
var PATH_FILL_VCOLOR_SPEC = {
|
|
392
|
+
vert: VCOLOR_VERT_SRC,
|
|
393
|
+
frag: VCOLOR_FRAG_SRC,
|
|
394
|
+
uniforms: PATH_FILL_UNIFORMS,
|
|
395
|
+
attributes: PATH_FILL_VCOLOR_ATTRIBUTES
|
|
396
|
+
};
|
|
397
|
+
var GRAD_FILL_SPEC = {
|
|
398
|
+
vert: GRAD_VERT_SRC,
|
|
399
|
+
frag: GRAD_FRAG_SRC,
|
|
400
|
+
uniforms: GRAD_FILL_UNIFORMS,
|
|
401
|
+
attributes: GRAD_FILL_ATTRIBUTES
|
|
402
|
+
};
|
|
403
|
+
var BATCH_FILL_MATRICES_SPEC = {
|
|
404
|
+
vert: BATCH_VERT_SRC,
|
|
405
|
+
frag: BATCH_MATRICES_FRAG_SRC,
|
|
406
|
+
uniforms: BATCH_FILL_UNIFORMS,
|
|
407
|
+
attributes: BATCH_FILL_ATTRIBUTES
|
|
408
|
+
};
|
|
409
|
+
var PATTERN_FILL_SPEC = {
|
|
410
|
+
vert: PATTERN_VERT_SRC,
|
|
411
|
+
frag: PATTERN_FRAG_SRC,
|
|
412
|
+
uniforms: PATTERN_FILL_UNIFORMS,
|
|
413
|
+
attributes: PATTERN_FILL_ATTRIBUTES
|
|
414
|
+
};
|
|
415
|
+
function createBatchFill(gl) {
|
|
416
|
+
const program = new ShaderProgram(gl, BATCH_VERT_SRC, BATCH_FRAG_SRC);
|
|
417
|
+
program.lookupUniforms(BATCH_FILL_UNIFORMS);
|
|
418
|
+
program.lookupAttributes(BATCH_FILL_ATTRIBUTES);
|
|
419
|
+
return program;
|
|
420
|
+
}
|
|
358
421
|
var L = BATCH_ATTRIBUTE_LOCATIONS;
|
|
359
422
|
var GLYPH_PAINT_VERT_SRC = (
|
|
360
423
|
/* glsl */
|
|
@@ -1553,6 +1616,83 @@ function meshHandle(ctx, mesh) {
|
|
|
1553
1616
|
function fillMeshHandle(ctx, path) {
|
|
1554
1617
|
return meshHandle(ctx, fillMesh(ctx, path));
|
|
1555
1618
|
}
|
|
1619
|
+
|
|
1620
|
+
// src/draw/foldColor.ts
|
|
1621
|
+
function isIdentityColorMatrix(cm) {
|
|
1622
|
+
return cm === IDENTITY_COLOR_MATRIX || sameValues(IDENTITY_COLOR_MATRIX, cm);
|
|
1623
|
+
}
|
|
1624
|
+
var clamp01 = (v) => v < 0 ? 0 : v > 1 ? 1 : v;
|
|
1625
|
+
function foldColor(ctx, r, g, b, a) {
|
|
1626
|
+
const cm = ctx.state.colorMatrix;
|
|
1627
|
+
const alpha = ctx.state.alpha;
|
|
1628
|
+
if (isIdentityColorMatrix(cm)) return [r, g, b, a * alpha];
|
|
1629
|
+
return [
|
|
1630
|
+
clamp01(cm[0] * r + cm[1] * g + cm[2] * b + cm[3] * a + cm[4]),
|
|
1631
|
+
clamp01(cm[5] * r + cm[6] * g + cm[7] * b + cm[8] * a + cm[9]),
|
|
1632
|
+
clamp01(cm[10] * r + cm[11] * g + cm[12] * b + cm[13] * a + cm[14]),
|
|
1633
|
+
clamp01(cm[15] * r + cm[16] * g + cm[17] * b + cm[18] * a + cm[19]) * alpha
|
|
1634
|
+
];
|
|
1635
|
+
}
|
|
1636
|
+
var NO_TINT = [1, 1, 1, 1];
|
|
1637
|
+
var DIAGONAL = [0, 6, 12, 18];
|
|
1638
|
+
function textureTint(ctx) {
|
|
1639
|
+
const cm = ctx.state.colorMatrix;
|
|
1640
|
+
const alpha = ctx.state.alpha;
|
|
1641
|
+
if (isIdentityColorMatrix(cm)) return alpha === 1 ? NO_TINT : [1, 1, 1, alpha];
|
|
1642
|
+
for (let i = 0; i < 20; i++) {
|
|
1643
|
+
const v = cm[i];
|
|
1644
|
+
if (DIAGONAL.includes(i) ? v < 0 || v > 1 : v !== 0) return null;
|
|
1645
|
+
}
|
|
1646
|
+
return [cm[0], cm[6], cm[12], cm[18] * alpha];
|
|
1647
|
+
}
|
|
1648
|
+
|
|
1649
|
+
// src/draw/batchMatrices.ts
|
|
1650
|
+
function matrixIndex(matrices, colorMatrix, alpha) {
|
|
1651
|
+
for (let i = 0; i < matrices.length; i++) {
|
|
1652
|
+
const m = matrices[i];
|
|
1653
|
+
if (m.alpha === alpha && (m.colorMatrix === colorMatrix || sameValues(m.colorMatrix, colorMatrix))) return i;
|
|
1654
|
+
}
|
|
1655
|
+
return matrices.length < (BATCH_MATRIX_SLOTS ) ? matrices.length : -1;
|
|
1656
|
+
}
|
|
1657
|
+
var MATRICES = new Float32Array(16 * BATCH_MATRIX_SLOTS);
|
|
1658
|
+
var BIASES = new Float32Array(4 * BATCH_MATRIX_SLOTS);
|
|
1659
|
+
var ALPHAS = new Float32Array(BATCH_MATRIX_SLOTS);
|
|
1660
|
+
var UPLOADED = /* @__PURE__ */ new WeakMap();
|
|
1661
|
+
function holds(held, matrices) {
|
|
1662
|
+
if (held.length < matrices.length) return false;
|
|
1663
|
+
for (let i = 0; i < matrices.length; i++) {
|
|
1664
|
+
const a = held[i];
|
|
1665
|
+
const b = matrices[i];
|
|
1666
|
+
if (a.alpha !== b.alpha) return false;
|
|
1667
|
+
if (a.colorMatrix !== b.colorMatrix && !sameValues(a.colorMatrix, b.colorMatrix)) return false;
|
|
1668
|
+
}
|
|
1669
|
+
return true;
|
|
1670
|
+
}
|
|
1671
|
+
function uploadBatchMatrices(ctx, prog, matrices) {
|
|
1672
|
+
let byProgram = UPLOADED.get(ctx);
|
|
1673
|
+
if (!byProgram) {
|
|
1674
|
+
byProgram = /* @__PURE__ */ new WeakMap();
|
|
1675
|
+
UPLOADED.set(ctx, byProgram);
|
|
1676
|
+
}
|
|
1677
|
+
const held = byProgram.get(prog);
|
|
1678
|
+
if (held !== void 0 && holds(held, matrices)) return;
|
|
1679
|
+
const n = matrices.length;
|
|
1680
|
+
for (let i = 0; i < n; i++) {
|
|
1681
|
+
const cm = matrices[i].colorMatrix;
|
|
1682
|
+
for (let row = 0; row < 4; row++) {
|
|
1683
|
+
for (let col = 0; col < 4; col++) MATRICES[16 * i + col * 4 + row] = cm[row * 5 + col];
|
|
1684
|
+
BIASES[4 * i + row] = cm[row * 5 + 4];
|
|
1685
|
+
}
|
|
1686
|
+
ALPHAS[i] = matrices[i].alpha;
|
|
1687
|
+
}
|
|
1688
|
+
const gl = ctx.gl;
|
|
1689
|
+
gl.uniformMatrix4fv(prog.uniform("u_colorMatrix"), false, MATRICES.subarray(0, 16 * n));
|
|
1690
|
+
gl.uniform4fv(prog.uniform("u_colorBias"), BIASES.subarray(0, 4 * n));
|
|
1691
|
+
gl.uniform1fv(prog.uniform("u_alpha"), ALPHAS.subarray(0, n));
|
|
1692
|
+
byProgram.set(prog, matrices.slice());
|
|
1693
|
+
}
|
|
1694
|
+
|
|
1695
|
+
// src/draw/flushBatch.ts
|
|
1556
1696
|
var BATCH_MODEL = mat3.identity();
|
|
1557
1697
|
var SAMPLER_UNITS = new Int32Array(
|
|
1558
1698
|
Array.from({ length: BATCH_TEXTURE_SLOTS }, (_, i) => i)
|
|
@@ -1566,14 +1706,12 @@ function flushBatch(ctx) {
|
|
|
1566
1706
|
return;
|
|
1567
1707
|
}
|
|
1568
1708
|
const gl = ctx.gl;
|
|
1569
|
-
const prog = ctx.batchFill;
|
|
1709
|
+
const prog = staged.matrices.length > 1 ? ctx.batchFillMatrices ?? ctx.batchFill : ctx.batchFill;
|
|
1570
1710
|
gl.useProgram(prog.handle);
|
|
1571
1711
|
const indexCount = batch.uploadAndBind();
|
|
1572
1712
|
setProjAndModel(ctx, prog, BATCH_MODEL);
|
|
1573
1713
|
setColorUniform(ctx, prog, 1, 1, 1, 1);
|
|
1574
|
-
|
|
1575
|
-
gl.uniform1f(prog.uniform("u_synthBold"), staged.synthBold);
|
|
1576
|
-
setColorMatrixUniforms(ctx, prog, staged.colorMatrix);
|
|
1714
|
+
uploadBatchMatrices(ctx, prog, staged.matrices);
|
|
1577
1715
|
gl.activeTexture(gl.TEXTURE0);
|
|
1578
1716
|
gl.bindTexture(gl.TEXTURE_2D, ctx.whiteTexture);
|
|
1579
1717
|
for (let i = 0; i < staged.textures.length; i++) {
|
|
@@ -1584,16 +1722,13 @@ function flushBatch(ctx) {
|
|
|
1584
1722
|
FIELD_SCALES[2 * (i + 1) + 1] = entry.fieldScale[1];
|
|
1585
1723
|
continue;
|
|
1586
1724
|
}
|
|
1587
|
-
if (entry.kind === "ramps") {
|
|
1588
|
-
ctx.gradRamps.bind(i + 1);
|
|
1589
|
-
continue;
|
|
1590
|
-
}
|
|
1591
1725
|
ctx.imageCache.bind(entry.image, i + 1);
|
|
1592
1726
|
ctx.imageCache.setMagFilter(
|
|
1593
1727
|
entry.image,
|
|
1594
1728
|
entry.sampling === "nearest" ? gl.NEAREST : gl.LINEAR
|
|
1595
1729
|
);
|
|
1596
1730
|
}
|
|
1731
|
+
if (staged.ramps) ctx.gradRamps.bind(RAMP_SLOT);
|
|
1597
1732
|
gl.uniform1iv(prog.uniform("u_samplers"), SAMPLER_UNITS);
|
|
1598
1733
|
gl.uniform2fv(prog.uniform("u_fieldScale"), FIELD_SCALES);
|
|
1599
1734
|
applyClipTest(ctx, staged.clipDepth);
|
|
@@ -1769,36 +1904,41 @@ function resolvedMarker(ref, scale) {
|
|
|
1769
1904
|
return { ...ref, size: resolveMarkerSize(ref, 0, quantizeStrokeScale(ref.size.px, scale)) };
|
|
1770
1905
|
}
|
|
1771
1906
|
|
|
1772
|
-
// src/draw/
|
|
1773
|
-
function
|
|
1774
|
-
|
|
1907
|
+
// src/draw/batchRun.ts
|
|
1908
|
+
function slotForBitmap(staged, image, sampling) {
|
|
1909
|
+
for (let i = 0; i < staged.textures.length; i++) {
|
|
1910
|
+
const entry = staged.textures[i];
|
|
1911
|
+
if (entry.kind !== "bitmap" || entry.image !== image) continue;
|
|
1912
|
+
return entry.sampling === sampling ? i + 1 : -1;
|
|
1913
|
+
}
|
|
1914
|
+
return nextFreeSlot(staged);
|
|
1775
1915
|
}
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
if (!staged.foldsAlpha) return [r, g, b, a];
|
|
1780
|
-
const cm = ctx.state.colorMatrix;
|
|
1781
|
-
const alpha = ctx.state.alpha;
|
|
1782
|
-
if (isIdentityColorMatrix(cm)) return [r, g, b, a * alpha];
|
|
1783
|
-
return [
|
|
1784
|
-
clamp01(cm[0] * r + cm[1] * g + cm[2] * b + cm[3] * a + cm[4]),
|
|
1785
|
-
clamp01(cm[5] * r + cm[6] * g + cm[7] * b + cm[8] * a + cm[9]),
|
|
1786
|
-
clamp01(cm[10] * r + cm[11] * g + cm[12] * b + cm[13] * a + cm[14]),
|
|
1787
|
-
clamp01(cm[15] * r + cm[16] * g + cm[17] * b + cm[18] * a + cm[19]) * alpha
|
|
1788
|
-
];
|
|
1916
|
+
function slotForRamps(staged) {
|
|
1917
|
+
if (staged.ramps) return RAMP_SLOT;
|
|
1918
|
+
return nextFreeSlot(staged) < 0 ? -1 : RAMP_SLOT;
|
|
1789
1919
|
}
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
for (let i = 0; i < 20; i++) {
|
|
1795
|
-
const v = cm[i];
|
|
1796
|
-
if (DIAGONAL.includes(i) ? v < 0 || v > 1 : v !== 0) return null;
|
|
1920
|
+
function slotForAtlas(staged, id) {
|
|
1921
|
+
for (let i = 0; i < staged.textures.length; i++) {
|
|
1922
|
+
const entry = staged.textures[i];
|
|
1923
|
+
if (entry.kind === "atlas" && entry.id === id) return i + 1;
|
|
1797
1924
|
}
|
|
1798
|
-
return
|
|
1925
|
+
return nextFreeSlot(staged);
|
|
1799
1926
|
}
|
|
1800
|
-
function
|
|
1801
|
-
|
|
1927
|
+
function nextFreeSlot(staged) {
|
|
1928
|
+
const taken = staged.textures.length + (staged.ramps ? 1 : 0);
|
|
1929
|
+
return taken + 1 < BATCH_TEXTURE_SLOTS ? staged.textures.length + 1 : -1;
|
|
1930
|
+
}
|
|
1931
|
+
function runTakes(ctx, staged, colorMatrix, alpha) {
|
|
1932
|
+
return staged.clipDepth === runClipDepth(ctx) && matrixIndex(staged.matrices, colorMatrix, alpha) >= 0;
|
|
1933
|
+
}
|
|
1934
|
+
function openRun(ctx) {
|
|
1935
|
+
ctx.batchState ??= { clipDepth: runClipDepth(ctx), matrices: [], textures: [], ramps: false };
|
|
1936
|
+
return ctx.batchState;
|
|
1937
|
+
}
|
|
1938
|
+
function takeMatrix(staged, colorMatrix, alpha) {
|
|
1939
|
+
const index = matrixIndex(staged.matrices, colorMatrix, alpha);
|
|
1940
|
+
if (index === staged.matrices.length) staged.matrices.push({ colorMatrix, alpha });
|
|
1941
|
+
return index;
|
|
1802
1942
|
}
|
|
1803
1943
|
function batchPaint(ctx, fill, hasVColors) {
|
|
1804
1944
|
if (hasVColors) return void 0;
|
|
@@ -1887,39 +2027,6 @@ function spaceToDevice(ctx, units) {
|
|
|
1887
2027
|
}
|
|
1888
2028
|
|
|
1889
2029
|
// src/draw/batch.ts
|
|
1890
|
-
function stagedStateIsLive(ctx, staged, image, sampling, synthBold = 0, folds = false) {
|
|
1891
|
-
if (staged.clipDepth !== (ctx.clipStack.length === 0 ? ctx.clipDepth : runClipDepth(ctx))) return false;
|
|
1892
|
-
if (staged.synthBold !== synthBold) return false;
|
|
1893
|
-
if (!staged.foldsAlpha && staged.alpha !== ctx.state.alpha) return false;
|
|
1894
|
-
if (image !== void 0 && slotForBitmap(staged, image, sampling) < 0) return false;
|
|
1895
|
-
const colorMatrix = ctx.state.colorMatrix;
|
|
1896
|
-
if (staged.colorMatrix === colorMatrix || sameValues(staged.colorMatrix, colorMatrix)) return true;
|
|
1897
|
-
return folds && staged.foldsAlpha;
|
|
1898
|
-
}
|
|
1899
|
-
function slotForBitmap(staged, image, sampling) {
|
|
1900
|
-
for (let i = 0; i < staged.textures.length; i++) {
|
|
1901
|
-
const entry = staged.textures[i];
|
|
1902
|
-
if (entry.kind !== "bitmap" || entry.image !== image) continue;
|
|
1903
|
-
return entry.sampling === sampling ? i + 1 : -1;
|
|
1904
|
-
}
|
|
1905
|
-
return nextFreeSlot(staged);
|
|
1906
|
-
}
|
|
1907
|
-
function slotForRamps(staged) {
|
|
1908
|
-
for (let i = 0; i < staged.textures.length; i++) {
|
|
1909
|
-
if (staged.textures[i].kind === "ramps") return i + 1;
|
|
1910
|
-
}
|
|
1911
|
-
return nextFreeSlot(staged);
|
|
1912
|
-
}
|
|
1913
|
-
function slotForAtlas(staged, id) {
|
|
1914
|
-
for (let i = 0; i < staged.textures.length; i++) {
|
|
1915
|
-
const entry = staged.textures[i];
|
|
1916
|
-
if (entry.kind === "atlas" && entry.id === id) return i + 1;
|
|
1917
|
-
}
|
|
1918
|
-
return nextFreeSlot(staged);
|
|
1919
|
-
}
|
|
1920
|
-
function nextFreeSlot(staged) {
|
|
1921
|
-
return staged.textures.length + 1 < BATCH_TEXTURE_SLOTS ? staged.textures.length + 1 : -1;
|
|
1922
|
-
}
|
|
1923
2030
|
var MAX_BATCHED_MESH_VERTICES = 96;
|
|
1924
2031
|
var MAX_BATCHED_MESH_VERTICES_IN_RUN = 1024;
|
|
1925
2032
|
var meshBatching = {
|
|
@@ -1932,79 +2039,78 @@ function canBatchMesh(ctx, mesh) {
|
|
|
1932
2039
|
return mesh.vertices.length >> 1 <= cap;
|
|
1933
2040
|
}
|
|
1934
2041
|
function stageSolid(ctx, vertices) {
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
2042
|
+
const colorMatrix = IDENTITY_COLOR_MATRIX ;
|
|
2043
|
+
const alpha = 1 ;
|
|
2044
|
+
const open = ctx.batchState;
|
|
2045
|
+
if (open !== void 0 && !runTakes(ctx, open, colorMatrix, alpha)) flushBatch(ctx);
|
|
1938
2046
|
if (ctx.drawBatch.wouldOverflow(vertices)) flushBatch(ctx);
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
synthBold: 0,
|
|
1950
|
-
foldsAlpha,
|
|
1951
|
-
textures: []
|
|
1952
|
-
};
|
|
1953
|
-
}
|
|
1954
|
-
return ctx.batchState;
|
|
2047
|
+
const matrix = takeMatrix(openRun(ctx), colorMatrix, alpha);
|
|
2048
|
+
return packSlot(withMatrix(WHITE_SLOT, matrix), PAINT_MODE_PLAIN);
|
|
2049
|
+
}
|
|
2050
|
+
var UNTINTED = [1, 1, 1, 1];
|
|
2051
|
+
function texturedUnder(ctx, alphaInEntry) {
|
|
2052
|
+
const tint = textureTint(ctx);
|
|
2053
|
+
if (tint !== null) return { colorMatrix: IDENTITY_COLOR_MATRIX, alpha: 1, tint, slot: 0 };
|
|
2054
|
+
const colorMatrix = ctx.state.colorMatrix;
|
|
2055
|
+
const alpha = ctx.state.alpha;
|
|
2056
|
+
return alphaInEntry ? { colorMatrix, alpha, tint: UNTINTED, slot: 0 } : { colorMatrix, alpha: 1, tint: [1, 1, 1, alpha], slot: 0 };
|
|
1955
2057
|
}
|
|
1956
2058
|
function stageImage(ctx, image, sampling) {
|
|
1957
|
-
const
|
|
1958
|
-
|
|
2059
|
+
const under = texturedUnder(ctx, false);
|
|
2060
|
+
const open = ctx.batchState;
|
|
2061
|
+
if (open !== void 0 && (!runTakes(ctx, open, under.colorMatrix, under.alpha) || slotForBitmap(open, image, sampling) < 0)) {
|
|
1959
2062
|
flushBatch(ctx);
|
|
1960
2063
|
}
|
|
1961
2064
|
if (ctx.drawBatch.wouldOverflow(4)) flushBatch(ctx);
|
|
1962
|
-
const staged = openRun(ctx
|
|
2065
|
+
const staged = openRun(ctx);
|
|
1963
2066
|
let slot = slotForBitmap(staged, image, sampling);
|
|
1964
2067
|
if (slot > staged.textures.length) {
|
|
1965
2068
|
staged.textures.push({ kind: "bitmap", image, sampling });
|
|
1966
2069
|
slot = staged.textures.length;
|
|
1967
2070
|
}
|
|
1968
|
-
|
|
2071
|
+
under.slot = withMatrix(slot, takeMatrix(staged, under.colorMatrix, under.alpha));
|
|
2072
|
+
return under;
|
|
1969
2073
|
}
|
|
1970
|
-
function stageGlyphs(ctx, atlasId, fieldScale
|
|
1971
|
-
|
|
2074
|
+
function stageGlyphs(ctx, atlasId, fieldScale) {
|
|
2075
|
+
const colorMatrix = IDENTITY_COLOR_MATRIX ;
|
|
2076
|
+
const alpha = 1 ;
|
|
2077
|
+
const open = ctx.batchState;
|
|
2078
|
+
if (open !== void 0 && (!runTakes(ctx, open, colorMatrix, alpha) || slotForAtlas(open, atlasId) < 0)) {
|
|
1972
2079
|
flushBatch(ctx);
|
|
1973
2080
|
}
|
|
1974
2081
|
if (ctx.drawBatch.wouldOverflow(4)) flushBatch(ctx);
|
|
1975
|
-
const staged = openRun(ctx
|
|
1976
|
-
staged.synthBold = synthBold;
|
|
2082
|
+
const staged = openRun(ctx);
|
|
1977
2083
|
let slot = slotForAtlas(staged, atlasId);
|
|
1978
2084
|
if (slot > staged.textures.length) {
|
|
1979
2085
|
staged.textures.push({ kind: "atlas", id: atlasId, fieldScale });
|
|
1980
2086
|
slot = staged.textures.length;
|
|
1981
2087
|
}
|
|
1982
|
-
return
|
|
2088
|
+
return withMatrix(slot, takeMatrix(staged, colorMatrix, alpha));
|
|
1983
2089
|
}
|
|
1984
2090
|
function stageRamps(ctx, stops, space, vertices) {
|
|
1985
2091
|
if (ctx.gradRamps.wouldReshape(stops, space)) flushBatch(ctx);
|
|
1986
|
-
|
|
2092
|
+
const under = texturedUnder(ctx, true);
|
|
2093
|
+
const open = ctx.batchState;
|
|
2094
|
+
if (open !== void 0 && (!runTakes(ctx, open, under.colorMatrix, under.alpha) || slotForRamps(open) < 0)) {
|
|
1987
2095
|
flushBatch(ctx);
|
|
1988
2096
|
}
|
|
1989
2097
|
if (ctx.drawBatch.wouldOverflow(vertices)) flushBatch(ctx);
|
|
1990
2098
|
const staged = openRun(ctx);
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
slot
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
}
|
|
1998
|
-
function stagedAlpha(ctx, staged, opacity) {
|
|
1999
|
-
return (opacity ?? 1) * (staged.foldsAlpha ? ctx.state.alpha : 1);
|
|
2099
|
+
const slot = slotForRamps(staged);
|
|
2100
|
+
staged.ramps = true;
|
|
2101
|
+
return {
|
|
2102
|
+
slot: withMatrix(slot, takeMatrix(staged, under.colorMatrix, under.alpha)),
|
|
2103
|
+
tint: under.tint,
|
|
2104
|
+
rowV: ctx.gradRamps.rowV(ctx.gradRamps.upload(stops, space))
|
|
2105
|
+
};
|
|
2000
2106
|
}
|
|
2001
|
-
function stagedColor(ctx,
|
|
2107
|
+
function stagedColor(ctx, paint) {
|
|
2002
2108
|
const [r, g, b, a] = resolveColor(paint.color);
|
|
2003
|
-
return foldColor(ctx,
|
|
2109
|
+
return foldColor(ctx, r, g, b, a * (paint.opacity ?? 1));
|
|
2004
2110
|
}
|
|
2005
2111
|
function pushRect(ctx, rect, fill) {
|
|
2006
|
-
const
|
|
2007
|
-
const [r, g, b, a] = stagedColor(ctx,
|
|
2112
|
+
const slot = stageSolid(ctx, 4);
|
|
2113
|
+
const [r, g, b, a] = stagedColor(ctx, fill);
|
|
2008
2114
|
if (!ctx.drawBatch.pushRect(
|
|
2009
2115
|
rect.x,
|
|
2010
2116
|
rect.y,
|
|
@@ -2014,18 +2120,19 @@ function pushRect(ctx, rect, fill) {
|
|
|
2014
2120
|
r,
|
|
2015
2121
|
g,
|
|
2016
2122
|
b,
|
|
2017
|
-
a
|
|
2123
|
+
a,
|
|
2124
|
+
slot
|
|
2018
2125
|
)) retryUncut(ctx, rect, fill, pushRect);
|
|
2019
2126
|
}
|
|
2020
2127
|
function pushMesh(ctx, mesh, paint) {
|
|
2021
|
-
const
|
|
2022
|
-
const [r, g, b, a] = stagedColor(ctx,
|
|
2023
|
-
if (!ctx.drawBatch.pushMesh(mesh, ctx.state.transform, r, g, b, a)) {
|
|
2128
|
+
const slot = stageSolid(ctx, mesh.vertices.length >> 1);
|
|
2129
|
+
const [r, g, b, a] = stagedColor(ctx, paint);
|
|
2130
|
+
if (!ctx.drawBatch.pushMesh(mesh, ctx.state.transform, r, g, b, a, slot)) {
|
|
2024
2131
|
retryUncut(ctx, mesh, paint, pushMesh);
|
|
2025
2132
|
}
|
|
2026
2133
|
}
|
|
2027
2134
|
function pushRampRect(ctx, rect, paint) {
|
|
2028
|
-
const {
|
|
2135
|
+
const { slot, tint, rowV } = stageRamps(ctx, paint.stops, paint.space, 4);
|
|
2029
2136
|
const { uv, post } = rampVertices(paint, rowV);
|
|
2030
2137
|
if (!ctx.drawBatch.pushGradientRect(
|
|
2031
2138
|
rect.x,
|
|
@@ -2037,14 +2144,14 @@ function pushRampRect(ctx, rect, paint) {
|
|
|
2037
2144
|
post,
|
|
2038
2145
|
slot,
|
|
2039
2146
|
paint.mode,
|
|
2040
|
-
|
|
2041
|
-
1,
|
|
2042
|
-
|
|
2043
|
-
|
|
2147
|
+
tint[0],
|
|
2148
|
+
tint[1],
|
|
2149
|
+
tint[2],
|
|
2150
|
+
(paint.opacity ?? 1) * tint[3]
|
|
2044
2151
|
)) retryUncut(ctx, rect, paint, pushRampRect);
|
|
2045
2152
|
}
|
|
2046
2153
|
function pushRampMesh(ctx, mesh, paint) {
|
|
2047
|
-
const {
|
|
2154
|
+
const { slot, tint, rowV } = stageRamps(ctx, paint.stops, paint.space, mesh.vertices.length >> 1);
|
|
2048
2155
|
const { uv, post } = rampVertices(paint, rowV);
|
|
2049
2156
|
if (!ctx.drawBatch.pushGradientMesh(
|
|
2050
2157
|
mesh,
|
|
@@ -2053,10 +2160,10 @@ function pushRampMesh(ctx, mesh, paint) {
|
|
|
2053
2160
|
post,
|
|
2054
2161
|
slot,
|
|
2055
2162
|
paint.mode,
|
|
2056
|
-
|
|
2057
|
-
1,
|
|
2058
|
-
|
|
2059
|
-
|
|
2163
|
+
tint[0],
|
|
2164
|
+
tint[1],
|
|
2165
|
+
tint[2],
|
|
2166
|
+
(paint.opacity ?? 1) * tint[3]
|
|
2060
2167
|
)) retryUncut(ctx, mesh, paint, pushRampMesh);
|
|
2061
2168
|
}
|
|
2062
2169
|
function tryStageFill(ctx, mesh, paint) {
|
|
@@ -2070,7 +2177,9 @@ function tryStageFill(ctx, mesh, paint) {
|
|
|
2070
2177
|
}
|
|
2071
2178
|
var NO_FIELD = [0, 0];
|
|
2072
2179
|
function stageColorGlyphs(ctx, atlasId) {
|
|
2073
|
-
|
|
2180
|
+
const under = texturedUnder(ctx, false);
|
|
2181
|
+
const open = ctx.batchState;
|
|
2182
|
+
if (open !== void 0 && (!runTakes(ctx, open, under.colorMatrix, under.alpha) || slotForAtlas(open, atlasId) < 0)) {
|
|
2074
2183
|
flushBatch(ctx);
|
|
2075
2184
|
}
|
|
2076
2185
|
if (ctx.drawBatch.wouldOverflow(4)) flushBatch(ctx);
|
|
@@ -2080,7 +2189,8 @@ function stageColorGlyphs(ctx, atlasId) {
|
|
|
2080
2189
|
staged.textures.push({ kind: "atlas", id: atlasId, fieldScale: NO_FIELD });
|
|
2081
2190
|
slot = staged.textures.length;
|
|
2082
2191
|
}
|
|
2083
|
-
|
|
2192
|
+
under.slot = withMatrix(slot, takeMatrix(staged, under.colorMatrix, under.alpha));
|
|
2193
|
+
return under;
|
|
2084
2194
|
}
|
|
2085
2195
|
function patternTileSpace(spaceInverse, origin, transform) {
|
|
2086
2196
|
const [a, b, c, d] = transform ?? [1, 0, 0, 1];
|
|
@@ -2142,8 +2252,10 @@ function bindPattern(ctx, prog, fill, model) {
|
|
|
2142
2252
|
gl.useProgram(prog.handle);
|
|
2143
2253
|
setProjAndModel(ctx, prog, model);
|
|
2144
2254
|
setColorMatrixUniforms(ctx, prog);
|
|
2145
|
-
gl.uniformMatrix3fv(prog.uniform("u_worldInv"), false, mat3.toUniform(tileSpace));
|
|
2146
2255
|
const [tw, th] = textureSize(entry.source);
|
|
2256
|
+
tileSpace[6] -= Math.floor(tileSpace[6] / tw) * tw;
|
|
2257
|
+
tileSpace[7] -= Math.floor(tileSpace[7] / th) * th;
|
|
2258
|
+
gl.uniformMatrix3fv(prog.uniform("u_worldInv"), false, mat3.toUniform(tileSpace));
|
|
2147
2259
|
gl.uniform2f(prog.uniform("u_tileSize"), tw, th);
|
|
2148
2260
|
ctx.textureCache.bind(tex.id, 0);
|
|
2149
2261
|
gl.uniform1i(prog.uniform("u_sampler"), 0);
|
|
@@ -2159,11 +2271,13 @@ function textureSize(source) {
|
|
|
2159
2271
|
function bindGradient(ctx, prog, fill, model) {
|
|
2160
2272
|
const inverse = gradientSpaceInverse(ctx, fill.units);
|
|
2161
2273
|
if (!inverse) return null;
|
|
2274
|
+
const about = fill.kind === "linear-gradient" ? fill.from : fill.center;
|
|
2275
|
+
const aboutStart = mat3.multiply(mat3.translated(mat3.identity(), -about.x, -about.y), inverse);
|
|
2162
2276
|
const gl = ctx.gl;
|
|
2163
2277
|
const row = ctx.gradRamps.upload(fill.stops, fill.interpolate ?? "rgb");
|
|
2164
2278
|
gl.useProgram(prog.handle);
|
|
2165
2279
|
setProjAndModel(ctx, prog, model);
|
|
2166
|
-
gl.uniformMatrix3fv(prog.uniform("u_worldInv"), false, mat3.toUniform(
|
|
2280
|
+
gl.uniformMatrix3fv(prog.uniform("u_worldInv"), false, mat3.toUniform(aboutStart));
|
|
2167
2281
|
setColorMatrixUniforms(ctx, prog);
|
|
2168
2282
|
ctx.gradRamps.bind(0);
|
|
2169
2283
|
gl.uniform1i(prog.uniform("u_ramp"), 0);
|
|
@@ -2175,21 +2289,18 @@ function bindGradient(ctx, prog, fill, model) {
|
|
|
2175
2289
|
const dx = fill.to.x - fill.from.x;
|
|
2176
2290
|
const dy = fill.to.y - fill.from.y;
|
|
2177
2291
|
const len = Math.hypot(dx, dy) || 1;
|
|
2178
|
-
gl.uniform2f(prog.uniform("u_gradP0"), fill.from.x, fill.from.y);
|
|
2179
2292
|
gl.uniform2f(prog.uniform("u_gradDir"), dx / len, dy / len);
|
|
2180
2293
|
gl.uniform1f(prog.uniform("u_gradLen"), len);
|
|
2181
2294
|
gl.uniform1f(prog.uniform("u_gradRadius"), 0);
|
|
2182
2295
|
gl.uniform1f(prog.uniform("u_gradAngle"), 0);
|
|
2183
2296
|
} else if (fill.kind === "radial-gradient") {
|
|
2184
2297
|
gl.uniform1i(prog.uniform("u_gradKind"), 1);
|
|
2185
|
-
gl.uniform2f(prog.uniform("u_gradP0"), fill.center.x, fill.center.y);
|
|
2186
2298
|
gl.uniform2f(prog.uniform("u_gradDir"), 0, 0);
|
|
2187
2299
|
gl.uniform1f(prog.uniform("u_gradLen"), 0);
|
|
2188
2300
|
gl.uniform1f(prog.uniform("u_gradRadius"), fill.radius);
|
|
2189
2301
|
gl.uniform1f(prog.uniform("u_gradAngle"), 0);
|
|
2190
2302
|
} else {
|
|
2191
2303
|
gl.uniform1i(prog.uniform("u_gradKind"), 2);
|
|
2192
|
-
gl.uniform2f(prog.uniform("u_gradP0"), fill.center.x, fill.center.y);
|
|
2193
2304
|
gl.uniform2f(prog.uniform("u_gradDir"), 0, 0);
|
|
2194
2305
|
gl.uniform1f(prog.uniform("u_gradLen"), 0);
|
|
2195
2306
|
gl.uniform1f(prog.uniform("u_gradRadius"), 0);
|
|
@@ -2522,11 +2633,9 @@ function drawColorGlyphs(ctx, group, dx, dy) {
|
|
|
2522
2633
|
const atlasId = colorPageTextureId(group.page);
|
|
2523
2634
|
const batch = ctx.drawBatch;
|
|
2524
2635
|
const m = ctx.state.transform;
|
|
2525
|
-
let {
|
|
2526
|
-
let alpha = opacity * (staged.foldsAlpha ? ctx.state.alpha : 1);
|
|
2636
|
+
let { slot, tint } = stageColorGlyphs(ctx, atlasId);
|
|
2527
2637
|
const restage = () => {
|
|
2528
|
-
({
|
|
2529
|
-
alpha = opacity * (staged.foldsAlpha ? ctx.state.alpha : 1);
|
|
2638
|
+
({ slot, tint } = stageColorGlyphs(ctx, atlasId));
|
|
2530
2639
|
};
|
|
2531
2640
|
for (const q of group.quads) {
|
|
2532
2641
|
if (batch.wouldOverflow(4)) {
|
|
@@ -2544,8 +2653,11 @@ function drawColorGlyphs(ctx, group, dx, dy) {
|
|
|
2544
2653
|
q.v0,
|
|
2545
2654
|
q.u1,
|
|
2546
2655
|
q.v1,
|
|
2547
|
-
|
|
2548
|
-
slot
|
|
2656
|
+
opacity * tint[3],
|
|
2657
|
+
slot,
|
|
2658
|
+
tint[0],
|
|
2659
|
+
tint[1],
|
|
2660
|
+
tint[2]
|
|
2549
2661
|
)) {
|
|
2550
2662
|
cut = enterUncut(ctx);
|
|
2551
2663
|
restage();
|
|
@@ -2694,14 +2806,19 @@ function drawTextDecorations(ctx, decorations, dx, dy) {
|
|
|
2694
2806
|
const [r, g, b, a] = isSolidPaint(paint) ? resolveColor(paint.color) : [0, 0, 0, 1];
|
|
2695
2807
|
let cut;
|
|
2696
2808
|
for (; ; ) {
|
|
2697
|
-
const
|
|
2809
|
+
const slot = stageSolid(ctx, 4);
|
|
2810
|
+
const rgba = foldColor(ctx, r, g, b, a);
|
|
2698
2811
|
if (ctx.drawBatch.pushRect(
|
|
2699
2812
|
d.x0 + dx,
|
|
2700
2813
|
d.y0 + dy,
|
|
2701
2814
|
d.x1 - d.x0,
|
|
2702
2815
|
d.y1 - d.y0,
|
|
2703
2816
|
ctx.state.transform,
|
|
2704
|
-
|
|
2817
|
+
rgba[0],
|
|
2818
|
+
rgba[1],
|
|
2819
|
+
rgba[2],
|
|
2820
|
+
rgba[3],
|
|
2821
|
+
slot
|
|
2705
2822
|
)) break;
|
|
2706
2823
|
cut = enterUncut(ctx);
|
|
2707
2824
|
}
|
|
@@ -2743,13 +2860,12 @@ function drawTextGroup(ctx, group, dx, dy) {
|
|
|
2743
2860
|
const color = isSolidPaint(fill) ? resolveColor(fill.color) : [0, 0, 0, 1];
|
|
2744
2861
|
const batch = ctx.drawBatch;
|
|
2745
2862
|
const m = ctx.state.transform;
|
|
2746
|
-
let
|
|
2747
|
-
|
|
2863
|
+
let slot = stageGlyphs(ctx, atlasId, fieldScale);
|
|
2864
|
+
const rgba = foldColor(ctx, color[0], color[1], color[2], color[3]);
|
|
2748
2865
|
for (const q of group.quads) {
|
|
2749
2866
|
if (batch.wouldOverflow(4)) {
|
|
2750
2867
|
flushBatch(ctx);
|
|
2751
|
-
|
|
2752
|
-
rgba = foldColor(ctx, staged, color[0], color[1], color[2], color[3]);
|
|
2868
|
+
slot = stageGlyphs(ctx, atlasId, fieldScale);
|
|
2753
2869
|
}
|
|
2754
2870
|
let cut;
|
|
2755
2871
|
while (!batch.pushGlyph(
|
|
@@ -2769,16 +2885,15 @@ function drawTextGroup(ctx, group, dx, dy) {
|
|
|
2769
2885
|
rgba[2],
|
|
2770
2886
|
rgba[3],
|
|
2771
2887
|
slot,
|
|
2772
|
-
mode
|
|
2888
|
+
mode,
|
|
2889
|
+
bold
|
|
2773
2890
|
)) {
|
|
2774
2891
|
cut = enterUncut(ctx);
|
|
2775
|
-
|
|
2776
|
-
rgba = foldColor(ctx, staged, color[0], color[1], color[2], color[3]);
|
|
2892
|
+
slot = stageGlyphs(ctx, atlasId, fieldScale);
|
|
2777
2893
|
}
|
|
2778
2894
|
if (cut !== void 0) {
|
|
2779
2895
|
leaveUncut(ctx, cut);
|
|
2780
|
-
|
|
2781
|
-
rgba = foldColor(ctx, staged, color[0], color[1], color[2], color[3]);
|
|
2896
|
+
slot = stageGlyphs(ctx, atlasId, fieldScale);
|
|
2782
2897
|
}
|
|
2783
2898
|
}
|
|
2784
2899
|
}
|
|
@@ -2835,7 +2950,8 @@ function drawPaintedGlyphs(ctx, group, dx, dy, kind, atlasId, mode, bold, tanIta
|
|
|
2835
2950
|
1,
|
|
2836
2951
|
1,
|
|
2837
2952
|
GLYPH_PAINT_ATLAS_UNIT,
|
|
2838
|
-
mode
|
|
2953
|
+
mode,
|
|
2954
|
+
0
|
|
2839
2955
|
);
|
|
2840
2956
|
}
|
|
2841
2957
|
drawStagedGlyphs(ctx);
|
|
@@ -2891,7 +3007,7 @@ function drawImage(ctx, cmd) {
|
|
|
2891
3007
|
const sh = cmd.source?.h ?? cmd.image.height;
|
|
2892
3008
|
if (isMinified(minifiedLimits(ctx), sw, sh, cmd.w, cmd.h)) ctx.imageCache.buildMipmaps(cmd.image);
|
|
2893
3009
|
}
|
|
2894
|
-
const {
|
|
3010
|
+
const { slot, tint } = stageImage(ctx, cmd.image, cmd.sampling ?? "linear");
|
|
2895
3011
|
const src = cmd.source;
|
|
2896
3012
|
let u0 = 0, v0 = 0, u1 = 1, v1 = 1;
|
|
2897
3013
|
if (src) {
|
|
@@ -2921,10 +3037,8 @@ function drawImage(ctx, cmd) {
|
|
|
2921
3037
|
v0,
|
|
2922
3038
|
u1,
|
|
2923
3039
|
v1,
|
|
2924
|
-
// Group alpha rides
|
|
2925
|
-
|
|
2926
|
-
// as well would apply it twice.
|
|
2927
|
-
(cmd.opacity ?? 1) * (staged.foldsAlpha ? ctx.state.alpha : 1) * tint[3],
|
|
3040
|
+
// Group alpha rides here with the opacity, in the tint's fourth channel.
|
|
3041
|
+
(cmd.opacity ?? 1) * tint[3],
|
|
2928
3042
|
slot,
|
|
2929
3043
|
tint[0],
|
|
2930
3044
|
tint[1],
|
|
@@ -2945,17 +3059,15 @@ function drawSprites(ctx, cmd) {
|
|
|
2945
3059
|
}
|
|
2946
3060
|
}
|
|
2947
3061
|
const sampling = cmd.sampling ?? "linear";
|
|
2948
|
-
let {
|
|
3062
|
+
let { slot, tint } = stageImage(ctx, cmd.image, sampling);
|
|
2949
3063
|
const batch = ctx.drawBatch;
|
|
2950
3064
|
const m = ctx.state.transform;
|
|
2951
|
-
let groupAlpha = (staged.foldsAlpha ? ctx.state.alpha : 1) * tint[3];
|
|
2952
3065
|
const tw = cmd.image.width;
|
|
2953
3066
|
const th = cmd.image.height;
|
|
2954
3067
|
for (let s = 0, i = 0; s < count; s++, i += SPRITE_STRIDE) {
|
|
2955
3068
|
if (batch.wouldOverflow(4)) {
|
|
2956
3069
|
flushBatch(ctx);
|
|
2957
|
-
({
|
|
2958
|
-
groupAlpha = (staged.foldsAlpha ? ctx.state.alpha : 1) * tint[3];
|
|
3070
|
+
({ slot, tint } = stageImage(ctx, cmd.image, sampling));
|
|
2959
3071
|
}
|
|
2960
3072
|
const sx = data[i + 4], sy = data[i + 5], sw = data[i + 6], sh = data[i + 7];
|
|
2961
3073
|
let cut;
|
|
@@ -2969,20 +3081,18 @@ function drawSprites(ctx, cmd) {
|
|
|
2969
3081
|
sy / th,
|
|
2970
3082
|
(sx + sw) / tw,
|
|
2971
3083
|
(sy + sh) / th,
|
|
2972
|
-
data[i + 8] *
|
|
3084
|
+
data[i + 8] * tint[3],
|
|
2973
3085
|
slot,
|
|
2974
3086
|
tint[0],
|
|
2975
3087
|
tint[1],
|
|
2976
3088
|
tint[2]
|
|
2977
3089
|
)) {
|
|
2978
3090
|
cut = enterUncut(ctx);
|
|
2979
|
-
({
|
|
2980
|
-
groupAlpha = (staged.foldsAlpha ? ctx.state.alpha : 1) * tint[3];
|
|
3091
|
+
({ slot, tint } = stageImage(ctx, cmd.image, sampling));
|
|
2981
3092
|
}
|
|
2982
3093
|
if (cut !== void 0) {
|
|
2983
3094
|
leaveUncut(ctx, cut);
|
|
2984
|
-
({
|
|
2985
|
-
groupAlpha = (staged.foldsAlpha ? ctx.state.alpha : 1) * tint[3];
|
|
3095
|
+
({ slot, tint } = stageImage(ctx, cmd.image, sampling));
|
|
2986
3096
|
}
|
|
2987
3097
|
}
|
|
2988
3098
|
}
|
|
@@ -3484,9 +3594,12 @@ var GLYPH_PAINT_SOURCES = {
|
|
|
3484
3594
|
var WeaselRenderer = class {
|
|
3485
3595
|
gl;
|
|
3486
3596
|
stats = { drawCalls: 0, ms: 0, spans: [] };
|
|
3597
|
+
/** Built on the first frame that draws with each, so a one-shot render of
|
|
3598
|
+
* plain shapes builds the batch program alone. */
|
|
3487
3599
|
pathFill;
|
|
3488
3600
|
pathFillVColor;
|
|
3489
3601
|
batchFill;
|
|
3602
|
+
batchFillMatrices;
|
|
3490
3603
|
gradFill;
|
|
3491
3604
|
patternFill;
|
|
3492
3605
|
/** Compiled on first use: only atlas text under a texture paint needs one. */
|
|
@@ -3566,21 +3679,12 @@ var WeaselRenderer = class {
|
|
|
3566
3679
|
}
|
|
3567
3680
|
this.applyGlState();
|
|
3568
3681
|
this.applyTarget();
|
|
3569
|
-
this.pathFill = new
|
|
3570
|
-
this.
|
|
3571
|
-
this.
|
|
3572
|
-
this.
|
|
3573
|
-
this.
|
|
3574
|
-
this.
|
|
3575
|
-
this.batchFill = new ShaderProgram(this.gl, BATCH_VERT_SRC, BATCH_FRAG_SRC);
|
|
3576
|
-
this.batchFill.lookupUniforms(BATCH_FILL_UNIFORMS);
|
|
3577
|
-
this.batchFill.lookupAttributes(BATCH_FILL_ATTRIBUTES);
|
|
3578
|
-
this.gradFill = new ShaderProgram(this.gl, GRAD_VERT_SRC, GRAD_FRAG_SRC);
|
|
3579
|
-
this.gradFill.lookupUniforms(GRAD_FILL_UNIFORMS);
|
|
3580
|
-
this.gradFill.lookupAttributes(GRAD_FILL_ATTRIBUTES);
|
|
3581
|
-
this.patternFill = new ShaderProgram(this.gl, PATTERN_VERT_SRC, PATTERN_FRAG_SRC);
|
|
3582
|
-
this.patternFill.lookupUniforms(PATTERN_FILL_UNIFORMS);
|
|
3583
|
-
this.patternFill.lookupAttributes(PATTERN_FILL_ATTRIBUTES);
|
|
3682
|
+
this.pathFill = new LazyProgram(this.gl, PATH_FILL_SPEC);
|
|
3683
|
+
this.pathFillVColor = new LazyProgram(this.gl, PATH_FILL_VCOLOR_SPEC);
|
|
3684
|
+
this.gradFill = new LazyProgram(this.gl, GRAD_FILL_SPEC);
|
|
3685
|
+
this.patternFill = new LazyProgram(this.gl, PATTERN_FILL_SPEC);
|
|
3686
|
+
this.batchFillMatrices = new LazyProgram(this.gl, BATCH_FILL_MATRICES_SPEC);
|
|
3687
|
+
this.batchFill = createBatchFill(this.gl);
|
|
3584
3688
|
this.meshCache = new GLMeshCache(this.gl);
|
|
3585
3689
|
this.textureCache = new GLTextureCache(this.gl);
|
|
3586
3690
|
this.imageCache = new GLImageCache(this.gl, this.imageMinification);
|
|
@@ -3589,6 +3693,9 @@ var WeaselRenderer = class {
|
|
|
3589
3693
|
this.drawBatch = new DrawBatch(this.gl, this.batchFill);
|
|
3590
3694
|
this.whiteTexture = createWhiteTexture(this.gl);
|
|
3591
3695
|
}
|
|
3696
|
+
lazyPrograms() {
|
|
3697
|
+
return [this.pathFill, this.pathFillVColor, this.gradFill, this.patternFill, this.batchFillMatrices];
|
|
3698
|
+
}
|
|
3592
3699
|
uploadQuadGeometry() {
|
|
3593
3700
|
const gl = this.gl;
|
|
3594
3701
|
this.quadVbo = gl.createBuffer();
|
|
@@ -3742,21 +3849,8 @@ var WeaselRenderer = class {
|
|
|
3742
3849
|
this.paintScratch.release();
|
|
3743
3850
|
this.paintResources.release();
|
|
3744
3851
|
this.paintResources = createPaintResources();
|
|
3745
|
-
|
|
3746
|
-
this.
|
|
3747
|
-
this.pathFill.lookupAttributes(PATH_FILL_ATTRIBUTES);
|
|
3748
|
-
this.pathFillVColor = new ShaderProgram(this.gl, VCOLOR_VERT_SRC, VCOLOR_FRAG_SRC);
|
|
3749
|
-
this.pathFillVColor.lookupUniforms(PATH_FILL_UNIFORMS);
|
|
3750
|
-
this.pathFillVColor.lookupAttributes(PATH_FILL_VCOLOR_ATTRIBUTES);
|
|
3751
|
-
this.batchFill = new ShaderProgram(this.gl, BATCH_VERT_SRC, BATCH_FRAG_SRC);
|
|
3752
|
-
this.batchFill.lookupUniforms(BATCH_FILL_UNIFORMS);
|
|
3753
|
-
this.batchFill.lookupAttributes(BATCH_FILL_ATTRIBUTES);
|
|
3754
|
-
this.gradFill = new ShaderProgram(this.gl, GRAD_VERT_SRC, GRAD_FRAG_SRC);
|
|
3755
|
-
this.gradFill.lookupUniforms(GRAD_FILL_UNIFORMS);
|
|
3756
|
-
this.gradFill.lookupAttributes(GRAD_FILL_ATTRIBUTES);
|
|
3757
|
-
this.patternFill = new ShaderProgram(this.gl, PATTERN_VERT_SRC, PATTERN_FRAG_SRC);
|
|
3758
|
-
this.patternFill.lookupUniforms(PATTERN_FILL_UNIFORMS);
|
|
3759
|
-
this.patternFill.lookupAttributes(PATTERN_FILL_ATTRIBUTES);
|
|
3852
|
+
for (const lazy of this.lazyPrograms()) lazy.abandon();
|
|
3853
|
+
this.batchFill = createBatchFill(this.gl);
|
|
3760
3854
|
this.glyphPaintPrograms.clear();
|
|
3761
3855
|
this.meshCache = new GLMeshCache(this.gl);
|
|
3762
3856
|
this.textureCache = new GLTextureCache(this.gl);
|
|
@@ -3795,14 +3889,8 @@ var WeaselRenderer = class {
|
|
|
3795
3889
|
}
|
|
3796
3890
|
this.meshCache.dispose();
|
|
3797
3891
|
this.paintResources.release();
|
|
3798
|
-
for (const
|
|
3799
|
-
|
|
3800
|
-
this.pathFillVColor,
|
|
3801
|
-
this.batchFill,
|
|
3802
|
-
this.gradFill,
|
|
3803
|
-
this.patternFill,
|
|
3804
|
-
...this.glyphPaintPrograms.values()
|
|
3805
|
-
]) {
|
|
3892
|
+
for (const lazy of this.lazyPrograms()) lazy.release();
|
|
3893
|
+
for (const prog of [this.batchFill, ...this.glyphPaintPrograms.values()]) {
|
|
3806
3894
|
gl.deleteProgram(prog.handle);
|
|
3807
3895
|
}
|
|
3808
3896
|
this.glyphPaintPrograms.clear();
|
|
@@ -3853,13 +3941,25 @@ var WeaselRenderer = class {
|
|
|
3853
3941
|
gl.clear(gl.COLOR_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
|
|
3854
3942
|
}
|
|
3855
3943
|
const device = this.deviceRect();
|
|
3944
|
+
const { pathFill, pathFillVColor, gradFill, patternFill, batchFillMatrices } = this;
|
|
3856
3945
|
const ctx = {
|
|
3857
3946
|
gl,
|
|
3858
|
-
pathFill
|
|
3859
|
-
|
|
3947
|
+
get pathFill() {
|
|
3948
|
+
return pathFill.get();
|
|
3949
|
+
},
|
|
3950
|
+
get pathFillVColor() {
|
|
3951
|
+
return pathFillVColor.get();
|
|
3952
|
+
},
|
|
3860
3953
|
batchFill: this.batchFill,
|
|
3861
|
-
|
|
3862
|
-
|
|
3954
|
+
get batchFillMatrices() {
|
|
3955
|
+
return batchFillMatrices.get();
|
|
3956
|
+
},
|
|
3957
|
+
get gradFill() {
|
|
3958
|
+
return gradFill.get();
|
|
3959
|
+
},
|
|
3960
|
+
get patternFill() {
|
|
3961
|
+
return patternFill.get();
|
|
3962
|
+
},
|
|
3863
3963
|
meshCache: this.meshCache,
|
|
3864
3964
|
textureCache: this.textureCache,
|
|
3865
3965
|
imageCache: this.imageCache,
|
|
@@ -3933,11 +4033,11 @@ var WeaselRenderer = class {
|
|
|
3933
4033
|
}
|
|
3934
4034
|
/** @internal */
|
|
3935
4035
|
_pathFill() {
|
|
3936
|
-
return this.pathFill;
|
|
4036
|
+
return this.pathFill.get();
|
|
3937
4037
|
}
|
|
3938
4038
|
/** @internal */
|
|
3939
4039
|
_pathFillVColor() {
|
|
3940
|
-
return this.pathFillVColor;
|
|
4040
|
+
return this.pathFillVColor.get();
|
|
3941
4041
|
}
|
|
3942
4042
|
/** @internal */
|
|
3943
4043
|
_drawBatch() {
|
|
@@ -3948,12 +4048,16 @@ var WeaselRenderer = class {
|
|
|
3948
4048
|
return this.batchFill;
|
|
3949
4049
|
}
|
|
3950
4050
|
/** @internal */
|
|
4051
|
+
_batchFillMatrices() {
|
|
4052
|
+
return this.batchFillMatrices.get();
|
|
4053
|
+
}
|
|
4054
|
+
/** @internal */
|
|
3951
4055
|
_gradFill() {
|
|
3952
|
-
return this.gradFill;
|
|
4056
|
+
return this.gradFill.get();
|
|
3953
4057
|
}
|
|
3954
4058
|
/** @internal */
|
|
3955
4059
|
_patternFill() {
|
|
3956
|
-
return this.patternFill;
|
|
4060
|
+
return this.patternFill.get();
|
|
3957
4061
|
}
|
|
3958
4062
|
/** @internal */
|
|
3959
4063
|
_meshCache() {
|