@pixldocs/canvas-renderer 0.5.159 → 0.5.160

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.
@@ -5786,12 +5786,16 @@ function bakeTextSvgToFabricLineStarts(svg, obj, w) {
5786
5786
  if (canUseAlignmentAnchor && Number.isFinite(lineW) && lineW > 0) {
5787
5787
  lineAnchors.push({
5788
5788
  x: alignmentAnchor === "end" ? baseStart + lineW : baseStart + lineW / 2,
5789
- anchor: alignmentAnchor
5789
+ anchor: alignmentAnchor,
5790
+ lineWidth: lineW,
5791
+ lineStart: baseStart
5790
5792
  });
5791
5793
  } else {
5792
5794
  lineAnchors.push({
5793
5795
  x: baseStart + (Number.isFinite(firstGlyphAdjust) ? firstGlyphAdjust : 0),
5794
- anchor: "start"
5796
+ anchor: "start",
5797
+ lineWidth: Number.isFinite(lineW) ? lineW : 0,
5798
+ lineStart: baseStart
5795
5799
  });
5796
5800
  }
5797
5801
  }
@@ -5829,7 +5833,7 @@ function bakeTextSvgToFabricLineStarts(svg, obj, w) {
5829
5833
  if (!lineAnchor || typeof lineAnchor.x !== "number" || !Number.isFinite(lineAnchor.x)) return _m;
5830
5834
  const cleanPre = stripAnchorAttrs(pre);
5831
5835
  const cleanPost = stripAnchorAttrs(post);
5832
- return `<tspan${cleanPre} x="${lineAnchor.x.toFixed(3)}" text-anchor="${lineAnchor.anchor}" data-pd-line-anchor="1"${cleanPost}>`;
5836
+ return `<tspan${cleanPre} x="${lineAnchor.x.toFixed(3)}" text-anchor="${lineAnchor.anchor}" data-pd-line-anchor="1" data-pd-line-width="${lineAnchor.lineWidth.toFixed(3)}" data-pd-line-start="${lineAnchor.lineStart.toFixed(3)}"${cleanPost}>`;
5833
5837
  }
5834
5838
  );
5835
5839
  return newSvg;
