@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
|
@@ -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,114 @@ 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();
|
|
14670
|
+
let localFontFaceStyleEl = null;
|
|
14671
|
+
function ensureLocalFontFaceStyle() {
|
|
14672
|
+
if (typeof document === "undefined") return null;
|
|
14673
|
+
if (localFontFaceStyleEl && localFontFaceStyleEl.isConnected) return localFontFaceStyleEl;
|
|
14674
|
+
try {
|
|
14675
|
+
localFontFaceStyleEl = document.createElement("style");
|
|
14676
|
+
localFontFaceStyleEl.setAttribute("data-pixldocs-local-fontfaces", "1");
|
|
14677
|
+
document.head.appendChild(localFontFaceStyleEl);
|
|
14678
|
+
return localFontFaceStyleEl;
|
|
14679
|
+
} catch {
|
|
14680
|
+
return null;
|
|
14681
|
+
}
|
|
14682
|
+
}
|
|
14683
|
+
function appendLocalFontFaceRule(family, weight, style, file) {
|
|
14684
|
+
const styleEl = ensureLocalFontFaceStyle();
|
|
14685
|
+
if (!styleEl) return;
|
|
14686
|
+
const cssText = `@font-face{font-family:"${family}";src:url("/fonts/${file}");font-weight:${weight};font-style:${style};font-display:swap;}
|
|
14687
|
+
`;
|
|
14688
|
+
styleEl.appendChild(document.createTextNode(cssText));
|
|
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
|
+
}
|
|
14636
14776
|
const LOCAL_FONT_FACE_VARIANTS = [
|
|
14637
14777
|
{ key: "regular", weight: 400, style: "normal" },
|
|
14638
14778
|
{ key: "bold", weight: 700, style: "normal" },
|
|
@@ -14662,6 +14802,7 @@ async function registerLocalFontFaces(fontFamily) {
|
|
|
14662
14802
|
style: variant.style
|
|
14663
14803
|
});
|
|
14664
14804
|
document.fonts.add(face);
|
|
14805
|
+
appendLocalFontFaceRule(fontFamily, variant.weight, variant.style, file);
|
|
14665
14806
|
loads.push(face.load().catch(() => void 0));
|
|
14666
14807
|
} catch {
|
|
14667
14808
|
}
|
|
@@ -14826,6 +14967,9 @@ async function ensureFontsForResolvedConfig(config) {
|
|
|
14826
14967
|
const descriptors = collectFontDescriptorsFromConfig(config);
|
|
14827
14968
|
const families = new Set(descriptors.map((d) => d.family));
|
|
14828
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);
|
|
14829
14973
|
if (document.fonts) {
|
|
14830
14974
|
descriptors.forEach((d) => {
|
|
14831
14975
|
const stylePrefix = d.style === "italic" ? "italic " : "";
|
|
@@ -15813,7 +15957,7 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
|
|
|
15813
15957
|
}
|
|
15814
15958
|
return svgString;
|
|
15815
15959
|
}
|
|
15816
|
-
const PACKAGE_VERSION = "0.5.
|
|
15960
|
+
const PACKAGE_VERSION = "0.5.136";
|
|
15817
15961
|
const roundParityValue = (value) => {
|
|
15818
15962
|
if (typeof value !== "number") return value;
|
|
15819
15963
|
return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
|
|
@@ -16232,7 +16376,7 @@ class PixldocsRenderer {
|
|
|
16232
16376
|
await this.waitForCanvasScene(container, cloned, i);
|
|
16233
16377
|
}
|
|
16234
16378
|
console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
|
|
16235
|
-
const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-
|
|
16379
|
+
const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-Bq-_OarH.cjs"));
|
|
16236
16380
|
const prepared = preparePagesForExport(
|
|
16237
16381
|
cloned.pages,
|
|
16238
16382
|
canvasWidth,
|
|
@@ -18135,7 +18279,6 @@ function rasterSvgToPngDataUrl(svgMarkup, pxW, pxH) {
|
|
|
18135
18279
|
const blob = new Blob([svgMarkup], { type: "image/svg+xml;charset=utf-8" });
|
|
18136
18280
|
const url = URL.createObjectURL(blob);
|
|
18137
18281
|
const img = new Image();
|
|
18138
|
-
img.crossOrigin = "anonymous";
|
|
18139
18282
|
const cleanup = () => {
|
|
18140
18283
|
try {
|
|
18141
18284
|
URL.revokeObjectURL(url);
|
|
@@ -18153,6 +18296,7 @@ function rasterSvgToPngDataUrl(svgMarkup, pxW, pxH) {
|
|
|
18153
18296
|
resolve(null);
|
|
18154
18297
|
return;
|
|
18155
18298
|
}
|
|
18299
|
+
ctx.clearRect(0, 0, pxW, pxH);
|
|
18156
18300
|
ctx.drawImage(img, 0, 0, pxW, pxH);
|
|
18157
18301
|
const dataUrl = canvas.toDataURL("image/png");
|
|
18158
18302
|
cleanup();
|
|
@@ -18324,7 +18468,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
|
|
|
18324
18468
|
if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
|
|
18325
18469
|
sanitizeSvgTreeForPdf(svgToDraw);
|
|
18326
18470
|
try {
|
|
18327
|
-
const { bakeTextAnchorPositionsFromLiveSvg } = await Promise.resolve().then(() => require("./vectorPdfExport-
|
|
18471
|
+
const { bakeTextAnchorPositionsFromLiveSvg } = await Promise.resolve().then(() => require("./vectorPdfExport-Bq-_OarH.cjs"));
|
|
18328
18472
|
await bakeTextAnchorPositionsFromLiveSvg(svgToDraw);
|
|
18329
18473
|
} catch (e) {
|
|
18330
18474
|
console.warn("[canvas-renderer][pdf-export] anchor-bake pass failed (continuing):", e);
|
|
@@ -18666,4 +18810,4 @@ exports.setAutoShrinkDebug = setAutoShrinkDebug;
|
|
|
18666
18810
|
exports.setBundledAssetPrefixes = setBundledAssetPrefixes;
|
|
18667
18811
|
exports.warmResolvedTemplateForPreview = warmResolvedTemplateForPreview;
|
|
18668
18812
|
exports.warmTemplateFromForm = warmTemplateFromForm;
|
|
18669
|
-
//# sourceMappingURL=index-
|
|
18813
|
+
//# sourceMappingURL=index-DUHE7WhJ.cjs.map
|