@pixldocs/canvas-renderer 0.5.64 → 0.5.66
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 +81 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +81 -17
- 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 +3 -1
package/dist/index.cjs
CHANGED
|
@@ -12561,7 +12561,7 @@ function PixldocsPreview(props) {
|
|
|
12561
12561
|
!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..." }) })
|
|
12562
12562
|
] });
|
|
12563
12563
|
}
|
|
12564
|
-
const PACKAGE_VERSION = "0.5.
|
|
12564
|
+
const PACKAGE_VERSION = "0.5.66";
|
|
12565
12565
|
let __underlineFixInstalled = false;
|
|
12566
12566
|
function installUnderlineFix(fab) {
|
|
12567
12567
|
var _a;
|
|
@@ -13277,6 +13277,7 @@ class PixldocsRenderer {
|
|
|
13277
13277
|
captureSvgViaPreviewCanvas(config, pageIndex, canvasWidth, canvasHeight) {
|
|
13278
13278
|
return new Promise(async (resolve, reject) => {
|
|
13279
13279
|
const { PreviewCanvas: PreviewCanvas2 } = await Promise.resolve().then(() => PreviewCanvas$1);
|
|
13280
|
+
const hasAutoShrink = configHasAutoShrinkText(config);
|
|
13280
13281
|
const container = document.createElement("div");
|
|
13281
13282
|
container.style.cssText = `
|
|
13282
13283
|
position: fixed; left: -99999px; top: -99999px;
|
|
@@ -13289,6 +13290,8 @@ class PixldocsRenderer {
|
|
|
13289
13290
|
reject(new Error("SVG render timeout (30s)"));
|
|
13290
13291
|
}, 3e4);
|
|
13291
13292
|
let root = null;
|
|
13293
|
+
let mountKey = 0;
|
|
13294
|
+
let didPreviewParityRemount = false;
|
|
13292
13295
|
const cleanup = () => {
|
|
13293
13296
|
clearTimeout(timeout);
|
|
13294
13297
|
try {
|
|
@@ -13297,6 +13300,48 @@ class PixldocsRenderer {
|
|
|
13297
13300
|
}
|
|
13298
13301
|
container.remove();
|
|
13299
13302
|
};
|
|
13303
|
+
const mountPreview = (readyHandler) => {
|
|
13304
|
+
root = client.createRoot(container);
|
|
13305
|
+
root.render(
|
|
13306
|
+
react.createElement(PreviewCanvas2, {
|
|
13307
|
+
key: `svg-capture-${mountKey}`,
|
|
13308
|
+
config,
|
|
13309
|
+
pageIndex,
|
|
13310
|
+
zoom: 1,
|
|
13311
|
+
absoluteZoom: true,
|
|
13312
|
+
skipFontReadyWait: false,
|
|
13313
|
+
onReady: readyHandler
|
|
13314
|
+
})
|
|
13315
|
+
);
|
|
13316
|
+
};
|
|
13317
|
+
const remountForPreviewParity = async () => {
|
|
13318
|
+
if (didPreviewParityRemount) return;
|
|
13319
|
+
didPreviewParityRemount = true;
|
|
13320
|
+
mountKey += 1;
|
|
13321
|
+
try {
|
|
13322
|
+
clearMeasurementCache();
|
|
13323
|
+
} catch {
|
|
13324
|
+
}
|
|
13325
|
+
try {
|
|
13326
|
+
clearFabricCharCache();
|
|
13327
|
+
} catch {
|
|
13328
|
+
}
|
|
13329
|
+
try {
|
|
13330
|
+
root == null ? void 0 : root.unmount();
|
|
13331
|
+
} catch {
|
|
13332
|
+
}
|
|
13333
|
+
await new Promise((settle) => {
|
|
13334
|
+
mountPreview(() => {
|
|
13335
|
+
this.waitForCanvasScene(container, config, pageIndex).then(async () => {
|
|
13336
|
+
const expectedImageCount = this.getExpectedImageCount(config, pageIndex);
|
|
13337
|
+
await this.waitForCanvasImages(container, expectedImageCount);
|
|
13338
|
+
await this.waitForStableTextMetrics(container, config);
|
|
13339
|
+
await this.waitForCanvasScene(container, config, pageIndex);
|
|
13340
|
+
settle();
|
|
13341
|
+
}).catch(() => settle());
|
|
13342
|
+
});
|
|
13343
|
+
});
|
|
13344
|
+
};
|
|
13300
13345
|
const onReady = () => {
|
|
13301
13346
|
this.waitForCanvasScene(container, config, pageIndex).then(async () => {
|
|
13302
13347
|
var _a, _b;
|
|
@@ -13305,6 +13350,10 @@ class PixldocsRenderer {
|
|
|
13305
13350
|
await this.waitForCanvasImages(container, expectedImageCount);
|
|
13306
13351
|
await this.waitForStableTextMetrics(container, config);
|
|
13307
13352
|
await this.waitForCanvasScene(container, config, pageIndex);
|
|
13353
|
+
if (hasAutoShrink && !didPreviewParityRemount) {
|
|
13354
|
+
console.log("[canvas-renderer][svg-parity] remounting once to match PixldocsPreview auto-shrink stabilization");
|
|
13355
|
+
await remountForPreviewParity();
|
|
13356
|
+
}
|
|
13308
13357
|
const fabricInstance = this.getFabricCanvasFromContainer(container);
|
|
13309
13358
|
if (!fabricInstance) {
|
|
13310
13359
|
cleanup();
|
|
@@ -13353,18 +13402,7 @@ class PixldocsRenderer {
|
|
|
13353
13402
|
}
|
|
13354
13403
|
});
|
|
13355
13404
|
};
|
|
13356
|
-
|
|
13357
|
-
root.render(
|
|
13358
|
-
react.createElement(PreviewCanvas2, {
|
|
13359
|
-
config,
|
|
13360
|
-
pageIndex,
|
|
13361
|
-
zoom: 1,
|
|
13362
|
-
// 1:1 — no UI scaling for SVG capture
|
|
13363
|
-
absoluteZoom: true,
|
|
13364
|
-
skipFontReadyWait: false,
|
|
13365
|
-
onReady
|
|
13366
|
-
})
|
|
13367
|
-
);
|
|
13405
|
+
mountPreview(onReady);
|
|
13368
13406
|
});
|
|
13369
13407
|
}
|
|
13370
13408
|
/**
|
|
@@ -15179,6 +15217,14 @@ async function svg2pdfWithDomMount(svg, pdf, opts) {
|
|
|
15179
15217
|
async function convertTextDecorationsToLines(svg) {
|
|
15180
15218
|
const doc = svg.ownerDocument;
|
|
15181
15219
|
if (!doc) return;
|
|
15220
|
+
const stripTextDecoration = (el) => {
|
|
15221
|
+
el.removeAttribute("text-decoration");
|
|
15222
|
+
const style = el.getAttribute("style") || "";
|
|
15223
|
+
if (!style) return;
|
|
15224
|
+
const kept = style.split(";").map((part) => part.trim()).filter(Boolean).filter((part) => !/^text-decoration\s*:/i.test(part));
|
|
15225
|
+
if (kept.length > 0) el.setAttribute("style", kept.join("; "));
|
|
15226
|
+
else el.removeAttribute("style");
|
|
15227
|
+
};
|
|
15182
15228
|
const resolveInheritedSvgValue = (el, attr, styleProp = attr) => {
|
|
15183
15229
|
var _a, _b;
|
|
15184
15230
|
let current = el;
|
|
@@ -15329,6 +15375,8 @@ async function convertTextDecorationsToLines(svg) {
|
|
|
15329
15375
|
if (textEl.parentElement) {
|
|
15330
15376
|
textEl.parentElement.insertBefore(line, textEl.nextSibling);
|
|
15331
15377
|
}
|
|
15378
|
+
stripTextDecoration(tspan);
|
|
15379
|
+
if (textHasUnderline) stripTextDecoration(textEl);
|
|
15332
15380
|
}
|
|
15333
15381
|
}
|
|
15334
15382
|
if (tempContainer) {
|
|
@@ -15567,7 +15615,7 @@ function drawPageBackground(pdf, pageIndex, pageWidth, pageHeight, backgroundCol
|
|
|
15567
15615
|
}
|
|
15568
15616
|
}
|
|
15569
15617
|
async function assemblePdfFromSvgs(svgResults, options = {}) {
|
|
15570
|
-
var _a, _b;
|
|
15618
|
+
var _a, _b, _c;
|
|
15571
15619
|
if (svgResults.length === 0) throw new Error("No pages to export");
|
|
15572
15620
|
const { title, stripPageBackground } = options;
|
|
15573
15621
|
const firstPage = svgResults[0];
|
|
@@ -15595,17 +15643,33 @@ async function assemblePdfFromSvgs(svgResults, options = {}) {
|
|
|
15595
15643
|
const hasGradient = !!((_b = (_a = page.backgroundGradient) == null ? void 0 : _a.stops) == null ? void 0 : _b.length);
|
|
15596
15644
|
drawPageBackground(pdf, i, page.width, page.height, page.backgroundColor, page.backgroundGradient);
|
|
15597
15645
|
const shouldStripBg = stripPageBackground ?? hasGradient;
|
|
15646
|
+
const shouldOutlineText = options.outlineText ?? true;
|
|
15598
15647
|
const pageSvg = page.svg;
|
|
15599
15648
|
let processedSvg = await prepareLiveCanvasSvgForPdf(pageSvg, page.width, page.height, `page-${i + 1}`, {
|
|
15600
15649
|
stripPageBackground: shouldStripBg
|
|
15601
15650
|
});
|
|
15602
15651
|
if (processedSvg) {
|
|
15603
|
-
|
|
15604
|
-
|
|
15652
|
+
await convertTextDecorationsToLines(processedSvg);
|
|
15653
|
+
if (shouldOutlineText) {
|
|
15654
|
+
try {
|
|
15655
|
+
const { convertAllTextToPath } = await Promise.resolve().then(() => require("./svgTextToPath-BTHnqJpM.cjs"));
|
|
15656
|
+
const outlinedSvg = await convertAllTextToPath(
|
|
15657
|
+
new XMLSerializer().serializeToString(processedSvg),
|
|
15658
|
+
fontBaseUrl
|
|
15659
|
+
);
|
|
15660
|
+
const outlineDoc = new DOMParser().parseFromString(outlinedSvg, "image/svg+xml");
|
|
15661
|
+
const outlinedRoot = outlineDoc.documentElement;
|
|
15662
|
+
if (outlinedRoot && ((_c = outlinedRoot.tagName) == null ? void 0 : _c.toLowerCase()) === "svg" && !outlineDoc.querySelector("parsererror")) {
|
|
15663
|
+
processedSvg = outlinedRoot;
|
|
15664
|
+
}
|
|
15665
|
+
} catch (outlineErr) {
|
|
15666
|
+
console.warn("[canvas-renderer][pdf] text outlining unavailable, falling back to embedded SVG text:", outlineErr);
|
|
15667
|
+
}
|
|
15668
|
+
}
|
|
15669
|
+
const rewrittenSvg = rewriteSvgFontsForJsPDF(new XMLSerializer().serializeToString(processedSvg));
|
|
15605
15670
|
const reParser = new DOMParser();
|
|
15606
15671
|
const reDoc = reParser.parseFromString(rewrittenSvg, "image/svg+xml");
|
|
15607
15672
|
processedSvg = reDoc.documentElement;
|
|
15608
|
-
await convertTextDecorationsToLines(processedSvg);
|
|
15609
15673
|
}
|
|
15610
15674
|
if (processedSvg) {
|
|
15611
15675
|
pdf.setFillColor(0, 0, 0);
|