@weasel-js/core 0.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 +381 -0
- package/LICENSE +21 -0
- package/README.md +144 -0
- package/dist/DrawCommand-Dl0bXNfS.d.ts +500 -0
- package/dist/chunk-775XXAHR.js +216 -0
- package/dist/chunk-775XXAHR.js.map +1 -0
- package/dist/chunk-7V6JEOXE.js +27754 -0
- package/dist/chunk-7V6JEOXE.js.map +1 -0
- package/dist/chunk-AM6ARSPN.js +517 -0
- package/dist/chunk-AM6ARSPN.js.map +1 -0
- package/dist/chunk-BGGZ4CVF.js +248 -0
- package/dist/chunk-BGGZ4CVF.js.map +1 -0
- package/dist/chunk-BHVYVFGV.js +29 -0
- package/dist/chunk-BHVYVFGV.js.map +1 -0
- package/dist/chunk-CQNKCG34.js +831 -0
- package/dist/chunk-CQNKCG34.js.map +1 -0
- package/dist/chunk-GVCNT7UH.js +47 -0
- package/dist/chunk-GVCNT7UH.js.map +1 -0
- package/dist/chunk-PZ5AY32C.js +9 -0
- package/dist/chunk-PZ5AY32C.js.map +1 -0
- package/dist/chunk-UGFFCMQP.js +28 -0
- package/dist/chunk-UGFFCMQP.js.map +1 -0
- package/dist/chunk-VOVKONXA.js +103 -0
- package/dist/chunk-VOVKONXA.js.map +1 -0
- package/dist/chunk-Y52N27PF.js +39 -0
- package/dist/chunk-Y52N27PF.js.map +1 -0
- package/dist/clipboard.d.ts +91 -0
- package/dist/clipboard.js +6 -0
- package/dist/clipboard.js.map +1 -0
- package/dist/clone.d.ts +8 -0
- package/dist/clone.js +6 -0
- package/dist/clone.js.map +1 -0
- package/dist/fitViewToBounds-evGsnR8Q.d.ts +62 -0
- package/dist/grid-Cf87knjU.d.ts +153 -0
- package/dist/index-DZBYMsHI.d.ts +1555 -0
- package/dist/index.css +121 -0
- package/dist/index.css.map +1 -0
- package/dist/index.d.ts +10200 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/insert.d.ts +33 -0
- package/dist/insert.js +81 -0
- package/dist/insert.js.map +1 -0
- package/dist/move.d.ts +69 -0
- package/dist/move.js +145 -0
- package/dist/move.js.map +1 -0
- package/dist/options-BPPBWMa7.d.ts +64 -0
- package/dist/patterns-builtin.d.ts +55 -0
- package/dist/patterns-builtin.js +100 -0
- package/dist/patterns-builtin.js.map +1 -0
- package/dist/pointSnapToGrid-D7s7QmOF.d.ts +185 -0
- package/dist/registerFont-CP-wCsrz.d.ts +109 -0
- package/dist/registerTexture-BzHTLhD9.d.ts +25 -0
- package/dist/renderer.css +121 -0
- package/dist/renderer.css.map +1 -0
- package/dist/renderer.d.ts +376 -0
- package/dist/renderer.js +13 -0
- package/dist/renderer.js.map +1 -0
- package/dist/resize.d.ts +78 -0
- package/dist/resize.js +5 -0
- package/dist/resize.js.map +1 -0
- package/dist/routing.css +35 -0
- package/dist/routing.css.map +1 -0
- package/dist/routing.d.ts +14 -0
- package/dist/routing.js +4 -0
- package/dist/routing.js.map +1 -0
- package/dist/types-B6MMiodD.d.ts +59 -0
- package/dist/types-BJ8_cyT7.d.ts +130 -0
- package/dist/types-B_-khFM0.d.ts +331 -0
- package/dist/types-BjUi2vA-.d.ts +355 -0
- package/dist/types-Cpb4hii1.d.ts +445 -0
- package/dist/types-D2tTKEU0.d.ts +18 -0
- package/dist/view-DSQgxBJB.d.ts +63 -0
- package/package.json +96 -0
|
@@ -0,0 +1,500 @@
|
|
|
1
|
+
import { P as Path } from './types-B6MMiodD.js';
|
|
2
|
+
import { T as TextureHandle } from './registerTexture-BzHTLhD9.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 2D affine matrix utilities. Column-major 9-element Float32Array, matching
|
|
6
|
+
* `WebGL2RenderingContext.uniformMatrix3fv` byte order so we can pass the
|
|
7
|
+
* array directly without a transpose flag.
|
|
8
|
+
*
|
|
9
|
+
* Layout (column-major):
|
|
10
|
+
* [m00, m10, 0,
|
|
11
|
+
* m01, m11, 0,
|
|
12
|
+
* tx, ty, 1]
|
|
13
|
+
*
|
|
14
|
+
* `apply(m, x, y)` returns `[m * (x, y, 1)] = [m00*x + m01*y + tx,
|
|
15
|
+
* m10*x + m11*y + ty]`.
|
|
16
|
+
*/
|
|
17
|
+
type Mat3 = Float32Array;
|
|
18
|
+
declare function identity(): Mat3;
|
|
19
|
+
declare function multiply(out: Mat3, m: Mat3): Mat3;
|
|
20
|
+
declare function translate(m: Mat3, tx: number, ty: number): Mat3;
|
|
21
|
+
declare function scale(m: Mat3, sx: number, sy: number): Mat3;
|
|
22
|
+
declare function apply(m: Mat3, x: number, y: number): [number, number];
|
|
23
|
+
/**
|
|
24
|
+
* Map screen pixel coords (0..width on X, 0..height on Y, top-left origin)
|
|
25
|
+
* into clip space (-1..1 on X, 1..-1 on Y — note Y flip so screen-down
|
|
26
|
+
* matches clip-down).
|
|
27
|
+
*/
|
|
28
|
+
declare function screenToClip(width: number, height: number): Mat3;
|
|
29
|
+
declare const mat3: {
|
|
30
|
+
identity: typeof identity;
|
|
31
|
+
multiply: typeof multiply;
|
|
32
|
+
translate: typeof translate;
|
|
33
|
+
scale: typeof scale;
|
|
34
|
+
apply: typeof apply;
|
|
35
|
+
screenToClip: typeof screenToClip;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* FillStyle and Stroke types — the unified shape for "what color or texture
|
|
40
|
+
* paints these pixels," modeled on SVG's paint-server concept.
|
|
41
|
+
*
|
|
42
|
+
* - `FillStyle` is a tagged union: solid color, pattern, or gradient. Used
|
|
43
|
+
* wherever a kit option previously took `fillStyle: string`.
|
|
44
|
+
* - `Stroke` pairs a `FillStyle` with structural stroke parameters (width, dash,
|
|
45
|
+
* line cap/join, alignment).
|
|
46
|
+
* - These types are consumed by the GL renderer's DrawCommand path fills
|
|
47
|
+
* and strokes.
|
|
48
|
+
*
|
|
49
|
+
* The 2D `applyPaint` / `applyStroke` / `renderFilledRegion` helpers that
|
|
50
|
+
* formerly lived alongside these types were deleted with the 2D backend in
|
|
51
|
+
* Step 10. `alignedStrokeRect` survives as a pure geometry helper used by
|
|
52
|
+
* path tessellation and the selection overlay.
|
|
53
|
+
*/
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Color/texture strategy for fills (and, via `Stroke.paint`, strokes).
|
|
57
|
+
*
|
|
58
|
+
* `fill` is optional and defaults to `'solid'` — `{ color: '#abc' }` is
|
|
59
|
+
* equivalent to `{ fill: 'solid', color: '#abc' }`. Pattern paints must set
|
|
60
|
+
* `fill: 'pattern'` explicitly.
|
|
61
|
+
*
|
|
62
|
+
* The `'pattern'` variant's payload is a `TextureHandle` (registered via
|
|
63
|
+
* `registerTexture()`). The kit-level factory `createTilePattern` (and the
|
|
64
|
+
* `patterns-builtin` catalog: `hatch`, `crosshatch`, `dots`, `chunks`)
|
|
65
|
+
* produces these handles by rendering a tile to an `OffscreenCanvas` and
|
|
66
|
+
* registering the resulting `ImageBitmap` as a GL texture.
|
|
67
|
+
*/
|
|
68
|
+
type FillStyle = {
|
|
69
|
+
fill?: 'solid';
|
|
70
|
+
color: string;
|
|
71
|
+
opacity?: number;
|
|
72
|
+
} | {
|
|
73
|
+
fill: 'pattern';
|
|
74
|
+
pattern: TextureHandle;
|
|
75
|
+
opacity?: number;
|
|
76
|
+
} | {
|
|
77
|
+
fill: 'linear-gradient';
|
|
78
|
+
from: {
|
|
79
|
+
x: number;
|
|
80
|
+
y: number;
|
|
81
|
+
};
|
|
82
|
+
to: {
|
|
83
|
+
x: number;
|
|
84
|
+
y: number;
|
|
85
|
+
};
|
|
86
|
+
stops: GradStop[];
|
|
87
|
+
opacity?: number;
|
|
88
|
+
} | {
|
|
89
|
+
fill: 'radial-gradient';
|
|
90
|
+
center: {
|
|
91
|
+
x: number;
|
|
92
|
+
y: number;
|
|
93
|
+
};
|
|
94
|
+
radius: number;
|
|
95
|
+
stops: GradStop[];
|
|
96
|
+
opacity?: number;
|
|
97
|
+
} | {
|
|
98
|
+
fill: 'conic-gradient';
|
|
99
|
+
center: {
|
|
100
|
+
x: number;
|
|
101
|
+
y: number;
|
|
102
|
+
};
|
|
103
|
+
angle: number;
|
|
104
|
+
stops: GradStop[];
|
|
105
|
+
opacity?: number;
|
|
106
|
+
};
|
|
107
|
+
/** A single color stop within a gradient. `offset` is in 0..1. */
|
|
108
|
+
interface GradStop {
|
|
109
|
+
offset: number;
|
|
110
|
+
color: string;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Where a stroke sits relative to the geometric edge it strokes.
|
|
114
|
+
*
|
|
115
|
+
* - `'center'` (default): canvas-native — half the stroke width sits inside
|
|
116
|
+
* the geometry, half outside.
|
|
117
|
+
* - `'inner'`: the entire stroke lies inside the geometry. The outer edge of
|
|
118
|
+
* the stroke coincides with the geometric edge.
|
|
119
|
+
* - `'outer'`: the entire stroke lies outside the geometry. The inner edge
|
|
120
|
+
* of the stroke coincides with the geometric edge.
|
|
121
|
+
*
|
|
122
|
+
* Mirrors the (proposed) SVG `stroke-alignment` property. Honoring `inner`
|
|
123
|
+
* or `outer` is the renderer's responsibility — for axis-aligned rects, the
|
|
124
|
+
* kit shifts coordinates by `width / 2`. For arbitrary paths, renderers
|
|
125
|
+
* typically use a stencil mask of the stroked path against the geometry.
|
|
126
|
+
*/
|
|
127
|
+
type StrokeAlign = 'center' | 'inner' | 'outer';
|
|
128
|
+
/** Stroke style: a FillStyle plus structural line parameters. */
|
|
129
|
+
interface Stroke {
|
|
130
|
+
paint: FillStyle;
|
|
131
|
+
width?: number;
|
|
132
|
+
/** Per `CanvasRenderingContext2D.setLineDash` — empty/omitted = solid. */
|
|
133
|
+
dash?: number[];
|
|
134
|
+
cap?: 'butt' | 'round' | 'square';
|
|
135
|
+
join?: 'miter' | 'round' | 'bevel';
|
|
136
|
+
/**
|
|
137
|
+
* Miter join fallback threshold. When the miter length exceeds
|
|
138
|
+
* `miterLimit * width / 2`, the join falls back to a bevel. Default 10
|
|
139
|
+
* (matching Canvas2D). SVG's default is 4; consumers that want SVG
|
|
140
|
+
* fidelity should set this explicitly when constructing strokes from
|
|
141
|
+
* SVG sources where the attribute was omitted.
|
|
142
|
+
*/
|
|
143
|
+
miterLimit?: number;
|
|
144
|
+
/** Where the stroke sits relative to the geometric edge. Default `'center'`. */
|
|
145
|
+
align?: StrokeAlign;
|
|
146
|
+
/**
|
|
147
|
+
* Per-anchor RGBA, flat (length = 4 × countPathAnchors(path)). Each
|
|
148
|
+
* value in 0..1. Arc-length interpolated across the tessellated ribbon
|
|
149
|
+
* between consecutive anchors. When set, `paint` is still required —
|
|
150
|
+
* its `opacity` (and color, as a placeholder) flow through the shader.
|
|
151
|
+
*/
|
|
152
|
+
vertexColors?: number[];
|
|
153
|
+
/**
|
|
154
|
+
* Per-anchor stroke width (length = `countPathAnchors(path)`). When set,
|
|
155
|
+
* the tessellator interpolates half-widths along each segment to produce
|
|
156
|
+
* a tapered ribbon. `width` is used as the fallback for any anchor whose
|
|
157
|
+
* entry is missing or non-finite. Pressure-driven pencil strokes use
|
|
158
|
+
* this; pair with `pressureToWidth` to derive widths from stylus input.
|
|
159
|
+
*
|
|
160
|
+
* Joins between adjacent segments whose widths differ by more than
|
|
161
|
+
* `varyingWidthJoinThreshold` (default 1.5×) are forced to bevel
|
|
162
|
+
* regardless of the `join` setting — miter math is unstable when widths
|
|
163
|
+
* vary across the corner; smooth round joins with mismatched widths
|
|
164
|
+
* are a future enhancement.
|
|
165
|
+
*/
|
|
166
|
+
vertexWidths?: number[];
|
|
167
|
+
/**
|
|
168
|
+
* Max width ratio (greater / lesser) at which a non-bevel join is
|
|
169
|
+
* preserved when `vertexWidths` causes adjacent segments to differ.
|
|
170
|
+
* Beyond this ratio the join falls back to bevel. Default 1.5. Ignored
|
|
171
|
+
* when `vertexWidths` is absent.
|
|
172
|
+
*/
|
|
173
|
+
varyingWidthJoinThreshold?: number;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Inflate (positive) or deflate (negative) a rect to honor `align` when
|
|
177
|
+
* stroking it. Returns the rect to pass to a stroked-rect renderer. `width`
|
|
178
|
+
* is the stroke width (defaults to 1 to match canvas).
|
|
179
|
+
*
|
|
180
|
+
* Pure geometry helper — no rendering side effects. Used by path
|
|
181
|
+
* tessellation and the selection overlay to produce a rect whose
|
|
182
|
+
* center-aligned stroke visually coincides with the requested
|
|
183
|
+
* inner/outer-aligned stroke of the original rect.
|
|
184
|
+
*/
|
|
185
|
+
declare function alignedStrokeRect(rect: {
|
|
186
|
+
x: number;
|
|
187
|
+
y: number;
|
|
188
|
+
width: number;
|
|
189
|
+
height: number;
|
|
190
|
+
}, align: StrokeAlign, width?: number): {
|
|
191
|
+
x: number;
|
|
192
|
+
y: number;
|
|
193
|
+
width: number;
|
|
194
|
+
height: number;
|
|
195
|
+
};
|
|
196
|
+
/** Region a fill is clipped to. */
|
|
197
|
+
interface Region {
|
|
198
|
+
x: number;
|
|
199
|
+
y: number;
|
|
200
|
+
w: number;
|
|
201
|
+
h: number;
|
|
202
|
+
shape: 'rectangle' | 'circle';
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Typography for `TextPose` and friends. Every field is optional; consumers
|
|
207
|
+
* pass `{}` or override the few they care about. Defaults live in
|
|
208
|
+
* `DEFAULT_TEXT_STYLE` and are applied at render/measure time, never written
|
|
209
|
+
* back to the pose.
|
|
210
|
+
*
|
|
211
|
+
* `fill` follows the kit-wide `FillStyle` model — solid color or pattern. The
|
|
212
|
+
* contenteditable edit overlay flattens non-solid fills to `'#000'` for CSS
|
|
213
|
+
* since the browser can't paint with a texture handle.
|
|
214
|
+
*/
|
|
215
|
+
|
|
216
|
+
/** User-facing text style. All fields optional; defaults applied at render time via `resolveTextStyle`. */
|
|
217
|
+
interface TextStyle {
|
|
218
|
+
/** Font size in world units. Default 16. */
|
|
219
|
+
fontSize?: number;
|
|
220
|
+
/** Default `'sans-serif'`. */
|
|
221
|
+
fontFamily?: string;
|
|
222
|
+
/** Default 400. */
|
|
223
|
+
fontWeight?: number | string;
|
|
224
|
+
/** Default `'normal'`. */
|
|
225
|
+
fontStyle?: 'normal' | 'italic';
|
|
226
|
+
/** Default `'left'`. */
|
|
227
|
+
align?: 'left' | 'center' | 'right';
|
|
228
|
+
/** Multiplier applied to `fontSize`. Default 1.2. */
|
|
229
|
+
lineHeight?: number;
|
|
230
|
+
/** Default `{ fill: 'solid', color: '#000' }`. */
|
|
231
|
+
fill?: FillStyle;
|
|
232
|
+
/**
|
|
233
|
+
* Caret color used by the edit overlay. Defaults to the text color when
|
|
234
|
+
* `fill` is solid; falls back to `#000` for non-solid paints.
|
|
235
|
+
*/
|
|
236
|
+
caretColor?: string;
|
|
237
|
+
/**
|
|
238
|
+
* Selection background color used by the edit overlay's `::selection`
|
|
239
|
+
* pseudo-element. Defaults to a 25%-opacity tint of `caretColor` via CSS
|
|
240
|
+
* `color-mix`. Pass `'none'` to fall back to the browser-native highlight.
|
|
241
|
+
*/
|
|
242
|
+
selectionBackground?: string;
|
|
243
|
+
/** Selection text color paired with `selectionBackground`. Default: inherits text color. */
|
|
244
|
+
selectionColor?: string;
|
|
245
|
+
}
|
|
246
|
+
/** `TextStyle` with all fields filled in from defaults — what the renderer actually consumes. */
|
|
247
|
+
interface ResolvedTextStyle {
|
|
248
|
+
fontSize: number;
|
|
249
|
+
fontFamily: string;
|
|
250
|
+
fontWeight: number | string;
|
|
251
|
+
fontStyle: 'normal' | 'italic';
|
|
252
|
+
align: 'left' | 'center' | 'right';
|
|
253
|
+
lineHeight: number;
|
|
254
|
+
fill: FillStyle;
|
|
255
|
+
caretColor: string;
|
|
256
|
+
selectionBackground: string | null;
|
|
257
|
+
selectionColor: string | null;
|
|
258
|
+
}
|
|
259
|
+
/** Default resolved style used when a `TextPose` omits `style`. */
|
|
260
|
+
declare const DEFAULT_TEXT_STYLE: ResolvedTextStyle;
|
|
261
|
+
/** Fill in a partial `TextStyle` with defaults from `DEFAULT_TEXT_STYLE`. */
|
|
262
|
+
declare function resolveTextStyle(style?: TextStyle): ResolvedTextStyle;
|
|
263
|
+
/** Build a CSS `font` shorthand suitable for `ctx.font`. */
|
|
264
|
+
declare function fontString(s: ResolvedTextStyle): string;
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Canonical inline-styling primitive for text nodes. A node's text is
|
|
268
|
+
* either a plain `string` (treated as a single-run, default-styled fragment)
|
|
269
|
+
* or `StyledRun[]` for rich content. `toRuns` is the funnel that normalizes
|
|
270
|
+
* either form into the array shape used by the renderer.
|
|
271
|
+
*
|
|
272
|
+
* Every field except `text` is optional; missing fields fall back to the
|
|
273
|
+
* node-level `TextStyle`. `bold`/`italic` are toggles; richer weight axes
|
|
274
|
+
* (300/500/900) are out of scope for slice 1.
|
|
275
|
+
*/
|
|
276
|
+
|
|
277
|
+
interface StyledRun {
|
|
278
|
+
text: string;
|
|
279
|
+
bold?: boolean;
|
|
280
|
+
italic?: boolean;
|
|
281
|
+
fontFamily?: string;
|
|
282
|
+
fontSize?: number;
|
|
283
|
+
fill?: FillStyle;
|
|
284
|
+
}
|
|
285
|
+
declare function toRuns(input: string | StyledRun[]): StyledRun[];
|
|
286
|
+
declare function runsToPlainText(runs: readonly StyledRun[]): string;
|
|
287
|
+
declare function runsToMarkdown(runs: readonly StyledRun[]): string;
|
|
288
|
+
/**
|
|
289
|
+
* Parse a small markdown subset (`**bold**`, `*italic*`, `***both***`) into
|
|
290
|
+
* styled runs. Backslash escapes `\*` and `\\`. Newlines are preserved as
|
|
291
|
+
* literal characters inside a run — they're not run-boundary markers in
|
|
292
|
+
* this format.
|
|
293
|
+
*/
|
|
294
|
+
declare function markdownToRuns(input: string): StyledRun[];
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Apply node-level `ResolvedTextStyle` defaults to each `StyledRun`,
|
|
298
|
+
* producing a fully-resolved run with every styling field set. Downstream
|
|
299
|
+
* layout and draw never re-resolve defaults — `ResolvedRun` is the
|
|
300
|
+
* canonical shape the renderer consumes.
|
|
301
|
+
*
|
|
302
|
+
* `bold`/`italic` toggles on a run are folded into `fontWeight`/`fontStyle`:
|
|
303
|
+
* `bold: true` → fontWeight 700, `italic: true` → fontStyle 'italic'.
|
|
304
|
+
* Explicit `fontFamily` / `fontSize` / `fill` on the run override the
|
|
305
|
+
* node-level value.
|
|
306
|
+
*/
|
|
307
|
+
|
|
308
|
+
interface ResolvedRun {
|
|
309
|
+
text: string;
|
|
310
|
+
fontFamily: string;
|
|
311
|
+
fontSize: number;
|
|
312
|
+
fontWeight: number;
|
|
313
|
+
fontStyle: 'normal' | 'italic';
|
|
314
|
+
fill: FillStyle;
|
|
315
|
+
}
|
|
316
|
+
declare function resolveRuns(runs: readonly StyledRun[], style: ResolvedTextStyle): ResolvedRun[];
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Box vertical alignment for text draw commands. Given the command's box
|
|
320
|
+
* `height` and the laid-out text block's height, returns the Y offset to
|
|
321
|
+
* apply to every quad. `'top'` (or an undefined `align`, or a missing box
|
|
322
|
+
* `height`) is the legacy behavior: offset 0.
|
|
323
|
+
*/
|
|
324
|
+
type TextVerticalAlign = 'top' | 'center' | 'bottom';
|
|
325
|
+
declare function verticalAlignOffset(align: TextVerticalAlign | undefined, boxHeight: number | undefined, textHeight: number): number;
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* registerProgram — public API for registering custom shader programs.
|
|
329
|
+
*
|
|
330
|
+
* Stores raw GLSL source strings in a module-level registry. GL compilation
|
|
331
|
+
* happens on each WeaselRenderer via WeaselRenderer.registerProgram(), which
|
|
332
|
+
* calls getProgramSource() and compiles the result. This keeps registerProgram
|
|
333
|
+
* GL-context-agnostic — identical pattern to registerFont storing ImageBitmap.
|
|
334
|
+
*
|
|
335
|
+
* Convention §9: module-level state = source strings only; compiled GL
|
|
336
|
+
* programs live on each renderer's programRegistry (Map<id, ShaderProgram>).
|
|
337
|
+
*
|
|
338
|
+
* Lifecycle: program sources live for the module lifetime. No unregister in v1.
|
|
339
|
+
*/
|
|
340
|
+
|
|
341
|
+
/** Opaque handle to a compiled custom shader program. */
|
|
342
|
+
interface ShaderProgramHandle {
|
|
343
|
+
readonly id: string;
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* Scalar and vector uniform types accepted by the custom shader uniform binder.
|
|
347
|
+
*
|
|
348
|
+
* | TS type | GL call |
|
|
349
|
+
* |-------------------------|--------------------------------------|
|
|
350
|
+
* | number | uniform1f |
|
|
351
|
+
* | [n, n] | uniform2fv |
|
|
352
|
+
* | [n, n, n] | uniform3fv |
|
|
353
|
+
* | [n, n, n, n] | uniform4fv |
|
|
354
|
+
* | Float32Array length 9 | uniformMatrix3fv (column-major) |
|
|
355
|
+
* | Float32Array length 16 | uniformMatrix4fv (column-major) |
|
|
356
|
+
* | TextureHandle | bind to next tex unit + uniform1i |
|
|
357
|
+
*/
|
|
358
|
+
type ShaderUniform = number | [number, number] | [number, number, number] | [number, number, number, number] | Float32Array | TextureHandle;
|
|
359
|
+
/**
|
|
360
|
+
* Register a custom shader program by id.
|
|
361
|
+
*
|
|
362
|
+
* Pass an empty string for `vert` to use the kit's default vertex shader
|
|
363
|
+
* (recommended). The kit's vertex shader exposes `v_uv`, `v_screen`, and
|
|
364
|
+
* `v_world` varyings plus `u_bounds` and `u_view` uniforms.
|
|
365
|
+
*
|
|
366
|
+
* **IMPORTANT — Premultiplied alpha (conventions §2):**
|
|
367
|
+
* Your fragment shader MUST output premultiplied alpha:
|
|
368
|
+
* `outColor = vec4(rgb * a, a);` ← correct
|
|
369
|
+
* `outColor = vec4(rgb, a);` ← WRONG — over-brightens translucent regions
|
|
370
|
+
*
|
|
371
|
+
* The renderer uses `gl.blendFunc(ONE, ONE_MINUS_SRC_ALPHA)` to match.
|
|
372
|
+
* Opaque fragments (a=1) are unaffected; only fragments with a < 1 differ.
|
|
373
|
+
*
|
|
374
|
+
* **Re-registration behavior:**
|
|
375
|
+
* - Dev mode (`NODE_ENV !== 'production'`): calling with an existing id replaces
|
|
376
|
+
* the source (hot-reload). Each renderer must call `WeaselRenderer.registerProgram(handle)`
|
|
377
|
+
* again to pick up the new source.
|
|
378
|
+
* - Prod mode: calling with an existing id throws.
|
|
379
|
+
*
|
|
380
|
+
* Actual GL compilation and `ShaderCompileError` throwing happen in
|
|
381
|
+
* `WeaselRenderer.registerProgram()`, not here.
|
|
382
|
+
*
|
|
383
|
+
* @experimental API may break before v2.
|
|
384
|
+
*/
|
|
385
|
+
declare function registerProgram(id: string, vert: string, frag: string): ShaderProgramHandle;
|
|
386
|
+
|
|
387
|
+
/**
|
|
388
|
+
* Solid-fill paint variant (subset of the full `FillStyle` union from
|
|
389
|
+
* `@weasel-js/core`). Kept for back-compat with step-1/2 consumers and
|
|
390
|
+
* because some code reads `fill.color` directly. Through step 4, fills can
|
|
391
|
+
* be any `FillStyle` variant — solid, pattern, or gradient.
|
|
392
|
+
*/
|
|
393
|
+
interface SolidPaint {
|
|
394
|
+
fill?: 'solid';
|
|
395
|
+
/** Any CSS color string accepted by `parseColor`: hex, `rgb()`/`rgba()`, `hsl()`/`hsla()`, named, or `transparent`. */
|
|
396
|
+
color: string;
|
|
397
|
+
opacity?: number;
|
|
398
|
+
}
|
|
399
|
+
/** DrawCommand variants implemented through step 6. */
|
|
400
|
+
type DrawCommand = PathDrawCommand | GroupDrawCommand | TextDrawCommand | ImageDrawCommand | ShaderDrawCommand;
|
|
401
|
+
interface PathDrawCommand {
|
|
402
|
+
kind: 'path';
|
|
403
|
+
path: Path;
|
|
404
|
+
/** Any `FillStyle` variant: solid, pattern, or gradient (linear/radial/conic). */
|
|
405
|
+
fill?: FillStyle;
|
|
406
|
+
/** Stroke spec. Only solid `paint` supported through step 4. */
|
|
407
|
+
stroke?: Stroke;
|
|
408
|
+
/**
|
|
409
|
+
* Optional flat RGBA-per-path-anchor color array (length =
|
|
410
|
+
* `4 × countPathAnchors(path)`, floats in 0..1). The renderer
|
|
411
|
+
* arc-length-interpolates these per-anchor colors across the
|
|
412
|
+
* flattened/triangulated mesh between consecutive anchors using the
|
|
413
|
+
* mesh's `anchorA` / `anchorB` / `anchorT` parameterization.
|
|
414
|
+
*
|
|
415
|
+
* **`fill` must also be set when using `vertexColors`.** The renderer
|
|
416
|
+
* only enters the per-vertex shader path when the command has a fill
|
|
417
|
+
* (the fill provides the opacity uniform; the vertex colors override
|
|
418
|
+
* the fill's color). Pass any solid `fill` (e.g. `{ color: '#fff' }`)
|
|
419
|
+
* as the placeholder; the per-vertex colors win in the shader.
|
|
420
|
+
*/
|
|
421
|
+
vertexColors?: number[];
|
|
422
|
+
}
|
|
423
|
+
interface GroupDrawCommand {
|
|
424
|
+
kind: 'group';
|
|
425
|
+
transform?: Mat3;
|
|
426
|
+
alpha?: number;
|
|
427
|
+
/**
|
|
428
|
+
* Optional 4×5 color matrix (row-major, 20 numbers) — `out = M₄ₓ₄ * in + bias`.
|
|
429
|
+
* Accumulated multiplicatively down the group stack. Defaults to identity.
|
|
430
|
+
*/
|
|
431
|
+
colorMatrix?: number[];
|
|
432
|
+
/** Optional clip path. When set, the renderer rasterizes this path into
|
|
433
|
+
* the stencil buffer before drawing `children`; the children paint only
|
|
434
|
+
* where the clip covers. Nested groups with clips intersect — a child
|
|
435
|
+
* cannot escape an ancestor's clip. Max 7 nesting levels; the renderer
|
|
436
|
+
* throws if exceeded. */
|
|
437
|
+
clip?: Path;
|
|
438
|
+
children: DrawCommand[];
|
|
439
|
+
}
|
|
440
|
+
/**
|
|
441
|
+
* Text draw command. Renders one or more runs at (`x`, `y`) in screen
|
|
442
|
+
* space, optionally word-wrapping at `maxWidth`. The renderer resolves
|
|
443
|
+
* each run's `(fontFamily, fontWeight, fontStyle)` to an MSDF atlas via
|
|
444
|
+
* `resolveFontVariant` and bucket-draws by atlas + color group.
|
|
445
|
+
*
|
|
446
|
+
* `style` carries node-level defaults (`lineHeight`, anti-alias width)
|
|
447
|
+
* that don't belong on individual runs.
|
|
448
|
+
*/
|
|
449
|
+
interface TextDrawCommand {
|
|
450
|
+
kind: 'text';
|
|
451
|
+
x: number;
|
|
452
|
+
y: number;
|
|
453
|
+
runs: ResolvedRun[];
|
|
454
|
+
maxWidth?: number;
|
|
455
|
+
align?: 'left' | 'center' | 'right';
|
|
456
|
+
style: TextStyle;
|
|
457
|
+
/** Box height for vertical alignment. When set with `verticalAlign`,
|
|
458
|
+
* the laid-out block shifts within `[y, y+height]`. */
|
|
459
|
+
height?: number;
|
|
460
|
+
/** Default 'top' — the legacy top-anchored behavior. */
|
|
461
|
+
verticalAlign?: TextVerticalAlign;
|
|
462
|
+
}
|
|
463
|
+
/**
|
|
464
|
+
* Image draw command — renders `image` at screen-space rect (x, y, w, h).
|
|
465
|
+
* The image is stretched to fit; no tiling. Use a pattern FillStyle on a path
|
|
466
|
+
* for tiling.
|
|
467
|
+
*/
|
|
468
|
+
interface ImageDrawCommand {
|
|
469
|
+
kind: 'image';
|
|
470
|
+
image: ImageBitmap;
|
|
471
|
+
x: number;
|
|
472
|
+
y: number;
|
|
473
|
+
w: number;
|
|
474
|
+
h: number;
|
|
475
|
+
opacity?: number;
|
|
476
|
+
}
|
|
477
|
+
/**
|
|
478
|
+
* Custom shader draw command. The renderer generates a quad over `bounds`
|
|
479
|
+
* and dispatches the consumer's fragment shader with the kit's vertex prelude.
|
|
480
|
+
*
|
|
481
|
+
* `uniforms` keys must match names declared in the consumer's fragment shader.
|
|
482
|
+
* The kit automatically sets `u_bounds`, `u_view`, and `u_proj` — do not
|
|
483
|
+
* declare those in `uniforms`.
|
|
484
|
+
*
|
|
485
|
+
* @experimental API may change before v2.
|
|
486
|
+
*/
|
|
487
|
+
interface ShaderDrawCommand {
|
|
488
|
+
kind: 'shader';
|
|
489
|
+
program: ShaderProgramHandle;
|
|
490
|
+
uniforms: Record<string, ShaderUniform>;
|
|
491
|
+
/** Screen-space bounding rect in CSS pixels. */
|
|
492
|
+
bounds: {
|
|
493
|
+
x: number;
|
|
494
|
+
y: number;
|
|
495
|
+
w: number;
|
|
496
|
+
h: number;
|
|
497
|
+
};
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
export { type DrawCommand as D, type FillStyle as F, type GradStop as G, type ImageDrawCommand as I, type Mat3 as M, type PathDrawCommand as P, type ResolvedTextStyle as R, type ShaderProgramHandle as S, type TextDrawCommand as T, type Stroke as a, type GroupDrawCommand as b, type ShaderDrawCommand as c, type ShaderUniform as d, type SolidPaint as e, type StyledRun as f, type TextStyle as g, type TextVerticalAlign as h, DEFAULT_TEXT_STYLE as i, type Region as j, type ResolvedRun as k, type StrokeAlign as l, mat3 as m, alignedStrokeRect as n, fontString as o, markdownToRuns as p, resolveRuns as q, registerProgram as r, resolveTextStyle as s, runsToMarkdown as t, runsToPlainText as u, toRuns as v, verticalAlignOffset as w };
|