@weasel-js/core 1.4.2 → 1.4.4
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 +742 -0
- package/dist/{DrawCommand-Ch8W63oQ.d.ts → DrawCommand-CD-ug3d9.d.ts} +45 -1
- package/dist/{pointSnapToGrid-Dmthv94u.d.ts → autoPoseDescriptor-DF1SnnSx.d.ts} +18 -3
- package/dist/{stroke-Dq8nL4A2.d.ts → builtins-BXFBXegF.d.ts} +251 -102
- package/dist/{chunk-Y5KS66G7.js → chunk-2VXGHUVL.js} +4 -4
- package/dist/{chunk-Y5KS66G7.js.map → chunk-2VXGHUVL.js.map} +1 -1
- package/dist/{chunk-2KKYDDDD.js → chunk-4RJP2N2L.js} +43 -21
- package/dist/chunk-4RJP2N2L.js.map +1 -0
- package/dist/{chunk-TORKRNFY.js → chunk-BL65SHCX.js} +83 -8
- package/dist/chunk-BL65SHCX.js.map +1 -0
- package/dist/{chunk-MXFSHJOM.js → chunk-D4AAWR64.js} +4 -4
- package/dist/{chunk-MXFSHJOM.js.map → chunk-D4AAWR64.js.map} +1 -1
- package/dist/{chunk-ZB7UYJVG.js → chunk-DOBSZOPR.js} +3 -3
- package/dist/{chunk-ZB7UYJVG.js.map → chunk-DOBSZOPR.js.map} +1 -1
- package/dist/{chunk-BLJNRMKB.js → chunk-PRGBGMH3.js} +3 -3
- package/dist/{chunk-BLJNRMKB.js.map → chunk-PRGBGMH3.js.map} +1 -1
- package/dist/{chunk-KIVJXUYE.js → chunk-R3AWPTLZ.js} +2779 -1660
- package/dist/chunk-R3AWPTLZ.js.map +1 -0
- package/dist/{chunk-67KE7SDP.js → chunk-T3UQ3F6R.js} +4 -4
- package/dist/{chunk-67KE7SDP.js.map → chunk-T3UQ3F6R.js.map} +1 -1
- package/dist/{chunk-SBFC6J3C.js → chunk-WPM42WJP.js} +3 -3
- package/dist/{chunk-SBFC6J3C.js.map → chunk-WPM42WJP.js.map} +1 -1
- package/dist/clipboard.d.ts +2 -2
- package/dist/clipboard.js +3 -3
- package/dist/clone.d.ts +2 -2
- package/dist/clone.js +3 -3
- package/dist/{geometry-Dtt_k6Dq.d.ts → geometry-6fCNhAux.d.ts} +3 -3
- package/dist/{grid-nnXU4VjN.d.ts → grid-0Pbn5B2C.d.ts} +1 -14
- package/dist/index.d.ts +330 -288
- package/dist/index.js +9 -9
- package/dist/insert.d.ts +3 -3
- package/dist/insert.js +1 -1
- package/dist/move.d.ts +4 -4
- package/dist/move.js +3 -3
- package/dist/{options-CdFl510T.d.ts → options-DbYLImvq.d.ts} +1 -1
- package/dist/{registry-BwY_DxJM.d.ts → registry-BY-wI9gm.d.ts} +98 -8
- package/dist/renderer.d.ts +32 -4
- package/dist/renderer.js +9 -9
- package/dist/resize.d.ts +5 -4
- package/dist/resize.js +2 -2
- package/dist/routing.d.ts +6 -6
- package/dist/routing.js +1 -1
- package/dist/{types-XBcDEp3Y.d.ts → types-DEALFt5F.d.ts} +10 -6
- package/dist/{types-DIQAisSG.d.ts → types-bcc7jcUy.d.ts} +116 -15
- package/dist/{types-miXHGrZM.d.ts → types-ei3UMl9R.d.ts} +1 -1
- package/package.json +9 -9
- package/dist/chunk-2KKYDDDD.js.map +0 -1
- package/dist/chunk-KIVJXUYE.js.map +0 -1
- package/dist/chunk-TORKRNFY.js.map +0 -1
|
@@ -116,6 +116,35 @@ type ShaderUniform = number | [number, number] | [number, number, number] | [num
|
|
|
116
116
|
*/
|
|
117
117
|
declare function registerProgram(id: string, vert: string, frag: string): ShaderProgramHandle;
|
|
118
118
|
|
|
119
|
+
/**
|
|
120
|
+
* One full-screen pass over what a group has already drawn.
|
|
121
|
+
*
|
|
122
|
+
* The renderer runs a group's effects in order, each reading the previous
|
|
123
|
+
* one's output through `u_source` and writing a whole new buffer — so an
|
|
124
|
+
* effect is free to read neighbouring pixels, which is the entire point and
|
|
125
|
+
* the one thing `colorMatrix` can never do.
|
|
126
|
+
*
|
|
127
|
+
* `uniforms` are the effect's own; `u_source`, `u_resolution` and `u_texel`
|
|
128
|
+
* come from the renderer and must not be passed here.
|
|
129
|
+
*/
|
|
130
|
+
interface Effect {
|
|
131
|
+
program: ShaderProgramHandle;
|
|
132
|
+
uniforms?: Record<string, ShaderUniform>;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Register a fragment shader as an effect. Sugar over `registerProgram` with
|
|
136
|
+
* the effect vertex shader, and the reason a consumer never imports the
|
|
137
|
+
* prelude: an effect that registers with the *custom-shader* vertex shader
|
|
138
|
+
* compiles, runs, and samples its source upside down.
|
|
139
|
+
*
|
|
140
|
+
* The fragment shader reads `v_uv` and `u_source`, and may declare
|
|
141
|
+
* `u_resolution` / `u_texel`. See `effectPrelude.ts` for the full contract,
|
|
142
|
+
* including the premultiplied-alpha requirement.
|
|
143
|
+
*
|
|
144
|
+
* @experimental
|
|
145
|
+
*/
|
|
146
|
+
declare function registerEffect(id: string, frag: string): ShaderProgramHandle;
|
|
147
|
+
|
|
119
148
|
/**
|
|
120
149
|
* Solid-fill paint variant (subset of the full `FillStyle` union from
|
|
121
150
|
* `@weasel-js/core`). Kept for back-compat with step-1/2 consumers and
|
|
@@ -172,6 +201,21 @@ interface GroupDrawCommand {
|
|
|
172
201
|
* cannot escape an ancestor's clip. Max 7 nesting levels; the renderer
|
|
173
202
|
* throws if exceeded. */
|
|
174
203
|
clip?: Path;
|
|
204
|
+
/**
|
|
205
|
+
* Full-screen passes run over this group's own pixels, in order, before it
|
|
206
|
+
* is composited into its parent.
|
|
207
|
+
*
|
|
208
|
+
* Unlike every other field here, this does not accumulate down the group
|
|
209
|
+
* stack — it is a render-target boundary. The children draw into a buffer of
|
|
210
|
+
* their own, each effect reads the previous one's output, and the result is
|
|
211
|
+
* composited back under this group's `transform`, `alpha`, `colorMatrix` and
|
|
212
|
+
* whatever clip encloses it. So a blur here blurs this group and nothing
|
|
213
|
+
* around it, which is what a CSS `filter` on the canvas cannot do.
|
|
214
|
+
*
|
|
215
|
+
* An empty or absent list costs nothing: no buffer is allocated until a
|
|
216
|
+
* group asks for one.
|
|
217
|
+
*/
|
|
218
|
+
effects?: readonly Effect[];
|
|
175
219
|
children: DrawCommand[];
|
|
176
220
|
}
|
|
177
221
|
/**
|
|
@@ -285,4 +329,4 @@ interface ShaderDrawCommand {
|
|
|
285
329
|
};
|
|
286
330
|
}
|
|
287
331
|
|
|
288
|
-
export { type DrawCommand as D, type GroupDrawCommand as G, type ImageDrawCommand as I, type Mat3 as M, type PathDrawCommand as P, SPRITE_STRIDE as S, type TextDrawCommand as T, type ShaderDrawCommand as a, type ShaderProgramHandle as b, type ShaderUniform as c, type SolidPaint as d, type SpritesDrawCommand as e, mat3 as m,
|
|
332
|
+
export { type DrawCommand as D, type Effect as E, type GroupDrawCommand as G, type ImageDrawCommand as I, type Mat3 as M, type PathDrawCommand as P, SPRITE_STRIDE as S, type TextDrawCommand as T, type ShaderDrawCommand as a, type ShaderProgramHandle as b, type ShaderUniform as c, type SolidPaint as d, type SpritesDrawCommand as e, registerProgram as f, mat3 as m, registerEffect as r };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { c as ResizeAnchor, R as ResizePose, B as BoundsConstraint, P as PointSnapBehavior, d as PointSnapFrame, M as ModifierState } from './types-
|
|
2
|
-
import { B as Bounds, P as PoseProjection } from './geometry-
|
|
1
|
+
import { c as ResizeAnchor, R as ResizePose, B as BoundsConstraint, P as PointSnapBehavior, d as PointSnapFrame, M as ModifierState } from './types-ei3UMl9R.js';
|
|
2
|
+
import { B as Bounds, P as PoseProjection } from './geometry-6fCNhAux.js';
|
|
3
3
|
import { D as DebugSink } from './types-BHK2dkMu.js';
|
|
4
|
+
import { P as Path } from './path-JEV2c5If.js';
|
|
4
5
|
|
|
5
6
|
/** Corner resize-handle: world-space center plus the anchor that pins the opposite corner during resize. */
|
|
6
7
|
interface CornerHandle {
|
|
@@ -137,4 +138,18 @@ declare function pointSnapToGrid<TPose extends ResizePose>(args: {
|
|
|
137
138
|
bypassKey?: keyof ModifierState;
|
|
138
139
|
}): PointSnapBehavior<TPose>;
|
|
139
140
|
|
|
140
|
-
|
|
141
|
+
/** True for Path-shaped poses (`{kind: 'polygon' | 'rect'}`). Useful for
|
|
142
|
+
* callers that need to fork between `pathPoseDescriptor` and
|
|
143
|
+
* `RECT_POSE_DESCRIPTOR` without forcing the consumer to wire `geometry`
|
|
144
|
+
* explicitly. */
|
|
145
|
+
declare function isPathLike(p: unknown): p is Path;
|
|
146
|
+
/** Per-call dispatch: if the pose looks like a Path, route to
|
|
147
|
+
* `pathPoseDescriptor`; otherwise treat as a plain rect pose. Avoids forcing
|
|
148
|
+
* demos with Path TPose to wire `geometry={pathPoseDescriptor}` explicitly.
|
|
149
|
+
* `getRotation` surfaces a `pose.rotation` field on non-Path poses so demos
|
|
150
|
+
* using rect-with-rotation shapes (e.g. `RotatedPose`) don't have to wire
|
|
151
|
+
* `geometry={ROTATED_POSE_DESCRIPTOR}` just to get rotated selection chrome
|
|
152
|
+
* and rotation-aware corner hit-tests. */
|
|
153
|
+
declare const AUTO_POSE_DESCRIPTOR: PoseProjection<unknown>;
|
|
154
|
+
|
|
155
|
+
export { AUTO_POSE_DESCRIPTOR as A, CORNER_ANCHORS as C, type UseResizeOptions as U, type CornerAnchor as a, type CornerHandle as b, cornerPoint as c, cornerResizeHandles as d, type CornerEdge as e, fixedCornerOf as f, hitCornerHandle as h, isPathLike as i, pointSnapToGrid as p };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { GradStop, Stroke } from '@weasel-js/paint';
|
|
2
|
-
import { M as Mat3, b as ShaderProgramHandle, D as DrawCommand } from './DrawCommand-
|
|
2
|
+
import { M as Mat3, b as ShaderProgramHandle, D as DrawCommand, E as Effect } from './DrawCommand-CD-ug3d9.js';
|
|
3
3
|
import { P as Path } from './path-JEV2c5If.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -218,6 +218,23 @@ declare class GLImageCache {
|
|
|
218
218
|
private readonly gl;
|
|
219
219
|
private readonly minification;
|
|
220
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;
|
|
221
238
|
/** `minification` selects the MIN_FILTER strategy for uploaded textures.
|
|
222
239
|
* `'linear'` (default) is the screen path's existing behavior. `'mipmap'`
|
|
223
240
|
* generates mipmaps and filters LINEAR_MIPMAP_LINEAR — required for
|
|
@@ -227,13 +244,21 @@ declare class GLImageCache {
|
|
|
227
244
|
constructor(gl: WebGL2RenderingContext, minification?: ImageMinification);
|
|
228
245
|
upload(key: object, source: TexSource, repetition?: PatternRepetition): WebGLTexture;
|
|
229
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;
|
|
230
251
|
}
|
|
231
252
|
|
|
232
253
|
/**
|
|
233
|
-
* CPU gradient-ramp builder + GL
|
|
254
|
+
* CPU gradient-ramp builder + the GL texture every baked ramp lives in.
|
|
234
255
|
*
|
|
235
|
-
* Each unique stop list is
|
|
236
|
-
*
|
|
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.
|
|
237
262
|
*
|
|
238
263
|
* Output convention §2: texels are stored as straight RGBA. The fragment
|
|
239
264
|
* shader applies premultiplication before writing outColor.
|
|
@@ -242,25 +267,66 @@ declare class GLImageCache {
|
|
|
242
267
|
/** Bake gradient stops into a 256-entry RGBA lookup strip, which the shader
|
|
243
268
|
* samples instead of evaluating stops per fragment. */
|
|
244
269
|
declare function buildGradientRamp(stops: GradStop[]): Uint8ClampedArray;
|
|
245
|
-
declare class
|
|
270
|
+
declare class GradientRampAtlas {
|
|
246
271
|
private readonly gl;
|
|
247
|
-
|
|
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;
|
|
248
280
|
private totalQueries;
|
|
249
281
|
private cacheHits;
|
|
250
282
|
constructor(gl: WebGL2RenderingContext);
|
|
251
|
-
|
|
252
|
-
|
|
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;
|
|
253
314
|
hitRate(): number;
|
|
254
315
|
resetStats(): void;
|
|
255
316
|
/**
|
|
256
|
-
* Delete
|
|
257
|
-
* `WeaselRenderer.dispose()`.
|
|
258
|
-
*
|
|
259
|
-
* `upload()` call and already gone by the time a ramp is cached. The
|
|
260
|
-
* cache is unusable but refillable afterward (stats are left as-is; call
|
|
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
|
|
261
320
|
* `resetStats()` separately if desired).
|
|
262
321
|
*/
|
|
263
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;
|
|
264
330
|
}
|
|
265
331
|
|
|
266
332
|
/** Row-major 4×5 color matrix identity. */
|
|
@@ -279,6 +345,22 @@ declare class GroupState {
|
|
|
279
345
|
get alpha(): number;
|
|
280
346
|
get colorMatrix(): Float32Array;
|
|
281
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
|
+
};
|
|
282
364
|
/** Drop every pushed frame, leaving the root. A frame that throws part-way
|
|
283
365
|
* down the tree never pops, and the next frame would draw under leftovers. */
|
|
284
366
|
reset(): void;
|
|
@@ -286,33 +368,72 @@ declare class GroupState {
|
|
|
286
368
|
}
|
|
287
369
|
|
|
288
370
|
/**
|
|
289
|
-
* Growable vertex staging for
|
|
371
|
+
* Growable vertex staging for a run of solid-fill geometry, image quads and
|
|
372
|
+
* glyphs.
|
|
290
373
|
*
|
|
291
374
|
* Geometry only: `draw.ts` owns when a run starts, what breaks it, and the
|
|
292
|
-
* uniforms the flush draws under.
|
|
293
|
-
*
|
|
294
|
-
*
|
|
295
|
-
*
|
|
296
|
-
*
|
|
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.
|
|
297
399
|
*/
|
|
298
400
|
|
|
299
|
-
|
|
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 {
|
|
300
418
|
private readonly gl;
|
|
301
419
|
private readonly aPos;
|
|
302
420
|
private readonly aColor;
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
private readonly
|
|
306
|
-
|
|
307
|
-
|
|
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. */
|
|
308
429
|
private readonly largeRing;
|
|
309
430
|
private nextLarge;
|
|
310
431
|
private verts;
|
|
311
432
|
private idx;
|
|
312
433
|
private nVerts;
|
|
313
434
|
private nIdx;
|
|
314
|
-
/** Whether the staged run is
|
|
315
|
-
*
|
|
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. */
|
|
316
437
|
private pureRects;
|
|
317
438
|
constructor(gl: WebGL2RenderingContext, prog: ShaderProgram);
|
|
318
439
|
get length(): number;
|
|
@@ -324,6 +445,62 @@ declare class SolidBatch {
|
|
|
324
445
|
* cover it and the batch draws at `u_model` identity.
|
|
325
446
|
*/
|
|
326
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;
|
|
327
504
|
/**
|
|
328
505
|
* Append a tessellated mesh through `m`, all vertices carrying `rgba`. The
|
|
329
506
|
* mesh's own indices are rebased onto the staged vertices, which is why the
|
|
@@ -335,6 +512,9 @@ declare class SolidBatch {
|
|
|
335
512
|
uploadAndBind(): number;
|
|
336
513
|
reset(): void;
|
|
337
514
|
dispose(): void;
|
|
515
|
+
private writeVertex;
|
|
516
|
+
/** Two triangles over the four corners just written. */
|
|
517
|
+
private pushQuadIndices;
|
|
338
518
|
/** Grow the CPU arrays so `vertices` / `indices` more fit. */
|
|
339
519
|
private reserve;
|
|
340
520
|
private nextRingSlot;
|
|
@@ -343,67 +523,6 @@ declare class SolidBatch {
|
|
|
343
523
|
private deleteSet;
|
|
344
524
|
}
|
|
345
525
|
|
|
346
|
-
/**
|
|
347
|
-
* Growable vertex staging for consecutive image quads.
|
|
348
|
-
*
|
|
349
|
-
* Geometry only: `draw.ts` owns when a run starts, what breaks it, and the
|
|
350
|
-
* uniforms the flush draws under. The counterpart to `SolidBatch`, and the same
|
|
351
|
-
* two tricks — the model transform is applied here rather than uploaded, so
|
|
352
|
-
* quads under different group transforms still share a draw, and opacity rides
|
|
353
|
-
* the vertices, so quads under different opacities do too. What it cannot
|
|
354
|
-
* absorb is the texture: a batch samples one, which is why an atlas is what
|
|
355
|
-
* makes a large run coalesce at all.
|
|
356
|
-
*
|
|
357
|
-
* Every run is quads, so a slot's index buffer is written once at creation and
|
|
358
|
-
* never again: the pattern for N quads is a prefix of the pattern for any
|
|
359
|
-
* larger N, so the pattern for a slot's capacity serves every flush it takes.
|
|
360
|
-
* `SolidBatch` carries meshes, whose indices are rebased per flush, and has to
|
|
361
|
-
* re-upload; this does not.
|
|
362
|
-
*/
|
|
363
|
-
|
|
364
|
-
declare class ImageBatch {
|
|
365
|
-
private readonly gl;
|
|
366
|
-
private readonly aPos;
|
|
367
|
-
private readonly aUv;
|
|
368
|
-
private readonly aOpacity;
|
|
369
|
-
/** One ring per tier, cycled per flush. Slots are created on first use, so a
|
|
370
|
-
* renderer that flushes rarely allocates as few as it flushes. */
|
|
371
|
-
private readonly rings;
|
|
372
|
-
private readonly nextInRing;
|
|
373
|
-
/** For flushes past the largest tier; these sets grow to fit. */
|
|
374
|
-
private readonly largeRing;
|
|
375
|
-
private nextLarge;
|
|
376
|
-
private verts;
|
|
377
|
-
private nQuads;
|
|
378
|
-
constructor(gl: WebGL2RenderingContext, prog: ShaderProgram);
|
|
379
|
-
/** Indices staged — what a caller passes to `drawElements`. */
|
|
380
|
-
get length(): number;
|
|
381
|
-
get quads(): number;
|
|
382
|
-
/** Whether staging one more quad would put the run past the per-flush cap. */
|
|
383
|
-
wouldOverflow(): boolean;
|
|
384
|
-
/**
|
|
385
|
-
* Append one image quad: the destination rect `(x, y, w, h)` mapped through
|
|
386
|
-
* `m`, sampling `(u0, v0)`-`(u1, v1)`, every corner carrying `opacity`.
|
|
387
|
-
*
|
|
388
|
-
* An affine maps a rect to a parallelogram, so two triangles still cover it
|
|
389
|
-
* and the batch draws at `u_model` identity. Corners wind top-left,
|
|
390
|
-
* top-right, bottom-right, bottom-left, with UVs following — the flips a
|
|
391
|
-
* command asks for are already in the `u`/`v` the caller passes.
|
|
392
|
-
*/
|
|
393
|
-
pushQuad(x: number, y: number, w: number, h: number, m: Mat3, u0: number, v0: number, u1: number, v1: number, opacity: number): void;
|
|
394
|
-
/** Upload the staged geometry into the next set of buffers and bind its VAO.
|
|
395
|
-
* Returns the index count for the caller's `drawElements`. */
|
|
396
|
-
uploadAndBind(): number;
|
|
397
|
-
reset(): void;
|
|
398
|
-
dispose(): void;
|
|
399
|
-
/** Grow the CPU arrays so one more quad fits. */
|
|
400
|
-
private reserve;
|
|
401
|
-
private nextRingSlot;
|
|
402
|
-
private nextLargeSlot;
|
|
403
|
-
private createSet;
|
|
404
|
-
private deleteSet;
|
|
405
|
-
}
|
|
406
|
-
|
|
407
526
|
/** How to construct a `WeaselRenderer`: the GL context or canvas to draw
|
|
408
527
|
* into, the output size, and the quality knobs that separate screen
|
|
409
528
|
* rendering from print. */
|
|
@@ -470,27 +589,30 @@ declare class WeaselRenderer {
|
|
|
470
589
|
private readonly gl;
|
|
471
590
|
private pathFill;
|
|
472
591
|
private pathFillVColor;
|
|
473
|
-
private textSdf;
|
|
474
|
-
private textSdfR8;
|
|
475
592
|
private imageFill;
|
|
476
|
-
private
|
|
593
|
+
private batchFill;
|
|
477
594
|
private gradFill;
|
|
478
595
|
private patternFill;
|
|
479
596
|
private meshCache;
|
|
480
597
|
private textureCache;
|
|
481
598
|
private imageCache;
|
|
482
|
-
private
|
|
599
|
+
private gradRamps;
|
|
483
600
|
private programRegistry;
|
|
484
601
|
private quadVbo;
|
|
485
602
|
private quadIbo;
|
|
486
|
-
private
|
|
487
|
-
|
|
603
|
+
private drawBatch;
|
|
604
|
+
/** 1x1 white, so a batch flush sampling no image still samples something —
|
|
605
|
+
* see `shaders/batchFill.ts`. */
|
|
606
|
+
private whiteTexture;
|
|
488
607
|
private readonly groupState;
|
|
489
608
|
private widthCss;
|
|
490
609
|
private heightCss;
|
|
491
610
|
private dpr;
|
|
492
611
|
private canvas;
|
|
493
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;
|
|
494
616
|
private readonly imageMinification;
|
|
495
617
|
private readonly flattenTolerance?;
|
|
496
618
|
private readonly bakeBudget;
|
|
@@ -541,7 +663,7 @@ declare class WeaselRenderer {
|
|
|
541
663
|
* Scope: built-in shader programs, any consumer-registered programs, the
|
|
542
664
|
* shared quad/rect geometry, any in-flight transient meshes, and the
|
|
543
665
|
* enumerable Map-keyed caches (`GLTextureCache` atlas/image textures,
|
|
544
|
-
* `
|
|
666
|
+
* `GradientRampAtlas`'s ramp texture) ARE freed.
|
|
545
667
|
*
|
|
546
668
|
* NOT freed: `GLImageCache` (bitmap/pattern textures) and `GLMeshCache`'s
|
|
547
669
|
* persistent per-Path mesh cache are keyed by `WeakMap`, not enumerable,
|
|
@@ -577,18 +699,15 @@ declare class WeaselRenderer {
|
|
|
577
699
|
/** @internal */ _gl(): WebGL2RenderingContext;
|
|
578
700
|
/** @internal */ _pathFill(): ShaderProgram;
|
|
579
701
|
/** @internal */ _pathFillVColor(): ShaderProgram;
|
|
580
|
-
/** @internal */
|
|
581
|
-
/** @internal */ _imageBatch(): ImageBatch;
|
|
582
|
-
/** @internal */ _textSdf(): ShaderProgram;
|
|
583
|
-
/** @internal */ _textSdfR8(): ShaderProgram;
|
|
702
|
+
/** @internal */ _drawBatch(): DrawBatch;
|
|
584
703
|
/** @internal */ _imageFill(): ShaderProgram;
|
|
585
|
-
/** @internal */
|
|
704
|
+
/** @internal */ _batchFill(): ShaderProgram;
|
|
586
705
|
/** @internal */ _gradFill(): ShaderProgram;
|
|
587
706
|
/** @internal */ _patternFill(): ShaderProgram;
|
|
588
707
|
/** @internal */ _meshCache(): GLMeshCache;
|
|
589
708
|
/** @internal */ _textureCache(): GLTextureCache;
|
|
590
709
|
/** @internal */ _imageCache(): GLImageCache;
|
|
591
|
-
/** @internal */
|
|
710
|
+
/** @internal */ _gradRamps(): GradientRampAtlas;
|
|
592
711
|
/** @internal */ _groupState(): GroupState;
|
|
593
712
|
/** @internal */ _widthCss(): number;
|
|
594
713
|
/** @internal */ _heightCss(): number;
|
|
@@ -688,4 +807,34 @@ declare function resolveStrokeWidth(width: number | {
|
|
|
688
807
|
*/
|
|
689
808
|
declare function tessellateStroke(path: Path, stroke: Stroke, opts?: StrokeOptions): Mesh;
|
|
690
809
|
|
|
691
|
-
|
|
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 };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { RECT_ORIGIN_PROJECTION } from './chunk-
|
|
2
|
-
import { registerOpFactory, captureSlot, slotFromIndex, resolveSlot } from './chunk-
|
|
1
|
+
import { RECT_ORIGIN_PROJECTION } from './chunk-WPM42WJP.js';
|
|
2
|
+
import { registerOpFactory, captureSlot, slotFromIndex, resolveSlot } from './chunk-4RJP2N2L.js';
|
|
3
3
|
|
|
4
4
|
// src/core/ops/transform.ts
|
|
5
5
|
function createTransformOp(args) {
|
|
@@ -142,5 +142,5 @@ function snap(strategy, opts = {}) {
|
|
|
142
142
|
}
|
|
143
143
|
|
|
144
144
|
export { createReparentOp, createTransformOp, deleteScratch, getScratch, scratchKey, setScratch, snap };
|
|
145
|
-
//# sourceMappingURL=chunk-
|
|
146
|
-
//# sourceMappingURL=chunk-
|
|
145
|
+
//# sourceMappingURL=chunk-2VXGHUVL.js.map
|
|
146
|
+
//# sourceMappingURL=chunk-2VXGHUVL.js.map
|