@godot-scene-web/canvas 0.1.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.
@@ -0,0 +1,882 @@
1
+ import { ColorMatrix } from "@godot-scene-web/core";
2
+
3
+ //#region src/damage.d.ts
4
+ /** A top-left-origin, axis-aligned rectangle. It is used in design or backing
5
+ * pixel space; the caller decides which, and {@link transformDamageRect} moves
6
+ * between them conservatively. */
7
+ interface DamageRect {
8
+ x: number;
9
+ y: number;
10
+ width: number;
11
+ height: number;
12
+ }
13
+ /** Public retained-rendering vocabulary for a rectangle that needs repainting. */
14
+ type DirtyRect = DamageRect;
15
+ /** A conservative rectangle reported by one draw command when its extent is
16
+ * known. `commandDamageBounds` returns `null` for a full/direct fallback. */
17
+ type CommandBounds = DamageRect;
18
+ /** A tile selected by {@link DamageTiles}. */
19
+ interface DamageTile extends DamageRect {
20
+ column: number;
21
+ row: number;
22
+ }
23
+ /** A tile accumulator for retaining a backing surface without retaining an
24
+ * unbounded list of tiny invalidations. */
25
+ interface DamageTiles {
26
+ readonly width: number;
27
+ readonly height: number;
28
+ /** Physical backing pixels in one tile. Retained callers use 64×64 tiles. */
29
+ readonly tileWidth: number;
30
+ readonly tileHeight: number;
31
+ readonly columns: number;
32
+ readonly rows: number;
33
+ readonly tileCount: number;
34
+ readonly dirtyCount: number;
35
+ /** `dirtyCount / tileCount`, or zero for an empty surface. */
36
+ readonly coverage: number;
37
+ readonly dirty: boolean;
38
+ resize(width: number, height: number): void;
39
+ mark(rect: DamageRect | null): void;
40
+ clear(): void;
41
+ /** The exact backing-pixel tiles currently marked, in paint order. */
42
+ tiles(): readonly DamageTile[];
43
+ /**
44
+ * Visit marked tiles without materialising `DamageTile` objects. The same
45
+ * mutable tile view is passed each time, so read it synchronously and do not
46
+ * retain it. This is the retained-frame hot path; `tiles()` is only a
47
+ * diagnostics convenience.
48
+ */
49
+ forEach(callback: (tile: DamageTile) => void): void;
50
+ /**
51
+ * Visit an exact, non-overlapping rectangular cover of the marked tiles.
52
+ * Horizontally adjacent tiles are joined, then identical row runs are joined
53
+ * vertically. No clean pixel is included, so each region is safe to pass to
54
+ * a scissored retained replay independently. As with {@link forEach}, the
55
+ * rectangle is a reusable mutable view and must not be retained.
56
+ */
57
+ forEachRegion(callback: (region: DamageRect) => void): void;
58
+ /** Return the marked tiles and clear the accumulator. */
59
+ consume(): readonly DamageTile[];
60
+ }
61
+ /** Retained replay uses fixed physical-pixel tiles, never CSS pixels. */
62
+ declare const RETAINED_DAMAGE_TILE_SIZE = 64;
63
+ /** The largest tile coverage that is worth planning for retained replay. */
64
+ declare const RETAINED_MAX_DAMAGE_COVERAGE = 0.2;
65
+ /** A `Transform2D` mapping the rect's coordinates into another top-left space. */
66
+ type DamageTransform = ArrayLike<number>;
67
+ declare function createDamageRect(): DamageRect;
68
+ declare function isDamageEmpty(rect: DamageRect): boolean;
69
+ /** Expand in the rectangle's own coordinate space without mutating inputs. */
70
+ declare function outsetDamageRect(rect: DamageRect, outset: number, out?: DamageRect): DamageRect | null;
71
+ /** True when two half-open rectangles overlap. Touching edges do not repaint. */
72
+ declare function damageIntersects(a: DamageRect, b: DamageRect): boolean;
73
+ /** Expand `out` to cover both input rectangles. */
74
+ declare function unionDamageRect(a: DamageRect, b: DamageRect, out?: DamageRect): DamageRect;
75
+ /** Transform all four corners, returning the enclosing axis-aligned rectangle. */
76
+ declare function transformDamageRect(rect: DamageRect, transform: DamageTransform, out?: DamageRect): DamageRect;
77
+ /**
78
+ * Compute a conservative visual bound for one command. `null` means unknown,
79
+ * which callers must treat as intersecting every damage region. Glyphs are
80
+ * known only when their producer supplied explicit local ink bounds; guessing
81
+ * from pen positions or em size could leave stale ink on a retained surface.
82
+ */
83
+ declare function commandDamageBounds<TTexture>(list: DrawList<TTexture>, index: number, out?: DamageRect): CommandBounds | null;
84
+ declare function createDamageTiles(width: number, height: number, tileWidth?: number, tileHeight?: number): DamageTiles;
85
+ //#endregion
86
+ //#region src/draw-list.d.ts
87
+ /**
88
+ * The draw-list IR for a Godot 2D scene: a flat, ordered recording of what one
89
+ * frame paints, produced by walking `CanvasItem`s in draw order and consumed by
90
+ * a GPU executor (a later wave). It is deliberately dumb — no scene concepts, no
91
+ * nodes, no styles, just quads, indexed textured meshes, nine-patches,
92
+ * polylines and clip pushes/pops in
93
+ * the order they must hit the framebuffer.
94
+ *
95
+ * Storage is a set of pooled parallel typed arrays, not an array of command
96
+ * objects:
97
+ *
98
+ * - `kinds` / `floatOffsets` / `intOffsets` are one entry per command,
99
+ * - `floats` and `ints` are arenas that every command's numeric payload is
100
+ * appended into (a quad writes 16 floats + 3 ints, a polyline writes a
101
+ * 5-float header plus 2 floats per point, …),
102
+ * - `colorMatrices` is a side arena for the rare 3x3 color transform,
103
+ * - `textures` is the ONLY object side-array — a texture handle cannot live in
104
+ * a typed array.
105
+ *
106
+ * That layout exists so a frame costs zero garbage: `reset()` rewinds the write
107
+ * cursors and the same buffers are refilled next frame, and reading a command
108
+ * back fills a caller-owned view instead of allocating one. Arrays grow on
109
+ * demand (capacity doubling) and never shrink.
110
+ *
111
+ * All geometry is in DESIGN space (the scene's own coordinate system); mapping
112
+ * design space to device pixels is the executor's job.
113
+ */
114
+ /** A textured/solid rectangle: the workhorse command. */
115
+ declare const DRAW_QUAD = 0;
116
+ /** A 9-sliced rectangle; the executor expands it to up to 9 quads. */
117
+ declare const DRAW_NINE_PATCH = 1;
118
+ /** A flattened, constant-width line strip. */
119
+ declare const DRAW_POLYLINE = 2;
120
+ /** Push a scissor/clip rect; every later command is clipped until the pop. */
121
+ declare const DRAW_CLIP_PUSH = 3;
122
+ /** Pop the most recent clip rect. */
123
+ declare const DRAW_CLIP_POP = 4;
124
+ /**
125
+ * A run of glyphs from one face, at one size, in one colour.
126
+ *
127
+ * The ONLY command that is not reducible to a textured quad, which is why it
128
+ * exists as its own kind rather than as sugar over `pushQuad`. Its glyphs are
129
+ * outlines evaluated per fragment (see `@godot-scene-web/hb-gpu`), so they carry
130
+ * an atlas slot id instead of a source rect and stay crisp under rotation and
131
+ * scale — the whole reason for the kind. An executor with no glyph pass
132
+ * installed skips it.
133
+ */
134
+ declare const DRAW_GLYPHS = 5;
135
+ /** An arbitrary triangle list with one texture and per-mesh premultiplied tint. */
136
+ declare const DRAW_TEXTURED_MESH = 6;
137
+ /** A screen-dependent pass executed at this exact painter position. */
138
+ declare const DRAW_SCREEN_EFFECT = 7;
139
+ /** A caller-owned GPU pass executed directly into the current framebuffer. */
140
+ declare const DRAW_EXTERNAL_EFFECT = 8;
141
+ interface ScreenEffectDrawContext {
142
+ readonly gl: WebGL2RenderingContext;
143
+ readonly framebuffer: WebGLFramebuffer | null;
144
+ readonly width: number;
145
+ readonly height: number;
146
+ readonly damage?: DamageRect;
147
+ readonly scissor: Readonly<{
148
+ x: number;
149
+ y: number;
150
+ width: number;
151
+ height: number;
152
+ }>;
153
+ }
154
+ /**
155
+ * The live painter target handed to an external pass. Unlike a screen effect,
156
+ * this pass does not imply a snapshot or read from the accumulated framebuffer.
157
+ */
158
+ interface ExternalEffectDrawContext {
159
+ readonly gl: WebGL2RenderingContext;
160
+ readonly framebuffer: WebGLFramebuffer | null;
161
+ readonly width: number;
162
+ readonly height: number;
163
+ readonly damage?: DamageRect;
164
+ readonly scissor: Readonly<{
165
+ x: number;
166
+ y: number;
167
+ width: number;
168
+ height: number;
169
+ }>;
170
+ }
171
+ /** A DOM-free pass that snapshots the executor's accumulated current target. */
172
+ interface ScreenEffectDrawCommand {
173
+ readonly screenDependent: true;
174
+ execute(context: ScreenEffectDrawContext): boolean;
175
+ }
176
+ /** A DOM-free pass that paints directly into the executor's current target. */
177
+ interface ExternalEffectDrawCommand {
178
+ execute(context: ExternalEffectDrawContext): boolean;
179
+ }
180
+ type DrawCommandKind = typeof DRAW_QUAD | typeof DRAW_NINE_PATCH | typeof DRAW_POLYLINE | typeof DRAW_CLIP_PUSH | typeof DRAW_CLIP_POP | typeof DRAW_GLYPHS | typeof DRAW_TEXTURED_MESH | typeof DRAW_SCREEN_EFFECT | typeof DRAW_EXTERNAL_EFFECT;
181
+ type DrawCommandName = "quad" | "ninePatch" | "polyline" | "clipPush" | "clipPop" | "glyphs" | "texturedMesh" | "screenEffect" | "externalEffect";
182
+ /** Indexed by {@link DrawCommandKind}; for debugging and test assertions. */
183
+ declare const DRAW_COMMAND_NAMES: readonly DrawCommandName[];
184
+ /** Godot `CanvasItemMaterial.BLEND_MODE_MIX`: normal alpha compositing. */
185
+ declare const BLEND_MIX = 0;
186
+ /** Godot `BLEND_MODE_ADD`. */
187
+ declare const BLEND_ADD = 1;
188
+ /** Godot `BLEND_MODE_SUB`. */
189
+ declare const BLEND_SUB = 2;
190
+ /** Godot `BLEND_MODE_MUL`. */
191
+ declare const BLEND_MUL = 3;
192
+ type BlendMode = typeof BLEND_MIX | typeof BLEND_ADD | typeof BLEND_SUB | typeof BLEND_MUL;
193
+ /** Bit in a command's packed flags int: mirror the source rect horizontally. */
194
+ declare const FLIP_H = 1;
195
+ /** Bit in a command's packed flags int: mirror the source rect vertically. */
196
+ declare const FLIP_V = 2;
197
+ /**
198
+ * A quad's numeric payload. Views are caller-owned and reusable: fill one and
199
+ * hand it to `pushQuad`, or pass one to `readQuad` to have it filled in place.
200
+ * Nothing here is retained by the list — the push copies into the arenas.
201
+ */
202
+ interface QuadView {
203
+ /**
204
+ * The 2x3 affine that maps the unit-ish quad into design space, in Godot
205
+ * `Transform2D` order: `[xx, xy, yx, yy, originX, originY]`, i.e.
206
+ * `x' = xx*x + yx*y + originX`, `y' = xy*x + yy*y + originY`. Length 6.
207
+ */
208
+ m: Float32Array;
209
+ /** Destination width in design units, before `m` is applied. */
210
+ w: number;
211
+ /** Destination height in design units, before `m` is applied. */
212
+ h: number;
213
+ /** Source rect on the texture page, in page pixels (not normalized). */
214
+ srcX: number;
215
+ srcY: number;
216
+ srcW: number;
217
+ srcH: number;
218
+ /** PREMULTIPLIED tint, linear 0..1 per channel (`rgb` already times `a`). */
219
+ r: number;
220
+ g: number;
221
+ b: number;
222
+ a: number;
223
+ blend: BlendMode;
224
+ flipH: boolean;
225
+ flipV: boolean;
226
+ /**
227
+ * Whether {@link QuadView.colorMatrix} is meaningful. Most quads carry no
228
+ * color transform at all (the field is the IR's "null"), so the matrix is
229
+ * stored in a side arena and skipped entirely when this is `false`.
230
+ */
231
+ hasColorMatrix: boolean;
232
+ /**
233
+ * Row-major 3x3 linear RGB transform (`out_rgb = m * in_rgb`, alpha
234
+ * untouched) — an HSV-style shader tint. Length 9. Ignored unless
235
+ * `hasColorMatrix`.
236
+ */
237
+ colorMatrix: Float32Array;
238
+ }
239
+ /**
240
+ * A nine-patch's payload: a quad plus the four stretch margins. `srcX..srcH` is
241
+ * the patch REGION on the page; the margins are insets into that region, in
242
+ * page pixels, exactly like Godot's `NinePatchRect.patch_margin_*`.
243
+ */
244
+ interface NinePatchView extends QuadView {
245
+ marginLeft: number;
246
+ marginTop: number;
247
+ marginRight: number;
248
+ marginBottom: number;
249
+ }
250
+ /** A polyline's payload: a flattened `x, y, x, y, …` strip with one width. */
251
+ interface PolylineView {
252
+ /**
253
+ * Flattened point coordinates in design space. Length is at least
254
+ * `pointCount * 2`; a longer buffer is allowed (and expected, since views are
255
+ * reused), only the first `pointCount * 2` entries are read.
256
+ */
257
+ points: Float32Array;
258
+ pointCount: number;
259
+ /** Stroke width in design units. */
260
+ width: number;
261
+ /** PREMULTIPLIED stroke color, linear 0..1 per channel. */
262
+ r: number;
263
+ g: number;
264
+ b: number;
265
+ a: number;
266
+ }
267
+ /**
268
+ * An indexed triangle list sampling one texture. Positions and UVs are paired
269
+ * by vertex index; positions are local design-space coordinates and `m` maps
270
+ * them to design space. UVs are normalized texture coordinates, intentionally
271
+ * not a quad source rect: arbitrary mesh topology must not be forced through a
272
+ * rectangle-shaped source contract.
273
+ */
274
+ interface TexturedMeshView {
275
+ /** Godot `Transform2D` mapping local vertex positions into design space. */
276
+ m: Float32Array;
277
+ /** Flattened local `x, y` pairs. Only `vertexCount * 2` entries are read. */
278
+ positions: Float32Array;
279
+ /** Flattened normalized `u, v` pairs, one pair for every position. */
280
+ uvs: Float32Array;
281
+ vertexCount: number;
282
+ /** Triangle-list vertex indices. Only `indexCount` entries are read. */
283
+ indices: Uint32Array;
284
+ indexCount: number;
285
+ /** PREMULTIPLIED mesh tint, linear 0..1 per channel. */
286
+ r: number;
287
+ g: number;
288
+ b: number;
289
+ a: number;
290
+ blend: BlendMode;
291
+ }
292
+ /**
293
+ * A glyph run's payload: one face, one size, one colour, N positioned glyphs.
294
+ *
295
+ * THE SLOT IDS ARE HANDLES, NOT ADDRESSES, and that distinction is the whole
296
+ * point of the indirection. A glyph atlas evicts — it is a fixed texture holding
297
+ * an unbounded pool — so recording a glyph's atlas OFFSET into a list that may be
298
+ * retained and repainted next frame is how you get a different glyph's outline
299
+ * drawn at the right size, in the right place, perfectly antialiased. Unreadable
300
+ * text that looks like working text. A slot id survives eviction because the
301
+ * atlas re-resolves it (re-uploading the outline if it has to) at draw time.
302
+ *
303
+ * Shaping is NOT this package's job. `positions` are pen positions a shaper
304
+ * produced; the list only records them.
305
+ */
306
+ interface GlyphsView {
307
+ /**
308
+ * The 2x3 affine that maps the run's local space into design space, in the
309
+ * same Godot `Transform2D` order as {@link QuadView.m}. Length 6.
310
+ *
311
+ * ROTATION BELONGS HERE, NEVER IN `positions`. The glyph shader dilates each
312
+ * outline by half a SCREEN pixel and works out how far that is by pushing the
313
+ * quad's corner and its normal through this same matrix. Pen positions rotated
314
+ * on the CPU would be dilated along the wrong axes — a rim of clipped
315
+ * antialiasing on one side of every glyph.
316
+ */
317
+ m: Float32Array;
318
+ /**
319
+ * Design units per em: the font size in the run's local space.
320
+ *
321
+ * The rendered outline is resolution-independent, but its ANTIALIASING is not
322
+ * unconditionally so: HarfBuzz's coverage shader takes a five-tap branch below
323
+ * ppem 16, and measured against an 8x-downsampled reference that branch is
324
+ * blurrier than a baked atlas at the same size. The ppem that matters is this
325
+ * times the scale in {@link GlyphsView.m} times the device-pixel ratio: a
326
+ * caller's zoom rides the matrix, and the shader sees it — see
327
+ * `docs/text-rendering.md`.
328
+ */
329
+ pixelsPerEm: number;
330
+ /** PREMULTIPLIED colour, linear 0..1 per channel, for the whole run. */
331
+ r: number;
332
+ g: number;
333
+ b: number;
334
+ a: number;
335
+ /**
336
+ * One atlas slot id per glyph. Length is at least {@link GlyphsView.glyphCount}
337
+ * — a longer buffer is allowed and expected, since views are reused.
338
+ */
339
+ slots: Int32Array;
340
+ /**
341
+ * Pen positions, flattened `x, y, x, y, …`, in the run's local space and
342
+ * BEFORE `m` is applied. Each is the glyph's em origin, i.e. a point on the
343
+ * baseline. Length is at least `glyphCount * 2`.
344
+ */
345
+ positions: Float32Array;
346
+ glyphCount: number;
347
+ /**
348
+ * Grow every glyph outward by this many design units before filling. `0` (the
349
+ * default) is a plain fill.
350
+ *
351
+ * AN OUTLINED LABEL IS TWO RUNS, NOT ONE: the same glyphs and pens in the
352
+ * outline colour with a spread, then again in the fill colour with none. This
353
+ * kind carries one colour and one spread by design — merging them would need
354
+ * two draw calls behind one command and would hide the ordering, which is the
355
+ * part a caller has to get right (outline UNDER fill).
356
+ *
357
+ * A CENTRED `strokeText` OF WIDTH `W` REACHES `W / 2` OUTWARD, so a caller
358
+ * matching one records `W / 2`. The arithmetic is the caller's: only it knows
359
+ * whether the stroke it is reproducing is centred, inner or outer.
360
+ *
361
+ * THE DILATION FILLS THE INTERIOR AND A STROKE DOES NOT. Identical under an
362
+ * opaque fill, which covers every pixel the two disagree about; visibly
363
+ * different under a TRANSLUCENT one, where the outline colour shows through
364
+ * the glyph's middle. Stated because it is a real limit of a coverage-max
365
+ * dilation rather than a rounding difference — see `HbGpuRenderer.setSpread`.
366
+ */
367
+ spreadPx: number;
368
+ /**
369
+ * The exact local-space rectangle containing the run's unspread glyph ink.
370
+ *
371
+ * These are optional for source compatibility with older producers. Omitting
372
+ * any one is deliberately an UNKNOWN bound, never an em-box estimate: a
373
+ * retained surface must repaint fully rather than leave stale text behind.
374
+ */
375
+ localInkX?: number;
376
+ localInkY?: number;
377
+ localInkWidth?: number;
378
+ localInkHeight?: number;
379
+ /** Additional local-space reach for effects and antialiasing. The draw list
380
+ * also adds its own `spreadPx`, so this is for reach beyond the unspread
381
+ * outline (for example a shadow or caller-measured coverage fringe). */
382
+ localInkOutset?: number;
383
+ }
384
+ /** A clip push's payload. */
385
+ interface ClipRectView {
386
+ /** Clip rect in design space. */
387
+ x: number;
388
+ y: number;
389
+ w: number;
390
+ h: number;
391
+ /**
392
+ * Corner radius in design units; `0` (the common case) is a plain rect and
393
+ * lets the executor use a cheap scissor instead of a mask.
394
+ */
395
+ cornerRadius: number;
396
+ /**
397
+ * One-axis slack: widen the rect by `outsetX` on BOTH x edges, i.e. clip to
398
+ * `[x - outsetX, x + w + outsetX]` while `y`/`h` stay exact. `0` (the common
399
+ * case) clips to the rect itself. This exists because a re-laid-out scene can
400
+ * legitimately paint slightly wider than the clip that Godot recorded, and
401
+ * only ever on x.
402
+ */
403
+ outsetX: number;
404
+ }
405
+ interface DrawListOptions {
406
+ /** Initial command capacity (entries, not bytes). Grows on demand. */
407
+ commandCapacity?: number;
408
+ /** Initial float-arena capacity. Grows on demand. */
409
+ floatCapacity?: number;
410
+ /** Initial int-arena capacity. Grows on demand. */
411
+ intCapacity?: number;
412
+ /** Initial color-matrix capacity, in matrices. Grows on demand. */
413
+ colorMatrixCapacity?: number;
414
+ /** Retained in-place patch records for compiled consumers. */
415
+ patchJournalCapacity?: number;
416
+ }
417
+ /** Caller-owned, grow-only output for {@link DrawList.readPatchesSince}. */
418
+ interface DrawListPatchView {
419
+ readonly indices: readonly number[];
420
+ readonly revision: number;
421
+ readonly overflowed: boolean;
422
+ }
423
+ /**
424
+ * A reusable, DOM- and GPU-ownership-free copy of a contiguous draw-list
425
+ * range. A fragment owns its arena bytes and command references, so it remains
426
+ * valid when the list it was captured from is reset, grows, or patched.
427
+ *
428
+ * Fragments deliberately retain texture and effect *references* rather than
429
+ * attempting to clone them: those handles are executor-owned identities, not
430
+ * draw-list data. Capturing and appending only copies the ordering and payload
431
+ * that names them.
432
+ */
433
+ interface DrawListFragment<TTexture = unknown> {
434
+ /** Number of commands in the captured half-open source range. */
435
+ readonly count: number;
436
+ /** Always zero for a valid standalone fragment. */
437
+ readonly clipDepth: number;
438
+ /** Deepest clip nesting within the captured range. */
439
+ readonly maxClipDepth: number;
440
+ /** Forget the captured range but retain all backing storage for reuse. */
441
+ reset(): void;
442
+ /**
443
+ * Clone `[start, end)` from `source` into this fragment. The range must be
444
+ * independently clip-balanced; an unmatched pop or push is rejected rather
445
+ * than producing a fragment whose replay depends on hidden painter state.
446
+ */
447
+ capture(source: DrawList<TTexture>, start: number, end?: number): void;
448
+ }
449
+ /** One same-shaped retained-fragment replacement in a draw list. */
450
+ interface DrawListFragmentPatch<TTexture = unknown> {
451
+ /** First destination command index. Patches are supplied in painter order. */
452
+ readonly start: number;
453
+ /** Replacement command payloads, captured through createDrawListFragment. */
454
+ readonly fragment: DrawListFragment<TTexture>;
455
+ }
456
+ declare function createDrawListPatchView(capacity?: number): DrawListPatchView;
457
+ /**
458
+ * An ordered, poolable recording of one frame's draws.
459
+ *
460
+ * `TTexture` is whatever the executor's texture handle is (a `WebGLTexture`, a
461
+ * `GPUTexture`, an atlas page id, …); the list only stores and returns it.
462
+ */
463
+ interface DrawList<TTexture = unknown> {
464
+ /** Number of commands recorded since the last `reset()`. */
465
+ readonly count: number;
466
+ /** Clip pushes that are currently open (0 at a balanced end of frame). */
467
+ readonly clipDepth: number;
468
+ /** Deepest clip nesting seen since `reset()` — sizes an executor's stack. */
469
+ readonly maxClipDepth: number;
470
+ /** Changes when commands are appended, removed, or their layout changes. */
471
+ readonly structuralRevision: number;
472
+ /** Changes for every structural or in-place command patch. */
473
+ readonly contentRevision: number;
474
+ /** Per-command patch generation, for retained compiled consumers. */
475
+ commandRevisionAt(index: number): number;
476
+ /** Fill reusable `out` with patches after `revision`; overflow means rebuild. */
477
+ readPatchesSince(revision: number, out: DrawListPatchView): DrawListPatchView;
478
+ /**
479
+ * The float arena. The identity of this array CHANGES when it grows, so an
480
+ * executor must re-read it (never cache it across pushes).
481
+ */
482
+ readonly floats: Float32Array;
483
+ /** The int arena. Same growth caveat as {@link DrawList.floats}. */
484
+ readonly ints: Int32Array;
485
+ /** The color-matrix arena, 9 floats per entry. Same growth caveat. */
486
+ readonly colorMatrices: Float32Array;
487
+ /** Rewind to an empty list, keeping (and reusing) the buffers. */
488
+ reset(): void;
489
+ /**
490
+ * Append a previously captured fragment in painter order and return the
491
+ * first destination command index. Empty fragments return `count` and do
492
+ * not change revisions.
493
+ */
494
+ appendFragment(fragment: DrawListFragment<TTexture>): number;
495
+ /**
496
+ * Atomically overwrite a same-shaped recorded range from a retained
497
+ * fragment. The fragment must fit at `start` and every command must retain
498
+ * its kind, numeric payload lengths, object-side payload shape, clip
499
+ * sequence, and colour-matrix presence. A mismatch leaves this list wholly
500
+ * unchanged and returns `false`; successful overwrites preserve command
501
+ * indices and structural revision while publishing ordinary content patches.
502
+ *
503
+ * An empty fragment is a successful no-op at any insertion index from `0`
504
+ * through `count`.
505
+ */
506
+ patchFragment(start: number, fragment: DrawListFragment<TTexture>): boolean;
507
+ /**
508
+ * Atomically apply non-overlapping same-shaped fragments in painter order.
509
+ * Every range is validated before any payload, reference, revision, or patch
510
+ * journal entry changes. Starts must be nondecreasing and non-empty ranges
511
+ * must not overlap.
512
+ */
513
+ patchFragments(patches: readonly DrawListFragmentPatch<TTexture>[]): boolean;
514
+ kindAt(index: number): DrawCommandKind;
515
+ kindNameAt(index: number): DrawCommandName;
516
+ /** The command's texture handle, or `null` for untextured/geometry commands. */
517
+ textureAt(index: number): TTexture | null;
518
+ /** Screen-dependent pass recorded at index, if this is one. */
519
+ screenEffectAt(index: number): ScreenEffectDrawCommand | null;
520
+ /** Direct framebuffer pass recorded at index, if this is one. */
521
+ externalEffectAt(index: number): ExternalEffectDrawCommand | null;
522
+ /** Start of the command's payload in {@link DrawList.floats}. */
523
+ floatOffsetAt(index: number): number;
524
+ /** Start of the command's payload in {@link DrawList.ints}. */
525
+ intOffsetAt(index: number): number;
526
+ /**
527
+ * Index of the command's color matrix in {@link DrawList.colorMatrices}
528
+ * (multiply by 9 for the float offset), or `-1` when it has none.
529
+ */
530
+ colorMatrixIndexAt(index: number): number;
531
+ /** Record a quad. Returns the command index. */
532
+ pushQuad(quad: QuadView, texture?: TTexture | null): number;
533
+ /** Record a nine-patch. Returns the command index. */
534
+ pushNinePatch(patch: NinePatchView, texture?: TTexture | null): number;
535
+ /** Record a polyline. Returns the command index. */
536
+ pushPolyline(line: PolylineView): number;
537
+ /** Record an indexed textured triangle mesh. Returns the command index. */
538
+ pushTexturedMesh(mesh: TexturedMeshView, texture?: TTexture | null): number;
539
+ /** Record a glyph run. Returns the command index. */
540
+ pushGlyphs(run: GlyphsView): number;
541
+ /** Record a pass that samples the accumulated framebuffer at this painter index. */
542
+ pushScreenEffect(command: ScreenEffectDrawCommand): number;
543
+ /** Record a direct framebuffer pass at this painter position. */
544
+ pushExternalEffect(command: ExternalEffectDrawCommand): number;
545
+ /** Open a clip rect. Returns the command index. */
546
+ pushClipRect(clip: ClipRectView): number;
547
+ /** Close the innermost clip rect. Returns the command index. */
548
+ popClip(): number;
549
+ /** Fill `out` from a `quad` command and return it. */
550
+ readQuad(index: number, out: QuadView): QuadView;
551
+ /** Fill `out` from a `ninePatch` command and return it. */
552
+ readNinePatch(index: number, out: NinePatchView): NinePatchView;
553
+ /**
554
+ * Fill `out` from a `polyline` command and return it. `out.points` is
555
+ * REPLACED by a larger buffer if it cannot hold the recorded points.
556
+ */
557
+ readPolyline(index: number, out: PolylineView): PolylineView;
558
+ /** Fill `out` from a textured mesh, growing its caller-owned arrays if needed. */
559
+ readTexturedMesh(index: number, out: TexturedMeshView): TexturedMeshView;
560
+ /**
561
+ * Fill `out` from a `glyphs` command and return it. `out.slots` and
562
+ * `out.positions` are REPLACED by larger buffers if they cannot hold the run.
563
+ */
564
+ readGlyphs(index: number, out: GlyphsView): GlyphsView;
565
+ /** Fill `out` from a `clipPush` command and return it. */
566
+ readClipRect(index: number, out: ClipRectView): ClipRectView;
567
+ /**
568
+ * Overwrite a recorded quad's transform IN PLACE, leaving the rest of its
569
+ * payload — size, source rect, colour, blend, flip flags, colour matrix —
570
+ * exactly as it was pushed.
571
+ *
572
+ * This exists for consumers that rebuild a whole frame today only because one
573
+ * node moved: they can keep last frame's list and repaint it, which is the
574
+ * point of a list that owns its storage. `m` is read in the same
575
+ * `Transform2D` order as {@link QuadView.m} and only its first 6 entries are
576
+ * used.
577
+ *
578
+ * PATCH THROUGH THIS METHOD, NEVER THROUGH A CACHED `floats`. The arenas are
579
+ * reallocated when they grow (see {@link DrawList.floats}), so a Float32Array
580
+ * captured before a `push` may be a DEAD copy — writing into it changes
581
+ * nothing that will be drawn, silently. The method re-reads the live arena on
582
+ * every call.
583
+ *
584
+ * Accepts `quad` and `ninePatch` commands (a nine-patch's payload IS a quad
585
+ * payload plus margins); anything else throws.
586
+ */
587
+ patchQuadTransform(index: number, m: ArrayLike<number>): void;
588
+ /**
589
+ * Overwrite a recorded quad's PREMULTIPLIED tint in place, leaving geometry,
590
+ * source rect, blend, flip flags and colour matrix alone.
591
+ *
592
+ * `rgb` must already be multiplied by `a`, exactly as {@link QuadView} states
593
+ * — this is a raw write into the arena, not a colour operation, so nothing
594
+ * here will premultiply on the caller's behalf.
595
+ *
596
+ * The same cached-arena hazard as {@link DrawList.patchQuadTransform}
597
+ * applies, and the same two kinds are accepted.
598
+ */
599
+ patchQuadColor(index: number, r: number, g: number, b: number, a: number): void;
600
+ /**
601
+ * Replace a quad-like command's texture and source rectangle without touching
602
+ * its destination geometry, tint, blend state, flags or colour matrix.
603
+ *
604
+ * Like the other patch methods this re-reads the current arenas. In
605
+ * particular, callers must not write source coordinates through a cached
606
+ * `floats` view: a later push may have grown that arena and made the cached
607
+ * view a detached copy.
608
+ */
609
+ patchQuadSource(index: number, texture: TTexture | null, srcX: number, srcY: number, srcW: number, srcH: number): void;
610
+ /** Replace the local positions of a mesh without changing its topology. */
611
+ patchTexturedMeshPositions(index: number, positions: Float32Array): void;
612
+ /** Replace the normalized UV pairs of a mesh without changing its topology. */
613
+ patchTexturedMeshUvs(index: number, uvs: Float32Array): void;
614
+ /** Replace a mesh's texture handle without changing geometry or UVs. */
615
+ patchTexturedMeshSource(index: number, texture: TTexture | null): void;
616
+ /** Replace a mesh's local-to-design transform. */
617
+ patchTexturedMeshTransform(index: number, m: ArrayLike<number>): void;
618
+ /** Replace a mesh's premultiplied tint. */
619
+ patchTexturedMeshColor(index: number, r: number, g: number, b: number, a: number): void;
620
+ /**
621
+ * Overwrite a recorded glyph run's transform in place, leaving its glyphs,
622
+ * size and colour alone.
623
+ *
624
+ * The counterpart of {@link DrawList.patchQuadTransform}, and the reason the
625
+ * glyph kind stores a transform at all instead of pre-transformed pen
626
+ * positions: a label that translates every frame re-records nothing, and the
627
+ * shader still sees the whole transform (which is what keeps its half-pixel
628
+ * dilation on the right axes). The same cached-arena hazard applies — patch
629
+ * through this method, never through a captured `floats`.
630
+ */
631
+ patchGlyphsTransform(index: number, m: ArrayLike<number>): void;
632
+ /**
633
+ * Overwrite a recorded glyph run's PREMULTIPLIED colour in place. `rgb` must
634
+ * already be multiplied by `a`, exactly as {@link GlyphsView} states.
635
+ */
636
+ patchGlyphsColor(index: number, r: number, g: number, b: number, a: number): void;
637
+ }
638
+ /** A fresh quad view: identity transform, opaque white, mix blend, no matrix. */
639
+ declare function createQuadView(): QuadView;
640
+ /** A fresh nine-patch view: a quad view with zero margins. */
641
+ declare function createNinePatchView(): NinePatchView;
642
+ /** A fresh polyline view with room for `pointCapacity` points. */
643
+ declare function createPolylineView(pointCapacity?: number): PolylineView;
644
+ /** A reusable textured mesh view with room for the requested topology. */
645
+ declare function createTexturedMeshView(vertexCapacity?: number, indexCapacity?: number): TexturedMeshView;
646
+ /** A fresh glyph-run view with room for `glyphCapacity` glyphs. */
647
+ declare function createGlyphsView(glyphCapacity?: number): GlyphsView;
648
+ /** A fresh clip-rect view: empty rect, square corners, no outset. */
649
+ declare function createClipRectView(): ClipRectView;
650
+ /**
651
+ * Copy an `html` {@link ColorMatrix} into a quad/nine-patch view and arm it.
652
+ * Passing `null` disarms the view's matrix (leaving its contents alone), which
653
+ * is the shape most callers have: a computed transform that is usually absent.
654
+ */
655
+ declare function setViewColorMatrix(view: QuadView, matrix: ColorMatrix | null | undefined): void;
656
+ /**
657
+ * Create reusable storage for a retained command fragment. The fragment holds
658
+ * only draw-list data and opaque caller references; it never creates or owns a
659
+ * DOM node, a WebGL object, or an executor.
660
+ */
661
+ declare function createDrawListFragment<TTexture = unknown>(options?: DrawListOptions): DrawListFragment<TTexture>;
662
+ /**
663
+ * Create an empty draw list. Capacities are only a starting point; every arena
664
+ * grows on demand, so a list settles at the high-water mark of the frames it
665
+ * has recorded and then allocates nothing.
666
+ */
667
+ declare function createDrawList<TTexture = unknown>(options?: DrawListOptions): DrawList<TTexture>;
668
+ //#endregion
669
+ //#region src/present.d.ts
670
+ /**
671
+ * The stage: a WebGL2 context of its OWN on a caller-supplied canvas, its exact
672
+ * backing-store size, the design->screen projection every other module in this
673
+ * package reads, and the context-loss plumbing.
674
+ *
675
+ * THE ONLY MODULE IN `@godot-scene-web/canvas` THAT TOUCHES A CANVAS. Everything
676
+ * else takes a `WebGL2RenderingContext` and does arithmetic; keeping the DOM
677
+ * surface to one file is what makes the rest of the package testable without a
678
+ * browser and reusable off the main thread.
679
+ *
680
+ * ITS OWN CONTEXT, not `html`'s shared one. The shared context exists so that N
681
+ * per-node effect canvases on one page do not each burn one of the browser's ~16
682
+ * live contexts; it renders offscreen and BLITS onto each node. The stage is the
683
+ * opposite shape — ONE canvas for the whole scene, presented directly — so it
684
+ * neither needs the blit nor wants to share a drawing buffer that is sized,
685
+ * cleared and grown by two other runtimes on their own schedule.
686
+ *
687
+ * THE CONTEXT ATTRIBUTES, and why each one:
688
+ *
689
+ * - `alpha: true` — the stage composites over whatever the page puts behind it
690
+ * (letterbox bars, a background layer), so it must carry real transparency.
691
+ * - `premultipliedAlpha: true` — the contract stated end to end: textures upload
692
+ * premultiplied (`./textures`), tints are premultiplied (the draw-list's own
693
+ * documentation), every fragment emits `vec4(rgb*a, a)`, the MIX blend is
694
+ * `(ONE, ONE_MINUS_SRC_ALPHA)`. This flag changes no byte in the drawing
695
+ * buffer; it tells the compositor how to READ them. Declare it wrong and
696
+ * nothing errors — the page simply multiplies by alpha a second time and every
697
+ * translucent pixel comes out dark. `html/webgl/shared-gl.ts` has the long
698
+ * version of this note and the bug that produced it.
699
+ * - `stencil: false`, `depth: false` — a painter's-algorithm 2D renderer uses
700
+ * neither, and both cost drawing-buffer memory on every device.
701
+ * - `antialias: false` — there is no geometry to multisample: every edge in the
702
+ * scene is a texture's own alpha, which LINEAR filtering already smooths. MSAA
703
+ * here would allocate a multisample buffer and resolve it every frame to change
704
+ * nothing.
705
+ * - `preserveDrawingBuffer: false` — the stage clears and repaints every frame,
706
+ * and preserving forces the implementation to keep a copy. Measurement trap
707
+ * that follows: once the stage is idle, a JS-side readback (`toDataURL`,
708
+ * `drawImage` of the canvas) returns an EMPTY image while the composited
709
+ * frame on screen is correct — the drawing buffer is gone after present, by
710
+ * design. Judge presentation only by compositor capture (a real screenshot
711
+ * of the tab), never by reading the canvas back.
712
+ * - `desynchronized` is deliberately NOT set. It can cut latency by letting the
713
+ * canvas bypass the compositor, but it also makes readback and screenshot
714
+ * behaviour implementation-defined — which is exactly what the pixel tests
715
+ * assert on — and on several drivers it silently disables the alpha compositing
716
+ * path the point above depends on. A latency measurement can turn it on later,
717
+ * with a test that proves the composite still holds.
718
+ */
719
+ /** The subset of a canvas the stage needs. Structural so that both an
720
+ * `HTMLCanvasElement` and an `OffscreenCanvas` satisfy it. */
721
+ interface StageCanvas {
722
+ width: number;
723
+ height: number;
724
+ getContext(contextId: "webgl2", options?: WebGLContextAttributes): WebGL2RenderingContext | null;
725
+ addEventListener(type: string, listener: (event: Event) => void): void;
726
+ removeEventListener(type: string, listener: (event: Event) => void): void;
727
+ }
728
+ /** How design coordinates reach the screen, in the two forms consumers need. */
729
+ interface StageProjection {
730
+ /** Exact scene coordinate extent, independent of float32 matrix rounding. */
731
+ readonly designWidth: number;
732
+ readonly designHeight: number;
733
+ /**
734
+ * Design -> clip space as `(scaleX, scaleY, translateX, translateY)`:
735
+ * `clip = design * scale + translate`. `scaleY` is NEGATIVE — design space
736
+ * measures Y downwards and clip space upwards.
737
+ */
738
+ readonly toClip: Float32Array;
739
+ /**
740
+ * Design -> framebuffer pixels as a 2x3 in the draw-list's `Transform2D` order
741
+ * `[xx, xy, yx, yy, originX, originY]`, with Y measured DOWN from the top. This
742
+ * is what `./clip-stack` turns into a scissor box.
743
+ */
744
+ readonly toFramebuffer: Float32Array;
745
+ /** The drawing buffer's REAL size — see {@link CanvasStage.setStageSize}. */
746
+ readonly framebufferWidth: number;
747
+ readonly framebufferHeight: number;
748
+ }
749
+ interface CanvasStageOptions {
750
+ canvas: StageCanvas;
751
+ /** The scene's own coordinate extent, e.g. 1920x1080. */
752
+ designWidth: number;
753
+ designHeight: number;
754
+ /**
755
+ * Request an alpha-capable drawing buffer. Omitted preserves the stage's
756
+ * compositing default (`true`); an opaque scene may opt out when it paints
757
+ * every output pixel itself.
758
+ */
759
+ alpha?: boolean;
760
+ /**
761
+ * Called after `webglcontextlost`. Every GL object the caller holds is dead:
762
+ * drop programs, buffers and textures (`CanvasTextureCache.reset`,
763
+ * `CanvasExecutor.invalidate`) without calling into GL to free them.
764
+ */
765
+ onContextLost?(): void;
766
+ /** Called after `webglcontextrestored`: rebuild programs, buffers, textures. */
767
+ onContextRestored?(): void;
768
+ }
769
+ interface CanvasStage {
770
+ readonly canvas: StageCanvas;
771
+ readonly gl: WebGL2RenderingContext;
772
+ readonly designWidth: number;
773
+ readonly designHeight: number;
774
+ /** The drawing buffer's real width/height, which may be smaller than asked. */
775
+ readonly stageWidth: number;
776
+ readonly stageHeight: number;
777
+ /** True between `webglcontextlost` and `webglcontextrestored`. */
778
+ readonly contextLost: boolean;
779
+ /**
780
+ * Whether the context actually has an alpha channel. This is read from the
781
+ * created context when available, rather than assuming the request won.
782
+ */
783
+ readonly alpha: boolean;
784
+ /**
785
+ * Size the backing store EXACTLY. Not grow-only: a stage that kept the largest
786
+ * size it had ever been asked for would keep a 4K drawing buffer alive after a
787
+ * window shrank, and would leave `gl.viewport` and the projection describing a
788
+ * buffer bigger than the one being presented. Re-reads the ACHIEVED size
789
+ * afterwards, because setting `canvas.width` only REQUESTS an allocation — an
790
+ * implementation may return a smaller buffer, and trusting the attribute over
791
+ * the buffer is how a renderer ends up drawing into rows that do not exist.
792
+ */
793
+ setStageSize(width: number, height: number): void;
794
+ /** Change the design extent (a scene that re-lays-out for a new aspect). */
795
+ setDesignSize(width: number, height: number): void;
796
+ /** The current projection. The returned object is reused; read it, don't keep it. */
797
+ projection(): StageProjection;
798
+ /** Set `gl.viewport` to the whole drawing buffer. */
799
+ applyViewport(): void;
800
+ /** Detach the context-loss listeners. Does not delete the context. */
801
+ dispose(): void;
802
+ }
803
+ /** The attributes the stage asks for, exported so a test can assert the contract
804
+ * rather than restate it. */
805
+ declare const STAGE_CONTEXT_ATTRIBUTES: Readonly<WebGLContextAttributes>;
806
+ /**
807
+ * Create a stage on `canvas`, or `null` when the browser gives no WebGL2 context.
808
+ *
809
+ * Note what is NOT here: no software-renderer refusal. `html`'s shared context
810
+ * declines SwiftShader/llvmpipe because running full-screen procedural fragment
811
+ * shaders on a CPU rasterizer costs more than the CSS fallback it has. The stage
812
+ * has no fallback to fall back TO — it is the renderer — and its fragment shader
813
+ * is a texture fetch and a multiply, which software GL runs perfectly well. The
814
+ * decision of whether this device should use the canvas renderer at all belongs
815
+ * to the consumer, one level up, where the alternative is known.
816
+ */
817
+ declare function createCanvasStage(options: CanvasStageOptions): CanvasStage | null;
818
+ //#endregion
819
+ //#region src/glyph-pass.d.ts
820
+ /**
821
+ * The seam between the executor and whatever draws glyph outlines.
822
+ *
823
+ * STRUCTURAL, AND IN THE CORE, SO THE BARREL STAYS FREE OF A GLYPH RENDERER. The only
824
+ * implementation this repo ships is backed by `@godot-scene-web/hb-gpu` and lives on the
825
+ * `./glyphs` subpath, for two reasons that are both about cost rather than taste: the main
826
+ * barrel's export list is mirrored by hand-maintained ambient `.d.ts` files in
827
+ * `../sts2-couch-coop` and `../spirectl` (see `AGENTS.md`), so every name added there is work
828
+ * downstream; and a scene with no text should not pull a glyph renderer, its wasm loader and its
829
+ * atlas into the bundle. A consumer that wants glyphs imports the adapter and injects it exactly
830
+ * the way `CanvasExecutorOptions.white` is injected today.
831
+ *
832
+ * ONE METHOD, AND NO FRAME LIFECYCLE. There is no `begin`/`end` here on purpose: the executor
833
+ * flushes its pending batch before calling {@link GlyphPass.drawRun} and restores its own GL state
834
+ * after, so a pass has nothing to get wrong about when a frame starts. Everything it needs about
835
+ * the frame is in the two arguments.
836
+ */
837
+ interface GlyphPass {
838
+ /**
839
+ * Draw ONE glyph run, in the GL state the executor is currently in.
840
+ *
841
+ * ONE DRAW CALL PER RUN, and that is a property of the mechanism rather than a thing to optimise
842
+ * away later: hb-gpu's program carries the run's colour and its model matrix as UNIFORMS, so two
843
+ * runs can only share a draw when both are identical, and the model matrix in particular cannot
844
+ * be moved onto the instance without also moving the dilation `hb_gpu_dilate` computes through
845
+ * it. A caller that wants fewer draws should merge runs when it BUILDS the list.
846
+ *
847
+ * `run` is the executor's own reusable view and is valid only for the duration of the call —
848
+ * `run.slots` and `run.positions` are overwritten by the next `readGlyphs`. Read what is needed
849
+ * and return.
850
+ *
851
+ * `projection` is the frame's, and the pass is expected to honour BOTH halves of it: `toClip`
852
+ * maps design space (the space `run.positions` are in, after `run.m`) to clip space, and
853
+ * `framebufferWidth`/`framebufferHeight` is the achieved drawing buffer, which is what a
854
+ * resolution-independent glyph shader measures a screen pixel against. They differ by the
855
+ * device-pixel ratio and conflating them is a dilation error, not a placement error.
856
+ *
857
+ * WHAT THE PASS MAY ASSUME on entry: `BLEND` is enabled, `SCISSOR_TEST` is enabled and the
858
+ * scissor box is the frame's current clip, the viewport is the whole drawing buffer, and the
859
+ * pending quad batch has already been drawn. WHAT IT MAY LEAVE DIRTY: the program, the bound
860
+ * VAO, `ARRAY_BUFFER`, texture unit 0 and the blend equation/function — the executor rebinds and
861
+ * re-invalidates all of those. It must NOT clear, must NOT touch the viewport, and must NOT
862
+ * touch `SCISSOR_TEST` or the scissor box, because that is what clips the run.
863
+ */
864
+ drawRun(run: GlyphsView, projection: StageProjection): {
865
+ glyphs: number;
866
+ drawCalls: number;
867
+ };
868
+ /**
869
+ * Draw consecutive glyph commands as one ordered submission. Optional so existing passes keep
870
+ * their exact one-command path. The executor only calls this for physically adjacent glyph
871
+ * commands in an unbroken clip/mask scope; implementations must preserve the supplied order.
872
+ */
873
+ drawRuns?(runs: readonly GlyphsView[], projection: StageProjection): {
874
+ glyphs: number;
875
+ drawCalls: number;
876
+ };
877
+ /** Conservative residency admission for `drawRuns`; false keeps commands separate. */
878
+ canBatchRuns?(runs: readonly GlyphsView[]): boolean;
879
+ }
880
+ //#endregion
881
+ export { DamageRect as $, DrawListPatchView as A, ScreenEffectDrawContext as B, DRAW_TEXTURED_MESH as C, DrawListFragment as D, DrawList as E, GlyphsView as F, createDrawListPatchView as G, createClipRectView as H, NinePatchView as I, createPolylineView as J, createGlyphsView as K, PolylineView as L, ExternalEffectDrawContext as M, FLIP_H as N, DrawListFragmentPatch as O, FLIP_V as P, CommandBounds as Q, QuadView as R, DRAW_SCREEN_EFFECT as S, DrawCommandName as T, createDrawList as U, TexturedMeshView as V, createDrawListFragment as W, createTexturedMeshView as X, createQuadView as Y, setViewColorMatrix as Z, DRAW_EXTERNAL_EFFECT as _, StageCanvas as a, RETAINED_MAX_DAMAGE_COVERAGE as at, DRAW_POLYLINE as b, BLEND_ADD as c, createDamageTiles as ct, BLEND_SUB as d, outsetDamageRect as dt, DamageTile as et, BlendMode as f, transformDamageRect as ft, DRAW_COMMAND_NAMES as g, DRAW_CLIP_PUSH as h, STAGE_CONTEXT_ATTRIBUTES as i, RETAINED_DAMAGE_TILE_SIZE as it, ExternalEffectDrawCommand as j, DrawListOptions as k, BLEND_MIX as l, damageIntersects as lt, DRAW_CLIP_POP as m, CanvasStage as n, DamageTransform as nt, StageProjection as o, commandDamageBounds as ot, ClipRectView as p, unionDamageRect as pt, createNinePatchView as q, CanvasStageOptions as r, DirtyRect as rt, createCanvasStage as s, createDamageRect as st, GlyphPass as t, DamageTiles as tt, BLEND_MUL as u, isDamageEmpty as ut, DRAW_GLYPHS as v, DrawCommandKind as w, DRAW_QUAD as x, DRAW_NINE_PATCH as y, ScreenEffectDrawCommand as z };
882
+ //# sourceMappingURL=glyph-pass-DfQlp_IH.d.ts.map