@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.
@@ -5804,12 +5804,16 @@ function bakeTextSvgToFabricLineStarts(svg, obj, w) {
5804
5804
  if (canUseAlignmentAnchor && Number.isFinite(lineW) && lineW > 0) {
5805
5805
  lineAnchors.push({
5806
5806
  x: alignmentAnchor === "end" ? baseStart + lineW : baseStart + lineW / 2,
5807
- anchor: alignmentAnchor
5807
+ anchor: alignmentAnchor,
5808
+ lineWidth: lineW,
5809
+ lineStart: baseStart
5808
5810
  });
5809
5811
  } else {
5810
5812
  lineAnchors.push({
5811
5813
  x: baseStart + (Number.isFinite(firstGlyphAdjust) ? firstGlyphAdjust : 0),
5812
- anchor: "start"
5814
+ anchor: "start",
5815
+ lineWidth: Number.isFinite(lineW) ? lineW : 0,
5816
+ lineStart: baseStart
5813
5817
  });
5814
5818
  }
5815
5819
  }
@@ -5847,7 +5851,7 @@ function bakeTextSvgToFabricLineStarts(svg, obj, w) {
5847
5851
  if (!lineAnchor || typeof lineAnchor.x !== "number" || !Number.isFinite(lineAnchor.x)) return _m;
5848
5852
  const cleanPre = stripAnchorAttrs(pre);
5849
5853
  const cleanPost = stripAnchorAttrs(post);
5850
- return `<tspan${cleanPre} x="${lineAnchor.x.toFixed(3)}" text-anchor="${lineAnchor.anchor}" data-pd-line-anchor="1"${cleanPost}>`;
5854
+ 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}>`;
5851
5855
  }
5852
5856
  );
5853
5857
  return newSvg;
@@ -15958,17 +15962,26 @@ function PixldocsPreview(props) {
15958
15962
  function isFabricTextLike(obj) {
15959
15963
  return !!obj && (obj.type === "textbox" || obj.type === "i-text" || obj.type === "text" || Array.isArray(obj._textLines) && typeof obj.getLineWidth === "function");
15960
15964
  }
15961
- function bakeSelectableTextSvgToFabricLineStarts(svg, obj) {
15965
+ function bakeSelectableTextSvgToFabricLineAnchors(svg, obj) {
15962
15966
  try {
15967
+ if (/\bdata-pd-line-anchor\s*=\s*"1"/i.test(svg)) return svg;
15963
15968
  const rawAlign = String((obj == null ? void 0 : obj.textAlign) || "left").toLowerCase();
15964
15969
  if (!/center|right|end/.test(rawAlign)) return svg;
15965
15970
  const lines = (obj == null ? void 0 : obj._textLines) ?? [];
15966
15971
  const width = Number((obj == null ? void 0 : obj.width) ?? 0);
15967
15972
  if (!Array.isArray(lines) || lines.length === 0 || !Number.isFinite(width) || width <= 0) return svg;
15973
+ const alignmentAnchor = /right|end/.test(rawAlign) ? "end" : "middle";
15974
+ const hasStyledChars = (() => {
15975
+ const styles = obj == null ? void 0 : obj.styles;
15976
+ if (!styles || typeof styles !== "object") return false;
15977
+ return Object.values(styles).some((line2) => line2 && typeof line2 === "object" && Object.keys(line2).length > 0);
15978
+ })();
15979
+ const canUseLineAnchor = !hasStyledChars && !(obj == null ? void 0 : obj.path) && !Number((obj == null ? void 0 : obj.charSpacing) ?? 0);
15968
15980
  const halfW = width / 2;
15969
- const lineStarts = lines.map((_line, i) => {
15970
- var _a, _b, _c;
15981
+ const lineAnchors = lines.map((_line, i) => {
15982
+ var _a, _b, _c, _d;
15971
15983
  let lineLeft = 0;
15984
+ let lineW = 0;
15972
15985
  let firstGlyphAdjust = 0;
15973
15986
  try {
15974
15987
  lineLeft = Number(((_a = obj._getLineLeftOffset) == null ? void 0 : _a.call(obj, i)) ?? 0);
@@ -15976,14 +15989,33 @@ function bakeSelectableTextSvgToFabricLineStarts(svg, obj) {
15976
15989
  lineLeft = 0;
15977
15990
  }
15978
15991
  try {
15979
- const firstBox = (_c = (_b = obj.__charBounds) == null ? void 0 : _b[i]) == null ? void 0 : _c[0];
15992
+ lineW = Number(((_b = obj.getLineWidth) == null ? void 0 : _b.call(obj, i)) ?? 0);
15993
+ } catch {
15994
+ lineW = 0;
15995
+ }
15996
+ try {
15997
+ const firstBox = (_d = (_c = obj.__charBounds) == null ? void 0 : _c[i]) == null ? void 0 : _d[0];
15980
15998
  const kerned = Number(firstBox == null ? void 0 : firstBox.kernedWidth);
15981
15999
  const glyphW = Number(firstBox == null ? void 0 : firstBox.width);
15982
16000
  if (Number.isFinite(kerned) && Number.isFinite(glyphW)) firstGlyphAdjust = kerned - glyphW;
15983
16001
  } catch {
15984
16002
  firstGlyphAdjust = 0;
15985
16003
  }
15986
- return -halfW + (Number.isFinite(lineLeft) ? lineLeft : 0) + (Number.isFinite(firstGlyphAdjust) ? firstGlyphAdjust : 0);
16004
+ const baseStart = -halfW + (Number.isFinite(lineLeft) ? lineLeft : 0);
16005
+ if (canUseLineAnchor && Number.isFinite(lineW) && lineW > 0) {
16006
+ return {
16007
+ x: alignmentAnchor === "end" ? baseStart + lineW : baseStart + lineW / 2,
16008
+ anchor: alignmentAnchor,
16009
+ lineWidth: lineW,
16010
+ lineStart: baseStart
16011
+ };
16012
+ }
16013
+ return {
16014
+ x: baseStart + (Number.isFinite(firstGlyphAdjust) ? firstGlyphAdjust : 0),
16015
+ anchor: "start",
16016
+ lineWidth: Number.isFinite(lineW) ? lineW : 0,
16017
+ lineStart: baseStart
16018
+ };
15987
16019
  });
15988
16020
  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) => {
15989
16021
  const cleaned = val.replace(/text-anchor\s*:\s*[^;"']+;?/gi, "").replace(/text-align\s*:\s*[^;"']+;?/gi, "").trim();
@@ -16001,21 +16033,21 @@ function bakeSelectableTextSvgToFabricLineStarts(svg, obj) {
16001
16033
  const attrs = `${pre} ${post}`;
16002
16034
  const yMatch = attrs.match(/\sy\s*=\s*"([^"]*)"/i);
16003
16035
  const y = (yMatch == null ? void 0 : yMatch[1]) ?? "";
16004
- const isLineStart = y !== "" ? y !== lastY : lineIdx < lineStarts.length;
16036
+ const isLineStart = y !== "" ? y !== lastY : lineIdx < lineAnchors.length;
16005
16037
  if (!isLineStart) return match;
16006
16038
  if (y !== "") lastY = y;
16007
- const x2 = lineStarts[lineIdx++];
16008
- if (!Number.isFinite(x2)) return match;
16039
+ const line2 = lineAnchors[lineIdx++];
16040
+ if (!line2 || !Number.isFinite(line2.x)) return match;
16009
16041
  replacedLine = true;
16010
- return `<tspan${stripAnchorAttrs(pre)} x="${x2.toFixed(3)}" text-anchor="start" data-pd-line-anchor="1"${stripAnchorAttrs(post)}>`;
16042
+ 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)}>`;
16011
16043
  }
