@pixldocs/canvas-renderer 0.5.148 → 0.5.150

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.
@@ -3,7 +3,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const jspdf = require("jspdf");
4
4
  const svg2pdf_js = require("svg2pdf.js");
5
5
  const fabric = require("fabric");
6
- const index = require("./index-Bt1m9Esp.cjs");
6
+ const index = require("./index-CczB1vpO.cjs");
7
7
  const pdfFonts = require("./pdfFonts-BTEVnYX8.cjs");
8
8
  function _interopNamespaceDefault(e) {
9
9
  const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
@@ -1253,24 +1253,26 @@ async function bakeTextAnchorPositionsFromLiveSvg(svg) {
1253
1253
  if (cleaned) node.setAttribute("style", cleaned);
1254
1254
  else node.removeAttribute("style");
1255
1255
  };
1256
- const bakeNode = (srcNode, liveNode, anchorOverride) => {
1256
+ const readInheritedX = (node) => {
1257
+ let cur = node;
1258
+ while (cur) {
1259
+ const v = cur.getAttribute("x");
1260
+ if (v) {
1261
+ const parsed = parseFloat(v.split(/[\s,]+/)[0]);
1262
+ return Number.isFinite(parsed) ? parsed : NaN;
1263
+ }
1264
+ cur = cur.parentElement;
1265
+ }
1266
+ return NaN;
1267
+ };
1268
+ const bakeNode = (srcNode, liveNode, anchorOverride, refXOverride) => {
1257
1269
  const anchor = (anchorOverride || _resolveAnchor(srcNode)).trim().toLowerCase();
1258
1270
  if (anchor !== "middle" && anchor !== "end") return;
1259
1271
  try {
1260
1272
  const content = srcNode.textContent || "";
1261
1273
  if (content.length > 0) {
1262
1274
  const width = _measureWidthCanvas(srcNode, content);
1263
- let refXAttr = null;
1264
- let cur = srcNode;
1265
- while (cur) {
1266
- const v = cur.getAttribute("x");
1267
- if (v) {
1268
- refXAttr = v;
1269
- break;
1270
- }
1271
- cur = cur.parentElement;
1272
- }
1273
- const refX = refXAttr !== null ? parseFloat(refXAttr.split(/[\s,]+/)[0]) : NaN;
1275
+ const refX = Number.isFinite(refXOverride) ? refXOverride : readInheritedX(srcNode);
1274
1276
  if (width !== null && Number.isFinite(refX)) {
1275
1277
  const newX = anchor === "middle" ? refX - width / 2 : refX - width;
1276
1278
  srcNode.setAttribute("x", String(newX));
@@ -1297,9 +1299,15 @@ async function bakeTextAnchorPositionsFromLiveSvg(svg) {
1297
1299
  if (srcTspans.length > 0) {
1298
1300
  const parentAnchor = _resolveAnchor(srcText);
1299
1301
  const tspanAnchors = srcTspans.map((tspan) => _resolveAnchor(tspan));
1300
- bakeNode(srcText, liveText, parentAnchor);
1302
+ const parentRefX = readInheritedX(srcText);
1303
+ const tspanRefXs = srcTspans.map((tspan) => readInheritedX(tspan));
1301
1304
  for (let j = 0; j < srcTspans.length; j++) {
1302
- if (liveTspans[j]) bakeNode(srcTspans[j], liveTspans[j], tspanAnchors[j]);
1305
+ const refX = Number.isFinite(tspanRefXs[j]) ? tspanRefXs[j] : parentRefX;
1306
+ if (liveTspans[j]) bakeNode(srcTspans[j], liveTspans[j], tspanAnchors[j] || parentAnchor, refX);
1307
+ }
1308
+ if (parentAnchor === "middle" || parentAnchor === "end") {
1309
+ srcText.setAttribute("text-anchor", "start");
1310
+ stripTextAnchorStyle(srcText);
1303
1311
  }
1304
1312
  } else {
1305
1313
  bakeNode(srcText, liveText);
@@ -1846,7 +1854,7 @@ async function collectInlinedFontFaceCss() {
1846
1854
  return cachedInlinedFontFaceCss;
1847
1855
  }
1848
1856
  async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey, options) {
1849
- var _a;
1857
+ var _a, _b;
1850
1858
  try {
1851
1859
  const parser = new DOMParser();
1852
1860
  const processedSvg = inlineNestedSvgImageDataUris(rawSvg, parser);
@@ -1865,7 +1873,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
1865
1873
  normalizeSvgViewBoxOrigin(svg);
1866
1874
  disambiguateNestedSvgIds(svg);
1867
1875
  expandSvgUseElements(svg, pageKey);
1868
- const svgToDraw = normalizeSvgExplicitColors(svg);
1876
+ let svgToDraw = normalizeSvgExplicitColors(svg);
1869
1877
  inlineComputedStyles(svgToDraw);
1870
1878
  sanitizeSvgTreeForPdf(svgToDraw);
1871
1879
  normalizeSvgGradientStopOffsets(svgToDraw);
@@ -1884,10 +1892,27 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
1884
1892
  console.warn("[Vector PDF] anchor-bake pass failed (continuing):", e);
1885
1893
  }
1886
1894
  await rasterizeShadowMarkers(svgToDraw);
1895
+ try {
1896
+ if (svgToDraw.querySelector("g[data-pd-shadow-blur] text")) {
1897
+ const { convertAllTextToPath } = await Promise.resolve().then(() => require("./svgTextToPath-DolCNU9g.cjs"));
1898
+ const outlined = await convertAllTextToPath(
1899
+ new XMLSerializer().serializeToString(svgToDraw),
1900
+ void 0,
1901
+ { mode: "shadow-bound" }
1902
+ );
1903
+ const outlinedDoc = parser.parseFromString(outlined, "image/svg+xml");
1904
+ if (!outlinedDoc.querySelector("parsererror") && ((_a = outlinedDoc.documentElement) == null ? void 0 : _a.tagName.toLowerCase()) === "svg") {
1905
+ svgToDraw = outlinedDoc.documentElement;
1906
+ console.log("[Vector PDF][parity] shadow-bound text outlined for headless alignment");
1907
+ }
1908
+ }
1909
+ } catch (outlineErr) {
1910
+ console.warn("[Vector PDF] shadow-bound text outline failed (continuing):", outlineErr);
1911
+ }
1887
1912
  await convertTextDecorationsToLines(svgToDraw);
1888
1913
  const rewritten = rewriteSvgFontsForJsPDFWithSourceMeta(new XMLSerializer().serializeToString(svgToDraw));
1889
1914
  const rewrittenDoc = parser.parseFromString(rewritten, "image/svg+xml");
1890
- if (!rewrittenDoc.querySelector("parsererror") && ((_a = rewrittenDoc.documentElement) == null ? void 0 : _a.tagName.toLowerCase()) === "svg") {
1915
+ if (!rewrittenDoc.querySelector("parsererror") && ((_b = rewrittenDoc.documentElement) == null ? void 0 : _b.tagName.toLowerCase()) === "svg") {
1891
1916
  return rewrittenDoc.documentElement;
1892
1917
  }
1893
1918
  return svgToDraw;
@@ -2469,7 +2494,7 @@ async function fetchSvgAsElement(imageUrl, colorMap) {
2469
2494
  async function getRecoloredSvgDataUrl(imageUrl, colorMap) {
2470
2495
  if (!colorMap || Object.keys(colorMap).length === 0) return null;
2471
2496
  try {
2472
- const { getNormalizedSvgUrl } = await Promise.resolve().then(() => require("./index-Bt1m9Esp.cjs")).then((n) => n.canvasImageLoader);
2497
+ const { getNormalizedSvgUrl } = await Promise.resolve().then(() => require("./index-CczB1vpO.cjs")).then((n) => n.canvasImageLoader);
2473
2498
  return await getNormalizedSvgUrl(imageUrl, colorMap);
2474
2499
  } catch {
2475
2500
  return null;
@@ -3250,7 +3275,7 @@ async function fetchImageAsBase64(imageUrl, opts = {}) {
3250
3275
  }
3251
3276
  let fetchUrl = imageUrl;
3252
3277
  if (imageUrl.startsWith("http://") || imageUrl.startsWith("https://")) {
3253
- const { isPrivateUrl } = await Promise.resolve().then(() => require("./index-Bt1m9Esp.cjs")).then((n) => n.canvasImageLoader);
3278
+ const { isPrivateUrl } = await Promise.resolve().then(() => require("./index-CczB1vpO.cjs")).then((n) => n.canvasImageLoader);
3254
3279
  if (isPrivateUrl(imageUrl)) return null;
3255
3280
  const proxyUrl = new URL(`${index.API_URL}/image-proxy`);
3256
3281
  proxyUrl.searchParams.set("url", imageUrl);
@@ -5232,4 +5257,4 @@ exports.exportMultiPagePdf = exportMultiPagePdf;
5232
5257
  exports.logTextMeasurementDiagnostic = logTextMeasurementDiagnostic;
5233
5258
  exports.preparePagesForExport = preparePagesForExport;
5234
5259
  exports.rewriteSvgFontsForJsPDFWithSourceMeta = rewriteSvgFontsForJsPDFWithSourceMeta;
5235
- //# sourceMappingURL=vectorPdfExport-JGntLQJQ.cjs.map
5260
+ //# sourceMappingURL=vectorPdfExport-qAWd8i87.cjs.map