@@ -15940,17 +15944,26 @@ function PixldocsPreview(props) {
15940
15944
  function isFabricTextLike(obj) {
15941
15945
  return !!obj && (obj.type === "textbox" || obj.type === "i-text" || obj.type === "text" || Array.isArray(obj._textLines) && typeof obj.getLineWidth === "function");
15942
15946
  }
15943
- function bakeSelectableTextSvgToFabricLineStarts(svg, obj) {
15947
+ function bakeSelectableTextSvgToFabricLineAnchors(svg, obj) {
15944
15948
  try {
15949
+ if (/\bdata-pd-line-anchor\s*=\s*"1"/i.test(svg)) return svg;
15945
15950
  const rawAlign = String((obj == null ? void 0 : obj.textAlign) || "left").toLowerCase();
15946
15951
  if (!/center|right|end/.test(rawAlign)) return svg;
15947
15952
  const lines = (obj == null ? void 0 : obj._textLines) ?? [];
15948
15953
  const width = Number((obj == null ? void 0 : obj.width) ?? 0);
15949
15954
  if (!Array.isArray(lines) || lines.length === 0 || !Number.isFinite(width) || width <= 0) return svg;
15955
+ const alignmentAnchor = /right|end/.test(rawAlign) ? "end" : "middle";
15956
+ const hasStyledChars = (() => {
15957
+ const styles = obj == null ? void 0 : obj.styles;
15958
+ if (!styles || typeof styles !== "object") return false;
15959
+ return Object.values(styles).some((line2) => line2 && typeof line2 === "object" && Object.keys(line2).length > 0);
15960
+ })();
15961
+ const canUseLineAnchor = !hasStyledChars && !(obj == null ? void 0 : obj.path) && !Number((obj == null ? void 0 : obj.charSpacing) ?? 0);
15950
15962
  const halfW = width / 2;
15951
- const lineStarts = lines.map((_line, i) => {
15952
- var _a, _b, _c;
15963
+ const lineAnchors = lines.map((_line, i) => {
15964
+ var _a, _b, _c, _d;
15953
15965
  let lineLeft = 0;
15966
+ let lineW = 0;
15954
15967
  let firstGlyphAdjust = 0;
15955
15968
  try {
15956
15969
  lineLeft = Number(((_a = obj._getLineLeftOffset) == null ? void 0 : _a.call(obj, i)) ?? 0);
@@ -15958,14 +15971,33 @@ function bakeSelectableTextSvgToFabricLineStarts(svg, obj) {
15958
15971
  lineLeft = 0;
15959
15972
  }
15960
15973
  try {
15961
- const firstBox = (_c = (_b = obj.__charBounds) == null ? void 0 : _b[i]) == null ? void 0 : _c[0];
15974
+ lineW = Number(((_b = obj.getLineWidth) == null ? void 0 : _b.call(obj, i)) ?? 0);
15975
+ } catch {
15976
+ lineW = 0;
15977
+ }
15978
+ try {
15979
+ const firstBox = (_d = (_c = obj.__charBounds) == null ? void 0 : _c[i]) == null ? void 0 : _d[0];
15962
15980
  const kerned = Number(firstBox == null ? void 0 : firstBox.kernedWidth);
15963
15981
  const glyphW = Number(firstBox == null ? void 0 : firstBox.width);
15964
15982
  if (Number.isFinite(kerned) && Number.isFinite(glyphW)) firstGlyphAdjust = kerned - glyphW;
15965
15983
  } catch {
15966
15984
  firstGlyphAdjust = 0;
15967
15985
  }
15968
- return -halfW + (Number.isFinite(lineLeft) ? lineLeft : 0) + (Number.isFinite(firstGlyphAdjust) ? firstGlyphAdjust : 0);
15986
+ const baseStart = -halfW + (Number.isFinite(lineLeft) ? lineLeft : 0);
15987
+ if (canUseLineAnchor && Number.isFinite(lineW) && lineW > 0) {
15988
+ return {
15989
+ x: alignmentAnchor === "end" ? baseStart + lineW : baseStart + lineW / 2,
15990
+ anchor: alignmentAnchor,
15991
+ lineWidth: lineW,
15992
+ lineStart: baseStart
15993
+ };
15994
+ }
15995
+ return {
15996
+ x: baseStart + (Number.isFinite(firstGlyphAdjust) ? firstGlyphAdjust : 0),
15997
+ anchor: "start",
15998
+ lineWidth: Number.isFinite(lineW) ? lineW : 0,
15999
+ lineStart: baseStart
16000
+ };
15969
16001
  });
15970
16002
  const stripAnchorAttrs = (attrs) => attrs.replace(/\s+text-anchor\s*=\s*"[^"]*"/gi, "").replace(/\s+data-pd-line-anchor\s*=\s*"[^"]*"/gi, "").replace(/(\sstyle=")([^"]*)(")/i, (_m, pre, val, post) => {
15971
16003
  const cleaned = val.replace(/text-anchor\s*:\s*[^;"']+;?/gi, "").replace(/text-align\s*:\s*[^;"']+;?/gi, "").trim();
@@ -15983,21 +16015,21 @@ function bakeSelectableTextSvgToFabricLineStarts(svg, obj) {
15983
16015
  const attrs = `${pre} ${post}`;
15984
16016
  const yMatch = attrs.match(/\sy\s*=\s*"([^"]*)"/i);
15985
16017
  const y = (yMatch == null ? void 0 : yMatch[1]) ?? "";
15986
- const isLineStart = y !== "" ? y !== lastY : lineIdx < lineStarts.length;
16018
+ const isLineStart = y !== "" ? y !== lastY : lineIdx < lineAnchors.length;
15987
16019
  if (!isLineStart) return match;
15988
16020
  if (y !== "") lastY = y;
15989
- const x2 = lineStarts[lineIdx++];
15990
- if (!Number.isFinite(x2)) return match;
16021
+ const line2 = lineAnchors[lineIdx++];
16022
+ if (!line2 || !Number.isFinite(line2.x)) return match;
15991
16023
  replacedLine = true;
15992
- return `<tspan${stripAnchorAttrs(pre)} x="${x2.toFixed(3)}" text-anchor="start" data-pd-line-anchor="1"${stripAnchorAttrs(post)}>`;
16024
+ return `<tspan${stripAnchorAttrs(pre)} x="${line2.x.toFixed(3)}" text-anchor="${line2.anchor}" data-pd-line-anchor="1" data-pd-line-width="${line2.lineWidth.toFixed(3)}" data-pd-line-start="${line2.lineStart.toFixed(3)}"${stripAnchorAttrs(post)}>`;
15993
16025
  }
15994
16026
  );
15995
16027
  if (replacedLine) return patched;
15996
- const x = lineStarts[0];
15997
- if (!Number.isFinite(x)) return patched;
16028
+ const line = lineAnchors[0];
16029
+ if (!line || !Number.isFinite(line.x)) return patched;
15998
16030
  return patched.replace(/<text\b([^>]*)>/i, (_m, attrs) => {
15999
16031
  const clean = stripAnchorAttrs(attrs).replace(/\s+x\s*=\s*"[^"]*"/i, "");
16000
- return `<text x="${x.toFixed(3)}" text-anchor="start" data-pd-line-anchor="1"${clean}>`;
16032
+ return `<text x="${line.x.toFixed(3)}" text-anchor="${line.anchor}" data-pd-line-anchor="1" data-pd-line-width="${line.lineWidth.toFixed(3)}" data-pd-line-start="${line.lineStart.toFixed(3)}"${clean}>`;
16001
16033
  });
16002
16034
  } catch {
16003
16035
  return svg;
@@ -16011,7 +16043,7 @@ function patchTextObjectsForSelectableSvg(fabricInstance) {
16011
16043
  if (isFabricTextLike(obj) && typeof obj.toSVG === "function") {
16012
16044
  const original = obj.toSVG;
16013
16045
  obj.toSVG = function patchedSelectableTextToSVG(reviver) {
16014
- return bakeSelectableTextSvgToFabricLineStarts(original.call(this, reviver), this);
16046
+ return bakeSelectableTextSvgToFabricLineAnchors(original.call(this, reviver), this);
16015
16047
  };
16016
16048
  records.push({ obj, toSVG: original });
16017
16049
  }
@@ -16152,9 +16184,9 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
16152
16184
  }
16153
16185
  return svgString;
16154
16186
  }
16155
- const resolvedPackageVersion = "0.5.159";
16187
+ const resolvedPackageVersion = "0.5.160";
16156
16188
  const PACKAGE_VERSION = resolvedPackageVersion;
16157
- const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.159";
16189
+ const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.160";
16158
16190
  const roundParityValue = (value) => {
16159
16191
  if (typeof value !== "number") return value;
16160
16192
  return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
@@ -16589,7 +16621,7 @@ class PixldocsRenderer {
16589
16621
  await this.waitForCanvasScene(container, cloned, i);
16590
16622
  }
16591
16623
  console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
16592
- const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-BRxfHxZU.js");
16624
+ const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-2NNilLNC.js");
16593
16625
  const prepared = preparePagesForExport(
16594
16626
  cloned.pages,
16595
16627
  canvasWidth,
@@ -18691,7 +18723,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
18691
18723
  if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
18692
18724
  sanitizeSvgTreeForPdf(svgToDraw);
18693
18725
  try {
18694
- const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await import("./vectorPdfExport-BRxfHxZU.js");
18726
+ const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await import("./vectorPdfExport-2NNilLNC.js");
18695
18727
  try {
18696
18728
  await logTextMeasurementDiagnostic(svgToDraw);
18697
18729
  } catch {
@@ -19041,4 +19073,4 @@ export {
19041
19073
  collectFontDescriptorsFromConfig as y,
19042
19074
  collectFontsFromConfig as z
19043
19075
  };
19044
- //# sourceMappingURL=index-ogNxtubz.js.map
19076
+ //# sourceMappingURL=index-CmhkyT2o.js.map