@pixldocs/canvas-renderer 0.5.132 → 0.5.134
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-4IzWx9f-.cjs → index-DmqoeVsF.cjs} +143 -15
- package/dist/index-DmqoeVsF.cjs.map +1 -0
- package/dist/{index-TWLUgM18.js → index-Sc4qRn5o.js} +143 -15
- package/dist/index-Sc4qRn5o.js.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/{pdfFonts-Cr8l-y3z.cjs → pdfFonts-BU2Lqz_O.cjs} +36 -11
- package/dist/{pdfFonts-Cr8l-y3z.cjs.map → pdfFonts-BU2Lqz_O.cjs.map} +1 -1
- package/dist/{pdfFonts-Y49FLHuG.js → pdfFonts-BVHbPFEz.js} +36 -11
- package/dist/{pdfFonts-Y49FLHuG.js.map → pdfFonts-BVHbPFEz.js.map} +1 -1
- package/dist/{svgTextToPath-Bne0QyE7.js → svgTextToPath-DG7rcbDE.js} +2 -2
- package/dist/{svgTextToPath-Bne0QyE7.js.map → svgTextToPath-DG7rcbDE.js.map} +1 -1
- package/dist/{svgTextToPath-D6xJoPO2.cjs → svgTextToPath-GeR0CexD.cjs} +2 -2
- package/dist/{svgTextToPath-D6xJoPO2.cjs.map → svgTextToPath-GeR0CexD.cjs.map} +1 -1
- package/dist/{vectorPdfExport-BmqYmqUF.cjs → vectorPdfExport-8Q3O7Z_Q.cjs} +8 -31
- package/dist/vectorPdfExport-8Q3O7Z_Q.cjs.map +1 -0
- package/dist/{vectorPdfExport-3QFNDStb.js → vectorPdfExport-BA6bhLs-.js} +8 -31
- package/dist/vectorPdfExport-BA6bhLs-.js.map +1 -0
- package/package.json +1 -1
- package/dist/index-4IzWx9f-.cjs.map +0 -1
- package/dist/index-TWLUgM18.js.map +0 -1
- package/dist/vectorPdfExport-3QFNDStb.js.map +0 -1
- package/dist/vectorPdfExport-BmqYmqUF.cjs.map +0 -1
|
@@ -5730,7 +5730,8 @@ function applyTextBackground(obj, cfg) {
|
|
|
5730
5730
|
const dataAttrs = `data-blur="${blur.toFixed(3)}" data-ox="${ox.toFixed(3)}" data-oy="${oy.toFixed(3)}" data-bx="${bx.toFixed(3)}" data-by="${by.toFixed(3)}" data-bw="${bw.toFixed(3)}" data-bh="${bh.toFixed(3)}" data-color="${escapeXmlAttr(shadowColor)}"`;
|
|
5731
5731
|
const wrapShadow = (markup) => blur <= 0 ? `<g transform="translate(${ox.toFixed(3)} ${oy.toFixed(3)})">${markup}</g>` : `<g class="__pdShadowRaster" ${dataAttrs}>${markup}</g>`;
|
|
5732
5732
|
if (hasBg && (bg == null ? void 0 : bg.shadowAffectsBg) !== false) {
|
|
5733
|
-
const
|
|
5733
|
+
const shadowOpacityAttr = bgOpacity < 1 ? ` fill-opacity="${bgOpacity}"` : "";
|
|
5734
|
+
const shadowBgPath = `<path d="${bgD}" fill="${escapeXmlAttr(shadowColor)}"${shadowOpacityAttr} />`;
|
|
5734
5735
|
bgShadowMarker = wrapShadow(shadowBgPath);
|
|
5735
5736
|
}
|
|
5736
5737
|
if ((bg == null ? void 0 : bg.shadowAffectsText) !== false) {
|
|
@@ -14031,7 +14032,8 @@ async function fetchGoogleFontTTF(fontFamily, weight, isItalic = false) {
|
|
|
14031
14032
|
async function fetchFontshareTTF(fontFamily, weight, isItalic = false) {
|
|
14032
14033
|
const cacheKey = `fs:${fontFamily}:${weight}:${isItalic ? "i" : "n"}`;
|
|
14033
14034
|
if (ttfCache.has(cacheKey)) return ttfCache.get(cacheKey);
|
|
14034
|
-
|
|
14035
|
+
const notFoundKey = remoteVariantKey(fontFamily, weight, isItalic);
|
|
14036
|
+
if (fontshareNotFound.has(notFoundKey)) return null;
|
|
14035
14037
|
const slug = fontFamily.trim().toLowerCase().replace(/\s+/g, "-");
|
|
14036
14038
|
const proxyBytes = await fetchTtfViaProxy(fontFamily, weight, isItalic, "fontshare");
|
|
14037
14039
|
if (proxyBytes) {
|
|
@@ -14044,13 +14046,13 @@ async function fetchFontshareTTF(fontFamily, weight, isItalic = false) {
|
|
|
14044
14046
|
const cssUrl = `https://api.fontshare.com/v2/css?f[]=${slug}@${weight}${styleSuffix}&display=swap`;
|
|
14045
14047
|
const cssRes = await fetch(cssUrl);
|
|
14046
14048
|
if (!cssRes.ok) {
|
|
14047
|
-
if (cssRes.status === 400 || cssRes.status === 404) fontshareNotFound.add(
|
|
14049
|
+
if (cssRes.status === 400 || cssRes.status === 404) fontshareNotFound.add(notFoundKey);
|
|
14048
14050
|
return null;
|
|
14049
14051
|
}
|
|
14050
14052
|
const css = await cssRes.text();
|
|
14051
14053
|
const ttMatch = css.match(/url\(([^)]+)\)\s+format\(['"]?truetype['"]?\)/i);
|
|
14052
14054
|
if (!ttMatch) {
|
|
14053
|
-
fontshareNotFound.add(
|
|
14055
|
+
fontshareNotFound.add(notFoundKey);
|
|
14054
14056
|
return null;
|
|
14055
14057
|
}
|
|
14056
14058
|
let ttfUrl = ttMatch[1].replace(/['"]/g, "").trim();
|
|
@@ -14097,11 +14099,38 @@ async function embedFontWithGoogleFallback(pdf, fontName, weight = 400, fontBase
|
|
|
14097
14099
|
if (ok) return true;
|
|
14098
14100
|
}
|
|
14099
14101
|
const resolved = resolveFontWeight(weight);
|
|
14100
|
-
const
|
|
14101
|
-
|
|
14102
|
-
|
|
14103
|
-
|
|
14104
|
-
|
|
14102
|
+
const weightLadder = [resolved];
|
|
14103
|
+
for (const w of [400, 500, 700, 600, 300]) {
|
|
14104
|
+
if (!weightLadder.includes(w)) weightLadder.push(w);
|
|
14105
|
+
}
|
|
14106
|
+
const tryFetch = async (w, italic) => {
|
|
14107
|
+
const fs = await fetchFontshareTTF(fontName, w, italic);
|
|
14108
|
+
if (fs) return fs;
|
|
14109
|
+
const g = await fetchGoogleFontTTF(fontName, w, italic);
|
|
14110
|
+
return g;
|
|
14111
|
+
};
|
|
14112
|
+
let b64 = null;
|
|
14113
|
+
let usedItalic = isItalic;
|
|
14114
|
+
let usedWeight = resolved;
|
|
14115
|
+
for (const w of weightLadder) {
|
|
14116
|
+
b64 = await tryFetch(w, isItalic);
|
|
14117
|
+
if (b64) {
|
|
14118
|
+
usedWeight = w;
|
|
14119
|
+
break;
|
|
14120
|
+
}
|
|
14121
|
+
}
|
|
14122
|
+
if (!b64 && isItalic) {
|
|
14123
|
+
for (const w of weightLadder) {
|
|
14124
|
+
b64 = await tryFetch(w, false);
|
|
14125
|
+
if (b64) {
|
|
14126
|
+
usedItalic = false;
|
|
14127
|
+
usedWeight = w;
|
|
14128
|
+
break;
|
|
14129
|
+
}
|
|
14130
|
+
}
|
|
14131
|
+
}
|
|
14132
|
+
if (!b64) return false;
|
|
14133
|
+
return registerJsPdfFont(pdf, fontName, usedWeight, usedItalic, b64);
|
|
14105
14134
|
}
|
|
14106
14135
|
async function embedFontsForConfig(pdf, config, fontBaseUrl) {
|
|
14107
14136
|
const fontKeys = /* @__PURE__ */ new Set();
|
|
@@ -16203,7 +16232,7 @@ class PixldocsRenderer {
|
|
|
16203
16232
|
await this.waitForCanvasScene(container, cloned, i);
|
|
16204
16233
|
}
|
|
16205
16234
|
console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
|
|
16206
|
-
const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-
|
|
16235
|
+
const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-8Q3O7Z_Q.cjs"));
|
|
16207
16236
|
const prepared = preparePagesForExport(
|
|
16208
16237
|
cloned.pages,
|
|
16209
16238
|
canvasWidth,
|
|
@@ -18041,7 +18070,7 @@ async function rasterizeShadowMarkers(svg) {
|
|
|
18041
18070
|
if ((_a = document.fonts) == null ? void 0 : _a.ready) await document.fonts.ready;
|
|
18042
18071
|
} catch {
|
|
18043
18072
|
}
|
|
18044
|
-
const fontFaceCss =
|
|
18073
|
+
const fontFaceCss = await collectInlinedFontFaceCss();
|
|
18045
18074
|
for (const marker of markers) {
|
|
18046
18075
|
try {
|
|
18047
18076
|
const blur = parseFloat(marker.getAttribute("data-blur") || "0");
|
|
@@ -18055,7 +18084,9 @@ async function rasterizeShadowMarkers(svg) {
|
|
|
18055
18084
|
(_b = marker.parentNode) == null ? void 0 : _b.removeChild(marker);
|
|
18056
18085
|
continue;
|
|
18057
18086
|
}
|
|
18058
|
-
const innerXml =
|
|
18087
|
+
const innerXml = restoreSourceFontsForShadowRaster(
|
|
18088
|
+
Array.from(marker.childNodes).map((n) => n instanceof Element ? new XMLSerializer().serializeToString(n) : "").join("")
|
|
18089
|
+
);
|
|
18059
18090
|
try {
|
|
18060
18091
|
const fontSpecs = collectFontSpecsFromMarkup(innerXml);
|
|
18061
18092
|
if (fontSpecs.length > 0 && ((_c = document.fonts) == null ? void 0 : _c.load)) {
|
|
@@ -18166,6 +18197,103 @@ function collectDocumentFontFaceCss() {
|
|
|
18166
18197
|
cachedFontFaceCss = out.join("\n");
|
|
18167
18198
|
return cachedFontFaceCss;
|
|
18168
18199
|
}
|
|
18200
|
+
let cachedInlinedFontFaceCss = null;
|
|
18201
|
+
const fontUrlDataCache = /* @__PURE__ */ new Map();
|
|
18202
|
+
async function fetchFontAsDataUri(url) {
|
|
18203
|
+
if (fontUrlDataCache.has(url)) return fontUrlDataCache.get(url) ?? null;
|
|
18204
|
+
try {
|
|
18205
|
+
const resp = await fetch(url, { mode: "cors", credentials: "omit" });
|
|
18206
|
+
if (!resp.ok) {
|
|
18207
|
+
fontUrlDataCache.set(url, null);
|
|
18208
|
+
return null;
|
|
18209
|
+
}
|
|
18210
|
+
const blob = await resp.blob();
|
|
18211
|
+
const dataUri = await new Promise((resolve, reject) => {
|
|
18212
|
+
const fr = new FileReader();
|
|
18213
|
+
fr.onload = () => resolve(String(fr.result));
|
|
18214
|
+
fr.onerror = () => reject(fr.error);
|
|
18215
|
+
fr.readAsDataURL(blob);
|
|
18216
|
+
});
|
|
18217
|
+
fontUrlDataCache.set(url, dataUri);
|
|
18218
|
+
return dataUri;
|
|
18219
|
+
} catch {
|
|
18220
|
+
fontUrlDataCache.set(url, null);
|
|
18221
|
+
return null;
|
|
18222
|
+
}
|
|
18223
|
+
}
|
|
18224
|
+
async function inlineUrlsInCss(css) {
|
|
18225
|
+
const urlRe = /url\((['"]?)([^'")]+)\1\)/gi;
|
|
18226
|
+
const matches = [];
|
|
18227
|
+
let m;
|
|
18228
|
+
while ((m = urlRe.exec(css)) !== null) {
|
|
18229
|
+
const raw = m[2].trim();
|
|
18230
|
+
if (raw.startsWith("data:")) continue;
|
|
18231
|
+
let abs = raw;
|
|
18232
|
+
try {
|
|
18233
|
+
abs = new URL(raw, document.baseURI).toString();
|
|
18234
|
+
} catch {
|
|
18235
|
+
}
|
|
18236
|
+
matches.push({ full: m[0], url: abs });
|
|
18237
|
+
}
|
|
18238
|
+
if (matches.length === 0) return css;
|
|
18239
|
+
const unique = Array.from(new Set(matches.map((mm) => mm.url)));
|
|
18240
|
+
const results = await Promise.all(unique.map((u) => fetchFontAsDataUri(u)));
|
|
18241
|
+
const map = /* @__PURE__ */ new Map();
|
|
18242
|
+
unique.forEach((u, i) => map.set(u, results[i]));
|
|
18243
|
+
let out = css;
|
|
18244
|
+
for (const { full, url } of matches) {
|
|
18245
|
+
const data = map.get(url);
|
|
18246
|
+
if (!data) continue;
|
|
18247
|
+
const safeFull = full.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
18248
|
+
out = out.replace(new RegExp(safeFull, "g"), `url("${data}")`);
|
|
18249
|
+
}
|
|
18250
|
+
return out;
|
|
18251
|
+
}
|
|
18252
|
+
async function collectInlinedFontFaceCss() {
|
|
18253
|
+
if (cachedInlinedFontFaceCss !== null) return cachedInlinedFontFaceCss;
|
|
18254
|
+
const raw = collectDocumentFontFaceCss();
|
|
18255
|
+
if (!raw) {
|
|
18256
|
+
cachedInlinedFontFaceCss = "";
|
|
18257
|
+
return "";
|
|
18258
|
+
}
|
|
18259
|
+
try {
|
|
18260
|
+
cachedInlinedFontFaceCss = await inlineUrlsInCss(raw);
|
|
18261
|
+
} catch {
|
|
18262
|
+
cachedInlinedFontFaceCss = raw;
|
|
18263
|
+
}
|
|
18264
|
+
return cachedInlinedFontFaceCss;
|
|
18265
|
+
}
|
|
18266
|
+
function restoreSourceFontsForShadowRaster(markup) {
|
|
18267
|
+
try {
|
|
18268
|
+
const parser = new DOMParser();
|
|
18269
|
+
const doc = parser.parseFromString(`<svg xmlns="http://www.w3.org/2000/svg">${markup}</svg>`, "image/svg+xml");
|
|
18270
|
+
if (doc.querySelector("parsererror")) return markup;
|
|
18271
|
+
for (const node of Array.from(doc.querySelectorAll("text, tspan, textPath"))) {
|
|
18272
|
+
const family = node.getAttribute("data-source-font-family");
|
|
18273
|
+
const weight = node.getAttribute("data-source-font-weight");
|
|
18274
|
+
const style = node.getAttribute("data-source-font-style");
|
|
18275
|
+
if (!family && !weight && !style) continue;
|
|
18276
|
+
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));
|
|
18277
|
+
if (family) {
|
|
18278
|
+
node.setAttribute("font-family", family);
|
|
18279
|
+
stylePairs.push(`font-family: ${family}`);
|
|
18280
|
+
}
|
|
18281
|
+
if (weight) {
|
|
18282
|
+
node.setAttribute("font-weight", weight);
|
|
18283
|
+
stylePairs.push(`font-weight: ${weight}`);
|
|
18284
|
+
}
|
|
18285
|
+
if (style) {
|
|
18286
|
+
node.setAttribute("font-style", style);
|
|
18287
|
+
stylePairs.push(`font-style: ${style}`);
|
|
18288
|
+
}
|
|
18289
|
+
if (stylePairs.length > 0) node.setAttribute("style", stylePairs.join("; "));
|
|
18290
|
+
}
|
|
18291
|
+
const root = doc.documentElement;
|
|
18292
|
+
return Array.from(root.childNodes).map((n) => n instanceof Element ? new XMLSerializer().serializeToString(n) : "").join("");
|
|
18293
|
+
} catch {
|
|
18294
|
+
return markup;
|
|
18295
|
+
}
|
|
18296
|
+
}
|
|
18169
18297
|
async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey, options) {
|
|
18170
18298
|
try {
|
|
18171
18299
|
const parser = new DOMParser();
|
|
@@ -18196,7 +18324,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
|
|
|
18196
18324
|
if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
|
|
18197
18325
|
sanitizeSvgTreeForPdf(svgToDraw);
|
|
18198
18326
|
try {
|
|
18199
|
-
const { bakeTextAnchorPositionsFromLiveSvg } = await Promise.resolve().then(() => require("./vectorPdfExport-
|
|
18327
|
+
const { bakeTextAnchorPositionsFromLiveSvg } = await Promise.resolve().then(() => require("./vectorPdfExport-8Q3O7Z_Q.cjs"));
|
|
18200
18328
|
await bakeTextAnchorPositionsFromLiveSvg(svgToDraw);
|
|
18201
18329
|
} catch (e) {
|
|
18202
18330
|
console.warn("[canvas-renderer][pdf-export] anchor-bake pass failed (continuing):", e);
|
|
@@ -18327,7 +18455,7 @@ async function assemblePdfFromSvgs(svgResults, options = {}) {
|
|
|
18327
18455
|
}
|
|
18328
18456
|
if (shouldOutlineText) {
|
|
18329
18457
|
try {
|
|
18330
|
-
const { convertAllTextToPath } = await Promise.resolve().then(() => require("./svgTextToPath-
|
|
18458
|
+
const { convertAllTextToPath } = await Promise.resolve().then(() => require("./svgTextToPath-GeR0CexD.cjs"));
|
|
18331
18459
|
pageSvg = await convertAllTextToPath(pageSvg, fontBaseUrl, { mode: outlineSubMode });
|
|
18332
18460
|
try {
|
|
18333
18461
|
dumpSvgTextDiagnostics(pageSvg, i, PARITY_TAG, "STAGE-1b-after-text-to-path-raw");
|
|
@@ -18538,4 +18666,4 @@ exports.setAutoShrinkDebug = setAutoShrinkDebug;
|
|
|
18538
18666
|
exports.setBundledAssetPrefixes = setBundledAssetPrefixes;
|
|
18539
18667
|
exports.warmResolvedTemplateForPreview = warmResolvedTemplateForPreview;
|
|
18540
18668
|
exports.warmTemplateFromForm = warmTemplateFromForm;
|
|
18541
|
-
//# sourceMappingURL=index-
|
|
18669
|
+
//# sourceMappingURL=index-DmqoeVsF.cjs.map
|