@dtducas/wh-forge-viewer 3.0.0-beta.6 → 3.0.0-beta.7

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.esm.js CHANGED
@@ -70646,6 +70646,7 @@ var SvgToPdfConverter = /*#__PURE__*/function () {
70646
70646
  }, {
70647
70647
  key: "drawEllipse",
70648
70648
  value: function drawEllipse(element, pdfPage, options, transform) {
70649
+ var _options$pageRotation;
70649
70650
  var cx = parseFloat(element.getAttribute('cx') || '0');
70650
70651
  var cy = parseFloat(element.getAttribute('cy') || '0');
70651
70652
  var rx = parseFloat(element.getAttribute('rx') || '0');
@@ -70657,16 +70658,24 @@ var SvgToPdfConverter = /*#__PURE__*/function () {
70657
70658
  _this$transformPoint34 = _slicedToArray(_this$transformPoint33, 2),
70658
70659
  pdfCx = _this$transformPoint34[0],
70659
70660
  pdfCy = _this$transformPoint34[1];
70660
- // Scale radii (apply SVG transform scale if present)
70661
- var svgScaleX = transform ? transform.scaleX : 1;
70662
- var svgScaleY = transform ? transform.scaleY : 1;
70661
+ // Scale radii (apply SVG transform scale if present). Use the *displayed*
70662
+ // page dims (swapped for 90/270) so radii are not stretched on rotated pages,
70663
+ // and swap rx/ry under a quarter rotation since the axes swap in user space.
70664
+ var svgScaleX = Math.abs(transform ? transform.scaleX : 1);
70665
+ var svgScaleY = Math.abs(transform ? transform.scaleY : 1);
70663
70666
  var mbE = options.modelBounds;
70664
70667
  var mapWE = mbE ? mbE.maxX - mbE.minX : options.svgViewBox.width;
70665
70668
  var mapHE = mbE ? mbE.maxY - mbE.minY : options.svgViewBox.height;
70666
- var scaleX = options.pageWidth / mapWE;
70667
- var scaleY = options.pageHeight / mapHE;
70668
- var pdfRx = rx * svgScaleX * scaleX;
70669
- var pdfRy = ry * svgScaleY * scaleY;
70669
+ var rotE = (((_options$pageRotation = options.pageRotation) !== null && _options$pageRotation !== void 0 ? _options$pageRotation : 0) % 360 + 360) % 360;
70670
+ var quarterE = rotE === 90 || rotE === 270;
70671
+ var dispWE = quarterE ? options.pageHeight : options.pageWidth;
70672
+ var dispHE = quarterE ? options.pageWidth : options.pageHeight;
70673
+ var scaleX = dispWE / mapWE;
70674
+ var scaleY = dispHE / mapHE;
70675
+ var rdx = rx * svgScaleX * scaleX;
70676
+ var rdy = ry * svgScaleY * scaleY;
70677
+ var pdfRx = quarterE ? rdy : rdx;
70678
+ var pdfRy = quarterE ? rdx : rdy;
70670
70679
  // Draw fill
70671
70680
  if (style.fillColor && style.fillOpacity > 0) {
70672
70681
  pdfPage.drawEllipse({
@@ -70698,6 +70707,7 @@ var SvgToPdfConverter = /*#__PURE__*/function () {
70698
70707
  }, {
70699
70708
  key: "drawCircle",
70700
70709
  value: function drawCircle(element, pdfPage, options, transform) {
70710
+ var _options$pageRotation2;
70701
70711
  var cx = parseFloat(element.getAttribute('cx') || '0');
70702
70712
  var cy = parseFloat(element.getAttribute('cy') || '0');
70703
70713
  var r = parseFloat(element.getAttribute('r') || '0');
@@ -70708,12 +70718,18 @@ var SvgToPdfConverter = /*#__PURE__*/function () {
70708
70718
  _this$transformPoint36 = _slicedToArray(_this$transformPoint35, 2),
70709
70719
  pdfCx = _this$transformPoint36[0],
70710
70720
  pdfCy = _this$transformPoint36[1];
70711
- // Scale radius (apply SVG transform scale if present)
70712
- var svgScale = transform ? Math.min(transform.scaleX, transform.scaleY) : 1;
70721
+ // Scale radius (apply SVG transform scale if present). Use displayed page
70722
+ // dims (swapped for 90/270) and absolute scale (the SVG Y-flip makes scaleY
70723
+ // negative, which must not flip the radius sign).
70724
+ var svgScale = transform ? Math.min(Math.abs(transform.scaleX), Math.abs(transform.scaleY)) : 1;
70713
70725
  var mbC = options.modelBounds;
70714
70726
  var mapWC = mbC ? mbC.maxX - mbC.minX : options.svgViewBox.width;
70715
70727
  var mapHC = mbC ? mbC.maxY - mbC.minY : options.svgViewBox.height;
70716
- var scale = svgScale * Math.min(options.pageWidth / mapWC, options.pageHeight / mapHC);
70728
+ var rotC = (((_options$pageRotation2 = options.pageRotation) !== null && _options$pageRotation2 !== void 0 ? _options$pageRotation2 : 0) % 360 + 360) % 360;
70729
+ var quarterC = rotC === 90 || rotC === 270;
70730
+ var dispWC = quarterC ? options.pageHeight : options.pageWidth;
70731
+ var dispHC = quarterC ? options.pageWidth : options.pageHeight;
70732
+ var scale = svgScale * Math.min(dispWC / mapWC, dispHC / mapHC);
70717
70733
  var pdfR = r * scale;
70718
70734
  // Draw fill
70719
70735
  if (style.fillColor && style.fillOpacity > 0) {
@@ -71544,6 +71560,7 @@ var SvgToPdfConverter = /*#__PURE__*/function () {
71544
71560
  }, {
71545
71561
  key: "transformPoint",
71546
71562
  value: function transformPoint(x, y, options, svgTransform) {
71563
+ var _options$pageRotation3;
71547
71564
  // Apply SVG transform (translate, rotate, scale) first
71548
71565
  var svgX = x;
71549
71566
  var svgY = y;
@@ -71573,12 +71590,44 @@ var SvgToPdfConverter = /*#__PURE__*/function () {
71573
71590
  var mapY = mb ? mb.minY : options.svgViewBox.y;
71574
71591
  var mapW = mb ? mb.maxX - mb.minX : options.svgViewBox.width;
71575
71592
  var mapH = mb ? mb.maxY - mb.minY : options.svgViewBox.height;
71576
- var scaleX = options.pageWidth / mapW;
71577
- var scaleY = options.pageHeight / mapH;
71578
- var pdfX = (svgX - mapX) * scaleX;
71593
+ // Raw (unrotated) mediabox dims — pdf-lib draws into this space.
71594
+ var rawW = options.pageWidth;
71595
+ var rawH = options.pageHeight;
71596
+ var rot = (((_options$pageRotation3 = options.pageRotation) !== null && _options$pageRotation3 !== void 0 ? _options$pageRotation3 : 0) % 360 + 360) % 360;
71597
+ var quarter = rot === 90 || rot === 270;
71598
+ // Displayed page dims = the orientation the markup was authored in. For a
71599
+ // 90/270 rotation the visible page is the mediabox with width/height swapped,
71600
+ // so we must scale into the swapped dims (otherwise X/Y scale differ → stretch).
71601
+ var dispW = quarter ? rawH : rawW;
71602
+ var dispH = quarter ? rawW : rawH;
71603
+ var scaleX = dispW / mapW;
71604
+ var scaleY = dispH / mapH;
71605
+ // Displayed-space coords (origin bottom-left of the *visible* page, Y-up).
71606
+ var dx = (svgX - mapX) * scaleX;
71579
71607
  // When SVG has CSS scale(1,-1), coordinates are already Y-up (like PDF)
71580
71608
  // so we map directly. Otherwise flip Y (SVG Y-down → PDF Y-up).
71581
- var pdfY = this.isYFlipped ? (svgY - mapY) * scaleY : options.pageHeight - (svgY - mapY) * scaleY;
71609
+ var dy = this.isYFlipped ? (svgY - mapY) * scaleY : dispH - (svgY - mapY) * scaleY;
71610
+ // Map displayed coords → unrotated mediabox space by inverting the page
71611
+ // /Rotate, so markup lines up with the rotated page content.
71612
+ var pdfX;
71613
+ var pdfY;
71614
+ switch (rot) {
71615
+ case 90:
71616
+ pdfX = rawW - dy;
71617
+ pdfY = dx;
71618
+ break;
71619
+ case 180:
71620
+ pdfX = rawW - dx;
71621
+ pdfY = rawH - dy;
71622
+ break;
71623
+ case 270:
71624
+ pdfX = dy;
71625
+ pdfY = rawH - dx;
71626
+ break;
71627
+ default:
71628
+ pdfX = dx;
71629
+ pdfY = dy;
71630
+ }
71582
71631
  return [pdfX, pdfY];
71583
71632
  }
71584
71633
  /**
@@ -72104,7 +72153,8 @@ var MarkupExportService = /*#__PURE__*/function () {
72104
72153
  pageWidth: width,
72105
72154
  pageHeight: height,
72106
72155
  svgViewBox: svgViewBox,
72107
- modelBounds: modelBounds
72156
+ modelBounds: modelBounds,
72157
+ pageRotation: page.getRotation().angle
72108
72158
  }; // Draw markup on page
72109
72159
  _context.n = 8;
72110
72160
  return this.converter.drawSvgOnPdfPage(svgString, page, converterOptions);
@@ -93863,9 +93913,9 @@ var CanvasExportService = /*#__PURE__*/function () {
93863
93913
  scene,
93864
93914
  _msg,
93865
93915
  _error,
93866
- svgString,
93867
93916
  sceneBounds,
93868
93917
  svgViewBox,
93918
+ svgString,
93869
93919
  modelBounds,
93870
93920
  pb,
93871
93921
  avgStrokePt,
@@ -93985,7 +94035,14 @@ var CanvasExportService = /*#__PURE__*/function () {
93985
94035
  _error.code = 'MISSING_PAGE_BOUNDS';
93986
94036
  throw _error;
93987
94037
  case 13:
93988
- svgString = SceneToSvg.convert(scene);
94038
+ sceneBounds = SceneToSvg.computeBounds(scene); // SVG viewBox: use full page bounds if available, else shape bounding box.
94039
+ // The viewBox must cover all shapes so nothing is clipped.
94040
+ svgViewBox = (_ref = (_scene$pageBounds = scene.pageBounds) !== null && _scene$pageBounds !== void 0 ? _scene$pageBounds : scene.viewportBounds) !== null && _ref !== void 0 ? _ref : sceneBounds; // Build the SVG with the SAME viewBox used for PDF coordinate mapping below.
94041
+ // SceneToSvg derives its viewBox attribute AND the Y-flip (translate/scale(1,-1))
94042
+ // from this rect; if it defaulted to viewportBounds while the converter maps via
94043
+ // modelBounds (=pageBounds), the flip origin and the mapping disagree → markup is
94044
+ // mispositioned. Passing svgViewBox keeps both consistent.
94045
+ svgString = SceneToSvg.convert(scene, svgViewBox);
93989
94046
  if (svgString) {
93990
94047
  _context2.n = 14;
93991
94048
  break;
@@ -93993,9 +94050,7 @@ var CanvasExportService = /*#__PURE__*/function () {
93993
94050
  console.debug("[CanvasExportService] page ".concat(pageIndex, ": SceneToSvg returned empty"));
93994
94051
  return _context2.a(3, 15);
93995
94052
  case 14:
93996
- sceneBounds = SceneToSvg.computeBounds(scene); // SVG viewBox: use full page bounds if available, else shape bounding box.
93997
- // The viewBox must cover all shapes so nothing is clipped.
93998
- svgViewBox = (_ref = (_scene$pageBounds = scene.pageBounds) !== null && _scene$pageBounds !== void 0 ? _scene$pageBounds : scene.viewportBounds) !== null && _ref !== void 0 ? _ref : sceneBounds; // modelBounds: the full page extent in world coordinates.
94053
+ // modelBounds: the full page extent in world coordinates.
93999
94054
  // CRITICAL: must be the full PDF page, not just the shape bounding box.
94000
94055
  // Using the shape bounding box stretches markup to fill the page (wrong scale/position).
94001
94056
  // pageBounds is captured from viewer.model.getBoundingBox() at save time.