@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
|
@@ -14626,6 +14626,38 @@ const pdfFonts = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProp
|
|
|
14626
14626
|
resolveFontWeight,
|
|
14627
14627
|
rewriteSvgFontsForJsPDF
|
|
14628
14628
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
14629
|
+
const FONTSHARE_SLUGS = {
|
|
14630
|
+
"Satoshi": "satoshi",
|
|
14631
|
+
"Cabinet Grotesk": "cabinet-grotesk",
|
|
14632
|
+
"Clash Display": "clash-display",
|
|
14633
|
+
"Clash Grotesk": "clash-grotesk",
|
|
14634
|
+
"General Sans": "general-sans",
|
|
14635
|
+
"Switzer": "switzer",
|
|
14636
|
+
"Supreme": "supreme",
|
|
14637
|
+
"Author": "author",
|
|
14638
|
+
"Boska": "boska",
|
|
14639
|
+
"Excon": "excon",
|
|
14640
|
+
"Khand": "khand",
|
|
14641
|
+
"Sentient": "sentient",
|
|
14642
|
+
"Synonym": "synonym",
|
|
14643
|
+
"Erode": "erode",
|
|
14644
|
+
"Ranade": "ranade",
|
|
14645
|
+
"Tanker": "tanker",
|
|
14646
|
+
"Zodiak": "zodiak",
|
|
14647
|
+
"Gambarino": "gambarino",
|
|
14648
|
+
"Melodrama": "melodrama",
|
|
14649
|
+
"Bespoke Serif": "bespoke-serif",
|
|
14650
|
+
"Bespoke Stencil": "bespoke-stencil",
|
|
14651
|
+
"Panchang": "panchang",
|
|
14652
|
+
"Quincy CF": "quincy-cf",
|
|
14653
|
+
"Pally": "pally",
|
|
14654
|
+
"Tabular": "tabular",
|
|
14655
|
+
"Sharpie": "sharpie",
|
|
14656
|
+
"Stardom": "stardom",
|
|
14657
|
+
"Rebond Grotesque": "rebond-grotesque",
|
|
14658
|
+
"Telma": "telma",
|
|
14659
|
+
"Nippo": "nippo"
|
|
14660
|
+
};
|
|
14629
14661
|
function normalizeFontFamily(fontStack) {
|
|
14630
14662
|
const first = fontStack.split(",")[0].trim();
|
|
14631
14663
|
return first.replace(/^['"]|['"]$/g, "");
|
|
@@ -14633,6 +14665,8 @@ function normalizeFontFamily(fontStack) {
|
|
|
14633
14665
|
const loadedFonts = /* @__PURE__ */ new Set();
|
|
14634
14666
|
const loadingPromises = /* @__PURE__ */ new Map();
|
|
14635
14667
|
const registeredLocalFontFaces = /* @__PURE__ */ new Set();
|
|
14668
|
+
const registeredRemoteFontFaces = /* @__PURE__ */ new Set();
|
|
14669
|
+
const remoteFontDataUriPromises = /* @__PURE__ */ new Map();
|
|
14636
14670
|
let localFontFaceStyleEl = null;
|
|
14637
14671
|
function ensureLocalFontFaceStyle() {
|
|
14638
14672
|
if (typeof document === "undefined") return null;
|
|
@@ -14653,6 +14687,92 @@ function appendLocalFontFaceRule(family, weight, style, file) {
|
|
|
14653
14687
|
`;
|
|
14654
14688
|
styleEl.appendChild(document.createTextNode(cssText));
|
|
14655
14689
|
}
|
|
14690
|
+
function appendDataUriFontFaceRule(family, weight, style, dataUri) {
|
|
14691
|
+
const styleEl = ensureLocalFontFaceStyle();
|
|
14692
|
+
if (!styleEl) return;
|
|
14693
|
+
const cssText = `@font-face{font-family:"${family}";src:url("${dataUri}") format("truetype");font-weight:${weight};font-style:${style};font-display:swap;}
|
|
14694
|
+
`;
|
|
14695
|
+
styleEl.appendChild(document.createTextNode(cssText));
|
|
14696
|
+
}
|
|
14697
|
+
function resolveHarnessFontProxyUrl() {
|
|
14698
|
+
var _a, _b;
|
|
14699
|
+
try {
|
|
14700
|
+
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)) || "";
|
|
14701
|
+
const base = String(runtimeBase || "").replace(/\/$/, "");
|
|
14702
|
+
return base ? `${base}/functions/v1/font-proxy` : "";
|
|
14703
|
+
} catch {
|
|
14704
|
+
return "";
|
|
14705
|
+
}
|
|
14706
|
+
}
|
|
14707
|
+
function isEmbeddableTrueType(bytes) {
|
|
14708
|
+
if (bytes.length < 12) return false;
|
|
14709
|
+
const signature = String.fromCharCode(bytes[0], bytes[1], bytes[2], bytes[3]);
|
|
14710
|
+
return signature === "\0\0\0" || signature === "true";
|
|
14711
|
+
}
|
|
14712
|
+
async function arrayBufferToDataUri(buf) {
|
|
14713
|
+
const blob = new Blob([buf], { type: "font/ttf" });
|
|
14714
|
+
return await new Promise((resolve, reject) => {
|
|
14715
|
+
const reader = new FileReader();
|
|
14716
|
+
reader.onload = () => resolve(String(reader.result));
|
|
14717
|
+
reader.onerror = () => reject(reader.error || new Error("Failed to read font bytes"));
|
|
14718
|
+
reader.readAsDataURL(blob);
|
|
14719
|
+
});
|
|
14720
|
+
}
|
|
14721
|
+
async function fetchFontProxyDataUri(family, weight, style, source) {
|
|
14722
|
+
const proxyUrl = resolveHarnessFontProxyUrl();
|
|
14723
|
+
if (!proxyUrl) return null;
|
|
14724
|
+
const key = `${source}|${family}|${weight}|${style}`;
|
|
14725
|
+
const existing = remoteFontDataUriPromises.get(key);
|
|
14726
|
+
if (existing) return existing;
|
|
14727
|
+
const promise = (async () => {
|
|
14728
|
+
try {
|
|
14729
|
+
const url = `${proxyUrl}?family=${encodeURIComponent(family)}&weight=${weight}&italic=${style === "italic" ? 1 : 0}&source=${source}`;
|
|
14730
|
+
const res = await fetch(url, { credentials: "omit" });
|
|
14731
|
+
if (!res.ok) return null;
|
|
14732
|
+
const contentType = res.headers.get("content-type") || "";
|
|
14733
|
+
if (/application\/json/i.test(contentType)) return null;
|
|
14734
|
+
const buf = await res.arrayBuffer();
|
|
14735
|
+
const bytes = new Uint8Array(buf);
|
|
14736
|
+
if (!isEmbeddableTrueType(bytes)) return null;
|
|
14737
|
+
return await arrayBufferToDataUri(buf);
|
|
14738
|
+
} catch {
|
|
14739
|
+
return null;
|
|
14740
|
+
}
|
|
14741
|
+
})();
|
|
14742
|
+
remoteFontDataUriPromises.set(key, promise);
|
|
14743
|
+
return promise;
|
|
14744
|
+
}
|
|
14745
|
+
async function registerRemoteFontFaceViaProxy(family, requestedWeight, styleRaw) {
|
|
14746
|
+
if (typeof document === "undefined" || typeof FontFace === "undefined" || !document.fonts) return false;
|
|
14747
|
+
if (!resolveHarnessFontProxyUrl()) return false;
|
|
14748
|
+
const style = /italic|oblique/i.test(styleRaw || "") ? "italic" : "normal";
|
|
14749
|
+
const parsed = typeof requestedWeight === "number" ? requestedWeight : Number.parseInt(String(requestedWeight || "400"), 10);
|
|
14750
|
+
const resolved = Number.isFinite(parsed) ? parsed <= 350 ? 300 : parsed <= 450 ? 400 : parsed <= 550 ? 500 : parsed <= 650 ? 600 : 700 : 400;
|
|
14751
|
+
const weightLadder = [resolved];
|
|
14752
|
+
for (const w of [400, 500, 700, 600, 300]) if (!weightLadder.includes(w)) weightLadder.push(w);
|
|
14753
|
+
const sourceOrder = FONTSHARE_SLUGS[family] ? ["fontshare", "google"] : ["google", "fontshare"];
|
|
14754
|
+
for (const actualWeight of weightLadder) {
|
|
14755
|
+
for (const source of sourceOrder) {
|
|
14756
|
+
const faceKey = `${family}|${actualWeight}|${style}|${source}`;
|
|
14757
|
+
if (registeredRemoteFontFaces.has(faceKey)) return true;
|
|
14758
|
+
const dataUri = await fetchFontProxyDataUri(family, actualWeight, style, source);
|
|
14759
|
+
if (!dataUri) continue;
|
|
14760
|
+
try {
|
|
14761
|
+
const face = new FontFace(family, `url("${dataUri}")`, {
|
|
14762
|
+
weight: String(actualWeight),
|
|
14763
|
+
style
|
|
14764
|
+
});
|
|
14765
|
+
await face.load();
|
|
14766
|
+
document.fonts.add(face);
|
|
14767
|
+
appendDataUriFontFaceRule(family, actualWeight, style, dataUri);
|
|
14768
|
+
registeredRemoteFontFaces.add(faceKey);
|
|
14769
|
+
return true;
|
|
14770
|
+
} catch {
|
|
14771
|
+
}
|
|
14772
|
+
}
|
|
14773
|
+
}
|
|
14774
|
+
return false;
|
|
14775
|
+
}
|
|
14656
14776
|
const LOCAL_FONT_FACE_VARIANTS = [
|
|
14657
14777
|
{ key: "regular", weight: 400, style: "normal" },
|
|
14658
14778
|
{ key: "bold", weight: 700, style: "normal" },
|
|
@@ -14847,6 +14967,9 @@ async function ensureFontsForResolvedConfig(config) {
|
|
|
14847
14967
|
const descriptors = collectFontDescriptorsFromConfig(config);
|
|
14848
14968
|
const families = new Set(descriptors.map((d) => d.family));
|
|
14849
14969
|
await withTimeout(Promise.all([...families].map((f) => loadGoogleFontCSS(f))), 3500);
|
|
14970
|
+
await withTimeout(Promise.all(
|
|
14971
|
+
descriptors.map((d) => registerRemoteFontFaceViaProxy(d.family, d.weight, d.style))
|
|
14972
|
+
), 5e3);
|
|
14850
14973
|
if (document.fonts) {
|
|
14851
14974
|
descriptors.forEach((d) => {
|
|
14852
14975
|
const stylePrefix = d.style === "italic" ? "italic " : "";
|
|
@@ -15834,7 +15957,7 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
|
|
|
15834
15957
|
}
|
|
15835
15958
|
return svgString;
|
|
15836
15959
|
}
|
|
15837
|
-
const PACKAGE_VERSION = "0.5.
|
|
15960
|
+
const PACKAGE_VERSION = "0.5.136";
|
|
15838
15961
|
const roundParityValue = (value) => {
|
|
15839
15962
|
if (typeof value !== "number") return value;
|
|
15840
15963
|
return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
|
|
@@ -16253,7 +16376,7 @@ class PixldocsRenderer {
|
|
|
16253
16376
|
await this.waitForCanvasScene(container, cloned, i);
|
|
16254
16377
|
}
|
|
16255
16378
|
console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
|
|
16256
|
-
const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-
|
|
16379
|
+
const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-Bq-_OarH.cjs"));
|
|
16257
16380
|
const prepared = preparePagesForExport(
|
|
16258
16381
|
cloned.pages,
|
|
16259
16382
|
canvasWidth,
|
|
@@ -18345,7 +18468,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
|
|
|
18345
18468
|
if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
|
|
18346
18469
|
sanitizeSvgTreeForPdf(svgToDraw);
|
|
18347
18470
|
try {
|
|
18348
|
-
const { bakeTextAnchorPositionsFromLiveSvg } = await Promise.resolve().then(() => require("./vectorPdfExport-
|
|
18471
|
+
const { bakeTextAnchorPositionsFromLiveSvg } = await Promise.resolve().then(() => require("./vectorPdfExport-Bq-_OarH.cjs"));
|
|
18349
18472
|
await bakeTextAnchorPositionsFromLiveSvg(svgToDraw);
|
|
18350
18473
|
} catch (e) {
|
|
18351
18474
|
console.warn("[canvas-renderer][pdf-export] anchor-bake pass failed (continuing):", e);
|
|
@@ -18687,4 +18810,4 @@ exports.setAutoShrinkDebug = setAutoShrinkDebug;
|
|
|
18687
18810
|
exports.setBundledAssetPrefixes = setBundledAssetPrefixes;
|
|
18688
18811
|
exports.warmResolvedTemplateForPreview = warmResolvedTemplateForPreview;
|
|
18689
18812
|
exports.warmTemplateFromForm = warmTemplateFromForm;
|
|
18690
|
-
//# sourceMappingURL=index-
|
|
18813
|
+
//# sourceMappingURL=index-DUHE7WhJ.cjs.map
|