@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.
@@ -4071,6 +4071,11 @@ async function loadImageAsync(element, placeholder, fc, fabricRef, syncLockedRef
4071
4071
  setObjectData(cropGroup, element.id);
4072
4072
  cropGroup.__imageSrc = imageUrl;
4073
4073
  cropGroup.__svgColorMap = nextSvgColorMap;
4074
+ cropGroup.set({
4075
+ flipX: element.flipX ?? false,
4076
+ flipY: element.flipY ?? false
4077
+ });
4078
+ cropGroup.setCoords();
4074
4079
  finalObject = cropGroup;
4075
4080
  } else {
4076
4081
  setObjectData(img, element.id);
@@ -10576,14 +10581,15 @@ const PageCanvas = react.forwardRef(
10576
10581
  const storePos = absoluteToStorePosition(absoluteLeft, absoluteTop, objId, pageChildrenForSave);
10577
10582
  const isLineObj = obj instanceof fabric__namespace.Line;
10578
10583
  const isAutoShrinkText = (sourceElement == null ? void 0 : sourceElement.type) === "text" && sourceElement.overflowPolicy === "auto-shrink";
10579
- const autoShrinkStoredWidth = isAutoShrinkText ? sourceElement.width : void 0;
10580
10584
  const autoShrinkStoredHeight = isAutoShrinkText ? sourceElement.height : void 0;
10581
10585
  const elementUpdate = {
10582
10586
  left: storePos.left,
10583
10587
  top: storePos.top,
10584
- // Auto-shrink: lock width, but let height shrink to actual rendered height for proper stack reflow.
10585
- width: isAutoShrinkText ? autoShrinkStoredWidth ?? finalWidth : finalWidth,
10586
- height: isLineObj ? 0 : isAutoShrinkText ? typeof autoShrinkStoredHeight === "number" ? Math.min(autoShrinkStoredHeight, finalHeight) : finalHeight : finalHeight,
10588
+ // Auto-shrink: persist width from the user-driven resize handles (ml/mr/corners).
10589
+ // Fabric's Textbox 'resizing' event updates obj.width directly with scaleX=1,
10590
+ // so finalWidth already reflects the new width chosen by the user.
10591
+ width: finalWidth,
10592
+ height: isLineObj ? 0 : isAutoShrinkText ? typeof autoShrinkStoredHeight === "number" ? autoShrinkStoredHeight : finalHeight : finalHeight,
10587
10593
  angle: decomposed.angle,
10588
10594
  skewX: isLineObj ? 0 : decomposed.skewX,
10589
10595
  skewY: isLineObj ? 0 : decomposed.skewY,
@@ -18964,9 +18970,9 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
18964
18970
  }
18965
18971
  return svgString;
18966
18972
  }
18967
- const resolvedPackageVersion = "0.5.209";
18973
+ const resolvedPackageVersion = "0.5.211";
18968
18974
  const PACKAGE_VERSION = resolvedPackageVersion;
18969
- const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.209";
18975
+ const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.211";
18970
18976
  const roundParityValue = (value) => {
18971
18977
  if (typeof value !== "number") return value;
18972
18978
  return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
@@ -19026,7 +19032,7 @@ function detectSafariOrIos() {
19026
19032
  return false;
19027
19033
  }
19028
19034
  }
19029
- async function downscaleConfigRasterImages(config, maxEdgePx, maxDataUrlBytes = 2e6) {
19035
+ async function downscaleConfigRasterImages(config, maxEdgePx, maxDataUrlBytes = 2e6, jpegQuality = 0.85) {
19030
19036
  if (!maxEdgePx || maxEdgePx <= 0) return 0;
19031
19037
  if (typeof document === "undefined") return 0;
19032
19038
  const targets = [];
@@ -19090,7 +19096,7 @@ async function downscaleConfigRasterImages(config, maxEdgePx, maxDataUrlBytes =
19090
19096
  return null;
19091
19097
  }
19092
19098
  let scale = tooLargeByEdge ? maxEdgePx / longest : 1;
19093
- let quality = 0.85;
19099
+ let quality = Math.max(0.4, Math.min(1, jpegQuality));
19094
19100
  let best = null;
19095
19101
  for (let attempt = 0; attempt < 4; attempt++) {
19096
19102
  const tw = Math.max(1, Math.round(w * scale));
@@ -19114,7 +19120,7 @@ async function downscaleConfigRasterImages(config, maxEdgePx, maxDataUrlBytes =
19114
19120
  }
19115
19121
  const byteScale = Math.sqrt(maxDataUrlBytes / Math.max(1, outBytes)) * 0.92;
19116
19122
  scale = Math.max(0.1, scale * Math.min(0.95, byteScale));
19117
- quality = Math.max(0.68, quality - 0.06);
19123
+ quality = Math.max(0.4, quality - 0.06);
19118
19124
  }
19119
19125
  if (blobUrl) URL.revokeObjectURL(blobUrl);
19120
19126
  return best;
@@ -19489,7 +19495,9 @@ class PixldocsRenderer {
19489
19495
  title: options == null ? void 0 : options.title,
19490
19496
  textMode: options == null ? void 0 : options.textMode,
19491
19497
  forcePerElementPdf: options == null ? void 0 : options.forcePerElementPdf,
19492
- maxImageEdgePx: options == null ? void 0 : options.maxImageEdgePx
19498
+ maxImageEdgePx: options == null ? void 0 : options.maxImageEdgePx,
19499
+ compressImages: options == null ? void 0 : options.compressImages,
19500
+ compressionQuality: options == null ? void 0 : options.compressionQuality
19493
19501
  });
19494
19502
  }
19495
19503
  /**
@@ -19497,7 +19505,7 @@ class PixldocsRenderer {
19497
19505
  * This is the primary PDF export API — mirrors renderFromForm() but returns a PDF.
19498
19506
  */
19499
19507
  async renderPdfFromForm(options) {
19500
- const { templateId, formSchemaId, sectionState, themeId, watermark, watermarkOptions, prefetched, title, fontBaseUrl, textMode, forcePerElementPdf, maxImageEdgePx } = options;
19508
+ const { templateId, formSchemaId, sectionState, themeId, watermark, watermarkOptions, prefetched, title, fontBaseUrl, textMode, forcePerElementPdf, maxImageEdgePx, compressImages, compressionQuality } = options;
19501
19509
  const resolved = await resolveFromForm({
19502
19510
  templateId,
19503
19511
  formSchemaId,
@@ -19520,7 +19528,9 @@ class PixldocsRenderer {
19520
19528
  watermark: shouldWatermark,
19521
19529
  textMode,
19522
19530
  forcePerElementPdf,
19523
- maxImageEdgePx
19531
+ maxImageEdgePx,
19532
+ compressImages,
19533
+ compressionQuality
19524
19534
  });
19525
19535
  }
19526
19536
  async renderById(templateId, formData, options) {
@@ -19567,13 +19577,20 @@ class PixldocsRenderer {
19567
19577
  const hasUserDataImage = configHasUserDataImage(cloned);
19568
19578
  const isSafariLike = detectSafariOrIos();
19569
19579
  const shouldForcePerElement = forceMode === true ? true : forceMode === false ? false : false;
19580
+ const compressImagesOpt = options.compressImages ?? true;
19570
19581
  const maxEdgeOpt = options.maxImageEdgePx ?? this.config.maxImageEdgePx;
19571
- const effectiveMaxEdge = typeof maxEdgeOpt === "number" ? Math.max(0, maxEdgeOpt | 0) : hasUserDataImage ? 2048 : 0;
19582
+ const effectiveMaxEdge = typeof maxEdgeOpt === "number" ? Math.max(0, maxEdgeOpt | 0) : compressImagesOpt ? hasUserDataImage ? 2048 : 0 : 0;
19583
+ const downscaleQuality = compressImagesOpt ? typeof options.compressionQuality === "number" ? Math.max(0.4, Math.min(1, options.compressionQuality)) : 0.85 : 0.95;
19572
19584
  if (effectiveMaxEdge > 0) {
19573
19585
  try {
19574
- const downscaled = await downscaleConfigRasterImages(cloned, effectiveMaxEdge);
19586
+ const downscaled = await downscaleConfigRasterImages(
19587
+ cloned,
19588
+ effectiveMaxEdge,
19589
+ void 0,
19590
+ downscaleQuality
19591
+ );
19575
19592
  if (downscaled > 0) {
19576
- console.log(`[canvas-renderer][pdf-unified] downscaled ${downscaled} raster image(s) to <=${effectiveMaxEdge}px edge`);
19593
+ console.log(`[canvas-renderer][pdf-unified] downscaled ${downscaled} raster image(s) to <=${effectiveMaxEdge}px edge @ q=${downscaleQuality}`);
19577
19594
  }
19578
19595
  } catch (e) {
19579
19596
  console.warn("[canvas-renderer][pdf-unified] image downscale pass failed (continuing with originals):", e);
@@ -19584,7 +19601,9 @@ class PixldocsRenderer {
19584
19601
  hasUserDataImage,
19585
19602
  isSafariLike,
19586
19603
  shouldForcePerElement,
19587
- effectiveMaxEdge
19604
+ effectiveMaxEdge,
19605
+ compressImages: compressImagesOpt,
19606
+ downscaleQuality
19588
19607
  });
19589
19608
  const stampPrefix = `__pixldocs_pdf_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
19590
19609
  const pageIds = cloned.pages.map((p, i) => {
@@ -19645,7 +19664,7 @@ class PixldocsRenderer {
19645
19664
  await this.waitForCanvasScene(container, cloned, i);
19646
19665
  }
19647
19666
  console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
19648
- const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-B04JIcJr.cjs"));
19667
+ const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-QzySzFJJ.cjs"));
19649
19668
  const prepared = preparePagesForExport(
19650
19669
  cloned.pages,
19651
19670
  canvasWidth,
@@ -19662,7 +19681,9 @@ class PixldocsRenderer {
19662
19681
  // path and use the live Fabric object PDF path instead, preserving live
19663
19682
  // matrices/order so we do not regress into stale config-space layout.
19664
19683
  skipLiveCanvasSvgFastPath: forceMode === true,
19665
- useLiveCanvasObjectPdfPath: shouldForcePerElement && forceMode !== true
19684
+ useLiveCanvasObjectPdfPath: shouldForcePerElement && forceMode !== true,
19685
+ compressImages: options.compressImages ?? true,
19686
+ compressionQuality: options.compressionQuality
19666
19687
  });
19667
19688
  if (!result || typeof result === "undefined") {
19668
19689
  throw new Error("exportMultiPagePdf returned no blob (returnBlob path failed)");
@@ -21829,7 +21850,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
21829
21850
  if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
21830
21851
  sanitizeSvgTreeForPdf(svgToDraw);
21831
21852
  try {
21832
- const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await Promise.resolve().then(() => require("./vectorPdfExport-B04JIcJr.cjs"));
21853
+ const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await Promise.resolve().then(() => require("./vectorPdfExport-QzySzFJJ.cjs"));
21833
21854
  try {
21834
21855
  await logTextMeasurementDiagnostic(svgToDraw);
21835
21856
  } catch {
@@ -22226,4 +22247,4 @@ exports.setAutoShrinkDebug = setAutoShrinkDebug;
22226
22247
  exports.setBundledAssetPrefixes = setBundledAssetPrefixes;
22227
22248
  exports.warmResolvedTemplateForPreview = warmResolvedTemplateForPreview;
22228
22249
  exports.warmTemplateFromForm = warmTemplateFromForm;
22229
- //# sourceMappingURL=index-DQF_on2h.cjs.map
22250
+ //# sourceMappingURL=index-d8U2oDzI.cjs.map