pcbnew: Avoid wx scaling error

When drawing to a scaled DC, the window doesn't reflect the expected
size if scaled after.  This causes elements drawn on the edge to reflect
back into the drawing area instead of being cut off.

We can simply scale our own values to avoid this issue.

Fixes #3849 | https://gitlab.com/kicad/code/kicad/issues/3849
This commit is contained in:
Seth Hillbrand 2020-02-25 07:36:41 -08:00
parent 7c6f7e6b01
commit 5b6a4d794f
1 changed files with 12 additions and 26 deletions

View File

@ -354,7 +354,7 @@ bool DIALOG_PAD_PRIMITIVE_POLY_PROPS::doValidate( bool aRemoveRedundantCorners )
if( valid && polyline.SelfIntersecting() ) if( valid && polyline.SelfIntersecting() )
{ {
m_warningText->SetLabel( _("Polygon may not be self-intersecting" ) ); m_warningText->SetLabel( _( "Polygon can not be self-intersecting" ) );
valid = false; valid = false;
} }
@ -459,43 +459,29 @@ void DIALOG_PAD_PRIMITIVE_POLY_PROPS::onPaintPolyPanel( wxPaintEvent& event )
dc.SetDeviceOrigin( dc_size.x / 2, dc_size.y / 2 ); dc.SetDeviceOrigin( dc_size.x / 2, dc_size.y / 2 );
// Calculate a suitable scale to fit the available draw area // Calculate a suitable scale to fit the available draw area
wxSize minsize; int minsize( Millimeter2iu( 0.5 ) );
for( unsigned ii = 0; ii < m_currshape.m_Poly.size(); ++ii ) for( unsigned ii = 0; ii < m_currshape.m_Poly.size(); ++ii )
{ {
minsize.x = std::max( minsize.x, std::abs( m_currshape.m_Poly[ii].x ) ); minsize = std::max( minsize, std::abs( m_currshape.m_Poly[ii].x ) );
minsize.y = std::max( minsize.y, std::abs( m_currshape.m_Poly[ii].y ) ); minsize = std::max( minsize, std::abs( m_currshape.m_Poly[ii].y ) );
} }
// The draw origin is the center of the window. // The draw origin is the center of the window.
// Therefore the window size is twice the minsize just calculated // Therefore the window size is twice the minsize just calculated
minsize.x *= 2; minsize *= 2;
minsize.y *= 2; minsize += m_currshape.m_Thickness;
minsize.x += m_currshape.m_Thickness;
minsize.y += m_currshape.m_Thickness;
// Avoid null or too small size:
int mindim = Millimeter2iu( 0.5 );
if( minsize.x < mindim )
minsize.x = mindim;
if( minsize.y < mindim )
minsize.y = mindim;
double scale = std::min( (double) dc_size.x / minsize.x, (double) dc_size.y / minsize.y );
// Give a margin // Give a margin
scale *= 0.9; double scale = std::min( double( dc_size.x ) / minsize, double( dc_size.y ) / minsize ) * 0.9;
dc.SetUserScale( scale, scale );
GRResetPenAndBrush( &dc ); GRResetPenAndBrush( &dc );
// Draw X and Y axis. This is particularly useful to show the // Draw X and Y axis. This is particularly useful to show the
// reference position of basic shape // reference position of basic shape
// Axis are drawn before the polygon to avoid masking segments on axis // Axis are drawn before the polygon to avoid masking segments on axis
GRLine( NULL, &dc, -int( dc_size.x/scale ), 0, int( dc_size.x/scale ), 0, 0, LIGHTBLUE ); // X axis GRLine( NULL, &dc, -dc_size.x, 0, dc_size.x, 0, 0, LIGHTBLUE ); // X axis
GRLine( NULL, &dc, 0, -int( dc_size.y/scale ), 0, int( dc_size.y/scale ), 0, LIGHTBLUE ); // Y axis GRLine( NULL, &dc, 0, -dc_size.y, 0, dc_size.y, 0, LIGHTBLUE ); // Y axis
// Draw polygon. // Draw polygon.
// The selected edge(s) are shown in selectcolor, the others in normalcolor. // The selected edge(s) are shown in selectcolor, the others in normalcolor.
@ -516,7 +502,7 @@ void DIALOG_PAD_PRIMITIVE_POLY_PROPS::onPaintPolyPanel( wxPaintEvent& event )
if( jj >= m_currshape.m_Poly.size() ) if( jj >= m_currshape.m_Poly.size() )
jj = 0; jj = 0;
GRLine( NULL, &dc, m_currshape.m_Poly[ii], m_currshape.m_Poly[jj], m_currshape.m_Thickness, color ); GRLine( NULL, &dc, m_currshape.m_Poly[ii] * scale, m_currshape.m_Poly[jj] * scale, m_currshape.m_Thickness * scale, color );
} }
event.Skip(); event.Skip();