From 44d9607461f29c1a0282c8ce3b87af1a8133932f Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Tue, 5 Nov 2013 18:12:27 +0100 Subject: [PATCH] Pcbnew: Fix incorrect bounding box calculation of texts. Only noticeable with boards conveted from Eagle, which are using other text justification than center. Eagle plugin: filter and replace not allowed chars in FPID(-':' and '/') by _ or -, if they are used in Eagle footprint names (otherwise, boards converted and saved under kicad_pcb format are not readable by Pcbnew). --- common/base_struct.cpp | 37 ++++++++++++++++++++++++++ eeschema/sch_text.cpp | 2 +- include/base_struct.h | 10 +++++++ include/eda_text.h | 3 ++- pcbnew/class_pcb_text.cpp | 18 +++++++++++++ pcbnew/class_pcb_text.h | 2 +- pcbnew/class_text_mod.cpp | 55 +++++++++------------------------------ pcbnew/class_text_mod.h | 9 +++---- pcbnew/eagle_plugin.cpp | 11 +++++++- 9 files changed, 94 insertions(+), 53 deletions(-) diff --git a/common/base_struct.cpp b/common/base_struct.cpp index 9250e1068d..280bdc9da6 100644 --- a/common/base_struct.cpp +++ b/common/base_struct.cpp @@ -532,3 +532,40 @@ double EDA_RECT::GetArea() const { return (double) GetWidth() * (double) GetHeight(); } + +/* Calculate the bounding box of this, when rotated + */ +EDA_RECT EDA_RECT::GetBoundingBoxRotated( wxPoint aRotCenter, double aAngle ) +{ + wxPoint corners[4]; + + // Build the corners list + corners[0] = GetOrigin(); + corners[2] = GetEnd(); + corners[1].x = corners[0].x; + corners[1].y = corners[2].y; + corners[3].x = corners[2].x; + corners[3].y = corners[0].y; + + // Rotate all corners, to find the bounding box + for( int ii = 0; ii < 4; ii ++ ) + RotatePoint( &corners[ii], aRotCenter, aAngle ); + + // Find the corners bounding box + wxPoint start = corners[0]; + wxPoint end = corners[0]; + + for( int ii = 1; ii < 4; ii ++ ) + { + start.x = std::min( start.x, corners[ii].x); + start.y = std::min( start.y, corners[ii].y); + end.x = std::max( end.x, corners[ii].x); + end.y = std::max( end.y, corners[ii].y); + } + + EDA_RECT bbox; + bbox.SetOrigin( start ); + bbox.SetEnd( end ); + + return bbox; +} diff --git a/eeschema/sch_text.cpp b/eeschema/sch_text.cpp index abfc85948b..11a1fd859a 100644 --- a/eeschema/sch_text.cpp +++ b/eeschema/sch_text.cpp @@ -363,7 +363,7 @@ void SCH_TEXT::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, const wxPoint& aOffset, DrawDanglingSymbol( panel, DC, m_Pos + aOffset, color ); // Enable these line to draw the bounding box (debug tests purposes only) -#if 0 +#if 1 { EDA_RECT BoundaryBox = GetBoundingBox(); GRRect( clipbox, DC, BoundaryBox, 0, BROWN ); diff --git a/include/base_struct.h b/include/base_struct.h index 530e0e1fc9..d3b6738fff 100644 --- a/include/base_struct.h +++ b/include/base_struct.h @@ -274,6 +274,16 @@ public: * @return The area of the rectangle. */ double GetArea() const; + + /** + * Function GetBoundingBoxRotated + * @return the bounding box of this, after rotation + * @param aAngle = the rotation angle in 0.1 deg. + * @param aRotCenter = the rotation point. + * useful to calculate bounding box of rotated items, when + * rotation if not k*90 degrees + */ + EDA_RECT GetBoundingBoxRotated( wxPoint aRotCenter, double aAngle ); }; diff --git a/include/eda_text.h b/include/eda_text.h index 7fca31fdaa..b5988c244f 100644 --- a/include/eda_text.h +++ b/include/eda_text.h @@ -229,7 +229,8 @@ public: * useful in multiline texts to calculate the full text or a line area (for * zones filling, locate functions....) * @return the rect containing the line of text (i.e. the position and the - * size of one line) this rectangle is calculated for 0 orient text. + * size of one line) + * this rectangle is calculated for 0 orient text. * If orientation is not 0 the rect must be rotated to match the * physical area * @param aLine The line of text to consider. diff --git a/pcbnew/class_pcb_text.cpp b/pcbnew/class_pcb_text.cpp index ac14a42e05..ee916e1ea4 100644 --- a/pcbnew/class_pcb_text.cpp +++ b/pcbnew/class_pcb_text.cpp @@ -106,6 +106,14 @@ void TEXTE_PCB::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, EDA_RECT* clipbox = panel? panel->GetClipBox() : NULL; EDA_TEXT::Draw( clipbox, DC, offset, color, DrawMode, fillmode, anchor_color ); + + // Enable these line to draw the bounding box (debug tests purposes only) +#if 0 + { + EDA_RECT BoundaryBox = GetBoundingBox(); + GRRect( clipbox, DC, BoundaryBox, 0, BROWN ); + } +#endif } @@ -150,6 +158,16 @@ void TEXTE_PCB::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList ) aList.push_back( MSG_PANEL_ITEM( _( "Size Y" ), msg, RED ) ); } +EDA_RECT TEXTE_PCB::GetBoundingBox() const +{ + EDA_RECT rect = GetTextBox( -1, -1 ); + + if( m_Orient ) + rect = rect.GetBoundingBoxRotated( m_Pos, m_Orient ); + + return rect; +} + void TEXTE_PCB::Rotate( const wxPoint& aRotCentre, double aAngle ) { diff --git a/pcbnew/class_pcb_text.h b/pcbnew/class_pcb_text.h index 48e6313df2..8a51aaae9b 100644 --- a/pcbnew/class_pcb_text.h +++ b/pcbnew/class_pcb_text.h @@ -130,7 +130,7 @@ public: BITMAP_DEF GetMenuImage() const { return add_text_xpm; } - EDA_RECT GetBoundingBox() const { return GetTextBox(); }; + EDA_RECT GetBoundingBox() const; EDA_ITEM* Clone() const; diff --git a/pcbnew/class_text_mod.cpp b/pcbnew/class_text_mod.cpp index 31b6a4d595..eda5544b03 100644 --- a/pcbnew/class_text_mod.cpp +++ b/pcbnew/class_text_mod.cpp @@ -159,45 +159,14 @@ void TEXTE_MODULE::SetLocalCoord() } m_Pos0 = m_Pos - module->GetPosition(); - double angle = module->GetOrientation(); - RotatePoint( &m_Pos0.x, &m_Pos0.y, -angle ); } - -/** - * Function GetTextRect - * @return an EDA_RECT which gives the position and size of the text area - * (for the footprint orientation) - */ -EDA_RECT TEXTE_MODULE::GetTextRect( void ) const -{ - EDA_RECT area; - - int dx, dy; - - dx = ( m_Size.x * GetLength() ) / 2; - dx = (dx * 10) / 9; /* letter size = 10/9 */ - dx += m_Thickness / 2; - dy = ( m_Size.y + m_Thickness ) / 2; - - wxPoint Org = m_Pos; // This is the position of the center of the area - Org.x -= dx; - Org.y -= dy; - area.SetOrigin( Org ); - area.SetHeight( 2 * dy ); - area.SetWidth( 2 * dx ); - area.Normalize(); - - return area; -} - - bool TEXTE_MODULE::HitTest( const wxPoint& aPosition ) { wxPoint rel_pos; - EDA_RECT area = GetTextRect(); + EDA_RECT area = GetTextBox( -1, -1 ); /* Rotate refPos to - angle * to test if refPos is within area (which is relative to an horizontal @@ -220,20 +189,12 @@ bool TEXTE_MODULE::HitTest( const wxPoint& aPosition ) */ EDA_RECT TEXTE_MODULE::GetBoundingBox() const { - // Calculate area without text fields: - EDA_RECT text_area; double angle = GetDrawRotation(); - wxPoint textstart, textend; + EDA_RECT text_area = GetTextBox( -1, -1 ); - text_area = GetTextRect(); - textstart = text_area.GetOrigin(); - textend = text_area.GetEnd(); - RotatePoint( &textstart, m_Pos, angle ); - RotatePoint( &textend, m_Pos, angle ); + if( angle ) + text_area = text_area.GetBoundingBoxRotated( m_Pos, m_Orient ); - text_area.SetOrigin( textstart ); - text_area.SetEnd( textend ); - text_area.Normalize(); return text_area; } @@ -319,6 +280,14 @@ void TEXTE_MODULE::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE draw_mode, EDA_RECT* clipbox = panel? panel->GetClipBox() : NULL; DrawGraphicText( clipbox, DC, pos, color, m_Text, orient, size, m_HJustify, m_VJustify, width, m_Italic, m_Bold ); + + // Enable these line to draw the bounding box (debug tests purposes only) +#if 0 + { + EDA_RECT BoundaryBox = GetBoundingBox(); + GRRect( clipbox, DC, BoundaryBox, 0, BROWN ); + } +#endif } /* Draws a line from the TEXTE_MODULE origin to parent MODULE origin. diff --git a/pcbnew/class_text_mod.h b/pcbnew/class_text_mod.h index b693298159..3b444c4b00 100644 --- a/pcbnew/class_text_mod.h +++ b/pcbnew/class_text_mod.h @@ -117,14 +117,11 @@ public: int GetLength() const; // text length - double GetDrawRotation() const; // Return text rotation for drawings and plotting - /** - * Function GetTextRect - * @return an EDA_RECT which gives the position and size of the text area - * (for the 0 orient text and footprint) + * @return the text rotation for drawings and plotting + * the footprint rotation is taken in account */ - EDA_RECT GetTextRect( void ) const; + double GetDrawRotation() const; EDA_RECT GetBoundingBox() const; diff --git a/pcbnew/eagle_plugin.cpp b/pcbnew/eagle_plugin.cpp index aace549fb8..5e7b0dc53c 100644 --- a/pcbnew/eagle_plugin.cpp +++ b/pcbnew/eagle_plugin.cpp @@ -1877,7 +1877,16 @@ MODULE* EAGLE_PLUGIN::makeModule( CPTREE& aPackage, const std::string& aPkgName { std::auto_ptr m( new MODULE( NULL ) ); - m->SetFPID( FPID( aPkgName ) ); + // Replace reserved chars in FPID by other chars + // ':' and '/' are used as separators in FPIDs + std::string fpid_str = aPkgName; + for( unsigned ii = 0; ii < fpid_str.size(); ii++ ) + { + if( fpid_str[ii] == ':' ) fpid_str[ii] = '_'; + if( fpid_str[ii] == '/' ) fpid_str[ii] = '-'; + } + + m->SetFPID( FPID( fpid_str ) ); opt_string description = aPackage.get_optional( "description" ); if( description )