From ea812ef5c9b1f3ae581de52b7360b46731106c68 Mon Sep 17 00:00:00 2001 From: Marco Serantoni Date: Sat, 9 Oct 2010 10:08:29 +0200 Subject: [PATCH] Zones drawing optimization with WXGrapchisContext + Fix bug #612132 --- CMakeLists.txt | 8 ++ common/gr_basic.cpp | 55 +++++++++++ demos/video/video.pro | 182 ++++++++++++++++++------------------ include/class_drawpanel.h | 2 +- include/gr_basic.h | 5 + pcbnew/class_module.cpp | 2 +- pcbnew/class_zone.cpp | 18 ++-- pcbnew/controle.cpp | 4 +- pcbnew/menubar_modedit.cpp | 2 +- pcbnew/menubar_pcbframe.cpp | 2 +- pcbnew/modules.cpp | 4 + pcbnew/tracepcb.cpp | 4 +- 12 files changed, 183 insertions(+), 105 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d0f273ff14..d70e1c5fba 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,6 +24,9 @@ option(USE_WX_ZOOM "Use wxDC to perform zooming (default OFF). Warning, this is option(USE_WX_GRAPHICS_CONTEXT "Use wxGraphicsContext for rendering (default OFF). Warning, this is experimental") +option(USE_WX_OVERLAY + "Use wxOverlay: Always ON for MAC (default OFF). Warning, this is experimental") + option(USE_BOOST_POLYGON_LIBRARY "Use boost polygon library instead of Kbool to calculate filled areas in zones (default OFF). Warning, this is experimental") @@ -54,6 +57,11 @@ if(USE_WX_ZOOM) add_definitions(-DUSE_WX_ZOOM) endif(USE_WX_ZOOM) +if(USE_WX_OVERLAY OR APPLE) + add_definitions(-DUSE_WX_OVERLAY) +endif(USE_WX_OVERLAY OR APPLE) + + if(USE_WX_GRAPHICS_CONTEXT) set( USE_WX_ZOOM ON ) add_definitions(-DUSE_WX_ZOOM) diff --git a/common/gr_basic.cpp b/common/gr_basic.cpp index 99a05c6738..5f740da948 100644 --- a/common/gr_basic.cpp +++ b/common/gr_basic.cpp @@ -12,6 +12,7 @@ #include "class_base_screen.h" #include "bezier_curves.h" #include "math_for_graphics.h" +#include #ifndef FILLED @@ -880,6 +881,60 @@ void GRSLine( EDA_Rect* ClipBox, GRLastMoveToY = y2; } +/* + * Draw an array of lines + */ + +void GRLineArray(EDA_Rect* ClipBox, + wxDC* DC, + wxPoint points[], + int lines, + int width, + int Color ) +{ + for(int i= 0 ; i < lines; i++) + { + points[i].x = GRMapX( points[i].x ); + points[i].y = GRMapY( points[i].y ); + } + + width = ZoomValue( width ); + GRSLineArray(ClipBox,DC,points,lines,width,Color); +} + + +void GRSLineArray(EDA_Rect* ClipBox, + wxDC* DC, + wxPoint points[], + int lines, + int width, + int Color ) +{ + GRSetColorPen( DC, Color, width ); +#if defined( USE_WX_GRAPHICS_CONTEXT ) || defined(__WXMAC__) + wxGraphicsContext *gc = wxGraphicsContext::Create( DC ); + wxASSERT(gc); + gc->Clip( ClipBox->GetX(), ClipBox->GetY(), ClipBox->GetRight(), ClipBox->GetHeight()); + wxGraphicsPath path = gc->CreatePath(); + + for(int i= 0 ; i < lines; i+=2) + { + path.MoveToPoint(points[i].x, points[i].y); + path.AddLineToPoint(points[i+1].x, points[i+1].y); + } + + gc->StrokePath(path); + gc->ResetClip(); + delete gc; +#else + for(int i= 0 ; i < lines; i+=2) + { + WinClipAndDrawLine( ClipBox, DC, points[i].x , points[i].y, points[i+1].x , points[i+1].y, Color, width ); + GRLastMoveToX = points[i+1].x; + GRLastMoveToY = points[i+1].y; + } +#endif +} /* * Move to a new position relative to current one, in object space. diff --git a/demos/video/video.pro b/demos/video/video.pro index e0ffa9a481..f7d924ec2b 100644 --- a/demos/video/video.pro +++ b/demos/video/video.pro @@ -1,91 +1,91 @@ -update=01/05/2010 14:42:54 -version=1 -last_client=pcbnew -[cvpcb] -version=1 -NetITyp=0 -NetIExt=.net -PkgIExt=.pkg -NetDir= -LibDir= -NetType=0 -[cvpcb/libraries] -EquName1=devcms -[general] -version=1 -RootSch=video.sch -BoardNm=video.brd -[eeschema] -version=1 -LibDir= -NetFmt=1 -HPGLSpd=20 -HPGLDm=15 -HPGLNum=1 -offX_A4=0 -offY_A4=0 -offX_A3=0 -offY_A3=0 -offX_A2=0 -offY_A2=0 -offX_A1=0 -offY_A1=0 -offX_A0=0 -offY_A0=0 -offX_A=0 -offY_A=0 -offX_B=0 -offY_B=0 -offX_C=0 -offY_C=0 -offX_D=0 -offY_D=0 -offX_E=0 -offY_E=0 -RptD_X=0 -RptD_Y=100 -RptLab=1 -PenMin=20 -SimCmd= -UseNetN=0 -[eeschema/libraries] -LibName1=power -LibName2=device -LibName3=conn -LibName4=brooktre -LibName5=linear -LibName6=regul -LibName7=74xx -LibName8=cmos4000 -LibName9=adc-dac -LibName10=memory -LibName11=xilinx -LibName12=special -LibName13=analog_switches -LibName14=philips -[pcbnew] -version=1 -PadDrlX=1200 -PadDimH=1500 -PadDimV=2000 -BoardThickness=630 -SgPcb45=1 -TxtPcbV=600 -TxtPcbH=600 -TxtModV=500 -TxtModH=500 -TxtModW=80 -VEgarde=100 -DrawLar=120 -EdgeLar=120 -TxtLar=80 -MSegLar=120 -LastNetListRead= -[pcbnew/libraries] -LibDir= -LibName1=supports -LibName2=connect -LibName3=discret -LibName4=pin_array -LibName5=divers -LibName6=libcms +update=Sabato, 2010 Ottobre 09 10:06:24 +version=1 +last_client=pcbnew +[cvpcb] +version=1 +NetITyp=0 +NetIExt=.net +PkgIExt=.pkg +NetDir= +LibDir= +NetType=0 +[cvpcb/libraries] +EquName1=devcms +[general] +version=1 +RootSch=video.sch +BoardNm=video.brd +[eeschema] +version=1 +LibDir= +NetFmt=1 +HPGLSpd=20 +HPGLDm=15 +HPGLNum=1 +offX_A4=0 +offY_A4=0 +offX_A3=0 +offY_A3=0 +offX_A2=0 +offY_A2=0 +offX_A1=0 +offY_A1=0 +offX_A0=0 +offY_A0=0 +offX_A=0 +offY_A=0 +offX_B=0 +offY_B=0 +offX_C=0 +offY_C=0 +offX_D=0 +offY_D=0 +offX_E=0 +offY_E=0 +RptD_X=0 +RptD_Y=100 +RptLab=1 +PenMin=20 +SimCmd= +UseNetN=0 +[eeschema/libraries] +LibName1=power +LibName2=device +LibName3=conn +LibName4=brooktre +LibName5=linear +LibName6=regul +LibName7=74xx +LibName8=cmos4000 +LibName9=adc-dac +LibName10=memory +LibName11=xilinx +LibName12=special +LibName13=analog_switches +LibName14=philips +[pcbnew] +version=1 +PadDrlX=1200 +PadDimH=1500 +PadDimV=2000 +BoardThickness=630 +SgPcb45=1 +TxtPcbV=600 +TxtPcbH=600 +TxtModV=500 +TxtModH=500 +TxtModW=80 +VEgarde=100 +DrawLar=120 +EdgeLar=120 +TxtLar=80 +MSegLar=120 +LastNetListRead= +[pcbnew/libraries] +LibDir= +LibName1=supports +LibName2=connect +LibName3=discret +LibName4=pin_array +LibName5=divers +LibName6=libcms diff --git a/include/class_drawpanel.h b/include/class_drawpanel.h index a90fd2fbea..d2163be68b 100644 --- a/include/class_drawpanel.h +++ b/include/class_drawpanel.h @@ -61,7 +61,7 @@ public: int m_CursorLevel; // Index for cursor redraw in XOR // mode -#ifdef __WXMAC__ +#ifdef USE_WX_OVERLAY // MAC Uses overlay to workaround the wxINVERT and wxXOR miss wxOverlay m_overlay; #endif diff --git a/include/gr_basic.h b/include/gr_basic.h index 3a1e474fb7..e5c6fabd95 100644 --- a/include/gr_basic.h +++ b/include/gr_basic.h @@ -198,4 +198,9 @@ void GRRectPs( EDA_Rect* aClipBox, wxDC* aDC,const EDA_Rect& aRect, void GRSFilledRect( EDA_Rect* ClipBox, wxDC* DC, int x1, int y1, int x2, int y2, int width, int Color, int BgColor ); +void GRLineArray( EDA_Rect* ClipBox, wxDC* DC, wxPoint points[], + int lines, int width, int Color ); +void GRSLineArray( EDA_Rect* ClipBox, wxDC* DC, wxPoint points[], + int lines, int width, int Color ); + #endif /* define GR_BASIC */ diff --git a/pcbnew/class_module.cpp b/pcbnew/class_module.cpp index 76d7420f92..ec63b18157 100644 --- a/pcbnew/class_module.cpp +++ b/pcbnew/class_module.cpp @@ -186,7 +186,7 @@ void MODULE::Copy( MODULE* aModule ) void MODULE::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode, const wxPoint& offset ) { - if( (m_Flags & DO_NOT_DRAW) ) + if( (m_Flags & DO_NOT_DRAW) || (m_Flags & IS_MOVED) ) return; for( D_PAD* pad = m_Pads; pad; pad = pad->Next() ) diff --git a/pcbnew/class_zone.cpp b/pcbnew/class_zone.cpp index 687c1b4a45..4d07bebb58 100644 --- a/pcbnew/class_zone.cpp +++ b/pcbnew/class_zone.cpp @@ -477,6 +477,7 @@ void ZONE_CONTAINER::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode, con // draw the lines int i_start_contour = 0; + wxPoint lines[( GetNumCorners()*2)+2]; for( int ic = 0; ic < GetNumCorners(); ic++ ) { seg_start = GetCornerPosition( ic ) + offset; @@ -489,18 +490,23 @@ void ZONE_CONTAINER::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode, con seg_end = GetCornerPosition( i_start_contour ) + offset; i_start_contour = ic + 1; } - GRLine( &panel->m_ClipBox, DC, seg_start.x, seg_start.y, seg_end.x, seg_end.y, 0, color ); + lines[ic*2].x = seg_start.x; + lines[ic*2].y = seg_start.y; + lines[ic*2+1].x = seg_start.x; + lines[ic*2+1].y = seg_start.y; } + GRLineArray(&panel->m_ClipBox, DC, lines, GetNumCorners(), 0, color); // draw hatches + wxPoint hatches[(m_Poly->m_HatchLines.size() *2)+2]; for( unsigned ic = 0; ic < m_Poly->m_HatchLines.size(); ic++ ) { - int xi = m_Poly->m_HatchLines[ic].xi + offset.x; - int yi = m_Poly->m_HatchLines[ic].yi + offset.y; - int xf = m_Poly->m_HatchLines[ic].xf + offset.x; - int yf = m_Poly->m_HatchLines[ic].yf + offset.y; - GRLine( &panel->m_ClipBox, DC, xi, yi, xf, yf, 0, color ); + hatches[ic*2].x = m_Poly->m_HatchLines[ic].xi + offset.x; + hatches[ic*2].y = m_Poly->m_HatchLines[ic].yi + offset.y; + hatches[ic*2+1].x = m_Poly->m_HatchLines[ic].xf + offset.x; + hatches[ic*2+1].y = m_Poly->m_HatchLines[ic].yf + offset.y; } + GRLineArray(&panel->m_ClipBox, DC, hatches, m_Poly->m_HatchLines.size(), 0, color ); } diff --git a/pcbnew/controle.cpp b/pcbnew/controle.cpp index ea91c15625..a04d7c12a6 100644 --- a/pcbnew/controle.cpp +++ b/pcbnew/controle.cpp @@ -361,7 +361,7 @@ void WinEDA_PcbFrame::GeneralControle( wxDC* DC, wxPoint Mouse ) if( DrawPanel->ManageCurseur ) { -#ifdef __WXMAC__ +#ifdef USE_WX_OVERLAY wxDCOverlay oDC( DrawPanel->m_overlay, DC ); oDC.Clear(); DrawPanel->ManageCurseur( DrawPanel, DC, FALSE ); @@ -369,7 +369,7 @@ void WinEDA_PcbFrame::GeneralControle( wxDC* DC, wxPoint Mouse ) DrawPanel->ManageCurseur( DrawPanel, DC, TRUE ); #endif } -#ifdef __WXMAC__ +#ifdef USE_WX_OVERLAY else DrawPanel->m_overlay.Reset(); #endif diff --git a/pcbnew/menubar_modedit.cpp b/pcbnew/menubar_modedit.cpp index 7dd95de630..99297ef613 100644 --- a/pcbnew/menubar_modedit.cpp +++ b/pcbnew/menubar_modedit.cpp @@ -91,7 +91,7 @@ void WinEDA_ModuleEditFrame::ReCreateMenuBar() fileMenu->AppendSeparator(); /* Print */ - item = new wxMenuItem( fileMenu, wxID_PRINT, _( "&Print" ), + item = new wxMenuItem( fileMenu, wxID_PRINT, _( "&Print\tCtrl+P" ), _( "Print the current module" ) ); item->SetBitmap( plot_xpm ); fileMenu->Append( item ); diff --git a/pcbnew/menubar_pcbframe.cpp b/pcbnew/menubar_pcbframe.cpp index a0139db801..4d77f03ef8 100644 --- a/pcbnew/menubar_pcbframe.cpp +++ b/pcbnew/menubar_pcbframe.cpp @@ -195,7 +195,7 @@ void WinEDA_PcbFrame::ReCreateMenuBar() filesMenu->AppendSeparator(); /* Print */ - item = new wxMenuItem( filesMenu, wxID_PRINT, _( "&Print" ), + item = new wxMenuItem( filesMenu, wxID_PRINT, _( "&Print\tCtrl+P" ), _( "Print board" ) ); item->SetBitmap( print_button ); filesMenu->Append( item ); diff --git a/pcbnew/modules.cpp b/pcbnew/modules.cpp index 539882eccc..a257502f71 100644 --- a/pcbnew/modules.cpp +++ b/pcbnew/modules.cpp @@ -224,6 +224,10 @@ void Abort_MoveOrCopyModule( WinEDA_DrawPanel* Panel, wxDC* DC ) pcbframe->GetBoard()->m_Status_Pcb &= ~DO_NOT_SHOW_GENERAL_RASTNEST; if( pcbframe->GetBoard()->IsElementVisible( RATSNEST_VISIBLE ) ) pcbframe->DrawGeneralRatsnest( DC ); + +#ifdef __WXMAC__ + pcbframe->GetScreen()->SetRefreshReq(); +#endif } diff --git a/pcbnew/tracepcb.cpp b/pcbnew/tracepcb.cpp index c8e4002896..35549bb968 100644 --- a/pcbnew/tracepcb.cpp +++ b/pcbnew/tracepcb.cpp @@ -54,7 +54,7 @@ void WinEDA_ModuleEditFrame::RedrawActiveWindow( wxDC* DC, bool EraseBg ) module->Draw( DrawPanel, DC, GR_OR ); } -#ifdef __WXMAC__ +#ifdef USE_WX_OVERLAY DrawPanel->m_overlay.Reset(); wxDCOverlay overlaydc( DrawPanel->m_overlay, DC ); overlaydc.Clear(); @@ -90,7 +90,7 @@ void WinEDA_PcbFrame::RedrawActiveWindow( wxDC* DC, bool EraseBg ) DrawGeneralRatsnest( DC ); -#ifdef __WXMAC__ +#ifdef USE_WX_OVERLAY DrawPanel->m_overlay.Reset(); wxDCOverlay overlaydc( DrawPanel->m_overlay, DC ); overlaydc.Clear();