From 72984c5c40cd19c9aa965a0e795434761f01a150 Mon Sep 17 00:00:00 2001
From: jean-pierre charras <jp.charras@wanadoo.fr>
Date: Fri, 8 Sep 2023 10:43:59 +0200
Subject: [PATCH] Gerbview: add refinements to option to set offset and
 rotation of layers. Fix incorrect calculation of bounding boxes when the
 rotation is not n*90 deg.

---
 .../dialogs/dialog_draw_layers_settings.cpp   |  6 +--
 gerbview/gerber_draw_item.cpp                 | 41 ++++++++++++++-----
 gerbview/gerber_file_image.cpp                | 10 ++---
 gerbview/gerber_file_image.h                  |  8 ++--
 4 files changed, 43 insertions(+), 22 deletions(-)

diff --git a/gerbview/dialogs/dialog_draw_layers_settings.cpp b/gerbview/dialogs/dialog_draw_layers_settings.cpp
index 0868d5e9f8..6e74801e62 100644
--- a/gerbview/dialogs/dialog_draw_layers_settings.cpp
+++ b/gerbview/dialogs/dialog_draw_layers_settings.cpp
@@ -54,9 +54,9 @@ bool DIALOG_DRAW_LAYERS_SETTINGS::TransferDataToWindow()
     wxFileName filename( gbrImage->m_FileName );
     m_stLayerName->SetLabel( filename.GetFullName() );
 
-    m_offsetX.SetValue( gbrImage->m_DrawOffset.x );
-    m_offsetY.SetValue( gbrImage->m_DrawOffset.y );
-    m_rotation.SetValue( gbrImage->m_DrawRotation.AsDegrees() );
+    m_offsetX.SetValue( gbrImage->m_DisplayOffset.x );
+    m_offsetY.SetValue( gbrImage->m_DisplayOffset.y );
+    m_rotation.SetValue( gbrImage->m_DisplayRotation.AsDegrees() );
 
     return true;
 }
diff --git a/gerbview/gerber_draw_item.cpp b/gerbview/gerber_draw_item.cpp
index 6168e70784..67985de164 100644
--- a/gerbview/gerber_draw_item.cpp
+++ b/gerbview/gerber_draw_item.cpp
@@ -161,11 +161,11 @@ VECTOR2I GERBER_DRAW_ITEM::GetABPosition( const VECTOR2I& aXYPosition ) const
         abPos.y = -abPos.y;
 
     // Now generate the draw transform
-    if( !m_GerberImageFile->m_DrawRotation.IsZero() )
-        RotatePoint( abPos, m_GerberImageFile->m_DrawRotation );
+    if( !m_GerberImageFile->m_DisplayRotation.IsZero() )
+        RotatePoint( abPos, m_GerberImageFile->m_DisplayRotation );
 
-    abPos.x += KiROUND( m_GerberImageFile->m_DrawOffset.x * m_drawScale.x );
-    abPos.y += KiROUND( m_GerberImageFile->m_DrawOffset.y * m_drawScale.y );
+    abPos.x += KiROUND( m_GerberImageFile->m_DisplayOffset.x * m_drawScale.x );
+    abPos.y += KiROUND( m_GerberImageFile->m_DisplayOffset.y * m_drawScale.y );
 
     return abPos;
 }
@@ -177,11 +177,11 @@ VECTOR2I GERBER_DRAW_ITEM::GetXYPosition( const VECTOR2I& aABPosition ) const
     VECTOR2I xyPos = aABPosition;
 
     // First, undo the draw transform
-    xyPos.x -= KiROUND( m_GerberImageFile->m_DrawOffset.x * m_drawScale.x );
-    xyPos.y -= KiROUND( m_GerberImageFile->m_DrawOffset.y * m_drawScale.y );
+    xyPos.x -= KiROUND( m_GerberImageFile->m_DisplayOffset.x * m_drawScale.x );
+    xyPos.y -= KiROUND( m_GerberImageFile->m_DisplayOffset.y * m_drawScale.y );
 
-    if( !m_GerberImageFile->m_DrawRotation.IsZero() )
-        RotatePoint( xyPos, -m_GerberImageFile->m_DrawRotation );
+    if( !m_GerberImageFile->m_DisplayRotation.IsZero() )
+        RotatePoint( xyPos, -m_GerberImageFile->m_DisplayRotation );
 
     if( m_mirrorA )
         xyPos.x = -xyPos.x;
