@pixldocs/canvas-renderer 0.5.229 → 0.5.231

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.
@@ -9627,6 +9627,63 @@ function renderSmartElementToDataUri(type, props, width, height) {
9627
9627
  if (!svg) return null;
9628
9628
  return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}`;
9629
9629
  }
9630
+ function runFontReloadAndReflow(opts) {
9631
+ const { canvas, pageTree, pageBoundsOptions, preserveGlobalFontCache, persistTextboxSize, preResnapSync } = opts;
9632
+ if (!canvas) return;
9633
+ try {
9634
+ clearFontCacheAndRerender(canvas, { clearGlobalCharCache: !preserveGlobalFontCache });
9635
+ } catch {
9636
+ }
9637
+ try {
9638
+ clearMeasurementCache();
9639
+ } catch {
9640
+ }
9641
+ if (!preserveGlobalFontCache) {
9642
+ try {
9643
+ clearFabricCharCache();
9644
+ } catch {
9645
+ }
9646
+ }
9647
+ if (persistTextboxSize && pageTree.length) {
9648
+ const elements = flattenChildren(pageTree);
9649
+ canvas.getObjects().forEach((obj) => {
9650
+ if (!(obj instanceof fabric__namespace.Textbox)) return;
9651
+ const id = getObjectId(obj);
9652
+ if (!id) return;
9653
+ const el = elements.find((e) => e.id === id);
9654
+ if (!el) return;
9655
+ persistTextboxSize(id, { width: obj.width ?? 0, height: obj.height ?? 0 }, el);
9656
+ });
9657
+ }
9658
+ if (preResnapSync) {
9659
+ try {
9660
+ preResnapSync();
9661
+ } catch (e) {
9662
+ console.warn("[canvasReflow] preResnapSync failed:", e);
9663
+ }
9664
+ }
9665
+ if (!pageTree.length) return;
9666
+ try {
9667
+ canvas.getObjects().forEach((obj) => {
9668
+ const id = getObjectId(obj);
9669
+ if (!id) return;
9670
+ const node = findNodeById(pageTree, id);
9671
+ if (!node) return;
9672
+ const abs = getAbsoluteBounds(node, pageTree, pageBoundsOptions);
9673
+ const targetLeft = obj.originX === "center" ? abs.left + abs.width / 2 : obj.originX === "right" ? abs.left + abs.width : abs.left;
9674
+ const targetTop = obj.originY === "center" ? abs.top + abs.height / 2 : obj.originY === "bottom" ? abs.top + abs.height : abs.top;
9675
+ const curLeft = obj.left ?? 0;
9676
+ const curTop = obj.top ?? 0;
9677
+ if (Math.abs(curLeft - targetLeft) > 0.1 || Math.abs(curTop - targetTop) > 0.1) {
9678
+ obj.set({ left: targetLeft, top: targetTop });
9679
+ obj.setCoords();
9680
+ }
9681
+ });
9682
+ canvas.requestRenderAll();
9683
+ } catch (e) {
9684
+ console.warn("[canvasReflow] resnap failed:", e);
9685
+ }
9686
+ }
9630
9687
  const EVT_SHOW_ORIG_TEXT_BOUNDS = "pixldocs:showOriginalTextBoundsChanged";
9631
9688
  function subscribeShowOriginalTextBounds(cb) {
9632
9689
  const handler = (e) => cb(!!e.detail);
@@ -9818,6 +9875,7 @@ const PageCanvas = react.forwardRef(
9818
9875
  });
9819
9876
  const isEditorMode = mode === "editor";
9820
9877
  const isPreviewMode = mode === "preview";
9878
+ const isExportMode = mode === "export";
9821
9879
  const allowEditing = isEditorMode;
9822
9880
  const allowSelection = isEditorMode;
9823
9881
  const allowDynamicFieldClick = isPreviewMode && dynamicFieldIds.length > 0;
@@ -13409,56 +13467,38 @@ const PageCanvas = react.forwardRef(
13409
13467
  var _a2;
13410
13468
  const fc = fabricRef.current;
13411
13469
  if (!fc || cancelled) return;
13412
- clearFontCacheAndRerender(fc, { clearGlobalCharCache: !preserveGlobalFontCache });
13413
13470
  const state = useEditorStore.getState();
13414
- const page = state.canvas.pages.find((p) => p.id === pageId);
13415
- if (page) {
13416
- const elements2 = flattenChildren(page.children);
13417
- fc.getObjects().forEach((obj) => {
13418
- if (obj instanceof fabric__namespace.Textbox) {
13419
- const id = getObjectId(obj);
13420
- if (!id) return;
13421
- const w = obj.width ?? 0;
13422
- const h = obj.height ?? 0;
13423
- const el = elements2.find((e) => e.id === id);
13424
- if (!el) return;
13425
- const storeW = el.width ?? 0;
13426
- const storeH = el.height ?? 0;
13427
- const updates = {};
13428
- const shouldKeepFixedSize = el.overflowPolicy === "auto-shrink";
13429
- if (!shouldKeepFixedSize && w > 0 && typeof storeW === "number" && Math.abs(w - storeW) > 0.1) updates.width = w;
13430
- if (shouldKeepFixedSize) {
13431
- if (h > 0 && typeof storeH === "number" && h < storeH - 0.5) updates.height = h;
13432
- } else {
13433
- if (h > 0 && (typeof storeH !== "number" || Math.abs(h - storeH) > 0.1)) updates.height = h;
13434
- }
13435
- if (Object.keys(updates).length > 0) {
13436
- state.updateElement(id, updates, { recordHistory: false, skipLayoutRecalc: true });
13437
- }
13471
+ const repositionTree = isPreviewMode && (pageChildren == null ? void 0 : pageChildren.length) ? pageChildren ?? [] : ((_a2 = state.canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _a2.children) ?? [];
13472
+ runFontReloadAndReflow({
13473
+ canvas: fc,
13474
+ pageTree: repositionTree,
13475
+ pageBoundsOptions,
13476
+ preserveGlobalFontCache,
13477
+ // Persist measured Textbox sizes back to the editor store. The
13478
+ // headless path passes no callback (it has no store to persist into).
13479
+ persistTextboxSize: (id, measured, el) => {
13480
+ const storeW = el.width ?? 0;
13481
+ const storeH = el.height ?? 0;
13482
+ const shouldKeepFixedSize = el.overflowPolicy === "auto-shrink";
13483
+ const updates = {};
13484
+ if (!shouldKeepFixedSize && measured.width > 0 && typeof storeW === "number" && Math.abs(measured.width - storeW) > 0.1) {
13485
+ updates.width = measured.width;
13438
13486
  }
13439
- });
13440
- }
13441
- try {
13442
- const repositionTree = isPreviewMode && (pageChildren == null ? void 0 : pageChildren.length) ? pageChildren ?? [] : ((_a2 = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _a2.children) ?? [];
13443
- if (repositionTree.length) {
13444
- fc.getObjects().forEach((obj) => {
13445
- const id = getObjectId(obj);
13446
- if (!id) return;
13447
- const node = findNodeById(repositionTree, id);
13448
- if (!node) return;
13449
- const abs = getAbsoluteBounds(node, repositionTree, pageBoundsOptions);
13450
- const curLeft = obj.left ?? 0;
13451
- const curTop = obj.top ?? 0;
13452
- if (Math.abs(curLeft - abs.left) > 0.1 || Math.abs(curTop - abs.top) > 0.1) {
13453
- obj.set({ left: abs.left, top: abs.top });
13454
- obj.setCoords();
13455
- }
13456
- });
13457
- fc.requestRenderAll();
13458
- }
13459
- } catch (e) {
13460
- console.warn("[PageCanvas] post-ready reposition failed:", e);
13461
- }
13487
+ if (shouldKeepFixedSize) {
13488
+ if (measured.height > 0 && typeof storeH === "number" && measured.height < storeH - 0.5) updates.height = measured.height;
13489
+ } else {
13490
+ if (measured.height > 0 && (typeof storeH !== "number" || Math.abs(measured.height - storeH) > 0.1)) updates.height = measured.height;
13491
+ }
13492
+ if (Object.keys(updates).length > 0) {
13493
+ state.updateElement(id, updates, { recordHistory: false, skipLayoutRecalc: true });
13494
+ }
13495
+ },
13496
+ // Rebuild section/background groups before resnapping top-level objects.
13497
+ preResnapSync: (isPreviewMode || isExportMode) && doSyncRef.current ? () => {
13498
+ var _a3;
13499
+ return (_a3 = doSyncRef.current) == null ? void 0 : _a3.call(doSyncRef);
13500
+ } : void 0
13501
+ });
13462
13502
  };
13463
13503
  const raf1 = requestAnimationFrame(() => {
13464
13504
  requestAnimationFrame(() => {
@@ -21016,9 +21056,9 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
21016
21056
  }
21017
21057
  return svgString;
21018
21058
  }
21019
- const resolvedPackageVersion = "0.5.229";
21059
+ const resolvedPackageVersion = "0.5.231";
21020
21060
  const PACKAGE_VERSION = resolvedPackageVersion;
21021
- const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.229";
21061
+ const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.231";
21022
21062
  const roundParityValue = (value) => {
21023
21063
  if (typeof value !== "number") return value;
21024
21064
  return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
@@ -21762,7 +21802,7 @@ class PixldocsRenderer {
21762
21802
  await this.waitForCanvasScene(container, cloned, i);
21763
21803
  }
21764
21804
  console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
21765
- const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-Cfic2O5h.cjs"));
21805
+ const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-Dwv5vpcI.cjs"));
21766
21806
  const prepared = preparePagesForExport(
21767
21807
  cloned.pages,
21768
21808
  canvasWidth,
@@ -24082,7 +24122,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
24082
24122
  if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
24083
24123
  sanitizeSvgTreeForPdf(svgToDraw);
24084
24124
  try {
24085
- const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await Promise.resolve().then(() => require("./vectorPdfExport-Cfic2O5h.cjs"));
24125
+ const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await Promise.resolve().then(() => require("./vectorPdfExport-Dwv5vpcI.cjs"));
24086
24126
  try {
24087
24127
  await logTextMeasurementDiagnostic(svgToDraw);
24088
24128
  } catch {
@@ -24478,4 +24518,4 @@ exports.setAutoShrinkDebug = setAutoShrinkDebug;
24478
24518
  exports.setBundledAssetPrefixes = setBundledAssetPrefixes;
24479
24519
  exports.warmResolvedTemplateForPreview = warmResolvedTemplateForPreview;
24480
24520
  exports.warmTemplateFromForm = warmTemplateFromForm;
24481
- //# sourceMappingURL=index-UL0ZxmJo.cjs.map
24521
+ //# sourceMappingURL=index-BbgFuxwu.cjs.map