@koiosdigital/matrx-render 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.
- package/LICENSE +674 -0
- package/dist/chunk-NASKU36A.js +551 -0
- package/dist/encode/webp-jsquash.d.ts +37 -0
- package/dist/encode/webp-jsquash.js +86 -0
- package/dist/index.d.ts +654 -0
- package/dist/index.js +2788 -0
- package/dist/testing/index.d.ts +22 -0
- package/dist/testing/index.js +76 -0
- package/dist/webp-D106DLhy.d.ts +84 -0
- package/dist/widget-DABrpucj.d.ts +174 -0
- package/package.json +41 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,654 @@
|
|
|
1
|
+
import { C as Color16, a as Canvas, W as Widget, b as Color, B as Bounds, D as DrawContext } from './widget-DABrpucj.js';
|
|
2
|
+
export { c as BLACK, T as TRANSPARENT, d as WHITE, e as bounds, f as color16, m as maxFrameCount, g as modInt, p as parseColor } from './widget-DABrpucj.js';
|
|
3
|
+
import { WidgetSpec, RootSpec } from '@koiosdigital/matrx-sdk';
|
|
4
|
+
export { D as DEFAULT_SCREEN_DELAY_MILLIS, F as FrameEncoder, I as Image, W as WebpDecoder, e as encodeWebp, s as setWebpDecoder } from './webp-D106DLhy.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* BDF bitmap-font parser — a line-for-line port of zachomedia/go-bdf
|
|
8
|
+
* (the parser pixlet uses), including its quirks, because Text rendering
|
|
9
|
+
* parity depends on them:
|
|
10
|
+
*
|
|
11
|
+
* - Metrics come from FONT_ASCENT / FONT_DESCENT properties.
|
|
12
|
+
* - Glyph advance is DWIDTH's x component; BBX gives the bitmap size and
|
|
13
|
+
* the lower-left offset (LowerPoint).
|
|
14
|
+
* - Bitmap rows are hex, MSB-first across bytes; BPP defaults to 1 and each
|
|
15
|
+
* pixel scales to 0..255 (binary for BPP=1).
|
|
16
|
+
* - Character code → rune mapping: go-bdf consults a charmap for
|
|
17
|
+
* ISO8859-1/2/9/15 registries, but BDF files quote the registry value
|
|
18
|
+
* (`CHARSET_REGISTRY "ISO10646"`), and go-bdf's lookup key includes those
|
|
19
|
+
* quotes — so the lookup never matches for any bundled font and the
|
|
20
|
+
* mapping is codepoint identity. (For ISO8859-1, the charmap *is* the
|
|
21
|
+
* identity anyway.) We implement identity, which is byte-identical for
|
|
22
|
+
* all twelve bundled fonts.
|
|
23
|
+
* - DEFAULT_CHAR: missing runes fall back to this glyph; if the property is
|
|
24
|
+
* absent the fallback code is 0 (go-bdf initializes 32, then always
|
|
25
|
+
* overwrites it after the property scan).
|
|
26
|
+
*/
|
|
27
|
+
interface Glyph {
|
|
28
|
+
name: string;
|
|
29
|
+
/** Character code (codepoint identity — see module docs). */
|
|
30
|
+
code: number;
|
|
31
|
+
/** DWIDTH x — horizontal advance in pixels. */
|
|
32
|
+
advanceX: number;
|
|
33
|
+
/** BBX width/height. */
|
|
34
|
+
w: number;
|
|
35
|
+
h: number;
|
|
36
|
+
/** BBX lower-left offset (lx, ly). */
|
|
37
|
+
lx: number;
|
|
38
|
+
ly: number;
|
|
39
|
+
/** Alpha bitmap, w*h bytes, row-major, 0..255 (binary for BPP=1). */
|
|
40
|
+
bitmap: Uint8Array;
|
|
41
|
+
}
|
|
42
|
+
interface BdfFont {
|
|
43
|
+
name: string;
|
|
44
|
+
ascent: number;
|
|
45
|
+
descent: number;
|
|
46
|
+
capHeight: number;
|
|
47
|
+
xHeight: number;
|
|
48
|
+
/** DEFAULT_CHAR code; 0 when the property is absent. */
|
|
49
|
+
defaultCode: number;
|
|
50
|
+
glyphs: Map<number, Glyph>;
|
|
51
|
+
}
|
|
52
|
+
/** go-bdf lookup(): exact glyph, else DEFAULT_CHAR's glyph, else null. */
|
|
53
|
+
declare function lookupGlyph(font: BdfFont, code: number): Glyph | null;
|
|
54
|
+
declare function parseBdf(text: string): BdfFont;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Font registry + text measurement/rasterization.
|
|
58
|
+
* Mirrors pixlet render/fonts.go (GetFont, lazy parse + cache) and the
|
|
59
|
+
* font.Drawer semantics that gg's MeasureString/drawString build on.
|
|
60
|
+
*/
|
|
61
|
+
|
|
62
|
+
declare function getFontList(): string[];
|
|
63
|
+
declare function getFont(name: string): BdfFont;
|
|
64
|
+
/**
|
|
65
|
+
* Sum of glyph advances in pixels. Mirrors font.Drawer.MeasureString via
|
|
66
|
+
* gg.MeasureString: kerning is always 0 for BDF faces; code points missing
|
|
67
|
+
* from the font (after DEFAULT_CHAR fallback) are skipped without advance.
|
|
68
|
+
* BDF advances are integral, so the 26.6 fixed-point floor is exact.
|
|
69
|
+
*/
|
|
70
|
+
declare function measureString(font: BdfFont, s: string): number;
|
|
71
|
+
declare function renderText(font: BdfFont, content: string, color: Color16, height: number, offset: number): Canvas;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Minimal deterministic PNG encoder (8-bit RGBA, zlib stored blocks).
|
|
75
|
+
* Zero dependencies so it runs identically in Node, Workers, and tests.
|
|
76
|
+
* Output is not size-optimized — it exists for golden fixtures, previews,
|
|
77
|
+
* and the CLI, not for production delivery (production output is WebP).
|
|
78
|
+
*/
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Encode a canvas as PNG. The canvas holds premultiplied RGBA; PNG wants
|
|
82
|
+
* straight alpha, so we un-premultiply exactly like Go's image/png does for
|
|
83
|
+
* image.RGBA input (NRGBAModel conversion: v = v16 * 0xffff / a16, >> 8).
|
|
84
|
+
*/
|
|
85
|
+
declare function encodePng(canvas: Canvas): Uint8Array;
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Hydration: `WidgetSpec` JSON (produced by app isolates via @koiosdigital/matrx-sdk
|
|
89
|
+
* builders) → paintable widget instances, plus the top-level render entry
|
|
90
|
+
* point. This is the host side of the D1 boundary: the isolate returns a
|
|
91
|
+
* serializable tree; layout/rasterization happen here.
|
|
92
|
+
*/
|
|
93
|
+
|
|
94
|
+
/** Hydrate a (non-root) widget spec and run all pending init()s. */
|
|
95
|
+
declare function buildWidget(spec: WidgetSpec): Promise<Widget>;
|
|
96
|
+
interface RenderResult {
|
|
97
|
+
frames: Canvas[];
|
|
98
|
+
/** Frame delay in milliseconds (Root.delay). */
|
|
99
|
+
delay: number;
|
|
100
|
+
/** Expiration time in seconds (Root.maxAge). */
|
|
101
|
+
maxAge: number;
|
|
102
|
+
showFullAnimation: boolean;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Render a root spec to frames. Canvas dimensions come from the render call
|
|
106
|
+
* (device-provided), not the app — handoff §10.
|
|
107
|
+
*/
|
|
108
|
+
declare function renderRoot(spec: RootSpec, opts?: {
|
|
109
|
+
width?: number;
|
|
110
|
+
height?: number;
|
|
111
|
+
maxFrameCount?: number;
|
|
112
|
+
solidBackground?: boolean;
|
|
113
|
+
}): Promise<RenderResult>;
|
|
114
|
+
|
|
115
|
+
/** Box — port of pixlet render/box.go. */
|
|
116
|
+
|
|
117
|
+
declare class Box implements Widget {
|
|
118
|
+
child: Widget | null;
|
|
119
|
+
width: number;
|
|
120
|
+
height: number;
|
|
121
|
+
padding: number;
|
|
122
|
+
color: Color | null;
|
|
123
|
+
constructor(props?: {
|
|
124
|
+
child?: Widget | null;
|
|
125
|
+
width?: number;
|
|
126
|
+
height?: number;
|
|
127
|
+
padding?: number;
|
|
128
|
+
color?: Color | null;
|
|
129
|
+
});
|
|
130
|
+
paintBounds(b: Bounds, _frameIdx: number): Bounds;
|
|
131
|
+
paint(dc: DrawContext, b: Bounds, frameIdx: number): void;
|
|
132
|
+
frameCount(): number;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Vector — port of pixlet render/vector.go: the shared layout engine behind
|
|
137
|
+
* Row and Column. Ported line-for-line, including the child-measurement
|
|
138
|
+
* overflow breaks, residual-space distribution, and the space_between
|
|
139
|
+
* `offset = -1` residual trick. Integer divisions use Math.trunc to match
|
|
140
|
+
* Go's truncating division (cross offsets can go negative when a child is
|
|
141
|
+
* taller than the clamped vector).
|
|
142
|
+
*/
|
|
143
|
+
|
|
144
|
+
type MainAlign = "start" | "end" | "center" | "space_between" | "space_evenly" | "space_around" | "";
|
|
145
|
+
type CrossAlign = "start" | "center" | "end" | "";
|
|
146
|
+
declare class Vector implements Widget {
|
|
147
|
+
children: Widget[];
|
|
148
|
+
mainAlign: MainAlign;
|
|
149
|
+
crossAlign: CrossAlign;
|
|
150
|
+
expanded: boolean;
|
|
151
|
+
vertical: boolean;
|
|
152
|
+
constructor(props: {
|
|
153
|
+
children: Widget[];
|
|
154
|
+
mainAlign?: MainAlign;
|
|
155
|
+
crossAlign?: CrossAlign;
|
|
156
|
+
expanded?: boolean;
|
|
157
|
+
vertical?: boolean;
|
|
158
|
+
});
|
|
159
|
+
paintBounds(b: Bounds, frameIdx: number): Bounds;
|
|
160
|
+
paint(dc: DrawContext, b: Bounds, frameIdx: number): void;
|
|
161
|
+
frameCount(): number;
|
|
162
|
+
}
|
|
163
|
+
/** Row — port of pixlet render/row.go (a horizontal Vector). */
|
|
164
|
+
declare class Row extends Vector {
|
|
165
|
+
constructor(props: {
|
|
166
|
+
children: Widget[];
|
|
167
|
+
mainAlign?: MainAlign;
|
|
168
|
+
crossAlign?: CrossAlign;
|
|
169
|
+
expanded?: boolean;
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
/** Column — port of pixlet render/column.go (a vertical Vector). */
|
|
173
|
+
declare class Column extends Vector {
|
|
174
|
+
constructor(props: {
|
|
175
|
+
children: Widget[];
|
|
176
|
+
mainAlign?: MainAlign;
|
|
177
|
+
crossAlign?: CrossAlign;
|
|
178
|
+
expanded?: boolean;
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/** Stack — port of pixlet render/stack.go. Children painted in order, later on top. */
|
|
183
|
+
|
|
184
|
+
declare class Stack implements Widget {
|
|
185
|
+
children: Widget[];
|
|
186
|
+
constructor(props: {
|
|
187
|
+
children: Widget[];
|
|
188
|
+
});
|
|
189
|
+
paintBounds(b: Bounds, frameIdx: number): Bounds;
|
|
190
|
+
paint(dc: DrawContext, b: Bounds, frameIdx: number): void;
|
|
191
|
+
frameCount(): number;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/** Padding — port of pixlet render/padding.go, including the negative-pad
|
|
195
|
+
* positioning hack and the clip/translate ordering. */
|
|
196
|
+
|
|
197
|
+
interface Insets {
|
|
198
|
+
left: number;
|
|
199
|
+
top: number;
|
|
200
|
+
right: number;
|
|
201
|
+
bottom: number;
|
|
202
|
+
}
|
|
203
|
+
declare class Padding implements Widget {
|
|
204
|
+
child: Widget;
|
|
205
|
+
pad: Insets;
|
|
206
|
+
expanded: boolean;
|
|
207
|
+
color: Color | null;
|
|
208
|
+
constructor(props: {
|
|
209
|
+
child: Widget;
|
|
210
|
+
pad?: Insets;
|
|
211
|
+
expanded?: boolean;
|
|
212
|
+
color?: Color | null;
|
|
213
|
+
});
|
|
214
|
+
paintBounds(b: Bounds, frameIdx: number): Bounds;
|
|
215
|
+
paint(dc: DrawContext, b: Bounds, frameIdx: number): void;
|
|
216
|
+
frameCount(): number;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/** Text — port of pixlet render/text.go: single line, prerendered at init. */
|
|
220
|
+
|
|
221
|
+
declare const DEFAULT_FONT_FACE = "tb-8";
|
|
222
|
+
declare class Text implements Widget {
|
|
223
|
+
content: string;
|
|
224
|
+
font: string;
|
|
225
|
+
height: number;
|
|
226
|
+
offset: number;
|
|
227
|
+
color: Color | null;
|
|
228
|
+
private img;
|
|
229
|
+
constructor(props: {
|
|
230
|
+
content: string;
|
|
231
|
+
font?: string;
|
|
232
|
+
height?: number;
|
|
233
|
+
offset?: number;
|
|
234
|
+
color?: Color | null;
|
|
235
|
+
});
|
|
236
|
+
init(): void;
|
|
237
|
+
private image;
|
|
238
|
+
size(): [number, number];
|
|
239
|
+
paintBounds(_b: Bounds, _frameIdx: number): Bounds;
|
|
240
|
+
paint(dc: DrawContext, _b: Bounds, _frameIdx: number): void;
|
|
241
|
+
frameCount(): number;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Root — port of pixlet render/root.go.
|
|
246
|
+
*
|
|
247
|
+
* Divergence from the fork (documented): the Go fork falls back to mutable
|
|
248
|
+
* package globals for dimensions (pre-thread-safety compat). Here dimensions
|
|
249
|
+
* are instance-only, defaulting to 64×32 — the behavior fork commit 665d55b
|
|
250
|
+
* was moving toward.
|
|
251
|
+
*/
|
|
252
|
+
|
|
253
|
+
declare const DEFAULT_FRAME_WIDTH = 64;
|
|
254
|
+
declare const DEFAULT_FRAME_HEIGHT = 32;
|
|
255
|
+
declare const DEFAULT_MAX_FRAME_COUNT = 2000;
|
|
256
|
+
declare class Root {
|
|
257
|
+
child: Widget;
|
|
258
|
+
/** Frame delay in milliseconds. */
|
|
259
|
+
delay: number;
|
|
260
|
+
/** Expiration time in seconds. */
|
|
261
|
+
maxAge: number;
|
|
262
|
+
showFullAnimation: boolean;
|
|
263
|
+
/** Canvas dimensions; 0 → defaults. */
|
|
264
|
+
width: number;
|
|
265
|
+
height: number;
|
|
266
|
+
constructor(props: {
|
|
267
|
+
child: Widget;
|
|
268
|
+
delay?: number;
|
|
269
|
+
maxAge?: number;
|
|
270
|
+
showFullAnimation?: boolean;
|
|
271
|
+
width?: number;
|
|
272
|
+
height?: number;
|
|
273
|
+
});
|
|
274
|
+
/** Render all frames. Mirrors Root.Paint (sequentially — no goroutines). */
|
|
275
|
+
paint(opts?: {
|
|
276
|
+
solidBackground?: boolean;
|
|
277
|
+
maxFrameCount?: number;
|
|
278
|
+
}): Canvas[];
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/** Animation — port of pixlet render/animation.go: each child is one frame. */
|
|
282
|
+
|
|
283
|
+
declare class Animation implements Widget {
|
|
284
|
+
children: Widget[];
|
|
285
|
+
constructor(props: {
|
|
286
|
+
children: Widget[];
|
|
287
|
+
});
|
|
288
|
+
frameCount(): number;
|
|
289
|
+
paintBounds(b: Bounds, frameIdx: number): Bounds;
|
|
290
|
+
paint(dc: DrawContext, b: Bounds, frameIdx: number): void;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Sequence — port of pixlet render/sequence.go (Koios fork, including the
|
|
295
|
+
* `duration` loop extension): children rendered one after another, each for
|
|
296
|
+
* its own frame count.
|
|
297
|
+
*/
|
|
298
|
+
|
|
299
|
+
declare class Sequence implements Widget {
|
|
300
|
+
children: Widget[];
|
|
301
|
+
/** Total duration in frames (0 = play once, >0 = loop children to fill). */
|
|
302
|
+
duration: number;
|
|
303
|
+
constructor(props: {
|
|
304
|
+
children: Widget[];
|
|
305
|
+
duration?: number;
|
|
306
|
+
});
|
|
307
|
+
/** Natural frame count of one complete pass through all children. */
|
|
308
|
+
baseCycleFrameCount(): number;
|
|
309
|
+
frameCount(): number;
|
|
310
|
+
private resolveFrameIdx;
|
|
311
|
+
paintBounds(b: Bounds, frameIdx: number): Bounds;
|
|
312
|
+
paint(dc: DrawContext, b: Bounds, frameIdx: number): void;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* Marquee — port of pixlet render/marquee.go (Koios fork: delay, endDelay,
|
|
317
|
+
* loop). Frame-count formulas are reproduced exactly (handoff §5).
|
|
318
|
+
*
|
|
319
|
+
* Ported quirk: frameCount() measures the child against the *default*
|
|
320
|
+
* 64×32 frame dimensions (the fork does this for thread safety), while
|
|
321
|
+
* paint() measures against the actual bounds. Keep it that way for parity.
|
|
322
|
+
*/
|
|
323
|
+
|
|
324
|
+
declare class Marquee implements Widget {
|
|
325
|
+
child: Widget;
|
|
326
|
+
width: number;
|
|
327
|
+
height: number;
|
|
328
|
+
offsetStart: number;
|
|
329
|
+
offsetEnd: number;
|
|
330
|
+
scrollDirection: string;
|
|
331
|
+
align: string;
|
|
332
|
+
delay: number;
|
|
333
|
+
endDelay: number;
|
|
334
|
+
loop: boolean;
|
|
335
|
+
constructor(props: {
|
|
336
|
+
child: Widget;
|
|
337
|
+
width?: number;
|
|
338
|
+
height?: number;
|
|
339
|
+
offsetStart?: number;
|
|
340
|
+
offsetEnd?: number;
|
|
341
|
+
scrollDirection?: string;
|
|
342
|
+
align?: string;
|
|
343
|
+
delay?: number;
|
|
344
|
+
endDelay?: number;
|
|
345
|
+
loop?: boolean;
|
|
346
|
+
});
|
|
347
|
+
private isVertical;
|
|
348
|
+
paintBounds(b: Bounds, _frameIdx: number): Bounds;
|
|
349
|
+
frameCount(): number;
|
|
350
|
+
paint(dc: DrawContext, b: Bounds, frameIdx: number): void;
|
|
351
|
+
private paintLoop;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* Easing curves — port of pixlet render/animation/curve.go.
|
|
356
|
+
*/
|
|
357
|
+
type Curve = (t: number) => number;
|
|
358
|
+
declare const linearCurve: Curve;
|
|
359
|
+
/**
|
|
360
|
+
* Cubic bezier easing, solved by bisection exactly like the Go code
|
|
361
|
+
* (epsilon 0.0001 on the x axis). The Go loop is unbounded; we cap the
|
|
362
|
+
* iteration count as a safety net — at 64 halvings the interval is far below
|
|
363
|
+
* any float64 epsilon, so a convergent input (monotone x, i.e. a,c ∈ [0,1])
|
|
364
|
+
* terminates identically to Go long before the cap.
|
|
365
|
+
*/
|
|
366
|
+
declare function cubicBezierCurve(a: number, b: number, c: number, d: number): Curve;
|
|
367
|
+
declare const easeIn: Curve;
|
|
368
|
+
declare const easeOut: Curve;
|
|
369
|
+
declare const easeInOut: Curve;
|
|
370
|
+
/** Port of animation.ParseCurve. */
|
|
371
|
+
declare function parseCurve(str: string): Curve;
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* Transforms and their interpolation — port of pixlet
|
|
375
|
+
* render/animation/{transform,translate,scale,rotate,rounding,util,vector}.go.
|
|
376
|
+
*/
|
|
377
|
+
|
|
378
|
+
declare function rescale(fromMin: number, fromMax: number, toMin: number, toMax: number, v: number): number;
|
|
379
|
+
declare function lerp(from: number, to: number, t: number): number;
|
|
380
|
+
type RoundingMode = "round" | "floor" | "ceil" | "none";
|
|
381
|
+
declare function applyRounding(mode: RoundingMode, v: number): number;
|
|
382
|
+
type Transform = {
|
|
383
|
+
kind: "translate";
|
|
384
|
+
x: number;
|
|
385
|
+
y: number;
|
|
386
|
+
} | {
|
|
387
|
+
kind: "scale";
|
|
388
|
+
x: number;
|
|
389
|
+
y: number;
|
|
390
|
+
} | {
|
|
391
|
+
kind: "rotate";
|
|
392
|
+
angle: number;
|
|
393
|
+
};
|
|
394
|
+
/**
|
|
395
|
+
* Pairwise interpolation of transform lists; lists of unequal length are
|
|
396
|
+
* extended with per-kind defaults. Mismatched kinds at the same position
|
|
397
|
+
* would require matrix-level interpolation, which pixlet does not support —
|
|
398
|
+
* returns ok=false, and no transforms are applied.
|
|
399
|
+
*/
|
|
400
|
+
declare function interpolateTransforms(lhs: Transform[], rhs: Transform[], progress: number): {
|
|
401
|
+
transforms: Transform[];
|
|
402
|
+
ok: boolean;
|
|
403
|
+
};
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* Keyframes, origin, direction, fill mode — port of pixlet
|
|
407
|
+
* render/animation/{keyframe,origin,direction,fill_mode,transformation}.go
|
|
408
|
+
* (the keyframe-processing half of transformation.go lives here).
|
|
409
|
+
*/
|
|
410
|
+
|
|
411
|
+
interface Keyframe {
|
|
412
|
+
/** Point in time, 0.0 .. 1.0. */
|
|
413
|
+
percentage: number;
|
|
414
|
+
transforms: Transform[];
|
|
415
|
+
curve: Curve;
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* Sort keyframes (stable) and add 0%/100% keyframes if missing.
|
|
419
|
+
* See https://www.w3.org/TR/css-animations-1/#keyframes
|
|
420
|
+
*/
|
|
421
|
+
declare function processKeyframes(arr: Keyframe[]): Keyframe[];
|
|
422
|
+
/**
|
|
423
|
+
* Find the adjacent keyframes for a progress value. Returns null when the
|
|
424
|
+
* value is out of range (including NaN progress from a zero-length
|
|
425
|
+
* animation, which flows through comparisons exactly like in Go) — the
|
|
426
|
+
* caller then applies no transforms.
|
|
427
|
+
*/
|
|
428
|
+
declare function findKeyframes(arr: Keyframe[], p: number): [Keyframe, Keyframe] | null;
|
|
429
|
+
interface Origin {
|
|
430
|
+
x: number;
|
|
431
|
+
y: number;
|
|
432
|
+
}
|
|
433
|
+
declare const DEFAULT_ORIGIN: Origin;
|
|
434
|
+
type DirectionMode = "normal" | "reverse" | "alternate" | "alternate_reverse";
|
|
435
|
+
type FillMode = "forwards" | "backwards";
|
|
436
|
+
|
|
437
|
+
/**
|
|
438
|
+
* Transformation — port of pixlet render/animation/transformation.go:
|
|
439
|
+
* CSS-like keyframe animation of translate/scale/rotate on a child widget.
|
|
440
|
+
*/
|
|
441
|
+
|
|
442
|
+
declare class Transformation implements Widget {
|
|
443
|
+
child: Widget;
|
|
444
|
+
keyframes: Keyframe[];
|
|
445
|
+
duration: number;
|
|
446
|
+
delay: number;
|
|
447
|
+
width: number;
|
|
448
|
+
height: number;
|
|
449
|
+
origin: Origin;
|
|
450
|
+
direction: DirectionMode;
|
|
451
|
+
fillMode: FillMode;
|
|
452
|
+
rounding: RoundingMode;
|
|
453
|
+
waitForChild: boolean;
|
|
454
|
+
constructor(props: {
|
|
455
|
+
child: Widget;
|
|
456
|
+
keyframes: Keyframe[];
|
|
457
|
+
duration: number;
|
|
458
|
+
delay?: number;
|
|
459
|
+
width?: number;
|
|
460
|
+
height?: number;
|
|
461
|
+
origin?: Origin;
|
|
462
|
+
direction?: DirectionMode;
|
|
463
|
+
fillMode?: FillMode;
|
|
464
|
+
rounding?: RoundingMode;
|
|
465
|
+
waitForChild?: boolean;
|
|
466
|
+
});
|
|
467
|
+
init(): void;
|
|
468
|
+
frameCount(): number;
|
|
469
|
+
paintBounds(b: Bounds, _frameIdx: number): Bounds;
|
|
470
|
+
paint(dc: DrawContext, b: Bounds, frameIdx: number): void;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
/**
|
|
474
|
+
* WrappedText — port of pixlet render/wrappedtext.go + gg's wordWrap and
|
|
475
|
+
* DrawStringWrapped line placement. Lines are rasterized with the shared
|
|
476
|
+
* text pipeline and blitted at the exact positions gg's anchored draw
|
|
477
|
+
* produces (fixed-point dot quantization → floor at .5 offsets).
|
|
478
|
+
*/
|
|
479
|
+
|
|
480
|
+
/** Port of gg wordWrap. */
|
|
481
|
+
declare function wordWrap(font: BdfFont, s: string, width: number): string[];
|
|
482
|
+
declare class WrappedText implements Widget {
|
|
483
|
+
content: string;
|
|
484
|
+
font: string;
|
|
485
|
+
height: number;
|
|
486
|
+
width: number;
|
|
487
|
+
lineSpacing: number;
|
|
488
|
+
color: Color | null;
|
|
489
|
+
align: string;
|
|
490
|
+
private face;
|
|
491
|
+
constructor(props: {
|
|
492
|
+
content: string;
|
|
493
|
+
font?: string;
|
|
494
|
+
height?: number;
|
|
495
|
+
width?: number;
|
|
496
|
+
lineSpacing?: number;
|
|
497
|
+
color?: Color | null;
|
|
498
|
+
align?: string;
|
|
499
|
+
});
|
|
500
|
+
init(): void;
|
|
501
|
+
private fontFace;
|
|
502
|
+
paintBounds(b: Bounds, _frameIdx: number): Bounds;
|
|
503
|
+
paint(dc: DrawContext, b: Bounds, frameIdx: number): void;
|
|
504
|
+
frameCount(): number;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
/** Circle — port of pixlet render/circle.go. */
|
|
508
|
+
|
|
509
|
+
declare class Circle implements Widget {
|
|
510
|
+
child: Widget | null;
|
|
511
|
+
color: Color;
|
|
512
|
+
diameter: number;
|
|
513
|
+
constructor(props: {
|
|
514
|
+
child?: Widget | null;
|
|
515
|
+
color: Color;
|
|
516
|
+
diameter: number;
|
|
517
|
+
});
|
|
518
|
+
paintBounds(_b: Bounds, _frameIdx: number): Bounds;
|
|
519
|
+
paint(dc: DrawContext, _b: Bounds, frameIdx: number): void;
|
|
520
|
+
frameCount(): number;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
/** PieChart — port of pixlet render/pie_chart.go. */
|
|
524
|
+
|
|
525
|
+
declare class PieChart implements Widget {
|
|
526
|
+
colors: Color[];
|
|
527
|
+
weights: number[];
|
|
528
|
+
diameter: number;
|
|
529
|
+
constructor(props: {
|
|
530
|
+
colors: Color[];
|
|
531
|
+
weights: number[];
|
|
532
|
+
diameter: number;
|
|
533
|
+
});
|
|
534
|
+
paintBounds(_b: Bounds, _frameIdx: number): Bounds;
|
|
535
|
+
paint(dc: DrawContext, _b: Bounds, _frameIdx: number): void;
|
|
536
|
+
frameCount(): number;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
/** PolyLine — port of pixlet render/paths.go (Bresenham line enumeration). */
|
|
540
|
+
interface PathPoint {
|
|
541
|
+
x: number;
|
|
542
|
+
y: number;
|
|
543
|
+
}
|
|
544
|
+
declare class PolyLine {
|
|
545
|
+
vertices: PathPoint[];
|
|
546
|
+
private path;
|
|
547
|
+
constructor(vertices: PathPoint[]);
|
|
548
|
+
length(): number;
|
|
549
|
+
point(i: number): [number, number];
|
|
550
|
+
private compute;
|
|
551
|
+
private addLineSegment;
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
/**
|
|
555
|
+
* Plot — port of pixlet render/plot.go: XY line/scatter chart drawn with
|
|
556
|
+
* raw pixel stores along a Bresenham polyline. NaN in xLim/yLim means
|
|
557
|
+
* "infer from data", exactly like the Go NaN sentinels.
|
|
558
|
+
*
|
|
559
|
+
* Ported quirk: the scatter branch pokes untransformed coordinates (the Go
|
|
560
|
+
* code skips TransformPoint there) — keep it for parity.
|
|
561
|
+
*/
|
|
562
|
+
|
|
563
|
+
declare const DEFAULT_PLOT_COLOR: Color;
|
|
564
|
+
/** Surface fill gets line color dampened by this factor. */
|
|
565
|
+
declare const FILL_DAMP_FACTOR = 85;
|
|
566
|
+
declare class Plot implements Widget {
|
|
567
|
+
data: [number, number][];
|
|
568
|
+
width: number;
|
|
569
|
+
height: number;
|
|
570
|
+
color: Color | null;
|
|
571
|
+
colorInverted: Color | null;
|
|
572
|
+
xLim: [number, number];
|
|
573
|
+
yLim: [number, number];
|
|
574
|
+
fill: boolean;
|
|
575
|
+
chartType: string;
|
|
576
|
+
fillColor: Color | null;
|
|
577
|
+
fillColorInverted: Color | null;
|
|
578
|
+
private invThreshold;
|
|
579
|
+
constructor(props: {
|
|
580
|
+
data: [number, number][];
|
|
581
|
+
width: number;
|
|
582
|
+
height: number;
|
|
583
|
+
color?: Color | null;
|
|
584
|
+
colorInverted?: Color | null;
|
|
585
|
+
xLim?: [number, number];
|
|
586
|
+
yLim?: [number, number];
|
|
587
|
+
fill?: boolean;
|
|
588
|
+
chartType?: string;
|
|
589
|
+
fillColor?: Color | null;
|
|
590
|
+
fillColorInverted?: Color | null;
|
|
591
|
+
});
|
|
592
|
+
/** Port of plot.go computeLimits. */
|
|
593
|
+
computeLimits(): [number, number, number, number];
|
|
594
|
+
/** Port of plot.go translatePoints (also computes invThreshold). */
|
|
595
|
+
translatePoints(): PathPoint[];
|
|
596
|
+
paintBounds(_b: Bounds, _frameIdx: number): Bounds;
|
|
597
|
+
paint(dc: DrawContext, _b: Bounds, _frameIdx: number): void;
|
|
598
|
+
frameCount(): number;
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
/**
|
|
602
|
+
* PNG decoder (pure TS + fflate inflate). Supports the formats that matter
|
|
603
|
+
* for pixel-art app assets: bit depths 1/2/4/8, color types gray, RGB,
|
|
604
|
+
* palette (incl. tRNS), gray+alpha, RGBA; filters 0–4. 16-bit channels and
|
|
605
|
+
* Adam7 interlacing are rejected with a clear error.
|
|
606
|
+
*
|
|
607
|
+
* Output is straight (non-premultiplied) RGBA, like Go's image.Decode
|
|
608
|
+
* producing NRGBA — premultiplication happens when frames are converted to
|
|
609
|
+
* Canvas.
|
|
610
|
+
*/
|
|
611
|
+
interface DecodedImage {
|
|
612
|
+
width: number;
|
|
613
|
+
height: number;
|
|
614
|
+
/** Straight RGBA. */
|
|
615
|
+
rgba: Uint8Array;
|
|
616
|
+
}
|
|
617
|
+
declare function isPng(data: Uint8Array): boolean;
|
|
618
|
+
declare function decodePng(data: Uint8Array): DecodedImage;
|
|
619
|
+
|
|
620
|
+
/**
|
|
621
|
+
* GIF decoder (pure TS): header/LSD/GCT parsing, LZW, per-frame rects,
|
|
622
|
+
* local palettes, transparency, interlacing, disposal + delays. Produces
|
|
623
|
+
* raw frame data; frame *composition* (Go's Image.InitFromGIF quirks
|
|
624
|
+
* included) lives in the Image widget.
|
|
625
|
+
*/
|
|
626
|
+
declare const enum GifDisposal {
|
|
627
|
+
None = 0,// includes "unspecified"
|
|
628
|
+
DoNotDispose = 1,
|
|
629
|
+
Background = 2,
|
|
630
|
+
Previous = 3
|
|
631
|
+
}
|
|
632
|
+
interface GifFrame {
|
|
633
|
+
x: number;
|
|
634
|
+
y: number;
|
|
635
|
+
width: number;
|
|
636
|
+
height: number;
|
|
637
|
+
/** Palette indices, width*height. */
|
|
638
|
+
indices: Uint8Array;
|
|
639
|
+
/** RGB triples. */
|
|
640
|
+
palette: Uint8Array;
|
|
641
|
+
transparentIndex: number | null;
|
|
642
|
+
disposal: GifDisposal;
|
|
643
|
+
/** Delay in 1/100s (GIF native units, like Go's gif.GIF.Delay). */
|
|
644
|
+
delayCS: number;
|
|
645
|
+
}
|
|
646
|
+
interface DecodedGif {
|
|
647
|
+
width: number;
|
|
648
|
+
height: number;
|
|
649
|
+
frames: GifFrame[];
|
|
650
|
+
}
|
|
651
|
+
declare function isGif(data: Uint8Array): boolean;
|
|
652
|
+
declare function decodeGif(data: Uint8Array): DecodedGif;
|
|
653
|
+
|
|
654
|
+
export { Animation, type BdfFont, Bounds, Box, Canvas, Circle, Color, Color16, Column, type CrossAlign, type Curve, DEFAULT_FONT_FACE, DEFAULT_FRAME_HEIGHT, DEFAULT_FRAME_WIDTH, DEFAULT_MAX_FRAME_COUNT, DEFAULT_ORIGIN, DEFAULT_PLOT_COLOR, type DirectionMode, DrawContext, FILL_DAMP_FACTOR, type FillMode, type Glyph, type Insets, type Keyframe, type MainAlign, Marquee, type Origin, Padding, type PathPoint, PieChart, Plot, PolyLine, type RenderResult, Root, type RoundingMode, Row, Sequence, Stack, Text, type Transform, Transformation, Vector, Widget, WrappedText, applyRounding, buildWidget, cubicBezierCurve, decodeGif, decodePng, easeIn, easeInOut, easeOut, encodePng, findKeyframes, getFont, getFontList, interpolateTransforms, isGif, isPng, lerp, linearCurve, lookupGlyph, measureString, parseBdf, parseCurve, processKeyframes, renderRoot, renderText, rescale, wordWrap };
|