16012
16044
  );
16013
16045
  if (replacedLine) return patched;
16014
- const x = lineStarts[0];
16015
- if (!Number.isFinite(x)) return patched;
16046
+ const line = lineAnchors[0];
16047
+ if (!line || !Number.isFinite(line.x)) return patched;
16016
16048
  return patched.replace(/<text\b([^>]*)>/i, (_m, attrs) => {
16017
16049
  const clean = stripAnchorAttrs(attrs).replace(/\s+x\s*=\s*"[^"]*"/i, "");
16018
- return `<text x="${x.toFixed(3)}" text-anchor="start" data-pd-line-anchor="1"${clean}>`;
16050
+ 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}>`;
16019
16051
  });
16020
16052
  } catch {
16021
16053
  return svg;
@@ -16029,7 +16061,7 @@ function patchTextObjectsForSelectableSvg(fabricInstance) {
16029
16061
  if (isFabricTextLike(obj) && typeof obj.toSVG === "function") {
16030
16062
  const original = obj.toSVG;
16031
16063
  obj.toSVG = function patchedSelectableTextToSVG(reviver) {
16032
- return bakeSelectableTextSvgToFabricLineStarts(original.call(this, reviver), this);
16064
+ return bakeSelectableTextSvgToFabricLineAnchors(original.call(this, reviver), this);
16033
16065
  };
16034
16066
  records.push({ obj, toSVG: original });
16035
16067
  }
@@ -16170,9 +16202,9 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
16170
16202
  }
16171
16203
  return svgString;
16172
16204
  }
16173
- const resolvedPackageVersion = "0.5.159";
16205
+ const resolvedPackageVersion = "0.5.160";
16174
16206
  const PACKAGE_VERSION = resolvedPackageVersion;
16175
- const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.159";
16207
+ const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.160";
16176
16208
  const roundParityValue = (value) => {
16177
16209
  if (typeof value !== "number") return value;
16178
16210
  return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
@@ -16607,7 +16639,7 @@ class PixldocsRenderer {
16607
16639
  await this.waitForCanvasScene(container, cloned, i);
16608
16640
  }
16609
16641
  console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
16610
- const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-BqyoXT--.cjs"));
16642
+ const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-DEMJeh_t.cjs"));
16611
16643
  const prepared = preparePagesForExport(
16612
16644
  cloned.pages,
16613
16645
  canvasWidth,
@@ -18709,7 +18741,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
18709
18741
  if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
18710
18742
  sanitizeSvgTreeForPdf(svgToDraw);
18711
18743
  try {
18712
- const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await Promise.resolve().then(() => require("./vectorPdfExport-BqyoXT--.cjs"));
18744
+ const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await Promise.resolve().then(() => require("./vectorPdfExport-DEMJeh_t.cjs"));
18713
18745
  try {
18714
18746
  await logTextMeasurementDiagnostic(svgToDraw);
18715
18747
  } catch {
@@ -19056,4 +19088,4 @@ exports.setAutoShrinkDebug = setAutoShrinkDebug;
19056
19088
  exports.setBundledAssetPrefixes = setBundledAssetPrefixes;
19057
19089
  exports.warmResolvedTemplateForPreview = warmResolvedTemplateForPreview;
19058
19090
  exports.warmTemplateFromForm = warmTemplateFromForm;
19059
- //# sourceMappingURL=index-CA-UhjM7.cjs.map
19091
+ //# sourceMappingURL=index-CtUEIsYl.cjs.map