Uses a buffered DC in OnPaint event. Seems solve slow grid redraw on some PC.

This commit is contained in:
charras 2010-01-12 13:15:13 +00:00
parent 9d81025e1a
commit 54b561236f
12 changed files with 73 additions and 55 deletions

View File

@ -4,6 +4,14 @@ KiCad ChangeLog 2009
Please add newer entries at the top, list the date and your name with Please add newer entries at the top, list the date and your name with
email address. email address.
2010-Jan-12 UPDATE Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
================================================================================
++All
Use wxAutoBufferedPaintDC in OnPaint event
Seems solves slow grid redraw on some PC (tested under Window 7)
and is faster than use wxPaintDC, not buffered
(note MACOSX has natively a double buffer, so no change for MACOSX)
2010-Jan-08 UPDATE Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr> 2010-Jan-08 UPDATE Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
================================================================================ ================================================================================
++Gerbview ++Gerbview

View File

@ -139,7 +139,8 @@ check_find_package_result(OPENGL_FOUND "OpenGL")
# http://www.wxwidgets.org/manuals/2.8/wx_librarieslist.html # http://www.wxwidgets.org/manuals/2.8/wx_librarieslist.html
if( KICAD_AUIMANAGER OR KICAD_AUITOOLBAR ) if( KICAD_AUIMANAGER OR KICAD_AUITOOLBAR )
find_package(wxWidgets COMPONENTS gl html adv core net base aui QUIET) # find_package(wxWidgets COMPONENTS gl html adv core net base aui QUIET)
find_package(wxWidgets COMPONENTS gl html adv core net base QUIET)
else( KICAD_AUIMANAGER OR KICAD_AUITOOLBAR ) else( KICAD_AUIMANAGER OR KICAD_AUITOOLBAR )
find_package(wxWidgets COMPONENTS gl html adv core net base QUIET) find_package(wxWidgets COMPONENTS gl html adv core net base QUIET)
endif( KICAD_AUIMANAGER OR KICAD_AUITOOLBAR ) endif( KICAD_AUIMANAGER OR KICAD_AUITOOLBAR )

View File

