@pixldocs/canvas-renderer 0.5.209 → 0.5.211

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.
@@ -4053,6 +4053,11 @@ async function loadImageAsync(element, placeholder, fc, fabricRef, syncLockedRef
4053
4053
  setObjectData(cropGroup, element.id);
4054
4054
  cropGroup.__imageSrc = imageUrl;
4055
4055
  cropGroup.__svgColorMap = nextSvgColorMap;
4056
+ cropGroup.set({
4057
+ flipX: element.flipX ?? false,
4058
+ flipY: element.flipY ?? false
4059
+ });
4060
+ cropGroup.setCoords();
4056
4061
  finalObject = cropGroup;
4057
4062
  } else {
4058
4063
  setObjectData(img, element.id);
@@ -10558,14 +10563,15 @@ const PageCanvas = forwardRef(
10558
10563
  const storePos = absoluteToStorePosition(absoluteLeft, absoluteTop, objId, pageChildrenForSave);
10559
10564
  const isLineObj = obj instanceof fabric.Line;
10560
10565
  const isAutoShrinkText = (sourceElement == null ? void 0 : sourceElement.type) === "text" && sourceElement.overflowPolicy === "auto-shrink";
10561
- const autoShrinkStoredWidth = isAutoShrinkText ? sourceElement.width : void 0;
10562
10566
  const autoShrinkStoredHeight = isAutoShrinkText ? sourceElement.height : void 0;
10563
10567
  const elementUpdate = {
10564
10568
  left: storePos.left,
10565
10569
  top: storePos.top,
10566
- // Auto-shrink: lock width, but let height shrink to actual rendered height for proper stack reflow.
10567
- width: isAutoShrinkText ? autoShrinkStoredWidth ?? finalWidth : finalWidth,
10568
- height: isLineObj ? 0 : isAutoShrinkText ? typeof autoShrinkStoredHeight === "number" ? Math.min(autoShrinkStoredHeight, finalHeight) : finalHeight : finalHeight,
10570
+ // Auto-shrink: persist width from the user-driven resize handles (ml/mr/corners).
10571
+ // Fabric's Textbox 'resizing' event updates obj.width directly with scaleX=1,
10572
+ // so finalWidth already reflects the new width chosen by the user.
10573
+ width: finalWidth,
10574
+ height: isLineObj ? 0 : isAutoShrinkText ? typeof autoShrinkStoredHeight === "number" ? autoShrinkStoredHeight : finalHeight : finalHeight,
10569
10575
  angle: decomposed.angle,
10570
10576
  skewX: isLineObj ? 0 : decomposed.skewX,
10571
10577
  skewY: isLineObj ? 0 : decomposed.skewY,
@@ -18946,9 +18952,9 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
18946
18952
  }
18947
18953
  return svgString;
18948
18954
  }
18949
- const resolvedPackageVersion = "0.5.209";
18955
+ const resolvedPackageVersion = "0.5.211";
18950
18956
  const PACKAGE_VERSION = resolvedPackageVersion;
18951
- const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.209";
18957
+ const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.211";
18952
18958
  const roundParityValue = (value) => {
18953
18959
  if (typeof value !== "number") return value;
18954
18960
  return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
@@ -19008,7 +19014,7 @@ function detectSafariOrIos() {
19008
19014
  return false;
19009
19015
  }
19010
19016
  }
19011
- async function downscaleConfigRasterImages(config, maxEdgePx, maxDataUrlBytes = 2e6) {
19017
+ async function downscaleConfigRasterImages(config, maxEdgePx, maxDataUrlBytes = 2e6, jpegQuality = 0.85) {
19012
19018
  if (!maxEdgePx || maxEdgePx <= 0) return 0;
19013
19019
  if (typeof document === "undefined") return 0;
19014
19020
  const targets = [];
@@ -19072,7 +19078,7 @@ async function downscaleConfigRasterImages(config, maxEdgePx, maxDataUrlBytes =
19072
19078
  return null;
19073
19079
  }
19074
19080
  let scale = tooLargeByEdge ? maxEdgePx / longest : 1;
19075
- let quality = 0.85;
19081
+ let quality = Math.max(0.4, Math.min(1, jpegQuality));
19076
19082
  let best = null;
19077
19083
  for (let attempt = 0; attempt < 4; attempt++) {
19078
19084
  const tw = Math.max(1, Math.round(w * scale));
@@ -19096,7 +19102,7 @@ async function downscaleConfigRasterImages(config, maxEdgePx, maxDataUrlBytes =
19096
19102
  }
19097
19103
  const byteScale = Math.sqrt(maxDataUrlBytes / Math.max(1, outBytes)) * 0.92;
19098
19104
  scale = Math.max(0.1, scale * Math.min(0.95, byteScale));
19099
- quality = Math.max(0.68, quality - 0.06);
19105
+ quality = Math.max(0.4, quality - 0.06);
19100
19106
  }
19101
19107
  if (blobUrl) URL.revokeObjectURL(blobUrl);
19102
19108
  return best;
@@ -19471,7 +19477,9 @@ class PixldocsRenderer {
19471
19477
  title: options == null ? void 0 : options.title,
19472
19478
  textMode: options == null ? void 0 : options.textMode,
19473
19479
  forcePerElementPdf: options == null ? void 0 : options.forcePerElementPdf,
19474
- maxImageEdgePx: options == null ? void 0 : options.maxImageEdgePx
19480
+ maxImageEdgePx: options == null ? void 0 : options.maxImageEdgePx,
19481
+ compressImages: options == null ? void 0 : options.compressImages,
19482
+ compressionQuality: options == null ? void 0 : options.compressionQuality
19475
19483
  });
19476
19484
  }
19477
19485
  /**
@@ -19479,7 +19487,7 @@ class PixldocsRenderer {
19479
19487
  * This is the primary PDF export API — mirrors renderFromForm() but returns a PDF.
19480
19488
  */
19481
19489
  async renderPdfFromForm(options) {
19482
- const { templateId, formSchemaId, sectionState, themeId, watermark, watermarkOptions, prefetched, title, fontBaseUrl, textMode, forcePerElementPdf, maxImageEdgePx } = options;
19490
+ const { templateId, formSchemaId, sectionState, themeId, watermark, watermarkOptions, prefetched, title, fontBaseUrl, textMode, forcePerElementPdf, maxImageEdgePx, compressImages, compressionQuality } = options;
19483
19491
  const resolved = await resolveFromForm({
19484
19492
  templateId,
19485
19493
  formSchemaId,
@@ -19502,7 +19510,9 @@ class PixldocsRenderer {
19502
19510
  watermark: shouldWatermark,
19503
19511
  textMode,
19504
19512
  forcePerElementPdf,
19505
- maxImageEdgePx
19513
+ maxImageEdgePx,
19514
+ compressImages,
19515
+ compressionQuality
19506
19516
  });
19507
19517
  }
19508
19518
  async renderById(templateId, formData, options) {
@@ -19549,13 +19559,20 @@ class PixldocsRenderer {
19549
19559
  const hasUserDataImage = configHasUserDataImage(cloned);
19550
19560
  const isSafariLike = detectSafariOrIos();
19551
19561
  const shouldForcePerElement = forceMode === true ? true : forceMode === false ? false : false;
19562
+ const compressImagesOpt = options.compressImages ?? true;
19552
19563
  const maxEdgeOpt = options.maxImageEdgePx ?? this.config.maxImageEdgePx;
19553
- const effectiveMaxEdge = typeof maxEdgeOpt === "number" ? Math.max(0, maxEdgeOpt | 0) : hasUserDataImage ? 2048 : 0;
19564
+ const effectiveMaxEdge = typeof maxEdgeOpt === "number" ? Math.max(0, maxEdgeOpt | 0) : compressImagesOpt ? hasUserDataImage ? 2048 : 0 : 0;
19565
+ const downscaleQuality = compressImagesOpt ? typeof options.compressionQuality === "number" ? Math.max(0.4, Math.min(1, options.compressionQuality)) : 0.85 : 0.95;
19554
19566
  if (effectiveMaxEdge > 0) {
19555
19567
  try {
19556
- const downscaled = await downscaleConfigRasterImages(cloned, effectiveMaxEdge);
19568
+ const downscaled = await downscaleConfigRasterImages(
19569
+ cloned,
19570
+ effectiveMaxEdge,
19571
+ void 0,
19572
+ downscaleQuality
19573
+ );
19557
19574
  if (downscaled > 0) {
19558
- console.log(`[canvas-renderer][pdf-unified] downscaled ${downscaled} raster image(s) to <=${effectiveMaxEdge}px edge`);
19575
+ console.log(`[canvas-renderer][pdf-unified] downscaled ${downscaled} raster image(s) to <=${effectiveMaxEdge}px edge @ q=${downscaleQuality}`);
19559
19576
  }
19560
19577
  } catch (e) {
19561
19578
  console.warn("[canvas-renderer][pdf-unified] image downscale pass failed (continuing with originals):", e);
@@ -19566,7 +19583,9 @@ class PixldocsRenderer {
19566
19583
  hasUserDataImage,
19567
19584
  isSafariLike,
19568
19585
  shouldForcePerElement,
19569
- effectiveMaxEdge
19586
+ effectiveMaxEdge,
19587
+ compressImages: compressImagesOpt,
19588
+ downscaleQuality
19570
19589
  });
19571
19590
  const stampPrefix = `__pixldocs_pdf_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
19572
19591
  const pageIds = cloned.pages.map((p, i) => {
@@ -19627,7 +19646,7 @@ class PixldocsRenderer {
19627
19646
  await this.waitForCanvasScene(container, cloned, i);
19628
19647
  }
19629
19648
  console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
19630
- const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-C0GsER0C.js");
19649
+ const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-BEGl71uB.js");
19631
19650
  const prepared = preparePagesForExport(
19632
19651
  cloned.pages,
19633
19652
  canvasWidth,
@@ -19644,7 +19663,9 @@ class PixldocsRenderer {
19644
19663
  // path and use the live Fabric object PDF path instead, preserving live
19645
19664
  // matrices/order so we do not regress into stale config-space layout.
19646
19665
  skipLiveCanvasSvgFastPath: forceMode === true,
19647
- useLiveCanvasObjectPdfPath: shouldForcePerElement && forceMode !== true
19666
+ useLiveCanvasObjectPdfPath: shouldForcePerElement && forceMode !== true,
19667
+ compressImages: options.compressImages ?? true,
19668
+ compressionQuality: options.compressionQuality
19648
19669
  });
19649
19670
  if (!result || typeof result === "undefined") {
19650
19671
  throw new Error("exportMultiPagePdf returned no blob (returnBlob path failed)");
@@ -21811,7 +21832,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
21811
21832
  if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
21812
21833
  sanitizeSvgTreeForPdf(svgToDraw);
21813
21834
  try {
21814
- const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await import("./vectorPdfExport-C0GsER0C.js");
21835
+ const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await import("./vectorPdfExport-BEGl71uB.js");
21815
21836
  try {
21816
21837
  await logTextMeasurementDiagnostic(svgToDraw);
21817
21838
  } catch {
@@ -22211,4 +22232,4 @@ export {
22211
22232
  buildTeaserBlurFlatKeys as y,
22212
22233
  collectFontDescriptorsFromConfig as z
22213
22234
  };
22214
- //# sourceMappingURL=index-DOIdbh-Q.js.map
22235
+ //# sourceMappingURL=index-C0tTvSFQ.js.map