@pixldocs/canvas-renderer 0.5.174 → 0.5.176

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.
@@ -3224,8 +3224,8 @@ const clearFabricCharCache = () => {
3224
3224
  fabric__namespace.util.clearFabricFontCache();
3225
3225
  }
3226
3226
  };
3227
- const clearFontCacheAndRerender = (canvas) => {
3228
- clearFabricCharCache();
3227
+ const clearFontCacheAndRerender = (canvas, options = {}) => {
3228
+ if (options.clearGlobalCharCache !== false) clearFabricCharCache();
3229
3229
  const logUnderlineDebug = (stage, payload) => {
3230
3230
  try {
3231
3231
  console.log(`[canvas-renderer][underline-debug] ${stage} ${JSON.stringify(payload)}`);
@@ -3316,9 +3316,9 @@ const ensureFontLoaded = async (fontFamily) => {
3316
3316
  } catch {
3317
3317
  }
3318
3318
  };
3319
- const setupFontLoadingListener = (canvas, afterRerender) => {
3319
+ const setupFontLoadingListener = (canvas, afterRerender, options = {}) => {
3320
3320
  const handleFontLoad = () => {
3321
- clearFontCacheAndRerender(canvas);
3321
+ clearFontCacheAndRerender(canvas, options);
3322
3322
  afterRerender == null ? void 0 : afterRerender(canvas);
3323
3323
  };
3324
3324
  if (document.fonts) {
@@ -7378,6 +7378,7 @@ const PageCanvas = react.forwardRef(
7378
7378
  canvasUpdateVersion = 0,
7379
7379
  pageChildren,
7380
7380
  skipFontReadyWait = false,
7381
+ preserveGlobalFontCache = false,
7381
7382
  onReady
7382
7383
  }, ref) => {
7383
7384
  setMarkdownThemeColors({
@@ -7743,7 +7744,7 @@ const PageCanvas = react.forwardRef(
7743
7744
  await waitUntilFontsAvailable(fontFamilies, { timeoutMs: 3500, pollIntervalMs: 60 });
7744
7745
  await new Promise((r) => requestAnimationFrame(() => r()));
7745
7746
  }
7746
- clearFabricCharCache();
7747
+ if (!preserveGlobalFontCache) clearFabricCharCache();
7747
7748
  clearMeasurementCache();
7748
7749
  setReady(true);
7749
7750
  } catch (e) {
@@ -7782,7 +7783,11 @@ const PageCanvas = react.forwardRef(
7782
7783
  }
7783
7784
  });
7784
7785
  };
7785
- const fontCleanup = setupFontLoadingListener(fabricCanvas, persistTextDimensionsAfterFontLoad);
7786
+ const fontCleanup = setupFontLoadingListener(
7787
+ fabricCanvas,
7788
+ persistTextDimensionsAfterFontLoad,
7789
+ { clearGlobalCharCache: !preserveGlobalFontCache }
7790
+ );
7786
7791
  fabricCanvas.__fontCleanup = fontCleanup;
7787
7792
  fabricCanvas.__isUserTransforming = false;
7788
7793
  fabricCanvas.on("mouse:down", () => {
@@ -9782,7 +9787,7 @@ const PageCanvas = react.forwardRef(
9782
9787
  pendingSyncRef.current = false;
9783
9788
  if (ready && !hasClearedCachesBeforeFirstSyncRef.current) {
9784
9789
  hasClearedCachesBeforeFirstSyncRef.current = true;
9785
- clearFabricCharCache();
9790
+ if (!preserveGlobalFontCache) clearFabricCharCache();
9786
9791
  clearMeasurementCache();
9787
9792
  }
9788
9793
  doSyncRef.current();
@@ -9866,7 +9871,7 @@ const PageCanvas = react.forwardRef(
9866
9871
  const runReflowAndPersist = () => {
9867
9872
  const fc = fabricRef.current;
9868
9873
  if (!fc || cancelled) return;
9869
- clearFontCacheAndRerender(fc);
9874
+ clearFontCacheAndRerender(fc, { clearGlobalCharCache: !preserveGlobalFontCache });
9870
9875
  const state = useEditorStore.getState();
9871
9876
  const page = state.canvas.pages.find((p) => p.id === pageId);
9872
9877
  if (page) {
@@ -11443,6 +11448,7 @@ function PreviewCanvas({
11443
11448
  zoom = 1,
11444
11449
  absoluteZoom = false,
11445
11450
  skipFontReadyWait = false,
11451
+ preserveGlobalFontCache = false,
11446
11452
  pageIdOverride,
11447
11453
  className,
11448
11454
  onDynamicFieldClick,
@@ -11605,6 +11611,7 @@ function PreviewCanvas({
11605
11611
  activeTool: "select",
11606
11612
  mode: "preview",
11607
11613
  skipFontReadyWait,
11614
+ preserveGlobalFontCache,
11608
11615
  dynamicFieldIds,
11609
11616
  onDynamicFieldClick: handleDynamicFieldClick,
11610
11617
  onReady
@@ -16349,9 +16356,9 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
16349
16356
  }
16350
16357
  return svgString;
16351
16358
  }
16352
- const resolvedPackageVersion = "0.5.174";
16359
+ const resolvedPackageVersion = "0.5.176";
16353
16360
  const PACKAGE_VERSION = resolvedPackageVersion;
16354
- const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.174";
16361
+ const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.176";
16355
16362
  const roundParityValue = (value) => {
16356
16363
  if (typeof value !== "number") return value;
16357
16364
  return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
@@ -16838,6 +16845,7 @@ class PixldocsRenderer {
16838
16845
  zoom: 1,
16839
16846
  absoluteZoom: true,
16840
16847
  skipFontReadyWait: false,
16848
+ preserveGlobalFontCache: true,
16841
16849
  onReady: () => {
16842
16850
  clearTimeout(timer);
16843
16851
  resolve();
@@ -16848,11 +16856,11 @@ class PixldocsRenderer {
16848
16856
  await this.waitForCanvasScene(container, cloned, i);
16849
16857
  const expected = this.getExpectedImageCount(cloned, i);
16850
16858
  await this.waitForCanvasImages(container, expected);
16851
- await this.waitForStableTextMetrics(container, cloned);
16859
+ await this.waitForStableTextMetrics(container, cloned, { clearGlobalCharCache: false });
16852
16860
  await this.waitForCanvasScene(container, cloned, i);
16853
16861
  }
16854
16862
  console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
16855
- const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-wyGn4ybk.cjs"));
16863
+ const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-CZWsOCqF.cjs"));
16856
16864
  const prepared = preparePagesForExport(
16857
16865
  cloned.pages,
16858
16866
  canvasWidth,
@@ -17235,6 +17243,7 @@ class PixldocsRenderer {
17235
17243
  zoom: pixelRatio,
17236
17244
  absoluteZoom: true,
17237
17245
  skipFontReadyWait: false,
17246
+ preserveGlobalFontCache: true,
17238
17247
  onReady: onReadyOnce
17239
17248
  })
17240
17249
  );
@@ -17295,6 +17304,7 @@ class PixldocsRenderer {
17295
17304
  zoom: pixelRatio,
17296
17305
  absoluteZoom: true,
17297
17306
  skipFontReadyWait: false,
17307
+ preserveGlobalFontCache: true,
17298
17308
  onReady
17299
17309
  })
17300
17310
  );
@@ -17346,6 +17356,7 @@ class PixldocsRenderer {
17346
17356
  zoom: 1,
17347
17357
  absoluteZoom: true,
17348
17358
  skipFontReadyWait: false,
17359
+ preserveGlobalFontCache: true,
17349
17360
  onReady: readyHandler
17350
17361
  })
17351
17362
  );
@@ -17491,7 +17502,7 @@ class PixldocsRenderer {
17491
17502
  (_a = fabricInstance == null ? void 0 : fabricInstance.getObjects) == null ? void 0 : _a.call(fabricInstance).forEach((obj) => visit(obj));
17492
17503
  logJsonLine("[canvas-renderer][fabric-text-parity]", { stage, textboxes: sample.length, sample });
17493
17504
  }
17494
- async waitForStableTextMetrics(container, config) {
17505
+ async waitForStableTextMetrics(container, config, options = {}) {
17495
17506
  var _a, _b, _c;
17496
17507
  if (typeof document !== "undefined") {
17497
17508
  void ensureFontsForResolvedConfig(config);
@@ -17526,9 +17537,11 @@ class PixldocsRenderer {
17526
17537
  obj.dirty = true;
17527
17538
  }
17528
17539
  };
17529
- try {
17530
- clearFabricCharCache();
17531
- } catch {
17540
+ if (options.clearGlobalCharCache !== false) {
17541
+ try {
17542
+ clearFabricCharCache();
17543
+ } catch {
17544
+ }
17532
17545
  }
17533
17546
  fabricInstance.getObjects().forEach(primeCharBounds);
17534
17547
  (_a = fabricInstance.calcOffset) == null ? void 0 : _a.call(fabricInstance);
@@ -18988,7 +19001,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
18988
19001
  if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
18989
19002
  sanitizeSvgTreeForPdf(svgToDraw);
18990
19003
  try {
18991
- const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await Promise.resolve().then(() => require("./vectorPdfExport-wyGn4ybk.cjs"));
19004
+ const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await Promise.resolve().then(() => require("./vectorPdfExport-CZWsOCqF.cjs"));
18992
19005
  try {
18993
19006
  await logTextMeasurementDiagnostic(svgToDraw);
18994
19007
  } catch {
@@ -19110,8 +19123,6 @@ async function assemblePdfFromSvgs(svgResults, options = {}) {
19110
19123
  drawPageBackground(pdf, i, page.width, page.height, page.backgroundColor, page.backgroundGradient);
19111
19124
  const shouldStripBg = stripPageBackground ?? hasGradient;
19112
19125
  const textMode = options.textMode ?? (options.outlineText === true ? "pixel-perfect" : "selectable");
19113
- const shouldOutlineText = textMode === "pixel-perfect" || textMode === "auto";
19114
- const outlineSubMode = textMode === "auto" ? "complex-only" : "all";
19115
19126
  let pageSvg = page.svg;
19116
19127
  try {
19117
19128
  pageSvg = await convertSvgTextDecorationsToLinesString(pageSvg);
@@ -19121,30 +19132,15 @@ async function assemblePdfFromSvgs(svgResults, options = {}) {
19121
19132
  underlineErr
19122
19133
  );
19123
19134
  }
19124
- if (shouldOutlineText) {
19125
- try {
19126
- const { convertAllTextToPath } = await Promise.resolve().then(() => require("./svgTextToPath-BLk_mcqi.cjs"));
19127
- pageSvg = await convertAllTextToPath(pageSvg, fontBaseUrl, { mode: outlineSubMode });
19128
- try {
19129
- dumpSvgTextDiagnostics(pageSvg, i, PARITY_TAG, "STAGE-1b-after-text-to-path-raw");
19130
- } catch {
19131
- }
19132
- } catch (outlineErr) {
19133
- console.warn(
19134
- "[canvas-renderer][pdf] raw-stage text outlining unavailable, falling back to embedded SVG text:",
19135
- outlineErr
19136
- );
19137
- }
19138
- } else {
19135
+ try {
19136
+ const { prepareSvgTextForPdfMode } = await Promise.resolve().then(() => require("./svgTextToPath-hYM9qTeC.cjs"));
19137
+ pageSvg = await prepareSvgTextForPdfMode(pageSvg, textMode, fontBaseUrl);
19139
19138
  try {
19140
- const { replaceGradientTextFillsWithFirstStop } = await Promise.resolve().then(() => require("./svgTextToPath-BLk_mcqi.cjs"));
19141
- pageSvg = replaceGradientTextFillsWithFirstStop(pageSvg);
19142
- } catch (gradErr) {
19143
- console.warn(
19144
- "[canvas-renderer][pdf] gradient-text fill resolution failed:",
19145
- gradErr
19146
- );
19139
+ dumpSvgTextDiagnostics(pageSvg, i, PARITY_TAG, "STAGE-1b-after-shared-text-prep");
19140
+ } catch {
19147
19141
  }
19142
+ } catch (textPrepErr) {
19143
+ console.warn("[canvas-renderer][pdf] shared text prep failed:", textPrepErr);
19148
19144
  }
19149
19145
  let processedSvg = await prepareLiveCanvasSvgForPdf(pageSvg, page.width, page.height, `page-${i + 1}`, {
19150
19146
  stripPageBackground: shouldStripBg
@@ -19398,4 +19394,4 @@ exports.setAutoShrinkDebug = setAutoShrinkDebug;
19398
19394
  exports.setBundledAssetPrefixes = setBundledAssetPrefixes;
19399
19395
  exports.warmResolvedTemplateForPreview = warmResolvedTemplateForPreview;
19400
19396
  exports.warmTemplateFromForm = warmTemplateFromForm;
19401
- //# sourceMappingURL=index-BH1kJLpb.cjs.map
19397
+ //# sourceMappingURL=index-DSe1eOVD.cjs.map