@ -421,12 +421,6 @@ void WinEDA_DrawPanel::OnActivate( wxActivateEvent& event )
} }
void WinEDA_DrawPanel::OnEraseBackground( wxEraseEvent& event )
{
event.Skip();
}
void WinEDA_DrawPanel::OnScroll( wxScrollWinEvent& event ) void WinEDA_DrawPanel::OnScroll( wxScrollWinEvent& event )
{ {
int id = event.GetEventType(); int id = event.GetEventType();

View File

@ -15,8 +15,6 @@
#include "class_base_screen.h" #include "class_base_screen.h"
#include "wxstruct.h" #include "wxstruct.h"
#include "kicad_device_context.h"
/** Compute draw offset (scroll bars and draw parameters) /** Compute draw offset (scroll bars and draw parameters)
* in order to have the current graphic cursor position at the screen center * in order to have the current graphic cursor position at the screen center
* @param ToMouse if TRUE, the mouse cursor is moved * @param ToMouse if TRUE, the mouse cursor is moved
@ -28,8 +26,8 @@ void WinEDA_DrawFrame::Recadre_Trace( bool ToMouse )
{ {
PutOnGrid( &(GetBaseScreen()->m_Curseur) ); PutOnGrid( &(GetBaseScreen()->m_Curseur) );
AdjustScrollBars(); AdjustScrollBars();
INSTALL_DC( dc, DrawPanel ) ; DrawPanel->Refresh(); // send OnPaint event
DrawPanel->ReDraw( &dc ); wxSafeYield(); // needed to allow OnPaint event execution here
/* Move the mouse cursor to the on grid graphic cursor position */ /* Move the mouse cursor to the on grid graphic cursor position */
if( ToMouse == TRUE ) if( ToMouse == TRUE )
@ -40,8 +38,8 @@ void WinEDA_DrawFrame::Recadre_Trace( bool ToMouse )
/** Adjust the coordinate to the nearest grid value /** Adjust the coordinate to the nearest grid value
* @param coord = coordinate to adjust * @param coord = coordinate to adjust
*/ */
void WinEDA_DrawFrame::PutOnGrid( wxPoint* coord ) void WinEDA_DrawFrame::PutOnGrid( wxPoint* coord )
{ {
wxRealPoint grid_size = GetBaseScreen()->GetGridSize(); wxRealPoint grid_size = GetBaseScreen()->GetGridSize();
@ -52,7 +50,7 @@ void WinEDA_DrawFrame::PutOnGrid( wxPoint* coord )
coord->x = wxRound( tmp * grid_size.x ); coord->x = wxRound( tmp * grid_size.x );
tmp = wxRound( coord->y / grid_size.y ); tmp = wxRound( coord->y / grid_size.y );
coord->y = wxRound ( tmp * grid_size.y ); coord->y = wxRound( tmp * grid_size.y );
} }
} }
@ -73,15 +71,16 @@ void WinEDA_DrawFrame::Zoom_Automatique( bool move_mouse_cursor )
*/ */
void WinEDA_DrawFrame::Window_Zoom( EDA_Rect& Rect ) void WinEDA_DrawFrame::Window_Zoom( EDA_Rect& Rect )
{ {
double scalex, bestscale; double scalex, bestscale;
wxSize size; wxSize size;
/* Compute the best zoom */ /* Compute the best zoom */
Rect.Normalize(); Rect.Normalize();
size = DrawPanel->GetClientSize(); size = DrawPanel->GetClientSize();
// Use ceil to at least show the full rect // Use ceil to at least show the full rect
scalex = (double) Rect.GetSize().x / size.x; scalex = (double) Rect.GetSize().x / size.x;
bestscale = (double)Rect.GetSize().y / size.y; bestscale = (double) Rect.GetSize().y / size.y;
bestscale = MAX( bestscale, scalex ); bestscale = MAX( bestscale, scalex );
GetBaseScreen()->SetScalingFactor( bestscale ); GetBaseScreen()->SetScalingFactor( bestscale );
@ -96,7 +95,7 @@ void WinEDA_DrawFrame::Window_Zoom( EDA_Rect& Rect )
void WinEDA_DrawFrame::OnZoom( wxCommandEvent& event ) void WinEDA_DrawFrame::OnZoom( wxCommandEvent& event )
{ {
if( DrawPanel == NULL ) if( DrawPanel == NULL )
return; return;
int i; int i;
int id = event.GetId(); int id = event.GetId();
@ -107,7 +106,8 @@ void WinEDA_DrawFrame::OnZoom( wxCommandEvent& event )
{ {
case ID_POPUP_ZOOM_IN: case ID_POPUP_ZOOM_IN:
zoom_at_cursor = true; zoom_at_cursor = true;
// fall thru
// fall thru
case ID_ZOOM_IN: case ID_ZOOM_IN:
if( id == ID_ZOOM_IN ) if( id == ID_ZOOM_IN )
@ -118,7 +118,8 @@ void WinEDA_DrawFrame::OnZoom( wxCommandEvent& event )
case ID_POPUP_ZOOM_OUT: case ID_POPUP_ZOOM_OUT:
zoom_at_cursor = true; zoom_at_cursor = true;
// fall thru
// fall thru
case ID_ZOOM_OUT: case ID_ZOOM_OUT:
if( id == ID_ZOOM_OUT ) if( id == ID_ZOOM_OUT )
@ -128,12 +129,7 @@ void WinEDA_DrawFrame::OnZoom( wxCommandEvent& event )
break; break;
case ID_ZOOM_REDRAW: case ID_ZOOM_REDRAW:
// DrawPanel->Refresh(); usually good, DrawPanel->Refresh();
// but does not work under linux, when called from here (wxGTK bug ?)
{
INSTALL_DC( dc, DrawPanel );
DrawPanel->ReDraw( &dc );
}
break; break;
case ID_POPUP_ZOOM_CENTER: case ID_POPUP_ZOOM_CENTER:
@ -199,12 +195,12 @@ void WinEDA_DrawPanel::AddMenuZoom( wxMenu* MasterMenu )
zoom = GetScreen()->GetZoom(); zoom = GetScreen()->GetZoom();
maxZoomIds = ID_POPUP_ZOOM_LEVEL_END - ID_POPUP_ZOOM_LEVEL_START; maxZoomIds = ID_POPUP_ZOOM_LEVEL_END - ID_POPUP_ZOOM_LEVEL_START;
maxZoomIds = ( (size_t) maxZoomIds < GetScreen()->m_ZoomList.GetCount() ) ? maxZoomIds = ( (size_t) maxZoomIds < GetScreen()->m_ZoomList.GetCount() ) ?
maxZoomIds : GetScreen()->m_ZoomList.GetCount(); maxZoomIds : GetScreen()->m_ZoomList.GetCount();
/* Populate zoom submenu. */ /* Populate zoom submenu. */
for( i = 0; i < (size_t) maxZoomIds; i++ ) for( i = 0; i < (size_t) maxZoomIds; i++ )
{ {
if ( ( GetScreen()->m_ZoomList[i] % GetScreen()->m_ZoomScalar ) == 0 ) if( ( GetScreen()->m_ZoomList[i] % GetScreen()->m_ZoomScalar ) == 0 )
msg.Printf( wxT( "%u" ), msg.Printf( wxT( "%u" ),
GetScreen()->m_ZoomList[i] / GetScreen()->m_ZoomScalar ); GetScreen()->m_ZoomList[i] / GetScreen()->m_ZoomScalar );
else else
@ -240,7 +236,7 @@ void WinEDA_DrawPanel::AddMenuZoom( wxMenu* MasterMenu )
} }
else else
{ {
if ( g_UnitMetric == 0 ) // inches if( g_UnitMetric == 0 ) // inches
msg.Printf( wxT( "%.1f mils" ), gridValue * 1000 ); msg.Printf( wxT( "%.1f mils" ), gridValue * 1000 );
else else
msg.Printf( wxT( "%.3f mm" ), gridValue ); msg.Printf( wxT( "%.3f mm" ), gridValue );

View File

@ -99,7 +99,6 @@ public:
void* aData ); void* aData );
void DrawBackGround( wxDC* DC ); void DrawBackGround( wxDC* DC );
void DrawAuxiliaryAxis( wxDC* DC, int drawmode ); void DrawAuxiliaryAxis( wxDC* DC, int drawmode );
void OnEraseBackground( wxEraseEvent& event );
void OnActivate( wxActivateEvent& event ); void OnActivate( wxActivateEvent& event );
/* Mouse and keys events */ /* Mouse and keys events */

View File

@ -10,8 +10,15 @@
// and uncomment to use buffered DC // and uncomment to use buffered DC
// #define KICAD_USE_BUFFERED_DC // Currently under test // #define KICAD_USE_BUFFERED_DC // Currently under test
#ifdef KICAD_USE_BUFFERED_DC // Comment this line to use the standard wxPaintDC
#include <wx/dcbuffer.h> // and uncomment to use buffered PaintDC
#define KICAD_USE_BUFFERED_PAINTDC // Currently under test
#if defined KICAD_USE_BUFFERED_DC || defined KICAD_USE_BUFFERED_PAINTDC
#ifndef KICAD_USE_BUFFERED_PAINTDC
#define KICAD_USE_BUFFERED_PAINTDC
#endif
#include <wx/dcbuffer.h>
#endif #endif
// Helper class to handle the client Device Context // Helper class to handle the client Device Context
@ -27,14 +34,16 @@ public:
#ifdef KICAD_USE_BUFFERED_DC #ifdef KICAD_USE_BUFFERED_DC
#define INSTALL_DC(name,parent) \ #define INSTALL_DC(name,parent) \
KicadGraphicContext _cDC( parent );\ KicadGraphicContext _cDC( parent );\
wxBufferedDC name(&_cDC, _cDC.GetSize() ); wxBufferedDC name(&_cDC, _cDC.GetSize() );
#define INSTALL_PAINTDC(name,parent) wxBufferedPaintDC name(parent )
#else #else
#define INSTALL_DC(name,parent) KicadGraphicContext name( parent ) #define INSTALL_DC(name,parent) KicadGraphicContext name( parent )
#define INSTALL_PAINTDC(name,parent) wxPaintDC name( parent ) #endif
#ifdef KICAD_USE_BUFFERED_PAINTDC
#define INSTALL_PAINTDC(name,parent) wxAutoBufferedPaintDC name(parent )
#else
#define INSTALL_PAINTDC(name,parent) wxPaintDC name( parent )
#endif #endif
#endif // __KICAD_DEVICE_CONTEXT_H__ #endif // __KICAD_DEVICE_CONTEXT_H__

View File

@ -318,7 +318,7 @@ int ZONE_CONTAINER::ReadDescr( FILE* aFile, int* aLineNum )
else if( strnicmp( Line, "ZOptions", 8 ) == 0 ) // Options info found else if( strnicmp( Line, "ZOptions", 8 ) == 0 ) // Options info found
{ {
int fillmode = 1; int fillmode = 1;
int arcsegmentcount = 16; int arcsegmentcount = ARC_APPROX_SEGMENTS_COUNT_LOW_DEF;
char fillstate = 'F'; char fillstate = 'F';
text = Line + 8; text = Line + 8;
ret = sscanf( text, "%d %d %c %d %d", &fillmode, &arcsegmentcount, &fillstate, ret = sscanf( text, "%d %d %c %d %d", &fillmode, &arcsegmentcount, &fillstate,
@ -329,8 +329,8 @@ int ZONE_CONTAINER::ReadDescr( FILE* aFile, int* aLineNum )
else else
m_FillMode = fillmode ? 1 : 0; m_FillMode = fillmode ? 1 : 0;
if( arcsegmentcount >= 32 ) if( arcsegmentcount >= ARC_APPROX_SEGMENTS_COUNT_HIGHT_DEF )
m_ArcToSegmentsCount = 32; m_ArcToSegmentsCount = ARC_APPROX_SEGMENTS_COUNT_HIGHT_DEF;
m_IsFilled = fillstate == 'F' ? true : false; m_IsFilled = fillstate == 'F' ? true : false;
} }

View File

@ -42,7 +42,8 @@ public:
int m_ZoneClearance; // clearance value int m_ZoneClearance; // clearance value
int m_ZoneMinThickness; // Min thickness value in filled areas int m_ZoneMinThickness; // Min thickness value in filled areas
int m_FillMode; // How to fillingareas: 0 = use polygonal areas , != 0 fill with segments int m_FillMode; // How to fillingareas: 0 = use polygonal areas , != 0 fill with segments
int m_ArcToSegmentsCount; // number of segments to convert a circle to a polygon (uses 16 or 32) int m_ArcToSegmentsCount; // number of segments to convert a circle to a polygon
// (uses ARC_APPROX_SEGMENTS_COUNT_LOW_DEF or ARC_APPROX_SEGMENTS_COUNT_HIGHT_DEF)
int m_PadOption; // int m_PadOption; //
int m_ThermalReliefGapValue; // tickness of the gap in thermal reliefs int m_ThermalReliefGapValue; // tickness of the gap in thermal reliefs
int m_ThermalReliefCopperBridgeValue; // tickness of the copper bridge in thermal reliefs int m_ThermalReliefCopperBridgeValue; // tickness of the copper bridge in thermal reliefs

View File

@ -30,8 +30,9 @@ ZONE_SETTING::ZONE_SETTING( void )
m_NetcodeSelection = 0; // Net code selection for the current zone m_NetcodeSelection = 0; // Net code selection for the current zone
m_CurrentZone_Layer = 0; // Layer used to create the current zone m_CurrentZone_Layer = 0; // Layer used to create the current zone
m_Zone_HatchingStyle = CPolyLine::DIAGONAL_EDGE; // Option to show the zone area (outlines only, short hatches or full hatches m_Zone_HatchingStyle = CPolyLine::DIAGONAL_EDGE; // Option to show the zone area (outlines only, short hatches or full hatches
m_ArcToSegmentsCount = 16; /* Option to select number of segments to approximate a circle m_ArcToSegmentsCount = ARC_APPROX_SEGMENTS_COUNT_LOW_DEF; /* Option to select number of segments to approximate a circle
* 16 or 32 segments */ * ARC_APPROX_SEGMENTS_COUNT_LOW_DEF
* or ARC_APPROX_SEGMENTS_COUNT_HIGHT_DEF segments */
m_ThermalReliefGapValue = 200; // tickness of the gap in thermal reliefs m_ThermalReliefGapValue = 200; // tickness of the gap in thermal reliefs
m_ThermalReliefCopperBridgeValue = 200; // tickness of the copper bridge in thermal reliefs m_ThermalReliefCopperBridgeValue = 200; // tickness of the copper bridge in thermal reliefs

View File

@ -33,7 +33,7 @@ dialog_copper_zone::dialog_copper_zone( WinEDA_PcbFrame* parent, ZONE_SETTING* z
m_Config = wxGetApp().m_EDA_Config; m_Config = wxGetApp().m_EDA_Config;
m_Zone_Setting = zone_setting; m_Zone_Setting = zone_setting;
m_NetSorting = 1; // 0 = alphabetic sort, 1 = pad count sort, and filtering net names m_NetSorting = 1; // 0 = alphabetic sort, 1 = pad count sort, and filtering net names
m_OnExitCode = ZONE_ABORT; m_OnExitCode = ZONE_ABORT;
if( m_Config ) if( m_Config )
{ {
@ -124,7 +124,8 @@ void dialog_copper_zone::OnInitDialog( wxInitDialogEvent& event )
break; break;
} }
m_ArcApproximationOpt->SetSelection( m_Zone_Setting->m_ArcToSegmentsCount == 32 ? 1 : 0 ); m_ArcApproximationOpt->SetSelection(
m_Zone_Setting->m_ArcToSegmentsCount == ARC_APPROX_SEGMENTS_COUNT_HIGHT_DEF ? 1 : 0 );
/* build copper layers list */ /* build copper layers list */
int layer_cnt = board->GetCopperLayerCount(); int layer_cnt = board->GetCopperLayerCount();
@ -253,7 +254,9 @@ bool dialog_copper_zone::AcceptOptions( bool aPromptForErrors, bool aUseExportab
break; break;
} }
m_Zone_Setting->m_ArcToSegmentsCount = m_ArcApproximationOpt->GetSelection() == 1 ? 32 : 16; m_Zone_Setting->m_ArcToSegmentsCount = m_ArcApproximationOpt->GetSelection() == 1 ?
ARC_APPROX_SEGMENTS_COUNT_HIGHT_DEF :
ARC_APPROX_SEGMENTS_COUNT_LOW_DEF;
if( m_Config ) if( m_Config )
{ {
@ -437,6 +440,7 @@ void dialog_copper_zone::ExportSetupToOtherCopperZones( wxCommandEvent& event )
m_Zone_Setting->ExportSetting( *zone, false ); // false = partiel export m_Zone_Setting->ExportSetting( *zone, false ); // false = partiel export
m_Parent->GetScreen()->SetModify(); m_Parent->GetScreen()->SetModify();
} }
m_OnExitCode = ZONE_EXPORT_VALUES; // values are exported to others zones m_OnExitCode = ZONE_EXPORT_VALUES; // values are exported to others zones
} }

View File

@ -10,6 +10,10 @@
#define U_PCB (PCB_INTERNAL_UNIT / EESCHEMA_INTERNAL_UNIT) #define U_PCB (PCB_INTERNAL_UNIT / EESCHEMA_INTERNAL_UNIT)
// Arcs are appromed by segments: define the number of segments per 360 deg (kicad use 0.1 deg approx:
#define ARC_APPROX_SEGMENTS_COUNT_LOW_DEF 16 // be aware 3600/ARC_APPROX_SEGMENTS_COUNT_LOW_DEF is an integer
#define ARC_APPROX_SEGMENTS_COUNT_HIGHT_DEF 32
/* Flag used in locate functions /* Flag used in locate functions
* the locate ref point is the on grid cursor or the off grid mouse cursor */ * the locate ref point is the on grid cursor or the off grid mouse cursor */
#define CURSEUR_ON_GRILLE (0 << 0) #define CURSEUR_ON_GRILLE (0 << 0)

View File

@ -75,9 +75,10 @@ void AddRoundedEndsSegmentPolygon( Bool_Engine* aBooleng,
// Local Variables: // Local Variables:
/* how many segments are used to create a polygon from a circle: */ /* how many segments are used to create a polygon from a circle: */
static int s_CircleToSegmentsCount = 16; /* default value. the real value will be changed to 32 static int s_CircleToSegmentsCount = ARC_APPROX_SEGMENTS_COUNT_LOW_DEF; /* default value. the real value will be changed to
* if g_Zone_Arc_Approximation == 1 * ARC_APPROX_SEGMENTS_COUNT_HIGHT_DEF
*/ * if m_ArcToSegmentsCount == ARC_APPROX_SEGMENTS_COUNT_HIGHT_DEF
*/
double s_Correction; /* mult coeff used to enlarge rounded and oval pads (and vias) double s_Correction; /* mult coeff used to enlarge rounded and oval pads (and vias)
* because the segment approximation for arcs and circles * because the segment approximation for arcs and circles
* create a smaller gap than a true circle * create a smaller gap than a true circle
@ -129,10 +130,10 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
bool have_poly_to_substract = false; bool have_poly_to_substract = false;
// Set the number of segments in arc approximations // Set the number of segments in arc approximations
if( m_ArcToSegmentsCount == 32 ) if( m_ArcToSegmentsCount == ARC_APPROX_SEGMENTS_COUNT_HIGHT_DEF )
s_CircleToSegmentsCount = 32; s_CircleToSegmentsCount = ARC_APPROX_SEGMENTS_COUNT_HIGHT_DEF;
else else
s_CircleToSegmentsCount = 16; s_CircleToSegmentsCount = ARC_APPROX_SEGMENTS_COUNT_LOW_DEF;
/* calculates the coeff to compensate radius reduction of holes clearance /* calculates the coeff to compensate radius reduction of holes clearance
* due to the segment approx. * due to the segment approx.