@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.
@@ -5711,6 +5711,7 @@ function applyTextBackground(obj, cfg) {
5711
5711
  const bgPath = hasBg ? `<path d="${bgD}" fill="${escapeXmlAttr(bgFill)}"${bgOpacityAttr} />` : "";
5712
5712
  svg = svg.replace(/style="[^"]*filter:\s*url\([^)]+\)[^"]*"/i, "");
5713
5713
  svg = svg.replace(/<filter[\s\S]*?<\/filter>/gi, "");
5714
+ svg = bakeTextSvgToFabricLineStarts(svg, this, w);
5714
5715
  let bgShadowMarker = "";
5715
5716
  let textShadowMarker = "";
5716
5717
  if (hasShadow) {
@@ -5743,17 +5744,89 @@ function applyTextBackground(obj, cfg) {
5743
5744
  const openTagMatch = svg.match(/^\s*<g\b[^>]*>/);
5744
5745
  const inserted = bgShadowMarker + bgPath + textShadowMarker;
5745
5746
  const shadowBlur = hasShadow ? Math.max(0, Number(shadow.blur ?? 0)) : 0;
5746
- const needsOutlineTag = shadowBlur > 0 ? ' data-pd-shadow-blur="1"' : "";
5747
+ const decorationTags = [
5748
+ shadowBlur > 0 ? 'data-pd-shadow-blur="1"' : "",
5749
+ hasBg ? 'data-pd-text-bg="1"' : ""
5750
+ ].filter(Boolean).join(" ");
5751
+ const decorationAttr = decorationTags ? ` ${decorationTags}` : "";
5747
5752
  if (openTagMatch) {
5748
5753
  const openTag = openTagMatch[0];
5749
- const taggedOpenTag = needsOutlineTag && !/data-pd-shadow-blur=/i.test(openTag) ? openTag.replace(/^<g\b/, `<g${needsOutlineTag}`) : openTag;
5754
+ 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;
5750
5755
  return svg.replace(openTag, taggedOpenTag + inserted);
5751
5756
  }
5752
- return `<g${needsOutlineTag}>${inserted}${svg}</g>`;
5757
+ return `<g${decorationAttr}>${inserted}${svg}</g>`;
5753
5758
  };
5754
5759
  }
5755
5760
  }
5756
5761
  function recolorSvgFills(svg, color) {
5762
+ return _recolorSvgFills(svg, color);
5763
+ }
5764
+ function bakeTextSvgToFabricLineStarts(svg, obj, w) {
5765
+ var _a, _b, _c;
5766
+ try {
5767
+ const lines = (obj == null ? void 0 : obj._textLines) ?? [];
5768
+ if (!Array.isArray(lines) || lines.length === 0) return svg;
5769
+ const halfW = w / 2;
5770
+ const lineXs = [];
5771
+ for (let i = 0; i < lines.length; i++) {
5772
+ let lineLeft = 0;
5773
+ let firstGlyphAdjust = 0;
5774
+ try {
5775
+ lineLeft = ((_a = obj._getLineLeftOffset) == null ? void 0 : _a.call(obj, i)) ?? 0;
5776
+ } catch {
5777
+ lineLeft = 0;
5778
+ }
5779
+ try {
5780
+ const firstBox = (_c = (_b = obj.__charBounds) == null ? void 0 : _b[i]) == null ? void 0 : _c[0];
5781
+ const kerned = Number(firstBox == null ? void 0 : firstBox.kernedWidth);
5782
+ const glyphW = Number(firstBox == null ? void 0 : firstBox.width);
5783
+ if (Number.isFinite(kerned) && Number.isFinite(glyphW)) {
5784
+ firstGlyphAdjust = kerned - glyphW;
5785
+ }
5786
+ } catch {
5787
+ firstGlyphAdjust = 0;
5788
+ }
5789
+ lineXs.push(
5790
+ -halfW + (Number.isFinite(lineLeft) ? lineLeft : 0) + (Number.isFinite(firstGlyphAdjust) ? firstGlyphAdjust : 0)
5791
+ );
5792
+ }
5793
+ const textOpenRe = /<text\b([^>]*)>/i;
5794
+ const textOpenMatch = svg.match(textOpenRe);
5795
+ if (!textOpenMatch) return svg;
5796
+ let textAttrs = textOpenMatch[1];
5797
+ if (/\stext-anchor\s*=\s*"[^"]*"/i.test(textAttrs)) {
5798
+ textAttrs = textAttrs.replace(/\stext-anchor\s*=\s*"[^"]*"/i, ' text-anchor="start"');
5799
+ } else {
5800
+ textAttrs = ` text-anchor="start"${textAttrs}`;
5801
+ }
5802
+ textAttrs = textAttrs.replace(
5803
+ /(\sstyle=")([^"]*)(")/i,
5804
+ (_m, pre, val, post) => pre + val.replace(/text-align\s*:\s*[^;"']+;?/gi, "").trim() + post
5805
+ );
5806
+ const newTextOpen = `<text${textAttrs}>`;
5807
+ let lineIdx = 0;
5808
+ let lastY = "";
5809
+ const newSvg = svg.replace(textOpenMatch[0], newTextOpen).replace(
5810
+ /<tspan\b([^>]*?)\sx="([^"]*)"([^>]*)>/gi,
5811
+ (_m, pre, _oldX, post) => {
5812
+ const attrs = `${pre} ${post}`;
5813
+ const yMatch = attrs.match(/\sy\s*=\s*"([^"]*)"/i);
5814
+ const y = (yMatch == null ? void 0 : yMatch[1]) ?? "";
5815
+ const isLineStart = y !== "" ? y !== lastY : lineIdx < lineXs.length;
5816
+ if (!isLineStart) return _m;
5817
+ if (y !== "") lastY = y;
5818
+ const x = lineXs[lineIdx];
5819
+ lineIdx += 1;
5820
+ if (typeof x !== "number" || !Number.isFinite(x)) return _m;
5821
+ return `<tspan${pre} x="${x.toFixed(3)}"${post}>`;
5822
+ }
5823
+ );
5824
+ return newSvg;
5825
+ } catch {
5826
+ return svg;
5827
+ }
5828
+ }
5829
+ function _recolorSvgFills(svg, color) {
5757
5830
  const safe = escapeXmlAttr(color);
5758
5831
  let out = svg.replace(
5759
5832
  /(<(?:text|tspan|path|rect)\b[^>]*?\sfill=")([^"]*)("[^>]*>)/gi,
@@ -15974,9 +16047,9 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
15974
16047
  }
15975
16048
  return svgString;
15976
16049
  }
