@pixldocs/canvas-renderer 0.5.21 → 0.5.23
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 +22 -46
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +22 -46
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -100,8 +100,8 @@ export declare function embedFontsInPdf(pdf: jsPDF, fontFamilies: Set<string>, f
|
|
|
100
100
|
* 1. Walks ALL text nodes (including clones/repeatables) collecting
|
|
101
101
|
* fontFamily + fontWeight + fontStyle.
|
|
102
102
|
* 2. Loads each unique family via Google Fonts CSS v1 (idempotent).
|
|
103
|
-
* 3.
|
|
104
|
-
*
|
|
103
|
+
* 3. Waits for each weight+style combo via `document.fonts.load()` so export
|
|
104
|
+
* capture never uses fallback font decoration metrics.
|
|
105
105
|
*
|
|
106
106
|
* Idempotent — safe to call multiple times for the same config.
|
|
107
107
|
*/
|
package/dist/index.js
CHANGED
|
@@ -11833,41 +11833,19 @@ async function ensureFontsForResolvedConfig(config) {
|
|
|
11833
11833
|
if (typeof document === "undefined") return;
|
|
11834
11834
|
const descriptors = collectFontDescriptorsFromConfig(config);
|
|
11835
11835
|
const families = new Set(descriptors.map((d) => d.family));
|
|
11836
|
-
|
|
11836
|
+
await withTimeout(Promise.all([...families].map((f) => loadGoogleFontCSS(f))), 6e3);
|
|
11837
11837
|
if (document.fonts) {
|
|
11838
|
-
descriptors.
|
|
11838
|
+
await withTimeout(Promise.all(descriptors.map((d) => {
|
|
11839
11839
|
const stylePrefix = d.style === "italic" ? "italic " : "";
|
|
11840
11840
|
const weightStr = String(d.weight);
|
|
11841
11841
|
const spec = `${stylePrefix}${weightStr} 16px "${d.family}"`;
|
|
11842
|
-
document.fonts.load(spec).catch(() => {
|
|
11842
|
+
return document.fonts.load(spec).catch(() => {
|
|
11843
11843
|
});
|
|
11844
|
-
});
|
|
11844
|
+
})), 6e3);
|
|
11845
|
+
await withTimeout(document.fonts.ready, 6e3);
|
|
11845
11846
|
}
|
|
11846
11847
|
}
|
|
11847
11848
|
const TEXT_TYPES = /* @__PURE__ */ new Set(["textbox", "text", "i-text"]);
|
|
11848
|
-
function getTextLines(obj) {
|
|
11849
|
-
const lines = Array.isArray(obj.textLines) && obj.textLines.length ? obj.textLines : String(obj.text || "").split("\n");
|
|
11850
|
-
return lines.map((line) => Array.isArray(line) ? line.join("") : String(line ?? ""));
|
|
11851
|
-
}
|
|
11852
|
-
function measureLineWidth(obj, line) {
|
|
11853
|
-
if (typeof document === "undefined") return 0;
|
|
11854
|
-
const canvas = document.createElement("canvas");
|
|
11855
|
-
const ctx = canvas.getContext("2d");
|
|
11856
|
-
if (!ctx) return 0;
|
|
11857
|
-
const fontStyle = obj.fontStyle || "normal";
|
|
11858
|
-
const fontWeight = obj.fontWeight || 400;
|
|
11859
|
-
const fontSize = obj.fontSize || 16;
|
|
11860
|
-
const fontFamily = obj.fontFamily || "sans-serif";
|
|
11861
|
-
ctx.font = `${fontStyle} ${fontWeight} ${fontSize}px ${fontFamily}`;
|
|
11862
|
-
const charSpacing = Number(obj.charSpacing || 0) / 1e3 * fontSize;
|
|
11863
|
-
return ctx.measureText(line).width + Math.max(0, line.length - 1) * charSpacing;
|
|
11864
|
-
}
|
|
11865
|
-
function getDecorationPadding(obj) {
|
|
11866
|
-
var _a;
|
|
11867
|
-
const strokeWidth = Number(obj.strokeWidth || 0);
|
|
11868
|
-
const shadowBlur = Number(((_a = obj.shadow) == null ? void 0 : _a.blur) || 0);
|
|
11869
|
-
return Math.max(0, strokeWidth) + Math.max(0, shadowBlur * 0.25);
|
|
11870
|
-
}
|
|
11871
11849
|
function getFabricCanvasFromContainer(container) {
|
|
11872
11850
|
const registry2 = window.__fabricCanvasRegistry;
|
|
11873
11851
|
if (registry2 instanceof Map) {
|
|
@@ -11914,10 +11892,6 @@ function stabilizeFabricTextObjects(fabricInstance) {
|
|
|
11914
11892
|
obj.initDimensions();
|
|
11915
11893
|
(_b2 = obj.set) == null ? void 0 : _b2.call(obj, { width: saved.width, scaleX: saved.scaleX, scaleY: saved.scaleY });
|
|
11916
11894
|
}
|
|
11917
|
-
if (obj.underline || obj.linethrough) {
|
|
11918
|
-
const decorationPadding = getDecorationPadding(obj);
|
|
11919
|
-
obj.__lineWidths = getTextLines(obj).map((line) => Math.max(0, measureLineWidth(obj, line) + decorationPadding));
|
|
11920
|
-
}
|
|
11921
11895
|
obj.dirty = true;
|
|
11922
11896
|
(_c2 = obj._clearCache) == null ? void 0 : _c2.call(obj);
|
|
11923
11897
|
(_d = obj.setCoords) == null ? void 0 : _d.call(obj);
|
|
@@ -12563,7 +12537,7 @@ class PixldocsRenderer {
|
|
|
12563
12537
|
container.style.cssText = `
|
|
12564
12538
|
position: fixed; left: -99999px; top: -99999px;
|
|
12565
12539
|
width: ${canvasWidth}px; height: ${canvasHeight}px;
|
|
12566
|
-
overflow: hidden; pointer-events: none;
|
|
12540
|
+
overflow: hidden; pointer-events: none; visibility: hidden;
|
|
12567
12541
|
`;
|
|
12568
12542
|
document.body.appendChild(container);
|
|
12569
12543
|
const timeout = setTimeout(() => {
|
|
@@ -12584,7 +12558,7 @@ class PixldocsRenderer {
|
|
|
12584
12558
|
finished = true;
|
|
12585
12559
|
this.waitForCanvasScene(container, config, pageIndex).then(async () => {
|
|
12586
12560
|
try {
|
|
12587
|
-
await this.waitForStableTextMetrics(container, config);
|
|
12561
|
+
await this.waitForStableTextMetrics(container, config, true);
|
|
12588
12562
|
await this.waitForCanvasScene(container, config, pageIndex, 2500, 50);
|
|
12589
12563
|
const fabricInstance = this.getFabricCanvasFromContainer(container);
|
|
12590
12564
|
const expectedImageCount = this.getExpectedImageCount(config, pageIndex);
|
|
@@ -12648,7 +12622,7 @@ class PixldocsRenderer {
|
|
|
12648
12622
|
container.style.cssText = `
|
|
12649
12623
|
position: fixed; left: -99999px; top: -99999px;
|
|
12650
12624
|
width: ${canvasWidth}px; height: ${canvasHeight}px;
|
|
12651
|
-
overflow: hidden; pointer-events: none;
|
|
12625
|
+
overflow: hidden; pointer-events: none; visibility: hidden;
|
|
12652
12626
|
`;
|
|
12653
12627
|
document.body.appendChild(container);
|
|
12654
12628
|
const timeout = setTimeout(() => {
|
|
@@ -12670,7 +12644,7 @@ class PixldocsRenderer {
|
|
|
12670
12644
|
this.waitForCanvasScene(container, config, pageIndex).then(async () => {
|
|
12671
12645
|
var _a, _b;
|
|
12672
12646
|
try {
|
|
12673
|
-
await this.waitForStableTextMetrics(container, config);
|
|
12647
|
+
await this.waitForStableTextMetrics(container, config, true);
|
|
12674
12648
|
await this.waitForCanvasScene(container, config, pageIndex, 2500, 50);
|
|
12675
12649
|
const fabricInstance = this.getFabricCanvasFromContainer(container);
|
|
12676
12650
|
if (!fabricInstance) {
|
|
@@ -12792,10 +12766,10 @@ class PixldocsRenderer {
|
|
|
12792
12766
|
getFabricCanvasFromContainer(container) {
|
|
12793
12767
|
return getFabricCanvasFromContainer(container);
|
|
12794
12768
|
}
|
|
12795
|
-
async waitForStableTextMetrics(container, config) {
|
|
12769
|
+
async waitForStableTextMetrics(container, config, strictFontWait = false) {
|
|
12796
12770
|
if (typeof document !== "undefined") {
|
|
12797
|
-
|
|
12798
|
-
await this.waitForRelevantFonts(config);
|
|
12771
|
+
await ensureFontsForResolvedConfig(config);
|
|
12772
|
+
await this.waitForRelevantFonts(config, strictFontWait ? 6e3 : 1800);
|
|
12799
12773
|
}
|
|
12800
12774
|
const fabricInstance = this.getFabricCanvasFromContainer(container);
|
|
12801
12775
|
if (!(fabricInstance == null ? void 0 : fabricInstance.getObjects)) return;
|
|
@@ -14553,19 +14527,21 @@ function convertTextDecorationsToLines(svg) {
|
|
|
14553
14527
|
const fontFamily = tspan.getAttribute("font-family") || textEl.getAttribute("font-family") || "sans-serif";
|
|
14554
14528
|
const fontWeight = tspan.getAttribute("font-weight") || textEl.getAttribute("font-weight") || "normal";
|
|
14555
14529
|
const fill = tspan.getAttribute("fill") || textEl.getAttribute("fill") || "#000000";
|
|
14556
|
-
let textWidth;
|
|
14557
|
-
if (ctx) {
|
|
14558
|
-
ctx.font = `${fontWeight} ${fontSize}px ${fontFamily.replace(/'/g, "")}`;
|
|
14559
|
-
textWidth = ctx.measureText(content).width;
|
|
14560
|
-
} else {
|
|
14561
|
-
textWidth = content.length * fontSize * 0.6;
|
|
14562
|
-
}
|
|
14530
|
+
let textWidth = 0;
|
|
14563
14531
|
if (typeof tspan.getComputedTextLength === "function") {
|
|
14564
14532
|
try {
|
|
14565
|
-
textWidth =
|
|
14533
|
+
textWidth = tspan.getComputedTextLength();
|
|
14566
14534
|
} catch {
|
|
14567
14535
|
}
|
|
14568
14536
|
}
|
|
14537
|
+
if (!Number.isFinite(textWidth) || textWidth <= 0) {
|
|
14538
|
+
if (ctx) {
|
|
14539
|
+
ctx.font = `${fontWeight} ${fontSize}px ${fontFamily.replace(/'/g, "")}`;
|
|
14540
|
+
textWidth = ctx.measureText(content).width;
|
|
14541
|
+
} else {
|
|
14542
|
+
textWidth = content.length * fontSize * 0.6;
|
|
14543
|
+
}
|
|
14544
|
+
}
|
|
14569
14545
|
const underlineY = y + fontSize * 0.15;
|
|
14570
14546
|
const thickness = Math.max(0.5, fontSize * 0.066667);
|
|
14571
14547
|
const line = doc.createElementNS("http://www.w3.org/2000/svg", "line");
|