@pixldocs/canvas-renderer 0.5.80 → 0.5.82
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 +26 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +14 -1
- package/dist/index.js +26 -9
- package/dist/index.js.map +1 -1
- package/dist/{svgTextToPath-BP0Kppla.js → svgTextToPath-B5sT7sre.js} +24 -2
- package/dist/{svgTextToPath-BP0Kppla.js.map → svgTextToPath-B5sT7sre.js.map} +1 -1
- package/dist/{svgTextToPath-BTHnqJpM.cjs → svgTextToPath-DHAXuVMF.cjs} +24 -2
- package/dist/{svgTextToPath-BTHnqJpM.cjs.map → svgTextToPath-DHAXuVMF.cjs.map} +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -256,7 +256,7 @@ export declare function normalizeFontFamily(fontStack: string): string;
|
|
|
256
256
|
* Package version banner. Bump alongside package.json so we can confirm
|
|
257
257
|
* (via browser:log) that the deployed bundle matches the expected build.
|
|
258
258
|
*/
|
|
259
|
-
export declare const PACKAGE_VERSION = "0.5.
|
|
259
|
+
export declare const PACKAGE_VERSION = "0.5.81";
|
|
260
260
|
|
|
261
261
|
export declare interface PageSettings {
|
|
262
262
|
backgroundColor?: string;
|
|
@@ -276,6 +276,14 @@ export declare interface PdfAssemblyOptions {
|
|
|
276
276
|
fontBaseUrl?: string;
|
|
277
277
|
/** Convert SVG text to paths before svg2pdf. Default: false — keep live Fabric SVG text for preview/PDF metric parity. */
|
|
278
278
|
outlineText?: boolean;
|
|
279
|
+
/**
|
|
280
|
+
* Per-template text rendering mode.
|
|
281
|
+
* - 'auto' : outline only complex scripts (Indic/Arabic/CJK/emoji); Latin stays selectable.
|
|
282
|
+
* - 'selectable' : never outline; all text remains real selectable text in the PDF.
|
|
283
|
+
* - 'pixel-perfect' : outline every <text> for 100% font parity.
|
|
284
|
+
* When omitted, falls back to `outlineText` (legacy boolean) for backwards compatibility.
|
|
285
|
+
*/
|
|
286
|
+
textMode?: 'auto' | 'selectable' | 'pixel-perfect';
|
|
279
287
|
}
|
|
280
288
|
|
|
281
289
|
/** Options for PDF rendering */
|
|
@@ -294,6 +302,8 @@ export declare interface PdfFromFormOptions {
|
|
|
294
302
|
title?: string;
|
|
295
303
|
/** Base URL for TTF font files for PDF font embedding */
|
|
296
304
|
fontBaseUrl?: string;
|
|
305
|
+
/** PDF text rendering mode. Default: selectable real text. */
|
|
306
|
+
textMode?: 'auto' | 'selectable' | 'pixel-perfect';
|
|
297
307
|
}
|
|
298
308
|
|
|
299
309
|
export declare interface PdfRenderResult {
|
|
@@ -403,6 +413,7 @@ export declare class PixldocsRenderer {
|
|
|
403
413
|
renderPdf(templateConfig: TemplateConfig, options?: {
|
|
404
414
|
title?: string;
|
|
405
415
|
fontBaseUrl?: string;
|
|
416
|
+
textMode?: 'auto' | 'selectable' | 'pixel-perfect';
|
|
406
417
|
}): Promise<PdfRenderResult>;
|
|
407
418
|
/**
|
|
408
419
|
* Resolve from V2 sectionState and render a vector PDF.
|
|
@@ -669,6 +680,8 @@ export declare interface TemplateConfig {
|
|
|
669
680
|
dynamicFields?: DynamicField[];
|
|
670
681
|
fieldGroups?: any[];
|
|
671
682
|
themeConfig?: ThemeConfig;
|
|
683
|
+
/** PDF text rendering mode. Default: selectable real text. */
|
|
684
|
+
pdfTextMode?: 'auto' | 'selectable' | 'pixel-perfect';
|
|
672
685
|
formBindingMode?: string;
|
|
673
686
|
boundFormDefId?: string;
|
|
674
687
|
boundFormDefName?: string;
|
package/dist/index.js
CHANGED
|
@@ -12590,7 +12590,7 @@ function PixldocsPreview(props) {
|
|
|
12590
12590
|
!canvasSettled && /* @__PURE__ */ jsx("div", { style: { position: "absolute", inset: 0, display: "flex", alignItems: "center", justifyContent: "center", minHeight: 200 }, children: /* @__PURE__ */ jsx("div", { style: { color: "#888", fontSize: 14 }, children: "Loading preview..." }) })
|
|
12591
12591
|
] });
|
|
12592
12592
|
}
|
|
12593
|
-
const PACKAGE_VERSION = "0.5.
|
|
12593
|
+
const PACKAGE_VERSION = "0.5.81";
|
|
12594
12594
|
const roundParityValue = (value) => {
|
|
12595
12595
|
if (typeof value !== "number") return value;
|
|
12596
12596
|
return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
|
|
@@ -12865,7 +12865,7 @@ class PixldocsRenderer {
|
|
|
12865
12865
|
async renderPdf(templateConfig, options) {
|
|
12866
12866
|
const svgs = await this.renderAllPageSvgs(templateConfig);
|
|
12867
12867
|
const { assemblePdfFromSvgs: assemblePdfFromSvgs2 } = await Promise.resolve().then(() => pdfExport);
|
|
12868
|
-
return assemblePdfFromSvgs2(svgs, { title: options == null ? void 0 : options.title, fontBaseUrl: options == null ? void 0 : options.fontBaseUrl });
|
|
12868
|
+
return assemblePdfFromSvgs2(svgs, { title: options == null ? void 0 : options.title, fontBaseUrl: options == null ? void 0 : options.fontBaseUrl, textMode: (options == null ? void 0 : options.textMode) ?? templateConfig.pdfTextMode ?? "selectable" });
|
|
12869
12869
|
}
|
|
12870
12870
|
/**
|
|
12871
12871
|
* Resolve from V2 sectionState and render a vector PDF.
|
|
@@ -12890,7 +12890,7 @@ class PixldocsRenderer {
|
|
|
12890
12890
|
}
|
|
12891
12891
|
const svgs = await this.renderAllPageSvgs(configToRender);
|
|
12892
12892
|
const { assemblePdfFromSvgs: assemblePdfFromSvgs2 } = await Promise.resolve().then(() => pdfExport);
|
|
12893
|
-
return assemblePdfFromSvgs2(svgs, { title: title ?? resolved.config.name, fontBaseUrl });
|
|
12893
|
+
return assemblePdfFromSvgs2(svgs, { title: title ?? resolved.config.name, fontBaseUrl, textMode: options.textMode ?? configToRender.pdfTextMode ?? "selectable" });
|
|
12894
12894
|
}
|
|
12895
12895
|
async renderById(templateId, formData, options) {
|
|
12896
12896
|
const resolved = await resolveTemplateData({
|
|
@@ -14140,10 +14140,22 @@ async function embedFont(pdf, fontName, weight, fontBaseUrl, isItalic = false) {
|
|
|
14140
14140
|
async function embedFontsForConfig(pdf, config, fontBaseUrl) {
|
|
14141
14141
|
const fontKeys = /* @__PURE__ */ new Set();
|
|
14142
14142
|
const SEP = "";
|
|
14143
|
+
const normalizeWeight = (raw) => {
|
|
14144
|
+
if (raw == null) return 400;
|
|
14145
|
+
if (typeof raw === "number" && Number.isFinite(raw)) return resolveFontWeight(raw);
|
|
14146
|
+
const str = String(raw).trim().toLowerCase();
|
|
14147
|
+
const parsed = Number.parseInt(str, 10);
|
|
14148
|
+
if (Number.isFinite(parsed)) return resolveFontWeight(parsed);
|
|
14149
|
+
if (str === "bold" || str === "bolder") return 700;
|
|
14150
|
+
if (str === "semibold" || str === "demibold") return 600;
|
|
14151
|
+
if (str === "medium") return 500;
|
|
14152
|
+
if (str === "light" || str === "lighter" || str === "thin") return 300;
|
|
14153
|
+
return 400;
|
|
14154
|
+
};
|
|
14143
14155
|
const walkElements = (elements) => {
|
|
14144
14156
|
for (const el of elements) {
|
|
14145
14157
|
if (el.fontFamily) {
|
|
14146
|
-
const w =
|
|
14158
|
+
const w = normalizeWeight(el.fontWeight);
|
|
14147
14159
|
fontKeys.add(`${el.fontFamily}${SEP}${w}`);
|
|
14148
14160
|
}
|
|
14149
14161
|
if (el.styles && typeof el.styles === "object") {
|
|
@@ -14153,7 +14165,7 @@ async function embedFontsForConfig(pdf, config, fontBaseUrl) {
|
|
|
14153
14165
|
for (const charKey of Object.keys(lineStyles)) {
|
|
14154
14166
|
const s = lineStyles[charKey];
|
|
14155
14167
|
if (s == null ? void 0 : s.fontFamily) {
|
|
14156
|
-
const w =
|
|
14168
|
+
const w = normalizeWeight(s.fontWeight);
|
|
14157
14169
|
fontKeys.add(`${s.fontFamily}${SEP}${w}`);
|
|
14158
14170
|
}
|
|
14159
14171
|
}
|
|
@@ -15435,7 +15447,9 @@ async function convertTextDecorationsToLines(svg) {
|
|
|
15435
15447
|
const fontFamily = tspan.getAttribute("data-source-font-family") || textEl.getAttribute("data-source-font-family") || resolveInheritedSvgValue(tspan, "font-family") || "sans-serif";
|
|
15436
15448
|
const fontWeight = tspan.getAttribute("data-source-font-weight") || textEl.getAttribute("data-source-font-weight") || resolveInheritedSvgValue(tspan, "font-weight") || "normal";
|
|
15437
15449
|
const fontStyle = tspan.getAttribute("data-source-font-style") || textEl.getAttribute("data-source-font-style") || resolveInheritedSvgValue(tspan, "font-style") || "normal";
|
|
15438
|
-
const
|
|
15450
|
+
const resolvedFill = tspan.getAttribute("fill") || getInlineStyleValue(tspan, "fill") || resolveInheritedSvgValue(tspan, "fill") || textEl.getAttribute("fill") || getInlineStyleValue(textEl, "fill") || "#000000";
|
|
15451
|
+
const fill = resolvedFill;
|
|
15452
|
+
const fillOpacity = tspan.getAttribute("fill-opacity") || getInlineStyleValue(tspan, "fill-opacity") || resolveInheritedSvgValue(tspan, "fill-opacity") || textEl.getAttribute("fill-opacity") || getInlineStyleValue(textEl, "fill-opacity") || null;
|
|
15439
15453
|
let textWidth = content.length * fontSize * 0.6;
|
|
15440
15454
|
if (ctx) {
|
|
15441
15455
|
ctx.font = `${fontStyle} ${fontWeight} ${fontSize}px ${fontFamily.replace(/'/g, "")}`;
|
|
@@ -15486,6 +15500,7 @@ async function convertTextDecorationsToLines(svg) {
|
|
|
15486
15500
|
line.setAttribute("stroke-width", String(thickness));
|
|
15487
15501
|
line.setAttribute("stroke-linecap", "butt");
|
|
15488
15502
|
line.setAttribute("fill", "none");
|
|
15503
|
+
if (fillOpacity) line.setAttribute("stroke-opacity", fillOpacity);
|
|
15489
15504
|
if (textEl.parentElement) {
|
|
15490
15505
|
textEl.parentElement.insertBefore(line, textEl.nextSibling);
|
|
15491
15506
|
}
|
|
@@ -15785,7 +15800,9 @@ async function assemblePdfFromSvgs(svgResults, options = {}) {
|
|
|
15785
15800
|
const hasGradient = !!((_b = (_a = page.backgroundGradient) == null ? void 0 : _a.stops) == null ? void 0 : _b.length);
|
|
15786
15801
|
drawPageBackground(pdf, i, page.width, page.height, page.backgroundColor, page.backgroundGradient);
|
|
15787
15802
|
const shouldStripBg = stripPageBackground ?? hasGradient;
|
|
15788
|
-
const
|
|
15803
|
+
const textMode = options.textMode ?? (options.outlineText ? "pixel-perfect" : "selectable");
|
|
15804
|
+
const shouldOutlineText = textMode === "pixel-perfect" || textMode === "auto";
|
|
15805
|
+
const outlineSubMode = textMode === "auto" ? "complex-only" : "all";
|
|
15789
15806
|
let pageSvg = page.svg;
|
|
15790
15807
|
try {
|
|
15791
15808
|
pageSvg = await convertSvgTextDecorationsToLinesString(pageSvg);
|
|
@@ -15797,8 +15814,8 @@ async function assemblePdfFromSvgs(svgResults, options = {}) {
|
|
|
15797
15814
|
}
|
|
15798
15815
|
if (shouldOutlineText) {
|
|
15799
15816
|
try {
|
|
15800
|
-
const { convertAllTextToPath } = await import("./svgTextToPath-
|
|
15801
|
-
pageSvg = await convertAllTextToPath(pageSvg, fontBaseUrl);
|
|
15817
|
+
const { convertAllTextToPath } = await import("./svgTextToPath-B5sT7sre.js");
|
|
15818
|
+
pageSvg = await convertAllTextToPath(pageSvg, fontBaseUrl, { mode: outlineSubMode });
|
|
15802
15819
|
try {
|
|
15803
15820
|
dumpSvgTextDiagnostics(pageSvg, i, PARITY_TAG, "STAGE-1b-after-text-to-path-raw");
|
|
15804
15821
|
} catch {
|