@pixldocs/canvas-renderer 0.5.27 → 0.5.29

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.
package/dist/index.js CHANGED
@@ -2571,6 +2571,10 @@ async function _doLoadGoogleFont(fontFamily, weights) {
2571
2571
  return false;
2572
2572
  }
2573
2573
  }
2574
+ const getObjectId = (obj) => obj.__docuforgeId;
2575
+ const setObjectData = (obj, id) => {
2576
+ obj.__docuforgeId = id;
2577
+ };
2574
2578
  const FONTS_TO_PRELOAD = [
2575
2579
  "Open Sans",
2576
2580
  "Playfair Display",
@@ -2710,6 +2714,42 @@ const clearFabricCharCache = () => {
2710
2714
  };
2711
2715
  const clearFontCacheAndRerender = (canvas) => {
2712
2716
  clearFabricCharCache();
2717
+ const logUnderlineDebug = (stage, payload) => {
2718
+ try {
2719
+ console.log(`[canvas-renderer][underline-debug] ${stage} ${JSON.stringify(payload)}`);
2720
+ } catch {
2721
+ console.log("[canvas-renderer][underline-debug]", stage, payload);
2722
+ }
2723
+ };
2724
+ const collectUnderlineMetrics = (obj) => {
2725
+ var _a, _b;
2726
+ if (obj instanceof fabric.Textbox) {
2727
+ if (!obj.underline) return [];
2728
+ const lineWidths = obj.__lineWidths;
2729
+ return [{
2730
+ id: getObjectId(obj) ?? null,
2731
+ text: (obj.text || "").slice(0, 120),
2732
+ textLength: ((_a = obj.text) == null ? void 0 : _a.length) ?? 0,
2733
+ fontFamily: obj.fontFamily,
2734
+ fontSize: obj.fontSize,
2735
+ fontWeight: obj.fontWeight,
2736
+ width: obj.width ?? null,
2737
+ height: obj.height ?? null,
2738
+ scaleX: obj.scaleX,
2739
+ scaleY: obj.scaleY,
2740
+ lineCount: ((_b = obj.textLines) == null ? void 0 : _b.length) ?? 0,
2741
+ maxLineWidth: lineWidths && lineWidths.length > 0 ? Math.max(...lineWidths) : null
2742
+ }];
2743
+ }
2744
+ if (obj instanceof fabric.Group) {
2745
+ return (obj._objects || []).flatMap((child) => collectUnderlineMetrics(child));
2746
+ }
2747
+ return [];
2748
+ };
2749
+ const beforeMetrics = canvas.getObjects().flatMap(collectUnderlineMetrics);
2750
+ if (beforeMetrics.length > 0) {
2751
+ logUnderlineDebug("before-rerender", beforeMetrics);
2752
+ }
2713
2753
  const resetTextboxLayoutInternals = (obj) => {
2714
2754
  var _a;
2715
2755
  (_a = obj._clearCache) == null ? void 0 : _a.call(obj);
@@ -2724,7 +2764,7 @@ const clearFontCacheAndRerender = (canvas) => {
2724
2764
  obj.dirty = true;
2725
2765
  };
2726
2766
  const fixTextbox = (obj) => {
2727
- var _a, _b;
2767
+ var _a, _b, _c;
2728
2768
  if (obj instanceof fabric.Textbox) {
2729
2769
  const savedWidth = obj.width;
2730
2770
  const savedScaleX = obj.scaleX;
@@ -2737,15 +2777,35 @@ const clearFontCacheAndRerender = (canvas) => {
2737
2777
  obj.initDimensions();
2738
2778
  obj.set({ width: savedWidth, scaleX: savedScaleX, scaleY: savedScaleY, dirty: true });
2739
2779
  }
2740
- (_a = obj._clearCache) == null ? void 0 : _a.call(obj);
2780
+ if (obj.underline) {
2781
+ const lineWidths = obj.__lineWidths;
2782
+ logUnderlineDebug("textbox-rerender", {
2783
+ id: getObjectId(obj) ?? null,
2784
+ text: (obj.text || "").slice(0, 120),
2785
+ fontFamily: obj.fontFamily,
2786
+ fontSize: obj.fontSize,
2787
+ savedWidth,
2788
+ finalWidth: obj.width ?? null,
2789
+ finalHeight: obj.height ?? null,
2790
+ scaleX: obj.scaleX,
2791
+ scaleY: obj.scaleY,
2792
+ lineCount: ((_a = obj.textLines) == null ? void 0 : _a.length) ?? 0,
2793
+ maxLineWidth: lineWidths && lineWidths.length > 0 ? Math.max(...lineWidths) : null
2794
+ });
2795
+ }
2796
+ (_b = obj._clearCache) == null ? void 0 : _b.call(obj);
2741
2797
  obj.setCoords();
2742
2798
  } else if (obj instanceof fabric.Group) {
2743
- (_b = obj._objects) == null ? void 0 : _b.forEach(fixTextbox);
2799
+ (_c = obj._objects) == null ? void 0 : _c.forEach(fixTextbox);
2744
2800
  obj.dirty = true;
2745
2801
  obj.setCoords();
2746
2802
  }
2747
2803
  };
2748
2804
  canvas.getObjects().forEach(fixTextbox);
2805
+ const afterMetrics = canvas.getObjects().flatMap(collectUnderlineMetrics);
2806
+ if (afterMetrics.length > 0) {
2807
+ logUnderlineDebug("after-rerender", afterMetrics);
2808
+ }
2749
2809
  canvas.requestRenderAll();
2750
2810
  };
2751
2811
  const ensureFontLoaded = async (fontFamily) => {
@@ -2783,10 +2843,6 @@ const setupFontLoadingListener = (canvas, afterRerender) => {
2783
2843
  };
2784
2844
  };
2785
2845
  preloadAllFonts();
2786
- const getObjectId = (obj) => obj.__docuforgeId;
2787
- const setObjectData = (obj, id) => {
2788
- obj.__docuforgeId = id;
2789
- };
2790
2846
  const svgTextCache = /* @__PURE__ */ new Map();
2791
2847
  const htmlImageCache = /* @__PURE__ */ new Map();
2792
2848
  const MAX_CACHE_ENTRIES = 200;
@@ -11844,6 +11900,21 @@ async function ensureFontsForResolvedConfig(config) {
11844
11900
  });
11845
11901
  }
