@pixldocs/canvas-renderer 0.5.52 → 0.5.54
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.cjs +107 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +13 -1
- package/dist/index.js +107 -7
- package/dist/index.js.map +1 -1
- package/dist/svgTextToPath-BP0Kppla.js +1083 -0
- package/dist/svgTextToPath-BP0Kppla.js.map +1 -0
- package/dist/svgTextToPath-BTHnqJpM.cjs +1105 -0
- package/dist/svgTextToPath-BTHnqJpM.cjs.map +1 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -2858,6 +2858,49 @@ function isPrivateUrl(url) {
|
|
|
2858
2858
|
return false;
|
|
2859
2859
|
}
|
|
2860
2860
|
}
|
|
2861
|
+
const DEFAULT_BUNDLED_PREFIXES = ["/pixldocs-bundled-assets/"];
|
|
2862
|
+
let bundledPrefixes = [...DEFAULT_BUNDLED_PREFIXES];
|
|
2863
|
+
function setBundledAssetPrefixes(prefixes) {
|
|
2864
|
+
const combined = /* @__PURE__ */ new Set([...DEFAULT_BUNDLED_PREFIXES]);
|
|
2865
|
+
for (const p of prefixes || []) {
|
|
2866
|
+
if (typeof p === "string" && p.startsWith("/")) combined.add(p);
|
|
2867
|
+
}
|
|
2868
|
+
bundledPrefixes = Array.from(combined);
|
|
2869
|
+
}
|
|
2870
|
+
function pathnameStartsWithBundledPrefix(pathname) {
|
|
2871
|
+
return bundledPrefixes.some((prefix) => pathname.startsWith(prefix));
|
|
2872
|
+
}
|
|
2873
|
+
function isBundledAssetUrl(url) {
|
|
2874
|
+
if (!url) return false;
|
|
2875
|
+
if (url.startsWith("/") && !url.startsWith("//")) {
|
|
2876
|
+
return pathnameStartsWithBundledPrefix(url);
|
|
2877
|
+
}
|
|
2878
|
+
try {
|
|
2879
|
+
const parsed = new URL(url);
|
|
2880
|
+
if (typeof window !== "undefined" && parsed.origin !== window.location.origin) {
|
|
2881
|
+
return false;
|
|
2882
|
+
}
|
|
2883
|
+
return pathnameStartsWithBundledPrefix(parsed.pathname);
|
|
2884
|
+
} catch {
|
|
2885
|
+
return false;
|
|
2886
|
+
}
|
|
2887
|
+
}
|
|
2888
|
+
function resolveBundledAssetUrl(url) {
|
|
2889
|
+
if (!url) return null;
|
|
2890
|
+
if (url.startsWith("/") && !url.startsWith("//") && pathnameStartsWithBundledPrefix(url)) {
|
|
2891
|
+
const origin = typeof window !== "undefined" ? window.location.origin : "";
|
|
2892
|
+
return origin ? new URL(url, origin).toString() : url;
|
|
2893
|
+
}
|
|
2894
|
+
try {
|
|
2895
|
+
const parsed = new URL(url);
|
|
2896
|
+
if (typeof window !== "undefined" && parsed.origin !== window.location.origin) return null;
|
|
2897
|
+
if (pathnameStartsWithBundledPrefix(parsed.pathname)) return parsed.toString();
|
|
2898
|
+
} catch {
|
|
2899
|
+
return null;
|
|
2900
|
+
}
|
|
2901
|
+
return null;
|
|
2902
|
+
}
|
|
2903
|
+
const loggedPrivateSkips = /* @__PURE__ */ new Set();
|
|
2861
2904
|
function toPublicStorageUrl(url) {
|
|
2862
2905
|
try {
|
|
2863
2906
|
const parsed = new URL(url);
|
|
@@ -2875,8 +2918,17 @@ function toPublicStorageUrl(url) {
|
|
|
2875
2918
|
function getProxiedImageUrl(imageUrl) {
|
|
2876
2919
|
if (!imageUrl) return "";
|
|
2877
2920
|
if (imageUrl.startsWith("data:") || imageUrl.startsWith("blob:")) return imageUrl;
|
|
2921
|
+
const bundled = resolveBundledAssetUrl(imageUrl);
|
|
2922
|
+
if (bundled) return bundled;
|
|
2923
|
+
if (imageUrl.startsWith("/") && !imageUrl.startsWith("//")) {
|
|
2924
|
+
if (typeof window !== "undefined") return new URL(imageUrl, window.location.origin).toString();
|
|
2925
|
+
return imageUrl;
|
|
2926
|
+
}
|
|
2878
2927
|
if (isPrivateUrl(imageUrl)) {
|
|
2879
|
-
|
|
2928
|
+
if (!loggedPrivateSkips.has(imageUrl)) {
|
|
2929
|
+
loggedPrivateSkips.add(imageUrl);
|
|
2930
|
+
console.debug("[image-proxy] Skipping private URL:", imageUrl.substring(0, 80));
|
|
2931
|
+
}
|
|
2880
2932
|
return "";
|
|
2881
2933
|
}
|
|
2882
2934
|
const publicUrl = toPublicStorageUrl(imageUrl);
|
|
@@ -4818,7 +4870,13 @@ function extractTextBgConfig(element) {
|
|
|
4818
4870
|
rxTL: Math.max(0, Number(element.textBgRxTL ?? 0)) || 0,
|
|
4819
4871
|
rxTR: Math.max(0, Number(element.textBgRxTR ?? 0)) || 0,
|
|
4820
4872
|
rxBR: Math.max(0, Number(element.textBgRxBR ?? 0)) || 0,
|
|
4821
|
-
rxBL: Math.max(0, Number(element.textBgRxBL ?? 0)) || 0
|
|
4873
|
+
rxBL: Math.max(0, Number(element.textBgRxBL ?? 0)) || 0,
|
|
4874
|
+
opacity: (() => {
|
|
4875
|
+
const n = Number(element.textBgOpacity);
|
|
4876
|
+
if (!Number.isFinite(n)) return void 0;
|
|
4877
|
+
return Math.max(0, Math.min(1, n));
|
|
4878
|
+
})(),
|
|
4879
|
+
shadowAffectsBg: element.textShadowAffectsBg !== false
|
|
4822
4880
|
};
|
|
4823
4881
|
}
|
|
4824
4882
|
function hasTextBackground(cfg) {
|
|
@@ -4879,6 +4937,13 @@ function applyTextBackground(obj, cfg) {
|
|
|
4879
4937
|
const bgW = w + pL + pR;
|
|
4880
4938
|
const bgH = h + pT + pB;
|
|
4881
4939
|
ctx.save();
|
|
4940
|
+
const suppressShadowOnBg = bg.shadowAffectsBg === false;
|
|
4941
|
+
if (suppressShadowOnBg) {
|
|
4942
|
+
ctx.shadowColor = "transparent";
|
|
4943
|
+
ctx.shadowBlur = 0;
|
|
4944
|
+
ctx.shadowOffsetX = 0;
|
|
4945
|
+
ctx.shadowOffsetY = 0;
|
|
4946
|
+
}
|
|
4882
4947
|
buildRoundedRectPath2D(
|
|
4883
4948
|
ctx,
|
|
4884
4949
|
x,
|
|
@@ -4890,6 +4955,8 @@ function applyTextBackground(obj, cfg) {
|
|
|
4890
4955
|
bg.rxBR ?? 0,
|
|
4891
4956
|
bg.rxBL ?? 0
|
|
4892
4957
|
);
|
|
4958
|
+
const op = typeof bg.opacity === "number" ? Math.max(0, Math.min(1, bg.opacity)) : 1;
|
|
4959
|
+
if (op < 1) ctx.globalAlpha = (ctx.globalAlpha ?? 1) * op;
|
|
4893
4960
|
ctx.fillStyle = bg.color;
|
|
4894
4961
|
ctx.fill();
|
|
4895
4962
|
ctx.restore();
|
|
@@ -4935,7 +5002,9 @@ function applyTextBackground(obj, cfg) {
|
|
|
4935
5002
|
(bg == null ? void 0 : bg.rxBL) ?? 0
|
|
4936
5003
|
);
|
|
4937
5004
|
const bgFill = (bg == null ? void 0 : bg.color) || "";
|
|
4938
|
-
const
|
|
5005
|
+
const bgOpacity = typeof (bg == null ? void 0 : bg.opacity) === "number" ? Math.max(0, Math.min(1, bg.opacity)) : 1;
|
|
5006
|
+
const bgOpacityAttr = bgOpacity < 1 ? ` fill-opacity="${bgOpacity}"` : "";
|
|
5007
|
+
const bgPath = hasBg ? `<path d="${bgD}" fill="${escapeXmlAttr(bgFill)}"${bgOpacityAttr} />` : "";
|
|
4939
5008
|
svg = svg.replace(/style="[^"]*filter:\s*url\([^)]+\)[^"]*"/i, "");
|
|
4940
5009
|
svg = svg.replace(/<filter[\s\S]*?<\/filter>/gi, "");
|
|
4941
5010
|
let bgShadowMarker = "";
|
|
@@ -4952,7 +5021,7 @@ function applyTextBackground(obj, cfg) {
|
|
|
4952
5021
|
const bh = h + pT + pB + pad * 2;
|
|
4953
5022
|
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)}"`;
|
|
4954
5023
|
const wrapShadow = (markup) => blur <= 0 ? `<g transform="translate(${ox.toFixed(3)} ${oy.toFixed(3)})">${markup}</g>` : `<g class="__pdShadowRaster" ${dataAttrs}>${markup}</g>`;
|
|
4955
|
-
if (hasBg) {
|
|
5024
|
+
if (hasBg && (bg == null ? void 0 : bg.shadowAffectsBg) !== false) {
|
|
4956
5025
|
const shadowBgPath = `<path d="${bgD}" fill="${escapeXmlAttr(shadowColor)}" />`;
|
|
4957
5026
|
bgShadowMarker = wrapShadow(shadowBgPath);
|
|
4958
5027
|
}
|
|
@@ -12171,7 +12240,20 @@ function PixldocsPreview(props) {
|
|
|
12171
12240
|
onDynamicFieldClick,
|
|
12172
12241
|
onReady,
|
|
12173
12242
|
onError,
|
|
12174
|
-
|
|
12243
|
+
// Default `false` so PageCanvas blocks textbox creation until the host
|
|
12244
|
+
// browser actually has the @font-face rules registered. This matters for
|
|
12245
|
+
// `overflowPolicy: 'auto-shrink'` text — `createText` runs the shrink
|
|
12246
|
+
// loop synchronously at mount time using whatever font metrics Fabric
|
|
12247
|
+
// can measure right then. If the real font hasn't loaded yet, Fabric
|
|
12248
|
+
// falls back to the system font (typically narrower), the shrink loop
|
|
12249
|
+
// decides "fits, no shrink needed", and when the real font finally
|
|
12250
|
+
// loads the text overflows the box.
|
|
12251
|
+
//
|
|
12252
|
+
// The renderer's imperative PNG/PDF paths (`renderPageViaPreviewCanvas`,
|
|
12253
|
+
// `captureSvgViaPreviewCanvas`) already pass `skipFontReadyWait: false`
|
|
12254
|
+
// for this exact reason — that's why the downloaded PDF was correct
|
|
12255
|
+
// while the on-screen preview wasn't.
|
|
12256
|
+
skipFontReadyWait = false
|
|
12175
12257
|
} = props;
|
|
12176
12258
|
react.useEffect(() => {
|
|
12177
12259
|
setPackageApiUrl(imageProxyUrl);
|
|
@@ -12340,7 +12422,7 @@ function PixldocsPreview(props) {
|
|
|
12340
12422
|
!canvasSettled && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { position: "absolute", inset: 0, display: "flex", alignItems: "center", justifyContent: "center", minHeight: 200 }, children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: { color: "#888", fontSize: 14 }, children: "Loading preview..." }) })
|
|
12341
12423
|
] });
|
|
12342
12424
|
}
|
|
12343
|
-
const PACKAGE_VERSION = "0.5.
|
|
12425
|
+
const PACKAGE_VERSION = "0.5.54";
|
|
12344
12426
|
let __underlineFixInstalled = false;
|
|
12345
12427
|
function installUnderlineFix(fab) {
|
|
12346
12428
|
var _a;
|
|
@@ -15264,7 +15346,14 @@ async function assemblePdfFromSvgs(svgResults, options = {}) {
|
|
|
15264
15346
|
const hasGradient = !!((_b = (_a = page.backgroundGradient) == null ? void 0 : _a.stops) == null ? void 0 : _b.length);
|
|
15265
15347
|
drawPageBackground(pdf, i, page.width, page.height, page.backgroundColor, page.backgroundGradient);
|
|
15266
15348
|
const shouldStripBg = stripPageBackground ?? hasGradient;
|
|
15267
|
-
let
|
|
15349
|
+
let pageSvg = page.svg;
|
|
15350
|
+
try {
|
|
15351
|
+
const mod = await Promise.resolve().then(() => require("./svgTextToPath-BTHnqJpM.cjs"));
|
|
15352
|
+
pageSvg = await mod.convertAllTextToPath(pageSvg, fontBaseUrl);
|
|
15353
|
+
} catch (outlineErr) {
|
|
15354
|
+
console.warn(`[canvas-renderer pdf] page ${i + 1}: text outliner unavailable, continuing with text-as-text`, outlineErr);
|
|
15355
|
+
}
|
|
15356
|
+
let processedSvg = await prepareLiveCanvasSvgForPdf(pageSvg, page.width, page.height, `page-${i + 1}`, {
|
|
15268
15357
|
stripPageBackground: shouldStripBg
|
|
15269
15358
|
});
|
|
15270
15359
|
if (processedSvg) {
|
|
@@ -15323,9 +15412,16 @@ function collectImageUrls(config) {
|
|
|
15323
15412
|
function normalizeAssetUrl(rawUrl, imageProxyUrl) {
|
|
15324
15413
|
if (!rawUrl) return null;
|
|
15325
15414
|
if (rawUrl.startsWith("data:") || rawUrl.startsWith("blob:")) return null;
|
|
15415
|
+
if (rawUrl.startsWith("/") && !rawUrl.startsWith("//")) {
|
|
15416
|
+
if (typeof window !== "undefined") return new URL(rawUrl, window.location.origin).toString();
|
|
15417
|
+
return null;
|
|
15418
|
+
}
|
|
15326
15419
|
try {
|
|
15327
15420
|
const h = new URL(rawUrl).hostname.toLowerCase();
|
|
15328
15421
|
if (h === "localhost" || h === "127.0.0.1" || h === "0.0.0.0" || h.endsWith(".local") || /^(10\.|192\.168\.|169\.254\.)/.test(h)) {
|
|
15422
|
+
if (typeof window !== "undefined" && new URL(rawUrl).origin === window.location.origin) {
|
|
15423
|
+
return rawUrl;
|
|
15424
|
+
}
|
|
15329
15425
|
return null;
|
|
15330
15426
|
}
|
|
15331
15427
|
} catch {
|
|
@@ -15392,13 +15488,17 @@ exports.embedFontsInPdf = embedFontsInPdf;
|
|
|
15392
15488
|
exports.ensureFontsForResolvedConfig = ensureFontsForResolvedConfig;
|
|
15393
15489
|
exports.extractFontFamiliesFromSvgs = extractFontFamiliesFromSvgs;
|
|
15394
15490
|
exports.getEmbeddedJsPDFFontName = getEmbeddedJsPDFFontName;
|
|
15491
|
+
exports.getProxiedImageUrl = getProxiedImageUrl;
|
|
15492
|
+
exports.isBundledAssetUrl = isBundledAssetUrl;
|
|
15395
15493
|
exports.isFontAvailable = isFontAvailable;
|
|
15494
|
+
exports.isPrivateUrl = isPrivateUrl;
|
|
15396
15495
|
exports.loadGoogleFontCSS = loadGoogleFontCSS;
|
|
15397
15496
|
exports.normalizeFontFamily = normalizeFontFamily;
|
|
15398
15497
|
exports.resolveFontWeight = resolveFontWeight;
|
|
15399
15498
|
exports.resolveFromForm = resolveFromForm;
|
|
15400
15499
|
exports.resolveTemplateData = resolveTemplateData;
|
|
15401
15500
|
exports.rewriteSvgFontsForJsPDF = rewriteSvgFontsForJsPDF;
|
|
15501
|
+
exports.setBundledAssetPrefixes = setBundledAssetPrefixes;
|
|
15402
15502
|
exports.warmResolvedTemplateForPreview = warmResolvedTemplateForPreview;
|
|
15403
15503
|
exports.warmTemplateFromForm = warmTemplateFromForm;
|
|
15404
15504
|
//# sourceMappingURL=index.cjs.map
|