@takumi-rs/wasm 2.0.0-rc.4 → 2.0.0-rc.6
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/dist/export.cjs +36 -94
- package/dist/export.d.cts +47 -74
- package/dist/export.d.mts +47 -74
- package/dist/export.mjs +37 -95
- package/package.json +2 -2
- package/pkg/takumi_wasm_bg.wasm +0 -0
package/dist/export.cjs
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
let _takumi_rs_helpers = require("@takumi-rs/helpers");
|
|
6
|
+
let _takumi_rs_helpers_renderer = require("@takumi-rs/helpers/renderer");
|
|
6
7
|
//#region pkg/takumi_wasm.js
|
|
7
8
|
/**
|
|
8
9
|
* The main renderer for Takumi image rendering engine.
|
|
@@ -517,142 +518,83 @@ async function __wbg_init(module_or_path) {
|
|
|
517
518
|
}
|
|
518
519
|
//#endregion
|
|
519
520
|
//#region src/export.ts
|
|
520
|
-
async function resolveImageLoaders(images) {
|
|
521
|
-
const { sources = [], cache } = Array.isArray(images) ? { sources: images } : images;
|
|
522
|
-
const bySrc = /* @__PURE__ */ new Map();
|
|
523
|
-
for (const image of sources) bySrc.set(image.src, image);
|
|
524
|
-
return Promise.all([...bySrc.values()].map(async ({ src, data, cache: own }) => ({
|
|
525
|
-
src,
|
|
526
|
-
data: typeof data === "function" ? await data() : data,
|
|
527
|
-
cache: own ?? cache
|
|
528
|
-
})));
|
|
529
|
-
}
|
|
530
521
|
var Renderer = class {
|
|
531
|
-
fontsByKey = /* @__PURE__ */ new Map();
|
|
532
|
-
fontsByData = /* @__PURE__ */ new WeakMap();
|
|
533
522
|
inner = new Renderer$1();
|
|
534
|
-
|
|
535
|
-
return typeof key === "string" ? this.fontsByKey.get(key) : this.fontsByData.get(key);
|
|
536
|
-
}
|
|
537
|
-
setFont(key, family) {
|
|
538
|
-
if (typeof key === "string") this.fontsByKey.set(key, family);
|
|
539
|
-
else this.fontsByData.set(key, family);
|
|
540
|
-
}
|
|
541
|
-
deleteFont(key) {
|
|
542
|
-
if (typeof key === "string") this.fontsByKey.delete(key);
|
|
543
|
-
else this.fontsByData.delete(key);
|
|
544
|
-
}
|
|
545
|
-
async prepareFonts(fonts) {
|
|
546
|
-
if (!fonts) return;
|
|
547
|
-
const families = await Promise.all(fonts.map(this.registerFont.bind(this)));
|
|
548
|
-
return [...new Set(families.flat().map((f) => f.name))];
|
|
549
|
-
}
|
|
523
|
+
fonts = new _takumi_rs_helpers_renderer.FontRegistry((font) => this.inner.registerFont(font));
|
|
550
524
|
async render(node, options) {
|
|
551
|
-
const { fonts, fontFamilies, images, ...rest } = options ?? {};
|
|
552
|
-
|
|
525
|
+
const { fonts, fontFamilies, signal, images, ...rest } = options ?? {};
|
|
526
|
+
signal?.throwIfAborted();
|
|
527
|
+
const resolved = await this.fonts.resolveResources(fonts && (0, _takumi_rs_helpers.subsetFonts)({
|
|
553
528
|
fonts,
|
|
554
529
|
source: node
|
|
555
|
-
}));
|
|
556
|
-
|
|
530
|
+
}), images, fontFamilies);
|
|
531
|
+
signal?.throwIfAborted();
|
|
557
532
|
return this.inner.render(node, {
|
|
558
533
|
...rest,
|
|
559
|
-
|
|
560
|
-
fontFamilies: fontFamilies ?? registeredFamilies
|
|
534
|
+
...resolved
|
|
561
535
|
});
|
|
562
536
|
}
|
|
563
537
|
async renderAsDataUrl(node, options) {
|
|
564
|
-
const { fonts, fontFamilies, images, ...rest } = options ?? {};
|
|
565
|
-
|
|
538
|
+
const { fonts, fontFamilies, signal, images, ...rest } = options ?? {};
|
|
539
|
+
signal?.throwIfAborted();
|
|
540
|
+
const resolved = await this.fonts.resolveResources(fonts && (0, _takumi_rs_helpers.subsetFonts)({
|
|
566
541
|
fonts,
|
|
567
542
|
source: node
|
|
568
|
-
}));
|
|
569
|
-
|
|
543
|
+
}), images, fontFamilies);
|
|
544
|
+
signal?.throwIfAborted();
|
|
570
545
|
return this.inner.renderAsDataUrl(node, {
|
|
571
546
|
...rest,
|
|
572
|
-
|
|
573
|
-
fontFamilies: fontFamilies ?? registeredFamilies
|
|
547
|
+
...resolved
|
|
574
548
|
});
|
|
575
549
|
}
|
|
576
550
|
async renderSvg(node, options) {
|
|
577
|
-
const { fonts, fontFamilies, images, ...rest } = options ?? {};
|
|
578
|
-
|
|
551
|
+
const { fonts, fontFamilies, signal, images, ...rest } = options ?? {};
|
|
552
|
+
signal?.throwIfAborted();
|
|
553
|
+
const resolved = await this.fonts.resolveResources(fonts && (0, _takumi_rs_helpers.subsetFonts)({
|
|
579
554
|
fonts,
|
|
580
555
|
source: node
|
|
581
|
-
}));
|
|
582
|
-
|
|
556
|
+
}), images, fontFamilies);
|
|
557
|
+
signal?.throwIfAborted();
|
|
583
558
|
return this.inner.renderSvg(node, {
|
|
584
559
|
...rest,
|
|
585
|
-
|
|
586
|
-
fontFamilies: fontFamilies ?? registeredFamilies
|
|
560
|
+
...resolved
|
|
587
561
|
});
|
|
588
562
|
}
|
|
589
563
|
async measure(node, options) {
|
|
590
|
-
const { fonts, fontFamilies, images, ...rest } = options ?? {};
|
|
591
|
-
|
|
564
|
+
const { fonts, fontFamilies, signal, images, ...rest } = options ?? {};
|
|
565
|
+
signal?.throwIfAborted();
|
|
566
|
+
const resolved = await this.fonts.resolveResources(fonts && (0, _takumi_rs_helpers.subsetFonts)({
|
|
592
567
|
fonts,
|
|
593
568
|
source: node
|
|
594
|
-
}));
|
|
595
|
-
|
|
569
|
+
}), images, fontFamilies);
|
|
570
|
+
signal?.throwIfAborted();
|
|
596
571
|
return this.inner.measure(node, {
|
|
597
572
|
...rest,
|
|
598
|
-
|
|
599
|
-
fontFamilies: fontFamilies ?? registeredFamilies
|
|
573
|
+
...resolved
|
|
600
574
|
});
|
|
601
575
|
}
|
|
602
576
|
async renderAnimation(options) {
|
|
603
|
-
const { fonts, fontFamilies, images, ...rest } = options;
|
|
577
|
+
const { fonts, fontFamilies, signal, images, ...rest } = options;
|
|
578
|
+
signal?.throwIfAborted();
|
|
604
579
|
const nodes = options.scenes.map((scene) => scene.node);
|
|
605
|
-
const
|
|
580
|
+
const resolved = await this.fonts.resolveResources(fonts && (0, _takumi_rs_helpers.subsetFonts)({
|
|
606
581
|
fonts,
|
|
607
582
|
source: nodes
|
|
608
|
-
}));
|
|
609
|
-
|
|
583
|
+
}), images, fontFamilies);
|
|
584
|
+
signal?.throwIfAborted();
|
|
610
585
|
return this.inner.renderAnimation({
|
|
611
586
|
...rest,
|
|
612
|
-
|
|
613
|
-
fontFamilies: fontFamilies ?? registeredFamilies
|
|
587
|
+
...resolved
|
|
614
588
|
});
|
|
615
589
|
}
|
|
590
|
+
registerFont(font) {
|
|
591
|
+
return this.fonts.register(font);
|
|
592
|
+
}
|
|
593
|
+
/** Releases the underlying wasm renderer's memory. */
|
|
616
594
|
free() {
|
|
617
595
|
this.inner.free();
|
|
618
596
|
}
|
|
619
|
-
async registerFont(font) {
|
|
620
|
-
const loader = typeof font === "string" ? (0, _takumi_rs_helpers.fontFromUrl)(font) : font;
|
|
621
|
-
const key = createFontKey(loader);
|
|
622
|
-
const cached = this.getFont(key);
|
|
623
|
-
if (cached) return cached;
|
|
624
|
-
const extracted = extractFontBuffer(loader);
|
|
625
|
-
const register = (data) => this.inner.registerFont(isBuffer(loader) ? data : {
|
|
626
|
-
...loader,
|
|
627
|
-
data
|
|
628
|
-
});
|
|
629
|
-
if (isBuffer(extracted)) {
|
|
630
|
-
const binded = register(extracted);
|
|
631
|
-
this.setFont(key, Promise.resolve(binded));
|
|
632
|
-
return binded;
|
|
633
|
-
}
|
|
634
|
-
const promise = extracted.then(register).catch((error) => {
|
|
635
|
-
this.deleteFont(key);
|
|
636
|
-
throw error;
|
|
637
|
-
});
|
|
638
|
-
this.setFont(key, promise);
|
|
639
|
-
return promise;
|
|
640
|
-
}
|
|
641
597
|
};
|
|
642
|
-
function extractFontBuffer(font) {
|
|
643
|
-
if (isBuffer(font)) return font;
|
|
644
|
-
if (typeof font.data !== "function") return font.data;
|
|
645
|
-
return font.data();
|
|
646
|
-
}
|
|
647
|
-
function createFontKey(font) {
|
|
648
|
-
if (isBuffer(font)) return font;
|
|
649
|
-
if ("key" in font && font.key) return font.key;
|
|
650
|
-
if (typeof font.data === "function") return `${font.name ?? ""}:${font.weight ?? ""}:${font.style ?? ""}`;
|
|
651
|
-
return font.data;
|
|
652
|
-
}
|
|
653
|
-
function isBuffer(data) {
|
|
654
|
-
return data instanceof Uint8Array || data instanceof ArrayBuffer || typeof Buffer !== "undefined" && Buffer.isBuffer(data);
|
|
655
|
-
}
|
|
656
598
|
//#endregion
|
|
657
599
|
exports.Renderer = Renderer;
|
|
658
600
|
exports.default = __wbg_init;
|
package/dist/export.d.cts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ContainerNode, ImageNode, Node, Node as Node$1, NodeMetadata, TextNode } from "@takumi-rs/helpers";
|
|
2
2
|
import { Properties } from "csstype";
|
|
3
|
+
import { AnimationOutputFormatOptions, AnimationOutputFormatOptions as AnimationOutputFormatOptions$1, FontLoader, FontLoader as FontLoader$1, ImageLoader, ImagesInput, ImagesInput as ImagesInput$1, OutputFormatOptions, OutputFormatOptions as OutputFormatOptions$1 } from "@takumi-rs/helpers/renderer";
|
|
3
4
|
|
|
4
5
|
//#region pkg/takumi_wasm.d.ts
|
|
5
6
|
type ByteBuf = Uint8Array | ArrayBuffer | Buffer;
|
|
@@ -12,6 +13,14 @@ type KeyframesRuleList = {
|
|
|
12
13
|
}[];
|
|
13
14
|
}[];
|
|
14
15
|
type Keyframes = KeyframesMap | KeyframesRuleList;
|
|
16
|
+
/** Output format for static images. */
|
|
17
|
+
type OutputFormat = "png" | "jpeg" | "webp" | "ico" | "raw";
|
|
18
|
+
/** Output format for animated images. */
|
|
19
|
+
type AnimationOutputFormat = "webp" | "apng" | "gif";
|
|
20
|
+
/** The output dithering algorithm. */
|
|
21
|
+
type DitheringAlgorithm = "none" | "ordered-bayer" | "floyd-steinberg";
|
|
22
|
+
/** Cache policy for a decoded image. Defaults to `"auto"`. */
|
|
23
|
+
type ImageCacheMode = "auto" | "none";
|
|
15
24
|
type RenderOptions$1 = {
|
|
16
25
|
/**
|
|
17
26
|
* The width of the image. If not provided, the width will be automatically calculated based on the content.
|
|
@@ -25,11 +34,17 @@ type RenderOptions$1 = {
|
|
|
25
34
|
* The format of the image.
|
|
26
35
|
* @default "png"
|
|
27
36
|
*/
|
|
28
|
-
format?:
|
|
37
|
+
format?: OutputFormat;
|
|
29
38
|
/**
|
|
30
|
-
* The quality of
|
|
39
|
+
* The quality of lossy formats (0-100). For JPEG; on wasm, WebP is always
|
|
40
|
+
* lossless so this is ignored for WebP.
|
|
31
41
|
*/
|
|
32
42
|
quality?: number;
|
|
43
|
+
/**
|
|
44
|
+
* Encode WebP losslessly. On wasm, WebP is always lossless, so this is
|
|
45
|
+
* accepted for parity with the native backend but has no effect.
|
|
46
|
+
*/
|
|
47
|
+
lossless?: boolean;
|
|
33
48
|
/**
|
|
34
49
|
* Images keyed by `src`, each carrying raw bytes. Provided up front and used
|
|
35
50
|
* in place of fetching external `src` URLs during rendering.
|
|
@@ -60,26 +75,33 @@ type RenderOptions$1 = {
|
|
|
60
75
|
* The output dithering algorithm.
|
|
61
76
|
* @default "none"
|
|
62
77
|
*/
|
|
63
|
-
dithering?:
|
|
78
|
+
dithering?: DitheringAlgorithm;
|
|
64
79
|
/**
|
|
65
80
|
* Per-render font stack: ordered family names used as the fallback chain.
|
|
66
81
|
* Defaults to all registered families in registration order.
|
|
67
82
|
*/
|
|
68
|
-
fontFamilies?: string[];
|
|
83
|
+
fontFamilies?: string[]; /** Default BCP-47 language applied to the root, inherited by nodes without their own lang. */
|
|
84
|
+
lang?: string;
|
|
69
85
|
};
|
|
70
86
|
/**
|
|
71
87
|
* SVG is a vector format, so the raster-only knobs do not apply.
|
|
72
88
|
*/
|
|
73
|
-
type SvgRenderOptions$1 = Omit<RenderOptions$1, "format" | "quality" | "drawDebugBorder" | "devicePixelRatio" | "dithering">;
|
|
89
|
+
type SvgRenderOptions$1 = Omit<RenderOptions$1, "format" | "quality" | "lossless" | "drawDebugBorder" | "devicePixelRatio" | "dithering">;
|
|
74
90
|
type RenderAnimationOptions$1 = {
|
|
75
91
|
scenes: AnimationScene[];
|
|
76
92
|
width: number;
|
|
77
93
|
height: number;
|
|
78
|
-
format?:
|
|
94
|
+
format?: AnimationOutputFormat;
|
|
79
95
|
/**
|
|
80
|
-
* The quality of WebP
|
|
96
|
+
* The quality of lossy WebP (0-100). Ignored for APNG and GIF; on wasm, WebP
|
|
97
|
+
* is always lossless so this is ignored for WebP too.
|
|
81
98
|
*/
|
|
82
99
|
quality?: number;
|
|
100
|
+
/**
|
|
101
|
+
* Encode WebP losslessly. On wasm, animated WebP is always lossless, so this
|
|
102
|
+
* is accepted for parity with the native backend but has no effect.
|
|
103
|
+
*/
|
|
104
|
+
lossless?: boolean;
|
|
83
105
|
/**
|
|
84
106
|
* Images keyed by `src`, each carrying raw bytes. Provided up front and used
|
|
85
107
|
* in place of fetching external `src` URLs during rendering.
|
|
@@ -103,7 +125,8 @@ type RenderAnimationOptions$1 = {
|
|
|
103
125
|
* Per-render font stack: ordered family names used as the fallback chain.
|
|
104
126
|
* Defaults to all registered families in registration order.
|
|
105
127
|
*/
|
|
106
|
-
fontFamilies?: string[];
|
|
128
|
+
fontFamilies?: string[]; /** Default BCP-47 language applied to the root, inherited by nodes without their own lang. */
|
|
129
|
+
lang?: string;
|
|
107
130
|
};
|
|
108
131
|
type FontDetails = {
|
|
109
132
|
name?: string;
|
|
@@ -120,7 +143,7 @@ type FontDetails = {
|
|
|
120
143
|
type ImageSource = {
|
|
121
144
|
src: string;
|
|
122
145
|
data: ByteBuf; /** Cache policy for the decoded image. Defaults to `"auto"`. */
|
|
123
|
-
cache?:
|
|
146
|
+
cache?: ImageCacheMode;
|
|
124
147
|
};
|
|
125
148
|
type KeyframeRule = {
|
|
126
149
|
offsets: number[];
|
|
@@ -204,82 +227,32 @@ declare function __wbg_init(module_or_path?: {
|
|
|
204
227
|
} | InitInput | Promise<InitInput>): Promise<InitOutput>;
|
|
205
228
|
//#endregion
|
|
206
229
|
//#region src/export.d.ts
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
type FontLoader = string | Font | (Omit<FontDetails, "data"> & {
|
|
212
|
-
data: () => Promise<FontDetails["data"]> | FontDetails["data"]; /** Inclusive codepoint ranges this face covers; lets `render` skip it when unused. */
|
|
213
|
-
ranges?: [number, number][];
|
|
214
|
-
} & ({
|
|
215
|
-
key: string;
|
|
216
|
-
} | {
|
|
217
|
-
name: string;
|
|
218
|
-
}));
|
|
219
|
-
type ImageLoaderData = ImageSource["data"];
|
|
220
|
-
type ImageLoader = Omit<ImageSource, "data"> & {
|
|
221
|
-
data: ImageLoaderData | (() => ImageLoaderData | Promise<ImageLoaderData>);
|
|
222
|
-
};
|
|
223
|
-
/** Images for a render: pre-fetched entries, or a group with a decode-cache default. */
|
|
224
|
-
type ImagesInput = ImageLoader[] | {
|
|
225
|
-
/** Pre-fetched entries, same as the array form. */sources?: ImageLoader[]; /** Decode-cache default for every image this render; a source's own `cache` wins. */
|
|
226
|
-
cache?: NonNullable<ImageLoader["cache"]>;
|
|
227
|
-
};
|
|
228
|
-
/**
|
|
229
|
-
* Output format. Format-specific options live on the variant that supports them,
|
|
230
|
-
* so `quality` cannot be paired with a lossless format. On wasm, WebP is always
|
|
231
|
-
* lossless (lossy WebP is native-only).
|
|
232
|
-
*/
|
|
233
|
-
type OutputFormatOptions = {
|
|
234
|
-
format?: "png";
|
|
235
|
-
} | {
|
|
236
|
-
format: "jpeg";
|
|
237
|
-
quality?: number;
|
|
238
|
-
} | {
|
|
239
|
-
format: "webp";
|
|
240
|
-
} | {
|
|
241
|
-
format: "ico";
|
|
242
|
-
} | {
|
|
243
|
-
format: "raw";
|
|
244
|
-
};
|
|
245
|
-
type RenderOptions = Omit<RenderOptions$1, "images" | "format" | "quality"> & OutputFormatOptions & {
|
|
246
|
-
fonts?: FontLoader[];
|
|
247
|
-
images?: ImagesInput;
|
|
248
|
-
};
|
|
249
|
-
/**
|
|
250
|
-
* Animation output format. On wasm, WebP animation is always lossless (lossy
|
|
251
|
-
* WebP is native-only).
|
|
252
|
-
*/
|
|
253
|
-
type AnimationOutputFormatOptions = {
|
|
254
|
-
format?: "webp";
|
|
255
|
-
} | {
|
|
256
|
-
format: "apng";
|
|
257
|
-
} | {
|
|
258
|
-
format: "gif";
|
|
230
|
+
type RenderOptions = Omit<RenderOptions$1, "images" | "format" | "quality" | "lossless"> & OutputFormatOptions$1 & {
|
|
231
|
+
fonts?: FontLoader$1[];
|
|
232
|
+
signal?: AbortSignal;
|
|
233
|
+
images?: ImagesInput$1;
|
|
259
234
|
};
|
|
260
|
-
type RenderAnimationOptions = Omit<RenderAnimationOptions$1, "images" | "format"> & AnimationOutputFormatOptions & {
|
|
261
|
-
fonts?: FontLoader[];
|
|
262
|
-
|
|
235
|
+
type RenderAnimationOptions = Omit<RenderAnimationOptions$1, "images" | "format" | "quality" | "lossless"> & AnimationOutputFormatOptions$1 & {
|
|
236
|
+
fonts?: FontLoader$1[];
|
|
237
|
+
signal?: AbortSignal;
|
|
238
|
+
images?: ImagesInput$1;
|
|
263
239
|
};
|
|
264
240
|
type SvgRenderOptions = Omit<SvgRenderOptions$1, "images"> & {
|
|
265
|
-
fonts?: FontLoader[];
|
|
266
|
-
|
|
241
|
+
fonts?: FontLoader$1[];
|
|
242
|
+
signal?: AbortSignal;
|
|
243
|
+
images?: ImagesInput$1;
|
|
267
244
|
};
|
|
268
245
|
declare class Renderer {
|
|
269
|
-
private fontsByKey;
|
|
270
|
-
private fontsByData;
|
|
271
246
|
private inner;
|
|
272
|
-
private
|
|
273
|
-
private setFont;
|
|
274
|
-
private deleteFont;
|
|
275
|
-
private prepareFonts;
|
|
247
|
+
private fonts;
|
|
276
248
|
render(node: Node, options?: RenderOptions): Promise<Uint8Array<ArrayBufferLike>>;
|
|
277
249
|
renderAsDataUrl(node: Node, options?: RenderOptions): Promise<string>;
|
|
278
250
|
renderSvg(node: Node, options?: SvgRenderOptions): Promise<string>;
|
|
279
251
|
measure(node: Node, options?: RenderOptions): Promise<MeasuredNode>;
|
|
280
252
|
renderAnimation(options: RenderAnimationOptions): Promise<Uint8Array<ArrayBufferLike>>;
|
|
253
|
+
registerFont(font: FontLoader$1): any;
|
|
254
|
+
/** Releases the underlying wasm renderer's memory. */
|
|
281
255
|
free(): void;
|
|
282
|
-
registerFont(font: FontLoader): Promise<RegisteredFamily[]>;
|
|
283
256
|
}
|
|
284
257
|
//#endregion
|
|
285
|
-
export { AnimationOutputFormatOptions, AnimationScene, ByteBuf, ContainerNode, Font, FontDetails, FontLoader, ImageLoader, ImageNode, ImageSource, ImagesInput, InitInput, InitOutput, KeyframeRule, Keyframes, KeyframesMap, KeyframesRule, KeyframesRuleList, MeasuredNode, MeasuredTextRun, type Node, NodeMetadata, OutputFormatOptions, RegisteredFace, RegisteredFamily, RenderAnimationOptions, RenderOptions, Renderer, SvgRenderOptions, SyncInitInput, TextNode, __wbg_init as default, initSync };
|
|
258
|
+
export { AnimationOutputFormat, type AnimationOutputFormatOptions, AnimationScene, ByteBuf, ContainerNode, DitheringAlgorithm, Font, FontDetails, type FontLoader, ImageCacheMode, type ImageLoader, ImageNode, ImageSource, type ImagesInput, InitInput, InitOutput, KeyframeRule, Keyframes, KeyframesMap, KeyframesRule, KeyframesRuleList, MeasuredNode, MeasuredTextRun, type Node, NodeMetadata, OutputFormat, type OutputFormatOptions, RegisteredFace, RegisteredFamily, RenderAnimationOptions, RenderOptions, Renderer, SvgRenderOptions, SyncInitInput, TextNode, __wbg_init as default, initSync };
|
package/dist/export.d.mts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ContainerNode, ImageNode, Node, Node as Node$1, NodeMetadata, TextNode } from "@takumi-rs/helpers";
|
|
2
|
+
import { AnimationOutputFormatOptions, AnimationOutputFormatOptions as AnimationOutputFormatOptions$1, FontLoader, FontLoader as FontLoader$1, ImageLoader, ImagesInput, ImagesInput as ImagesInput$1, OutputFormatOptions, OutputFormatOptions as OutputFormatOptions$1 } from "@takumi-rs/helpers/renderer";
|
|
2
3
|
import { Properties } from "csstype";
|
|
3
4
|
|
|
4
5
|
//#region pkg/takumi_wasm.d.ts
|
|
@@ -12,6 +13,14 @@ type KeyframesRuleList = {
|
|
|
12
13
|
}[];
|
|
13
14
|
}[];
|
|
14
15
|
type Keyframes = KeyframesMap | KeyframesRuleList;
|
|
16
|
+
/** Output format for static images. */
|
|
17
|
+
type OutputFormat = "png" | "jpeg" | "webp" | "ico" | "raw";
|
|
18
|
+
/** Output format for animated images. */
|
|
19
|
+
type AnimationOutputFormat = "webp" | "apng" | "gif";
|
|
20
|
+
/** The output dithering algorithm. */
|
|
21
|
+
type DitheringAlgorithm = "none" | "ordered-bayer" | "floyd-steinberg";
|
|
22
|
+
/** Cache policy for a decoded image. Defaults to `"auto"`. */
|
|
23
|
+
type ImageCacheMode = "auto" | "none";
|
|
15
24
|
type RenderOptions$1 = {
|
|
16
25
|
/**
|
|
17
26
|
* The width of the image. If not provided, the width will be automatically calculated based on the content.
|
|
@@ -25,11 +34,17 @@ type RenderOptions$1 = {
|
|
|
25
34
|
* The format of the image.
|
|
26
35
|
* @default "png"
|
|
27
36
|
*/
|
|
28
|
-
format?:
|
|
37
|
+
format?: OutputFormat;
|
|
29
38
|
/**
|
|
30
|
-
* The quality of
|
|
39
|
+
* The quality of lossy formats (0-100). For JPEG; on wasm, WebP is always
|
|
40
|
+
* lossless so this is ignored for WebP.
|
|
31
41
|
*/
|
|
32
42
|
quality?: number;
|
|
43
|
+
/**
|
|
44
|
+
* Encode WebP losslessly. On wasm, WebP is always lossless, so this is
|
|
45
|
+
* accepted for parity with the native backend but has no effect.
|
|
46
|
+
*/
|
|
47
|
+
lossless?: boolean;
|
|
33
48
|
/**
|
|
34
49
|
* Images keyed by `src`, each carrying raw bytes. Provided up front and used
|
|
35
50
|
* in place of fetching external `src` URLs during rendering.
|
|
@@ -60,26 +75,33 @@ type RenderOptions$1 = {
|
|
|
60
75
|
* The output dithering algorithm.
|
|
61
76
|
* @default "none"
|
|
62
77
|
*/
|
|
63
|
-
dithering?:
|
|
78
|
+
dithering?: DitheringAlgorithm;
|
|
64
79
|
/**
|
|
65
80
|
* Per-render font stack: ordered family names used as the fallback chain.
|
|
66
81
|
* Defaults to all registered families in registration order.
|
|
67
82
|
*/
|
|
68
|
-
fontFamilies?: string[];
|
|
83
|
+
fontFamilies?: string[]; /** Default BCP-47 language applied to the root, inherited by nodes without their own lang. */
|
|
84
|
+
lang?: string;
|
|
69
85
|
};
|
|
70
86
|
/**
|
|
71
87
|
* SVG is a vector format, so the raster-only knobs do not apply.
|
|
72
88
|
*/
|
|
73
|
-
type SvgRenderOptions$1 = Omit<RenderOptions$1, "format" | "quality" | "drawDebugBorder" | "devicePixelRatio" | "dithering">;
|
|
89
|
+
type SvgRenderOptions$1 = Omit<RenderOptions$1, "format" | "quality" | "lossless" | "drawDebugBorder" | "devicePixelRatio" | "dithering">;
|
|
74
90
|
type RenderAnimationOptions$1 = {
|
|
75
91
|
scenes: AnimationScene[];
|
|
76
92
|
width: number;
|
|
77
93
|
height: number;
|
|
78
|
-
format?:
|
|
94
|
+
format?: AnimationOutputFormat;
|
|
79
95
|
/**
|
|
80
|
-
* The quality of WebP
|
|
96
|
+
* The quality of lossy WebP (0-100). Ignored for APNG and GIF; on wasm, WebP
|
|
97
|
+
* is always lossless so this is ignored for WebP too.
|
|
81
98
|
*/
|
|
82
99
|
quality?: number;
|
|
100
|
+
/**
|
|
101
|
+
* Encode WebP losslessly. On wasm, animated WebP is always lossless, so this
|
|
102
|
+
* is accepted for parity with the native backend but has no effect.
|
|
103
|
+
*/
|
|
104
|
+
lossless?: boolean;
|
|
83
105
|
/**
|
|
84
106
|
* Images keyed by `src`, each carrying raw bytes. Provided up front and used
|
|
85
107
|
* in place of fetching external `src` URLs during rendering.
|
|
@@ -103,7 +125,8 @@ type RenderAnimationOptions$1 = {
|
|
|
103
125
|
* Per-render font stack: ordered family names used as the fallback chain.
|
|
104
126
|
* Defaults to all registered families in registration order.
|
|
105
127
|
*/
|
|
106
|
-
fontFamilies?: string[];
|
|
128
|
+
fontFamilies?: string[]; /** Default BCP-47 language applied to the root, inherited by nodes without their own lang. */
|
|
129
|
+
lang?: string;
|
|
107
130
|
};
|
|
108
131
|
type FontDetails = {
|
|
109
132
|
name?: string;
|
|
@@ -120,7 +143,7 @@ type FontDetails = {
|
|
|
120
143
|
type ImageSource = {
|
|
121
144
|
src: string;
|
|
122
145
|
data: ByteBuf; /** Cache policy for the decoded image. Defaults to `"auto"`. */
|
|
123
|
-
cache?:
|
|
146
|
+
cache?: ImageCacheMode;
|
|
124
147
|
};
|
|
125
148
|
type KeyframeRule = {
|
|
126
149
|
offsets: number[];
|
|
@@ -204,82 +227,32 @@ declare function __wbg_init(module_or_path?: {
|
|
|
204
227
|
} | InitInput | Promise<InitInput>): Promise<InitOutput>;
|
|
205
228
|
//#endregion
|
|
206
229
|
//#region src/export.d.ts
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
type FontLoader = string | Font | (Omit<FontDetails, "data"> & {
|
|
212
|
-
data: () => Promise<FontDetails["data"]> | FontDetails["data"]; /** Inclusive codepoint ranges this face covers; lets `render` skip it when unused. */
|
|
213
|
-
ranges?: [number, number][];
|
|
214
|
-
} & ({
|
|
215
|
-
key: string;
|
|
216
|
-
} | {
|
|
217
|
-
name: string;
|
|
218
|
-
}));
|
|
219
|
-
type ImageLoaderData = ImageSource["data"];
|
|
220
|
-
type ImageLoader = Omit<ImageSource, "data"> & {
|
|
221
|
-
data: ImageLoaderData | (() => ImageLoaderData | Promise<ImageLoaderData>);
|
|
222
|
-
};
|
|
223
|
-
/** Images for a render: pre-fetched entries, or a group with a decode-cache default. */
|
|
224
|
-
type ImagesInput = ImageLoader[] | {
|
|
225
|
-
/** Pre-fetched entries, same as the array form. */sources?: ImageLoader[]; /** Decode-cache default for every image this render; a source's own `cache` wins. */
|
|
226
|
-
cache?: NonNullable<ImageLoader["cache"]>;
|
|
227
|
-
};
|
|
228
|
-
/**
|
|
229
|
-
* Output format. Format-specific options live on the variant that supports them,
|
|
230
|
-
* so `quality` cannot be paired with a lossless format. On wasm, WebP is always
|
|
231
|
-
* lossless (lossy WebP is native-only).
|
|
232
|
-
*/
|
|
233
|
-
type OutputFormatOptions = {
|
|
234
|
-
format?: "png";
|
|
235
|
-
} | {
|
|
236
|
-
format: "jpeg";
|
|
237
|
-
quality?: number;
|
|
238
|
-
} | {
|
|
239
|
-
format: "webp";
|
|
240
|
-
} | {
|
|
241
|
-
format: "ico";
|
|
242
|
-
} | {
|
|
243
|
-
format: "raw";
|
|
244
|
-
};
|
|
245
|
-
type RenderOptions = Omit<RenderOptions$1, "images" | "format" | "quality"> & OutputFormatOptions & {
|
|
246
|
-
fonts?: FontLoader[];
|
|
247
|
-
images?: ImagesInput;
|
|
248
|
-
};
|
|
249
|
-
/**
|
|
250
|
-
* Animation output format. On wasm, WebP animation is always lossless (lossy
|
|
251
|
-
* WebP is native-only).
|
|
252
|
-
*/
|
|
253
|
-
type AnimationOutputFormatOptions = {
|
|
254
|
-
format?: "webp";
|
|
255
|
-
} | {
|
|
256
|
-
format: "apng";
|
|
257
|
-
} | {
|
|
258
|
-
format: "gif";
|
|
230
|
+
type RenderOptions = Omit<RenderOptions$1, "images" | "format" | "quality" | "lossless"> & OutputFormatOptions$1 & {
|
|
231
|
+
fonts?: FontLoader$1[];
|
|
232
|
+
signal?: AbortSignal;
|
|
233
|
+
images?: ImagesInput$1;
|
|
259
234
|
};
|
|
260
|
-
type RenderAnimationOptions = Omit<RenderAnimationOptions$1, "images" | "format"> & AnimationOutputFormatOptions & {
|
|
261
|
-
fonts?: FontLoader[];
|
|
262
|
-
|
|
235
|
+
type RenderAnimationOptions = Omit<RenderAnimationOptions$1, "images" | "format" | "quality" | "lossless"> & AnimationOutputFormatOptions$1 & {
|
|
236
|
+
fonts?: FontLoader$1[];
|
|
237
|
+
signal?: AbortSignal;
|
|
238
|
+
images?: ImagesInput$1;
|
|
263
239
|
};
|
|
264
240
|
type SvgRenderOptions = Omit<SvgRenderOptions$1, "images"> & {
|
|
265
|
-
fonts?: FontLoader[];
|
|
266
|
-
|
|
241
|
+
fonts?: FontLoader$1[];
|
|
242
|
+
signal?: AbortSignal;
|
|
243
|
+
images?: ImagesInput$1;
|
|
267
244
|
};
|
|
268
245
|
declare class Renderer {
|
|
269
|
-
private fontsByKey;
|
|
270
|
-
private fontsByData;
|
|
271
246
|
private inner;
|
|
272
|
-
private
|
|
273
|
-
private setFont;
|
|
274
|
-
private deleteFont;
|
|
275
|
-
private prepareFonts;
|
|
247
|
+
private fonts;
|
|
276
248
|
render(node: Node, options?: RenderOptions): Promise<Uint8Array<ArrayBufferLike>>;
|
|
277
249
|
renderAsDataUrl(node: Node, options?: RenderOptions): Promise<string>;
|
|
278
250
|
renderSvg(node: Node, options?: SvgRenderOptions): Promise<string>;
|
|
279
251
|
measure(node: Node, options?: RenderOptions): Promise<MeasuredNode>;
|
|
280
252
|
renderAnimation(options: RenderAnimationOptions): Promise<Uint8Array<ArrayBufferLike>>;
|
|
253
|
+
registerFont(font: FontLoader$1): any;
|
|
254
|
+
/** Releases the underlying wasm renderer's memory. */
|
|
281
255
|
free(): void;
|
|
282
|
-
registerFont(font: FontLoader): Promise<RegisteredFamily[]>;
|
|
283
256
|
}
|
|
284
257
|
//#endregion
|
|
285
|
-
export { AnimationOutputFormatOptions, AnimationScene, ByteBuf, ContainerNode, Font, FontDetails, FontLoader, ImageLoader, ImageNode, ImageSource, ImagesInput, InitInput, InitOutput, KeyframeRule, Keyframes, KeyframesMap, KeyframesRule, KeyframesRuleList, MeasuredNode, MeasuredTextRun, type Node, NodeMetadata, OutputFormatOptions, RegisteredFace, RegisteredFamily, RenderAnimationOptions, RenderOptions, Renderer, SvgRenderOptions, SyncInitInput, TextNode, __wbg_init as default, initSync };
|
|
258
|
+
export { AnimationOutputFormat, type AnimationOutputFormatOptions, AnimationScene, ByteBuf, ContainerNode, DitheringAlgorithm, Font, FontDetails, type FontLoader, ImageCacheMode, type ImageLoader, ImageNode, ImageSource, type ImagesInput, InitInput, InitOutput, KeyframeRule, Keyframes, KeyframesMap, KeyframesRule, KeyframesRuleList, MeasuredNode, MeasuredTextRun, type Node, NodeMetadata, OutputFormat, type OutputFormatOptions, RegisteredFace, RegisteredFamily, RenderAnimationOptions, RenderOptions, Renderer, SvgRenderOptions, SyncInitInput, TextNode, __wbg_init as default, initSync };
|
package/dist/export.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { subsetFonts } from "@takumi-rs/helpers";
|
|
2
|
+
import { FontRegistry } from "@takumi-rs/helpers/renderer";
|
|
2
3
|
//#region pkg/takumi_wasm.js
|
|
3
4
|
/**
|
|
4
5
|
* The main renderer for Takumi image rendering engine.
|
|
@@ -513,141 +514,82 @@ async function __wbg_init(module_or_path) {
|
|
|
513
514
|
}
|
|
514
515
|
//#endregion
|
|
515
516
|
//#region src/export.ts
|
|
516
|
-
async function resolveImageLoaders(images) {
|
|
517
|
-
const { sources = [], cache } = Array.isArray(images) ? { sources: images } : images;
|
|
518
|
-
const bySrc = /* @__PURE__ */ new Map();
|
|
519
|
-
for (const image of sources) bySrc.set(image.src, image);
|
|
520
|
-
return Promise.all([...bySrc.values()].map(async ({ src, data, cache: own }) => ({
|
|
521
|
-
src,
|
|
522
|
-
data: typeof data === "function" ? await data() : data,
|
|
523
|
-
cache: own ?? cache
|
|
524
|
-
})));
|
|
525
|
-
}
|
|
526
517
|
var Renderer = class {
|
|
527
|
-
fontsByKey = /* @__PURE__ */ new Map();
|
|
528
|
-
fontsByData = /* @__PURE__ */ new WeakMap();
|
|
529
518
|
inner = new Renderer$1();
|
|
530
|
-
|
|
531
|
-
return typeof key === "string" ? this.fontsByKey.get(key) : this.fontsByData.get(key);
|
|
532
|
-
}
|
|
533
|
-
setFont(key, family) {
|
|
534
|
-
if (typeof key === "string") this.fontsByKey.set(key, family);
|
|
535
|
-
else this.fontsByData.set(key, family);
|
|
536
|
-
}
|
|
537
|
-
deleteFont(key) {
|
|
538
|
-
if (typeof key === "string") this.fontsByKey.delete(key);
|
|
539
|
-
else this.fontsByData.delete(key);
|
|
540
|
-
}
|
|
541
|
-
async prepareFonts(fonts) {
|
|
542
|
-
if (!fonts) return;
|
|
543
|
-
const families = await Promise.all(fonts.map(this.registerFont.bind(this)));
|
|
544
|
-
return [...new Set(families.flat().map((f) => f.name))];
|
|
545
|
-
}
|
|
519
|
+
fonts = new FontRegistry((font) => this.inner.registerFont(font));
|
|
546
520
|
async render(node, options) {
|
|
547
|
-
const { fonts, fontFamilies, images, ...rest } = options ?? {};
|
|
548
|
-
|
|
521
|
+
const { fonts, fontFamilies, signal, images, ...rest } = options ?? {};
|
|
522
|
+
signal?.throwIfAborted();
|
|
523
|
+
const resolved = await this.fonts.resolveResources(fonts && subsetFonts({
|
|
549
524
|
fonts,
|
|
550
525
|
source: node
|
|
551
|
-
}));
|
|
552
|
-
|
|
526
|
+
}), images, fontFamilies);
|
|
527
|
+
signal?.throwIfAborted();
|
|
553
528
|
return this.inner.render(node, {
|
|
554
529
|
...rest,
|
|
555
|
-
|
|
556
|
-
fontFamilies: fontFamilies ?? registeredFamilies
|
|
530
|
+
...resolved
|
|
557
531
|
});
|
|
558
532
|
}
|
|
559
533
|
async renderAsDataUrl(node, options) {
|
|
560
|
-
const { fonts, fontFamilies, images, ...rest } = options ?? {};
|
|
561
|
-
|
|
534
|
+
const { fonts, fontFamilies, signal, images, ...rest } = options ?? {};
|
|
535
|
+
signal?.throwIfAborted();
|
|
536
|
+
const resolved = await this.fonts.resolveResources(fonts && subsetFonts({
|
|
562
537
|
fonts,
|
|
563
538
|
source: node
|
|
564
|
-
}));
|
|
565
|
-
|
|
539
|
+
}), images, fontFamilies);
|
|
540
|
+
signal?.throwIfAborted();
|
|
566
541
|
return this.inner.renderAsDataUrl(node, {
|
|
567
542
|
...rest,
|
|
568
|
-
|
|
569
|
-
fontFamilies: fontFamilies ?? registeredFamilies
|
|
543
|
+
...resolved
|
|
570
544
|
});
|
|
571
545
|
}
|
|
572
546
|
async renderSvg(node, options) {
|
|
573
|
-
const { fonts, fontFamilies, images, ...rest } = options ?? {};
|
|
574
|
-
|
|
547
|
+
const { fonts, fontFamilies, signal, images, ...rest } = options ?? {};
|
|
548
|
+
signal?.throwIfAborted();
|
|
549
|
+
const resolved = await this.fonts.resolveResources(fonts && subsetFonts({
|
|
575
550
|
fonts,
|
|
576
551
|
source: node
|
|
577
|
-
}));
|
|
578
|
-
|
|
552
|
+
}), images, fontFamilies);
|
|
553
|
+
signal?.throwIfAborted();
|
|
579
554
|
return this.inner.renderSvg(node, {
|
|
580
555
|
...rest,
|
|
581
|
-
|
|
582
|
-
fontFamilies: fontFamilies ?? registeredFamilies
|
|
556
|
+
...resolved
|
|
583
557
|
});
|
|
584
558
|
}
|
|
585
559
|
async measure(node, options) {
|
|
586
|
-
const { fonts, fontFamilies, images, ...rest } = options ?? {};
|
|
587
|
-
|
|
560
|
+
const { fonts, fontFamilies, signal, images, ...rest } = options ?? {};
|
|
561
|
+
signal?.throwIfAborted();
|
|
562
|
+
const resolved = await this.fonts.resolveResources(fonts && subsetFonts({
|
|
588
563
|
fonts,
|
|
589
564
|
source: node
|
|
590
|
-
}));
|
|
591
|
-
|
|
565
|
+
}), images, fontFamilies);
|
|
566
|
+
signal?.throwIfAborted();
|
|
592
567
|
return this.inner.measure(node, {
|
|
593
568
|
...rest,
|
|
594
|
-
|
|
595
|
-
fontFamilies: fontFamilies ?? registeredFamilies
|
|
569
|
+
...resolved
|
|
596
570
|
});
|
|
597
571
|
}
|
|
598
572
|
async renderAnimation(options) {
|
|
599
|
-
const { fonts, fontFamilies, images, ...rest } = options;
|
|
573
|
+
const { fonts, fontFamilies, signal, images, ...rest } = options;
|
|
574
|
+
signal?.throwIfAborted();
|
|
600
575
|
const nodes = options.scenes.map((scene) => scene.node);
|
|
601
|
-
const
|
|
576
|
+
const resolved = await this.fonts.resolveResources(fonts && subsetFonts({
|
|
602
577
|
fonts,
|
|
603
578
|
source: nodes
|
|
604
|
-
}));
|
|
605
|
-
|
|
579
|
+
}), images, fontFamilies);
|
|
580
|
+
signal?.throwIfAborted();
|
|
606
581
|
return this.inner.renderAnimation({
|
|
607
582
|
...rest,
|
|
608
|
-
|
|
609
|
-
fontFamilies: fontFamilies ?? registeredFamilies
|
|
583
|
+
...resolved
|
|
610
584
|
});
|
|
611
585
|
}
|
|
586
|
+
registerFont(font) {
|
|
587
|
+
return this.fonts.register(font);
|
|
588
|
+
}
|
|
589
|
+
/** Releases the underlying wasm renderer's memory. */
|
|
612
590
|
free() {
|
|
613
591
|
this.inner.free();
|
|
614
592
|
}
|
|
615
|
-
async registerFont(font) {
|
|
616
|
-
const loader = typeof font === "string" ? fontFromUrl(font) : font;
|
|
617
|
-
const key = createFontKey(loader);
|
|
618
|
-
const cached = this.getFont(key);
|
|
619
|
-
if (cached) return cached;
|
|
620
|
-
const extracted = extractFontBuffer(loader);
|
|
621
|
-
const register = (data) => this.inner.registerFont(isBuffer(loader) ? data : {
|
|
622
|
-
...loader,
|
|
623
|
-
data
|
|
624
|
-
});
|
|
625
|
-
if (isBuffer(extracted)) {
|
|
626
|
-
const binded = register(extracted);
|
|
627
|
-
this.setFont(key, Promise.resolve(binded));
|
|
628
|
-
return binded;
|
|
629
|
-
}
|
|
630
|
-
const promise = extracted.then(register).catch((error) => {
|
|
631
|
-
this.deleteFont(key);
|
|
632
|
-
throw error;
|
|
633
|
-
});
|
|
634
|
-
this.setFont(key, promise);
|
|
635
|
-
return promise;
|
|
636
|
-
}
|
|
637
593
|
};
|
|
638
|
-
function extractFontBuffer(font) {
|
|
639
|
-
if (isBuffer(font)) return font;
|
|
640
|
-
if (typeof font.data !== "function") return font.data;
|
|
641
|
-
return font.data();
|
|
642
|
-
}
|
|
643
|
-
function createFontKey(font) {
|
|
644
|
-
if (isBuffer(font)) return font;
|
|
645
|
-
if ("key" in font && font.key) return font.key;
|
|
646
|
-
if (typeof font.data === "function") return `${font.name ?? ""}:${font.weight ?? ""}:${font.style ?? ""}`;
|
|
647
|
-
return font.data;
|
|
648
|
-
}
|
|
649
|
-
function isBuffer(data) {
|
|
650
|
-
return data instanceof Uint8Array || data instanceof ArrayBuffer || typeof Buffer !== "undefined" && Buffer.isBuffer(data);
|
|
651
|
-
}
|
|
652
594
|
//#endregion
|
|
653
595
|
export { Renderer, __wbg_init as default, initSync };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@takumi-rs/wasm",
|
|
3
|
-
"version": "2.0.0-rc.
|
|
3
|
+
"version": "2.0.0-rc.6",
|
|
4
4
|
"keywords": [
|
|
5
5
|
"css",
|
|
6
6
|
"image",
|
|
@@ -116,7 +116,7 @@
|
|
|
116
116
|
"publish-lint": "attw --pack . && publint --strict ."
|
|
117
117
|
},
|
|
118
118
|
"dependencies": {
|
|
119
|
-
"@takumi-rs/helpers": "2.0.0-rc.
|
|
119
|
+
"@takumi-rs/helpers": "2.0.0-rc.6",
|
|
120
120
|
"csstype": "^3.2.3"
|
|
121
121
|
},
|
|
122
122
|
"devDependencies": {
|
package/pkg/takumi_wasm_bg.wasm
CHANGED
|
Binary file
|