@pixldocs/canvas-renderer 0.5.151 → 0.5.153

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.
@@ -5744,20 +5744,56 @@ function recolorSvgFills(svg, color) {
5744
5744
  return _recolorSvgFills(svg, color);
5745
5745
  }
5746
5746
  function bakeTextSvgToFabricLineStarts(svg, obj, w) {
5747
- var _a;
5747
+ var _a, _b, _c, _d;
5748
5748
  try {
5749
5749
  const lines = (obj == null ? void 0 : obj._textLines) ?? [];
5750
5750
  if (!Array.isArray(lines) || lines.length === 0) return svg;
5751
+ const rawAlign = String((obj == null ? void 0 : obj.textAlign) || "left").toLowerCase();
5752
+ const alignmentAnchor = /right|end/.test(rawAlign) ? "end" : /center/.test(rawAlign) ? "middle" : "start";
5753
+ const hasStyledChars = (() => {
5754
+ const styles = obj == null ? void 0 : obj.styles;
5755
+ if (!styles || typeof styles !== "object") return false;
5756
+ return Object.values(styles).some((line) => line && typeof line === "object" && Object.keys(line).length > 0);
5757
+ })();
5758
+ const canUseAlignmentAnchor = alignmentAnchor !== "start" && !hasStyledChars && !(obj == null ? void 0 : obj.path) && !Number((obj == null ? void 0 : obj.charSpacing) ?? 0);
5751
5759
  const halfW = w / 2;
5752
- const lineXs = [];
5760
+ const lineAnchors = [];
5753
5761
  for (let i = 0; i < lines.length; i++) {
5754
5762
  let lineLeft = 0;
5763
+ let lineW = 0;
5764
+ let firstGlyphAdjust = 0;
5755
5765
  try {
5756
5766
  lineLeft = ((_a = obj._getLineLeftOffset) == null ? void 0 : _a.call(obj, i)) ?? 0;
5757
5767
  } catch {
5758
5768
  lineLeft = 0;
5759
5769
  }
5760
- lineXs.push(-halfW + (Number.isFinite(lineLeft) ? lineLeft : 0));
5770
+ try {
5771
+ lineW = ((_b = obj.getLineWidth) == null ? void 0 : _b.call(obj, i)) ?? 0;
5772
+ } catch {
5773
+ lineW = 0;
5774
+ }
5775
+ try {
5776
+ const firstBox = (_d = (_c = obj.__charBounds) == null ? void 0 : _c[i]) == null ? void 0 : _d[0];
5777
+ const kerned = Number(firstBox == null ? void 0 : firstBox.kernedWidth);
5778
+ const glyphW = Number(firstBox == null ? void 0 : firstBox.width);
5779
+ if (Number.isFinite(kerned) && Number.isFinite(glyphW)) {
5780
+ firstGlyphAdjust = kerned - glyphW;
5781
+ }
5782
+ } catch {
5783
+ firstGlyphAdjust = 0;
5784
+ }
5785
+ const baseStart = -halfW + (Number.isFinite(lineLeft) ? lineLeft : 0);
5786
+ if (canUseAlignmentAnchor && Number.isFinite(lineW) && lineW > 0) {
5787
+ lineAnchors.push({
5788
+ x: alignmentAnchor === "end" ? baseStart + lineW : baseStart + lineW / 2,
5789
+ anchor: alignmentAnchor
5790
+ });
5791
+ } else {
5792
+ lineAnchors.push({
5793
+ x: baseStart + (Number.isFinite(firstGlyphAdjust) ? firstGlyphAdjust : 0),
5794
+ anchor: "start"
5795
+ });
5796
+ }
5761
5797
  }
5762
5798
  const textOpenRe = /<text\b([^>]*)>/i;
5763
5799
  const textOpenMatch = svg.match(textOpenRe);
@@ -5773,14 +5809,27 @@ function bakeTextSvgToFabricLineStarts(svg, obj, w) {
5773
5809
  (_m, pre, val, post) => pre + val.replace(/text-align\s*:\s*[^;"']+;?/gi, "").trim() + post
5774
5810
  );
5775
5811
  const newTextOpen = `<text${textAttrs}>`;
5812
+ const stripAnchorAttrs = (attrs) => attrs.replace(/\s+text-anchor\s*=\s*"[^"]*"/gi, "").replace(
5813
+ /(\sstyle=")([^"]*)(")/i,
5814
+ (_m, pre, val, post) => pre + val.replace(/text-anchor\s*:\s*[^;"']+;?/gi, "").trim() + post
5815
+ );
5776
5816
  let lineIdx = 0;
5817
+ let lastY = "";
5777
5818
  const newSvg = svg.replace(textOpenMatch[0], newTextOpen).replace(
5778
5819
  /<tspan\b([^>]*?)\sx="([^"]*)"([^>]*)>/gi,
5779
5820
  (_m, pre, _oldX, post) => {
5780
- const x = lineXs[lineIdx];
5821
+ const attrs = `${pre} ${post}`;
5822
+ const yMatch = attrs.match(/\sy\s*=\s*"([^"]*)"/i);
5823
+ const y = (yMatch == null ? void 0 : yMatch[1]) ?? "";
5824
+ const isLineStart = y !== "" ? y !== lastY : lineIdx < lineAnchors.length;
5825
+ if (!isLineStart) return _m;
5826
+ if (y !== "") lastY = y;
5827
+ const lineAnchor = lineAnchors[lineIdx];
5781
5828
  lineIdx += 1;
5782
- if (typeof x !== "number" || !Number.isFinite(x)) return _m;
5783
- return `<tspan${pre} x="${x.toFixed(3)}"${post}>`;
5829
+ if (!lineAnchor || typeof lineAnchor.x !== "number" || !Number.isFinite(lineAnchor.x)) return _m;
5830
+ const cleanPre = stripAnchorAttrs(pre);
5831
+ const cleanPost = stripAnchorAttrs(post);
5832
+ return `<tspan${cleanPre} x="${lineAnchor.x.toFixed(3)}" text-anchor="${lineAnchor.anchor}" data-pd-line-anchor="1"${cleanPost}>`;
5784
5833
  }
5785
5834
  );
5786
5835
  return newSvg;
@@ -16009,9 +16058,9 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
16009
16058
  }
16010
16059
  return svgString;
16011
16060
  }