@@ -387,8 +387,29 @@ const BOX2I GERBER_DRAW_ITEM::GetBoundingBox() const
     }
 
     // calculate the corners coordinates in current Gerber axis orientations
-    VECTOR2I org = GetABPosition( bbox.GetOrigin() );
-    VECTOR2I end = GetABPosition( bbox.GetEnd() );
+    // because the initial bbox is a horizontal rect, but the bbox in AB position
+    // is the bbox image with perhaps a rotation, we need to calculate the coords of the
+    // corners of the bbox rotated, and then calculate the final bounding box
+    VECTOR2I corners[4];
+    corners[0] = bbox.GetOrigin();  // top left
+    corners[2] = bbox.GetEnd();     // bottom right
+    corners[1] = VECTOR2I( corners[2].x, corners[0].y );    // top right
+    corners[3] = VECTOR2I( corners[0].x, corners[2].y );    // bottom left
+
+    VECTOR2I org;
+    VECTOR2I end;
+
+    for( int ii = 0; ii < 4; ii++ )
+    {
+        corners[ii] = GetABPosition( corners[ii] );
+
+        org.x = std::min( org.x, corners[ii].x );
+        org.y = std::min( org.y, corners[ii].y );
+
+        end.x = std::max( end.x, corners[ii].x );
+        end.y = std::max( end.y, corners[ii].y );
+    }
+
 
     // Set the corners position:
     bbox.SetOrigin( org );
diff --git a/gerbview/gerber_file_image.cpp b/gerbview/gerber_file_image.cpp
index c70bbe1798..ee45d8f90c 100644
--- a/gerbview/gerber_file_image.cpp
+++ b/gerbview/gerber_file_image.cpp
@@ -111,9 +111,9 @@ GERBER_FILE_IMAGE::~GERBER_FILE_IMAGE()
 
 void GERBER_FILE_IMAGE::SetDrawOffetAndRotation( VECTOR2D aOffsetMM, EDA_ANGLE aRotation )
 {
-    m_DrawOffset.x = KiROUND( aOffsetMM.x * gerbIUScale.IU_PER_MM );
-    m_DrawOffset.y = KiROUND( aOffsetMM.y * gerbIUScale.IU_PER_MM );
-    m_DrawRotation = aRotation;
+    m_DisplayOffset.x = KiROUND( aOffsetMM.x * gerbIUScale.IU_PER_MM );
+    m_DisplayOffset.y = KiROUND( aOffsetMM.y * gerbIUScale.IU_PER_MM );
+    m_DisplayRotation = aRotation;
 
     // Clear m_AbsolutePolygon member of Gerber items, because draw coordinates
     // are now outdated
@@ -226,8 +226,8 @@ void GERBER_FILE_IMAGE::ResetDefaultValues()
     m_Last_Pen_Command = 0;
     m_Exposure = false;
 
-    m_DrawOffset.x = m_DrawOffset.y = 0;
-    m_DrawRotation = ANGLE_0;
+    m_DisplayOffset.x = m_DisplayOffset.y = 0;
+    m_DisplayRotation = ANGLE_0;
 }
 
 
diff --git a/gerbview/gerber_file_image.h b/gerbview/gerber_file_image.h
index b074dae00f..2fdd60a2fa 100644
--- a/gerbview/gerber_file_image.h
+++ b/gerbview/gerber_file_image.h
@@ -464,10 +464,10 @@ public:
     GERBER_LAYER       m_GBRLayerParams;                 // hold params for the current gerber layer
     GERBER_DRAW_ITEMS  m_drawings;                       // linked list of Gerber Items to draw
 
-    ///< Parameters used only to draw items on this layer.
-    ///< Not not change actual coordinates/orientation
-    VECTOR2I           m_DrawOffset;
-    EDA_ANGLE          m_DrawRotation;
+    ///< Parameters used only to draw (display) items on this layer.
+    ///< Do not change actual coordinates/orientation
+    VECTOR2I           m_DisplayOffset;
+    EDA_ANGLE          m_DisplayRotation;
 
 private:
     wxArrayString      m_messagesList;         // A list of messages created when reading a file