@pixldocs/canvas-renderer 0.5.56 → 0.5.58
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 +178 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +51 -1
- package/dist/index.js +178 -15
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -25,6 +25,19 @@ export declare function applyThemeToConfig(config: TemplateConfig, themeOverride
|
|
|
25
25
|
*/
|
|
26
26
|
export declare function assemblePdfFromSvgs(svgResults: SvgRenderResult[], options?: PdfAssemblyOptions): Promise<PdfRenderResult>;
|
|
27
27
|
|
|
28
|
+
/**
|
|
29
|
+
* Block until the webfonts referenced by `config` have actually loaded
|
|
30
|
+
* (or `maxWaitMs` elapses). Stronger than `ensureFontsForResolvedConfig`
|
|
31
|
+
* which only fire-and-forget queues `document.fonts.load()`.
|
|
32
|
+
*
|
|
33
|
+
* Use this BEFORE mounting `PreviewCanvas` so the synchronous
|
|
34
|
+
* `createText` auto-shrink loop measures against real font metrics
|
|
35
|
+
* instead of system fallback ones (which are typically narrower → loop
|
|
36
|
+
* decides "fits, no shrink needed" → text overflows once the real font
|
|
37
|
+
* swaps in).
|
|
38
|
+
*/
|
|
39
|
+
export declare function awaitFontsForConfig(config: TemplateConfig, maxWaitMs: number): Promise<void>;
|
|
40
|
+
|
|
28
41
|
export declare interface CanvasNode {
|
|
29
42
|
id: string;
|
|
30
43
|
name?: string;
|
|
@@ -64,6 +77,16 @@ export declare function collectFontsFromConfig(config: TemplateConfig): Set<stri
|
|
|
64
77
|
*/
|
|
65
78
|
export declare function collectImageUrls(config: TemplateConfig): string[];
|
|
66
79
|
|
|
80
|
+
/**
|
|
81
|
+
* Returns true when any text node in `config` uses
|
|
82
|
+
* `overflowPolicy: 'auto-shrink'`. The synchronous shrink loop in
|
|
83
|
+
* `createText` measures with whatever font Fabric can resolve at mount
|
|
84
|
+
* time, so for these configs the consumer MUST block on real font load
|
|
85
|
+
* before mounting (otherwise it shrinks against fallback metrics and
|
|
86
|
+
* overflows once the real font swaps in).
|
|
87
|
+
*/
|
|
88
|
+
export declare function configHasAutoShrinkText(config: TemplateConfig | null | undefined): boolean;
|
|
89
|
+
|
|
67
90
|
export declare interface DynamicField {
|
|
68
91
|
id: string;
|
|
69
92
|
label: string;
|
|
@@ -231,7 +254,7 @@ export declare function normalizeFontFamily(fontStack: string): string;
|
|
|
231
254
|
* Package version banner. Bump alongside package.json so we can confirm
|
|
232
255
|
* (via browser:log) that the deployed bundle matches the expected build.
|
|
233
256
|
*/
|
|
234
|
-
export declare const PACKAGE_VERSION = "0.5.
|
|
257
|
+
export declare const PACKAGE_VERSION = "0.5.57";
|
|
235
258
|
|
|
236
259
|
export declare interface PageSettings {
|
|
237
260
|
backgroundColor?: string;
|
|
@@ -391,6 +414,18 @@ export declare class PixldocsRenderer {
|
|
|
391
414
|
private waitForCanvasImages;
|
|
392
415
|
private waitForCanvasScene;
|
|
393
416
|
private waitForRelevantFonts;
|
|
417
|
+
/**
|
|
418
|
+
* Block until the webfonts referenced by `config` have actually loaded
|
|
419
|
+
* (or `maxWaitMs` elapses). Used by the headless capture path BEFORE
|
|
420
|
+
* mounting `PreviewCanvas`, so the synchronous `createText` auto-shrink
|
|
421
|
+
* loop measures against final font metrics instead of fallback ones.
|
|
422
|
+
*
|
|
423
|
+
* Stronger than `ensureFontsForResolvedConfig` (which is fire-and-forget)
|
|
424
|
+
* — this awaits each `document.fonts.load(spec)` AND `document.fonts.ready`,
|
|
425
|
+
* racing the whole thing against `maxWaitMs` so a slow CDN can't hang the
|
|
426
|
+
* renderer.
|
|
427
|
+
*/
|
|
428
|
+
private awaitFontsForConfig;
|
|
394
429
|
private getNormalizedGradientStops;
|
|
395
430
|
private paintPageBackground;
|
|
396
431
|
private renderPageViaPreviewCanvas;
|
|
@@ -447,6 +482,21 @@ export declare interface RenderOptions {
|
|
|
447
482
|
scale?: number;
|
|
448
483
|
/** Custom pixel ratio override */
|
|
449
484
|
pixelRatio?: number;
|
|
485
|
+
/**
|
|
486
|
+
* If true, skip the blocking font-ready wait before mounting the headless
|
|
487
|
+
* PreviewCanvas. Default: `false`. Setting this to `true` makes capture
|
|
488
|
+
* faster but can cause `overflowPolicy: 'auto-shrink'` text to overflow
|
|
489
|
+
* when the real webfont loads after auto-shrink has already measured
|
|
490
|
+
* against fallback metrics.
|
|
491
|
+
*/
|
|
492
|
+
skipFontReadyWait?: boolean;
|
|
493
|
+
/**
|
|
494
|
+
* Maximum time (ms) to wait for `document.fonts.load()` per descriptor
|
|
495
|
+
* before mounting PreviewCanvas. Default: `4000` for configs that contain
|
|
496
|
+
* any `auto-shrink` text (correctness matters), `1800` otherwise. Only
|
|
497
|
+
* applies when `skipFontReadyWait` is false.
|
|
498
|
+
*/
|
|
499
|
+
waitForFontsMs?: number;
|
|
450
500
|
}
|
|
451
501
|
|
|
452
502
|
export declare interface RenderResult {
|
package/dist/index.js
CHANGED
|
@@ -12244,6 +12244,46 @@ async function ensureFontsForResolvedConfig(config) {
|
|
|
12244
12244
|
});
|
|
12245
12245
|
}
|
|
12246
12246
|
}
|
|
12247
|
+
function configHasAutoShrinkText$1(config) {
|
|
12248
|
+
var _a;
|
|
12249
|
+
if (!((_a = config == null ? void 0 : config.pages) == null ? void 0 : _a.length)) return false;
|
|
12250
|
+
const walk = (nodes) => {
|
|
12251
|
+
for (const node of nodes || []) {
|
|
12252
|
+
if (!node) continue;
|
|
12253
|
+
if (node.type === "text" && node.overflowPolicy === "auto-shrink") return true;
|
|
12254
|
+
if (Array.isArray(node.children) && node.children.length && walk(node.children)) return true;
|
|
12255
|
+
}
|
|
12256
|
+
return false;
|
|
12257
|
+
};
|
|
12258
|
+
for (const page of config.pages) {
|
|
12259
|
+
if (walk(page.children || [])) return true;
|
|
12260
|
+
}
|
|
12261
|
+
return false;
|
|
12262
|
+
}
|
|
12263
|
+
async function awaitFontsForConfig(config, maxWaitMs) {
|
|
12264
|
+
if (typeof document === "undefined" || !document.fonts) return;
|
|
12265
|
+
void ensureFontsForResolvedConfig(config);
|
|
12266
|
+
const descriptors = collectFontDescriptorsFromConfig(config);
|
|
12267
|
+
if (descriptors.length === 0) return;
|
|
12268
|
+
const loads = Promise.all(
|
|
12269
|
+
descriptors.map((d) => {
|
|
12270
|
+
const stylePrefix = d.style === "italic" ? "italic " : "";
|
|
12271
|
+
const spec = `${stylePrefix}${d.weight} 16px "${d.family}"`;
|
|
12272
|
+
return document.fonts.load(spec).catch(() => []);
|
|
12273
|
+
})
|
|
12274
|
+
).then(() => void 0);
|
|
12275
|
+
await Promise.race([
|
|
12276
|
+
loads,
|
|
12277
|
+
new Promise((resolve) => setTimeout(resolve, maxWaitMs))
|
|
12278
|
+
]);
|
|
12279
|
+
await Promise.race([
|
|
12280
|
+
document.fonts.ready.catch(() => void 0).then(() => void 0),
|
|
12281
|
+
new Promise((r) => setTimeout(r, Math.min(500, maxWaitMs)))
|
|
12282
|
+
]);
|
|
12283
|
+
await new Promise(
|
|
12284
|
+
(resolve) => requestAnimationFrame(() => requestAnimationFrame(() => resolve()))
|
|
12285
|
+
);
|
|
12286
|
+
}
|
|
12247
12287
|
const PREVIEW_DEBUG_PREFIX = "[canvas-renderer][preview-debug]";
|
|
12248
12288
|
function countUnderlinedNodes(config) {
|
|
12249
12289
|
var _a;
|
|
@@ -12329,15 +12369,17 @@ function PixldocsPreview(props) {
|
|
|
12329
12369
|
underlinedNodes: countUnderlinedNodes(resolved.config)
|
|
12330
12370
|
});
|
|
12331
12371
|
setResolvedConfig(resolved.config);
|
|
12332
|
-
|
|
12372
|
+
const hasAutoShrink = configHasAutoShrinkText$1(resolved.config);
|
|
12373
|
+
const waitMs = hasAutoShrink ? 4e3 : 1800;
|
|
12374
|
+
awaitFontsForConfig(resolved.config, waitMs).then(() => {
|
|
12333
12375
|
if (!cancelled) {
|
|
12334
|
-
console.log(PREVIEW_DEBUG_PREFIX, "resolve-mode fonts
|
|
12376
|
+
console.log(PREVIEW_DEBUG_PREFIX, "resolve-mode fonts settled", { hasAutoShrink, waitMs });
|
|
12335
12377
|
setFontsReady(true);
|
|
12336
12378
|
setIsLoading(false);
|
|
12337
12379
|
}
|
|
12338
12380
|
}).catch((err) => {
|
|
12339
12381
|
if (!cancelled) {
|
|
12340
|
-
console.warn(PREVIEW_DEBUG_PREFIX, "resolve-mode
|
|
12382
|
+
console.warn(PREVIEW_DEBUG_PREFIX, "resolve-mode font wait failed", err);
|
|
12341
12383
|
setFontsReady(true);
|
|
12342
12384
|
setIsLoading(false);
|
|
12343
12385
|
}
|
|
@@ -12406,16 +12448,26 @@ function PixldocsPreview(props) {
|
|
|
12406
12448
|
setFontsReady(false);
|
|
12407
12449
|
setCanvasSettled(false);
|
|
12408
12450
|
setStabilizationPass(0);
|
|
12409
|
-
|
|
12410
|
-
|
|
12451
|
+
let cancelled = false;
|
|
12452
|
+
const hasAutoShrink = configHasAutoShrinkText$1(config);
|
|
12453
|
+
const waitMs = hasAutoShrink ? 4e3 : 1800;
|
|
12454
|
+
awaitFontsForConfig(config, waitMs).then(() => {
|
|
12455
|
+
if (cancelled) return;
|
|
12456
|
+
console.log(PREVIEW_DEBUG_PREFIX, "config-mode fonts settled", {
|
|
12411
12457
|
pageIndex,
|
|
12458
|
+
hasAutoShrink,
|
|
12459
|
+
waitMs,
|
|
12412
12460
|
underlinedNodes: countUnderlinedNodes(config)
|
|
12413
12461
|
});
|
|
12414
12462
|
setFontsReady(true);
|
|
12415
12463
|
}).catch((err) => {
|
|
12416
|
-
|
|
12464
|
+
if (cancelled) return;
|
|
12465
|
+
console.warn(PREVIEW_DEBUG_PREFIX, "config-mode font wait failed", err);
|
|
12417
12466
|
setFontsReady(true);
|
|
12418
12467
|
});
|
|
12468
|
+
return () => {
|
|
12469
|
+
cancelled = true;
|
|
12470
|
+
};
|
|
12419
12471
|
}, [isResolveMode, config]);
|
|
12420
12472
|
const handleCanvasReady = useCallback(() => {
|
|
12421
12473
|
if (stabilizationPass === 0) {
|
|
@@ -12452,7 +12504,7 @@ function PixldocsPreview(props) {
|
|
|
12452
12504
|
!canvasSettled && /* @__PURE__ */ jsx("div", { style: { position: "absolute", inset: 0, display: "flex", alignItems: "center", justifyContent: "center", minHeight: 200 }, children: /* @__PURE__ */ jsx("div", { style: { color: "#888", fontSize: 14 }, children: "Loading preview..." }) })
|
|
12453
12505
|
] });
|
|
12454
12506
|
}
|
|
12455
|
-
const PACKAGE_VERSION = "0.5.
|
|
12507
|
+
const PACKAGE_VERSION = "0.5.57";
|
|
12456
12508
|
let __underlineFixInstalled = false;
|
|
12457
12509
|
function installUnderlineFix(fab) {
|
|
12458
12510
|
var _a;
|
|
@@ -12549,6 +12601,22 @@ function installUnderlineFix(fab) {
|
|
|
12549
12601
|
__underlineFixInstalled = true;
|
|
12550
12602
|
console.log(`[canvas-renderer] underline-fix monkey patch installed (v${PACKAGE_VERSION})`);
|
|
12551
12603
|
}
|
|
12604
|
+
function configHasAutoShrinkText(config) {
|
|
12605
|
+
var _a;
|
|
12606
|
+
if (!((_a = config == null ? void 0 : config.pages) == null ? void 0 : _a.length)) return false;
|
|
12607
|
+
const walk = (nodes) => {
|
|
12608
|
+
for (const node of nodes || []) {
|
|
12609
|
+
if (!node) continue;
|
|
12610
|
+
if (node.type === "text" && node.overflowPolicy === "auto-shrink") return true;
|
|
12611
|
+
if (Array.isArray(node.children) && node.children.length && walk(node.children)) return true;
|
|
12612
|
+
}
|
|
12613
|
+
return false;
|
|
12614
|
+
};
|
|
12615
|
+
for (const page of config.pages) {
|
|
12616
|
+
if (walk(page.children || [])) return true;
|
|
12617
|
+
}
|
|
12618
|
+
return false;
|
|
12619
|
+
}
|
|
12552
12620
|
class PixldocsRenderer {
|
|
12553
12621
|
constructor(config) {
|
|
12554
12622
|
__publicField(this, "config");
|
|
@@ -12575,6 +12643,11 @@ class PixldocsRenderer {
|
|
|
12575
12643
|
throw new Error(`Page index ${pageIndex} not found (template has ${templateConfig.pages.length} pages)`);
|
|
12576
12644
|
}
|
|
12577
12645
|
await ensureFontsForResolvedConfig(templateConfig);
|
|
12646
|
+
if (!options.skipFontReadyWait) {
|
|
12647
|
+
const hasAutoShrink = configHasAutoShrinkText(templateConfig);
|
|
12648
|
+
const defaultWait = hasAutoShrink ? 4e3 : 1800;
|
|
12649
|
+
await this.awaitFontsForConfig(templateConfig, options.waitForFontsMs ?? defaultWait);
|
|
12650
|
+
}
|
|
12578
12651
|
const { setPackageApiUrl: setPackageApiUrl2 } = await Promise.resolve().then(() => appApi);
|
|
12579
12652
|
setPackageApiUrl2(this.config.imageProxyUrl);
|
|
12580
12653
|
const dataUrl = await this.renderPageViaPreviewCanvas(
|
|
@@ -12582,7 +12655,8 @@ class PixldocsRenderer {
|
|
|
12582
12655
|
pageIndex,
|
|
12583
12656
|
pixelRatio,
|
|
12584
12657
|
format,
|
|
12585
|
-
quality
|
|
12658
|
+
quality,
|
|
12659
|
+
{ skipFontReadyWait: options.skipFontReadyWait, waitForFontsMs: options.waitForFontsMs }
|
|
12586
12660
|
);
|
|
12587
12661
|
return {
|
|
12588
12662
|
dataUrl,
|
|
@@ -12596,9 +12670,14 @@ class PixldocsRenderer {
|
|
|
12596
12670
|
* Render all pages and return array of results.
|
|
12597
12671
|
*/
|
|
12598
12672
|
async renderAllPages(templateConfig, options = {}) {
|
|
12673
|
+
if (!options.skipFontReadyWait) {
|
|
12674
|
+
const hasAutoShrink = configHasAutoShrinkText(templateConfig);
|
|
12675
|
+
const defaultWait = hasAutoShrink ? 4e3 : 1800;
|
|
12676
|
+
await this.awaitFontsForConfig(templateConfig, options.waitForFontsMs ?? defaultWait);
|
|
12677
|
+
}
|
|
12599
12678
|
const results = [];
|
|
12600
12679
|
for (let i = 0; i < templateConfig.pages.length; i++) {
|
|
12601
|
-
results.push(await this.render(templateConfig, { ...options, pageIndex: i }));
|
|
12680
|
+
results.push(await this.render(templateConfig, { ...options, pageIndex: i, skipFontReadyWait: true }));
|
|
12602
12681
|
}
|
|
12603
12682
|
return results;
|
|
12604
12683
|
}
|
|
@@ -12635,6 +12714,8 @@ class PixldocsRenderer {
|
|
|
12635
12714
|
throw new Error(`Page index ${pageIndex} not found (template has ${templateConfig.pages.length} pages)`);
|
|
12636
12715
|
}
|
|
12637
12716
|
await ensureFontsForResolvedConfig(templateConfig);
|
|
12717
|
+
const hasAutoShrinkSvg = configHasAutoShrinkText(templateConfig);
|
|
12718
|
+
await this.awaitFontsForConfig(templateConfig, hasAutoShrinkSvg ? 4e3 : 1800);
|
|
12638
12719
|
const { setPackageApiUrl: setPackageApiUrl2 } = await Promise.resolve().then(() => appApi);
|
|
12639
12720
|
setPackageApiUrl2(this.config.imageProxyUrl);
|
|
12640
12721
|
const canvasWidth = templateConfig.canvas.width;
|
|
@@ -12646,6 +12727,8 @@ class PixldocsRenderer {
|
|
|
12646
12727
|
*/
|
|
12647
12728
|
async renderAllPageSvgs(templateConfig) {
|
|
12648
12729
|
await ensureFontsForResolvedConfig(templateConfig);
|
|
12730
|
+
const hasAutoShrinkSvg = configHasAutoShrinkText(templateConfig);
|
|
12731
|
+
await this.awaitFontsForConfig(templateConfig, hasAutoShrinkSvg ? 4e3 : 1800);
|
|
12649
12732
|
const { setPackageApiUrl: setPackageApiUrl2 } = await Promise.resolve().then(() => appApi);
|
|
12650
12733
|
setPackageApiUrl2(this.config.imageProxyUrl);
|
|
12651
12734
|
const results = [];
|
|
@@ -12898,6 +12981,26 @@ class PixldocsRenderer {
|
|
|
12898
12981
|
]);
|
|
12899
12982
|
await new Promise((resolve) => requestAnimationFrame(() => requestAnimationFrame(() => resolve())));
|
|
12900
12983
|
}
|
|
12984
|
+
/**
|
|
12985
|
+
* Block until the webfonts referenced by `config` have actually loaded
|
|
12986
|
+
* (or `maxWaitMs` elapses). Used by the headless capture path BEFORE
|
|
12987
|
+
* mounting `PreviewCanvas`, so the synchronous `createText` auto-shrink
|
|
12988
|
+
* loop measures against final font metrics instead of fallback ones.
|
|
12989
|
+
*
|
|
12990
|
+
* Stronger than `ensureFontsForResolvedConfig` (which is fire-and-forget)
|
|
12991
|
+
* — this awaits each `document.fonts.load(spec)` AND `document.fonts.ready`,
|
|
12992
|
+
* racing the whole thing against `maxWaitMs` so a slow CDN can't hang the
|
|
12993
|
+
* renderer.
|
|
12994
|
+
*/
|
|
12995
|
+
async awaitFontsForConfig(config, maxWaitMs) {
|
|
12996
|
+
if (typeof document === "undefined" || !document.fonts) return;
|
|
12997
|
+
void ensureFontsForResolvedConfig(config);
|
|
12998
|
+
await this.waitForRelevantFonts(config, maxWaitMs);
|
|
12999
|
+
await Promise.race([
|
|
13000
|
+
document.fonts.ready.catch(() => void 0).then(() => void 0),
|
|
13001
|
+
new Promise((r) => setTimeout(r, Math.min(500, maxWaitMs)))
|
|
13002
|
+
]);
|
|
13003
|
+
}
|
|
12901
13004
|
getNormalizedGradientStops(gradient) {
|
|
12902
13005
|
const stops = Array.isArray(gradient == null ? void 0 : gradient.stops) ? gradient.stops.map((stop) => ({
|
|
12903
13006
|
offset: Math.max(0, Math.min(1, Number((stop == null ? void 0 : stop.offset) ?? 0))),
|
|
@@ -12971,10 +13074,19 @@ class PixldocsRenderer {
|
|
|
12971
13074
|
} catch {
|
|
12972
13075
|
}
|
|
12973
13076
|
}
|
|
12974
|
-
async renderPageViaPreviewCanvas(config, pageIndex, pixelRatio, format, quality) {
|
|
13077
|
+
async renderPageViaPreviewCanvas(config, pageIndex, pixelRatio, format, quality, options = {}) {
|
|
12975
13078
|
const { PreviewCanvas: PreviewCanvas2 } = await Promise.resolve().then(() => PreviewCanvas$1);
|
|
12976
13079
|
const canvasWidth = config.canvas.width;
|
|
12977
13080
|
const canvasHeight = config.canvas.height;
|
|
13081
|
+
const hasAutoShrink = configHasAutoShrinkText(config);
|
|
13082
|
+
let firstMountSettled = false;
|
|
13083
|
+
let lateFontSettleDetected = false;
|
|
13084
|
+
if (typeof document !== "undefined" && document.fonts && hasAutoShrink) {
|
|
13085
|
+
document.fonts.ready.then(() => {
|
|
13086
|
+
if (firstMountSettled) lateFontSettleDetected = true;
|
|
13087
|
+
}).catch(() => {
|
|
13088
|
+
});
|
|
13089
|
+
}
|
|
12978
13090
|
return new Promise((resolve, reject) => {
|
|
12979
13091
|
const container = document.createElement("div");
|
|
12980
13092
|
container.style.cssText = `
|
|
@@ -12987,6 +13099,8 @@ class PixldocsRenderer {
|
|
|
12987
13099
|
cleanup();
|
|
12988
13100
|
reject(new Error("Render timeout (30s)"));
|
|
12989
13101
|
}, 3e4);
|
|
13102
|
+
let root;
|
|
13103
|
+
let mountKey = 0;
|
|
12990
13104
|
const cleanup = () => {
|
|
12991
13105
|
clearTimeout(timeout);
|
|
12992
13106
|
try {
|
|
@@ -12995,6 +13109,46 @@ class PixldocsRenderer {
|
|
|
12995
13109
|
}
|
|
12996
13110
|
container.remove();
|
|
12997
13111
|
};
|
|
13112
|
+
const remountWithFreshKey = async () => {
|
|
13113
|
+
mountKey += 1;
|
|
13114
|
+
try {
|
|
13115
|
+
clearMeasurementCache();
|
|
13116
|
+
} catch {
|
|
13117
|
+
}
|
|
13118
|
+
try {
|
|
13119
|
+
clearFabricCharCache();
|
|
13120
|
+
} catch {
|
|
13121
|
+
}
|
|
13122
|
+
try {
|
|
13123
|
+
root.unmount();
|
|
13124
|
+
} catch {
|
|
13125
|
+
}
|
|
13126
|
+
root = createRoot(container);
|
|
13127
|
+
await new Promise((settle) => {
|
|
13128
|
+
const onReadyOnce = () => {
|
|
13129
|
+
this.waitForCanvasScene(container, config, pageIndex).then(async () => {
|
|
13130
|
+
const fabricInstance = this.getFabricCanvasFromContainer(container);
|
|
13131
|
+
const expectedImageCount = this.getExpectedImageCount(config, pageIndex);
|
|
13132
|
+
await this.waitForCanvasImages(container, expectedImageCount);
|
|
13133
|
+
await this.waitForStableTextMetrics(container, config);
|
|
13134
|
+
await this.waitForCanvasScene(container, config, pageIndex);
|
|
13135
|
+
if (!fabricInstance) return settle();
|
|
13136
|
+
settle();
|
|
13137
|
+
}).catch(() => settle());
|
|
13138
|
+
};
|
|
13139
|
+
root.render(
|
|
13140
|
+
createElement(PreviewCanvas2, {
|
|
13141
|
+
key: `remount-${mountKey}`,
|
|
13142
|
+
config,
|
|
13143
|
+
pageIndex,
|
|
13144
|
+
zoom: pixelRatio,
|
|
13145
|
+
absoluteZoom: true,
|
|
13146
|
+
skipFontReadyWait: false,
|
|
13147
|
+
onReady: onReadyOnce
|
|
13148
|
+
})
|
|
13149
|
+
);
|
|
13150
|
+
});
|
|
13151
|
+
};
|
|
12998
13152
|
const onReady = () => {
|
|
12999
13153
|
this.waitForCanvasScene(container, config, pageIndex).then(async () => {
|
|
13000
13154
|
try {
|
|
@@ -13003,16 +13157,23 @@ class PixldocsRenderer {
|
|
|
13003
13157
|
await this.waitForCanvasImages(container, expectedImageCount);
|
|
13004
13158
|
await this.waitForStableTextMetrics(container, config);
|
|
13005
13159
|
await this.waitForCanvasScene(container, config, pageIndex);
|
|
13160
|
+
firstMountSettled = true;
|
|
13161
|
+
if (hasAutoShrink && lateFontSettleDetected) {
|
|
13162
|
+
console.log("[canvas-renderer][parity] late font-settle detected — remounting for auto-shrink reflow");
|
|
13163
|
+
await remountWithFreshKey();
|
|
13164
|
+
}
|
|
13006
13165
|
const fabricCanvas = container.querySelector("canvas.upper-canvas, canvas");
|
|
13007
13166
|
const sourceCanvas = (fabricInstance == null ? void 0 : fabricInstance.lowerCanvasEl) || container.querySelector("canvas.lower-canvas") || fabricCanvas;
|
|
13167
|
+
const fabricInstanceAfter = this.getFabricCanvasFromContainer(container) || fabricInstance;
|
|
13168
|
+
const sourceCanvasAfter = (fabricInstanceAfter == null ? void 0 : fabricInstanceAfter.lowerCanvasEl) || container.querySelector("canvas.lower-canvas") || sourceCanvas;
|
|
13008
13169
|
if (!sourceCanvas) {
|
|
13009
13170
|
cleanup();
|
|
13010
13171
|
reject(new Error("No canvas element found after render"));
|
|
13011
13172
|
return;
|
|
13012
13173
|
}
|
|
13013
13174
|
const exportCanvas = document.createElement("canvas");
|
|
13014
|
-
exportCanvas.width =
|
|
13015
|
-
exportCanvas.height =
|
|
13175
|
+
exportCanvas.width = sourceCanvasAfter.width;
|
|
13176
|
+
exportCanvas.height = sourceCanvasAfter.height;
|
|
13016
13177
|
const exportCtx = exportCanvas.getContext("2d");
|
|
13017
13178
|
if (!exportCtx) {
|
|
13018
13179
|
cleanup();
|
|
@@ -13020,10 +13181,10 @@ class PixldocsRenderer {
|
|
|
13020
13181
|
return;
|
|
13021
13182
|
}
|
|
13022
13183
|
exportCtx.save();
|
|
13023
|
-
exportCtx.scale(
|
|
13184
|
+
exportCtx.scale(sourceCanvasAfter.width / canvasWidth, sourceCanvasAfter.height / canvasHeight);
|
|
13024
13185
|
this.paintPageBackground(exportCtx, config.pages[pageIndex], canvasWidth, canvasHeight);
|
|
13025
13186
|
exportCtx.restore();
|
|
13026
|
-
exportCtx.drawImage(
|
|
13187
|
+
exportCtx.drawImage(sourceCanvasAfter, 0, 0);
|
|
13027
13188
|
const mimeType = format === "jpeg" ? "image/jpeg" : format === "webp" ? "image/webp" : "image/png";
|
|
13028
13189
|
const dataUrl = exportCanvas.toDataURL(mimeType, quality);
|
|
13029
13190
|
cleanup();
|
|
@@ -13034,7 +13195,7 @@ class PixldocsRenderer {
|
|
|
13034
13195
|
}
|
|
13035
13196
|
});
|
|
13036
13197
|
};
|
|
13037
|
-
|
|
13198
|
+
root = createRoot(container);
|
|
13038
13199
|
root.render(
|
|
13039
13200
|
createElement(PreviewCanvas2, {
|
|
13040
13201
|
config,
|
|
@@ -15515,9 +15676,11 @@ export {
|
|
|
15515
15676
|
PixldocsRenderer,
|
|
15516
15677
|
applyThemeToConfig,
|
|
15517
15678
|
assemblePdfFromSvgs,
|
|
15679
|
+
awaitFontsForConfig,
|
|
15518
15680
|
collectFontDescriptorsFromConfig,
|
|
15519
15681
|
collectFontsFromConfig,
|
|
15520
15682
|
collectImageUrls,
|
|
15683
|
+
configHasAutoShrinkText$1 as configHasAutoShrinkText,
|
|
15521
15684
|
embedFont,
|
|
15522
15685
|
embedFontsForConfig,
|
|
15523
15686
|
embedFontsInPdf,
|