@pixldocs/canvas-renderer 0.5.159 → 0.5.161

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,7 +5693,6 @@ 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);
5697
5696
  let bgShadowMarker = "";
5698
5697
  let textShadowMarker = "";
5699
5698
  if (hasShadow) {
@@ -5743,100 +5742,6 @@ function applyTextBackground(obj, cfg) {
5743
5742
  function recolorSvgFills(svg, color) {
5744
5743
  return _recolorSvgFills(svg, color);
5745
5744
  }
5746
- function bakeTextSvgToFabricLineStarts(svg, obj, w) {
5747
- var _a, _b, _c, _d;
5748
- try {
5749
- const lines = (obj == null ? void 0 : obj._textLines) ?? [];
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);
5759
- const halfW = w / 2;
5760
- const lineAnchors = [];
5761
- for (let i = 0; i < lines.length; i++) {
5762
- let lineLeft = 0;
5763
- let lineW = 0;
5764
- let firstGlyphAdjust = 0;
5765
- try {
5766
- lineLeft = ((_a = obj._getLineLeftOffset) == null ? void 0 : _a.call(obj, i)) ?? 0;
5767
- } catch {
5768
- lineLeft = 0;
5769
- }
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
- }
5797
- }
5798
- const textOpenRe = /<text\b([^>]*)>/i;
5799
- const textOpenMatch = svg.match(textOpenRe);
5800
- if (!textOpenMatch) return svg;
5801
- let textAttrs = textOpenMatch[1];
5802
- if (/\stext-anchor\s*=\s*"[^"]*"/i.test(textAttrs)) {
5803
- textAttrs = textAttrs.replace(/\stext-anchor\s*=\s*"[^"]*"/i, ' text-anchor="start"');
5804
- } else {
5805
- textAttrs = ` text-anchor="start"${textAttrs}`;
5806
- }
5807
- textAttrs = textAttrs.replace(
5808
- /(\sstyle=")([^"]*)(")/i,
5809
- (_m, pre, val, post) => pre + val.replace(/text-align\s*:\s*[^;"']+;?/gi, "").trim() + post
5810
- );
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
- );
5816
- let lineIdx = 0;
5817
- let lastY = "";
5818
- const newSvg = svg.replace(textOpenMatch[0], newTextOpen).replace(
5819
- /<tspan\b([^>]*?)\sx="([^"]*)"([^>]*)>/gi,
5820
- (_m, pre, _oldX, post) => {
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];
5828
- lineIdx += 1;
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}>`;
5833
- }
5834
- );
5835
- return newSvg;
5836
- } catch {
5837
- return svg;
5838
- }
5839
- }
5840
5745
  function _recolorSvgFills(svg, color) {
5841
5746
  const safe = escapeXmlAttr(color);
5842
5747
  let out = svg.replace(
@@ -15937,93 +15842,6 @@ function PixldocsPreview(props) {
15937
15842
  !canvasSettled && /* @__PURE__ */ jsx("div", { style: { position: "absolute", inset: 0, display: "flex", alignItems: "center", justifyContent: "center", minHeight: 200 }, children: /* @__PURE__ */ jsx("div", { style: { color: "#888", fontSize: 14 }, children: "Loading preview..." }) })
15938
15843
  ] });
15939
15844
  }
15940
- function isFabricTextLike(obj) {
15941
- return !!obj && (obj.type === "textbox" || obj.type === "i-text" || obj.type === "text" || Array.isArray(obj._textLines) && typeof obj.getLineWidth === "function");
15942
- }
15943
- function bakeSelectableTextSvgToFabricLineStarts(svg, obj) {
15944
- try {
15945
- const rawAlign = String((obj == null ? void 0 : obj.textAlign) || "left").toLowerCase();
15946
- if (!/center|right|end/.test(rawAlign)) return svg;
15947
- const lines = (obj == null ? void 0 : obj._textLines) ?? [];
15948
- const width = Number((obj == null ? void 0 : obj.width) ?? 0);
15949
- if (!Array.isArray(lines) || lines.length === 0 || !Number.isFinite(width) || width <= 0) return svg;
15950
- const halfW = width / 2;
15951
- const lineStarts = lines.map((_line, i) => {
15952
- var _a, _b, _c;
15953
- let lineLeft = 0;
15954
- let firstGlyphAdjust = 0;
15955
- try {
15956
- lineLeft = Number(((_a = obj._getLineLeftOffset) == null ? void 0 : _a.call(obj, i)) ?? 0);
15957
- } catch {
15958
- lineLeft = 0;
15959
- }
15960
- try {
15961
- const firstBox = (_c = (_b = obj.__charBounds) == null ? void 0 : _b[i]) == null ? void 0 : _c[0];
15962
- const kerned = Number(firstBox == null ? void 0 : firstBox.kernedWidth);
15963
- const glyphW = Number(firstBox == null ? void 0 : firstBox.width);
15964
- if (Number.isFinite(kerned) && Number.isFinite(glyphW)) firstGlyphAdjust = kerned - glyphW;
15965
- } catch {
15966
- firstGlyphAdjust = 0;
15967
- }
15968
- return -halfW + (Number.isFinite(lineLeft) ? lineLeft : 0) + (Number.isFinite(firstGlyphAdjust) ? firstGlyphAdjust : 0);
15969
- });
15970
- 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
- const cleaned = val.replace(/text-anchor\s*:\s*[^;"']+;?/gi, "").replace(/text-align\s*:\s*[^;"']+;?/gi, "").trim();
15972
- return cleaned ? `${pre}${cleaned}${post}` : "";
15973
- });
15974
- const textOpenMatch = svg.match(/<text\b([^>]*)>/i);
15975
- if (!textOpenMatch) return svg;
15976
- const textAttrs = stripAnchorAttrs(textOpenMatch[1]);
15977
- let lineIdx = 0;
15978
- let lastY = "";
15979
- let replacedLine = false;
15980
- const patched = svg.replace(textOpenMatch[0], `<text text-anchor="start"${textAttrs}>`).replace(
15981
- /<tspan\b([^>]*?)\sx="([^"]*)"([^>]*)>/gi,
15982
- (match, pre, _oldX, post) => {
15983
- const attrs = `${pre} ${post}`;
15984
- const yMatch = attrs.match(/\sy\s*=\s*"([^"]*)"/i);
15985
- const y = (yMatch == null ? void 0 : yMatch[1]) ?? "";
15986
- const isLineStart = y !== "" ? y !== lastY : lineIdx < lineStarts.length;
15987
- if (!isLineStart) return match;
15988
- if (y !== "") lastY = y;
15989
- const x2 = lineStarts[lineIdx++];
15990
- if (!Number.isFinite(x2)) return match;
15991
- replacedLine = true;
15992
- return `<tspan${stripAnchorAttrs(pre)} x="${x2.toFixed(3)}" text-anchor="start" data-pd-line-anchor="1"${stripAnchorAttrs(post)}>`;
15993
- }
15994
- );
15995
- if (replacedLine) return patched;
15996
- const x = lineStarts[0];
15997
- if (!Number.isFinite(x)) return patched;
15998
- return patched.replace(/<text\b([^>]*)>/i, (_m, attrs) => {
15999
- 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}>`;
16001
- });
16002
- } catch {
16003
- return svg;
16004
- }
16005
- }
16006
- function patchTextObjectsForSelectableSvg(fabricInstance) {
16007
- var _a;
16008
- const records = [];
16009
- const visit = (obj) => {
16010
- if (!obj || typeof obj !== "object") return;
16011
- if (isFabricTextLike(obj) && typeof obj.toSVG === "function") {
16012
- const original = obj.toSVG;
16013
- obj.toSVG = function patchedSelectableTextToSVG(reviver) {
16014
- return bakeSelectableTextSvgToFabricLineStarts(original.call(this, reviver), this);
16015
- };
16016
- records.push({ obj, toSVG: original });
16017
- }
16018
- const children = typeof obj.getObjects === "function" ? obj.getObjects() : obj._objects;
16019
- if (Array.isArray(children)) children.forEach(visit);
16020
- };
16021
- try {
16022
- (_a = fabricInstance == null ? void 0 : fabricInstance.getObjects) == null ? void 0 : _a.call(fabricInstance).forEach(visit);
16023
- } catch {
16024
- }
16025
- return records;
16026
- }
16027
15845
  function normalizeSvgDimensions(svg, targetWidth, targetHeight) {
16028
15846
  let normalized = svg;
16029
15847
  if (/\bwidth="[^"]*"/i.test(normalized)) {
@@ -16077,7 +15895,6 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
16077
15895
  } catch {
16078
15896
  }
