@pixldocs/canvas-renderer 0.5.135 → 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-WM3oV4wa.js → index-BHa3ekoF.js} +127 -4
- package/dist/{index-WM3oV4wa.js.map → index-BHa3ekoF.js.map} +1 -1
- package/dist/{index-BCvB875s.cjs → index-DUHE7WhJ.cjs} +127 -4
- package/dist/{index-BCvB875s.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-DFgDiZck.cjs → vectorPdfExport-Bq-_OarH.cjs} +4 -4
- package/dist/{vectorPdfExport-DFgDiZck.cjs.map → vectorPdfExport-Bq-_OarH.cjs.map} +1 -1
- package/dist/{vectorPdfExport-CyHRXea-.js → vectorPdfExport-D3L64sAJ.js} +4 -4
- package/dist/{vectorPdfExport-CyHRXea-.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,8 @@ 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();
|
|
14618
14652
|
let localFontFaceStyleEl = null;
|
|
14619
14653
|
function ensureLocalFontFaceStyle() {
|
|
14620
14654
|
if (typeof document === "undefined") return null;
|
|
@@ -14635,6 +14669,92 @@ function appendLocalFontFaceRule(family, weight, style, file) {
|
|
|
14635
14669
|
`;
|
|
14636
14670
|
styleEl.appendChild(document.createTextNode(cssText));
|
|
14637
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
|
+
}
|
|
14638
14758
|
const LOCAL_FONT_FACE_VARIANTS = [
|
|
14639
14759
|
{ key: "regular", weight: 400, style: "normal" },
|
|
14640
14760
|
{ key: "bold", weight: 700, style: "normal" },
|
|
@@ -14829,6 +14949,9 @@ async function ensureFontsForResolvedConfig(config) {
|
|
|
14829
14949
|
const descriptors = collectFontDescriptorsFromConfig(config);
|
|
14830
14950
|
const families = new Set(descriptors.map((d) => d.family));
|
|
14831
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);
|
|
14832
14955
|
if (document.fonts) {
|
|
14833
14956
|
descriptors.forEach((d) => {
|
|
14834
14957
|
const stylePrefix = d.style === "italic" ? "italic " : "";
|
|
@@ -15816,7 +15939,7 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
|
|
|
15816
15939
|
}
|
|
15817
15940
|
return svgString;
|
|
15818
15941
|
}
|
|
15819
|
-
const PACKAGE_VERSION = "0.5.
|
|
15942
|
+
const PACKAGE_VERSION = "0.5.136";
|
|
15820
15943
|
const roundParityValue = (value) => {
|
|
15821
15944
|
if (typeof value !== "number") return value;
|
|
15822
15945
|
return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
|
|
@@ -16235,7 +16358,7 @@ class PixldocsRenderer {
|
|
|
16235
16358
|
await this.waitForCanvasScene(container, cloned, i);
|
|
16236
16359
|
}
|
|
16237
16360
|
console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
|
|
16238
|
-
const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-
|
|
16361
|
+
const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-D3L64sAJ.js");
|
|
16239
16362
|
const prepared = preparePagesForExport(
|
|
16240
16363
|
cloned.pages,
|
|
16241
16364
|
canvasWidth,
|
|
@@ -18327,7 +18450,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
|
|
|
18327
18450
|
if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
|
|
18328
18451
|
sanitizeSvgTreeForPdf(svgToDraw);
|
|
18329
18452
|
try {
|
|
18330
|
-
const { bakeTextAnchorPositionsFromLiveSvg } = await import("./vectorPdfExport-
|
|
18453
|
+
const { bakeTextAnchorPositionsFromLiveSvg } = await import("./vectorPdfExport-D3L64sAJ.js");
|
|
18331
18454
|
await bakeTextAnchorPositionsFromLiveSvg(svgToDraw);
|
|
18332
18455
|
} catch (e) {
|
|
18333
18456
|
console.warn("[canvas-renderer][pdf-export] anchor-bake pass failed (continuing):", e);
|
|
@@ -18672,4 +18795,4 @@ export {
|
|
|
18672
18795
|
collectFontDescriptorsFromConfig as y,
|
|
18673
18796
|
collectFontsFromConfig as z
|
|
18674
18797
|
};
|
|
18675
|
-
//# sourceMappingURL=index-
|
|
18798
|
+
//# sourceMappingURL=index-BHa3ekoF.js.map
|