@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
|
@@ -14615,6 +14615,26 @@ function normalizeFontFamily(fontStack) {
|
|
|
14615
14615
|
const loadedFonts = /* @__PURE__ */ new Set();
|
|
14616
14616
|
const loadingPromises = /* @__PURE__ */ new Map();
|
|
14617
14617
|
const registeredLocalFontFaces = /* @__PURE__ */ new Set();
|
|
14618
|
+
let localFontFaceStyleEl = null;
|
|
14619
|
+
function ensureLocalFontFaceStyle() {
|
|
14620
|
+
if (typeof document === "undefined") return null;
|
|
14621
|
+
if (localFontFaceStyleEl && localFontFaceStyleEl.isConnected) return localFontFaceStyleEl;
|
|
14622
|
+
try {
|
|
14623
|
+
localFontFaceStyleEl = document.createElement("style");
|
|
14624
|
+
localFontFaceStyleEl.setAttribute("data-pixldocs-local-fontfaces", "1");
|
|
14625
|
+
document.head.appendChild(localFontFaceStyleEl);
|
|
14626
|
+
return localFontFaceStyleEl;
|
|
14627
|
+
} catch {
|
|
14628
|
+
return null;
|
|
14629
|
+
}
|
|
14630
|
+
}
|
|
14631
|
+
function appendLocalFontFaceRule(family, weight, style, file) {
|
|
14632
|
+
const styleEl = ensureLocalFontFaceStyle();
|
|
14633
|
+
if (!styleEl) return;
|
|
14634
|
+
const cssText = `@font-face{font-family:"${family}";src:url("/fonts/${file}");font-weight:${weight};font-style:${style};font-display:swap;}
|
|
14635
|
+
`;
|
|
14636
|
+
styleEl.appendChild(document.createTextNode(cssText));
|
|
14637
|
+
}
|
|
14618
14638
|
const LOCAL_FONT_FACE_VARIANTS = [
|
|
14619
14639
|
{ key: "regular", weight: 400, style: "normal" },
|
|
14620
14640
|
{ key: "bold", weight: 700, style: "normal" },
|
|
@@ -14644,6 +14664,7 @@ async function registerLocalFontFaces(fontFamily) {
|
|
|
14644
14664
|
style: variant.style
|
|
14645
14665
|
});
|
|
14646
14666
|
document.fonts.add(face);
|
|
14667
|
+
appendLocalFontFaceRule(fontFamily, variant.weight, variant.style, file);
|
|
14647
14668
|
loads.push(face.load().catch(() => void 0));
|
|
14648
14669
|
} catch {
|
|
14649
14670
|
}
|
|
@@ -15795,7 +15816,7 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
|
|
|
15795
15816
|
}
|
|
15796
15817
|
return svgString;
|
|
15797
15818
|
}
|
|
15798
|
-
const PACKAGE_VERSION = "0.5.
|
|
15819
|
+
const PACKAGE_VERSION = "0.5.135";
|
|
15799
15820
|
const roundParityValue = (value) => {
|
|
15800
15821
|
if (typeof value !== "number") return value;
|
|
15801
15822
|
return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
|
|
@@ -16214,7 +16235,7 @@ class PixldocsRenderer {
|
|
|
16214
16235
|
await this.waitForCanvasScene(container, cloned, i);
|
|
16215
16236
|
}
|
|
16216
16237
|
console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
|
|
16217
|
-
const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-
|
|
16238
|
+
const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-CyHRXea-.js");
|
|
16218
16239
|
const prepared = preparePagesForExport(
|
|
16219
16240
|
cloned.pages,
|
|
16220
16241
|
canvasWidth,
|
|
@@ -18052,7 +18073,7 @@ async function rasterizeShadowMarkers(svg) {
|
|
|
18052
18073
|
if ((_a = document.fonts) == null ? void 0 : _a.ready) await document.fonts.ready;
|
|
18053
18074
|
} catch {
|
|
18054
18075
|
}
|
|
18055
|
-
const fontFaceCss =
|
|
18076
|
+
const fontFaceCss = await collectInlinedFontFaceCss();
|
|
18056
18077
|
for (const marker of markers) {
|
|
18057
18078
|
try {
|
|
18058
18079
|
const blur = parseFloat(marker.getAttribute("data-blur") || "0");
|
|
@@ -18066,7 +18087,9 @@ async function rasterizeShadowMarkers(svg) {
|
|
|
18066
18087
|
(_b = marker.parentNode) == null ? void 0 : _b.removeChild(marker);
|
|
18067
18088
|
continue;
|
|
18068
18089
|
}
|
|
18069
|
-
const innerXml =
|
|
18090
|
+
const innerXml = restoreSourceFontsForShadowRaster(
|
|
18091
|
+
Array.from(marker.childNodes).map((n) => n instanceof Element ? new XMLSerializer().serializeToString(n) : "").join("")
|
|
18092
|
+
);
|
|
18070
18093
|
try {
|
|
18071
18094
|
const fontSpecs = collectFontSpecsFromMarkup(innerXml);
|
|
18072
18095
|
if (fontSpecs.length > 0 && ((_c = document.fonts) == null ? void 0 : _c.load)) {
|
|
@@ -18115,7 +18138,6 @@ function rasterSvgToPngDataUrl(svgMarkup, pxW, pxH) {
|
|
|
18115
18138
|
const blob = new Blob([svgMarkup], { type: "image/svg+xml;charset=utf-8" });
|
|
18116
18139
|
const url = URL.createObjectURL(blob);
|
|
18117
18140
|
const img = new Image();
|
|
18118
|
-
img.crossOrigin = "anonymous";
|
|
18119
18141
|
const cleanup = () => {
|
|
18120
18142
|
try {
|
|
18121
18143
|
URL.revokeObjectURL(url);
|
|
@@ -18133,6 +18155,7 @@ function rasterSvgToPngDataUrl(svgMarkup, pxW, pxH) {
|
|
|
18133
18155
|
resolve(null);
|
|
18134
18156
|
return;
|
|
18135
18157
|
}
|
|
18158
|
+
ctx.clearRect(0, 0, pxW, pxH);
|
|
18136
18159
|
ctx.drawImage(img, 0, 0, pxW, pxH);
|
|
18137
18160
|
const dataUrl = canvas.toDataURL("image/png");
|
|
18138
18161
|
cleanup();
|
|
@@ -18177,6 +18200,103 @@ function collectDocumentFontFaceCss() {
|
|
|
18177
18200
|
cachedFontFaceCss = out.join("\n");
|
|
18178
18201
|
return cachedFontFaceCss;
|
|
18179
18202
|
}
|
|
18203
|
+
let cachedInlinedFontFaceCss = null;
|
|
18204
|
+
const fontUrlDataCache = /* @__PURE__ */ new Map();
|
|
18205
|
+
async function fetchFontAsDataUri(url) {
|
|
18206
|
+
if (fontUrlDataCache.has(url)) return fontUrlDataCache.get(url) ?? null;
|
|
18207
|
+
try {
|
|
18208
|
+
const resp = await fetch(url, { mode: "cors", credentials: "omit" });
|
|
18209
|
+
if (!resp.ok) {
|
|
18210
|
+
fontUrlDataCache.set(url, null);
|
|
18211
|
+
return null;
|
|
18212
|
+
}
|
|
18213
|
+
const blob = await resp.blob();
|
|
18214
|
+
const dataUri = await new Promise((resolve, reject) => {
|
|
18215
|
+
const fr = new FileReader();
|
|
18216
|
+
fr.onload = () => resolve(String(fr.result));
|
|
18217
|
+
fr.onerror = () => reject(fr.error);
|
|
18218
|
+
fr.readAsDataURL(blob);
|
|
18219
|
+
});
|
|
18220
|
+
fontUrlDataCache.set(url, dataUri);
|
|
18221
|
+
return dataUri;
|
|
18222
|
+
} catch {
|
|
18223
|
+
fontUrlDataCache.set(url, null);
|
|
18224
|
+
return null;
|
|
18225
|
+
}
|
|
18226
|
+
}
|
|
18227
|
+
async function inlineUrlsInCss(css) {
|
|
18228
|
+
const urlRe = /url\((['"]?)([^'")]+)\1\)/gi;
|
|
18229
|
+
const matches = [];
|
|
18230
|
+
let m;
|
|
18231
|
+
while ((m = urlRe.exec(css)) !== null) {
|
|
18232
|
+
const raw = m[2].trim();
|
|
18233
|
+
if (raw.startsWith("data:")) continue;
|
|
18234
|
+
let abs = raw;
|
|
18235
|
+
try {
|
|
18236
|
+
abs = new URL(raw, document.baseURI).toString();
|
|
18237
|
+
} catch {
|
|
18238
|
+
}
|
|
18239
|
+
matches.push({ full: m[0], url: abs });
|
|
18240
|
+
}
|
|
18241
|
+
if (matches.length === 0) return css;
|
|
18242
|
+
const unique = Array.from(new Set(matches.map((mm) => mm.url)));
|
|
18243
|
+
const results = await Promise.all(unique.map((u) => fetchFontAsDataUri(u)));
|
|
18244
|
+
const map = /* @__PURE__ */ new Map();
|
|
18245
|
+
unique.forEach((u, i) => map.set(u, results[i]));
|
|
18246
|
+
let out = css;
|
|
18247
|
+
for (const { full, url } of matches) {
|
|
18248
|
+
const data = map.get(url);
|
|
18249
|
+
if (!data) continue;
|
|
18250
|
+
const safeFull = full.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
18251
|
+
out = out.replace(new RegExp(safeFull, "g"), `url("${data}")`);
|
|
18252
|
+
}
|
|
18253
|
+
return out;
|
|
18254
|
+
}
|
|
18255
|
+
async function collectInlinedFontFaceCss() {
|
|
18256
|
+
if (cachedInlinedFontFaceCss !== null) return cachedInlinedFontFaceCss;
|
|
18257
|
+
const raw = collectDocumentFontFaceCss();
|
|
18258
|
+
if (!raw) {
|
|
18259
|
+
cachedInlinedFontFaceCss = "";
|
|
18260
|
+
return "";
|
|
18261
|
+
}
|
|
18262
|
+
try {
|
|
18263
|
+
cachedInlinedFontFaceCss = await inlineUrlsInCss(raw);
|
|
18264
|
+
} catch {
|
|
18265
|
+
cachedInlinedFontFaceCss = raw;
|
|
18266
|
+
}
|
|
18267
|
+
return cachedInlinedFontFaceCss;
|
|
18268
|
+
}
|
|
18269
|
+
function restoreSourceFontsForShadowRaster(markup) {
|
|
18270
|
+
try {
|
|
18271
|
+
const parser = new DOMParser();
|
|
18272
|
+
const doc = parser.parseFromString(`<svg xmlns="http://www.w3.org/2000/svg">${markup}</svg>`, "image/svg+xml");
|
|
18273
|
+
if (doc.querySelector("parsererror")) return markup;
|
|
18274
|
+
for (const node of Array.from(doc.querySelectorAll("text, tspan, textPath"))) {
|
|
18275
|
+
const family = node.getAttribute("data-source-font-family");
|
|
18276
|
+
const weight = node.getAttribute("data-source-font-weight");
|
|
18277
|
+
const style = node.getAttribute("data-source-font-style");
|
|
18278
|
+
if (!family && !weight && !style) continue;
|
|
18279
|
+
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));
|
|
18280
|
+
if (family) {
|
|
18281
|
+
node.setAttribute("font-family", family);
|
|
18282
|
+
stylePairs.push(`font-family: ${family}`);
|
|
18283
|
+
}
|
|
18284
|
+
if (weight) {
|
|
18285
|
+
node.setAttribute("font-weight", weight);
|
|
18286
|
+
stylePairs.push(`font-weight: ${weight}`);
|
|
18287
|
+
}
|
|
18288
|
+
if (style) {
|
|
18289
|
+
node.setAttribute("font-style", style);
|
|
18290
|
+
stylePairs.push(`font-style: ${style}`);
|
|
18291
|
+
}
|
|
18292
|
+
if (stylePairs.length > 0) node.setAttribute("style", stylePairs.join("; "));
|
|
18293
|
+
}
|
|
18294
|
+
const root = doc.documentElement;
|
|
18295
|
+
return Array.from(root.childNodes).map((n) => n instanceof Element ? new XMLSerializer().serializeToString(n) : "").join("");
|
|
18296
|
+
} catch {
|
|
18297
|
+
return markup;
|
|
18298
|
+
}
|
|
18299
|
+
}
|
|
18180
18300
|
async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey, options) {
|
|
18181
18301
|
try {
|
|
18182
18302
|
const parser = new DOMParser();
|
|
@@ -18207,7 +18327,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
|
|
|
18207
18327
|
if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
|
|
18208
18328
|
sanitizeSvgTreeForPdf(svgToDraw);
|
|
18209
18329
|
try {
|
|
18210
|
-
const { bakeTextAnchorPositionsFromLiveSvg } = await import("./vectorPdfExport-
|
|
18330
|
+
const { bakeTextAnchorPositionsFromLiveSvg } = await import("./vectorPdfExport-CyHRXea-.js");
|
|
18211
18331
|
await bakeTextAnchorPositionsFromLiveSvg(svgToDraw);
|
|
18212
18332
|
} catch (e) {
|
|
18213
18333
|
console.warn("[canvas-renderer][pdf-export] anchor-bake pass failed (continuing):", e);
|
|
@@ -18552,4 +18672,4 @@ export {
|
|
|
18552
18672
|
collectFontDescriptorsFromConfig as y,
|
|
18553
18673
|
collectFontsFromConfig as z
|
|
18554
18674
|
};
|
|
18555
|
-
//# sourceMappingURL=index-
|
|
18675
|
+
//# sourceMappingURL=index-WM3oV4wa.js.map
|