@pixldocs/canvas-renderer 0.5.134 → 0.5.136
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-Sc4qRn5o.js → index-BHa3ekoF.js} +149 -5
- package/dist/{index-Sc4qRn5o.js.map → index-BHa3ekoF.js.map} +1 -1
- package/dist/{index-DmqoeVsF.cjs → index-DUHE7WhJ.cjs} +149 -5
- package/dist/{index-DmqoeVsF.cjs.map → index-DUHE7WhJ.cjs.map} +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/{vectorPdfExport-8Q3O7Z_Q.cjs → vectorPdfExport-Bq-_OarH.cjs} +4 -4
- package/dist/{vectorPdfExport-8Q3O7Z_Q.cjs.map → vectorPdfExport-Bq-_OarH.cjs.map} +1 -1
- package/dist/{vectorPdfExport-BA6bhLs-.js → vectorPdfExport-D3L64sAJ.js} +4 -4
- package/dist/{vectorPdfExport-BA6bhLs-.js.map → vectorPdfExport-D3L64sAJ.js.map} +1 -1
- package/package.json +1 -1
|
@@ -14608,6 +14608,38 @@ const pdfFonts = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProp
|
|
|
14608
14608
|
resolveFontWeight,
|
|
14609
14609
|
rewriteSvgFontsForJsPDF
|
|
14610
14610
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
14611
|
+
const FONTSHARE_SLUGS = {
|
|
14612
|
+
"Satoshi": "satoshi",
|
|
14613
|
+
"Cabinet Grotesk": "cabinet-grotesk",
|
|
14614
|
+
"Clash Display": "clash-display",
|
|
14615
|
+
"Clash Grotesk": "clash-grotesk",
|
|
14616
|
+
"General Sans": "general-sans",
|
|
14617
|
+
"Switzer": "switzer",
|
|
14618
|
+
"Supreme": "supreme",
|
|
14619
|
+
"Author": "author",
|
|
14620
|
+
"Boska": "boska",
|
|
14621
|
+
"Excon": "excon",
|
|
14622
|
+
"Khand": "khand",
|
|
14623
|
+
"Sentient": "sentient",
|
|
14624
|
+
"Synonym": "synonym",
|
|
14625
|
+
"Erode": "erode",
|
|
14626
|
+
"Ranade": "ranade",
|
|
14627
|
+
"Tanker": "tanker",
|
|
14628
|
+
"Zodiak": "zodiak",
|
|
14629
|
+
"Gambarino": "gambarino",
|
|
14630
|
+
"Melodrama": "melodrama",
|
|
14631
|
+
"Bespoke Serif": "bespoke-serif",
|
|
14632
|
+
"Bespoke Stencil": "bespoke-stencil",
|
|
14633
|
+
"Panchang": "panchang",
|
|
14634
|
+
"Quincy CF": "quincy-cf",
|
|
14635
|
+
"Pally": "pally",
|
|
14636
|
+
"Tabular": "tabular",
|
|
14637
|
+
"Sharpie": "sharpie",
|
|
14638
|
+
"Stardom": "stardom",
|
|
14639
|
+
"Rebond Grotesque": "rebond-grotesque",
|
|
14640
|
+
"Telma": "telma",
|
|
14641
|
+
"Nippo": "nippo"
|
|
14642
|
+
};
|
|
14611
14643
|
function normalizeFontFamily(fontStack) {
|
|
14612
14644
|
const first = fontStack.split(",")[0].trim();
|
|
14613
14645
|
return first.replace(/^['"]|['"]$/g, "");
|
|
@@ -14615,6 +14647,114 @@ function normalizeFontFamily(fontStack) {
|
|
|
14615
14647
|
const loadedFonts = /* @__PURE__ */ new Set();
|
|
14616
14648
|
const loadingPromises = /* @__PURE__ */ new Map();
|
|
14617
14649
|
const registeredLocalFontFaces = /* @__PURE__ */ new Set();
|
|
14650
|
+
const registeredRemoteFontFaces = /* @__PURE__ */ new Set();
|
|
14651
|
+
const remoteFontDataUriPromises = /* @__PURE__ */ new Map();
|
|
14652
|
+
let localFontFaceStyleEl = null;
|
|
14653
|
+
function ensureLocalFontFaceStyle() {
|
|
14654
|
+
if (typeof document === "undefined") return null;
|
|
14655
|
+
if (localFontFaceStyleEl && localFontFaceStyleEl.isConnected) return localFontFaceStyleEl;
|
|
14656
|
+
try {
|
|
14657
|
+
localFontFaceStyleEl = document.createElement("style");
|
|
14658
|
+
localFontFaceStyleEl.setAttribute("data-pixldocs-local-fontfaces", "1");
|
|
14659
|
+
document.head.appendChild(localFontFaceStyleEl);
|
|
14660
|
+
return localFontFaceStyleEl;
|
|
14661
|
+
} catch {
|
|
14662
|
+
return null;
|
|
14663
|
+
}
|
|
14664
|
+
}
|
|
14665
|
+
function appendLocalFontFaceRule(family, weight, style, file) {
|
|
14666
|
+
const styleEl = ensureLocalFontFaceStyle();
|
|
14667
|
+
if (!styleEl) return;
|
|
14668
|
+
const cssText = `@font-face{font-family:"${family}";src:url("/fonts/${file}");font-weight:${weight};font-style:${style};font-display:swap;}
|
|
14669
|
+
`;
|
|
14670
|
+
styleEl.appendChild(document.createTextNode(cssText));
|
|
14671
|
+
}
|
|
14672
|
+
function appendDataUriFontFaceRule(family, weight, style, dataUri) {
|
|
14673
|
+
const styleEl = ensureLocalFontFaceStyle();
|
|
14674
|
+
if (!styleEl) return;
|
|
14675
|
+
const cssText = `@font-face{font-family:"${family}";src:url("${dataUri}") format("truetype");font-weight:${weight};font-style:${style};font-display:swap;}
|
|
14676
|
+
`;
|
|
14677
|
+
styleEl.appendChild(document.createTextNode(cssText));
|
|
14678
|
+
}
|
|
14679
|
+
function resolveHarnessFontProxyUrl() {
|
|
14680
|
+
var _a, _b;
|
|
14681
|
+
try {
|
|
14682
|
+
const runtimeBase = typeof window !== "undefined" && (window.__PIXLDOCS_SUPABASE_URL || ((_a = window.__CONFIG__) == null ? void 0 : _a.supabaseUrl)) || typeof globalThis !== "undefined" && (globalThis.__PIXLDOCS_SUPABASE_URL || ((_b = globalThis.__CONFIG__) == null ? void 0 : _b.supabaseUrl)) || "";
|
|
14683
|
+
const base = String(runtimeBase || "").replace(/\/$/, "");
|
|
14684
|
+
return base ? `${base}/functions/v1/font-proxy` : "";
|
|
14685
|
+
} catch {
|
|
14686
|
+
return "";
|
|
14687
|
+
}
|
|
14688
|
+
}
|
|
14689
|
+
function isEmbeddableTrueType(bytes) {
|
|
14690
|
+
if (bytes.length < 12) return false;
|
|
14691
|
+
const signature = String.fromCharCode(bytes[0], bytes[1], bytes[2], bytes[3]);
|
|
14692
|
+
return signature === "\0\0\0" || signature === "true";
|
|
14693
|
+
}
|
|
14694
|
+
async function arrayBufferToDataUri(buf) {
|
|
14695
|
+
const blob = new Blob([buf], { type: "font/ttf" });
|
|
14696
|
+
return await new Promise((resolve, reject) => {
|
|
14697
|
+
const reader = new FileReader();
|
|
14698
|
+
reader.onload = () => resolve(String(reader.result));
|
|
14699
|
+
reader.onerror = () => reject(reader.error || new Error("Failed to read font bytes"));
|
|
14700
|
+
reader.readAsDataURL(blob);
|
|
14701
|
+
});
|
|
14702
|
+
}
|
|
14703
|
+
async function fetchFontProxyDataUri(family, weight, style, source) {
|
|
14704
|
+
const proxyUrl = resolveHarnessFontProxyUrl();
|
|
14705
|
+
if (!proxyUrl) return null;
|
|
14706
|
+
const key = `${source}|${family}|${weight}|${style}`;
|
|
14707
|
+
const existing = remoteFontDataUriPromises.get(key);
|
|
14708
|
+
if (existing) return existing;
|
|
14709
|
+
const promise = (async () => {
|
|
14710
|
+
try {
|
|
14711
|
+
const url = `${proxyUrl}?family=${encodeURIComponent(family)}&weight=${weight}&italic=${style === "italic" ? 1 : 0}&source=${source}`;
|
|
14712
|
+
const res = await fetch(url, { credentials: "omit" });
|
|
14713
|
+
if (!res.ok) return null;
|
|
14714
|
+
const contentType = res.headers.get("content-type") || "";
|
|
14715
|
+
if (/application\/json/i.test(contentType)) return null;
|
|
14716
|
+
const buf = await res.arrayBuffer();
|
|
14717
|
+
const bytes = new Uint8Array(buf);
|
|
14718
|
+
if (!isEmbeddableTrueType(bytes)) return null;
|
|
14719
|
+
return await arrayBufferToDataUri(buf);
|
|
14720
|
+
} catch {
|
|
14721
|
+
return null;
|
|
14722
|
+
}
|
|
14723
|
+
})();
|
|
14724
|
+
remoteFontDataUriPromises.set(key, promise);
|
|
14725
|
+
return promise;
|
|
14726
|
+
}
|
|
14727
|
+
async function registerRemoteFontFaceViaProxy(family, requestedWeight, styleRaw) {
|
|
14728
|
+
if (typeof document === "undefined" || typeof FontFace === "undefined" || !document.fonts) return false;
|
|
14729
|
+
if (!resolveHarnessFontProxyUrl()) return false;
|
|
14730
|
+
const style = /italic|oblique/i.test(styleRaw || "") ? "italic" : "normal";
|
|
14731
|
+
const parsed = typeof requestedWeight === "number" ? requestedWeight : Number.parseInt(String(requestedWeight || "400"), 10);
|
|
14732
|
+
const resolved = Number.isFinite(parsed) ? parsed <= 350 ? 300 : parsed <= 450 ? 400 : parsed <= 550 ? 500 : parsed <= 650 ? 600 : 700 : 400;
|
|
14733
|
+
const weightLadder = [resolved];
|
|
14734
|
+
for (const w of [400, 500, 700, 600, 300]) if (!weightLadder.includes(w)) weightLadder.push(w);
|
|
14735
|
+
const sourceOrder = FONTSHARE_SLUGS[family] ? ["fontshare", "google"] : ["google", "fontshare"];
|
|
14736
|
+
for (const actualWeight of weightLadder) {
|
|
14737
|
+
for (const source of sourceOrder) {
|
|
14738
|
+
const faceKey = `${family}|${actualWeight}|${style}|${source}`;
|
|
14739
|
+
if (registeredRemoteFontFaces.has(faceKey)) return true;
|
|
14740
|
+
const dataUri = await fetchFontProxyDataUri(family, actualWeight, style, source);
|
|
14741
|
+
if (!dataUri) continue;
|
|
14742
|
+
try {
|
|
14743
|
+
const face = new FontFace(family, `url("${dataUri}")`, {
|
|
14744
|
+
weight: String(actualWeight),
|
|
14745
|
+
style
|
|
14746
|
+
});
|
|
14747
|
+
await face.load();
|
|
14748
|
+
document.fonts.add(face);
|
|
14749
|
+
appendDataUriFontFaceRule(family, actualWeight, style, dataUri);
|
|
14750
|
+
registeredRemoteFontFaces.add(faceKey);
|
|
14751
|
+
return true;
|
|
14752
|
+
} catch {
|
|
14753
|
+
}
|
|
14754
|
+
}
|
|
14755
|
+
}
|
|
14756
|
+
return false;
|
|
14757
|
+
}
|
|
14618
14758
|
const LOCAL_FONT_FACE_VARIANTS = [
|
|
14619
14759
|
{ key: "regular", weight: 400, style: "normal" },
|
|
14620
14760
|
{ key: "bold", weight: 700, style: "normal" },
|
|
@@ -14644,6 +14784,7 @@ async function registerLocalFontFaces(fontFamily) {
|
|
|
14644
14784
|
style: variant.style
|
|
14645
14785
|
});
|
|
14646
14786
|
document.fonts.add(face);
|
|
14787
|
+
appendLocalFontFaceRule(fontFamily, variant.weight, variant.style, file);
|
|
14647
14788
|
loads.push(face.load().catch(() => void 0));
|
|
14648
14789
|
} catch {
|
|
14649
14790
|
}
|
|
@@ -14808,6 +14949,9 @@ async function ensureFontsForResolvedConfig(config) {
|
|
|
14808
14949
|
const descriptors = collectFontDescriptorsFromConfig(config);
|
|
14809
14950
|
const families = new Set(descriptors.map((d) => d.family));
|
|
14810
14951
|
await withTimeout(Promise.all([...families].map((f) => loadGoogleFontCSS(f))), 3500);
|
|
14952
|
+
await withTimeout(Promise.all(
|
|
14953
|
+
descriptors.map((d) => registerRemoteFontFaceViaProxy(d.family, d.weight, d.style))
|
|
14954
|
+
), 5e3);
|
|
14811
14955
|
if (document.fonts) {
|
|
14812
14956
|
descriptors.forEach((d) => {
|
|
14813
14957
|
const stylePrefix = d.style === "italic" ? "italic " : "";
|
|
@@ -15795,7 +15939,7 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
|
|
|
15795
15939
|
}
|
|
15796
15940
|
return svgString;
|
|
15797
15941
|
}
|
|
15798
|
-
const PACKAGE_VERSION = "0.5.
|
|
15942
|
+
const PACKAGE_VERSION = "0.5.136";
|
|
15799
15943
|
const roundParityValue = (value) => {
|
|
15800
15944
|
if (typeof value !== "number") return value;
|
|
15801
15945
|
return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
|
|
@@ -16214,7 +16358,7 @@ class PixldocsRenderer {
|
|
|
16214
16358
|
await this.waitForCanvasScene(container, cloned, i);
|
|
16215
16359
|
}
|
|
16216
16360
|
console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
|
|
16217
|
-
const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-
|
|
16361
|
+
const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-D3L64sAJ.js");
|
|
16218
16362
|
const prepared = preparePagesForExport(
|
|
16219
16363
|
cloned.pages,
|
|
16220
16364
|
canvasWidth,
|
|
@@ -18117,7 +18261,6 @@ function rasterSvgToPngDataUrl(svgMarkup, pxW, pxH) {
|
|
|
18117
18261
|
const blob = new Blob([svgMarkup], { type: "image/svg+xml;charset=utf-8" });
|
|
18118
18262
|
const url = URL.createObjectURL(blob);
|
|
18119
18263
|
const img = new Image();
|
|
18120
|
-
img.crossOrigin = "anonymous";
|
|
18121
18264
|
const cleanup = () => {
|
|
18122
18265
|
try {
|
|
18123
18266
|
URL.revokeObjectURL(url);
|
|
@@ -18135,6 +18278,7 @@ function rasterSvgToPngDataUrl(svgMarkup, pxW, pxH) {
|
|
|
18135
18278
|
resolve(null);
|
|
18136
18279
|
return;
|
|
18137
18280
|
}
|
|
18281
|
+
ctx.clearRect(0, 0, pxW, pxH);
|
|
18138
18282
|
ctx.drawImage(img, 0, 0, pxW, pxH);
|
|
18139
18283
|
const dataUrl = canvas.toDataURL("image/png");
|
|
18140
18284
|
cleanup();
|
|
@@ -18306,7 +18450,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
|
|
|
18306
18450
|
if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
|
|
18307
18451
|
sanitizeSvgTreeForPdf(svgToDraw);
|
|
18308
18452
|
try {
|
|
18309
|
-
const { bakeTextAnchorPositionsFromLiveSvg } = await import("./vectorPdfExport-
|
|
18453
|
+
const { bakeTextAnchorPositionsFromLiveSvg } = await import("./vectorPdfExport-D3L64sAJ.js");
|
|
18310
18454
|
await bakeTextAnchorPositionsFromLiveSvg(svgToDraw);
|
|
18311
18455
|
} catch (e) {
|
|
18312
18456
|
console.warn("[canvas-renderer][pdf-export] anchor-bake pass failed (continuing):", e);
|
|
@@ -18651,4 +18795,4 @@ export {
|
|
|
18651
18795
|
collectFontDescriptorsFromConfig as y,
|
|
18652
18796
|
collectFontsFromConfig as z
|
|
18653
18797
|
};
|
|
18654
|
-
//# sourceMappingURL=index-
|
|
18798
|
+
//# sourceMappingURL=index-BHa3ekoF.js.map
|