@pixldocs/canvas-renderer 0.3.12 → 0.3.13
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/index.cjs +82 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +31 -0
- package/dist/index.js +82 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -36,6 +36,8 @@ export declare interface CanvasSize {
|
|
|
36
36
|
height: number;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
export declare function collectFontDescriptorsFromConfig(config: TemplateConfig): FontDescriptor[];
|
|
40
|
+
|
|
39
41
|
/**
|
|
40
42
|
* Collect all font families used in a template config.
|
|
41
43
|
*/
|
|
@@ -52,6 +54,35 @@ export declare interface DynamicField {
|
|
|
52
54
|
[key: string]: any;
|
|
53
55
|
}
|
|
54
56
|
|
|
57
|
+
/**
|
|
58
|
+
* Ensure all fonts required by a fully-resolved TemplateConfig are loaded
|
|
59
|
+
* and available to Fabric/Canvas before rendering.
|
|
60
|
+
*
|
|
61
|
+
* This is the **single API** consumers (and the renderer internally) should
|
|
62
|
+
* call to guarantee font parity with EC2 `/render-from-form`.
|
|
63
|
+
*
|
|
64
|
+
* It:
|
|
65
|
+
* 1. Walks ALL text nodes (including clones/repeatables) collecting
|
|
66
|
+
* fontFamily + fontWeight + fontStyle.
|
|
67
|
+
* 2. Loads each unique family via Google Fonts CSS v1 (idempotent).
|
|
68
|
+
* 3. Explicitly loads each weight+style combo via `document.fonts.load()`.
|
|
69
|
+
* 4. Awaits `document.fonts.ready` so Fabric never paints with fallback faces.
|
|
70
|
+
*
|
|
71
|
+
* Idempotent — safe to call multiple times for the same config.
|
|
72
|
+
*/
|
|
73
|
+
export declare function ensureFontsForResolvedConfig(config: TemplateConfig): Promise<void>;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Walk a fully-resolved TemplateConfig and collect every unique
|
|
77
|
+
* { fontFamily, fontWeight, fontStyle } tuple from all text nodes
|
|
78
|
+
* (including clones, repeatable children, and per-character Fabric styles).
|
|
79
|
+
*/
|
|
80
|
+
export declare interface FontDescriptor {
|
|
81
|
+
family: string;
|
|
82
|
+
weight: number | string;
|
|
83
|
+
style: string;
|
|
84
|
+
}
|
|
85
|
+
|
|
55
86
|
export { InferredSection }
|
|
56
87
|
|
|
57
88
|
/**
|
package/dist/index.js
CHANGED
|
@@ -10496,6 +10496,15 @@ function collectFontsFromConfig(config) {
|
|
|
10496
10496
|
for (const node of nodes) {
|
|
10497
10497
|
if (node.fontFamily) fonts.add(normalizeFontFamily(node.fontFamily));
|
|
10498
10498
|
if ((_a2 = node.smartProps) == null ? void 0 : _a2.fontFamily) fonts.add(normalizeFontFamily(node.smartProps.fontFamily));
|
|
10499
|
+
if (node.styles && Array.isArray(node.styles)) {
|
|
10500
|
+
for (const lineStyle of node.styles) {
|
|
10501
|
+
if (lineStyle && typeof lineStyle === "object") {
|
|
10502
|
+
for (const charStyle of Object.values(lineStyle)) {
|
|
10503
|
+
if (charStyle == null ? void 0 : charStyle.fontFamily) fonts.add(normalizeFontFamily(charStyle.fontFamily));
|
|
10504
|
+
}
|
|
10505
|
+
}
|
|
10506
|
+
}
|
|
10507
|
+
}
|
|
10499
10508
|
if (node.children) walk(node.children);
|
|
10500
10509
|
}
|
|
10501
10510
|
}
|
|
@@ -10513,6 +10522,76 @@ function collectFontsFromConfig(config) {
|
|
|
10513
10522
|
}
|
|
10514
10523
|
return fonts;
|
|
10515
10524
|
}
|
|
10525
|
+
function collectFontDescriptorsFromConfig(config) {
|
|
10526
|
+
var _a;
|
|
10527
|
+
const seen = /* @__PURE__ */ new Set();
|
|
10528
|
+
const descriptors = [];
|
|
10529
|
+
function add(family, weight, style) {
|
|
10530
|
+
const f = normalizeFontFamily(family);
|
|
10531
|
+
if (!f) return;
|
|
10532
|
+
const w = weight ?? 400;
|
|
10533
|
+
const s = style ?? "normal";
|
|
10534
|
+
const key = `${f}|${w}|${s}`;
|
|
10535
|
+
if (seen.has(key)) return;
|
|
10536
|
+
seen.add(key);
|
|
10537
|
+
descriptors.push({ family: f, weight: w, style: s });
|
|
10538
|
+
}
|
|
10539
|
+
function walk(nodes) {
|
|
10540
|
+
var _a2;
|
|
10541
|
+
if (!nodes) return;
|
|
10542
|
+
for (const node of nodes) {
|
|
10543
|
+
if (node.fontFamily) {
|
|
10544
|
+
add(node.fontFamily, node.fontWeight, node.fontStyle);
|
|
10545
|
+
}
|
|
10546
|
+
if ((_a2 = node.smartProps) == null ? void 0 : _a2.fontFamily) {
|
|
10547
|
+
add(node.smartProps.fontFamily, node.smartProps.fontWeight, node.smartProps.fontStyle);
|
|
10548
|
+
}
|
|
10549
|
+
if (node.styles && Array.isArray(node.styles)) {
|
|
10550
|
+
for (const lineStyle of node.styles) {
|
|
10551
|
+
if (lineStyle && typeof lineStyle === "object") {
|
|
10552
|
+
for (const charStyle of Object.values(lineStyle)) {
|
|
10553
|
+
if (charStyle == null ? void 0 : charStyle.fontFamily) {
|
|
10554
|
+
add(charStyle.fontFamily, charStyle.fontWeight, charStyle.fontStyle);
|
|
10555
|
+
}
|
|
10556
|
+
}
|
|
10557
|
+
}
|
|
10558
|
+
}
|
|
10559
|
+
}
|
|
10560
|
+
if (node.children) walk(node.children);
|
|
10561
|
+
}
|
|
10562
|
+
}
|
|
10563
|
+
add("Open Sans", 400, "normal");
|
|
10564
|
+
for (const page of config.pages || []) {
|
|
10565
|
+
walk(page.children || []);
|
|
10566
|
+
}
|
|
10567
|
+
if ((_a = config.themeConfig) == null ? void 0 : _a.variables) {
|
|
10568
|
+
for (const def of Object.values(config.themeConfig.variables)) {
|
|
10569
|
+
if (def.value && typeof def.value === "string" && !def.value.startsWith("#") && !def.value.startsWith("rgb")) {
|
|
10570
|
+
if (def.label && /font/i.test(def.label)) {
|
|
10571
|
+
add(def.value);
|
|
10572
|
+
}
|
|
10573
|
+
}
|
|
10574
|
+
}
|
|
10575
|
+
}
|
|
10576
|
+
return descriptors;
|
|
10577
|
+
}
|
|
10578
|
+
async function ensureFontsForResolvedConfig(config) {
|
|
10579
|
+
if (typeof document === "undefined") return;
|
|
10580
|
+
const descriptors = collectFontDescriptorsFromConfig(config);
|
|
10581
|
+
const families = new Set(descriptors.map((d) => d.family));
|
|
10582
|
+
await Promise.all([...families].map((f) => loadGoogleFontCSS(f)));
|
|
10583
|
+
if (document.fonts) {
|
|
10584
|
+
const loadPromises = descriptors.map((d) => {
|
|
10585
|
+
const stylePrefix = d.style === "italic" ? "italic " : "";
|
|
10586
|
+
const weightStr = String(d.weight);
|
|
10587
|
+
const spec = `${stylePrefix}${weightStr} 16px "${d.family}"`;
|
|
10588
|
+
return document.fonts.load(spec).catch(() => {
|
|
10589
|
+
});
|
|
10590
|
+
});
|
|
10591
|
+
await Promise.all(loadPromises);
|
|
10592
|
+
await document.fonts.ready;
|
|
10593
|
+
}
|
|
10594
|
+
}
|
|
10516
10595
|
class PixldocsRenderer {
|
|
10517
10596
|
constructor(config) {
|
|
10518
10597
|
__publicField(this, "config");
|
|
@@ -10533,8 +10612,7 @@ class PixldocsRenderer {
|
|
|
10533
10612
|
if (!page) {
|
|
10534
10613
|
throw new Error(`Page index ${pageIndex} not found (template has ${templateConfig.pages.length} pages)`);
|
|
10535
10614
|
}
|
|
10536
|
-
|
|
10537
|
-
await Promise.all([...fonts].map((f) => loadGoogleFontCSS(f)));
|
|
10615
|
+
await ensureFontsForResolvedConfig(templateConfig);
|
|
10538
10616
|
const { setPackageApiUrl: setPackageApiUrl2 } = await Promise.resolve().then(() => appApi);
|
|
10539
10617
|
setPackageApiUrl2(this.config.imageProxyUrl);
|
|
10540
10618
|
const dataUrl = await this.renderPageViaPreviewCanvas(
|
|
@@ -10762,7 +10840,9 @@ export {
|
|
|
10762
10840
|
PixldocsPreview,
|
|
10763
10841
|
PixldocsRenderer,
|
|
10764
10842
|
applyThemeToConfig,
|
|
10843
|
+
collectFontDescriptorsFromConfig,
|
|
10765
10844
|
collectFontsFromConfig,
|
|
10845
|
+
ensureFontsForResolvedConfig,
|
|
10766
10846
|
loadGoogleFontCSS,
|
|
10767
10847
|
normalizeFontFamily,
|
|
10768
10848
|
resolveFromForm,
|