From ac82654563000b4a58b6cadcf2c73e9ced9966cd Mon Sep 17 00:00:00 2001 From: stambaughw Date: Thu, 11 Feb 2010 19:57:47 +0000 Subject: [PATCH] More USE_WX_ZOOM bug fixes. * Changed line clipping function in gr_basic.cpp when USE_WX_ZOOM is enabled. * Set wxDC clipping region to client size when drawing outside of paint event handler. * Updated kicad and eeschema CMake files as the common library now requires linking to the polygon library. --- common/drawpanel.cpp | 45 +++++++++++++++++++----- common/gr_basic.cpp | 76 +++++++++++++++++++++++++++++++++++++++++ eeschema/CMakeLists.txt | 2 +- kicad/CMakeLists.txt | 2 +- 4 files changed, 115 insertions(+), 10 deletions(-) diff --git a/common/drawpanel.cpp b/common/drawpanel.cpp index 9fea2d0e59..f6d40f68b7 100644 --- a/common/drawpanel.cpp +++ b/common/drawpanel.cpp @@ -525,7 +525,15 @@ void WinEDA_DrawPanel::OnSize( wxSizeEvent& event ) /** Function SetBoundaryBox() - * set the m_ClipBox member to the current displayed rectangle dimensions + * Set the clip box to the current displayed rectangle dimensions. + * + * When using wxDC for scaling, the clip box coordinates are in drawing (logical) + * units. In other words, the area of the drawing that will be displayed on the + * screen. When using Kicad's scaling, the clip box coordinates are in screen + * (device) units according to the current scroll position. + * + * @param dc - The device context use for drawing with the correct scale and + * offsets already configured. See DoPrepareDC(). */ void WinEDA_DrawPanel::SetBoundaryBox( wxDC* dc ) { @@ -561,7 +569,22 @@ void WinEDA_DrawPanel::SetBoundaryBox( wxDC* dc ) m_ClipBox.m_Pos.y = dc->DeviceToLogicalY( 0 ); m_ClipBox.m_Size.x = dc->DeviceToLogicalXRel( m_ClipBox.m_Size.x ); m_ClipBox.m_Size.y = dc->DeviceToLogicalYRel( m_ClipBox.m_Size.y ); - m_ClipBox.Inflate( dc->DeviceToLogicalXRel( 2 ) ); + + /* Set to one (1) to draw bounding box validate bounding box calculation. */ +#if 0 + EDA_Rect bBox = m_ClipBox; + m_ClipBox.Inflate( -dc->DeviceToLogicalXRel( 1 ) ); + GRRect( NULL, dc, bBox.GetOrigin().x, bBox.GetOrigin().y, + bBox.GetEnd().x, bBox.GetEnd().y, 0, LIGHTMAGENTA ); +#endif + + m_ClipBox.Inflate( dc->DeviceToLogicalXRel( 1 ) ); + + /* Always set the clipping region to the screen size. This prevents this bug: + * from occurring on WXMSW if you happen + * to be zoomed way in and your drawing coodinates get too large. + */ + dc->SetClippingRegion( m_ClipBox ); #endif Screen->m_ScrollbarPos.x = GetScrollPos( wxHORIZONTAL ); @@ -637,10 +660,18 @@ void WinEDA_DrawPanel::OnPaint( wxPaintEvent& event ) m_ClipBox.m_Pos.y = paintDC.DeviceToLogicalY( PaintClipBox.y ); m_ClipBox.m_Size.x = paintDC.DeviceToLogicalXRel( PaintClipBox.width ); m_ClipBox.m_Size.y = paintDC.DeviceToLogicalYRel( PaintClipBox.height ); - m_ClipBox.Inflate( paintDC.DeviceToLogicalXRel( 2 ) ); + +#if 0 + EDA_Rect bBox = m_ClipBox; + m_ClipBox.Inflate( -paintDC.DeviceToLogicalXRel( 1 ) ); + GRRect( NULL, &paintDC, bBox.GetOrigin().x, bBox.GetOrigin().y, + bBox.GetEnd().x, bBox.GetEnd().y, 0, LIGHTMAGENTA ); +#endif + + m_ClipBox.Inflate( paintDC.DeviceToLogicalXRel( 1 ) ); PaintClipBox = m_ClipBox; #else - /* When using Kicads scaling the clipping region coordinates are in screen + /* When using Kicad's scaling the clipping region coordinates are in screen * (device) units. */ m_ClipBox.SetX( PaintClipBox.GetX() ); @@ -766,10 +797,8 @@ void WinEDA_DrawPanel::DrawGrid( wxDC* DC ) || DC->LogicalToDeviceXRel( wxRound( screen_grid_size.y ) ) < 5 ) return; - org.x = DC->DeviceToLogicalX( 0 ); - org.y = DC->DeviceToLogicalY( 0 ); - size.SetWidth( DC->DeviceToLogicalXRel( size.GetWidth() ) ); - size.SetHeight( DC->DeviceToLogicalYRel( size.GetHeight() ) ); + org = m_ClipBox.m_Pos; + size = m_ClipBox.m_Size; #else wxRealPoint dgrid = screen_grid_size; screen->Scale( dgrid ); // dgrid = grid size in pixels diff --git a/common/gr_basic.cpp b/common/gr_basic.cpp index f179b30afc..d90b25ac7a 100644 --- a/common/gr_basic.cpp +++ b/common/gr_basic.cpp @@ -11,6 +11,7 @@ #include "base_struct.h" #include "class_base_screen.h" #include "bezier_curves.h" +#include "math_for_graphics.h" #ifndef FILLED @@ -137,6 +138,71 @@ int GRMapY( int y ) #define WHEN_INSIDE +#if defined( USE_WX_ZOOM ) + +/** + * Test if any part of a line falls within the bounds of a rectangle. + * + * Please note that this is only accurate for lines that are one pixel wide. + * + * @param aRect - The rectangle to test. + * @param x1 - X coordinate of one end of a line. + * @param y1 - Y coordinate of one end of a line. + * @param x2 - X coordinate of the other end of a line. + * @param y2 - Y coordinate of the other end of a line. + * + * @return - False if any part of the line lies within the rectangle. + */ +static bool clipLine( EDA_Rect* aClipBox, int x1, int y1, int x2, int y2 ) +{ + if( aClipBox->Inside( x1, y1 ) || aClipBox->Inside( x2, y2 ) ) + return false; + + int ax1, ay1, ax2, ay2; + wxRect rect =*aClipBox; + ax1 = rect.GetBottomLeft().x; + ay1 = rect.GetBottomLeft().y; + ax2 = rect.GetTopLeft().x; + ay2 = rect.GetTopLeft().y; + + /* Left clip rectangle line. */ + if( TestForIntersectionOfStraightLineSegments( x1, y1, x2, y2, ax1, ay1, ax2, ay2 ) ) + return false; + + ax1 = rect.GetTopRight().x; + ay1 = rect.GetTopRight().y; + + + /* Top clip rectangle line. */ + if( TestForIntersectionOfStraightLineSegments( x1, y1, x2, y2, ax1, ay1, ax2, ay2 ) ) + return false; + + ax2 = rect.GetBottomRight().x; + ay2 = rect.GetBottomRight().y; + + /* Right clip rectangle line. */ + if( TestForIntersectionOfStraightLineSegments( x1, y1, x2, y2, ax1, ay1, ax2, ay2 ) ) + return false; + + ax1 = rect.GetBottomLeft().x; + ay1 = rect.GetBottomLeft().y; + + /* Bottom clip rectangle line. */ + if( TestForIntersectionOfStraightLineSegments( x1, y1, x2, y2, ax1, ay1, ax2, ay2 ) ) + return false; + + /* Set this to one to verify that diagonal lines get clipped properly. */ +#if 0 + if( !( x1 == x2 || y1 == y2 ) ) + wxLogDebug( wxT( "Clipped line (%d,%d):(%d,%d) from rectangle (%d,%d,%d,%d)" ), + x1, y1, x2, y2, rect.x, rect.y, rect.x + rect.width, rect.y + rect.height ); +#endif + + return true; +} + +#else + /** * Function clip_line * @return bool - true when WHEN_OUTSIDE fires, else false. @@ -240,6 +306,8 @@ static inline bool clip_line( int& x1, int& y1, int& x2, int& y2 ) return false; } +#endif + static void WinClipAndDrawLine( EDA_Rect* ClipBox, wxDC* DC, int x1, int y1, int x2, int y2, @@ -261,7 +329,11 @@ static void WinClipAndDrawLine( EDA_Rect* ClipBox, wxDC* DC, xcliphi += width; ycliphi += width; +#if defined( USE_WX_ZOOM ) + if ( clipLine( ClipBox, x1, y1, x2, y2 ) ) +#else if( clip_line( x1, y1, x2, y2 ) ) +#endif return; } @@ -790,7 +862,11 @@ void GRSCSegm( EDA_Rect* ClipBox, xcliphi += width; ycliphi += width; +#if defined( USE_WX_ZOOM ) + if( clipLine( ClipBox, x1, y1, x2, y2 ) ) +#else if( clip_line( x1, y1, x2, y2 ) ) +#endif return; } diff --git a/eeschema/CMakeLists.txt b/eeschema/CMakeLists.txt index 804be3bdba..a577ca0013 100644 --- a/eeschema/CMakeLists.txt +++ b/eeschema/CMakeLists.txt @@ -154,7 +154,7 @@ if(APPLE) set_target_properties(eeschema PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist) endif(APPLE) -target_link_libraries(eeschema common bitmaps ${wxWidgets_LIBRARIES} ${GDI_PLUS_LIBRARIES}) +target_link_libraries(eeschema common bitmaps polygon ${wxWidgets_LIBRARIES} ${GDI_PLUS_LIBRARIES}) install(TARGETS eeschema DESTINATION ${KICAD_BIN} diff --git a/kicad/CMakeLists.txt b/kicad/CMakeLists.txt index 5abc249acd..55505f19ba 100644 --- a/kicad/CMakeLists.txt +++ b/kicad/CMakeLists.txt @@ -49,7 +49,7 @@ install(TARGETS KiCad DESTINATION ${KICAD_BIN} COMPONENT binary) else(APPLE) - target_link_libraries(kicad common bitmaps ${wxWidgets_LIBRARIES} ${GDI_PLUS_LIBRARIES}) + target_link_libraries(kicad common bitmaps polygon ${wxWidgets_LIBRARIES} ${GDI_PLUS_LIBRARIES}) install(TARGETS kicad DESTINATION ${KICAD_BIN} COMPONENT binary)