@pixldocs/canvas-renderer 0.5.155 → 0.5.156

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.
@@ -1,8 +1,8 @@
1
1
  import { jsPDF, ShadingPattern } from "jspdf";
2
2
  import { svg2pdf } from "svg2pdf.js";
3
3
  import * as fabric from "fabric";
4
- import { g as getCanvasForPage, c as captureFabricCanvasSvgForPdf, f as findNodeById, a as getAbsoluteBounds, p as parseTextMarkdown, r as renderSmartElementToSvg, n as normalizeShapeType, h as hasEdgeFade, b as getProxiedImageUrl, d as bakeEdgeFade, i as isElement, e as isGroup, j as buildRoundedTrianglePath, A as API_URL, k as getImageProxyFetchOptions, l as getRoundedRectRadii, T as TRIANGLE_STROKE_MITER_LIMIT, m as getTrianglePoints } from "./index-BQA8_wgq.js";
5
- import { resetPdfFontRegistry, FONT_FALLBACK_SYMBOLS, FONT_FALLBACK_MATH, FONT_FALLBACK_DEVANAGARI, embedFontWithGoogleFallback, getEmbeddedVariantsList, isFontAvailable, isFamilyEmbedded, resolveBestRegisteredVariant, getEmbeddedJsPDFFontName, resolveFontWeight, doesVariantSupportChar } from "./pdfFonts-b3_bv7F0.js";
4
+ import { g as getCanvasForPage, c as captureFabricCanvasSvgForPdf, f as findNodeById, a as getAbsoluteBounds, p as parseTextMarkdown, r as renderSmartElementToSvg, n as normalizeShapeType, h as hasEdgeFade, b as getProxiedImageUrl, d as bakeEdgeFade, i as isElement, e as isGroup, j as buildRoundedTrianglePath, A as API_URL, k as getImageProxyFetchOptions, l as getRoundedRectRadii, T as TRIANGLE_STROKE_MITER_LIMIT, m as getTrianglePoints } from "./index-DJQnrBbh.js";
5
+ import { r as resetPdfFontRegistry, F as FONT_FALLBACK_SYMBOLS, a as FONT_FALLBACK_MATH, b as FONT_FALLBACK_DEVANAGARI, e as embedFontWithGoogleFallback, g as getEmbeddedVariantsList, i as isFontAvailable, c as isFamilyEmbedded, d as resolveBestRegisteredVariant, f as getEmbeddedJsPDFFontName, h as convertAllTextToPath, j as resolveFontWeight, k as doesVariantSupportChar } from "./svgTextToPath-V1vC0SQt.js";
6
6
  async function embedFontsForSvg(pdf, svgStr) {
7
7
  var _a;
8
8
  const {
@@ -12,7 +12,7 @@ async function embedFontsForSvg(pdf, svgStr) {
12
12
  FONT_FALLBACK_SYMBOLS: FONT_FALLBACK_SYMBOLS2,
13
13
  FONT_FALLBACK_DEVANAGARI: FONT_FALLBACK_DEVANAGARI2,
14
14
  FONT_FALLBACK_MATH: FONT_FALLBACK_MATH2
15
- } = await import("./pdfFonts-b3_bv7F0.js");
15
+ } = await import("./svgTextToPath-V1vC0SQt.js").then((n) => n.p);
16
16
  const parser = new DOMParser();
17
17
  const doc = parser.parseFromString(svgStr, "image/svg+xml");
18
18
  const textEls = Array.from(doc.querySelectorAll("text, tspan, textPath"));
@@ -1308,50 +1308,34 @@ async function bakeTextAnchorPositionsFromLiveSvg(svg) {
1308
1308
  }
1309
1309
  }
1310
1310
  }
