From 78ec983632ae2e3cafc7d1eddff17d6ff765709b Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Wed, 25 Oct 2017 09:39:26 +0200 Subject: [PATCH] DRAWSEGMENT fix crash when trying to copy a empty polygon. SHAPE_POLY_SET: fix crash in VertexCount when it is a empty poly set, or when params are incorrect. minor other fixes: warning in degug mode in dialog_dxf_import_base.cpp pcb_painter.cpp: remove a useless debug line. --- common/geometry/shape_poly_set.cpp | 12 +++++++--- include/geometry/shape_poly_set.h | 9 +++++--- pcbnew/class_drawsegment.cpp | 5 ++++- pcbnew/class_edge_mod.cpp | 3 +++ pcbnew/import_dxf/dialog_dxf_import.fbp | 4 ++-- pcbnew/import_dxf/dialog_dxf_import_base.cpp | 23 +++++++++++++++----- pcbnew/import_dxf/dialog_dxf_import_base.h | 4 ++-- pcbnew/pcb_painter.cpp | 5 +---- pcbnew/tools/drawing_tool.cpp | 1 + 9 files changed, 46 insertions(+), 20 deletions(-) diff --git a/common/geometry/shape_poly_set.cpp b/common/geometry/shape_poly_set.cpp index 63ed4ee4b2..01a36ca1fc 100644 --- a/common/geometry/shape_poly_set.cpp +++ b/common/geometry/shape_poly_set.cpp @@ -220,7 +220,10 @@ void SHAPE_POLY_SET::InsertVertex( int aGlobalIndex, VECTOR2I aNewVertex ) int SHAPE_POLY_SET::VertexCount( int aOutline , int aHole ) const { - if( aOutline < 0 ) + if( m_polys.size() == 0 ) // Empty poly set + return 0; + + if( aOutline < 0 ) // Use last outline aOutline += m_polys.size(); int idx; @@ -230,8 +233,11 @@ int SHAPE_POLY_SET::VertexCount( int aOutline , int aHole ) const else idx = aHole + 1; - assert ( aOutline < (int)m_polys.size() ); - assert ( idx < (int)m_polys[aOutline].size() ); + if( aOutline >= (int)m_polys.size() ) // not existing outline + return 0; + + if( idx >= (int)m_polys[aOutline].size() ) // not existing hole + return 0; return m_polys[aOutline][idx].PointCount(); } diff --git a/include/geometry/shape_poly_set.h b/include/geometry/shape_poly_set.h index b82dd9de4b..be04ce3965 100644 --- a/include/geometry/shape_poly_set.h +++ b/include/geometry/shape_poly_set.h @@ -496,8 +496,11 @@ class SHAPE_POLY_SET : public SHAPE ///> Returns the number of holes in a given outline int HoleCount( int aOutline ) const { - if( (aOutline > (int)m_polys.size()) || (m_polys[aOutline].size() < 2) ) + if( ( aOutline < 0 ) || (aOutline >= (int)m_polys.size()) || (m_polys[aOutline].size() < 2) ) return 0; + + // the first polygon in m_polys[aOutline] is the main contour, + // only others are holes: return m_polys[aOutline].size() - 1; } @@ -1053,9 +1056,9 @@ class SHAPE_POLY_SET : public SHAPE POLYGON chamferFilletPolygon( CORNER_MODE aMode, unsigned int aDistance, int aIndex, int aSegments = -1 ); - typedef std::vector Polyset; + typedef std::vector POLYSET; - Polyset m_polys; + POLYSET m_polys; }; #endif diff --git a/pcbnew/class_drawsegment.cpp b/pcbnew/class_drawsegment.cpp index b516dfb4af..d3fbdbf86c 100644 --- a/pcbnew/class_drawsegment.cpp +++ b/pcbnew/class_drawsegment.cpp @@ -409,6 +409,8 @@ const EDA_RECT DRAWSEGMENT::GetBoundingBox() const break; case S_POLYGON: + if( m_Poly.IsEmpty() ) + break; { wxPoint p_end; MODULE* module = GetParentModule(); @@ -442,6 +444,7 @@ const EDA_RECT DRAWSEGMENT::GetBoundingBox() const p_end.y = std::max( p_end.y, pt.y ); } } + bbox.SetEnd( p_end ); break; } @@ -748,7 +751,7 @@ const std::vector DRAWSEGMENT::GetPolyPoints() const { std::vector rv; - if( m_Poly.VertexCount() > 0 ) + if( !m_Poly.IsEmpty() ) { for ( auto iter = m_Poly.CIterate(); iter; iter++ ) { diff --git a/pcbnew/class_edge_mod.cpp b/pcbnew/class_edge_mod.cpp index 268b7c53c8..a080fa885b 100644 --- a/pcbnew/class_edge_mod.cpp +++ b/pcbnew/class_edge_mod.cpp @@ -199,6 +199,9 @@ void EDGE_MODULE::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE draw_mode, break; case S_POLYGON: + if( m_Poly.IsEmpty() ) + break; + { // We must compute absolute coordinates from m_PolyPoints // which are relative to module position, orientation 0 diff --git a/pcbnew/import_dxf/dialog_dxf_import.fbp b/pcbnew/import_dxf/dialog_dxf_import.fbp index f2f699dba0..2a15ff7be5 100644 --- a/pcbnew/import_dxf/dialog_dxf_import.fbp +++ b/pcbnew/import_dxf/dialog_dxf_import.fbp @@ -44,7 +44,7 @@ DIALOG_DXF_IMPORT_BASE - -1,-1 + 455,297 wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER DIALOG_SHIM; dialog_shim.h Import DXF File @@ -1124,7 +1124,7 @@ 5 - wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND + wxALIGN_CENTER_VERTICAL|wxALL 1 1 diff --git a/pcbnew/import_dxf/dialog_dxf_import_base.cpp b/pcbnew/import_dxf/dialog_dxf_import_base.cpp index f3ba8e3eab..a75999d549 100644 --- a/pcbnew/import_dxf/dialog_dxf_import_base.cpp +++ b/pcbnew/import_dxf/dialog_dxf_import_base.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Jun 5 2014) +// C++ code generated with wxFormBuilder (version Aug 4 2017) // http://www.wxformbuilder.org/ // // PLEASE DO "NOT" EDIT THIS FILE! @@ -56,7 +56,14 @@ DIALOG_DXF_IMPORT_BASE::DIALOG_DXF_IMPORT_BASE( wxWindow* parent, wxWindowID id, bSizer6->Add( m_staticText4, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); m_DXFPCBXCoord = new wxTextCtrl( this, wxID_ANY, _("0.0"), wxDefaultPosition, wxDefaultSize, 0 ); - m_DXFPCBXCoord->SetMaxLength( 10 ); + #ifdef __WXGTK__ + if ( !m_DXFPCBXCoord->HasFlag( wxTE_MULTILINE ) ) + { + m_DXFPCBXCoord->SetMaxLength( 10 ); + } + #else + m_DXFPCBXCoord->SetMaxLength( 10 ); + #endif m_DXFPCBXCoord->SetToolTip( _("DXF origin on PCB Grid, X Coordinate") ); bSizer6->Add( m_DXFPCBXCoord, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); @@ -72,7 +79,14 @@ DIALOG_DXF_IMPORT_BASE::DIALOG_DXF_IMPORT_BASE( wxWindow* parent, wxWindowID id, bSizer7->Add( m_staticText5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); m_DXFPCBYCoord = new wxTextCtrl( this, wxID_ANY, _("0.0"), wxDefaultPosition, wxDefaultSize, 0 ); - m_DXFPCBYCoord->SetMaxLength( 10 ); + #ifdef __WXGTK__ + if ( !m_DXFPCBYCoord->HasFlag( wxTE_MULTILINE ) ) + { + m_DXFPCBYCoord->SetMaxLength( 10 ); + } + #else + m_DXFPCBYCoord->SetMaxLength( 10 ); + #endif m_DXFPCBYCoord->SetToolTip( _("DXF origin on PCB Grid, Y Coordinate") ); bSizer7->Add( m_DXFPCBYCoord, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); @@ -112,7 +126,7 @@ DIALOG_DXF_IMPORT_BASE::DIALOG_DXF_IMPORT_BASE( wxWindow* parent, wxWindowID id, bSizer8->Add( m_staticTextBrdlayer, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxTOP, 5 ); m_SelLayerBox = new PCB_LAYER_BOX_SELECTOR( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 ); - bSizer8->Add( m_SelLayerBox, 1, wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 5 ); + bSizer8->Add( m_SelLayerBox, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); bSizerMain->Add( bSizer8, 0, wxALL|wxEXPAND, 5 ); @@ -132,7 +146,6 @@ DIALOG_DXF_IMPORT_BASE::DIALOG_DXF_IMPORT_BASE( wxWindow* parent, wxWindowID id, this->SetSizer( bSizerMain ); this->Layout(); - bSizerMain->Fit( this ); this->Centre( wxBOTH ); diff --git a/pcbnew/import_dxf/dialog_dxf_import_base.h b/pcbnew/import_dxf/dialog_dxf_import_base.h index 7592d9bb08..2d7937750b 100644 --- a/pcbnew/import_dxf/dialog_dxf_import_base.h +++ b/pcbnew/import_dxf/dialog_dxf_import_base.h @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Jun 5 2014) +// C++ code generated with wxFormBuilder (version Aug 4 2017) // http://www.wxformbuilder.org/ // // PLEASE DO "NOT" EDIT THIS FILE! @@ -69,7 +69,7 @@ class DIALOG_DXF_IMPORT_BASE : public DIALOG_SHIM public: - DIALOG_DXF_IMPORT_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Import DXF File"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); + DIALOG_DXF_IMPORT_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Import DXF File"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 455,297 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); ~DIALOG_DXF_IMPORT_BASE(); }; diff --git a/pcbnew/pcb_painter.cpp b/pcbnew/pcb_painter.cpp index 7ab373d3f3..a0d490b633 100644 --- a/pcbnew/pcb_painter.cpp +++ b/pcbnew/pcb_painter.cpp @@ -926,14 +926,11 @@ void PCB_PAINTER::draw( const DRAWSEGMENT* aSegment, int aLayer ) break; case S_RECT: - wxASSERT_MSG( false, wxT( "Not tested yet" ) ); + wxASSERT_MSG( false, "Not tested yet" ); m_gal->DrawRectangle( start, end ); break; case S_ARC: -printf( "S_ARC st %f end %f angle %f\n", -aSegment->GetArcAngleStart()/10.0, (aSegment->GetArcAngleStart() + aSegment->GetAngle())/10.0, -aSegment->GetAngle()/10.0 ); m_gal->DrawArcSegment( start, aSegment->GetRadius(), DECIDEG2RAD( aSegment->GetArcAngleStart() ), DECIDEG2RAD( aSegment->GetArcAngleStart() + aSegment->GetAngle() ), diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index 2c3ca4498d..4987cc750f 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -838,6 +838,7 @@ int DRAWING_TOOL::PlaceDXF( const TOOL_EVENT& aEvent ) modSeg->SetBezControl2( seg->GetBezControl2() ); modSeg->SetBezierPoints( seg->GetBezierPoints() ); modSeg->SetPolyPoints( seg->GetPolyPoints() ); + modSeg->SetLocalCoord(); converted = modSeg; break; }