@pixldocs/canvas-renderer 0.5.150 → 0.5.152

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.
@@ -5693,6 +5693,7 @@ function applyTextBackground(obj, cfg) {
5693
5693
  const bgPath = hasBg ? `<path d="${bgD}" fill="${escapeXmlAttr(bgFill)}"${bgOpacityAttr} />` : "";
5694
5694
  svg = svg.replace(/style="[^"]*filter:\s*url\([^)]+\)[^"]*"/i, "");
5695
5695
  svg = svg.replace(/<filter[\s\S]*?<\/filter>/gi, "");
5696
+ svg = bakeTextSvgToFabricLineStarts(svg, this, w);
5696
5697
  let bgShadowMarker = "";
5697
5698
  let textShadowMarker = "";
5698
5699
  if (hasShadow) {
@@ -5725,17 +5726,89 @@ function applyTextBackground(obj, cfg) {
5725
5726
  const openTagMatch = svg.match(/^\s*<g\b[^>]*>/);
5726
5727
  const inserted = bgShadowMarker + bgPath + textShadowMarker;
5727
5728
  const shadowBlur = hasShadow ? Math.max(0, Number(shadow.blur ?? 0)) : 0;
5728
- const needsOutlineTag = shadowBlur > 0 ? ' data-pd-shadow-blur="1"' : "";
5729
+ const decorationTags = [
5730
+ shadowBlur > 0 ? 'data-pd-shadow-blur="1"' : "",
5731
+ hasBg ? 'data-pd-text-bg="1"' : ""
5732
+ ].filter(Boolean).join(" ");
5733
+ const decorationAttr = decorationTags ? ` ${decorationTags}` : "";
5729
5734
  if (openTagMatch) {
5730
5735
  const openTag = openTagMatch[0];
5731
- const taggedOpenTag = needsOutlineTag && !/data-pd-shadow-blur=/i.test(openTag) ? openTag.replace(/^<g\b/, `<g${needsOutlineTag}`) : openTag;
5736
+ const taggedOpenTag = decorationAttr ? openTag.replace(/^<g\b/, `<g${decorationAttr}`).replace(/\s(data-pd-shadow-blur="1")(?=[^>]*\s\1)/i, "").replace(/\s(data-pd-text-bg="1")(?=[^>]*\s\1)/i, "") : openTag;
5732
5737
  return svg.replace(openTag, taggedOpenTag + inserted);
5733
5738
  }
5734
- return `<g${needsOutlineTag}>${inserted}${svg}</g>`;
5739
+ return `<g${decorationAttr}>${inserted}${svg}</g>`;
5735
5740
  };
5736
5741
  }
5737
5742
  }