1311
- function promoteFabricLineAnchorsToSelectableText(svg) {
1311
+ function appendInvisibleSelectableTextLayer(svg) {
1312
+ var _a;
1312
1313
  const doc = svg.ownerDocument;
1313
1314
  if (!doc) return;
1314
- const lineTspans = Array.from(svg.querySelectorAll('tspan[data-pd-line-anchor="1"]'));
1315
- if (lineTspans.length === 0) return;
1315
+ const texts = Array.from(svg.querySelectorAll("text"));
1316
+ if (texts.length === 0) return;
1316
1317
  const SVG_NS = "http://www.w3.org/2000/svg";
1317
- const touchedParents = /* @__PURE__ */ new Set();
1318
- let promoted = 0;
1319
- for (const tspan of lineTspans) {
1320
- const parentText = tspan.parentElement;
1321
- if (!parentText || parentText.tagName.toLowerCase() !== "text" || !parentText.parentNode) continue;
1322
- const rawWidth = Number.parseFloat(tspan.getAttribute("data-pd-line-width") || "");
1323
- const rawX = Number.parseFloat(tspan.getAttribute("x") || parentText.getAttribute("x") || "");
1324
- if (!Number.isFinite(rawWidth) || rawWidth <= 0 || !Number.isFinite(rawX)) continue;
1325
- const anchor = (tspan.getAttribute("text-anchor") || "start").trim().toLowerCase();
1326
- if (anchor !== "middle" && anchor !== "end") continue;
1327
- const startX = anchor === "end" ? rawX - rawWidth : anchor === "middle" ? rawX - rawWidth / 2 : rawX;
1328
- const y = tspan.getAttribute("y") || parentText.getAttribute("y") || "0";
1329
- const wrapper = doc.createElementNS(SVG_NS, "text");
1330
- for (const attr of Array.from(parentText.attributes)) {
1331
- if (["x", "y", "dx", "dy", "text-anchor", "textLength", "lengthAdjust"].includes(attr.name)) continue;
1332
- wrapper.setAttribute(attr.name, attr.value);
1333
- }
1334
- for (const attr of Array.from(tspan.attributes)) {
1335
- if (["x", "y", "dx", "dy", "text-anchor", "data-pd-line-anchor", "data-pd-line-width", "textLength", "lengthAdjust"].includes(attr.name)) continue;
1336
- wrapper.setAttribute(attr.name, attr.value);
1337
- }
1338
- wrapper.setAttribute("x", startX.toFixed(3));
1339
- wrapper.setAttribute("y", y);
1340
- wrapper.setAttribute("text-anchor", "start");
1341
- wrapper.setAttribute("textLength", rawWidth.toFixed(3));
1342
- wrapper.setAttribute("lengthAdjust", "spacing");
1343
- wrapper.textContent = tspan.textContent || "";
1344
- parentText.parentNode.insertBefore(wrapper, parentText);
1345
- tspan.remove();
1346
- touchedParents.add(parentText);
1347
- promoted++;
1348
- }
1349
- for (const parentText of touchedParents) {
1350
- if (!parentText.parentNode) continue;
1351
- const hasText = Array.from(parentText.childNodes).some((node) => (node.textContent || "").trim().length > 0);
1352
- if (!hasText) parentText.parentNode.removeChild(parentText);
1353
- }
1354
- if (promoted > 0) console.log(`[Vector PDF][parity] promoted ${promoted} Fabric line anchor(s) to selectable fixed-width text`);
1318
+ const layer = doc.createElementNS(SVG_NS, "g");
1319
+ layer.setAttribute("data-pd-selectable-layer", "1");
1320
+ layer.setAttribute("fill", "none");
1321
+ layer.setAttribute("stroke", "none");
1322
+ let cloned = 0;
1323
+ for (const text of texts) {
1324
+ if ((_a = text.closest) == null ? void 0 : _a.call(text, '[data-pd-selectable-layer="1"]')) continue;
1325
+ if (!(text.textContent || "").trim()) continue;
1326
+ const clone = text.cloneNode(true);
1327
+ clone.setAttribute("fill", "none");
1328
+ clone.setAttribute("stroke", "none");
1329
+ clone.removeAttribute("opacity");
1330
+ clone.removeAttribute("fill-opacity");
1331
+ clone.removeAttribute("stroke-opacity");
1332
+ layer.appendChild(clone);
1333
+ cloned++;
1334
+ }
1335
+ if (cloned > 0) {
1336
+ svg.appendChild(layer);
1337
+ console.log(`[Vector PDF][selectable-layer] appended ${cloned} invisible text clone(s)`);
1338
+ }
1355
1339
  }
1356
1340
  async function logTextMeasurementDiagnostic(svg) {
1357
1341
  var _a, _b, _c, _d, _e;
@@ -1881,7 +1865,7 @@ async function collectInlinedFontFaceCss() {
1881
1865
  return cachedInlinedFontFaceCss;
1882
1866
  }
1883
1867
  async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey, options) {
1884
- var _a;
1868
+ var _a, _b;
1885
1869
  try {
1886
1870
  const parser = new DOMParser();
1887
1871
  const processedSvg = inlineNestedSvgImageDataUris(rawSvg, parser);
@@ -1918,12 +1902,17 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
1918
1902
  } catch (e) {
1919
1903
  console.warn("[Vector PDF] anchor-bake pass failed (continuing):", e);
1920
1904
  }
1905
+ appendInvisibleSelectableTextLayer(svgToDraw);
1921
1906
  await rasterizeShadowMarkers(svgToDraw);
1922
- promoteFabricLineAnchorsToSelectableText(svgToDraw);
1923
1907
  await convertTextDecorationsToLines(svgToDraw);
1908
+ const outlined = await convertAllTextToPath(new XMLSerializer().serializeToString(svgToDraw), void 0, { mode: "shadow-bound" });
1909
+ const outlinedDoc = parser.parseFromString(outlined, "image/svg+xml");
1910
+ if (!outlinedDoc.querySelector("parsererror") && ((_a = outlinedDoc.documentElement) == null ? void 0 : _a.tagName.toLowerCase()) === "svg") {
1911
+ svgToDraw = outlinedDoc.documentElement;
1912
+ }
1924
1913
  const rewritten = rewriteSvgFontsForJsPDFWithSourceMeta(new XMLSerializer().serializeToString(svgToDraw));
1925
1914
  const rewrittenDoc = parser.parseFromString(rewritten, "image/svg+xml");
1926
- 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") {
1927
1916
  return rewrittenDoc.documentElement;
1928
1917
  }
1929
1918
  return svgToDraw;
@@ -2505,7 +2494,7 @@ async function fetchSvgAsElement(imageUrl, colorMap) {
2505
2494
  async function getRecoloredSvgDataUrl(imageUrl, colorMap) {
2506
2495
  if (!colorMap || Object.keys(colorMap).length === 0) return null;
2507
2496
  try {
2508
- const { getNormalizedSvgUrl } = await import("./index-BQA8_wgq.js").then((n) => n.$);
2497
+ const { getNormalizedSvgUrl } = await import("./index-DJQnrBbh.js").then((n) => n.$);
2509
2498
  return await getNormalizedSvgUrl(imageUrl, colorMap);
2510
2499
  } catch {
2511
2500
  return null;
@@ -3286,7 +3275,7 @@ async function fetchImageAsBase64(imageUrl, opts = {}) {
3286
3275
  }
3287
3276
  let fetchUrl = imageUrl;
3288
3277
  if (imageUrl.startsWith("http://") || imageUrl.startsWith("https://")) {
3289
- const { isPrivateUrl } = await import("./index-BQA8_wgq.js").then((n) => n.$);
3278
+ const { isPrivateUrl } = await import("./index-DJQnrBbh.js").then((n) => n.$);
3290
3279
  if (isPrivateUrl(imageUrl)) return null;
3291
3280
  const proxyUrl = new URL(`${API_URL}/image-proxy`);
3292
3281
  proxyUrl.searchParams.set("url", imageUrl);
@@ -5260,6 +5249,7 @@ async function exportMultiPagePdf(pages, options) {
5260
5249
  pdf.save(filename);
5261
5250
  }
5262
5251
  export {
5252
+ appendInvisibleSelectableTextLayer,
5263
5253
  bakeTextAnchorPositionsFromLiveSvg,
5264
5254
  convertSvgTextDecorationsToLinesString,
5265
5255
  drawPreparedLiveCanvasSvgPageToPdf,
@@ -5268,7 +5258,6 @@ export {
5268
5258
  exportMultiPagePdf,
5269
5259
  logTextMeasurementDiagnostic,
5270
5260
  preparePagesForExport,
5271
- promoteFabricLineAnchorsToSelectableText,
5272
5261
  rewriteSvgFontsForJsPDFWithSourceMeta
5273
5262
  };
5274
- //# sourceMappingURL=vectorPdfExport-vCax992V.js.map
5263
+ //# sourceMappingURL=vectorPdfExport-DSTA9YWG.js.map