11846
11902
  }
11903
+ const PREVIEW_DEBUG_PREFIX = "[canvas-renderer][preview-debug]";
11904
+ function countUnderlinedNodes(config) {
11905
+ var _a;
11906
+ if (!((_a = config == null ? void 0 : config.pages) == null ? void 0 : _a.length)) return 0;
11907
+ let count = 0;
11908
+ const walk = (nodes) => {
11909
+ var _a2;
11910
+ for (const node of nodes || []) {
11911
+ if (node == null ? void 0 : node.underline) count += 1;
11912
+ if ((_a2 = node == null ? void 0 : node.children) == null ? void 0 : _a2.length) walk(node.children);
11913
+ }
11914
+ };
11915
+ for (const page of config.pages) walk(page.children || []);
11916
+ return count;
11917
+ }
11847
11918
  function PixldocsPreview(props) {
11848
11919
  const {
11849
11920
  pageIndex = 0,
@@ -11871,6 +11942,7 @@ function PixldocsPreview(props) {
11871
11942
  if (!isResolveMode) {
11872
11943
  setResolvedConfig(null);
11873
11944
  setCanvasSettled(false);
11945
+ console.log(PREVIEW_DEBUG_PREFIX, "config-mode active");
11874
11946
  return;
11875
11947
  }
11876
11948
  const p = props;
@@ -11879,6 +11951,12 @@ function PixldocsPreview(props) {
11879
11951
  setIsLoading(true);
11880
11952
  setFontsReady(false);
11881
11953
  setCanvasSettled(false);
11954
+ console.log(PREVIEW_DEBUG_PREFIX, "resolve-start", {
11955
+ templateId: p.templateId,
11956
+ formSchemaId: p.formSchemaId,
11957
+ themeId: p.themeId ?? null,
11958
+ pageIndex
11959
+ });
11882
11960
  resolveFromForm({
11883
11961
  templateId: p.templateId,
11884
11962
  formSchemaId: p.formSchemaId,
@@ -11887,15 +11965,22 @@ function PixldocsPreview(props) {
11887
11965
  supabaseUrl: p.supabaseUrl,
11888
11966
  supabaseAnonKey: p.supabaseAnonKey
11889
11967
  }).then((resolved) => {
11968
+ var _a, _b;
11890
11969
  if (!cancelled) {
11970
+ console.log(PREVIEW_DEBUG_PREFIX, "resolve-done", {
11971
+ pages: ((_b = (_a = resolved.config) == null ? void 0 : _a.pages) == null ? void 0 : _b.length) ?? 0,
11972
+ underlinedNodes: countUnderlinedNodes(resolved.config)
11973
+ });
11891
11974
  setResolvedConfig(resolved.config);
11892
11975
  ensureFontsForResolvedConfig(resolved.config).then(() => {
11893
11976
  if (!cancelled) {
11977
+ console.log(PREVIEW_DEBUG_PREFIX, "resolve-mode fonts queued");
11894
11978
  setFontsReady(true);
11895
11979
  setIsLoading(false);
11896
11980
  }
11897
- }).catch(() => {
11981
+ }).catch((err) => {
11898
11982
  if (!cancelled) {
11983
+ console.warn(PREVIEW_DEBUG_PREFIX, "resolve-mode fonts queue failed", err);
11899
11984
  setFontsReady(true);
11900
11985
  setIsLoading(false);
11901
11986
  }
@@ -11904,6 +11989,7 @@ function PixldocsPreview(props) {
11904
11989
  }).catch((err) => {
11905
11990
  if (!cancelled) {
11906
11991
  setIsLoading(false);
11992
+ console.warn(PREVIEW_DEBUG_PREFIX, "resolve-error", err);
11907
11993
  onError == null ? void 0 : onError(err instanceof Error ? err : new Error(String(err)));
11908
11994
  }
11909
11995
  });
@@ -11920,18 +12006,28 @@ function PixldocsPreview(props) {
11920
12006
  ]);
11921
12007
  const config = isResolveMode ? resolvedConfig : props.config;
11922
12008
  useEffect(() => {
11923
- var _a, _b;
12009
+ var _a, _b, _c;
11924
12010
  if (!config) return;
11925
12011
  let cancelled = false;
11926
12012
  setCanvasSettled(false);
11927
12013
  setStabilizationPass(0);
12014
+ console.log(PREVIEW_DEBUG_PREFIX, "config-changed", {
12015
+ pageIndex,
12016
+ pages: ((_a = config.pages) == null ? void 0 : _a.length) ?? 0,
12017
+ underlinedNodes: countUnderlinedNodes(config),
12018
+ isResolveMode
12019
+ });
11928
12020
  const bump = () => {
11929
12021
  if (cancelled) return;
11930
12022
  clearMeasurementCache();
11931
12023
  clearFabricCharCache();
11932
- setFontsReadyVersion((v) => v + 1);
12024
+ setFontsReadyVersion((v) => {
12025
+ const next = v + 1;
12026
+ console.log(PREVIEW_DEBUG_PREFIX, "font-bump", { pageIndex, next, stabilizationPass });
12027
+ return next;
12028
+ });
11933
12029
  };
11934
- (_b = (_a = document.fonts) == null ? void 0 : _a.ready) == null ? void 0 : _b.then(bump);
12030
+ (_c = (_b = document.fonts) == null ? void 0 : _b.ready) == null ? void 0 : _c.then(bump);
11935
12031
  const timeoutId = window.setTimeout(bump, 350);
11936
12032
  return () => {
11937
12033
  cancelled = true;
@@ -11953,17 +12049,28 @@ function PixldocsPreview(props) {
11953
12049
  setFontsReady(false);
11954
12050
  setCanvasSettled(false);
11955
12051
  setStabilizationPass(0);
11956
- ensureFontsForResolvedConfig(config).then(() => setFontsReady(true)).catch(() => setFontsReady(true));
12052
+ ensureFontsForResolvedConfig(config).then(() => {
12053
+ console.log(PREVIEW_DEBUG_PREFIX, "config-mode fonts queued", {
12054
+ pageIndex,
12055
+ underlinedNodes: countUnderlinedNodes(config)
12056
+ });
12057
+ setFontsReady(true);
12058
+ }).catch((err) => {
12059
+ console.warn(PREVIEW_DEBUG_PREFIX, "config-mode fonts queue failed", err);
12060
+ setFontsReady(true);
12061
+ });
11957
12062
  }, [isResolveMode, config]);
11958
12063
  const handleCanvasReady = useCallback(() => {
11959
12064
  if (stabilizationPass === 0) {
12065
+ console.log(PREVIEW_DEBUG_PREFIX, "canvas-ready-pass", { pageIndex, stabilizationPass, action: "stabilize-again" });
11960
12066
  setCanvasSettled(false);
11961
12067
  setStabilizationPass(1);
11962
12068
  return;
11963
12069
  }
12070
+ console.log(PREVIEW_DEBUG_PREFIX, "canvas-ready-pass", { pageIndex, stabilizationPass, action: "settled" });
11964
12071
  setCanvasSettled(true);
11965
12072
  onReady == null ? void 0 : onReady();
11966
- }, [onReady, stabilizationPass]);
12073
+ }, [onReady, pageIndex, stabilizationPass]);
11967
12074
  if (isLoading) {
11968
12075
  return /* @__PURE__ */ jsx("div", { className, style: { ...style, display: "flex", alignItems: "center", justifyContent: "center", minHeight: 200 }, children: /* @__PURE__ */ jsx("div", { style: { color: "#888", fontSize: 14 }, children: "Loading preview..." }) });
11969
12076
  }