@weasel-js/core 1.4.4 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +937 -2202
- package/README.md +118 -75
- package/dist/{autoPoseDescriptor-DF1SnnSx.d.ts → autoPoseDescriptor-CvjflWJK.d.ts} +29 -26
- package/dist/{chunk-2VXGHUVL.js → chunk-BDWAA634.js} +4 -22
- package/dist/chunk-BDWAA634.js.map +1 -0
- package/dist/{chunk-R3AWPTLZ.js → chunk-MG7OXCAI.js} +2760 -4491
- package/dist/chunk-MG7OXCAI.js.map +1 -0
- package/dist/{chunk-PRGBGMH3.js → chunk-MQI4PIX3.js} +3 -3
- package/dist/chunk-MQI4PIX3.js.map +1 -0
- package/dist/{chunk-WPM42WJP.js → chunk-UCPV7JXC.js} +201 -256
- package/dist/chunk-UCPV7JXC.js.map +1 -0
- package/dist/clipboard.d.ts +2 -3
- package/dist/clone.d.ts +3 -2
- package/dist/depSchema-nMqj_qTM.d.ts +3490 -0
- package/dist/{grid-0Pbn5B2C.d.ts → grid-BrIa38gG.d.ts} +7 -10
- package/dist/index.d.ts +1996 -1229
- package/dist/index.js +4 -5
- package/dist/insert.d.ts +4 -4
- package/dist/insert.js +1 -1
- package/dist/move.d.ts +5 -6
- package/dist/move.js +3 -6
- package/dist/move.js.map +1 -1
- package/dist/{options-DbYLImvq.d.ts → options-BDyCnrp8.d.ts} +3 -2
- package/dist/poseDescriptor-CGOgIgf8.d.ts +134 -0
- package/dist/renderer.d.ts +10 -4
- package/dist/renderer.js +4 -5
- package/dist/resize.d.ts +10 -12
- package/dist/resize.js +2 -2
- package/dist/routing.d.ts +1 -142
- package/dist/routing.js +1 -1
- package/dist/routing.js.map +1 -1
- package/dist/{types-ei3UMl9R.d.ts → types-DMyo7dnM.d.ts} +12 -41
- package/dist/{types-DEALFt5F.d.ts → types-DtjCJA5r.d.ts} +9 -3
- package/package.json +13 -10
- package/dist/DrawCommand-CD-ug3d9.d.ts +0 -332
- package/dist/builtins-BXFBXegF.d.ts +0 -840
- package/dist/chunk-2VXGHUVL.js.map +0 -1
- package/dist/chunk-BL65SHCX.js +0 -573
- package/dist/chunk-BL65SHCX.js.map +0 -1
- package/dist/chunk-PRGBGMH3.js.map +0 -1
- package/dist/chunk-R3AWPTLZ.js.map +0 -1
- package/dist/chunk-WPM42WJP.js.map +0 -1
- package/dist/geometry-6fCNhAux.d.ts +0 -114
- package/dist/path-JEV2c5If.d.ts +0 -48
- package/dist/registry-BY-wI9gm.d.ts +0 -4003
- package/dist/types-BHK2dkMu.d.ts +0 -172
- package/dist/types-bcc7jcUy.d.ts +0 -594
- package/dist/view-DSQgxBJB.d.ts +0 -63
|
@@ -1,840 +0,0 @@
|
|
|
1
|
-
import { GradStop, Stroke } from '@weasel-js/paint';
|
|
2
|
-
import { M as Mat3, b as ShaderProgramHandle, D as DrawCommand, E as Effect } from './DrawCommand-CD-ug3d9.js';
|
|
3
|
-
import { P as Path } from './path-JEV2c5If.js';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Minimal compile/link/lookup wrapper for a GL program. Throws
|
|
7
|
-
* `ShaderCompileError` on compile or link failure with the GL info log
|
|
8
|
-
* embedded in the error message — never returns a half-initialized program.
|
|
9
|
-
*
|
|
10
|
-
* Designed so test code can stub `getShaderParameter` / `getProgramParameter`
|
|
11
|
-
* via the recorder Proxy without further special-casing.
|
|
12
|
-
*/
|
|
13
|
-
type Stage = 'vertex' | 'fragment' | 'link';
|
|
14
|
-
/** Thrown when a shader fails to compile or link, carrying which stage failed
|
|
15
|
-
* and the driver's log. */
|
|
16
|
-
declare class ShaderCompileError extends Error {
|
|
17
|
-
readonly stage: Stage;
|
|
18
|
-
readonly log: string;
|
|
19
|
-
constructor(stage: Stage, log: string);
|
|
20
|
-
}
|
|
21
|
-
declare class ShaderProgram {
|
|
22
|
-
private readonly gl;
|
|
23
|
-
readonly handle: WebGLProgram;
|
|
24
|
-
private readonly uniforms;
|
|
25
|
-
private readonly attributes;
|
|
26
|
-
constructor(gl: WebGL2RenderingContext, vertSrc: string, fragSrc: string);
|
|
27
|
-
private compile;
|
|
28
|
-
lookupUniforms(names: readonly string[]): void;
|
|
29
|
-
lookupAttributes(names: readonly string[]): void;
|
|
30
|
-
uniform(name: string): WebGLUniformLocation | undefined;
|
|
31
|
-
attribute(name: string): number | undefined;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* A tessellated representation of a Path, ready to upload to GL.
|
|
36
|
-
*
|
|
37
|
-
* - `vertices` is interleaved x,y in path-local coordinates (`Float32Array`
|
|
38
|
-
* of length `2 * vertexCount`).
|
|
39
|
-
* - `indices` are triangle indices into `vertices` (`Uint32Array`, length
|
|
40
|
-
* `3 * triangleCount`).
|
|
41
|
-
* - `requiresStencil` is set for paths whose fillRule is `'evenodd'` and
|
|
42
|
-
* whose triangulation is a *naive* per-contour fan rather than a clean
|
|
43
|
-
* inside/outside triangulation. The renderer must use a stencil
|
|
44
|
-
* two-pass when this flag is true. Single-contour paths and `'nonzero'`
|
|
45
|
-
* multi-contour paths leave it false.
|
|
46
|
-
* - `anchorA` / `anchorB` / `anchorT` parameterize each mesh vertex by
|
|
47
|
-
* the two consecutive path anchors it lies between and the arc-length
|
|
48
|
-
* fraction along that segment (0 = at A, 1 = at B). Vertices that fall
|
|
49
|
-
* exactly on an anchor set A === B and t = 0. Used at draw time when
|
|
50
|
-
* the DrawCommand supplies per-anchor colors so the renderer can lerp
|
|
51
|
-
* per mesh vertex. Optional — emitted by the path tessellators; absent
|
|
52
|
-
* on meshes built by other paths (e.g. text glyphs).
|
|
53
|
-
*/
|
|
54
|
-
interface Mesh {
|
|
55
|
-
readonly vertices: Float32Array;
|
|
56
|
-
readonly indices: Uint32Array;
|
|
57
|
-
readonly requiresStencil?: boolean;
|
|
58
|
-
readonly anchorA?: Uint32Array;
|
|
59
|
-
readonly anchorB?: Uint32Array;
|
|
60
|
-
readonly anchorT?: Float32Array;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
interface GLMeshHandle {
|
|
64
|
-
readonly vao: WebGLVertexArrayObject;
|
|
65
|
-
readonly indexCount: number;
|
|
66
|
-
readonly requiresStencil: boolean;
|
|
67
|
-
readonly anchorA?: Uint32Array;
|
|
68
|
-
readonly anchorB?: Uint32Array;
|
|
69
|
-
readonly anchorT?: Float32Array;
|
|
70
|
-
}
|
|
71
|
-
/** Resources to release when a Mesh is reclaimed by GC. */
|
|
72
|
-
interface MeshResources {
|
|
73
|
-
vao: WebGLVertexArrayObject;
|
|
74
|
-
vbo: WebGLBuffer;
|
|
75
|
-
ibo: WebGLBuffer;
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* Caches GL-side buffers + VAO per `Mesh` identity. Upload happens lazily
|
|
79
|
-
* on first `handleFor(mesh)` call.
|
|
80
|
-
*
|
|
81
|
-
* **GC-aware cleanup (deferred-delete queue):** when a Mesh becomes
|
|
82
|
-
* unreachable, the WeakMap entry is dropped automatically — but the
|
|
83
|
-
* underlying GL resources (VAO, VBO, IBO) would leak forever without an
|
|
84
|
-
* explicit `gl.delete*` call. We register each Mesh with a
|
|
85
|
-
* `FinalizationRegistry`; when the Mesh is reclaimed, the finalizer pushes
|
|
86
|
-
* the resources onto an internal queue. The renderer drains this queue at
|
|
87
|
-
* the start of each `render()` call (via `drainPendingDeletes()`), when GL
|
|
88
|
-
* is in a known state — no VAO bound, no draw mid-flight. Deleting from the
|
|
89
|
-
* finalizer directly was racy (it could fire between two `gl.bindVertexArray`
|
|
90
|
-
* calls inside `dispatch()`, sometimes corrupting the next draw); deferring
|
|
91
|
-
* the actual delete to a known-safe point keeps the use-after-free risk to
|
|
92
|
-
* zero.
|
|
93
|
-
*
|
|
94
|
-
* Caveats:
|
|
95
|
-
* - Finalizer timing is non-deterministic; resources may live for a frame
|
|
96
|
-
* or two beyond their Mesh, but they will be reclaimed.
|
|
97
|
-
* - If the GL context is lost between finalizer and drain, the drain
|
|
98
|
-
* no-ops safely (`gl.isContextLost()` makes deletes no-ops, and
|
|
99
|
-
* `gl.deleteBuffer(null)` is allowed).
|
|
100
|
-
*
|
|
101
|
-
* The cache is GL-context-bound; if the context is lost and re-created, the
|
|
102
|
-
* renderer should construct a new GLMeshCache. (Context loss handling lives
|
|
103
|
-
* in `WeaselRenderer`.)
|
|
104
|
-
*/
|
|
105
|
-
declare class GLMeshCache {
|
|
106
|
-
private readonly gl;
|
|
107
|
-
private readonly aPositionLoc;
|
|
108
|
-
private readonly map;
|
|
109
|
-
/** Meshes this context has drawn at least once; see `uploadRecurring`. */
|
|
110
|
-
private readonly seen;
|
|
111
|
-
private readonly finalizer;
|
|
112
|
-
private readonly pendingDeletes;
|
|
113
|
-
/** Transient resources allocated this frame; freed at end of render(). */
|
|
114
|
-
private readonly transientThisFrame;
|
|
115
|
-
constructor(gl: WebGL2RenderingContext, aPositionLoc: number);
|
|
116
|
-
handleFor(mesh: Mesh): GLMeshHandle;
|
|
117
|
-
/**
|
|
118
|
-
* Upload a Mesh that the caller knows is single-use (e.g. the per-frame
|
|
119
|
-
* stroke ribbon from `tessellateStroke`). Returns a handle backed by fresh
|
|
120
|
-
* GL resources that the renderer will free deterministically at the end
|
|
121
|
-
* of the current frame via `freeTransient()`. Bypasses the WeakMap cache
|
|
122
|
-
* and the FinalizationRegistry, so transient meshes never wait on GC.
|
|
123
|
-
*/
|
|
124
|
-
uploadTransient(mesh: Mesh): GLMeshHandle;
|
|
125
|
-
/**
|
|
126
|
-
* Upload a Mesh that may or may not recur across frames. Its first sight in
|
|
127
|
-
* *this* context takes `uploadTransient`; every later one takes the
|
|
128
|
-
* persistent handle. One transient upload to find out is cheaper than
|
|
129
|
-
* stranding a persistent VAO on a mesh that never returns, whose release
|
|
130
|
-
* would wait on GC. The transient upload does not populate the persistent
|
|
131
|
-
* map, so steady-state reuse begins on the third frame.
|
|
132
|
-
*/
|
|
133
|
-
uploadRecurring(mesh: Mesh): GLMeshHandle;
|
|
134
|
-
/**
|
|
135
|
-
* Free all transient resources allocated since the last call. Called by
|
|
136
|
-
* the renderer at the end of each `render()`. Safe under context loss.
|
|
137
|
-
*/
|
|
138
|
-
freeTransient(): void;
|
|
139
|
-
/** @internal — for tests asserting the transient-list size. */
|
|
140
|
-
_transientCount(): number;
|
|
141
|
-
/**
|
|
142
|
-
* Free GL resources whose Mesh has been GC'd since the last drain.
|
|
143
|
-
* Called by the renderer at the top of each `render()`, before any draws.
|
|
144
|
-
*/
|
|
145
|
-
drainPendingDeletes(): void;
|
|
146
|
-
/** @internal — for tests asserting the queue size. */
|
|
147
|
-
_pendingDeleteCount(): number;
|
|
148
|
-
/** @internal — for tests that need to simulate the finalizer firing. */
|
|
149
|
-
_enqueueDeleteForTest(resources: MeshResources): void;
|
|
150
|
-
private upload;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* GL texture upload + cache for MSDF font atlases (and future images).
|
|
155
|
-
*
|
|
156
|
-
* Textures are keyed by a string id (the font family name or image id).
|
|
157
|
-
* Pixels are uploaded once per id; a later upload of the same id reuses the
|
|
158
|
-
* texture and only re-applies its wrap mode when that changed.
|
|
159
|
-
* The cache is GL-context-bound; discard and create a new one on context loss.
|
|
160
|
-
*
|
|
161
|
-
* Atlas format: RGBA UNSIGNED_BYTE, linear filtering, no mipmaps.
|
|
162
|
-
* Mipmap generation is deliberately skipped — MSDF works correctly with
|
|
163
|
-
* linear filtering, and mipmap resampling corrupts the multi-channel SDF signal.
|
|
164
|
-
*/
|
|
165
|
-
type TexSource$1 = HTMLImageElement | ImageBitmap | ImageData | HTMLCanvasElement;
|
|
166
|
-
/** How a texture samples outside `0..1`. Pattern tiles need `'repeat'`;
|
|
167
|
-
* everything else clamps. WebGL2 allows `REPEAT` on NPOT textures, so a
|
|
168
|
-
* tile of any size tiles correctly. */
|
|
169
|
-
type TextureWrap = 'clamp' | 'repeat';
|
|
170
|
-
declare class GLTextureCache {
|
|
171
|
-
private readonly gl;
|
|
172
|
-
private readonly map;
|
|
173
|
-
private readonly wraps;
|
|
174
|
-
constructor(gl: WebGL2RenderingContext);
|
|
175
|
-
has(id: string): boolean;
|
|
176
|
-
/** Uploads the pixels once per id. `wrap` is re-applied whenever it differs
|
|
177
|
-
* from what the id was last uploaded under: the same registered image can
|
|
178
|
-
* be a clamped shader texture in one draw and a repeating pattern tile in
|
|
179
|
-
* the next, and first-upload-wins gave the second one the first one's mode. */
|
|
180
|
-
upload(id: string, source: TexSource$1, wrap?: TextureWrap): string;
|
|
181
|
-
private applyWrap;
|
|
182
|
-
/** Create a single-channel R8 texture from raw bytes (full upload).
|
|
183
|
-
* No-op if `id` already exists. Same LINEAR/CLAMP params as `upload`;
|
|
184
|
-
* UNPACK_ALIGNMENT dropped to 1 for non-4-aligned row widths. */
|
|
185
|
-
uploadR8(id: string, width: number, height: number, data: Uint8Array): void;
|
|
186
|
-
/** Patch a rect of an existing R8 texture with tightly-packed w×h bytes. */
|
|
187
|
-
subImageR8(id: string, x: number, y: number, w: number, h: number, data: Uint8Array): void;
|
|
188
|
-
bind(id: string, unit: number): void;
|
|
189
|
-
/**
|
|
190
|
-
* Delete every uploaded GL texture and clear the map. Called by
|
|
191
|
-
* `WeaselRenderer.dispose()`. The cache is unusable but refillable
|
|
192
|
-
* afterward — a subsequent `upload()` for a previously-seen id re-creates
|
|
193
|
-
* the texture rather than restoring the deleted one.
|
|
194
|
-
*/
|
|
195
|
-
free(): void;
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
/**
|
|
199
|
-
* GL texture upload cache for ImageBitmap objects.
|
|
200
|
-
*
|
|
201
|
-
* Key: ImageBitmap (or pattern source object) identity (WeakMap) — lets GC
|
|
202
|
-
* reclaim unreferenced bitmaps. The GL textures are NOT freed when the source
|
|
203
|
-
* is gc'd; deferred to v2.
|
|
204
|
-
*
|
|
205
|
-
* Wrapping is set once at upload time per the `repetition` parameter:
|
|
206
|
-
* - undefined / 'no-repeat' → CLAMP_TO_EDGE
|
|
207
|
-
* - 'repeat' → REPEAT (both axes)
|
|
208
|
-
* - 'repeat-x' → REPEAT on S, CLAMP on T
|
|
209
|
-
* - 'repeat-y' → CLAMP on S, REPEAT on T
|
|
210
|
-
*
|
|
211
|
-
* Convention §2: texels stored straight; shader premultiplies.
|
|
212
|
-
*/
|
|
213
|
-
type PatternRepetition = 'repeat' | 'repeat-x' | 'repeat-y' | 'no-repeat';
|
|
214
|
-
/** MIN_FILTER strategy for uploaded textures. */
|
|
215
|
-
type ImageMinification = 'linear' | 'mipmap';
|
|
216
|
-
type TexSource = ImageBitmap | ImageData | HTMLCanvasElement | HTMLImageElement;
|
|
217
|
-
declare class GLImageCache {
|
|
218
|
-
private readonly gl;
|
|
219
|
-
private readonly minification;
|
|
220
|
-
private readonly map;
|
|
221
|
-
/**
|
|
222
|
-
* MAG_FILTER each texture currently carries, so a redundant write can be
|
|
223
|
-
* skipped.
|
|
224
|
-
*
|
|
225
|
-
* The batch sets this per flush — the same bitmap can be drawn at both
|
|
226
|
-
* filters in one frame, and the value has to be right at the draw rather than
|
|
227
|
-
* at upload. Filtering is state on the *texture object*, though, not on the
|
|
228
|
-
* unit, so re-asserting a value it already has is a write to a live texture
|
|
229
|
-
* for no reason. On a large sheet that is not free: a consumer's wall samples
|
|
230
|
-
* a 5652px-square atlas, 122MB resident, and measured `sampling: 'nearest'`
|
|
231
|
-
* costing up to 8x `'linear'` there — where the linear pass re-asserts the
|
|
232
|
-
* upload default and the nearest pass changes state on every draw.
|
|
233
|
-
*
|
|
234
|
-
* Whether that is the cause is unproven (see `docs/TODO.md`), but the write
|
|
235
|
-
* was redundant either way.
|
|
236
|
-
*/
|
|
237
|
-
private readonly magFilters;
|
|
238
|
-
/** `minification` selects the MIN_FILTER strategy for uploaded textures.
|
|
239
|
-
* `'linear'` (default) is the screen path's existing behavior. `'mipmap'`
|
|
240
|
-
* generates mipmaps and filters LINEAR_MIPMAP_LINEAR — required for
|
|
241
|
-
* quality minification when a large source bitmap is drawn small (the
|
|
242
|
-
* headless print/export path); bilinear-only minification undersamples
|
|
243
|
-
* and produces moiré. */
|
|
244
|
-
constructor(gl: WebGL2RenderingContext, minification?: ImageMinification);
|
|
245
|
-
upload(key: object, source: TexSource, repetition?: PatternRepetition): WebGLTexture;
|
|
246
|
-
bind(key: object, unit: number): void;
|
|
247
|
-
/** Set `key`'s MAG_FILTER, skipping the call when it already holds that
|
|
248
|
-
* value. Its texture must be bound to the active unit — callers pair this
|
|
249
|
-
* with `bind`. */
|
|
250
|
-
setMagFilter(key: object, filter: number): void;
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
/**
|
|
254
|
-
* CPU gradient-ramp builder + the GL texture every baked ramp lives in.
|
|
255
|
-
*
|
|
256
|
-
* Each unique stop list is baked once into a 256-texel strip and written to its
|
|
257
|
-
* own **row** of one RGBA texture, keyed by `JSON.stringify(stops)`. One
|
|
258
|
-
* texture rather than one per ramp is what lets a gradient take a batch texture
|
|
259
|
-
* slot the way a bitmap or a font atlas does: every gradient in a frame samples
|
|
260
|
-
* the same unit, so a run does not break per gradient. The atlas is
|
|
261
|
-
* GL-context-bound; discard and recreate on context loss.
|
|
262
|
-
*
|
|
263
|
-
* Output convention §2: texels are stored as straight RGBA. The fragment
|
|
264
|
-
* shader applies premultiplication before writing outColor.
|
|
265
|
-
*/
|
|
266
|
-
|
|
267
|
-
/** Bake gradient stops into a 256-entry RGBA lookup strip, which the shader
|
|
268
|
-
* samples instead of evaluating stops per fragment. */
|
|
269
|
-
declare function buildGradientRamp(stops: GradStop[]): Uint8ClampedArray;
|
|
270
|
-
declare class GradientRampAtlas {
|
|
271
|
-
private readonly gl;
|
|
272
|
-
/** Row per stop list, in least-recently-used order: a hit re-inserts, so the
|
|
273
|
-
* first entry is the row a full atlas recycles. */
|
|
274
|
-
private readonly rowByKey;
|
|
275
|
-
private texture;
|
|
276
|
-
private rows;
|
|
277
|
-
/** Mirror of the texture, so growth can respecify it without re-baking every
|
|
278
|
-
* ramp it already holds. */
|
|
279
|
-
private pixels;
|
|
280
|
-
private totalQueries;
|
|
281
|
-
private cacheHits;
|
|
282
|
-
constructor(gl: WebGL2RenderingContext);
|
|
283
|
-
/** Rows the atlas currently holds — its texture height. */
|
|
284
|
-
get height(): number;
|
|
285
|
-
/**
|
|
286
|
-
* Bake `stops` into a row and return it, reusing the row an identical stop
|
|
287
|
-
* list already holds.
|
|
288
|
-
*
|
|
289
|
-
* **A returned row outlives the frame only while the atlas has room.** Past
|
|
290
|
-
* `RAMP_ATLAS_MAX_ROWS` an upload recycles the least recently used row, which
|
|
291
|
-
* rewrites texels a row handed out earlier still names. Nothing that defers
|
|
292
|
-
* its draw past this call may hold a row across another `upload` without
|
|
293
|
-
* arranging to be flushed first.
|
|
294
|
-
*/
|
|
295
|
-
upload(stops: GradStop[]): number;
|
|
296
|
-
/**
|
|
297
|
-
* Whether uploading `stops` would move where existing rows sit — by growing
|
|
298
|
-
* the atlas, which changes every row's `v`, or by recycling one, which
|
|
299
|
-
* rewrites its texels.
|
|
300
|
-
*
|
|
301
|
-
* Anything holding a row past this call asks first and gets itself out of
|
|
302
|
-
* the way, because neither can be undone once it has happened.
|
|
303
|
-
*/
|
|
304
|
-
wouldReshape(stops: GradStop[]): boolean;
|
|
305
|
-
/**
|
|
306
|
-
* The `v` a row is sampled at — its center.
|
|
307
|
-
*
|
|
308
|
-
* The center is load-bearing: the atlas filters LINEAR, so a `v` anywhere
|
|
309
|
-
* else blends the ramp beside it into this one. At the center the neighbor's
|
|
310
|
-
* weight is exactly zero.
|
|
311
|
-
*/
|
|
312
|
-
rowV(row: number): number;
|
|
313
|
-
bind(unit: number): void;
|
|
314
|
-
hitRate(): number;
|
|
315
|
-
resetStats(): void;
|
|
316
|
-
/**
|
|
317
|
-
* Delete the atlas texture and forget every row in it. Called by
|
|
318
|
-
* `WeaselRenderer.dispose()`. The CPU mirror goes with it, so the atlas is
|
|
319
|
-
* unusable but refillable afterward (stats are left as-is; call
|
|
320
|
-
* `resetStats()` separately if desired).
|
|
321
|
-
*/
|
|
322
|
-
free(): void;
|
|
323
|
-
/** The row the next ramp is written to: a free one, a taller atlas, or the
|
|
324
|
-
* least recently used row of a full one. */
|
|
325
|
-
private claimRow;
|
|
326
|
-
/** Grow to `rows`, keeping every row at the index it already had — a row
|
|
327
|
-
* index is a stable name, and callers hold them. */
|
|
328
|
-
private resize;
|
|
329
|
-
private writeRow;
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
/** Row-major 4×5 color matrix identity. */
|
|
333
|
-
declare const IDENTITY_COLOR_MATRIX: Float32Array<ArrayBuffer>;
|
|
334
|
-
interface GroupFrame {
|
|
335
|
-
transform?: Mat3;
|
|
336
|
-
alpha?: number;
|
|
337
|
-
/** Row-major 4×5 color matrix (20 floats). Absent leaves the stack unchanged. */
|
|
338
|
-
colorMatrix?: Float32Array | number[];
|
|
339
|
-
}
|
|
340
|
-
declare class GroupState {
|
|
341
|
-
private transformStack;
|
|
342
|
-
private alphaStack;
|
|
343
|
-
private colorMatrixStack;
|
|
344
|
-
get transform(): Mat3;
|
|
345
|
-
get alpha(): number;
|
|
346
|
-
get colorMatrix(): Float32Array;
|
|
347
|
-
push(frame: GroupFrame): void;
|
|
348
|
-
/**
|
|
349
|
-
* Push a frame whose children paint into a surface of their own.
|
|
350
|
-
*
|
|
351
|
-
* The transform still accumulates — the children draw where they would have
|
|
352
|
-
* drawn. Alpha and colour do not: they describe how the finished surface
|
|
353
|
-
* joins the frame, and applying them on the way in as well would fade the
|
|
354
|
-
* pixels an effect is about to read, then fade them again on the way out.
|
|
355
|
-
*
|
|
356
|
-
* Returns the pair the caller must apply at composite time — what `push`
|
|
357
|
-
* would have left on the stack — so the composition rules live here and not
|
|
358
|
-
* in the dispatcher.
|
|
359
|
-
*/
|
|
360
|
-
pushIsolated(frame: GroupFrame): {
|
|
361
|
-
alpha: number;
|
|
362
|
-
colorMatrix: Float32Array;
|
|
363
|
-
};
|
|
364
|
-
/** Drop every pushed frame, leaving the root. A frame that throws part-way
|
|
365
|
-
* down the tree never pops, and the next frame would draw under leftovers. */
|
|
366
|
-
reset(): void;
|
|
367
|
-
pop(): void;
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
/**
|
|
371
|
-
* Growable vertex staging for a run of solid-fill geometry, image quads and
|
|
372
|
-
* glyphs.
|
|
373
|
-
*
|
|
374
|
-
* Geometry only: `draw.ts` owns when a run starts, what breaks it, and the
|
|
375
|
-
* uniforms the flush draws under.
|
|
376
|
-
*
|
|
377
|
-
* **One batch for all three, because a page interleaves them.** A grid of
|
|
378
|
-
* thumbnails is a ground rect under an atlas quad under a caption, per cell,
|
|
379
|
-
* and while each kind staged separately every one had to drain the others
|
|
380
|
-
* before it could stage — so a shape that batches perfectly in any one half
|
|
381
|
-
* alone paid a flush per command. Everything a vertex needs to say which it is
|
|
382
|
-
* fits in the same vertex: solids carry the UV of a 1x1 white texel and are
|
|
383
|
-
* their own color, quads carry their atlas UV and a white color, glyphs carry
|
|
384
|
-
* a font atlas UV, their text color, and a paint mode saying the texel is a
|
|
385
|
-
* distance field rather than a color. Gradients join as a fourth off the ramp
|
|
386
|
-
* atlas — a linear one without a mode of its own, since (ramp position, row) is
|
|
387
|
-
* what the plain mode already samples, and a radial or conic one with a mode
|
|
388
|
-
* that says its UV is a gradient-space coordinate to take a `length` or an
|
|
389
|
-
* `atan` of. See `shaders/batchFill.ts`.
|
|
390
|
-
*
|
|
391
|
-
* Colors ride the vertices because shapes in a run differ in color and a merged
|
|
392
|
-
* draw has one set of uniforms — and so does the model transform, applied here
|
|
393
|
-
* rather than uploaded, so shapes under different transforms still share a
|
|
394
|
-
* draw. The texture rides them too, as a slot index into the units the flush
|
|
395
|
-
* binds: slot 0 is the white texel every solid samples, and `draw.ts` hands out
|
|
396
|
-
* the rest per bitmap. A run holds as many bitmaps as there are slots, so an
|
|
397
|
-
* atlas is what makes a wall of one sheet coalesce and a handful of loose
|
|
398
|
-
* bitmaps no longer breaks a run per command.
|
|
399
|
-
*/
|
|
400
|
-
|
|
401
|
-
/**
|
|
402
|
-
* A gradient vertex's `a_uv`, each channel affine in the coordinates the
|
|
403
|
-
* geometry arrives in: `u = ux*x + uy*y + u0`, and the same for `v`.
|
|
404
|
-
*
|
|
405
|
-
* One shape for all three gradients. A linear one's `v` row is the constant
|
|
406
|
-
* atlas row and its `u` row is the ramp position; a radial or conic one's two
|
|
407
|
-
* rows are the gradient-space coordinate, and the row rides `a_post` instead.
|
|
408
|
-
*/
|
|
409
|
-
interface GradientUV {
|
|
410
|
-
ux: number;
|
|
411
|
-
uy: number;
|
|
412
|
-
u0: number;
|
|
413
|
-
vx: number;
|
|
414
|
-
vy: number;
|
|
415
|
-
v0: number;
|
|
416
|
-
}
|
|
417
|
-
declare class DrawBatch {
|
|
418
|
-
private readonly gl;
|
|
419
|
-
private readonly aPos;
|
|
420
|
-
private readonly aColor;
|
|
421
|
-
private readonly aUv;
|
|
422
|
-
private readonly aPost;
|
|
423
|
-
private readonly aSlot;
|
|
424
|
-
/** One ring per tier, cycled per flush. Slots are created on first use, so a
|
|
425
|
-
* renderer that flushes rarely allocates as few as it flushes. */
|
|
426
|
-
private readonly rings;
|
|
427
|
-
private readonly nextInRing;
|
|
428
|
-
/** The same, for flushes past the largest tier; these sets grow to fit. */
|
|
429
|
-
private readonly largeRing;
|
|
430
|
-
private nextLarge;
|
|
431
|
-
private verts;
|
|
432
|
-
private idx;
|
|
433
|
-
private nVerts;
|
|
434
|
-
private nIdx;
|
|
435
|
-
/** Whether the staged run is quads alone, so its indices are the canonical
|
|
436
|
-
* pattern and a slot already holding that pattern needs no upload. */
|
|
437
|
-
private pureRects;
|
|
438
|
-
constructor(gl: WebGL2RenderingContext, prog: ShaderProgram);
|
|
439
|
-
get length(): number;
|
|
440
|
-
/** Whether staging `vertices` more would put the run past the per-flush cap. */
|
|
441
|
-
wouldOverflow(vertices: number): boolean;
|
|
442
|
-
/**
|
|
443
|
-
* Append one rect's four corners through `m`, all carrying `rgba` (straight
|
|
444
|
-
* alpha). An affine maps a rect to a parallelogram, so two triangles still
|
|
445
|
-
* cover it and the batch draws at `u_model` identity.
|
|
446
|
-
*/
|
|
447
|
-
pushRect(x: number, y: number, w: number, h: number, m: Mat3, r: number, g: number, b: number, a: number): void;
|
|
448
|
-
/**
|
|
449
|
-
* Append one image quad: the destination rect `(x, y, w, h)` mapped through
|
|
450
|
-
* `m`, sampling `(u0, v0)`-`(u1, v1)`, every corner carrying `post` as the
|
|
451
|
-
* after-the-color-matrix alpha factor.
|
|
452
|
-
*
|
|
453
|
-
* Corners wind top-left, top-right, bottom-right, bottom-left with UVs
|
|
454
|
-
* following — the same winding `pushRect` uses, which is what lets a run of
|
|
455
|
-
* mixed rects and quads keep the canonical index pattern. The flips a command
|
|
456
|
-
* asks for are already in the `u` / `v` the caller passes.
|
|
457
|
-
*
|
|
458
|
-
* `slot` is the texture unit the corners sample, which `draw.ts` assigns per
|
|
459
|
-
* bitmap within the run.
|
|
460
|
-
*/
|
|
461
|
-
pushQuad(x: number, y: number, w: number, h: number, m: Mat3, u0: number, v0: number, u1: number, v1: number, post: number, slot: number): void;
|
|
462
|
-
/**
|
|
463
|
-
* Append one glyph quad: the box `(x0, y0)`-`(x1, y1)` mapped through `m`,
|
|
464
|
-
* sampling `(u0, v0)`-`(u1, v1)` of the font atlas at `slot`, painted in
|
|
465
|
-
* `rgba`.
|
|
466
|
-
*
|
|
467
|
-
* `mode` says which channels of that atlas carry the distance field, and
|
|
468
|
-
* rides the vertices packed into the slot — so a run off a baked MSDF atlas
|
|
469
|
-
* and one off the runtime canvas bake still share a draw. The synthetic-bold
|
|
470
|
-
* threshold does not: it is `u_synthBold`, and `draw.ts` breaks the run when
|
|
471
|
-
* it changes.
|
|
472
|
-
*
|
|
473
|
-
* **A synthetic oblique is sheared here rather than in the shader.** The old
|
|
474
|
-
* text program carried the baseline per vertex and skewed against
|
|
475
|
-
* `u_synthItalic`; the batch places its own corners, so the shear is one
|
|
476
|
-
* multiply while they are being placed, and `tanItalic` is 0 for an upright
|
|
477
|
-
* face. It has to happen before `m`, which is where the shader had it too.
|
|
478
|
-
*
|
|
479
|
-
* Corners wind top-left, top-right, bottom-right, bottom-left — `pushQuad`'s
|
|
480
|
-
* winding, which is what lets a run of mixed rects, image quads and glyphs
|
|
481
|
-
* keep the canonical index pattern.
|
|
482
|
-
*/
|
|
483
|
-
pushGlyph(x0: number, y0: number, x1: number, y1: number, baselineY: number, tanItalic: number, m: Mat3, u0: number, v0: number, u1: number, v1: number, r: number, g: number, b: number, a: number, slot: number, mode: number): void;
|
|
484
|
-
/**
|
|
485
|
-
* Append one rect filled by a gradient: the corners of `(x, y, w, h)` mapped
|
|
486
|
-
* through `m`, sampling the ramp atlas at `slot`.
|
|
487
|
-
*
|
|
488
|
-
* `uv` gives each channel of `a_uv` as an affine function of the coordinates
|
|
489
|
-
* the corners arrive in, which is what lets a gradient ride the vertices at
|
|
490
|
-
* all: a linear one's ramp position is affine in position outright, and a
|
|
491
|
-
* radial or conic one's gradient-space *coordinate* is, even though the ramp
|
|
492
|
-
* position it yields is not. Either way the rasterizer's interpolation across
|
|
493
|
-
* a triangle is exact. `mode` says which of the two the fragment shader is
|
|
494
|
-
* looking at, and `post` carries the atlas row for the modes that read it —
|
|
495
|
-
* see `shaders/batchFill.ts`.
|
|
496
|
-
*
|
|
497
|
-
* Values outside 0..1 are the sampler's business; the atlas clamps to the
|
|
498
|
-
* edge texel, which is what the gradient shader's own `clamp` did.
|
|
499
|
-
*/
|
|
500
|
-
pushGradientRect(x: number, y: number, w: number, h: number, m: Mat3, uv: GradientUV, post: number, slot: number, mode: number, r: number, g: number, b: number, a: number): void;
|
|
501
|
-
/** `pushMesh` for a mesh filled by a gradient — see `pushGradientRect` for
|
|
502
|
-
* what `uv`, `post` and `mode` carry. */
|
|
503
|
-
pushGradientMesh(mesh: Mesh, m: Mat3, uv: GradientUV, post: number, slot: number, mode: number, r: number, g: number, b: number, a: number): void;
|
|
504
|
-
/**
|
|
505
|
-
* Append a tessellated mesh through `m`, all vertices carrying `rgba`. The
|
|
506
|
-
* mesh's own indices are rebased onto the staged vertices, which is why the
|
|
507
|
-
* index buffer is uploaded per flush rather than written once.
|
|
508
|
-
*/
|
|
509
|
-
pushMesh(mesh: Mesh, m: Mat3, r: number, g: number, b: number, a: number): void;
|
|
510
|
-
/** Upload the staged geometry into the next set of buffers and bind its VAO.
|
|
511
|
-
* Returns the index count for the caller's `drawElements`. */
|
|
512
|
-
uploadAndBind(): number;
|
|
513
|
-
reset(): void;
|
|
514
|
-
dispose(): void;
|
|
515
|
-
private writeVertex;
|
|
516
|
-
/** Two triangles over the four corners just written. */
|
|
517
|
-
private pushQuadIndices;
|
|
518
|
-
/** Grow the CPU arrays so `vertices` / `indices` more fit. */
|
|
519
|
-
private reserve;
|
|
520
|
-
private nextRingSlot;
|
|
521
|
-
private nextLargeSlot;
|
|
522
|
-
private createSet;
|
|
523
|
-
private deleteSet;
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
/** How to construct a `WeaselRenderer`: the GL context or canvas to draw
|
|
527
|
-
* into, the output size, and the quality knobs that separate screen
|
|
528
|
-
* rendering from print. */
|
|
529
|
-
interface WeaselRendererOptions {
|
|
530
|
-
gl?: WebGL2RenderingContext;
|
|
531
|
-
canvas?: HTMLCanvasElement;
|
|
532
|
-
width: number;
|
|
533
|
-
height: number;
|
|
534
|
-
dpr: number;
|
|
535
|
-
/** MIN_FILTER strategy for image/pattern textures (`GLImageCache`).
|
|
536
|
-
* Default `'linear'` — the existing screen behavior. The headless
|
|
537
|
-
* `renderSceneToPixels` path passes `'mipmap'` for print-quality
|
|
538
|
-
* minification. Explicitly passing `'linear'` is always valid. */
|
|
539
|
-
imageMinification?: ImageMinification;
|
|
540
|
-
/** Flatness tolerance for curve tessellation, in WORLD units (see
|
|
541
|
-
* `TessellateOptions.flattenTolerance`). When set, path fills are
|
|
542
|
-
* tessellated fresh at this tolerance per frame (transient pool) instead
|
|
543
|
-
* of served from the Path-identity mesh cache — the cache key does not
|
|
544
|
-
* include tolerance. Default: unset — the existing cached behavior at
|
|
545
|
-
* `DEFAULT_FLATTEN_TOLERANCE`. The headless path derives this from the
|
|
546
|
-
* requested output scale; screen callers normally leave it unset. */
|
|
547
|
-
flattenTolerance?: number;
|
|
548
|
-
/** Per-render synchronous bake budget for dynamic canvas-SDF glyphs.
|
|
549
|
-
* Default DEFAULT_BAKE_BUDGET (16). The headless renderSceneToPixels
|
|
550
|
-
* path passes Infinity so print never defers a glyph. */
|
|
551
|
-
bakeBudget?: number;
|
|
552
|
-
/** On-screen glyph size, in CSS pixels, at or above which text renders from
|
|
553
|
-
* tessellated font outlines instead of a distance field — see
|
|
554
|
-
* `OUTLINE_MIN_SCREEN_PX`. Only faces registered with
|
|
555
|
-
* `registerFontOutlines` are affected; everything else keeps its SDF tier
|
|
556
|
-
* whatever this says. Pass `Infinity` to disable the tier outright, or 0
|
|
557
|
-
* to use outlines wherever they exist (what the headless path does, since
|
|
558
|
-
* print has no reason to sample a field it could evaluate exactly). */
|
|
559
|
-
textOutlineMinScreenSize?: number;
|
|
560
|
-
}
|
|
561
|
-
/** Where a renderer draws inside a buffer it does not own.
|
|
562
|
-
*
|
|
563
|
-
* The rect's SIZE is the renderer's own `width`/`height` — `resize()` owns
|
|
564
|
-
* that, and a second copy here could disagree with the one `DrawContext`
|
|
565
|
-
* reports to screen-space layers. */
|
|
566
|
-
interface RenderTarget {
|
|
567
|
-
/** Top-left of this renderer's output within the drawing buffer, in CSS
|
|
568
|
-
* pixels, with the origin at the buffer's top-left. GL's bottom-left origin
|
|
569
|
-
* is handled internally. */
|
|
570
|
-
origin: {
|
|
571
|
-
x: number;
|
|
572
|
-
y: number;
|
|
573
|
-
};
|
|
574
|
-
/** Clear colour and stencil within the rect before drawing. Default true.
|
|
575
|
-
* Pass false only when the caller clears the whole buffer itself on behalf
|
|
576
|
-
* of every co-tenant — a frame that clears neither inherits its neighbour's
|
|
577
|
-
* stencil bits, and even-odd fills then fill their holes. */
|
|
578
|
-
clear?: boolean;
|
|
579
|
-
}
|
|
580
|
-
/**
|
|
581
|
-
* The WebGL2 renderer: takes a list of draw commands and paints them.
|
|
582
|
-
*
|
|
583
|
-
* It knows nothing about the scene — commands are the whole interface, which
|
|
584
|
-
* is what lets layers, HUD widgets and overlays all draw through the same
|
|
585
|
-
* pipeline. GPU resources (meshes, textures, gradient ramps) are cached across
|
|
586
|
-
* frames and keyed by identity, so re-issuing the same command is cheap.
|
|
587
|
-
*/
|
|
588
|
-
declare class WeaselRenderer {
|
|
589
|
-
private readonly gl;
|
|
590
|
-
private pathFill;
|
|
591
|
-
private pathFillVColor;
|
|
592
|
-
private imageFill;
|
|
593
|
-
private batchFill;
|
|
594
|
-
private gradFill;
|
|
595
|
-
private patternFill;
|
|
596
|
-
private meshCache;
|
|
597
|
-
private textureCache;
|
|
598
|
-
private imageCache;
|
|
599
|
-
private gradRamps;
|
|
600
|
-
private programRegistry;
|
|
601
|
-
private quadVbo;
|
|
602
|
-
private quadIbo;
|
|
603
|
-
private drawBatch;
|
|
604
|
-
/** 1x1 white, so a batch flush sampling no image still samples something —
|
|
605
|
-
* see `shaders/batchFill.ts`. */
|
|
606
|
-
private whiteTexture;
|
|
607
|
-
private readonly groupState;
|
|
608
|
-
private widthCss;
|
|
609
|
-
private heightCss;
|
|
610
|
-
private dpr;
|
|
611
|
-
private canvas;
|
|
612
|
-
private target;
|
|
613
|
-
/** Offscreen buffers for group effects. Allocates nothing until a group
|
|
614
|
-
* with effects asks, so a canvas without them pays no memory. */
|
|
615
|
-
private readonly effectTargets;
|
|
616
|
-
private readonly imageMinification;
|
|
617
|
-
private readonly flattenTolerance?;
|
|
618
|
-
private readonly bakeBudget;
|
|
619
|
-
private readonly textOutlineMinScreenSize;
|
|
620
|
-
private contextLost;
|
|
621
|
-
private boundOnLost;
|
|
622
|
-
private boundOnRestored;
|
|
623
|
-
/** True after `dispose()`. A disposed renderer ignores further `render()`
|
|
624
|
-
* calls and `registerProgram()` calls. */
|
|
625
|
-
private disposed;
|
|
626
|
-
constructor(opts: WeaselRendererOptions);
|
|
627
|
-
private uploadQuadGeometry;
|
|
628
|
-
/**
|
|
629
|
-
* Compile a consumer-registered shader program against this renderer's GL context.
|
|
630
|
-
*
|
|
631
|
-
* Call once per renderer after the module-level `registerProgram()`.
|
|
632
|
-
* Throws `ShaderCompileError` if compilation fails.
|
|
633
|
-
*
|
|
634
|
-
* In dev mode, calling again with the same handle replaces the compiled program.
|
|
635
|
-
*
|
|
636
|
-
* @experimental
|
|
637
|
-
*/
|
|
638
|
-
registerProgram(handle: ShaderProgramHandle): void;
|
|
639
|
-
/**
|
|
640
|
-
* The compiled program for `id`, compiling it against this context on first
|
|
641
|
-
* use. Unlike {@link registerProgram} this neither throws on a missing
|
|
642
|
-
* source nor on a compile failure: a paint kind asking for a program it
|
|
643
|
-
* never registered must decline the paint, not take down the frame.
|
|
644
|
-
*/
|
|
645
|
-
private ensureProgram;
|
|
646
|
-
/** The GL state every frame assumes. Applied per `render()` rather than once
|
|
647
|
-
* at construction because a co-tenant sharing this context moves all of it
|
|
648
|
-
* between our frames. */
|
|
649
|
-
private applyGlState;
|
|
650
|
-
/** Viewport and scissor for this frame. Re-applied inside `render()` because
|
|
651
|
-
* a co-tenant on the same context moves both between our frames. */
|
|
652
|
-
private applyTarget;
|
|
653
|
-
/** Confine this renderer to a rect of its drawing buffer, or pass null to
|
|
654
|
-
* give it the whole buffer back. Takes effect from the next `render()`. */
|
|
655
|
-
setTarget(target: RenderTarget | null): void;
|
|
656
|
-
getTarget(): RenderTarget | null;
|
|
657
|
-
isContextLost(): boolean;
|
|
658
|
-
private onContextLost;
|
|
659
|
-
private onContextRestored;
|
|
660
|
-
/** Free the GL resources this renderer itself owns and detach context-loss
|
|
661
|
-
* listeners when a canvas was supplied. Idempotent.
|
|
662
|
-
*
|
|
663
|
-
* Scope: built-in shader programs, any consumer-registered programs, the
|
|
664
|
-
* shared quad/rect geometry, any in-flight transient meshes, and the
|
|
665
|
-
* enumerable Map-keyed caches (`GLTextureCache` atlas/image textures,
|
|
666
|
-
* `GradientRampAtlas`'s ramp texture) ARE freed.
|
|
667
|
-
*
|
|
668
|
-
* NOT freed: `GLImageCache` (bitmap/pattern textures) and `GLMeshCache`'s
|
|
669
|
-
* persistent per-Path mesh cache are keyed by `WeakMap`, not enumerable,
|
|
670
|
-
* and are only reclaimed when the GL context itself goes away (cf.
|
|
671
|
-
* `GLImageCache`'s own "deferred to v2" note). On a caller-owned
|
|
672
|
-
* long-lived context — the headless render-to-pixels path hands the same
|
|
673
|
-
* `gl` to many short-lived renderers — the image/pattern textures and
|
|
674
|
-
* persistent Path meshes each renderer uploads DO accumulate across
|
|
675
|
-
* renderer instances until the caller recycles the context.
|
|
676
|
-
*
|
|
677
|
-
* Also: a Mesh that gets GC'd after `dispose()` still lands in
|
|
678
|
-
* `GLMeshCache`'s `pendingDeletes` queue via its `FinalizationRegistry`,
|
|
679
|
-
* but nothing drains that queue post-dispose (only `render()` does) —
|
|
680
|
-
* those GL resources leak until the context goes away too.
|
|
681
|
-
*
|
|
682
|
-
* A disposed renderer ignores further `render()` and `registerProgram()`
|
|
683
|
-
* calls. */
|
|
684
|
-
dispose(): void;
|
|
685
|
-
/**
|
|
686
|
-
* Draw one frame.
|
|
687
|
-
*
|
|
688
|
-
* `viewMatrix` is the frame's world→screen transform. It is only consulted
|
|
689
|
-
* by `units: 'world'` gradients, which fall back to screen space without
|
|
690
|
-
* it — every other command carries its own transform in the stream, so
|
|
691
|
-
* callers with no view concept can keep calling `render(commands)`.
|
|
692
|
-
*/
|
|
693
|
-
render(commands: DrawCommand[], viewMatrix?: Mat3): void;
|
|
694
|
-
resize(dims: {
|
|
695
|
-
width: number;
|
|
696
|
-
height: number;
|
|
697
|
-
dpr: number;
|
|
698
|
-
}): void;
|
|
699
|
-
/** @internal */ _gl(): WebGL2RenderingContext;
|
|
700
|
-
/** @internal */ _pathFill(): ShaderProgram;
|
|
701
|
-
/** @internal */ _pathFillVColor(): ShaderProgram;
|
|
702
|
-
/** @internal */ _drawBatch(): DrawBatch;
|
|
703
|
-
/** @internal */ _imageFill(): ShaderProgram;
|
|
704
|
-
/** @internal */ _batchFill(): ShaderProgram;
|
|
705
|
-
/** @internal */ _gradFill(): ShaderProgram;
|
|
706
|
-
/** @internal */ _patternFill(): ShaderProgram;
|
|
707
|
-
/** @internal */ _meshCache(): GLMeshCache;
|
|
708
|
-
/** @internal */ _textureCache(): GLTextureCache;
|
|
709
|
-
/** @internal */ _imageCache(): GLImageCache;
|
|
710
|
-
/** @internal */ _gradRamps(): GradientRampAtlas;
|
|
711
|
-
/** @internal */ _groupState(): GroupState;
|
|
712
|
-
/** @internal */ _widthCss(): number;
|
|
713
|
-
/** @internal */ _heightCss(): number;
|
|
714
|
-
/** @internal */ _dpr(): number;
|
|
715
|
-
}
|
|
716
|
-
|
|
717
|
-
/**
|
|
718
|
-
* Uniform-grid sprite sheet layout — frame index to the source rect an
|
|
719
|
-
* `ImageDrawCommand` samples. Pure arithmetic over the grid description; it
|
|
720
|
-
* never touches the bitmap.
|
|
721
|
-
*/
|
|
722
|
-
/** A sprite sheet's grid. `margin` and `spacing` follow the Tiled / Aseprite
|
|
723
|
-
* tileset convention, so a sheet exported from either describes itself here. */
|
|
724
|
-
interface SpriteSheet {
|
|
725
|
-
frameWidth: number;
|
|
726
|
-
frameHeight: number;
|
|
727
|
-
columns: number;
|
|
728
|
-
/** Empty pixels around the whole grid. Default 0. */
|
|
729
|
-
margin?: number;
|
|
730
|
-
/** Empty pixels between adjacent cells — the gutter that keeps linear
|
|
731
|
-
* sampling off the neighboring frame. Default 0. */
|
|
732
|
-
spacing?: number;
|
|
733
|
-
}
|
|
734
|
-
/**
|
|
735
|
-
* Row-major source rect for frame `index`, counting from 0 at the top-left.
|
|
736
|
-
*
|
|
737
|
-
* `index` is not range-checked and does not wrap: past the last cell this
|
|
738
|
-
* returns a rect below the sheet, which draws as an edge smear. Wrapping is
|
|
739
|
-
* the animation's business (`frameRect(sheet, tick % count)`) — a sheet does
|
|
740
|
-
* not know how many of its cells are filled.
|
|
741
|
-
*/
|
|
742
|
-
declare function frameRect(sheet: SpriteSheet, index: number): {
|
|
743
|
-
x: number;
|
|
744
|
-
y: number;
|
|
745
|
-
w: number;
|
|
746
|
-
h: number;
|
|
747
|
-
};
|
|
748
|
-
|
|
749
|
-
/**
|
|
750
|
-
* View → Mat3 helper for layer `draw` implementations on world-space layers.
|
|
751
|
-
*
|
|
752
|
-
* The kit's main package ships a `View` type at
|
|
753
|
-
* `src/core/viewport/view.ts`; we re-declare a structurally compatible
|
|
754
|
-
* shape here to avoid a runtime cross-package import. Exported as
|
|
755
|
-
* `ViewLike` from the package barrel.
|
|
756
|
-
*/
|
|
757
|
-
|
|
758
|
-
/** A weasel View — `{x, y, scale: {x, y}}`. Local type to avoid a cross-package import. */
|
|
759
|
-
interface View {
|
|
760
|
-
x: number;
|
|
761
|
-
y: number;
|
|
762
|
-
scale: {
|
|
763
|
-
x: number;
|
|
764
|
-
y: number;
|
|
765
|
-
};
|
|
766
|
-
}
|
|
767
|
-
/**
|
|
768
|
-
* Build the world→screen transform matrix for a `View`.
|
|
769
|
-
* Use as the `transform` field of a `kind: 'group'` DrawCommand to wrap
|
|
770
|
-
* world-space content emitted from a layer `draw` implementation.
|
|
771
|
-
*
|
|
772
|
-
* Mapping: `screen = (world − {view.x, view.y}) × {view.scale.x, view.scale.y}`.
|
|
773
|
-
*
|
|
774
|
-
* Column-major layout (matches `mat3.identity()`):
|
|
775
|
-
* `[scale.x, 0, 0, 0, scale.y, 0, -view.x*scale.x, -view.y*scale.y, 1]`.
|
|
776
|
-
*/
|
|
777
|
-
declare function viewToMat3(view: View): Mat3;
|
|
778
|
-
|
|
779
|
-
/** Options for stroke tessellation. */
|
|
780
|
-
interface StrokeOptions {
|
|
781
|
-
flattenTolerance?: number;
|
|
782
|
-
/**
|
|
783
|
-
* Shorten each open subpath by this much at its start / end, in the same
|
|
784
|
-
* world units as the path. Stroke markers use this so a filled head is not
|
|
785
|
-
* speared by its own line; the caller resolves the distance, because this
|
|
786
|
-
* layer knows nothing about the marker registry.
|
|
787
|
-
*/
|
|
788
|
-
startInset?: number;
|
|
789
|
-
endInset?: number;
|
|
790
|
-
}
|
|
791
|
-
/** Resolve a stroke width to world units. A number is already world units;
|
|
792
|
-
* `{ px }` is screen pixels divided by the accumulated scale, so it holds its
|
|
793
|
-
* on-screen thickness as the view zooms. */
|
|
794
|
-
declare function resolveStrokeWidth(width: number | {
|
|
795
|
-
px: number;
|
|
796
|
-
}, scale: number): number;
|
|
797
|
-
/**
|
|
798
|
-
* Build a triangle-mesh ribbon from a stroked Path.
|
|
799
|
-
*
|
|
800
|
-
* Supports:
|
|
801
|
-
* - cap: 'butt' | 'round' | 'square'
|
|
802
|
-
* - join: 'miter' | 'round' | 'bevel'
|
|
803
|
-
* - center alignment directly; RectPath inner/outer alignment via a
|
|
804
|
-
* pre-shifted rect; PolygonPath inner/outer alignment via stencil at the
|
|
805
|
-
* renderer level
|
|
806
|
-
* - dash splitting
|
|
807
|
-
*/
|
|
808
|
-
declare function tessellateStroke(path: Path, stroke: Stroke, opts?: StrokeOptions): Mesh;
|
|
809
|
-
|
|
810
|
-
/**
|
|
811
|
-
* Effects that ship with the kit.
|
|
812
|
-
*
|
|
813
|
-
* Each is a function returning `Effect[]`, not a single `Effect`, because a
|
|
814
|
-
* separable kernel is genuinely two passes and hiding that behind one entry
|
|
815
|
-
* would make the cost invisible at the callsite:
|
|
816
|
-
*
|
|
817
|
-
* effects={[...blur({ radius: 4 }), ...vignette({ amount: 0.6 })]}
|
|
818
|
-
*/
|
|
819
|
-
|
|
820
|
-
/**
|
|
821
|
-
* Gaussian blur, as a horizontal pass followed by a vertical one.
|
|
822
|
-
*
|
|
823
|
-
* `radius` is in device pixels and is the distance of the outermost tap, not a
|
|
824
|
-
* standard deviation — 0 is a copy, and the falloff is the same nine-tap
|
|
825
|
-
* kernel at every radius, so a large one is a wide blur rather than a better
|
|
826
|
-
* one. Two passes at O(9) beat one at O(81) and look the same.
|
|
827
|
-
*/
|
|
828
|
-
declare function blur({ radius }: {
|
|
829
|
-
radius: number;
|
|
830
|
-
}): Effect[];
|
|
831
|
-
/**
|
|
832
|
-
* Darken toward the corners. `amount` is how dark the corner gets (0..1) and
|
|
833
|
-
* `feather` how much of the radius the falloff occupies.
|
|
834
|
-
*/
|
|
835
|
-
declare function vignette({ amount, feather }: {
|
|
836
|
-
amount: number;
|
|
837
|
-
feather?: number;
|
|
838
|
-
}): Effect[];
|
|
839
|
-
|
|
840
|
-
export { IDENTITY_COLOR_MATRIX as I, type Mesh as M, type RenderTarget as R, ShaderCompileError as S, type View as V, WeaselRenderer as W, type ImageMinification as a, type SpriteSheet as b, type StrokeOptions as c, type WeaselRendererOptions as d, blur as e, buildGradientRamp as f, frameRect as g, vignette as h, ShaderProgram as i, resolveStrokeWidth as r, tessellateStroke as t, viewToMat3 as v };
|