diff --git a/common/base_screen.cpp b/common/base_screen.cpp index 7f65548a7e..ef0eac3d3c 100644 --- a/common/base_screen.cpp +++ b/common/base_screen.cpp @@ -98,16 +98,8 @@ double BASE_SCREEN::GetScalingFactor() const void BASE_SCREEN::SetScalingFactor( double aScale ) { - double zoom = aScale; - // Limit zoom to max and min allowed values: - if( zoom < m_ZoomList[0] ) - zoom = m_ZoomList[0]; - - int idxmax = m_ZoomList.GetCount() - 1; - - if( zoom > m_ZoomList[idxmax] ) - zoom = m_ZoomList[idxmax]; + double zoom = Clamp( GetMinAllowedZoom(), aScale, GetMaxAllowedZoom() ); SetZoom( zoom ); } @@ -115,38 +107,30 @@ void BASE_SCREEN::SetScalingFactor( double aScale ) bool BASE_SCREEN::SetFirstZoom() { - if( m_ZoomList.IsEmpty() ) - { - if( m_Zoom != 1.0 ) - { - SetZoom( 1.0 ); - return true; - } - } - else if( m_Zoom != m_ZoomList[0] ) - { - SetZoom( m_ZoomList[0] ); - return true; - } - - return false; + return SetZoom( GetMinAllowedZoom() ); } -double BASE_SCREEN::GetZoom() const +bool BASE_SCREEN::SetLastZoom() { - return m_Zoom; + return SetZoom( GetMaxAllowedZoom() ); } -bool BASE_SCREEN::SetZoom( double coeff ) +bool BASE_SCREEN::SetZoom( double iu_per_du ) { - if( coeff == m_Zoom ) + if( iu_per_du == m_Zoom ) return false; - wxLogDebug( "Zoom:%16g 1/Zoom:%16g", coeff, 1/coeff ); + wxLogDebug( "Zoom:%16g 1/Zoom:%16g", iu_per_du, 1/iu_per_du ); - m_Zoom = coeff; + if( iu_per_du < GetMinAllowedZoom() ) + return false; + + if( iu_per_du > GetMaxAllowedZoom() ) + return false; + + m_Zoom = iu_per_du; return true; } @@ -154,10 +138,7 @@ bool BASE_SCREEN::SetZoom( double coeff ) bool BASE_SCREEN::SetNextZoom() { - if( m_ZoomList.IsEmpty() || m_Zoom >= m_ZoomList.Last() ) - return false; - - for( unsigned i = 0; i < m_ZoomList.GetCount(); i++ ) + for( unsigned i=0; i < m_ZoomList.size(); ++i ) { if( m_Zoom < m_ZoomList[i] ) { @@ -172,10 +153,7 @@ bool BASE_SCREEN::SetNextZoom() bool BASE_SCREEN::SetPreviousZoom() { - if( m_ZoomList.IsEmpty() || m_Zoom <= m_ZoomList[0] ) - return false; - - for( unsigned i = m_ZoomList.GetCount(); i != 0; i-- ) + for( unsigned i = m_ZoomList.size(); i != 0; --i ) { if( m_Zoom > m_ZoomList[i - 1] ) { @@ -188,15 +166,6 @@ bool BASE_SCREEN::SetPreviousZoom() } -bool BASE_SCREEN::SetLastZoom() -{ - if( m_ZoomList.IsEmpty() || m_Zoom == m_ZoomList.Last() ) - return false; - - return SetZoom( m_ZoomList.Last() ); -} - - void BASE_SCREEN::SetGridList( GRIDS& gridlist ) { if( !m_grids.empty() ) diff --git a/common/common_plotPDF_functions.cpp b/common/common_plotPDF_functions.cpp index 8bfaf84e84..9a35b59345 100644 --- a/common/common_plotPDF_functions.cpp +++ b/common/common_plotPDF_functions.cpp @@ -425,7 +425,8 @@ void PDF_PLOTTER::closePdfStream() workFile = 0; ::wxRemoveFile( workFilename ); - wxMemoryOutputStream memos; + // NULL means memos owns the memory, but provide a hint on optimum size needed. + wxMemoryOutputStream memos( NULL, std::max( 2000, stream_len ) ) ; { /* Somewhat standard parameters to compress in DEFLATE. The PDF spec is diff --git a/common/drawframe.cpp b/common/drawframe.cpp index 760b84cc47..0c8c2c9f13 100644 --- a/common/drawframe.cpp +++ b/common/drawframe.cpp @@ -660,9 +660,13 @@ bool EDA_DRAW_FRAME::HandleBlockBegin( wxDC* aDC, int aKey, const wxPoint& aPosi return true; } +#define SAFETY_MARGIN 100 -#define VIRT_MIN double(INT_MIN+100) -#define VIRT_MAX double(INT_MAX-100) +// see comment in classpcb.cpp near line 66 +static const double MAX_AXIS = 1518500251 - SAFETY_MARGIN; + +#define VIRT_MIN (-MAX_AXIS/2.0) ///< min X or Y coordinate in virtual space +#define VIRT_MAX (MAX_AXIS/2.0) ///< max X or Y coordinate in virtual space void EDA_DRAW_FRAME::AdjustScrollBars( const wxPoint& aCenterPositionIU ) @@ -707,20 +711,20 @@ void EDA_DRAW_FRAME::AdjustScrollBars( const wxPoint& aCenterPositionIU ) DBOX clientRectIU( xIU, yIU, clientSizeIU.x, clientSizeIU.y ); wxPoint centerPositionIU; +#if 1 || defined( USE_PCBNEW_NANOMETRES ) // put "int" limits on the clientRect - { - if( clientRectIU.GetLeft() < VIRT_MIN ) - clientRectIU.MoveLeftTo( VIRT_MIN ); - if( clientRectIU.GetTop() < VIRT_MIN ) - clientRectIU.MoveTopTo( VIRT_MIN ); - if( clientRectIU.GetRight() > VIRT_MAX ) - clientRectIU.MoveRightTo( VIRT_MAX ); - if( clientRectIU.GetBottom() > VIRT_MAX ) - clientRectIU.MoveBottomTo( VIRT_MAX ); + if( clientRectIU.GetLeft() < VIRT_MIN ) + clientRectIU.MoveLeftTo( VIRT_MIN ); + if( clientRectIU.GetTop() < VIRT_MIN ) + clientRectIU.MoveTopTo( VIRT_MIN ); + if( clientRectIU.GetRight() > VIRT_MAX ) + clientRectIU.MoveRightTo( VIRT_MAX ); + if( clientRectIU.GetBottom() > VIRT_MAX ) + clientRectIU.MoveBottomTo( VIRT_MAX ); +#endif - centerPositionIU.x = KiROUND( clientRectIU.x + clientRectIU.width/2 ); - centerPositionIU.y = KiROUND( clientRectIU.y + clientRectIU.height/2 ); - } + centerPositionIU.x = KiROUND( clientRectIU.x + clientRectIU.width/2 ); + centerPositionIU.y = KiROUND( clientRectIU.y + clientRectIU.height/2 ); DSIZE virtualSizeIU; @@ -784,19 +788,19 @@ void EDA_DRAW_FRAME::AdjustScrollBars( const wxPoint& aCenterPositionIU ) } } +#if 1 || defined( USE_PCBNEW_NANOMETRES ) + // put "int" limits on the virtualSizeIU + virtualSizeIU.x = std::min( virtualSizeIU.x, MAX_AXIS ); + virtualSizeIU.y = std::min( virtualSizeIU.y, MAX_AXIS ); +#endif + if( screen->m_Center ) { - virtualSizeIU.x = std::min( virtualSizeIU.x, VIRT_MAX ); - virtualSizeIU.y = std::min( virtualSizeIU.y, VIRT_MAX ); - screen->m_DrawOrg.x = -KiROUND( virtualSizeIU.x / 2.0 ); screen->m_DrawOrg.y = -KiROUND( virtualSizeIU.y / 2.0 ); } else { - virtualSizeIU.x = std::min( virtualSizeIU.x, VIRT_MAX ); - virtualSizeIU.y = std::min( virtualSizeIU.y, VIRT_MAX ); - screen->m_DrawOrg.x = -KiROUND( ( virtualSizeIU.x - pageRectIU.width ) / 2.0 ); screen->m_DrawOrg.y = -KiROUND( ( virtualSizeIU.y - pageRectIU.height ) / 2.0 ); } @@ -868,4 +872,3 @@ void EDA_DRAW_FRAME::AdjustScrollBars( const wxPoint& aCenterPositionIU ) screen->m_ScrollbarPos.x, screen->m_ScrollbarPos.y, noRefresh ); } - diff --git a/common/zoom.cpp b/common/zoom.cpp index 79b9472d19..3f11a9e854 100644 --- a/common/zoom.cpp +++ b/common/zoom.cpp @@ -59,7 +59,10 @@ void EDA_DRAW_FRAME::Zoom_Automatique( bool aWarpPointer ) { BASE_SCREEN* screen = GetScreen(); - screen->SetZoom( BestZoom() ); // Set the best zoom and get center point. + // Set the best zoom and get center point. + double bestzoom = BestZoom(); + + screen->SetScalingFactor( bestzoom ); if( screen->m_FirstRedraw ) screen->SetCrossHairPosition( screen->GetScrollCenterPosition() ); @@ -103,47 +106,27 @@ void EDA_DRAW_FRAME::OnZoom( wxCommandEvent& event ) bool zoom_at_cursor = false; BASE_SCREEN* screen = GetScreen(); wxPoint center = screen->GetScrollCenterPosition(); - wxPoint zoom_center = center; - double zoom = screen->GetZoom(); switch( id ) { case ID_POPUP_ZOOM_IN: zoom_at_cursor = true; - zoom_center = screen->GetCrossHairPosition(); + center = screen->GetCrossHairPosition(); // fall thru case ID_ZOOM_IN: - if( screen->SetPreviousZoom() ) { - if( zoom_at_cursor ) { - double new_zoom = screen->GetZoom(); - double factor = new_zoom / zoom; - wxPoint delta = center - zoom_center; - center = wxPoint( - zoom_center.x + delta.x * factor, - zoom_center.y + delta.y * factor); - } - RedrawScreen( center, false ); - } + if( screen->SetPreviousZoom() ) + RedrawScreen( center, zoom_at_cursor ); break; case ID_POPUP_ZOOM_OUT: zoom_at_cursor = true; - zoom_center = screen->GetCrossHairPosition(); + center = screen->GetCrossHairPosition(); // fall thru case ID_ZOOM_OUT: - if( screen->SetNextZoom() ) { - if( zoom_at_cursor ) { - double new_zoom = screen->GetZoom(); - double factor = new_zoom / zoom; - wxPoint delta = center - zoom_center; - center = wxPoint( - zoom_center.x + delta.x * factor, - zoom_center.y + delta.y * factor); - } - RedrawScreen( center, false ); - } + if( screen->SetNextZoom() ) + RedrawScreen( center, zoom_at_cursor ); break; case ID_ZOOM_REDRAW: @@ -171,7 +154,7 @@ void EDA_DRAW_FRAME::OnZoom( wxCommandEvent& event ) i = id - ID_POPUP_ZOOM_LEVEL_START; - if( i >= screen->m_ZoomList.GetCount() ) + if( i >= screen->m_ZoomList.size() ) { wxLogDebug( wxT( "%s %d: index %d is outside the bounds of the zoom list." ), __TFILE__, __LINE__, i ); @@ -214,8 +197,8 @@ void EDA_DRAW_FRAME::AddMenuZoomAndGrid( wxMenu* MasterMenu ) zoom = screen->GetZoom(); maxZoomIds = ID_POPUP_ZOOM_LEVEL_END - ID_POPUP_ZOOM_LEVEL_START; - maxZoomIds = ( (size_t) maxZoomIds < screen->m_ZoomList.GetCount() ) ? - maxZoomIds : screen->m_ZoomList.GetCount(); + maxZoomIds = ( (size_t) maxZoomIds < screen->m_ZoomList.size() ) ? + maxZoomIds : screen->m_ZoomList.size(); // Populate zoom submenu. for( int i = 0; i < maxZoomIds; i++ ) diff --git a/eeschema/sch_screen.cpp b/eeschema/sch_screen.cpp index edebba2571..299b975e0c 100644 --- a/eeschema/sch_screen.cpp +++ b/eeschema/sch_screen.cpp @@ -106,7 +106,7 @@ SCH_SCREEN::SCH_SCREEN() : SetZoom( 32 ); for( i = 0; i < SCHEMATIC_ZOOM_LIST_CNT; i++ ) - m_ZoomList.Add( SchematicZoomList[i] ); + m_ZoomList.push_back( SchematicZoomList[i] ); for( i = 0; i < SCHEMATIC_GRID_LIST_CNT; i++ ) AddGrid( SchematicGridList[i] ); diff --git a/gerbview/class_gbr_screen.cpp b/gerbview/class_gbr_screen.cpp index f36dedd9af..f6670805d8 100644 --- a/gerbview/class_gbr_screen.cpp +++ b/gerbview/class_gbr_screen.cpp @@ -88,15 +88,16 @@ static GRID_TYPE gbrGridList[] = }; -GBR_SCREEN::GBR_SCREEN( const wxSize& aPageSizeIU ) : BASE_SCREEN( SCREEN_T ) +GBR_SCREEN::GBR_SCREEN( const wxSize& aPageSizeIU ) : + BASE_SCREEN( SCREEN_T ) { for( unsigned i = 0; i < DIM( gbrZoomList ); ++i ) - m_ZoomList.Add( gbrZoomList[i] ); + m_ZoomList.push_back( gbrZoomList[i] ); for( unsigned i = 0; i < DIM( gbrGridList ); ++i ) AddGrid( gbrGridList[i] ); - // Set the working grid size to a reasonnable value (in 1/10000 inch) + // Set the working grid size to a reasonable value (in 1/10000 inch) SetGrid( DMIL_GRID( 500 ) ); m_Active_Layer = LAYER_N_BACK; // default active layer = bottom layer diff --git a/include/class_base_screen.h b/include/class_base_screen.h index 26c9b2b99a..914da401e3 100644 --- a/include/class_base_screen.h +++ b/include/class_base_screen.h @@ -130,13 +130,13 @@ public: // block control BLOCK_SELECTOR m_BlockLocate; ///< Block description for block commands - int m_ScreenNumber; - int m_NumberOfScreen; + int m_ScreenNumber; + int m_NumberOfScreen; - wxPoint m_GridOrigin; + wxPoint m_GridOrigin; - wxArrayDouble m_ZoomList; ///< Array of standard zoom (i.e. scale) coefficients. - bool m_IsPrinting; + std::vector m_ZoomList; ///< standard zoom (i.e. scale) coefficients. + bool m_IsPrinting; public: BASE_SCREEN( KICAD_T aType = SCREEN_T ); @@ -267,45 +267,63 @@ public: //------------------------------------------------------------- + /** + * Function GetZoom + * returns the current "zoom factor", which is a measure of + * "internal units per device unit", or "world units per device unit". + * A device unit is typically a pixel. + */ + double GetZoom() const { return m_Zoom; } + + /** + * Function SetZoom + * adjusts the current zoom factor. + * + * @param iu_per_du is the number of internal units (world units) per + * device units (pixels typically). + */ + bool SetZoom( double iu_per_du ); + + bool SetNextZoom(); + bool SetPreviousZoom(); + bool SetFirstZoom(); + bool SetLastZoom(); + + /** + * Function GetMaxAllowedZoom + * returns the maximum allowed zoom factor, which was established as the last entry + * in m_ZoomList. + */ + double GetMaxAllowedZoom() const { return m_ZoomList.size() ? *m_ZoomList.rbegin() : 1.0; } + + /** + * Function GetMinAllowedZoom + * returns the minimum allowed zoom factor, which was established as the first entry + * in m_ZoomList. + */ + double GetMinAllowedZoom() const { return m_ZoomList.size() ? *m_ZoomList.begin() : 1.0; } + /** * Function GetScalingFactor - * @return the the current scale used to draw items on screen + * returns the the current scale used to draw items on screen * draw coordinates are user coordinates * GetScalingFactor() */ double GetScalingFactor() const; /** * Function SetScalingFactor - * sets the scaling factor of "device units per logical unit". + * sets the scaling factor of "device units per internal unit". * If the output device is a screen, then "device units" are pixels. The * "logical unit" is wx terminology, and corresponds to KiCad's "Internal Unit (IU)". * * Another way of thinking of scaling factor, when applied to a screen, - * is "pixelsPerIU". + * is "pixelsPerIU" * @param aScale = the the current scale used to draw items onto the device context wxDC. * device coordinates (pixels) = IU coordinates * GetScalingFactor() */ void SetScalingFactor( double aScale ); - /** - * Function GetZoom - * returns the - * @return the current zoom factor - */ - double GetZoom() const; - - /** - * Function SetZoom - * adjusts the current zoom factor - * @param coeff - Zoom coefficient. - */ - bool SetZoom( double coeff ); - - bool SetNextZoom(); - bool SetPreviousZoom(); - bool SetFirstZoom(); - bool SetLastZoom(); //-------------------------------------------------------------- diff --git a/include/convert_to_biu.h b/include/convert_to_biu.h index 8cae47d000..15fa2dcaa3 100644 --- a/include/convert_to_biu.h +++ b/include/convert_to_biu.h @@ -1,5 +1,5 @@ -#ifndef CONVERT_TO_BIU_H -#define CONVERT_TO_BIU_H +#ifndef CONVERT_TO_BIU_H_ +#define CONVERT_TO_BIU_H_ #include // USE_PCBNEW_NANOMETRES is defined here @@ -10,27 +10,28 @@ /** * @brief some define and functions to convert a value in mils, decimils or mm - * to the internal unit used in pcbnew, cvpcb or gerbview (nanometer or decimil) - * depending on compil option + * to the internal unit used in pcbnew, cvpcb or gerbview (nanometer or deci-mil) + * depending on compile time option */ /// Scaling factor to convert mils to internal units. #if defined(PCBNEW) || defined(CVPCB) || defined(GERBVIEW) - #if defined( USE_PCBNEW_NANOMETRES ) - #if defined(GERBVIEW) - #define IU_PER_MM 1e5 // Gerbview uses 10 micrometer. - #else - #define IU_PER_MM 1e6 // Pcbnew uses nanometers. - #endif - #define IU_PER_MILS ( IU_PER_MM * 0.0254 ) - #define IU_PER_DECIMILS (IU_PER_MM * 0.00254 ) - #else // Pcbnew in deci-mils. - #define IU_PER_DECIMILS 1 - #define IU_PER_MILS 10.0 - #define IU_PER_MM (1e4 / 25.4) - #endif + #if defined( USE_PCBNEW_NANOMETRES ) + #if defined(GERBVIEW) + #define IU_PER_MM 1e5 // Gerbview uses 10 micrometer. + #else + #define IU_PER_MM 1e6 // Pcbnew uses nanometers. + #endif + #define IU_PER_MILS (IU_PER_MM * 0.0254) + #define IU_PER_DECIMILS (IU_PER_MM * 0.00254) + + #else // Pcbnew compiled for deci-mils. + #define IU_PER_DECIMILS 1 + #define IU_PER_MILS 10.0 + #define IU_PER_MM (1e4 / 25.4) + #endif /// Convert mils to PCBNEW internal units (iu). inline int Mils2iu( int mils ) @@ -55,9 +56,10 @@ inline int DMils2iu( int dmils ) } #else // Eeschema and anything else. -#define IU_PER_DECIMILS 0.1 -#define IU_PER_MILS 1.0 -#define IU_PER_MM (IU_PER_MILS / 0.0254) + +#define IU_PER_DECIMILS 0.1 +#define IU_PER_MILS 1.0 +#define IU_PER_MM (IU_PER_MILS / 0.0254) inline int Mils2iu( int mils ) { @@ -65,4 +67,4 @@ inline int Mils2iu( int mils ) } #endif -#endif // #define CONVERT_TO_BIU_H +#endif // CONVERT_TO_BIU_H_ diff --git a/include/vector2d.h b/include/vector2d.h index de1609bff2..3968984df1 100644 --- a/include/vector2d.h +++ b/include/vector2d.h @@ -31,12 +31,8 @@ /// Forward declaration for template friends -template class VECTOR2; +//template class VECTOR2; -/* -#include -template ostream& operator<<( ostream &stream, const VECTOR2& vector ); -*/ /** * Class VECTOR2 @@ -56,9 +52,6 @@ public: /// Construct a 2D-vector with x, y = 0 VECTOR2(); - /// Copy constructor - VECTOR2( const VECTOR2& aVector ); - /// Constructor with a wxPoint as argument VECTOR2( const wxPoint& aPoint ); @@ -150,11 +143,6 @@ public: // --- Implementation --- // ---------------------- -template VECTOR2::VECTOR2( VECTOR2 const& aVector ) : - x( aVector.x ), y( aVector.y ) -{ -} - template VECTOR2::VECTOR2() { x = y = 0.0; @@ -194,7 +182,8 @@ template T VECTOR2::Angle() return atan2(y, x); } -template VECTOR2 VECTOR2::Perpendicular(){ +template VECTOR2 VECTOR2::Perpendicular() +{ VECTOR2 perpendicular(-y, x); return perpendicular; } @@ -291,28 +280,27 @@ template T VECTOR2::operator^( const VECTOR2& aVector ) return x * aVector.y - y * aVector.x; } -template bool VECTOR2::operator<( const VECTOR2& o ) +template bool VECTOR2::operator<( const VECTOR2& aVector ) { // VECTOR2 vector( aVector ); - return (double( x ) * x + double( y ) * y) < (double( o.x ) * o.x + double( o.y ) * y); + // need a specialization for T = int because of overflow: + // return (double( x ) * x + double( y ) * y) < (double( o.x ) * o.x + double( o.y ) * y); + return ( *this * *this ) < ( aVector * aVector ); } template bool VECTOR2::operator<=( const VECTOR2& aVector ) { - VECTOR2 vector( aVector ); - return ( *this * *this ) <= ( vector * vector ); + return ( *this * *this ) <= ( aVector * aVector ); } template bool VECTOR2::operator>( const VECTOR2& aVector ) { - VECTOR2 vector( aVector ); - return ( *this * *this ) > ( vector * vector ); + return ( *this * *this ) > ( aVector * aVector ); } template bool VECTOR2::operator>=( const VECTOR2& aVector ) { - VECTOR2 vector( aVector ); - return ( *this * *this ) >= ( vector * vector ); + return ( *this * *this ) >= ( aVector * aVector ); } template bool const VECTOR2::operator==( VECTOR2 const& aVector ) @@ -339,11 +327,19 @@ public: x( aX ), y( aY ), width( aWidth ), height( aHeight ) {} + BOX2( const VECTOR2& aPos, const VECTOR2& aSize ) : + x( aPos.x ), y( aPos.y ), width( aSize.x ), height( aSize.y ) + {} - /// Copy constructor - BOX2( const BOX2& aRect ) : + BOX2( const wxPoint& aPos, const wxSize& aSize ) : + x( aPos.x ), y( aPos.y ), width( aSize.x ), height( aSize.y ) + {} + + /* + BOX2( const EDA_RECT& aRect ): x( aRect.x ), y( aRect.y ), width( aRect.width ), height( aRect.height ) {} + */ /// Constructor with a wxPoint as argument? diff --git a/include/wxstruct.h b/include/wxstruct.h index 39df566219..81cf334c0e 100644 --- a/include/wxstruct.h +++ b/include/wxstruct.h @@ -657,7 +657,7 @@ public: /* Set the zoom level to show the area Rect */ void Window_Zoom( EDA_RECT& Rect ); - /* Return the zoom level which displays the full page on screen */ + /** Return the zoom level which displays the full page on screen */ virtual double BestZoom() = 0; /** diff --git a/pcbnew/basepcbframe.cpp b/pcbnew/basepcbframe.cpp index 26850d49a1..bd3fa07a18 100644 --- a/pcbnew/basepcbframe.cpp +++ b/pcbnew/basepcbframe.cpp @@ -43,6 +43,7 @@ #include #include +#include // Configuration entry names. @@ -247,36 +248,21 @@ EDA_RECT PCB_BASE_FRAME::GetBoardBoundingBox( bool aBoardEdgesOnly ) const double PCB_BASE_FRAME::BestZoom() { - int dx, dy; - - double ii, jj; - wxSize size; - if( m_Pcb == NULL ) - return 32.0; + return 1.0; - EDA_RECT bbbox = GetBoardBoundingBox(); + EDA_RECT ibbbox = GetBoardBoundingBox(); + DSIZE clientz = m_canvas->GetClientSize(); + DSIZE boardz( ibbbox.GetWidth(), ibbbox.GetHeight() ); - dx = bbbox.GetWidth(); - dy = bbbox.GetHeight(); + double iu_per_du_X = clientz.x ? boardz.x / clientz.x : 1.0; + double iu_per_du_Y = clientz.y ? boardz.y / clientz.y : 1.0; - size = m_canvas->GetClientSize(); + double bestzoom = std::max( iu_per_du_X, iu_per_du_Y ); - if( size.x ) - ii = (double)(dx + ( size.x / 2) ) / (double) size.x; - else - ii = 32.0; + GetScreen()->SetScrollCenterPosition( ibbbox.Centre() ); - if ( size.y ) - jj = (double)( dy + (size.y / 2) ) / (double) size.y; - else - jj = 32.0; - - double bestzoom = max( ii, jj ); - - GetScreen()->SetScrollCenterPosition( bbbox.Centre() ); - - return bestzoom ; + return bestzoom; } @@ -432,7 +418,7 @@ void PCB_BASE_FRAME::OnUpdateSelectZoom( wxUpdateUIEvent& aEvent ) int current = 0; - for( size_t i = 0; i < GetScreen()->m_ZoomList.GetCount(); i++ ) + for( unsigned i = 0; i < GetScreen()->m_ZoomList.size(); i++ ) { if( GetScreen()->GetZoom() == GetScreen()->m_ZoomList[i] ) { @@ -807,7 +793,7 @@ void PCB_BASE_FRAME::updateZoomSelectBox() m_zoomSelectBox->Append( _( "Auto" ) ); m_zoomSelectBox->SetSelection( 0 ); - for( int i = 0; i < (int)GetScreen()->m_ZoomList.GetCount(); i++ ) + for( unsigned i = 0; i < GetScreen()->m_ZoomList.size(); ++i ) { msg = _( "Zoom " ); diff --git a/pcbnew/classpcb.cpp b/pcbnew/classpcb.cpp index b873e36be2..c0ef75cb4b 100644 --- a/pcbnew/classpcb.cpp +++ b/pcbnew/classpcb.cpp @@ -61,6 +61,50 @@ static const double pcbZoomList[] = ZOOM_FACTOR( 200.0 ), ZOOM_FACTOR( 300.0 ), +/* + + The largest distance that wx can support is INT_MAX, since it represents + distance often in a wxCoord or wxSize. As a scalar, a distance is always + positive. On most machines which run KiCad, int is 32 bits and INT_MAX is + 2147483647. The most difficult distance for a virtual (world) cartesian + space is the hypotenuse, or diagonal measurement at a 45 degree angle. This + puts the most stress on the distance magnitude within the bounded virtual + space. So if we allow this distance to be our constraint of <= INT_MAX, this + constraint then propagates to the maximum distance in X and in Y that can be + supported on each axis. Remember that the hypotenuse of a 1x1 square is + sqrt( 1x1 + 1x1 ) = sqrt(2) = 1.41421356. + + hypotenuse of any square = sqrt(2) * deltaX; + + Let maximum supported hypotenuse be INT_MAX, then: + + MAX_AXIS = INT_MAX / sqrt(2) = 2147483647 / 1.41421356 = 1518500251 + + This maximum distance is imposed by wxWidgets, not by KiCad. The imposition + comes in the form of the data structures used in the graphics API at the + wxDC level. Obviously when we are not interacting with wx we can use double + to compute distances larger than this. For example the computation of the + total length of a net, can and should be done in double, since it might + actually be longer than a single diagonal line. + + The next choice is what to use for internal units (IU), sometimes called + world units. If nanometers, then the virtual space must be limited to + about 1.5 x 1.5 meters square. This is 1518500251 divided by 1e9 nm/meter. + + The maximum zoom factor then depends on the client window size. If we ask + wx to handle something outside INT_MIN to INT_MAX, there are unreported + problems in the non-Debug build because wxRound() goes silent. + + Let: + const double MAX_AXIS = 1518500251; + + Then a maximum zoom factor for a screen of 1920 pixels wide is + 1518500251 / 1920 = 790885. + + The largest ZOOM_FACTOR in above table is ZOOM_FACTOR( 300 ), which computes + out to 762000 just below 790885. +*/ + #if !defined( USE_PCBNEW_NANOMETRES ) ZOOM_FACTOR( 500.0 ), @@ -106,13 +150,16 @@ PCB_SCREEN::PCB_SCREEN( const wxSize& aPageSizeIU ) : { wxSize displayz = wxGetDisplaySize(); + D(printf( "displayz x:%d y:%d lastZoomFactor: %.16g\n", displayz.x, displayz.y, pcbZoomList[DIM(pcbZoomList)-1] );) + + for( unsigned i = 0; i < DIM( pcbZoomList ); ++i ) - m_ZoomList.Add( pcbZoomList[i] ); + m_ZoomList.push_back( pcbZoomList[i] ); for( unsigned i = 0; i < DIM( pcbGridList ); ++i ) AddGrid( pcbGridList[i] ); - // Set the working grid size to a reasonnable value (in 1/10000 inch) + // Set the working grid size to a reasonable value (in 1/10000 inch) SetGrid( DMIL_GRID( 500 ) ); m_Active_Layer = LAYER_N_BACK; // default active layer = bottom layer