@pixldocs/canvas-renderer 0.5.133 → 0.5.135
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-D5rY5lp8.cjs → index-BCvB875s.cjs} +127 -7
- package/dist/{index-D5rY5lp8.cjs.map → index-BCvB875s.cjs.map} +1 -1
- package/dist/{index-DMkFzgNL.js → index-WM3oV4wa.js} +127 -7
- package/dist/{index-DMkFzgNL.js.map → index-WM3oV4wa.js.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-BQO8W14A.js → vectorPdfExport-CyHRXea-.js} +4 -4
- package/dist/{vectorPdfExport-BQO8W14A.js.map → vectorPdfExport-CyHRXea-.js.map} +1 -1
- package/dist/{vectorPdfExport-DCNpWd6K.cjs → vectorPdfExport-DFgDiZck.cjs} +4 -4
- package/dist/{vectorPdfExport-DCNpWd6K.cjs.map → vectorPdfExport-DFgDiZck.cjs.map} +1 -1
- package/package.json +1 -1
|
@@ -14633,6 +14633,26 @@ function normalizeFontFamily(fontStack) {
|
|
|
14633
14633
|
const loadedFonts = /* @__PURE__ */ new Set();
|
|
14634
14634
|
const loadingPromises = /* @__PURE__ */ new Map();
|
|
14635
14635
|
const registeredLocalFontFaces = /* @__PURE__ */ new Set();
|
|
14636
|
+
let localFontFaceStyleEl = null;
|
|
14637
|
+
function ensureLocalFontFaceStyle() {
|
|
14638
|
+
if (typeof document === "undefined") return null;
|
|
14639
|
+
if (localFontFaceStyleEl && localFontFaceStyleEl.isConnected) return localFontFaceStyleEl;
|
|
14640
|
+
try {
|
|
14641
|
+
localFontFaceStyleEl = document.createElement("style");
|
|
14642
|
+
localFontFaceStyleEl.setAttribute("data-pixldocs-local-fontfaces", "1");
|
|
14643
|
+
document.head.appendChild(localFontFaceStyleEl);
|
|
14644
|
+
return localFontFaceStyleEl;
|
|
14645
|
+
} catch {
|
|
14646
|
+
return null;
|
|
14647
|
+
}
|
|
14648
|
+
}
|
|
14649
|
+
function appendLocalFontFaceRule(family, weight, style, file) {
|
|
14650
|
+
const styleEl = ensureLocalFontFaceStyle();
|
|
14651
|
+
if (!styleEl) return;
|
|
14652
|
+
const cssText = `@font-face{font-family:"${family}";src:url("/fonts/${file}");font-weight:${weight};font-style:${style};font-display:swap;}
|
|
14653
|
+
`;
|
|
14654
|
+
styleEl.appendChild(document.createTextNode(cssText));
|
|
14655
|
+
}
|
|
14636
14656
|
const LOCAL_FONT_FACE_VARIANTS = [
|
|
14637
14657
|
{ key: "regular", weight: 400, style: "normal" },
|
|
14638
14658
|
{ key: "bold", weight: 700, style: "normal" },
|
|
@@ -14662,6 +14682,7 @@ async function registerLocalFontFaces(fontFamily) {
|
|
|
14662
14682
|
style: variant.style
|
|
14663
14683
|
});
|
|
14664
14684
|
document.fonts.add(face);
|
|
14685
|
+
appendLocalFontFaceRule(fontFamily, variant.weight, variant.style, file);
|
|
14665
14686
|
loads.push(face.load().catch(() => void 0));
|
|
14666
14687
|
} catch {
|
|
14667
14688
|
}
|
|
@@ -15813,7 +15834,7 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
|
|
|
15813
15834
|
}
|
|
15814
15835
|
return svgString;
|
|
15815
15836
|
}
|
|
15816
|
-
const PACKAGE_VERSION = "0.5.
|
|
15837
|
+
const PACKAGE_VERSION = "0.5.135";
|
|
15817
15838
|
const roundParityValue = (value) => {
|
|
15818
15839
|
if (typeof value !== "number") return value;
|
|
15819
15840
|
return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
|
|
@@ -16232,7 +16253,7 @@ class PixldocsRenderer {
|
|
|
16232
16253
|
await this.waitForCanvasScene(container, cloned, i);
|
|
16233
16254
|
}
|
|
16234
16255
|
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-
|
|
16256
|
+
const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-DFgDiZck.cjs"));
|
|
16236
16257
|
const prepared = preparePagesForExport(
|
|
16237
16258
|
cloned.pages,
|
|
16238
16259
|
canvasWidth,
|
|
@@ -18070,7 +18091,7 @@ async function rasterizeShadowMarkers(svg) {
|
|
|
18070
18091
|
if ((_a = document.fonts) == null ? void 0 : _a.ready) await document.fonts.ready;
|
|
18071
18092
|
} catch {
|
|
18072
18093
|
}
|
|
18073
|
-
const fontFaceCss =
|
|
18094
|
+
const fontFaceCss = await collectInlinedFontFaceCss();
|
|
18074
18095
|
for (const marker of markers) {
|
|
18075
18096
|
try {
|
|
18076
18097
|
const blur = parseFloat(marker.getAttribute("data-blur") || "0");
|
|
@@ -18084,7 +18105,9 @@ async function rasterizeShadowMarkers(svg) {
|
|
|
18084
18105
|
(_b = marker.parentNode) == null ? void 0 : _b.removeChild(marker);
|
|
18085
18106
|
continue;
|
|
18086
18107
|
}
|
|
18087
|
-
const innerXml =
|
|
18108
|
+
const innerXml = restoreSourceFontsForShadowRaster(
|
|
18109
|
+
Array.from(marker.childNodes).map((n) => n instanceof Element ? new XMLSerializer().serializeToString(n) : "").join("")
|
|
18110
|
+
);
|
|
18088
18111
|
try {
|
|
18089
18112
|
const fontSpecs = collectFontSpecsFromMarkup(innerXml);
|
|
18090
18113
|
if (fontSpecs.length > 0 && ((_c = document.fonts) == null ? void 0 : _c.load)) {
|
|
@@ -18133,7 +18156,6 @@ function rasterSvgToPngDataUrl(svgMarkup, pxW, pxH) {
|
|
|
18133
18156
|
const blob = new Blob([svgMarkup], { type: "image/svg+xml;charset=utf-8" });
|
|
18134
18157
|
const url = URL.createObjectURL(blob);
|
|
18135
18158
|
const img = new Image();
|
|
18136
|
-
img.crossOrigin = "anonymous";
|
|
18137
18159
|
const cleanup = () => {
|
|
18138
18160
|
try {
|
|
18139
18161
|
URL.revokeObjectURL(url);
|
|
@@ -18151,6 +18173,7 @@ function rasterSvgToPngDataUrl(svgMarkup, pxW, pxH) {
|
|
|
18151
18173
|
resolve(null);
|
|
18152
18174
|
return;
|
|
18153
18175
|
}
|
|
18176
|
+
ctx.clearRect(0, 0, pxW, pxH);
|
|
18154
18177
|
ctx.drawImage(img, 0, 0, pxW, pxH);
|
|
18155
18178
|
const dataUrl = canvas.toDataURL("image/png");
|
|
18156
18179
|
cleanup();
|
|
@@ -18195,6 +18218,103 @@ function collectDocumentFontFaceCss() {
|
|
|
18195
18218
|
cachedFontFaceCss = out.join("\n");
|
|
18196
18219
|
return cachedFontFaceCss;
|
|
18197
18220
|
}
|
|
18221
|
+
let cachedInlinedFontFaceCss = null;
|
|
18222
|
+
const fontUrlDataCache = /* @__PURE__ */ new Map();
|
|
18223
|
+
async function fetchFontAsDataUri(url) {
|
|
18224
|
+
if (fontUrlDataCache.has(url)) return fontUrlDataCache.get(url) ?? null;
|
|
18225
|
+
try {
|
|
18226
|
+
const resp = await fetch(url, { mode: "cors", credentials: "omit" });
|
|
18227
|
+
if (!resp.ok) {
|
|
18228
|
+
fontUrlDataCache.set(url, null);
|
|
18229
|
+
return null;
|
|
18230
|
+
}
|
|
18231
|
+
const blob = await resp.blob();
|
|
18232
|
+
const dataUri = await new Promise((resolve, reject) => {
|
|
18233
|
+
const fr = new FileReader();
|
|
18234
|
+
fr.onload = () => resolve(String(fr.result));
|
|
18235
|
+
fr.onerror = () => reject(fr.error);
|
|
18236
|
+
fr.readAsDataURL(blob);
|
|
18237
|
+
});
|
|
18238
|
+
fontUrlDataCache.set(url, dataUri);
|
|
18239
|
+
return dataUri;
|
|
18240
|
+
} catch {
|
|
18241
|
+
fontUrlDataCache.set(url, null);
|
|
18242
|
+
return null;
|
|
18243
|
+
}
|
|
18244
|
+
}
|
|
18245
|
+
async function inlineUrlsInCss(css) {
|
|
18246
|
+
const urlRe = /url\((['"]?)([^'")]+)\1\)/gi;
|
|
18247
|
+
const matches = [];
|
|
18248
|
+
let m;
|
|
18249
|
+
while ((m = urlRe.exec(css)) !== null) {
|
|
18250
|
+
const raw = m[2].trim();
|
|
18251
|
+
if (raw.startsWith("data:")) continue;
|
|
18252
|
+
let abs = raw;
|
|
18253
|
+
try {
|
|
18254
|
+
abs = new URL(raw, document.baseURI).toString();
|
|
18255
|
+
} catch {
|
|
18256
|
+
}
|
|
18257
|
+
matches.push({ full: m[0], url: abs });
|
|
18258
|
+
}
|
|
18259
|
+
if (matches.length === 0) return css;
|
|
18260
|
+
const unique = Array.from(new Set(matches.map((mm) => mm.url)));
|
|
18261
|
+
const results = await Promise.all(unique.map((u) => fetchFontAsDataUri(u)));
|
|
18262
|
+
const map = /* @__PURE__ */ new Map();
|
|
18263
|
+
unique.forEach((u, i) => map.set(u, results[i]));
|
|
18264
|
+
let out = css;
|
|
18265
|
+
for (const { full, url } of matches) {
|
|
18266
|
+
const data = map.get(url);
|
|
18267
|
+
if (!data) continue;
|
|
18268
|
+
const safeFull = full.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
18269
|
+
out = out.replace(new RegExp(safeFull, "g"), `url("${data}")`);
|
|
18270
|
+
}
|
|
18271
|
+
return out;
|
|
18272
|
+
}
|
|
18273
|
+
async function collectInlinedFontFaceCss() {
|
|
18274
|
+
if (cachedInlinedFontFaceCss !== null) return cachedInlinedFontFaceCss;
|
|
18275
|
+
const raw = collectDocumentFontFaceCss();
|
|
18276
|
+
if (!raw) {
|
|
18277
|
+
cachedInlinedFontFaceCss = "";
|
|
18278
|
+
return "";
|
|
18279
|
+
}
|
|
18280
|
+
try {
|
|
18281
|
+
cachedInlinedFontFaceCss = await inlineUrlsInCss(raw);
|
|
18282
|
+
} catch {
|
|
18283
|
+
cachedInlinedFontFaceCss = raw;
|
|
18284
|
+
}
|
|
18285
|
+
return cachedInlinedFontFaceCss;
|
|
18286
|
+
}
|
|
18287
|
+
function restoreSourceFontsForShadowRaster(markup) {
|
|
18288
|
+
try {
|
|
18289
|
+
const parser = new DOMParser();
|
|
18290
|
+
const doc = parser.parseFromString(`<svg xmlns="http://www.w3.org/2000/svg">${markup}</svg>`, "image/svg+xml");
|
|
18291
|
+
if (doc.querySelector("parsererror")) return markup;
|
|
18292
|
+
for (const node of Array.from(doc.querySelectorAll("text, tspan, textPath"))) {
|
|
18293
|
+
const family = node.getAttribute("data-source-font-family");
|
|
18294
|
+
const weight = node.getAttribute("data-source-font-weight");
|
|
18295
|
+
const style = node.getAttribute("data-source-font-style");
|
|
18296
|
+
if (!family && !weight && !style) continue;
|
|
18297
|
+
const stylePairs = (node.getAttribute("style") || "").split(";").map((part) => part.trim()).filter(Boolean).filter((part) => !/^font-family\s*:/i.test(part) && !/^font-weight\s*:/i.test(part) && !/^font-style\s*:/i.test(part));
|
|
18298
|
+
if (family) {
|
|
18299
|
+
node.setAttribute("font-family", family);
|
|
18300
|
+
stylePairs.push(`font-family: ${family}`);
|
|
18301
|
+
}
|
|
18302
|
+
if (weight) {
|
|
18303
|
+
node.setAttribute("font-weight", weight);
|
|
18304
|
+
stylePairs.push(`font-weight: ${weight}`);
|
|
18305
|
+
}
|
|
18306
|
+
if (style) {
|
|
18307
|
+
node.setAttribute("font-style", style);
|
|
18308
|
+
stylePairs.push(`font-style: ${style}`);
|
|
18309
|
+
}
|
|
18310
|
+
if (stylePairs.length > 0) node.setAttribute("style", stylePairs.join("; "));
|
|
18311
|
+
}
|
|
18312
|
+
const root = doc.documentElement;
|
|
18313
|
+
return Array.from(root.childNodes).map((n) => n instanceof Element ? new XMLSerializer().serializeToString(n) : "").join("");
|
|
18314
|
+
} catch {
|
|
18315
|
+
return markup;
|
|
18316
|
+
}
|
|
18317
|
+
}
|
|
18198
18318
|
async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey, options) {
|
|
18199
18319
|
try {
|
|
18200
18320
|
const parser = new DOMParser();
|
|
@@ -18225,7 +18345,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
|
|
|
18225
18345
|
if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
|
|
18226
18346
|
sanitizeSvgTreeForPdf(svgToDraw);
|
|
18227
18347
|
try {
|
|
18228
|
-
const { bakeTextAnchorPositionsFromLiveSvg } = await Promise.resolve().then(() => require("./vectorPdfExport-
|
|
18348
|
+
const { bakeTextAnchorPositionsFromLiveSvg } = await Promise.resolve().then(() => require("./vectorPdfExport-DFgDiZck.cjs"));
|
|
18229
18349
|
await bakeTextAnchorPositionsFromLiveSvg(svgToDraw);
|
|
18230
18350
|
} catch (e) {
|
|
18231
18351
|
console.warn("[canvas-renderer][pdf-export] anchor-bake pass failed (continuing):", e);
|
|
@@ -18567,4 +18687,4 @@ exports.setAutoShrinkDebug = setAutoShrinkDebug;
|
|
|
18567
18687
|
exports.setBundledAssetPrefixes = setBundledAssetPrefixes;
|
|
18568
18688
|
exports.warmResolvedTemplateForPreview = warmResolvedTemplateForPreview;
|
|
18569
18689
|
exports.warmTemplateFromForm = warmTemplateFromForm;
|
|
18570
|
-
//# sourceMappingURL=index-
|
|
18690
|
+
//# sourceMappingURL=index-BCvB875s.cjs.map
|