16012
- const resolvedPackageVersion = "0.5.151";
16061
+ const resolvedPackageVersion = "0.5.153";
16013
16062
  const PACKAGE_VERSION = resolvedPackageVersion;
16014
- const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.151";
16063
+ const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.153";
16015
16064
  const roundParityValue = (value) => {
16016
16065
  if (typeof value !== "number") return value;
16017
16066
  return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
@@ -16446,7 +16495,7 @@ class PixldocsRenderer {
16446
16495
  await this.waitForCanvasScene(container, cloned, i);
16447
16496
  }
16448
16497
  console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
16449
- const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-TF3IGImZ.js");
16498
+ const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-DTssH1-U.js");
16450
16499
  const prepared = preparePagesForExport(
16451
16500
  cloned.pages,
16452
16501
  canvasWidth,
@@ -18548,7 +18597,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
18548
18597
  if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
18549
18598
  sanitizeSvgTreeForPdf(svgToDraw);
18550
18599
  try {
18551
- const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await import("./vectorPdfExport-TF3IGImZ.js");
18600
+ const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await import("./vectorPdfExport-DTssH1-U.js");
18552
18601
  try {
18553
18602
  await logTextMeasurementDiagnostic(svgToDraw);
18554
18603
  } catch {
@@ -18683,7 +18732,7 @@ async function assemblePdfFromSvgs(svgResults, options = {}) {
18683
18732
  }
18684
18733
  if (shouldOutlineText) {
18685
18734
  try {
18686
- const { convertAllTextToPath } = await import("./svgTextToPath-BE8TxgiO.js");
18735
+ const { convertAllTextToPath } = await import("./svgTextToPath-BXAzwaaR.js");
18687
18736
  pageSvg = await convertAllTextToPath(pageSvg, fontBaseUrl, { mode: outlineSubMode });
18688
18737
  try {
18689
18738
  dumpSvgTextDiagnostics(pageSvg, i, PARITY_TAG, "STAGE-1b-after-text-to-path-raw");
@@ -18898,4 +18947,4 @@ export {
18898
18947
  collectFontDescriptorsFromConfig as y,
18899
18948
  collectFontsFromConfig as z
18900
18949
  };
18901
- //# sourceMappingURL=index-Dp8yJxTW.js.map
18950
+ //# sourceMappingURL=index-CAH9akzI.js.map