5738
5743
  function recolorSvgFills(svg, color) {
5744
+ return _recolorSvgFills(svg, color);
5745
+ }
5746
+ function bakeTextSvgToFabricLineStarts(svg, obj, w) {
5747
+ var _a, _b, _c;
5748
+ try {
5749
+ const lines = (obj == null ? void 0 : obj._textLines) ?? [];
5750
+ if (!Array.isArray(lines) || lines.length === 0) return svg;
5751
+ const halfW = w / 2;
5752
+ const lineXs = [];
5753
+ for (let i = 0; i < lines.length; i++) {
5754
+ let lineLeft = 0;
5755
+ let firstGlyphAdjust = 0;
5756
+ try {
5757
+ lineLeft = ((_a = obj._getLineLeftOffset) == null ? void 0 : _a.call(obj, i)) ?? 0;
5758
+ } catch {
5759
+ lineLeft = 0;
5760
+ }
5761
+ try {
5762
+ const firstBox = (_c = (_b = obj.__charBounds) == null ? void 0 : _b[i]) == null ? void 0 : _c[0];
5763
+ const kerned = Number(firstBox == null ? void 0 : firstBox.kernedWidth);
5764
+ const glyphW = Number(firstBox == null ? void 0 : firstBox.width);
5765
+ if (Number.isFinite(kerned) && Number.isFinite(glyphW)) {
5766
+ firstGlyphAdjust = kerned - glyphW;
5767
+ }
5768
+ } catch {
5769
+ firstGlyphAdjust = 0;
5770
+ }
5771
+ lineXs.push(
5772
+ -halfW + (Number.isFinite(lineLeft) ? lineLeft : 0) + (Number.isFinite(firstGlyphAdjust) ? firstGlyphAdjust : 0)
5773
+ );
5774
+ }
5775
+ const textOpenRe = /<text\b([^>]*)>/i;
5776
+ const textOpenMatch = svg.match(textOpenRe);
5777
+ if (!textOpenMatch) return svg;
5778
+ let textAttrs = textOpenMatch[1];
5779
+ if (/\stext-anchor\s*=\s*"[^"]*"/i.test(textAttrs)) {
5780
+ textAttrs = textAttrs.replace(/\stext-anchor\s*=\s*"[^"]*"/i, ' text-anchor="start"');
5781
+ } else {
5782
+ textAttrs = ` text-anchor="start"${textAttrs}`;
5783
+ }
5784
+ textAttrs = textAttrs.replace(
5785
+ /(\sstyle=")([^"]*)(")/i,
5786
+ (_m, pre, val, post) => pre + val.replace(/text-align\s*:\s*[^;"']+;?/gi, "").trim() + post
5787
+ );
5788
+ const newTextOpen = `<text${textAttrs}>`;
5789
+ let lineIdx = 0;
5790
+ let lastY = "";
5791
+ const newSvg = svg.replace(textOpenMatch[0], newTextOpen).replace(
5792
+ /<tspan\b([^>]*?)\sx="([^"]*)"([^>]*)>/gi,
5793
+ (_m, pre, _oldX, post) => {
5794
+ const attrs = `${pre} ${post}`;
5795
+ const yMatch = attrs.match(/\sy\s*=\s*"([^"]*)"/i);
5796
+ const y = (yMatch == null ? void 0 : yMatch[1]) ?? "";
5797
+ const isLineStart = y !== "" ? y !== lastY : lineIdx < lineXs.length;
5798
+ if (!isLineStart) return _m;
5799
+ if (y !== "") lastY = y;
5800
+ const x = lineXs[lineIdx];
5801
+ lineIdx += 1;
5802
+ if (typeof x !== "number" || !Number.isFinite(x)) return _m;
5803
+ return `<tspan${pre} x="${x.toFixed(3)}"${post}>`;
5804
+ }
5805
+ );
5806
+ return newSvg;
5807
+ } catch {
5808
+ return svg;
5809
+ }
5810
+ }
5811
+ function _recolorSvgFills(svg, color) {
5739
5812
  const safe = escapeXmlAttr(color);
5740
5813
  let out = svg.replace(
5741
5814
  /(<(?:text|tspan|path|rect)\b[^>]*?\sfill=")([^"]*)("[^>]*>)/gi,
@@ -15956,9 +16029,9 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
15956
16029
  }
15957
16030
  return svgString;
15958
16031
  }
15959
- const resolvedPackageVersion = "0.5.150";
16032
+ const resolvedPackageVersion = "0.5.152";
15960
16033
  const PACKAGE_VERSION = resolvedPackageVersion;
15961
- const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.150";
16034
+ const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.152";
15962
16035
  const roundParityValue = (value) => {
15963
16036
  if (typeof value !== "number") return value;
15964
16037
  return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
@@ -16393,7 +16466,7 @@ class PixldocsRenderer {
16393
16466
  await this.waitForCanvasScene(container, cloned, i);
16394
16467
  }
16395
16468
  console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
16396
- const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-CDnEStQk.js");
16469
+ const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-RiNowoiG.js");
16397
16470
  const prepared = preparePagesForExport(
16398
16471
  cloned.pages,
16399
16472
  canvasWidth,
@@ -18495,7 +18568,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
18495
18568
  if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
18496
18569
  sanitizeSvgTreeForPdf(svgToDraw);
18497
18570
  try {
18498
- const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await import("./vectorPdfExport-CDnEStQk.js");
18571
+ const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await import("./vectorPdfExport-RiNowoiG.js");
18499
18572
  try {
18500
18573
  await logTextMeasurementDiagnostic(svgToDraw);
18501
18574
  } catch {
@@ -18630,7 +18703,7 @@ async function assemblePdfFromSvgs(svgResults, options = {}) {
18630
18703
  }
18631
18704
  if (shouldOutlineText) {
18632
18705
  try {
18633
- const { convertAllTextToPath } = await import("./svgTextToPath-ws6Fh3rx.js");
18706
+ const { convertAllTextToPath } = await import("./svgTextToPath-BE8TxgiO.js");
18634
18707
  pageSvg = await convertAllTextToPath(pageSvg, fontBaseUrl, { mode: outlineSubMode });
18635
18708
  try {
18636
18709
  dumpSvgTextDiagnostics(pageSvg, i, PARITY_TAG, "STAGE-1b-after-text-to-path-raw");
@@ -18845,4 +18918,4 @@ export {
18845
18918
  collectFontDescriptorsFromConfig as y,
18846
18919
  collectFontsFromConfig as z
18847
18920
  };
18848
- //# sourceMappingURL=index-khnxviCH.js.map
18921
+ //# sourceMappingURL=index-DjobDQ7X.js.map