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