15977
- const resolvedPackageVersion = "0.5.150";
16050
+ const resolvedPackageVersion = "0.5.152";
15978
16051
  const PACKAGE_VERSION = resolvedPackageVersion;
15979
- const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.150";
16052
+ const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.152";
15980
16053
  const roundParityValue = (value) => {
15981
16054
  if (typeof value !== "number") return value;
15982
16055
  return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
@@ -16411,7 +16484,7 @@ class PixldocsRenderer {
16411
16484
  await this.waitForCanvasScene(container, cloned, i);
16412
16485
  }
16413
16486
  console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
16414
- const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-qAWd8i87.cjs"));
16487
+ const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-gHfbrQfT.cjs"));
16415
16488
  const prepared = preparePagesForExport(
16416
16489
  cloned.pages,
16417
16490
  canvasWidth,
@@ -18513,7 +18586,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
18513
18586
  if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
18514
18587
  sanitizeSvgTreeForPdf(svgToDraw);
18515
18588
  try {
18516
- const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await Promise.resolve().then(() => require("./vectorPdfExport-qAWd8i87.cjs"));
18589
+ const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await Promise.resolve().then(() => require("./vectorPdfExport-gHfbrQfT.cjs"));
18517
18590
  try {
18518
18591
  await logTextMeasurementDiagnostic(svgToDraw);
18519
18592
  } catch {
@@ -18648,7 +18721,7 @@ async function assemblePdfFromSvgs(svgResults, options = {}) {
18648
18721
  }
18649
18722
  if (shouldOutlineText) {
18650
18723
  try {
18651
- const { convertAllTextToPath } = await Promise.resolve().then(() => require("./svgTextToPath-DolCNU9g.cjs"));
18724
+ const { convertAllTextToPath } = await Promise.resolve().then(() => require("./svgTextToPath-qhinMiiS.cjs"));
18652
18725
  pageSvg = await convertAllTextToPath(pageSvg, fontBaseUrl, { mode: outlineSubMode });
18653
18726
  try {
18654
18727
  dumpSvgTextDiagnostics(pageSvg, i, PARITY_TAG, "STAGE-1b-after-text-to-path-raw");
@@ -18860,4 +18933,4 @@ exports.setAutoShrinkDebug = setAutoShrinkDebug;
18860
18933
  exports.setBundledAssetPrefixes = setBundledAssetPrefixes;
18861
18934
  exports.warmResolvedTemplateForPreview = warmResolvedTemplateForPreview;
18862
18935
  exports.warmTemplateFromForm = warmTemplateFromForm;
18863
- //# sourceMappingURL=index-CczB1vpO.cjs.map
18936
+ //# sourceMappingURL=index-CM_LXIKO.cjs.map