16079
15897
  const fadeBakeRecords = [];
16080
- const textSvgPatchRecords = patchTextObjectsForSelectableSvg(fabricInstance);
16081
15898
  try {
16082
15899
  const objs = fabricInstance.getObjects().slice();
16083
15900
  for (const obj of objs) {
@@ -16126,12 +15943,6 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
16126
15943
  const raw = fabricInstance.toSVG();
16127
15944
  svgString = normalizeSvgDimensions(raw, canvasWidth, canvasHeight);
16128
15945
  } finally {
16129
- for (const rec of textSvgPatchRecords) {
16130
- try {
16131
- rec.obj.toSVG = rec.toSVG;
16132
- } catch {
16133
- }
16134
- }
16135
15946
  for (const rec of fadeBakeRecords) {
16136
15947
  try {
16137
15948
  fabricInstance.remove(rec.replacement);
@@ -16152,9 +15963,9 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
16152
15963
  }
16153
15964
  return svgString;
16154
15965
  }
16155
- const resolvedPackageVersion = "0.5.159";
15966
+ const resolvedPackageVersion = "0.5.161";
16156
15967
  const PACKAGE_VERSION = resolvedPackageVersion;
16157
- const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.159";
15968
+ const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.161";
16158
15969
  const roundParityValue = (value) => {
16159
15970
  if (typeof value !== "number") return value;
16160
15971
  return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
@@ -16589,7 +16400,7 @@ class PixldocsRenderer {
16589
16400
  await this.waitForCanvasScene(container, cloned, i);
16590
16401
  }
16591
16402
  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");
16403
+ const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-B_T8jiQ3.js");
16593
16404
  const prepared = preparePagesForExport(
16594
16405
  cloned.pages,
16595
16406
  canvasWidth,
@@ -18691,7 +18502,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
18691
18502
  if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
18692
18503
  sanitizeSvgTreeForPdf(svgToDraw);
18693
18504
  try {
18694
- const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await import("./vectorPdfExport-BRxfHxZU.js");
18505
+ const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await import("./vectorPdfExport-B_T8jiQ3.js");
18695
18506
  try {
18696
18507
  await logTextMeasurementDiagnostic(svgToDraw);
18697
18508
  } catch {
@@ -19041,4 +18852,4 @@ export {
19041
18852
  collectFontDescriptorsFromConfig as y,
19042
18853
  collectFontsFromConfig as z
19043
18854
  };
19044
- //# sourceMappingURL=index-ogNxtubz.js.map
18855
+ //# sourceMappingURL=index-Co0kEgTl.js.map