diff --git a/common/eda_item.cpp b/common/eda_item.cpp index 2a31ff0e68..f822dd4838 100644 --- a/common/eda_item.cpp +++ b/common/eda_item.cpp @@ -295,12 +295,8 @@ static struct EDA_ITEM_DESC .Map( LIB_SYMBOL_T, _HKI( "Symbol" ) ) .Map( LIB_ALIAS_T, _HKI( "Alias" ) ) - .Map( LIB_ARC_T, _HKI( "Arc" ) ) - .Map( LIB_CIRCLE_T, _HKI( "Circle" ) ) + .Map( LIB_SHAPE_T, _HKI( "Graphic" ) ) .Map( LIB_TEXT_T, _HKI( "Text" ) ) - .Map( LIB_RECTANGLE_T, _HKI( "Rectangle" ) ) - .Map( LIB_POLYLINE_T, _HKI( "Polyline" ) ) - .Map( LIB_BEZIER_T, _HKI( "Bezier" ) ) .Map( LIB_PIN_T, _HKI( "Pin" ) ) .Map( LIB_FIELD_T, _HKI( "Symbol Field" ) ) diff --git a/common/eda_shape.cpp b/common/eda_shape.cpp index bc677b6fee..663032d9ad 100644 --- a/common/eda_shape.cpp +++ b/common/eda_shape.cpp @@ -35,12 +35,11 @@ #include -EDA_SHAPE::EDA_SHAPE( SHAPE_T aType, int aDefaultLineWidth ) : +EDA_SHAPE::EDA_SHAPE( SHAPE_T aType, int aLineWidth, FILL_T aFill ) : m_shape( aType ), - m_width( aDefaultLineWidth ) + m_width( aLineWidth ), + m_fill( aFill ) { - m_arcAngle = 0; - m_filled = false; } @@ -173,9 +172,6 @@ void EDA_SHAPE::scale( double aScale ) pt.y = KiROUND( pt.y * aScale ); }; - int radius = GetRadius(); - - // specific parameters: switch( m_shape ) { case SHAPE_T::ARC: @@ -188,7 +184,7 @@ void EDA_SHAPE::scale( double aScale ) case SHAPE_T::CIRCLE: // ring or circle scalePt( m_start ); - m_end.x = m_start.x + KiROUND( radius * aScale ); + m_end.x = m_start.x + KiROUND( GetRadius() * aScale ); m_end.y = m_start.y; break; @@ -224,10 +220,13 @@ void EDA_SHAPE::rotate( const wxPoint& aRotCentre, double aAngle ) { switch( m_shape ) { - case SHAPE_T::ARC: case SHAPE_T::SEGMENT: case SHAPE_T::CIRCLE: - // these can all be done by just rotating the constituent points + RotatePoint( &m_start, aRotCentre, aAngle ); + RotatePoint( &m_end, aRotCentre, aAngle ); + break; + + case SHAPE_T::ARC: RotatePoint( &m_start, aRotCentre, aAngle ); RotatePoint( &m_end, aRotCentre, aAngle ); RotatePoint( &m_arcCenter, aRotCentre, aAngle ); @@ -280,20 +279,48 @@ void EDA_SHAPE::flip( const wxPoint& aCentre, bool aFlipLeftRight ) { case SHAPE_T::SEGMENT: case SHAPE_T::RECT: + if( aFlipLeftRight ) + { + m_start.x = aCentre.x - ( m_start.x - aCentre.x ); + m_end.x = aCentre.x - ( m_end.x - aCentre.x ); + } + else + { + m_start.y = aCentre.y - ( m_start.y - aCentre.y ); + m_end.y = aCentre.y - ( m_end.y - aCentre.y ); + } + + std::swap( m_start, m_end ); + break; + case SHAPE_T::CIRCLE: + if( aFlipLeftRight ) + { + m_start.x = aCentre.x - ( m_start.x - aCentre.x ); + m_end.x = aCentre.x - ( m_end.x - aCentre.x ); + } + else + { + m_start.y = aCentre.y - ( m_start.y - aCentre.y ); + m_end.y = aCentre.y - ( m_end.y - aCentre.y ); + } + break; + case SHAPE_T::ARC: if( aFlipLeftRight ) { - m_start.x = aCentre.x - ( m_start.x - aCentre.x ); - m_end.x = aCentre.x - ( m_end.x - aCentre.x ); + m_start.x = aCentre.x - ( m_start.x - aCentre.x ); + m_end.x = aCentre.x - ( m_end.x - aCentre.x ); m_arcCenter.x = aCentre.x - ( m_arcCenter.x - aCentre.x ); } else { - m_start.y = aCentre.y - ( m_start.y - aCentre.y ); - m_end.y = aCentre.y - ( m_end.y - aCentre.y ); + m_start.y = aCentre.y - ( m_start.y - aCentre.y ); + m_end.y = aCentre.y - ( m_end.y - aCentre.y ); m_arcCenter.y = aCentre.y - ( m_arcCenter.y - aCentre.y ); } + + std::swap( m_start, m_end ); break; case SHAPE_T::POLY: @@ -301,7 +328,6 @@ void EDA_SHAPE::flip( const wxPoint& aCentre, bool aFlipLeftRight ) break; case SHAPE_T::BEZIER: - { if( aFlipLeftRight ) { m_start.x = aCentre.x - ( m_start.x - aCentre.x ); @@ -318,10 +344,11 @@ void EDA_SHAPE::flip( const wxPoint& aCentre, bool aFlipLeftRight ) } // Rebuild the poly points shape - std::vector ctrlPoints = { m_start, m_bezierC1, m_bezierC2, m_end }; - BEZIER_POLY converter( ctrlPoints ); - converter.GetPoly( m_bezierPoints, m_width ); - } + { + std::vector ctrlPoints = { m_start, m_bezierC1, m_bezierC2, m_end }; + BEZIER_POLY converter( ctrlPoints ); + converter.GetPoly( m_bezierPoints, m_width ); + } break; default: @@ -512,17 +539,17 @@ void EDA_SHAPE::ShapeGetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector 0 ) + maxdist += m_width / 2; switch( m_shape ) { @@ -666,6 +696,7 @@ bool EDA_SHAPE::hitTest( const wxPoint& aPosition, int aAccuracy ) const // this relative arc should be < arc angle if arc angle > 0 (CW arc) // and > arc angle if arc angle < 0 (CCW arc) double arc_angle_start = GetArcAngleStart(); // Always 0.0 ... 360 deg, in 0.1 deg + double arc_swept_angle = GetArcAngleEnd() - arc_angle_start; double arc_hittest = ArcTangente( relPos.y, relPos.x ); @@ -677,10 +708,10 @@ bool EDA_SHAPE::hitTest( const wxPoint& aPosition, int aAccuracy ) const // Check angle: inside the arc angle when it is > 0 and outside the not drawn arc when // it is < 0 - if( GetArcAngle() >= 0.0 ) - return arc_hittest <= GetArcAngle(); + if( arc_swept_angle >= 0.0 ) + return arc_hittest <= arc_swept_angle; else - return arc_hittest >= ( 3600.0 + GetArcAngle() ); + return arc_hittest >= ( 3600.0 + arc_swept_angle ); } else { @@ -735,7 +766,7 @@ bool EDA_SHAPE::hitTest( const wxPoint& aPosition, int aAccuracy ) const } default: - wxFAIL_MSG( "EDA_SHAPE::hitTest(point) not implemented for " + SHAPE_T_asString() ); + UNIMPLEMENTED_FOR( SHAPE_T_asString() ); return false; } } @@ -841,24 +872,36 @@ bool EDA_SHAPE::hitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) if( getParentOrientation() ) orientation = -DECIDEG2RAD( getParentOrientation() ); - SHAPE_POLY_SET poly{ m_poly }; + SHAPE_LINE_CHAIN poly = m_poly.Outline( 0 ); poly.Rotate( orientation ); poly.Move( offset ); - int count = poly.TotalVertices(); + int count = poly.GetPointCount(); for( int ii = 0; ii < count; ii++ ) { - VECTOR2I vertex = poly.CVertex( ii ); - VECTOR2I vertexNext = poly.CVertex( ( ii + 1 ) % count ); + VECTOR2I vertex = poly.GetPoint( ii ); // Test if the point is within aRect if( arect.Contains( ( wxPoint ) vertex ) ) return true; - // Test if this edge intersects aRect - if( arect.Intersects( ( wxPoint ) vertex, ( wxPoint ) vertexNext ) ) - return true; + if( ii + 1 < count ) + { + VECTOR2I vertexNext = poly.GetPoint( ii + 1 ); + + // Test if this edge intersects aRect + if( arect.Intersects( ( wxPoint ) vertex, ( wxPoint ) vertexNext ) ) + return true; + } + else if( poly.IsClosed() ) + { + VECTOR2I vertexNext = poly.GetPoint( 0 ); + + // Test if this edge intersects aRect + if( arect.Intersects( ( wxPoint ) vertex, ( wxPoint ) vertexNext ) ) + return true; + } } return false; @@ -1170,13 +1213,13 @@ void EDA_SHAPE::SwapShape( EDA_SHAPE* aImage ) int EDA_SHAPE::Compare( const EDA_SHAPE* aOther ) const { -#define TEST( a, b ) { if( a != b ) return a < b; } +#define TEST( a, b ) { if( a != b ) return a - b; } #define TEST_PT( a, b ) { TEST( a.x, b.x ); TEST( a.y, b.y ); } TEST_PT( m_start, aOther->m_start ); TEST_PT( m_end, aOther->m_end ); - TEST( m_shape, aOther->m_shape ); + TEST( (int) m_shape, (int) aOther->m_shape ); if( m_shape == SHAPE_T::ARC ) { @@ -1190,15 +1233,13 @@ int EDA_SHAPE::Compare( const EDA_SHAPE* aOther ) const else if( m_shape == SHAPE_T::POLY ) { TEST( m_poly.TotalVertices(), aOther->m_poly.TotalVertices() ); + + for( int ii = 0; ii < m_poly.TotalVertices(); ++ii ) + TEST_PT( m_poly.CVertex( ii ), aOther->m_poly.CVertex( ii ) ); } - for( size_t ii = 0; ii < m_bezierPoints.size(); ++ii ) - TEST_PT( m_bezierPoints[ii], aOther->m_bezierPoints[ii] ); - - for( int ii = 0; ii < m_poly.TotalVertices(); ++ii ) - TEST_PT( m_poly.CVertex( ii ), aOther->m_poly.CVertex( ii ) ); - TEST( m_width, aOther->m_width ); + TEST( (int) m_fill, (int) aOther->m_fill ); return 0; } \ No newline at end of file diff --git a/common/eda_text.cpp b/common/eda_text.cpp index cc3a368078..9218c0e5f0 100644 --- a/common/eda_text.cpp +++ b/common/eda_text.cpp @@ -651,7 +651,7 @@ double EDA_TEXT::GetDrawRotation() const int EDA_TEXT::Compare( const EDA_TEXT* aOther ) const { -#define TEST( a, b ) { if( a != b ) return a < b; } +#define TEST( a, b ) { if( a != b ) return a - b; } #define TEST_PT( a, b ) { TEST( a.x, b.x ); TEST( a.y, b.y ); } TEST_PT( m_e.pos, aOther->m_e.pos ); diff --git a/common/plotters/DXF_plotter.cpp b/common/plotters/DXF_plotter.cpp index 0935fe9142..b2157d050b 100644 --- a/common/plotters/DXF_plotter.cpp +++ b/common/plotters/DXF_plotter.cpp @@ -409,7 +409,7 @@ void DXF_PLOTTER::SetColor( const COLOR4D& color ) } -void DXF_PLOTTER::Rect( const wxPoint& p1, const wxPoint& p2, FILL_TYPE fill, int width ) +void DXF_PLOTTER::Rect( const wxPoint& p1, const wxPoint& p2, FILL_T fill, int width ) { wxASSERT( m_outputFile ); MoveTo( p1 ); @@ -420,7 +420,7 @@ void DXF_PLOTTER::Rect( const wxPoint& p1, const wxPoint& p2, FILL_TYPE fill, in } -void DXF_PLOTTER::Circle( const wxPoint& centre, int diameter, FILL_TYPE fill, int width ) +void DXF_PLOTTER::Circle( const wxPoint& centre, int diameter, FILL_T fill, int width ) { wxASSERT( m_outputFile ); double radius = userToDeviceSize( diameter / 2 ); @@ -430,14 +430,13 @@ void DXF_PLOTTER::Circle( const wxPoint& centre, int diameter, FILL_TYPE fill, i { wxString cname = getDXFColorName( m_currentColor ); - if( fill == FILL_TYPE::NO_FILL ) + if( fill == FILL_T::NO_FILL ) { fprintf( m_outputFile, "0\nCIRCLE\n8\n%s\n10\n%g\n20\n%g\n40\n%g\n", TO_UTF8( cname ), centre_dev.x, centre_dev.y, radius ); } - - if( fill == FILL_TYPE::FILLED_SHAPE ) + else if( fill == FILL_T::FILLED_SHAPE ) { double r = radius*0.5; fprintf( m_outputFile, "0\nPOLYLINE\n" ); @@ -455,8 +454,8 @@ void DXF_PLOTTER::Circle( const wxPoint& centre, int diameter, FILL_TYPE fill, i } -void DXF_PLOTTER::PlotPoly( const std::vector& aCornerList, - FILL_TYPE aFill, int aWidth, void* aData ) +void DXF_PLOTTER::PlotPoly( const std::vector& aCornerList, FILL_T aFill, int aWidth, + void* aData ) { if( aCornerList.size() <= 1 ) return; @@ -472,7 +471,7 @@ void DXF_PLOTTER::PlotPoly( const std::vector& aCornerList, LineTo( aCornerList[ii] ); // Close polygon if 'fill' requested - if( aFill != FILL_TYPE::NO_FILL ) + if( aFill != FILL_T::NO_FILL ) { if( aCornerList[last] != aCornerList[0] ) LineTo( aCornerList[0] ); @@ -485,7 +484,7 @@ void DXF_PLOTTER::PlotPoly( const std::vector& aCornerList, // if the polygon outline has thickness, and is not filled // (i.e. is a polyline) plot outlines with thick segments - if( aWidth > 0 && aFill == FILL_TYPE::NO_FILL ) + if( aWidth > 0 && aFill == FILL_T::NO_FILL ) { MoveTo( aCornerList[0] ); @@ -610,7 +609,7 @@ void DXF_PLOTTER::ThickSegment( const wxPoint& aStart, const wxPoint& aEnd, int if( cornerList[0] != cornerList[cornerList.size() - 1] ) cornerList.push_back( cornerList[0] ); - PlotPoly( cornerList, FILL_TYPE::NO_FILL ); + PlotPoly( cornerList, FILL_T::NO_FILL ); } else { @@ -621,7 +620,7 @@ void DXF_PLOTTER::ThickSegment( const wxPoint& aStart, const wxPoint& aEnd, int void DXF_PLOTTER::Arc( const wxPoint& centre, double StAngle, double EndAngle, int radius, - FILL_TYPE fill, int width ) + FILL_T fill, int width ) { wxASSERT( m_outputFile ); @@ -671,7 +670,7 @@ void DXF_PLOTTER::FlashPadCircle( const wxPoint& pos, int diametre, OUTLINE_MODE trace_mode, void* aData ) { wxASSERT( m_outputFile ); - Circle( pos, diametre, FILL_TYPE::NO_FILL ); + Circle( pos, diametre, FILL_T::NO_FILL ); } diff --git a/common/plotters/GERBER_plotter.cpp b/common/plotters/GERBER_plotter.cpp index 3255b77c02..895c8cf4fd 100644 --- a/common/plotters/GERBER_plotter.cpp +++ b/common/plotters/GERBER_plotter.cpp @@ -793,7 +793,7 @@ void GERBER_PLOTTER::PenTo( const wxPoint& aPos, char plume ) } -void GERBER_PLOTTER::Rect( const wxPoint& p1, const wxPoint& p2, FILL_TYPE fill, int width ) +void GERBER_PLOTTER::Rect( const wxPoint& p1, const wxPoint& p2, FILL_T fill, int width ) { std::vector< wxPoint > cornerList; @@ -811,15 +811,15 @@ void GERBER_PLOTTER::Rect( const wxPoint& p1, const wxPoint& p2, FILL_TYPE fill, } -void GERBER_PLOTTER::Circle( const wxPoint& aCenter, int aDiameter, FILL_TYPE aFill, int aWidth ) +void GERBER_PLOTTER::Circle( const wxPoint& aCenter, int aDiameter, FILL_T aFill, int aWidth ) { Arc( aCenter, 0, 3600, aDiameter / 2, aFill, aWidth ); } -void GERBER_PLOTTER::Arc( const wxPoint& aCenter, double aStAngle, double aEndAngle, - int aRadius, FILL_TYPE aFill, int aWidth ) +void GERBER_PLOTTER::Arc( const wxPoint& aCenter, double aStAngle, double aEndAngle, int aRadius, + FILL_T aFill, int aWidth ) { SetCurrentLineWidth( aWidth ); @@ -920,7 +920,7 @@ void GERBER_PLOTTER::PlotGerberRegion( const SHAPE_LINE_CHAIN& aPoly, void* aDat } } - PlotPoly( aPoly, FILL_TYPE::FILLED_SHAPE, 0 , gbr_metadata ); + PlotPoly( aPoly, FILL_T::FILLED_SHAPE, 0 , gbr_metadata ); // Clear the TA attribute, to avoid the next item to inherit it: if( clearTA_AperFunction ) @@ -957,7 +957,7 @@ void GERBER_PLOTTER::PlotGerberRegion( const std::vector< wxPoint >& aCornerList } } - PlotPoly( aCornerList, FILL_TYPE::FILLED_SHAPE, 0, gbr_metadata ); + PlotPoly( aCornerList, FILL_T::FILLED_SHAPE, 0, gbr_metadata ); // Clear the TA attribute, to avoid the next item to inherit it: if( clearTA_AperFunction ) @@ -974,7 +974,7 @@ void GERBER_PLOTTER::PlotGerberRegion( const std::vector< wxPoint >& aCornerList } -void GERBER_PLOTTER::PlotPoly( const SHAPE_LINE_CHAIN& aPoly, FILL_TYPE aFill, int aWidth, +void GERBER_PLOTTER::PlotPoly( const SHAPE_LINE_CHAIN& aPoly, FILL_T aFill, int aWidth, void* aData ) { if( aPoly.CPoints().size() <= 1 ) @@ -988,7 +988,7 @@ void GERBER_PLOTTER::PlotPoly( const SHAPE_LINE_CHAIN& aPoly, FILL_TYPE aFill, i if( gbr_metadata ) formatNetAttribute( &gbr_metadata->m_NetlistMetadata ); - if( aFill != FILL_TYPE::NO_FILL ) + if( aFill != FILL_T::NO_FILL ) { fputs( "G36*\n", m_outputFile ); @@ -1045,15 +1045,15 @@ void GERBER_PLOTTER::PlotPoly( const SHAPE_LINE_CHAIN& aPoly, FILL_TYPE aFill, i // Ensure the thick outline is closed for filled polygons // (if not filled, could be only a polyline) - if( aFill != FILL_TYPE::NO_FILL && ( aPoly.CPoint( 0 ) != aPoly.CPoint( -1 ) ) ) + if( aFill != FILL_T::NO_FILL && ( aPoly.CPoint( 0 ) != aPoly.CPoint( -1 ) ) ) LineTo( wxPoint( aPoly.CPoint( 0 ) ) ); PenFinish(); } } -void GERBER_PLOTTER::PlotPoly( const std::vector< wxPoint >& aCornerList, - FILL_TYPE aFill, int aWidth, void * aData ) +void GERBER_PLOTTER::PlotPoly( const std::vector< wxPoint >& aCornerList, FILL_T aFill, int aWidth, + void * aData ) { if( aCornerList.size() <= 1 ) return; @@ -1066,7 +1066,7 @@ void GERBER_PLOTTER::PlotPoly( const std::vector< wxPoint >& aCornerList, if( gbr_metadata ) formatNetAttribute( &gbr_metadata->m_NetlistMetadata ); - if( aFill != FILL_TYPE::NO_FILL ) + if( aFill != FILL_T::NO_FILL ) { fputs( "G36*\n", m_outputFile ); @@ -1094,7 +1094,7 @@ void GERBER_PLOTTER::PlotPoly( const std::vector< wxPoint >& aCornerList, // Ensure the thick outline is closed for filled polygons // (if not filled, could be only a polyline) - if( aFill != FILL_TYPE::NO_FILL &&( aCornerList[aCornerList.size() - 1] != aCornerList[0] ) ) + if( aFill != FILL_T::NO_FILL && ( aCornerList[aCornerList.size() - 1] != aCornerList[0] ) ) LineTo( aCornerList[0] ); PenFinish(); @@ -1134,16 +1134,15 @@ void GERBER_PLOTTER::ThickArc( const wxPoint& centre, double StAngle, double End if( tracemode == FILLED ) { - Arc( centre, StAngle, EndAngle, radius, FILL_TYPE::NO_FILL, DO_NOT_SET_LINE_WIDTH ); + Arc( centre, StAngle, EndAngle, radius, FILL_T::NO_FILL, DO_NOT_SET_LINE_WIDTH ); } else { SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH ); - Arc( centre, StAngle, EndAngle, - radius - ( width - m_currentPenWidth ) / 2, FILL_TYPE::NO_FILL, + Arc( centre, StAngle, EndAngle, radius - ( width - m_currentPenWidth ) / 2, FILL_T::NO_FILL, + DO_NOT_SET_LINE_WIDTH ); + Arc( centre, StAngle, EndAngle, radius + ( width - m_currentPenWidth ) / 2, FILL_T::NO_FILL, DO_NOT_SET_LINE_WIDTH ); - Arc( centre, StAngle, EndAngle, radius + ( width - m_currentPenWidth ) / 2, - FILL_TYPE::NO_FILL, DO_NOT_SET_LINE_WIDTH ); } } @@ -1159,7 +1158,7 @@ void GERBER_PLOTTER::ThickRect( const wxPoint& p1, const wxPoint& p2, int width, if( tracemode == FILLED ) { - Rect( p1, p2, FILL_TYPE::NO_FILL, DO_NOT_SET_LINE_WIDTH ); + Rect( p1, p2, FILL_T::NO_FILL, DO_NOT_SET_LINE_WIDTH ); } else { @@ -1168,12 +1167,12 @@ void GERBER_PLOTTER::ThickRect( const wxPoint& p1, const wxPoint& p2, int width, p1.y - (width - m_currentPenWidth) / 2 ); wxPoint offsetp2( p2.x + (width - m_currentPenWidth) / 2, p2.y + (width - m_currentPenWidth) / 2 ); - Rect( offsetp1, offsetp2, FILL_TYPE::NO_FILL, -1 ); + Rect( offsetp1, offsetp2, FILL_T::NO_FILL, -1 ); offsetp1.x += (width - m_currentPenWidth); offsetp1.y += (width - m_currentPenWidth); offsetp2.x -= (width - m_currentPenWidth); offsetp2.y -= (width - m_currentPenWidth); - Rect( offsetp1, offsetp2, FILL_TYPE::NO_FILL, DO_NOT_SET_LINE_WIDTH ); + Rect( offsetp1, offsetp2, FILL_T::NO_FILL, DO_NOT_SET_LINE_WIDTH ); } } @@ -1189,15 +1188,15 @@ void GERBER_PLOTTER::ThickCircle( const wxPoint& pos, int diametre, int width, if( tracemode == FILLED ) { - Circle( pos, diametre, FILL_TYPE::NO_FILL, DO_NOT_SET_LINE_WIDTH ); + Circle( pos, diametre, FILL_T::NO_FILL, DO_NOT_SET_LINE_WIDTH ); } else { SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH, gbr_metadata ); - Circle( pos, diametre - (width - m_currentPenWidth), - FILL_TYPE::NO_FILL, DO_NOT_SET_LINE_WIDTH ); - Circle( pos, diametre + (width - m_currentPenWidth), - FILL_TYPE::NO_FILL, DO_NOT_SET_LINE_WIDTH ); + Circle( pos, diametre - (width - m_currentPenWidth), FILL_T::NO_FILL, + DO_NOT_SET_LINE_WIDTH ); + Circle( pos, diametre + (width - m_currentPenWidth), FILL_T::NO_FILL, + DO_NOT_SET_LINE_WIDTH ); } } @@ -1217,17 +1216,18 @@ void GERBER_PLOTTER::FilledCircle( const wxPoint& pos, int diametre, // Draw a circle of diameter = diameter/2 with a line thickness = radius, // To create a filled circle SetCurrentLineWidth( diametre/2, gbr_metadata ); - Circle( pos, diametre/2, FILL_TYPE::NO_FILL, DO_NOT_SET_LINE_WIDTH ); + Circle( pos, diametre/2, FILL_T::NO_FILL, DO_NOT_SET_LINE_WIDTH ); } else { SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH, gbr_metadata ); - Circle( pos, diametre, FILL_TYPE::NO_FILL, DO_NOT_SET_LINE_WIDTH ); + Circle( pos, diametre, FILL_T::NO_FILL, DO_NOT_SET_LINE_WIDTH ); } } -void GERBER_PLOTTER::FlashPadCircle( const wxPoint& pos, int diametre, OUTLINE_MODE trace_mode, void* aData ) +void GERBER_PLOTTER::FlashPadCircle( const wxPoint& pos, int diametre, OUTLINE_MODE trace_mode, + void* aData ) { wxSize size( diametre, diametre ); GBR_METADATA* gbr_metadata = static_cast( aData ); @@ -1239,7 +1239,7 @@ void GERBER_PLOTTER::FlashPadCircle( const wxPoint& pos, int diametre, OUTLINE_M SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH ); - Circle( pos, diametre - m_currentPenWidth, FILL_TYPE::NO_FILL, DO_NOT_SET_LINE_WIDTH ); + Circle( pos, diametre - m_currentPenWidth, FILL_T::NO_FILL, DO_NOT_SET_LINE_WIDTH ); } else { @@ -1363,7 +1363,7 @@ void GERBER_PLOTTER::FlashPadRect( const wxPoint& pos, const wxSize& aSize, pos.y - (size.y - GetCurrentLineWidth()) / 2 ), wxPoint( pos.x + (size.x - GetCurrentLineWidth()) / 2, pos.y + (size.y - GetCurrentLineWidth()) / 2 ), - FILL_TYPE::NO_FILL, GetCurrentLineWidth() ); + FILL_T::NO_FILL, GetCurrentLineWidth() ); } else { @@ -1446,7 +1446,7 @@ void GERBER_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aS cornerList.push_back( cornerList[0] ); // plot outlines - PlotPoly( cornerList, FILL_TYPE::NO_FILL, GetCurrentLineWidth(), gbr_metadata ); + PlotPoly( cornerList, FILL_T::NO_FILL, GetCurrentLineWidth(), gbr_metadata ); } else { @@ -1663,7 +1663,7 @@ void GERBER_PLOTTER::FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize if( aTraceMode == SKETCH ) { - PlotPoly( cornerList, FILL_TYPE::NO_FILL, GetCurrentLineWidth(), &gbr_metadata ); + PlotPoly( cornerList, FILL_T::NO_FILL, GetCurrentLineWidth(), &gbr_metadata ); } else { @@ -1734,7 +1734,7 @@ void GERBER_PLOTTER::FlashPadChamferRoundRect( const wxPoint& aShapePos, const w cornerList.push_back( cornerList[0] ); if( aPlotMode == SKETCH ) - PlotPoly( cornerList, FILL_TYPE::NO_FILL, GetCurrentLineWidth(), &gbr_metadata ); + PlotPoly( cornerList, FILL_T::NO_FILL, GetCurrentLineWidth(), &gbr_metadata ); else { #ifdef GBR_USE_MACROS_FOR_CHAMFERED_ROUND_RECT @@ -1847,7 +1847,7 @@ void GERBER_PLOTTER::FlashPadTrapez( const wxPoint& aPadPos, const wxPoint* aCo if( aTrace_Mode == SKETCH ) { - PlotPoly( cornerList, FILL_TYPE::NO_FILL, GetCurrentLineWidth(), &metadata ); + PlotPoly( cornerList, FILL_T::NO_FILL, GetCurrentLineWidth(), &metadata ); return; } @@ -1903,7 +1903,7 @@ void GERBER_PLOTTER::FlashRegularPolygon( const wxPoint& aShapePos, int aDiamete cornerList.push_back( cornerList[0] ); // Close the shape - PlotPoly( cornerList, FILL_TYPE::NO_FILL, GetCurrentLineWidth(), &gbr_metadata ); + PlotPoly( cornerList, FILL_T::NO_FILL, GetCurrentLineWidth(), &gbr_metadata ); } else { diff --git a/common/plotters/HPGL_plotter.cpp b/common/plotters/HPGL_plotter.cpp index 0e04de36e7..e728b7e8c0 100644 --- a/common/plotters/HPGL_plotter.cpp +++ b/common/plotters/HPGL_plotter.cpp @@ -383,7 +383,7 @@ void HPGL_PLOTTER::SetPenDiameter( double diameter ) } -void HPGL_PLOTTER::Rect( const wxPoint& p1, const wxPoint& p2, FILL_TYPE fill, int width ) +void HPGL_PLOTTER::Rect( const wxPoint& p1, const wxPoint& p2, FILL_T fill, int width ) { wxASSERT( m_outputFile ); @@ -392,7 +392,7 @@ void HPGL_PLOTTER::Rect( const wxPoint& p1, const wxPoint& p2, FILL_TYPE fill, i MoveTo( p1 ); - if( fill == FILL_TYPE::FILLED_SHAPE ) + if( fill == FILL_T::FILLED_SHAPE ) { startOrAppendItem( p1dev, wxString::Format( "RA %.0f,%.0f;", p2dev.x, p2dev.y ) ); } @@ -405,7 +405,7 @@ void HPGL_PLOTTER::Rect( const wxPoint& p1, const wxPoint& p2, FILL_TYPE fill, i } -void HPGL_PLOTTER::Circle( const wxPoint& centre, int diameter, FILL_TYPE fill, int width ) +void HPGL_PLOTTER::Circle( const wxPoint& centre, int diameter, FILL_T fill, int width ) { wxASSERT( m_outputFile ); double radius = userToDeviceSize( diameter / 2 ); @@ -425,7 +425,7 @@ void HPGL_PLOTTER::Circle( const wxPoint& centre, int diameter, FILL_TYPE fill, chord_degrees = 45; } - if( fill == FILL_TYPE::FILLED_SHAPE ) + if( fill == FILL_T::FILLED_SHAPE ) { // Draw the filled area MoveTo( centre ); @@ -451,8 +451,8 @@ void HPGL_PLOTTER::Circle( const wxPoint& centre, int diameter, FILL_TYPE fill, } -void HPGL_PLOTTER::PlotPoly( const std::vector& aCornerList, FILL_TYPE aFill, - int aWidth, void* aData ) +void HPGL_PLOTTER::PlotPoly( const std::vector& aCornerList, FILL_T aFill, int aWidth, + void* aData ) { if( aCornerList.size() <= 1 ) return; @@ -468,7 +468,7 @@ void HPGL_PLOTTER::PlotPoly( const std::vector& aCornerList, FILL_TYPE MoveTo( aCornerList[0] ); startItem( userToDeviceCoordinates( aCornerList[0] ) ); - if( aFill == FILL_TYPE::FILLED_SHAPE ) + if( aFill == FILL_T::FILLED_SHAPE ) { // Draw the filled area SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH ); @@ -493,7 +493,7 @@ void HPGL_PLOTTER::PlotPoly( const std::vector& aCornerList, FILL_TYPE LineTo( aCornerList[ii] ); // Always close polygon if filled. - if( aFill != FILL_TYPE::NO_FILL ) + if( aFill != FILL_T::NO_FILL ) { int ii = aCornerList.size() - 1; @@ -563,7 +563,7 @@ void HPGL_PLOTTER::ThickSegment( const wxPoint& start, const wxPoint& end, void HPGL_PLOTTER::Arc( const wxPoint& centre, double StAngle, double EndAngle, int radius, - FILL_TYPE fill, int width ) + FILL_T fill, int width ) { wxASSERT( m_outputFile ); double angle; @@ -725,7 +725,7 @@ void HPGL_PLOTTER::FlashPadRect( const wxPoint& pos, const wxSize& padsize, corners[ii] += pos; } - PlotPoly( corners, trace_mode == FILLED ? FILL_TYPE::FILLED_SHAPE : FILL_TYPE::NO_FILL ); + PlotPoly( corners, trace_mode == FILLED ? FILL_T::FILLED_SHAPE : FILL_T::NO_FILL ); } @@ -763,7 +763,7 @@ void HPGL_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSiz if( cornerList.back() != cornerList.front() ) cornerList.push_back( cornerList.front() ); - PlotPoly( cornerList, aTraceMode == FILLED ? FILL_TYPE::FILLED_SHAPE : FILL_TYPE::NO_FILL ); + PlotPoly( cornerList, aTraceMode == FILLED ? FILL_T::FILLED_SHAPE : FILL_T::NO_FILL ); } @@ -785,7 +785,7 @@ void HPGL_PLOTTER::FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize, if( cornerList.back() != cornerList.front() ) cornerList.push_back( cornerList.front() ); - PlotPoly( cornerList, aTraceMode == FILLED ? FILL_TYPE::FILLED_SHAPE : FILL_TYPE::NO_FILL ); + PlotPoly( cornerList, aTraceMode == FILLED ? FILL_T::FILLED_SHAPE : FILL_T::NO_FILL ); } } @@ -807,7 +807,7 @@ void HPGL_PLOTTER::FlashPadTrapez( const wxPoint& aPadPos, const wxPoint* aCorne // Close polygon cornerList.push_back( cornerList.front() ); - PlotPoly( cornerList, aTraceMode == FILLED ? FILL_TYPE::FILLED_SHAPE : FILL_TYPE::NO_FILL ); + PlotPoly( cornerList, aTraceMode == FILLED ? FILL_T::FILLED_SHAPE : FILL_T::NO_FILL ); } diff --git a/common/plotters/PDF_plotter.cpp b/common/plotters/PDF_plotter.cpp index 4b70ed2493..7d88ff0957 100644 --- a/common/plotters/PDF_plotter.cpp +++ b/common/plotters/PDF_plotter.cpp @@ -190,7 +190,7 @@ void PDF_PLOTTER::SetDash( PLOT_DASH_TYPE dashed ) } -void PDF_PLOTTER::Rect( const wxPoint& p1, const wxPoint& p2, FILL_TYPE fill, int width ) +void PDF_PLOTTER::Rect( const wxPoint& p1, const wxPoint& p2, FILL_T fill, int width ) { wxASSERT( workFile ); DPOINT p1_dev = userToDeviceCoordinates( p1 ); @@ -198,11 +198,11 @@ void PDF_PLOTTER::Rect( const wxPoint& p1, const wxPoint& p2, FILL_TYPE fill, in SetCurrentLineWidth( width ); fprintf( workFile, "%g %g %g %g re %c\n", p1_dev.x, p1_dev.y, - p2_dev.x - p1_dev.x, p2_dev.y - p1_dev.y, fill == FILL_TYPE::NO_FILL ? 'S' : 'B' ); + p2_dev.x - p1_dev.x, p2_dev.y - p1_dev.y, fill == FILL_T::NO_FILL ? 'S' : 'B' ); } -void PDF_PLOTTER::Circle( const wxPoint& pos, int diametre, FILL_TYPE aFill, int width ) +void PDF_PLOTTER::Circle( const wxPoint& pos, int diametre, FILL_T aFill, int width ) { wxASSERT( workFile ); DPOINT pos_dev = userToDeviceCoordinates( pos ); @@ -217,9 +217,9 @@ void PDF_PLOTTER::Circle( const wxPoint& pos, int diametre, FILL_TYPE aFill, int SetCurrentLineWidth( width ); // If diameter is less than width, switch to filled mode - if( aFill == FILL_TYPE::NO_FILL && diametre < width ) + if( aFill == FILL_T::NO_FILL && diametre < width ) { - aFill = FILL_TYPE::FILLED_SHAPE; + aFill = FILL_T::FILLED_SHAPE; SetCurrentLineWidth( 0 ); radius = userToDeviceSize( ( diametre / 2.0 ) + ( width / 2.0 ) ); @@ -251,18 +251,18 @@ void PDF_PLOTTER::Circle( const wxPoint& pos, int diametre, FILL_TYPE aFill, int pos_dev.x - radius, pos_dev.y - magic, pos_dev.x - radius, pos_dev.y, - aFill == FILL_TYPE::NO_FILL ? 's' : 'b' ); + aFill == FILL_T::NO_FILL ? 's' : 'b' ); } void PDF_PLOTTER::Arc( const wxPoint& centre, double StAngle, double EndAngle, int radius, - FILL_TYPE fill, int width ) + FILL_T fill, int width ) { wxASSERT( workFile ); if( radius <= 0 ) { - Circle( centre, width, FILL_TYPE::FILLED_SHAPE, 0 ); + Circle( centre, width, FILL_T::FILLED_SHAPE, 0 ); return; } @@ -297,7 +297,7 @@ void PDF_PLOTTER::Arc( const wxPoint& centre, double StAngle, double EndAngle, i // The arc is drawn... if not filled we stroke it, otherwise we finish // closing the pie at the center - if( fill == FILL_TYPE::NO_FILL ) + if( fill == FILL_T::NO_FILL ) { fputs( "S\n", workFile ); } @@ -309,8 +309,8 @@ void PDF_PLOTTER::Arc( const wxPoint& centre, double StAngle, double EndAngle, i } -void PDF_PLOTTER::PlotPoly( const std::vector< wxPoint >& aCornerList, - FILL_TYPE aFill, int aWidth, void* aData ) +void PDF_PLOTTER::PlotPoly( const std::vector< wxPoint >& aCornerList, FILL_T aFill, int aWidth, + void* aData ) { wxASSERT( workFile ); @@ -329,7 +329,7 @@ void PDF_PLOTTER::PlotPoly( const std::vector< wxPoint >& aCornerList, } // Close path and stroke(/fill) - fprintf( workFile, "%c\n", aFill == FILL_TYPE::NO_FILL ? 'S' : 'b' ); + fprintf( workFile, "%c\n", aFill == FILL_T::NO_FILL ? 'S' : 'b' ); } diff --git a/common/plotters/PS_plotter.cpp b/common/plotters/PS_plotter.cpp index 96877f590d..b99e7dc0a2 100644 --- a/common/plotters/PS_plotter.cpp +++ b/common/plotters/PS_plotter.cpp @@ -47,12 +47,12 @@ const double PSLIKE_PLOTTER::postscriptTextAscent = 0.718; // return a id used to select a ps macro (see StartPlot() ) from a FILL_TYPE // fill mode, for arc, rect, circle and poly draw primitives -static int getFillId( FILL_TYPE aFill ) +static int getFillId( FILL_T aFill ) { - if( aFill == FILL_TYPE::NO_FILL ) + if( aFill == FILL_T::NO_FILL ) return 0; - if( aFill == FILL_TYPE::FILLED_SHAPE ) + if( aFill == FILL_T::FILLED_SHAPE ) return 1; return 2; @@ -122,7 +122,7 @@ void PSLIKE_PLOTTER::FlashPadCircle( const wxPoint& aPadPos, int aDiameter, { if( aTraceMode == FILLED ) { - Circle( aPadPos, aDiameter, FILL_TYPE::FILLED_SHAPE, 0 ); + Circle( aPadPos, aDiameter, FILL_T::FILLED_SHAPE, 0 ); } else // Plot a ring: { @@ -133,7 +133,7 @@ void PSLIKE_PLOTTER::FlashPadCircle( const wxPoint& aPadPos, int aDiameter, if( linewidth > aDiameter-2 ) linewidth = aDiameter-2; - Circle( aPadPos, aDiameter - linewidth, FILL_TYPE::NO_FILL, linewidth ); + Circle( aPadPos, aDiameter - linewidth, FILL_T::NO_FILL, linewidth ); } SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH ); @@ -185,7 +185,7 @@ void PSLIKE_PLOTTER::FlashPadRect( const wxPoint& aPadPos, const wxSize& aSize, cornerList.push_back( cornerList[0] ); - PlotPoly( cornerList, ( aTraceMode == FILLED ) ? FILL_TYPE::FILLED_SHAPE : FILL_TYPE::NO_FILL, + PlotPoly( cornerList, ( aTraceMode == FILLED ) ? FILL_T::FILLED_SHAPE : FILL_T::NO_FILL, GetCurrentLineWidth() ); } @@ -225,7 +225,7 @@ void PSLIKE_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aS // Close polygon cornerList.push_back( cornerList[0] ); - PlotPoly( cornerList, ( aTraceMode == FILLED ) ? FILL_TYPE::FILLED_SHAPE : FILL_TYPE::NO_FILL, + PlotPoly( cornerList, ( aTraceMode == FILLED ) ? FILL_T::FILLED_SHAPE : FILL_T::NO_FILL, GetCurrentLineWidth() ); } @@ -261,7 +261,7 @@ void PSLIKE_PLOTTER::FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize // Close polygon cornerList.push_back( cornerList[0] ); - PlotPoly( cornerList, ( aTraceMode == FILLED ) ? FILL_TYPE::FILLED_SHAPE : FILL_TYPE::NO_FILL, + PlotPoly( cornerList, ( aTraceMode == FILLED ) ? FILL_T::FILLED_SHAPE : FILL_T::NO_FILL, GetCurrentLineWidth() ); } } @@ -309,7 +309,7 @@ void PSLIKE_PLOTTER::FlashPadTrapez( const wxPoint& aPadPos, const wxPoint *aCor } cornerList.push_back( cornerList[0] ); - PlotPoly( cornerList, ( aTraceMode == FILLED ) ? FILL_TYPE::FILLED_SHAPE : FILL_TYPE::NO_FILL, + PlotPoly( cornerList, ( aTraceMode == FILLED ) ? FILL_T::FILLED_SHAPE : FILL_T::NO_FILL, GetCurrentLineWidth() ); } @@ -577,7 +577,7 @@ void PS_PLOTTER::SetDash( PLOT_DASH_TYPE dashed ) } -void PS_PLOTTER::Rect( const wxPoint& p1, const wxPoint& p2, FILL_TYPE fill, int width ) +void PS_PLOTTER::Rect( const wxPoint& p1, const wxPoint& p2, FILL_T fill, int width ) { DPOINT p1_dev = userToDeviceCoordinates( p1 ); DPOINT p2_dev = userToDeviceCoordinates( p2 ); @@ -588,7 +588,7 @@ void PS_PLOTTER::Rect( const wxPoint& p1, const wxPoint& p2, FILL_TYPE fill, int } -void PS_PLOTTER::Circle( const wxPoint& pos, int diametre, FILL_TYPE fill, int width ) +void PS_PLOTTER::Circle( const wxPoint& pos, int diametre, FILL_T fill, int width ) { wxASSERT( m_outputFile ); DPOINT pos_dev = userToDeviceCoordinates( pos ); @@ -599,8 +599,8 @@ void PS_PLOTTER::Circle( const wxPoint& pos, int diametre, FILL_TYPE fill, int w } -void PS_PLOTTER::Arc( const wxPoint& centre, double StAngle, double EndAngle, - int radius, FILL_TYPE fill, int width ) +void PS_PLOTTER::Arc( const wxPoint& centre, double StAngle, double EndAngle, int radius, + FILL_T fill, int width ) { wxASSERT( m_outputFile ); @@ -636,8 +636,8 @@ void PS_PLOTTER::Arc( const wxPoint& centre, double StAngle, double EndAngle, } -void PS_PLOTTER::PlotPoly( const std::vector< wxPoint >& aCornerList, - FILL_TYPE aFill, int aWidth, void * aData ) +void PS_PLOTTER::PlotPoly( const std::vector< wxPoint >& aCornerList, FILL_T aFill, + int aWidth, void * aData ) { if( aCornerList.size() <= 1 ) return; diff --git a/common/plotters/SVG_plotter.cpp b/common/plotters/SVG_plotter.cpp index e2a1f0e93b..cdbc23d44a 100644 --- a/common/plotters/SVG_plotter.cpp +++ b/common/plotters/SVG_plotter.cpp @@ -93,6 +93,7 @@ #include #include +#include #include #include #include @@ -163,7 +164,7 @@ SVG_PLOTTER::SVG_PLOTTER() { m_graphics_changed = true; SetTextMode( PLOT_TEXT_MODE::STROKE ); - m_fillMode = FILL_TYPE::NO_FILL; // or FILLED_SHAPE or FILLED_WITH_BG_BODYCOLOR + m_fillMode = FILL_T::NO_FILL; // or FILLED_SHAPE or FILLED_WITH_BG_BODYCOLOR m_pen_rgb_color = 0; // current color value (black) m_brush_rgb_color = 0; // current color value (black) m_dashed = PLOT_DASH_TYPE::SOLID; @@ -215,7 +216,7 @@ void SVG_PLOTTER::SetColor( const COLOR4D& color ) } -void SVG_PLOTTER::setFillMode( FILL_TYPE fill ) +void SVG_PLOTTER::setFillMode( FILL_T fill ) { if( m_fillMode != fill ) { @@ -235,20 +236,11 @@ void SVG_PLOTTER::setSVGPlotStyle( bool aIsGroup, const std::string& aExtraStyle switch( m_fillMode ) { - case FILL_TYPE::NO_FILL: - fputs( "fill-opacity:0.0; ", m_outputFile ); - break; - - case FILL_TYPE::FILLED_SHAPE: - fputs( "fill-opacity:1.0; ", m_outputFile ); - break; - - case FILL_TYPE::FILLED_WITH_BG_BODYCOLOR: - fputs( "fill-opacity:0.6; ", m_outputFile ); - break; - - case FILL_TYPE::FILLED_WITH_COLOR: - wxFAIL_MSG( "FILLED_WITH_COLOR not implemented" ); + case FILL_T::NO_FILL: fputs( "fill-opacity:0.0; ", m_outputFile ); break; + case FILL_T::FILLED_SHAPE: fputs( "fill-opacity:1.0; ", m_outputFile ); break; + case FILL_T::FILLED_WITH_BG_BODYCOLOR: fputs( "fill-opacity:0.6; ", m_outputFile ); break; + case FILL_T::FILLED_WITH_COLOR: + UNIMPLEMENTED_FOR( "FILLED_WITH_COLOR" ); break; } @@ -373,7 +365,7 @@ void SVG_PLOTTER::SetDash( PLOT_DASH_TYPE dashed ) } -void SVG_PLOTTER::Rect( const wxPoint& p1, const wxPoint& p2, FILL_TYPE fill, int width ) +void SVG_PLOTTER::Rect( const wxPoint& p1, const wxPoint& p2, FILL_T fill, int width ) { EDA_RECT rect( p1, wxSize( p2.x -p1.x, p2.y -p1.y ) ); rect.Normalize(); @@ -410,7 +402,7 @@ void SVG_PLOTTER::Rect( const wxPoint& p1, const wxPoint& p2, FILL_TYPE fill, in } -void SVG_PLOTTER::Circle( const wxPoint& pos, int diametre, FILL_TYPE fill, int width ) +void SVG_PLOTTER::Circle( const wxPoint& pos, int diametre, FILL_T fill, int width ) { DPOINT pos_dev = userToDeviceCoordinates( pos ); double radius = userToDeviceSize( diametre / 2.0 ); @@ -419,9 +411,9 @@ void SVG_PLOTTER::Circle( const wxPoint& pos, int diametre, FILL_TYPE fill, int SetCurrentLineWidth( width ); // If diameter is less than width, switch to filled mode - if( fill == FILL_TYPE::NO_FILL && diametre < width ) + if( fill == FILL_T::NO_FILL && diametre < width ) { - setFillMode( FILL_TYPE::FILLED_SHAPE ); + setFillMode( FILL_T::FILLED_SHAPE ); SetCurrentLineWidth( 0 ); radius = userToDeviceSize( ( diametre / 2.0 ) + ( width / 2.0 ) ); @@ -434,7 +426,7 @@ void SVG_PLOTTER::Circle( const wxPoint& pos, int diametre, FILL_TYPE fill, int void SVG_PLOTTER::Arc( const wxPoint& centre, double StAngle, double EndAngle, int radius, - FILL_TYPE fill, int width ) + FILL_T fill, int width ) { /* Draws an arc of a circle, centered on (xc,yc), with starting point * (x1, y1) and ending at (x2, y2). The current pen is used for the outline @@ -446,7 +438,7 @@ void SVG_PLOTTER::Arc( const wxPoint& centre, double StAngle, double EndAngle, i if( radius <= 0 ) { - Circle( centre, width, FILL_TYPE::FILLED_SHAPE, 0 ); + Circle( centre, width, FILL_T::FILLED_SHAPE, 0 ); return; } @@ -513,7 +505,7 @@ void SVG_PLOTTER::Arc( const wxPoint& centre, double StAngle, double EndAngle, i // flag arc size (0 = small arc > 180 deg, 1 = large arc > 180 deg), // sweep arc ( 0 = CCW, 1 = CW), // end point - if( fill != FILL_TYPE::NO_FILL ) + if( fill != FILL_T::NO_FILL ) { // Filled arcs (in Eeschema) consist of the pie wedge and a stroke only on the arc // This needs to be drawn in two steps. @@ -526,7 +518,7 @@ void SVG_PLOTTER::Arc( const wxPoint& centre, double StAngle, double EndAngle, i end.x, end.y, centre_dev.x, centre_dev.y ); } - setFillMode( FILL_TYPE::NO_FILL ); + setFillMode( FILL_T::NO_FILL ); SetCurrentLineWidth( width ); fprintf( m_outputFile, "\n", start.x, start.y, radius_dev, radius_dev, @@ -540,7 +532,7 @@ void SVG_PLOTTER::BezierCurve( const wxPoint& aStart, const wxPoint& aControl1, int aTolerance, int aLineThickness ) { #if 1 - setFillMode( FILL_TYPE::NO_FILL ); + setFillMode( FILL_T::NO_FILL ); SetCurrentLineWidth( aLineThickness ); DPOINT start = userToDeviceCoordinates( aStart ); @@ -558,7 +550,7 @@ void SVG_PLOTTER::BezierCurve( const wxPoint& aStart, const wxPoint& aControl1, } -void SVG_PLOTTER::PlotPoly( const std::vector& aCornerList, FILL_TYPE aFill, +void SVG_PLOTTER::PlotPoly( const std::vector& aCornerList, FILL_T aFill, int aWidth, void* aData ) { if( aCornerList.size() <= 1 ) @@ -570,16 +562,16 @@ void SVG_PLOTTER::PlotPoly( const std::vector& aCornerList, FILL_TYPE a switch( aFill ) { - case FILL_TYPE::NO_FILL: + case FILL_T::NO_FILL: setSVGPlotStyle( false, "fill:none" ); break; - case FILL_TYPE::FILLED_WITH_BG_BODYCOLOR: - case FILL_TYPE::FILLED_SHAPE: + case FILL_T::FILLED_WITH_BG_BODYCOLOR: + case FILL_T::FILLED_SHAPE: setSVGPlotStyle( false, "fill-rule:evenodd;" ); break; - case FILL_TYPE::FILLED_WITH_COLOR: + case FILL_T::FILLED_WITH_COLOR: wxFAIL_MSG( "FILLED_WITH_COLOR not implemented" ); break; } @@ -673,9 +665,9 @@ void SVG_PLOTTER::PenTo( const wxPoint& pos, char plume ) // Ensure we do not use a fill mode when moving the pen, // in SVG mode (i;e. we are plotting only basic lines, not a filled area - if( m_fillMode != FILL_TYPE::NO_FILL ) + if( m_fillMode != FILL_T::NO_FILL ) { - setFillMode( FILL_TYPE::NO_FILL ); + setFillMode( FILL_T::NO_FILL ); setSVGPlotStyle(); } @@ -773,7 +765,7 @@ void SVG_PLOTTER::Text( const wxPoint& aPos, bool aMultilineAllowed, void* aData ) { - setFillMode( FILL_TYPE::NO_FILL ); + setFillMode( FILL_T::NO_FILL ); SetColor( aColor ); SetCurrentLineWidth( aWidth ); diff --git a/common/plotters/common_plot_functions.cpp b/common/plotters/common_plot_functions.cpp index 289b3c8175..a730be2570 100644 --- a/common/plotters/common_plot_functions.cpp +++ b/common/plotters/common_plot_functions.cpp @@ -109,7 +109,7 @@ void PlotDrawingSheet( PLOTTER* plotter, const PROJECT* aProject, const TITLE_BL { DS_DRAW_ITEM_RECT* rect = (DS_DRAW_ITEM_RECT*) item; int penWidth = std::max( rect->GetPenWidth(), defaultPenWidth ); - plotter->Rect( rect->GetStart(), rect->GetEnd(), FILL_TYPE::NO_FILL, penWidth ); + plotter->Rect( rect->GetStart(), rect->GetEnd(), FILL_T::NO_FILL, penWidth ); } break; @@ -138,7 +138,7 @@ void PlotDrawingSheet( PLOTTER* plotter, const PROJECT* aProject, const TITLE_BL for( int ii = 0; ii < outline.PointCount(); ii++ ) points.emplace_back( outline.CPoint( ii ).x, outline.CPoint( ii ).y ); - plotter->PlotPoly( points, FILL_TYPE::FILLED_SHAPE, penWidth ); + plotter->PlotPoly( points, FILL_T::FILLED_SHAPE, penWidth ); } } break; diff --git a/common/plotters/plotter.cpp b/common/plotters/plotter.cpp index 7aee80f381..4d4b7d7331 100644 --- a/common/plotters/plotter.cpp +++ b/common/plotters/plotter.cpp @@ -157,12 +157,12 @@ double PLOTTER::GetDashGapLenIU() const void PLOTTER::Arc( const SHAPE_ARC& aArc ) { Arc( wxPoint( aArc.GetCenter() ), aArc.GetStartAngle(), aArc.GetEndAngle(), aArc.GetRadius(), - FILL_TYPE::NO_FILL, aArc.GetWidth() ); + FILL_T::NO_FILL, aArc.GetWidth() ); } void PLOTTER::Arc( const wxPoint& centre, double StAngle, double EndAngle, int radius, - FILL_TYPE fill, int width ) + FILL_T fill, int width ) { wxPoint start, end; const int delta = 50; // increment (in 0.1 degrees) to draw circles @@ -176,7 +176,7 @@ void PLOTTER::Arc( const wxPoint& centre, double StAngle, double EndAngle, int r start.x = centre.x + KiROUND( cosdecideg( radius, -StAngle ) ); start.y = centre.y + KiROUND( sindecideg( radius, -StAngle ) ); - if( fill != FILL_TYPE::NO_FILL ) + if( fill != FILL_T::NO_FILL ) { MoveTo( centre ); LineTo( start ); @@ -196,7 +196,7 @@ void PLOTTER::Arc( const wxPoint& centre, double StAngle, double EndAngle, int r end.x = centre.x + KiROUND( cosdecideg( radius, -EndAngle ) ); end.y = centre.y + KiROUND( sindecideg( radius, -EndAngle ) ); - if( fill != FILL_TYPE::NO_FILL ) + if( fill != FILL_T::NO_FILL ) { LineTo( end ); FinishTo( centre ); @@ -248,7 +248,7 @@ void PLOTTER::PlotImage(const wxImage& aImage, const wxPoint& aPos, double aScal end.x += size.x; end.y += size.y; - Rect( start, end, FILL_TYPE::NO_FILL ); + Rect( start, end, FILL_T::NO_FILL ); } @@ -273,13 +273,13 @@ void PLOTTER::markerSquare( const wxPoint& position, int radius ) corner.y = position.y + r; corner_list.push_back( corner ); - PlotPoly( corner_list, FILL_TYPE::NO_FILL, GetCurrentLineWidth() ); + PlotPoly( corner_list, FILL_T::NO_FILL, GetCurrentLineWidth() ); } void PLOTTER::markerCircle( const wxPoint& position, int radius ) { - Circle( position, radius * 2, FILL_TYPE::NO_FILL, GetCurrentLineWidth() ); + Circle( position, radius * 2, FILL_T::NO_FILL, GetCurrentLineWidth() ); } @@ -303,7 +303,7 @@ void PLOTTER::markerLozenge( const wxPoint& position, int radius ) corner.y = position.y + radius; corner_list.push_back( corner ); - PlotPoly( corner_list, FILL_TYPE::NO_FILL, GetCurrentLineWidth() ); + PlotPoly( corner_list, FILL_T::NO_FILL, GetCurrentLineWidth() ); } @@ -514,15 +514,11 @@ void PLOTTER::sketchOval( const wxPoint& pos, const wxSize& aSize, double orient cx = 0; cy = deltaxy / 2; RotatePoint( &cx, &cy, orient ); - Arc( wxPoint( cx + pos.x, cy + pos.y ), - orient + 1800, orient + 3600, - radius, FILL_TYPE::NO_FILL ); + Arc( wxPoint( cx + pos.x, cy + pos.y ), orient + 1800, orient + 3600, radius, FILL_T::NO_FILL ); cx = 0; cy = -deltaxy / 2; RotatePoint( &cx, &cy, orient ); - Arc( wxPoint( cx + pos.x, cy + pos.y ), - orient, orient + 1800, - radius, FILL_TYPE::NO_FILL ); + Arc( wxPoint( cx + pos.x, cy + pos.y ), orient, orient + 1800, radius, FILL_T::NO_FILL ); } @@ -533,7 +529,7 @@ void PLOTTER::ThickSegment( const wxPoint& start, const wxPoint& end, int width, { if( start == end ) { - Circle( start, width, FILL_TYPE::FILLED_SHAPE, 0 ); + Circle( start, width, FILL_T::FILLED_SHAPE, 0 ); } else { @@ -555,15 +551,15 @@ void PLOTTER::ThickArc( const wxPoint& centre, double StAngle, double EndAngle, { if( tracemode == FILLED ) { - Arc( centre, StAngle, EndAngle, radius, FILL_TYPE::NO_FILL, width ); + Arc( centre, StAngle, EndAngle, radius, FILL_T::NO_FILL, width ); } else { SetCurrentLineWidth( -1 ); - Arc( centre, StAngle, EndAngle, - radius - ( width - m_currentPenWidth ) / 2, FILL_TYPE::NO_FILL, -1 ); - Arc( centre, StAngle, EndAngle, - radius + ( width - m_currentPenWidth ) / 2, FILL_TYPE::NO_FILL, -1 ); + Arc( centre, StAngle, EndAngle, radius - ( width - m_currentPenWidth ) / 2, + FILL_T::NO_FILL, -1 ); + Arc( centre, StAngle, EndAngle, radius + ( width - m_currentPenWidth ) / 2, + FILL_T::NO_FILL, -1 ); } } @@ -573,7 +569,7 @@ void PLOTTER::ThickRect( const wxPoint& p1, const wxPoint& p2, int width, { if( tracemode == FILLED ) { - Rect( p1, p2, FILL_TYPE::NO_FILL, width ); + Rect( p1, p2, FILL_T::NO_FILL, width ); } else { @@ -582,12 +578,12 @@ void PLOTTER::ThickRect( const wxPoint& p1, const wxPoint& p2, int width, p1.y - (width - m_currentPenWidth) / 2 ); wxPoint offsetp2( p2.x + (width - m_currentPenWidth) / 2, p2.y + (width - m_currentPenWidth) / 2 ); - Rect( offsetp1, offsetp2, FILL_TYPE::NO_FILL, -1 ); + Rect( offsetp1, offsetp2, FILL_T::NO_FILL, -1 ); offsetp1.x += ( width - m_currentPenWidth ); offsetp1.y += ( width - m_currentPenWidth ); offsetp2.x -= ( width - m_currentPenWidth ); offsetp2.y -= ( width - m_currentPenWidth ); - Rect( offsetp1, offsetp2, FILL_TYPE::NO_FILL, -1 ); + Rect( offsetp1, offsetp2, FILL_T::NO_FILL, -1 ); } } @@ -597,13 +593,13 @@ void PLOTTER::ThickCircle( const wxPoint& pos, int diametre, int width, OUTLINE_ { if( tracemode == FILLED ) { - Circle( pos, diametre, FILL_TYPE::NO_FILL, width ); + Circle( pos, diametre, FILL_T::NO_FILL, width ); } else { SetCurrentLineWidth( -1 ); - Circle( pos, diametre - width + m_currentPenWidth, FILL_TYPE::NO_FILL, -1 ); - Circle( pos, diametre + width - m_currentPenWidth, FILL_TYPE::NO_FILL, -1 ); + Circle( pos, diametre - width + m_currentPenWidth, FILL_T::NO_FILL, -1 ); + Circle( pos, diametre + width - m_currentPenWidth, FILL_T::NO_FILL, -1 ); } } @@ -612,18 +608,17 @@ void PLOTTER::FilledCircle( const wxPoint& pos, int diametre, OUTLINE_MODE trace { if( tracemode == FILLED ) { - Circle( pos, diametre, FILL_TYPE::FILLED_SHAPE, 0 ); + Circle( pos, diametre, FILL_T::FILLED_SHAPE, 0 ); } else { SetCurrentLineWidth( -1 ); - Circle( pos, diametre, FILL_TYPE::NO_FILL, -1 ); + Circle( pos, diametre, FILL_T::NO_FILL, -1 ); } } -void PLOTTER::PlotPoly( const SHAPE_LINE_CHAIN& aCornerList, FILL_TYPE aFill, - int aWidth, void* aData ) +void PLOTTER::PlotPoly( const SHAPE_LINE_CHAIN& aCornerList, FILL_T aFill, int aWidth, void* aData ) { std::vector cornerList; cornerList.reserve( aCornerList.PointCount() ); diff --git a/eeschema/CMakeLists.txt b/eeschema/CMakeLists.txt index 07d2a1e5d1..7e9ada553d 100644 --- a/eeschema/CMakeLists.txt +++ b/eeschema/CMakeLists.txt @@ -177,14 +177,10 @@ set( EESCHEMA_SRCS generate_alias_info.cpp getpart.cpp hierarch.cpp - lib_arc.cpp - lib_bezier.cpp - lib_circle.cpp + lib_shape.cpp lib_item.cpp lib_field.cpp lib_pin.cpp - lib_polyline.cpp - lib_rectangle.cpp lib_symbol.cpp lib_text.cpp symbol_viewer_frame.cpp @@ -274,6 +270,7 @@ set( EESCHEMA_COMMON_SRCS ${CMAKE_SOURCE_DIR}/common/base_screen.cpp ${CMAKE_SOURCE_DIR}/common/base_units.cpp ${CMAKE_SOURCE_DIR}/common/eda_text.cpp + ${CMAKE_SOURCE_DIR}/common/eda_shape.cpp ${CMAKE_SOURCE_DIR}/common/page_info.cpp ) diff --git a/eeschema/dialogs/dialog_lib_shape_properties.cpp b/eeschema/dialogs/dialog_lib_shape_properties.cpp index 09db5c5592..a3804be3f1 100644 --- a/eeschema/dialogs/dialog_lib_shape_properties.cpp +++ b/eeschema/dialogs/dialog_lib_shape_properties.cpp @@ -63,8 +63,11 @@ bool DIALOG_LIB_SHAPE_PROPERTIES::TransferDataToWindow() return false; LIB_SYMBOL* symbol = m_item->GetParent(); + EDA_SHAPE* shape = dynamic_cast( m_item ); + + if( shape ) + m_lineWidth.SetValue( shape->GetWidth() ); - m_lineWidth.SetValue( m_item->GetWidth() ); m_checkApplyToAllUnits->SetValue( m_item->GetUnit() == 0 ); m_checkApplyToAllUnits->Enable( symbol && symbol->GetUnitCount() > 1 ); m_checkApplyToAllConversions->SetValue( m_item->GetConvert() == 0 ); @@ -80,8 +83,10 @@ bool DIALOG_LIB_SHAPE_PROPERTIES::TransferDataToWindow() m_checkApplyToAllConversions->Enable( enblConvOptStyle ); - m_fillCtrl->SetSelection( static_cast( m_item->GetFillMode() ) ); - m_fillCtrl->Enable( m_item->IsFillable() ); + if( shape ) + m_fillCtrl->SetSelection( static_cast( shape->GetFillType() ) ); + + m_fillCtrl->Enable( shape != nullptr ); return true; } @@ -92,10 +97,13 @@ bool DIALOG_LIB_SHAPE_PROPERTIES::TransferDataFromWindow() if( !wxDialog::TransferDataFromWindow() ) return false; - if( m_item->IsFillable() ) - m_item->SetFillMode( (FILL_TYPE) std::max( m_fillCtrl->GetSelection(), 0 ) ); + EDA_SHAPE* shape = dynamic_cast( m_item ); - m_item->SetWidth( m_lineWidth.GetValue() ); + if( shape ) + shape->SetFillMode((FILL_T) std::max( m_fillCtrl->GetSelection(), 0 )); + + if( shape ) + shape->SetWidth( m_lineWidth.GetValue() ); if( GetApplyToAllConversions() ) m_item->SetConvert( 0 ); diff --git a/eeschema/dialogs/dialog_plot_schematic.cpp b/eeschema/dialogs/dialog_plot_schematic.cpp index cd74f84244..a508b8e49a 100644 --- a/eeschema/dialogs/dialog_plot_schematic.cpp +++ b/eeschema/dialogs/dialog_plot_schematic.cpp @@ -898,7 +898,7 @@ void DIALOG_PLOT_SCHEMATIC::plotOneSheetPDF( PLOTTER* aPlotter, SCH_SCREEN* aScr aPlotter->SetColor( aPlotter->RenderSettings()->GetBackgroundColor() ); wxPoint end( aPlotter->PageSettings().GetWidthIU(), aPlotter->PageSettings().GetHeightIU() ); - aPlotter->Rect( wxPoint( 0, 0 ), end, FILL_TYPE::FILLED_SHAPE, 1.0 ); + aPlotter->Rect( wxPoint( 0, 0 ), end, FILL_T::FILLED_SHAPE, 1.0 ); } if( aPlotDrawingSheet ) @@ -1088,7 +1088,7 @@ bool DIALOG_PLOT_SCHEMATIC::plotOneSheetPS( const wxString& aFileName, { plotter->SetColor( plotter->RenderSettings()->GetLayerColor( LAYER_SCHEMATIC_BACKGROUND ) ); wxPoint end( plotter->PageSettings().GetWidthIU(), plotter->PageSettings().GetHeightIU() ); - plotter->Rect( wxPoint( 0, 0 ), end, FILL_TYPE::FILLED_SHAPE, 1.0 ); + plotter->Rect( wxPoint( 0, 0 ), end, FILL_T::FILLED_SHAPE, 1.0 ); } if( aPlotFrameRef ) @@ -1218,7 +1218,7 @@ bool DIALOG_PLOT_SCHEMATIC::plotOneSheetSVG( const wxString& aFileName, plotter->SetColor( plotter->RenderSettings()->GetLayerColor( LAYER_SCHEMATIC_BACKGROUND ) ); wxPoint end( plotter->PageSettings().GetWidthIU(), plotter->PageSettings().GetHeightIU() ); - plotter->Rect( wxPoint( 0, 0 ), end, FILL_TYPE::FILLED_SHAPE, 1.0 ); + plotter->Rect( wxPoint( 0, 0 ), end, FILL_T::FILLED_SHAPE, 1.0 ); } if( aPlotFrameRef ) diff --git a/eeschema/dialogs/panel_eeschema_color_settings.cpp b/eeschema/dialogs/panel_eeschema_color_settings.cpp index 155bb8c417..7ef0b3a6bf 100644 --- a/eeschema/dialogs/panel_eeschema_color_settings.cpp +++ b/eeschema/dialogs/panel_eeschema_color_settings.cpp @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include #include @@ -347,12 +347,12 @@ void PANEL_EESCHEMA_COLOR_SETTINGS::createPreviewItems() symbol->SetShowPinNumbers( true ); symbol->SetPinNameOffset( 0 ); - LIB_POLYLINE* comp_body = new LIB_POLYLINE( symbol ); + LIB_SHAPE* comp_body = new LIB_SHAPE( symbol, SHAPE_T::POLY ); comp_body->SetUnit( 0 ); comp_body->SetConvert( 0 ); comp_body->SetWidth( Mils2iu( 10 ) ); - comp_body->SetFillMode( FILL_TYPE::FILLED_WITH_BG_BODYCOLOR ); + comp_body->SetFillMode( FILL_T::FILLED_WITH_BG_BODYCOLOR ); comp_body->AddPoint( MILS_POINT( p.x - 200, p.y + 200 ) ); comp_body->AddPoint( MILS_POINT( p.x + 200, p.y ) ); comp_body->AddPoint( MILS_POINT( p.x - 200, p.y - 200 ) ); diff --git a/eeschema/lib_arc.cpp b/eeschema/lib_arc.cpp index c4abdee87f..8b13789179 100644 --- a/eeschema/lib_arc.cpp +++ b/eeschema/lib_arc.cpp @@ -1,545 +1 @@ -/* - * This program source code file is part of KiCad, a free EDA CAD application. - * - * Copyright (C) 2017 Jean-Pierre Charras, jp.charras at wanadoo.fr - * Copyright (C) 2004-2021 KiCad Developers, see AUTHORS.txt for contributors. - * Copyright (C) 2019 CERN - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, you may find one here: - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * or you may search the http://www.gnu.org website for the version 2 license, - * or you may write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include -#include -#include -#include -#include -#include -#include // for KiROUND -#include -#include -#include -#include -#include -#include - -// Helper function -static inline wxPoint twoPointVector( const wxPoint &startPoint, const wxPoint &endPoint ) -{ - return endPoint - startPoint; -} - - -LIB_ARC::LIB_ARC( LIB_SYMBOL* aParent ) : LIB_ITEM( LIB_ARC_T, aParent ) -{ - m_Width = 0; - m_fill = FILL_TYPE::NO_FILL; - m_isFillable = true; - m_editState = 0; -} - - -int LIB_ARC::GetRadius() const -{ - return KiROUND( GetLineLength( GetCenter(), GetStart() ) ); -} - - -bool LIB_ARC::HitTest( const wxPoint& aRefPoint, int aAccuracy ) const -{ - int mindist = std::max( aAccuracy + GetPenWidth() / 2, - Mils2iu( MINIMUM_SELECTION_DISTANCE ) ); - wxPoint relativePosition = aRefPoint; - - relativePosition.y = -relativePosition.y; // reverse Y axis - - int distance = KiROUND( GetLineLength( m_Pos, relativePosition ) ); - - if( abs( distance - GetRadius() ) > mindist ) - return false; - - // We are on the circle, ensure we are only on the arc, i.e. between - // m_ArcStart and m_ArcEnd - - wxPoint startEndVector = twoPointVector( m_ArcStart, m_ArcEnd ); - wxPoint startRelativePositionVector = twoPointVector( m_ArcStart, relativePosition ); - - wxPoint centerStartVector = twoPointVector( m_Pos, m_ArcStart ); - wxPoint centerEndVector = twoPointVector( m_Pos, m_ArcEnd ); - wxPoint centerRelativePositionVector = twoPointVector( m_Pos, relativePosition ); - - // Compute the cross product to check if the point is in the sector - double crossProductStart = CrossProduct( centerStartVector, centerRelativePositionVector ); - double crossProductEnd = CrossProduct( centerEndVector, centerRelativePositionVector ); - - // The cross products need to be exchanged, depending on which side the center point - // relative to the start point to end point vector lies - if( CrossProduct( startEndVector, startRelativePositionVector ) < 0 ) - { - std::swap( crossProductStart, crossProductEnd ); - } - - // When the cross products have a different sign, the point lies in sector - // also check, if the reference is near start or end point - return HitTestPoints( m_ArcStart, relativePosition, MINIMUM_SELECTION_DISTANCE ) || - HitTestPoints( m_ArcEnd, relativePosition, MINIMUM_SELECTION_DISTANCE ) || - ( crossProductStart <= 0 && crossProductEnd >= 0 ); -} - - -bool LIB_ARC::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const -{ - if( m_flags & (STRUCT_DELETED | SKIP_STRUCT ) ) - return false; - - wxPoint center = DefaultTransform.TransformCoordinate( GetPosition() ); - int radius = GetRadius(); - int lineWidth = GetWidth(); - EDA_RECT sel = aRect ; - - if ( aAccuracy ) - sel.Inflate( aAccuracy ); - - if( aContained ) - return sel.Contains( GetBoundingBox() ); - - EDA_RECT arcRect = GetBoundingBox().Common( sel ); - - /* All following tests must pass: - * 1. Rectangle must intersect arc BoundingBox - * 2. Rectangle must cross the outside of the arc - */ - return arcRect.Intersects( sel ) && arcRect.IntersectsCircleEdge( center, radius, lineWidth ); -} - - -EDA_ITEM* LIB_ARC::Clone() const -{ - return new LIB_ARC( *this ); -} - - -int LIB_ARC::compare( const LIB_ITEM& aOther, LIB_ITEM::COMPARE_FLAGS aCompareFlags ) const -{ - wxASSERT( aOther.Type() == LIB_ARC_T ); - - int retv = LIB_ITEM::compare( aOther ); - - if( retv ) - return retv; - - const LIB_ARC* tmp = ( LIB_ARC* ) &aOther; - - if( m_Pos.x != tmp->m_Pos.x ) - return m_Pos.x - tmp->m_Pos.x; - - if( m_Pos.y != tmp->m_Pos.y ) - return m_Pos.y - tmp->m_Pos.y; - - return 0; -} - - -void LIB_ARC::Offset( const wxPoint& aOffset ) -{ - m_Pos += aOffset; - m_ArcStart += aOffset; - m_ArcEnd += aOffset; -} - - -void LIB_ARC::MoveTo( const wxPoint& aPosition ) -{ - wxPoint offset = aPosition - m_Pos; - m_Pos = aPosition; - m_ArcStart += offset; - m_ArcEnd += offset; -} - - -void LIB_ARC::MirrorHorizontal( const wxPoint& aCenter ) -{ - m_Pos.x -= aCenter.x; - m_Pos.x *= -1; - m_Pos.x += aCenter.x; - m_ArcStart.x -= aCenter.x; - m_ArcStart.x *= -1; - m_ArcStart.x += aCenter.x; - m_ArcEnd.x -= aCenter.x; - m_ArcEnd.x *= -1; - m_ArcEnd.x += aCenter.x; - std::swap( m_ArcStart, m_ArcEnd ); -} - - -void LIB_ARC::MirrorVertical( const wxPoint& aCenter ) -{ - m_Pos.y -= aCenter.y; - m_Pos.y *= -1; - m_Pos.y += aCenter.y; - m_ArcStart.y -= aCenter.y; - m_ArcStart.y *= -1; - m_ArcStart.y += aCenter.y; - m_ArcEnd.y -= aCenter.y; - m_ArcEnd.y *= -1; - m_ArcEnd.y += aCenter.y; - std::swap( m_ArcStart, m_ArcEnd ); -} - - -void LIB_ARC::Rotate( const wxPoint& aCenter, bool aRotateCCW ) -{ - int rot_angle = aRotateCCW ? -900 : 900; - RotatePoint( &m_Pos, aCenter, rot_angle ); - RotatePoint( &m_ArcStart, aCenter, rot_angle ); - RotatePoint( &m_ArcEnd, aCenter, rot_angle ); -} - - -void LIB_ARC::Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill, - const TRANSFORM& aTransform ) const -{ - wxASSERT( aPlotter != nullptr ); - - wxPoint center = aTransform.TransformCoordinate( GetCenter() ) + aOffset; - int startAngle; - int endAngle; - int pen_size = GetEffectivePenWidth( aPlotter->RenderSettings() ); - FILL_TYPE fill = aFill ? m_fill : FILL_TYPE::NO_FILL; - - CalcAngles( startAngle, endAngle ); - aTransform.MapAngles( &startAngle, &endAngle ); - - if( fill == FILL_TYPE::FILLED_WITH_BG_BODYCOLOR ) - { - aPlotter->SetColor( aPlotter->RenderSettings()->GetLayerColor( LAYER_DEVICE_BACKGROUND ) ); - aPlotter->Arc( center, -endAngle, -startAngle, GetRadius(), fill, 0 ); - - if( pen_size <= 0 ) - return; - else - fill = FILL_TYPE::NO_FILL; - } - - pen_size = std::max( pen_size, aPlotter->RenderSettings()->GetMinPenWidth() ); - - aPlotter->SetColor( aPlotter->RenderSettings()->GetLayerColor( LAYER_DEVICE ) ); - aPlotter->Arc( center, -endAngle, -startAngle, GetRadius(), fill, pen_size ); -} - - -int LIB_ARC::GetPenWidth() const -{ - return m_Width; -} - - -void LIB_ARC::print( const RENDER_SETTINGS* aSettings, const wxPoint& aOffset, void* aData, - const TRANSFORM& aTransform ) -{ - bool forceNoFill = static_cast( aData ); - int penWidth = GetEffectivePenWidth( aSettings ); - - if( forceNoFill && m_fill != FILL_TYPE::NO_FILL && penWidth == 0 ) - return; - - wxDC* DC = aSettings->GetPrintDC(); - wxPoint pos1, pos2, posc; - COLOR4D color = aSettings->GetLayerColor( LAYER_DEVICE ); - - pos1 = aTransform.TransformCoordinate( m_ArcEnd ) + aOffset; - pos2 = aTransform.TransformCoordinate( m_ArcStart ) + aOffset; - posc = aTransform.TransformCoordinate( m_Pos ) + aOffset; - - int t1; - int t2; - - CalcAngles( t1, t2 ); - aTransform.MapAngles( &t1, &t2 ); - - if( forceNoFill || m_fill == FILL_TYPE::NO_FILL ) - { - GRArc1( nullptr, DC, pos1.x, pos1.y, pos2.x, pos2.y, posc.x, posc.y, penWidth, color ); - } - else - { - if( m_fill == FILL_TYPE::FILLED_WITH_BG_BODYCOLOR ) - color = aSettings->GetLayerColor( LAYER_DEVICE_BACKGROUND ); - - GRFilledArc( nullptr, DC, posc.x, posc.y, t1, t2, GetRadius(), penWidth, color, color ); - } -} - - -const EDA_RECT LIB_ARC::GetBoundingBox() const -{ - int radius = GetRadius(); - int minX, minY, maxX, maxY, angleStart, angleEnd; - EDA_RECT rect; - wxPoint nullPoint, startPos, endPos, centerPos; - wxPoint normStart = m_ArcStart - m_Pos; - wxPoint normEnd = m_ArcEnd - m_Pos; - - if( normStart == nullPoint || normEnd == nullPoint || radius == 0 ) - return rect; - - endPos = DefaultTransform.TransformCoordinate( m_ArcEnd ); - startPos = DefaultTransform.TransformCoordinate( m_ArcStart ); - centerPos = DefaultTransform.TransformCoordinate( m_Pos ); - - CalcAngles( angleStart, angleEnd ); - DefaultTransform.MapAngles( &angleStart, &angleEnd ); - - /* Start with the start and end point of the arc. */ - minX = std::min( startPos.x, endPos.x ); - minY = std::min( startPos.y, endPos.y ); - maxX = std::max( startPos.x, endPos.x ); - maxY = std::max( startPos.y, endPos.y ); - - /* Zero degrees is a special case. */ - if( angleStart == 0 ) - maxX = centerPos.x + radius; - - /* Arc end angle wrapped passed 360. */ - if( angleStart > angleEnd ) - angleEnd += 3600; - - if( angleStart <= 900 && angleEnd >= 900 ) /* 90 deg */ - maxY = centerPos.y + radius; - - if( angleStart <= 1800 && angleEnd >= 1800 ) /* 180 deg */ - minX = centerPos.x - radius; - - if( angleStart <= 2700 && angleEnd >= 2700 ) /* 270 deg */ - minY = centerPos.y - radius; - - if( angleStart <= 3600 && angleEnd >= 3600 ) /* 0 deg */ - maxX = centerPos.x + radius; - - rect.SetOrigin( minX, minY ); - rect.SetEnd( maxX, maxY ); - rect.Inflate( ( GetPenWidth() / 2 ) + 1 ); - - return rect; -} - - -void LIB_ARC::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector& aList ) -{ - wxString msg; - EDA_RECT bBox = GetBoundingBox(); - - LIB_ITEM::GetMsgPanelInfo( aFrame, aList ); - - msg = MessageTextFromValue( aFrame->GetUserUnits(), m_Width ); - - aList.emplace_back( _( "Line Width" ), msg ); - - msg.Printf( wxT( "(%d, %d, %d, %d)" ), bBox.GetOrigin().x, - bBox.GetOrigin().y, bBox.GetEnd().x, bBox.GetEnd().y ); - - aList.emplace_back( _( "Bounding Box" ), msg ); -} - - -wxString LIB_ARC::GetSelectMenuText( EDA_UNITS aUnits ) const -{ - return wxString::Format( _( "Arc, radius %s" ), - MessageTextFromValue( aUnits, GetRadius() ) ); -} - - -BITMAPS LIB_ARC::GetMenuImage() const -{ - return BITMAPS::add_arc; -} - - -void LIB_ARC::BeginEdit( const wxPoint& aPosition ) -{ - m_ArcStart = m_ArcEnd = aPosition; - m_editState = 1; -} - - -void LIB_ARC::CalcEdit( const wxPoint& aPosition ) -{ -#define sq( x ) pow( x, 2 ) - - int radius = GetRadius(); - - // Edit state 0: drawing: place ArcStart - // Edit state 1: drawing: place ArcEnd (center calculated for 90-degree subtended angle) - // Edit state 2: point editing: move ArcStart (center calculated for invariant subtended angle) - // Edit state 3: point editing: move ArcEnd (center calculated for invariant subtended angle) - // Edit state 4: point editing: move center - - switch( m_editState ) - { - case 0: - m_ArcStart = aPosition; - m_ArcEnd = aPosition; - m_Pos = aPosition; - radius = 0; - return; - - case 1: - m_ArcEnd = aPosition; - radius = KiROUND( sqrt( sq( GetLineLength( m_ArcStart, m_ArcEnd ) ) / 2.0 ) ); - break; - - case 2: - case 3: - { - wxPoint v = m_ArcStart - m_ArcEnd; - double chordBefore = sq( v.x ) + sq( v.y ); - - if( m_editState == 2 ) - m_ArcStart = aPosition; - else - m_ArcEnd = aPosition; - - v = m_ArcStart - m_ArcEnd; - double chordAfter = sq( v.x ) + sq( v.y ); - double ratio = chordAfter / chordBefore; - - if( ratio != 0 ) - { - radius = std::max( int( sqrt( sq( radius ) * ratio ) ) + 1, - int( sqrt( chordAfter ) / 2 ) + 1 ); - } - - break; - } - - case 4: - { - double chordA = GetLineLength( m_ArcStart, aPosition ); - double chordB = GetLineLength( m_ArcEnd, aPosition ); - radius = int( ( chordA + chordB ) / 2.0 ) + 1; - break; - } - } - - // Calculate center based on start, end, and radius - // - // Let 'l' be the length of the chord and 'm' the middle point of the chord - double l = GetLineLength( m_ArcStart, m_ArcEnd ); - wxPoint m = ( m_ArcStart + m_ArcEnd ) / 2; - - // Calculate 'd', the vector from the chord midpoint to the center - wxPoint d; - d.x = KiROUND( sqrt( sq( radius ) - sq( l/2 ) ) * ( m_ArcStart.y - m_ArcEnd.y ) / l ); - d.y = KiROUND( sqrt( sq( radius ) - sq( l/2 ) ) * ( m_ArcEnd.x - m_ArcStart.x ) / l ); - - wxPoint c1 = m + d; - wxPoint c2 = m - d; - - // Solution gives us 2 centers; we need to pick one: - switch( m_editState ) - { - case 1: - { - // Keep center clockwise from chord while drawing - wxPoint chordVector = twoPointVector( m_ArcStart, m_ArcEnd ); - double chordAngle = ArcTangente( chordVector.y, chordVector.x ); - NORMALIZE_ANGLE_POS( chordAngle ); - - wxPoint c1Test = c1; - RotatePoint( &c1Test, m_ArcStart, -chordAngle ); - - m_Pos = c1Test.x > 0 ? c2 : c1; - } - break; - - case 2: - case 3: - // Pick the one closer to the old center - m_Pos = ( GetLineLength( c1, m_Pos ) < GetLineLength( c2, m_Pos ) ) ? c1 : c2; - break; - - case 4: - // Pick the one closer to the mouse position - m_Pos = ( GetLineLength( c1, aPosition ) < GetLineLength( c2, aPosition ) ) ? c1 : c2; - break; - } -} - - -void LIB_ARC::CalcAngles( int& aStartAngle, int& aEndAngle ) const -{ - wxPoint centerStartVector = twoPointVector( GetCenter(), GetStart() ); - wxPoint centerEndVector = twoPointVector( GetCenter(), GetEnd() ); - - // Angles in Eeschema are still integers - aStartAngle = KiROUND( ArcTangente( centerStartVector.y, centerStartVector.x ) ); - aEndAngle = KiROUND( ArcTangente( centerEndVector.y, centerEndVector.x ) ); - - NORMALIZE_ANGLE_POS( aStartAngle ); - NORMALIZE_ANGLE_POS( aEndAngle ); // angles = 0 .. 3600 - - // Restrict angle to less than 180 to avoid PBS display mirror Trace because it is - // assumed that the arc is less than 180 deg to find orientation after rotate or mirror. - if( ( aEndAngle - aStartAngle ) > 1800 ) - aEndAngle -= 3600; - else if( ( aEndAngle - aStartAngle ) <= -1800 ) - aEndAngle += 3600; - - while( ( aEndAngle - aStartAngle ) >= 1800 ) - { - aEndAngle--; - aStartAngle++; - } - - while( ( aStartAngle - aEndAngle ) >= 1800 ) - { - aEndAngle++; - aStartAngle--; - } - - NORMALIZE_ANGLE_POS( aStartAngle ); - - if( !IsMoving() ) - NORMALIZE_ANGLE_POS( aEndAngle ); -} - - -VECTOR2I LIB_ARC::CalcMidPoint() const -{ - VECTOR2D midPoint; - int radius = GetRadius(); - int t1; - int t2; - - CalcAngles( t1, t2 ); - - double startAngle = static_cast( t1 ) / 10.0; - double endAngle = static_cast( t2 ) / 10.0; - - if( endAngle < startAngle ) - endAngle -= 360.0; - - double midPointAngle = ( ( endAngle - startAngle ) / 2.0 ) + startAngle; - double x = cos( DEG2RAD( midPointAngle ) ) * radius; - double y = sin( DEG2RAD( midPointAngle ) ) * radius; - - midPoint.x = KiROUND( x ) + m_Pos.x; - midPoint.y = KiROUND( y ) + m_Pos.y; - - return midPoint; -} diff --git a/eeschema/lib_arc.h b/eeschema/lib_arc.h deleted file mode 100644 index 07f7521f2f..0000000000 --- a/eeschema/lib_arc.h +++ /dev/null @@ -1,148 +0,0 @@ -/* - * This program source code file is part of KiCad, a free EDA CAD application. - * - * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com - * Copyright (C) 2004-2021 KiCad Developers, see change_log.txt for contributors. - * Copyright (C) 2019 CERN - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, you may find one here: - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * or you may search the http://www.gnu.org website for the version 2 license, - * or you may write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#ifndef LIB_ARC_H -#define LIB_ARC_H - -#include -#include - -class TRANSFORM; - - -class LIB_ARC : public LIB_ITEM -{ -public: - LIB_ARC( LIB_SYMBOL* aParent ); - - // Do not create a copy constructor. The one generated by the compiler is adequate. - - ~LIB_ARC() { } - - wxString GetClass() const override - { - return wxT( "LIB_ARC" ); - } - - wxString GetTypeName() const override - { - return _( "Arc" ); - } - - bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override; - bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override; - - const EDA_RECT GetBoundingBox() const override; - - void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector& aList ) override; - - int GetPenWidth() const override; - - void BeginEdit( const wxPoint& aStartPoint ) override; - void CalcEdit( const wxPoint& aPosition ) override; - void SetEditState( int aState ) { m_editState = aState; } - - void Offset( const wxPoint& aOffset ) override; - - void MoveTo( const wxPoint& aPosition ) override; - - wxPoint GetPosition() const override { return m_Pos; } - - void MirrorHorizontal( const wxPoint& aCenter ) override; - void MirrorVertical( const wxPoint& aCenter ) override; - void Rotate( const wxPoint& aCenter, bool aRotateCCW = true ) override; - - void Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill, - const TRANSFORM& aTransform ) const override; - - int GetWidth() const override { return m_Width; } - void SetWidth( int aWidth ) override { m_Width = aWidth; } - - int GetRadius() const; - - wxPoint GetStart() const { return m_ArcStart; } - void SetStart( const wxPoint& aPoint ) { m_ArcStart = aPoint; } - - wxPoint GetEnd() const { return m_ArcEnd; } - void SetEnd( const wxPoint& aPoint ) { m_ArcEnd = aPoint; } - - wxPoint GetCenter() const { return m_Pos; } - void SetCenter( const wxPoint& aPoint ) { m_Pos = aPoint; } - - - /** - * Calculate the arc mid point using the arc start and end angles and radius length. - * - * @note This is not a general purpose trigonometric arc midpoint calculation. It is - * limited to the less than 180.0 degree arcs used in symbols. - * - * @return A #VECTOR2I object containing the midpoint of the arc. - */ - VECTOR2I CalcMidPoint() const; - - /** - * Calculate the start and end angles of an arc using the start, end, and center points. - */ - void CalcAngles( int& aStartAngle, int& aEndAngle ) const; - - - wxString GetSelectMenuText( EDA_UNITS aUnits ) const override; - - BITMAPS GetMenuImage() const override; - - EDA_ITEM* Clone() const override; - -private: - void print( const RENDER_SETTINGS* aSettings, const wxPoint& aOffset, void* aData, - const TRANSFORM& aTransform ) override; - - /** - * @copydoc LIB_ITEM::compare() - * - * The arc specific sort order is as follows: - * - Arc horizontal (X) position. - * - Arc vertical (Y) position. - * - Arc start angle. - * - Arc end angle. - */ - int compare( const LIB_ITEM& aOther, - LIB_ITEM::COMPARE_FLAGS aCompareFlags = LIB_ITEM::COMPARE_FLAGS::NORMAL ) const override; - - enum SELECT_T // When creating an arc: status of arc - { - ARC_STATUS_START, - ARC_STATUS_END, - ARC_STATUS_OUTLINE, - }; - - wxPoint m_ArcStart; - wxPoint m_ArcEnd; /* Arc end position. */ - wxPoint m_Pos; /* Radius center point. */ - int m_Width; /* Line width */ - int m_editState; -}; - - -#endif // LIB_ARC_H diff --git a/eeschema/lib_bezier.cpp b/eeschema/lib_bezier.cpp deleted file mode 100644 index ba084613ce..0000000000 --- a/eeschema/lib_bezier.cpp +++ /dev/null @@ -1,353 +0,0 @@ -/* - * This program source code file is part of KiCad, a free EDA CAD application. - * - * Copyright (C) 2004-2021 KiCad Developers, see AUTHORS.txt for contributors. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, you may find one here: - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * or you may search the http://www.gnu.org website for the version 2 license, - * or you may write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -LIB_BEZIER::LIB_BEZIER( LIB_SYMBOL* aParent ) : - LIB_ITEM( LIB_BEZIER_T, aParent ) -{ - m_fill = FILL_TYPE::NO_FILL; - m_Width = 0; - m_isFillable = true; -} - - -EDA_ITEM* LIB_BEZIER::Clone() const -{ - return new LIB_BEZIER( *this ); -} - - -int LIB_BEZIER::compare( const LIB_ITEM& aOther, LIB_ITEM::COMPARE_FLAGS aCompareFlags ) const -{ - wxASSERT( aOther.Type() == LIB_BEZIER_T ); - - int retv = LIB_ITEM::compare( aOther ); - - if( retv ) - return retv; - - const LIB_BEZIER* tmp = ( LIB_BEZIER* ) &aOther; - - if( m_BezierPoints.size() != tmp->m_BezierPoints.size() ) - return m_BezierPoints.size() - tmp->m_BezierPoints.size(); - - for( size_t i = 0; i < m_BezierPoints.size(); i++ ) - { - if( m_BezierPoints[i].x != tmp->m_BezierPoints[i].x ) - return m_BezierPoints[i].x - tmp->m_BezierPoints[i].x; - - if( m_BezierPoints[i].y != tmp->m_BezierPoints[i].y ) - return m_BezierPoints[i].y - tmp->m_BezierPoints[i].y; - } - - return 0; -} - - -void LIB_BEZIER::Offset( const wxPoint& aOffset ) -{ - size_t i; - - for( i = 0; i < m_BezierPoints.size(); i++ ) - m_BezierPoints[i] += aOffset; - - for( i = 0; i < m_PolyPoints.size(); i++ ) - m_PolyPoints[i] += aOffset; -} - - -void LIB_BEZIER::MoveTo( const wxPoint& aPosition ) -{ - if ( !m_PolyPoints.size() ) - m_PolyPoints.emplace_back(0, 0 ); - - Offset( aPosition - m_PolyPoints[ 0 ] ); -} - - -const wxPoint LIB_BEZIER::GetOffset() const -{ - if ( !m_PolyPoints.size() ) - return wxPoint(0, 0); - - return m_PolyPoints[0]; -} - - -void LIB_BEZIER::MirrorHorizontal( const wxPoint& aCenter ) -{ - size_t i, imax = m_PolyPoints.size(); - - for( i = 0; i < imax; i++ ) - { - m_PolyPoints[i].x -= aCenter.x; - m_PolyPoints[i].x *= -1; - m_PolyPoints[i].x += aCenter.x; - } - - imax = m_BezierPoints.size(); - - for( i = 0; i < imax; i++ ) - { - m_BezierPoints[i].x -= aCenter.x; - m_BezierPoints[i].x *= -1; - m_BezierPoints[i].x += aCenter.x; - } -} - - -void LIB_BEZIER::MirrorVertical( const wxPoint& aCenter ) -{ - size_t i, imax = m_PolyPoints.size(); - - for( i = 0; i < imax; i++ ) - { - m_PolyPoints[i].y -= aCenter.y; - m_PolyPoints[i].y *= -1; - m_PolyPoints[i].y += aCenter.y; - } - - imax = m_BezierPoints.size(); - - for( i = 0; i < imax; i++ ) - { - m_BezierPoints[i].y -= aCenter.y; - m_BezierPoints[i].y *= -1; - m_BezierPoints[i].y += aCenter.y; - } -} - - -void LIB_BEZIER::Rotate( const wxPoint& aCenter, bool aRotateCCW ) -{ - int rot_angle = aRotateCCW ? -900 : 900; - - for( wxPoint& point : m_PolyPoints ) - RotatePoint( &point, aCenter, rot_angle ); - - for( wxPoint& bezierPoint : m_BezierPoints ) - RotatePoint( &bezierPoint, aCenter, rot_angle ); -} - - -void LIB_BEZIER::Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill, - const TRANSFORM& aTransform ) const -{ - wxASSERT( aPlotter != nullptr ); - - static std::vector< wxPoint > cornerList; - cornerList.clear(); - - for( wxPoint pos : m_PolyPoints ) - { - pos = aTransform.TransformCoordinate( pos ) + aOffset; - cornerList.push_back( pos ); - } - - if( aFill && m_fill == FILL_TYPE::FILLED_WITH_BG_BODYCOLOR ) - { - aPlotter->SetColor( aPlotter->RenderSettings()->GetLayerColor( LAYER_DEVICE_BACKGROUND ) ); - aPlotter->PlotPoly( cornerList, FILL_TYPE::FILLED_WITH_BG_BODYCOLOR, 0 ); - } - - bool already_filled = m_fill == FILL_TYPE::FILLED_WITH_BG_BODYCOLOR; - int pen_size = GetEffectivePenWidth( aPlotter->RenderSettings() ); - - if( !already_filled || pen_size > 0 ) - { - aPlotter->SetColor( aPlotter->RenderSettings()->GetLayerColor( LAYER_DEVICE ) ); - aPlotter->PlotPoly( cornerList, already_filled ? FILL_TYPE::NO_FILL : m_fill, pen_size ); - } -} - - -int LIB_BEZIER::GetPenWidth() const -{ - return m_Width; -} - - -void LIB_BEZIER::print( const RENDER_SETTINGS* aSettings, const wxPoint& aOffset, void* aData, - const TRANSFORM& aTransform ) -{ - bool forceNoFill = static_cast( aData ); - int penWidth = GetEffectivePenWidth( aSettings ); - - if( forceNoFill && m_fill != FILL_TYPE::NO_FILL && penWidth == 0 ) - return; - - std::vector PolyPointsTraslated; - - wxDC* DC = aSettings->GetPrintDC(); - COLOR4D color = aSettings->GetLayerColor( LAYER_DEVICE ); - BEZIER_POLY converter( m_BezierPoints ); - converter.GetPoly( m_PolyPoints ); - - PolyPointsTraslated.clear(); - - for( wxPoint& point : m_PolyPoints ) - PolyPointsTraslated.push_back( aTransform.TransformCoordinate( point ) + aOffset ); - - if( forceNoFill || m_fill == FILL_TYPE::NO_FILL ) - { - GRPoly( nullptr, DC, m_PolyPoints.size(), &PolyPointsTraslated[0], false, penWidth, - color, color ); - } - else - { - if( m_fill == FILL_TYPE::FILLED_WITH_BG_BODYCOLOR ) - color = aSettings->GetLayerColor( LAYER_DEVICE_BACKGROUND ); - - GRPoly( nullptr, DC, m_PolyPoints.size(), &PolyPointsTraslated[0], true, penWidth, - color, color ); - } -} - - -bool LIB_BEZIER::HitTest( const wxPoint& aRefPos, int aAccuracy ) const -{ - int mindist = std::max( aAccuracy + GetPenWidth() / 2, - Mils2iu( MINIMUM_SELECTION_DISTANCE ) ); - wxPoint start, end; - - for( unsigned ii = 1; ii < GetCornerCount(); ii++ ) - { - start = DefaultTransform.TransformCoordinate( m_PolyPoints[ii - 1] ); - end = DefaultTransform.TransformCoordinate( m_PolyPoints[ii] ); - - if ( TestSegmentHit( aRefPos, start, end, mindist ) ) - return true; - } - - return false; -} - - -bool LIB_BEZIER::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const -{ - if( m_flags & (STRUCT_DELETED | SKIP_STRUCT ) ) - return false; - - EDA_RECT sel = aRect; - - if ( aAccuracy ) - sel.Inflate( aAccuracy ); - - if( aContained ) - return sel.Contains( GetBoundingBox() ); - - // Fast test: if aRect is outside the polygon bounding box, rectangles cannot intersect - if( !sel.Intersects( GetBoundingBox() ) ) - return false; - - // Account for the width of the line - sel.Inflate( GetWidth() / 2 ); - unsigned count = m_BezierPoints.size(); - - for( unsigned ii = 1; ii < count; ii++ ) - { - wxPoint vertex = DefaultTransform.TransformCoordinate( m_BezierPoints[ii-1] ); - wxPoint vertexNext = DefaultTransform.TransformCoordinate( m_BezierPoints[ii] ); - - // Test if the point is within aRect - if( sel.Contains( vertex ) ) - return true; - - // Test if this edge intersects aRect - if( sel.Intersects( vertex, vertexNext ) ) - return true; - } - - return false; -} - - -const EDA_RECT LIB_BEZIER::GetBoundingBox() const -{ - EDA_RECT rect; - int xmin, xmax, ymin, ymax; - - if( !GetCornerCount() ) - return rect; - - xmin = xmax = m_PolyPoints[0].x; - ymin = ymax = m_PolyPoints[0].y; - - for( unsigned ii = 1; ii < GetCornerCount(); ii++ ) - { - xmin = std::min( xmin, m_PolyPoints[ii].x ); - xmax = std::max( xmax, m_PolyPoints[ii].x ); - ymin = std::min( ymin, m_PolyPoints[ii].y ); - ymax = std::max( ymax, m_PolyPoints[ii].y ); - } - - rect.SetOrigin( xmin, ymin ); - rect.SetEnd( xmax, ymax ); - rect.Inflate( ( GetPenWidth() / 2 ) + 1 ); - - rect.RevertYAxis(); - - return rect; -} - - -void LIB_BEZIER::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector& aList ) -{ - wxString msg; - EDA_RECT bBox = GetBoundingBox(); - - LIB_ITEM::GetMsgPanelInfo( aFrame, aList ); - - msg = MessageTextFromValue( aFrame->GetUserUnits(), m_Width ); - - aList.emplace_back( _( "Line Width" ), msg ); - - msg.Printf( wxT( "(%d, %d, %d, %d)" ), - bBox.GetOrigin().x, - bBox.GetOrigin().y, - bBox.GetEnd().x, - bBox.GetEnd().y ); - - aList.emplace_back( _( "Bounding Box" ), msg ); -} - -wxPoint LIB_BEZIER::GetPosition() const -{ - if( !m_PolyPoints.size() ) - return wxPoint(0, 0); - - return m_PolyPoints[0]; -} diff --git a/eeschema/lib_bezier.h b/eeschema/lib_bezier.h deleted file mode 100644 index 6235df1985..0000000000 --- a/eeschema/lib_bezier.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * This program source code file is part of KiCad, a free EDA CAD application. - * - * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com - * Copyright (C) 2004-2021 KiCad Developers, see change_log.txt for contributors. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, you may find one here: - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * or you may search the http://www.gnu.org website for the version 2 license, - * or you may write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#ifndef LIB_BEZIER_H -#define LIB_BEZIER_H - -#include - - -/** - * Define a bezier curve graphic body item. - */ -class LIB_BEZIER : public LIB_ITEM -{ -public: - LIB_BEZIER( LIB_SYMBOL* aParent ); - - // Do not create a copy constructor. The one generated by the compiler is adequate. - - ~LIB_BEZIER() { } - - wxString GetClass() const override - { - return wxT( "LIB_BEZIER" ); - } - - wxString GetTypeName() const override - { - return _( "Bezier" ); - } - - void Reserve( size_t aCount ) { m_BezierPoints.reserve( aCount ); } - void AddPoint( const wxPoint& aPoint ) { m_BezierPoints.push_back( aPoint ); } - - void Offset( const wxPoint& aOffset ) override; - const wxPoint GetOffset() const; - - /** - * @return the number of corners - */ - unsigned GetCornerCount() const { return m_PolyPoints.size(); } - - const std::vector< wxPoint >& GetPoints() const { return m_BezierPoints; } - - bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override; - bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override; - - const EDA_RECT GetBoundingBox() const override; - - void MoveTo( const wxPoint& aPosition ) override; - - wxPoint GetPosition() const override; - - void MirrorHorizontal( const wxPoint& aCenter ) override; - void MirrorVertical( const wxPoint& aCenter ) override; - void Rotate( const wxPoint& aCenter, bool aRotateCCW = true ) override; - - void Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill, - const TRANSFORM& aTransform ) const override; - - int GetWidth() const override { return m_Width; } - void SetWidth( int aWidth ) override { m_Width = aWidth; } - - int GetPenWidth() const override; - - void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector& aList ) override; - - EDA_ITEM* Clone() const override; - -private: - /** - * @copydoc LIB_ITEM::compare() - * - * The bezier curve specific sort order for each curve segment point is as follows: - * - Bezier horizontal (X) point position. - * - Bezier vertical (Y) point position. - */ - int compare( const LIB_ITEM& aOther, - LIB_ITEM::COMPARE_FLAGS aCompareFlags = LIB_ITEM::COMPARE_FLAGS::NORMAL ) const override; - - void print( const RENDER_SETTINGS* aSettings, const wxPoint& aOffset, - void* aData, const TRANSFORM& aTransform ) override; - - int m_Width; // Line width - std::vector m_BezierPoints; // list of parameter (3|4) - std::vector m_PolyPoints; // list of points (>= 2) -}; - - -#endif // LIB_BEZIER_H diff --git a/eeschema/lib_circle.cpp b/eeschema/lib_circle.cpp deleted file mode 100644 index 36cd1bf056..0000000000 --- a/eeschema/lib_circle.cpp +++ /dev/null @@ -1,285 +0,0 @@ -/* - * This program source code file is part of KiCad, a free EDA CAD application. - * - * Copyright (C) 2017 Jean-Pierre Charras, jp.charras at wanadoo.fr - * Copyright (C) 2004-2021 KiCad Developers, see AUTHORS.txt for contributors. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, you may find one here: - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * or you may search the http://www.gnu.org website for the version 2 license, - * or you may write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include // for KiROUND -#include -#include -#include -#include -#include - - -LIB_CIRCLE::LIB_CIRCLE( LIB_SYMBOL* aParent ) : - LIB_ITEM( LIB_CIRCLE_T, aParent ) -{ - m_Width = 0; - m_fill = FILL_TYPE::NO_FILL; - m_isFillable = true; -} - - -bool LIB_CIRCLE::HitTest( const wxPoint& aPosRef, int aAccuracy ) const -{ - int mindist = std::max( aAccuracy + GetPenWidth() / 2, - Mils2iu( MINIMUM_SELECTION_DISTANCE ) ); - int dist = KiROUND( GetLineLength( aPosRef, DefaultTransform.TransformCoordinate( m_Pos ) ) ); - - if( abs( dist - GetRadius() ) <= mindist ) - return true; - - if( m_fill == FILL_TYPE::NO_FILL ) - return false; - - return dist <= GetRadius(); -} - - -bool LIB_CIRCLE::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const -{ - if( m_flags & (STRUCT_DELETED | SKIP_STRUCT ) ) - return false; - - wxPoint center = DefaultTransform.TransformCoordinate( GetPosition() ); - int radius = GetRadius(); - int lineWidth = GetWidth(); - EDA_RECT sel = aRect ; - - if ( aAccuracy ) - sel.Inflate( aAccuracy ); - - if( aContained ) - return sel.Contains( GetBoundingBox() ); - - // If the rectangle does not intersect the bounding box, this is a much quicker test - if( !sel.Intersects( GetBoundingBox() ) ) - return false; - else - return sel.IntersectsCircleEdge( center, radius, lineWidth ); -} - - -EDA_ITEM* LIB_CIRCLE::Clone() const -{ - return new LIB_CIRCLE( *this ); -} - - -int LIB_CIRCLE::compare( const LIB_ITEM& aOther, LIB_ITEM::COMPARE_FLAGS aCompareFlags ) const -{ - wxASSERT( aOther.Type() == LIB_CIRCLE_T ); - - int retv = LIB_ITEM::compare( aOther, aCompareFlags ); - - if( retv ) - return retv; - - const LIB_CIRCLE* tmp = ( LIB_CIRCLE* ) &aOther; - - if( m_Pos.x != tmp->m_Pos.x ) - return m_Pos.x - tmp->m_Pos.x; - - if( m_Pos.y != tmp->m_Pos.y ) - return m_Pos.y - tmp->m_Pos.y; - - if( m_EndPos.x != tmp->m_EndPos.x ) - return m_EndPos.x - tmp->m_EndPos.x; - - if( m_EndPos.y != tmp->m_EndPos.y ) - return m_EndPos.y - tmp->m_EndPos.y; - - return 0; -} - - -void LIB_CIRCLE::Offset( const wxPoint& aOffset ) -{ - m_Pos += aOffset; - m_EndPos += aOffset; -} - - -void LIB_CIRCLE::MoveTo( const wxPoint& aPosition ) -{ - Offset( aPosition - m_Pos ); -} - - -void LIB_CIRCLE::MirrorHorizontal( const wxPoint& aCenter ) -{ - m_Pos.x -= aCenter.x; - m_Pos.x *= -1; - m_Pos.x += aCenter.x; - m_EndPos.x -= aCenter.x; - m_EndPos.x *= -1; - m_EndPos.x += aCenter.x; -} - - -void LIB_CIRCLE::MirrorVertical( const wxPoint& aCenter ) -{ - m_Pos.y -= aCenter.y; - m_Pos.y *= -1; - m_Pos.y += aCenter.y; - m_EndPos.y -= aCenter.y; - m_EndPos.y *= -1; - m_EndPos.y += aCenter.y; -} - - -void LIB_CIRCLE::Rotate( const wxPoint& aCenter, bool aRotateCCW ) -{ - int rot_angle = aRotateCCW ? -900 : 900; - - RotatePoint( &m_Pos, aCenter, rot_angle ); - RotatePoint( &m_EndPos, aCenter, rot_angle ); -} - - -void LIB_CIRCLE::Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill, - const TRANSFORM& aTransform ) const -{ - wxPoint pos = aTransform.TransformCoordinate( m_Pos ) + aOffset; - - if( aFill && m_fill == FILL_TYPE::FILLED_WITH_BG_BODYCOLOR ) - { - aPlotter->SetColor( aPlotter->RenderSettings()->GetLayerColor( LAYER_DEVICE_BACKGROUND ) ); - aPlotter->Circle( pos, GetRadius() * 2, FILL_TYPE::FILLED_WITH_BG_BODYCOLOR, 0 ); - } - - bool already_filled = m_fill == FILL_TYPE::FILLED_WITH_BG_BODYCOLOR; - int pen_size = GetEffectivePenWidth( aPlotter->RenderSettings() ); - - if( !already_filled || pen_size > 0 ) - { - aPlotter->SetColor( aPlotter->RenderSettings()->GetLayerColor( LAYER_DEVICE ) ); - aPlotter->Circle( pos, GetRadius() * 2, already_filled ? FILL_TYPE::NO_FILL : m_fill, - pen_size ); - } -} - - -int LIB_CIRCLE::GetPenWidth() const -{ - return m_Width; -} - - -void LIB_CIRCLE::print( const RENDER_SETTINGS* aSettings, const wxPoint& aOffset, - void* aData, const TRANSFORM& aTransform ) -{ - bool forceNoFill = static_cast( aData ); - int penWidth = GetEffectivePenWidth( aSettings ); - - if( forceNoFill && m_fill != FILL_TYPE::NO_FILL && penWidth == 0 ) - return; - - wxDC* DC = aSettings->GetPrintDC(); - wxPoint pos1 = aTransform.TransformCoordinate( m_Pos ) + aOffset; - COLOR4D color = aSettings->GetLayerColor( LAYER_DEVICE ); - - if( forceNoFill || m_fill == FILL_TYPE::NO_FILL ) - { - GRCircle( nullptr, DC, pos1.x, pos1.y, GetRadius(), penWidth, color ); - } - else - { - if( m_fill == FILL_TYPE::FILLED_WITH_BG_BODYCOLOR ) - color = aSettings->GetLayerColor( LAYER_DEVICE_BACKGROUND ); - - GRFilledCircle( nullptr, DC, pos1.x, pos1.y, GetRadius(), 0, color, color ); - } -} - - -const EDA_RECT LIB_CIRCLE::GetBoundingBox() const -{ - EDA_RECT rect; - int radius = GetRadius(); - - rect.SetOrigin( m_Pos.x - radius, m_Pos.y - radius ); - rect.SetEnd( m_Pos.x + radius, m_Pos.y + radius ); - rect.Inflate( ( GetPenWidth() / 2 ) + 1 ); - - rect.RevertYAxis(); - - return rect; -} - - -void LIB_CIRCLE::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector& aList ) -{ - EDA_RECT bBox = GetBoundingBox(); - - LIB_ITEM::GetMsgPanelInfo( aFrame, aList ); - - aList.emplace_back( _( "Line Width" ), MessageTextFromValue( aFrame->GetUserUnits(), - m_Width ) ); - - aList.emplace_back( _( "Radius" ), MessageTextFromValue( aFrame->GetUserUnits(), - GetRadius() ) ); - - aList.emplace_back( _( "Bounding Box" ), wxString::Format( wxT( "(%d, %d, %d, %d)" ), - bBox.GetOrigin().x, - bBox.GetOrigin().y, - bBox.GetEnd().x, - bBox.GetEnd().y ) ); -} - - -int LIB_CIRCLE::GetRadius() const -{ - return KiROUND( GetLineLength( m_EndPos, m_Pos ) ); -} - - -wxString LIB_CIRCLE::GetSelectMenuText( EDA_UNITS aUnits ) const -{ - return wxString::Format( _( "Circle, radius %s" ), - MessageTextFromValue( aUnits, GetRadius() ) ); -} - - -BITMAPS LIB_CIRCLE::GetMenuImage() const -{ - return BITMAPS::add_circle; -} - - -void LIB_CIRCLE::BeginEdit( const wxPoint& aPosition ) -{ - m_Pos = aPosition; -} - - -void LIB_CIRCLE::CalcEdit( const wxPoint& aPosition ) -{ - SetEnd( aPosition ); -} diff --git a/eeschema/lib_circle.h b/eeschema/lib_circle.h deleted file mode 100644 index 6676412f65..0000000000 --- a/eeschema/lib_circle.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * This program source code file is part of KiCad, a free EDA CAD application. - * - * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com - * Copyright (C) 2004-2021 KiCad Developers, see AUTHORS.txt for contributors. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, you may find one here: - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * or you may search the http://www.gnu.org website for the version 2 license, - * or you may write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#ifndef LIB_CIRCLE_H -#define LIB_CIRCLE_H - -#include - - -class LIB_CIRCLE : public LIB_ITEM -{ -public: - LIB_CIRCLE( LIB_SYMBOL* aParent ); - - // Do not create a copy constructor. The one generated by the compiler is adequate. - - ~LIB_CIRCLE() { } - - wxString GetClass() const override - { - return wxT( "LIB_CIRCLE" ); - } - - wxString GetTypeName() const override - { - return _( "Circle" ); - } - - bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override; - bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override; - - int GetPenWidth() const override; - - const EDA_RECT GetBoundingBox() const override; - - void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector& aList ) override; - - void BeginEdit( const wxPoint& aStartPoint ) override; - void CalcEdit( const wxPoint& aPosition ) override; - - void Offset( const wxPoint& aOffset ) override; - - void MoveTo( const wxPoint& aPosition ) override; - - wxPoint GetPosition() const override { return m_Pos; } - - void SetEnd( const wxPoint& aPosition ) { m_EndPos = aPosition; } - wxPoint GetEnd() const { return m_EndPos; } - - void MirrorHorizontal( const wxPoint& aCenter ) override; - void MirrorVertical( const wxPoint& aCenter ) override; - void Rotate( const wxPoint& aCenter, bool aRotateCCW = true ) override; - - void Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill, - const TRANSFORM& aTransform ) const override; - - int GetWidth() const override { return m_Width; } - void SetWidth( int aWidth ) override { m_Width = aWidth; } - - void SetRadius( int aRadius ) { m_EndPos = wxPoint( m_Pos.x + aRadius, m_Pos.y ); } - int GetRadius() const; - - wxString GetSelectMenuText( EDA_UNITS aUnits ) const override; - - BITMAPS GetMenuImage() const override; - - EDA_ITEM* Clone() const override; - -private: - /** - * @copydoc LIB_ITEM::compare() - * - * The circle specific sort order is as follows: - * - Circle horizontal (X) position. - * - Circle vertical (Y) position. - * - Circle radius. - */ - int compare( const LIB_ITEM& aOther, - LIB_ITEM::COMPARE_FLAGS aCompareFlags = LIB_ITEM::COMPARE_FLAGS::NORMAL ) const override; - - void print( const RENDER_SETTINGS* aSettings, const wxPoint& aOffset, void* aData, - const TRANSFORM& aTransform ) override; - - wxPoint m_Pos; // Position or centre (Arc and Circle) or start point (segments). - wxPoint m_EndPos; // A point on the circumference of the circle. - int m_Width; // Line width. -}; - - -#endif // LIB_CIRCLE_H diff --git a/eeschema/lib_field.h b/eeschema/lib_field.h index eb2b889406..93e77474e4 100644 --- a/eeschema/lib_field.h +++ b/eeschema/lib_field.h @@ -163,9 +163,6 @@ public: void Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill, const TRANSFORM& aTransform ) const override; - int GetWidth() const override { return GetTextThickness(); } - void SetWidth( int aWidth ) override { SetTextThickness( aWidth ); } - wxString GetSelectMenuText( EDA_UNITS aUnits ) const override; BITMAPS GetMenuImage() const override; diff --git a/eeschema/lib_item.cpp b/eeschema/lib_item.cpp index 56d730cee3..01f5bfb605 100644 --- a/eeschema/lib_item.cpp +++ b/eeschema/lib_item.cpp @@ -3,7 +3,7 @@ * * Copyright (C) 2015 Jean-Pierre Charras, jaen-pierre.charras at wanadoo.fr * Copyright (C) 2015 Wayne Stambaugh - * Copyright (C) 2004-2019 KiCad Developers, see change_log.txt for contributors. + * Copyright (C) 2004-2021 KiCad Developers, see change_log.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -25,25 +25,19 @@ #include #include - +#include #include #include const int fill_tab[3] = { 'N', 'F', 'f' }; -LIB_ITEM::LIB_ITEM( KICAD_T aType, - LIB_SYMBOL* aSymbol, - int aUnit, - int aConvert, - FILL_TYPE aFillType ) : - EDA_ITEM( aType ) +LIB_ITEM::LIB_ITEM( KICAD_T aType, LIB_SYMBOL* aSymbol, int aUnit, int aConvert ) : + EDA_ITEM( aSymbol, aType ), + m_unit( aUnit ), + m_convert( aConvert ), + m_editState( 0 ) { - m_unit = aUnit; - m_convert = aConvert; - m_fill = aFillType; - m_parent = (EDA_ITEM*) aSymbol; - m_isFillable = false; } @@ -83,9 +77,6 @@ int LIB_ITEM::compare( const LIB_ITEM& aOther, LIB_ITEM::COMPARE_FLAGS aCompareF if( !( aCompareFlags & COMPARE_FLAGS::UNIT ) && m_convert != aOther.m_convert ) return m_convert - aOther.m_convert; - if( m_fill != aOther.m_fill ) - return static_cast( m_fill ) - static_cast( aOther.m_fill ); - return 0; } diff --git a/eeschema/lib_item.h b/eeschema/lib_item.h index 0ab1f76208..5085e7df82 100644 --- a/eeschema/lib_item.h +++ b/eeschema/lib_item.h @@ -28,7 +28,7 @@ #include #include -#include +#include #include #include @@ -61,8 +61,7 @@ typedef std::vector< LIB_PIN* > LIB_PINS; class LIB_ITEM : public EDA_ITEM { public: - LIB_ITEM( KICAD_T aType, LIB_SYMBOL* aSymbol = nullptr, int aUnit = 0, int aConvert = 0, - FILL_TYPE aFillType = FILL_TYPE::NO_FILL ); + LIB_ITEM( KICAD_T aType, LIB_SYMBOL* aSymbol = nullptr, int aUnit = 0, int aConvert = 0 ); // Do not create a copy constructor. The one generated by the compiler is adequate. @@ -127,6 +126,12 @@ public: */ virtual void CalcEdit( const wxPoint& aPosition ) {} + /** + * For use by more complex editing routines that need to indicate what phase they are in. + * @param aState + */ + virtual void SetEditState( int aState ) { m_editState = aState; } + /** * Draw an item * @@ -148,9 +153,7 @@ public: // For historical reasons, a stored value of 0 means "default width" and negative // numbers meant "don't stroke". - if( GetPenWidth() < 0 && GetFillMode() != FILL_TYPE::NO_FILL ) - return 0; - else if( GetPenWidth() == 0 ) + if( GetPenWidth() <= 0 ) return aSettings->GetDefaultPenWidth(); else return std::max( GetPenWidth(), aSettings->GetMinPenWidth() ); @@ -257,26 +260,12 @@ public: virtual void Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill, const TRANSFORM& aTransform ) const = 0; - virtual int GetWidth() const = 0; - virtual void SetWidth( int aWidth ) = 0; - - /** - * Check if draw object can be filled. - * - * The default setting is false. If the derived object support filling, set the - * m_isFillable member to true. - */ - bool IsFillable() const { return m_isFillable; } - void SetUnit( int aUnit ) { m_unit = aUnit; } int GetUnit() const { return m_unit; } void SetConvert( int aConvert ) { m_convert = aConvert; } int GetConvert() const { return m_convert; } - void SetFillMode( FILL_TYPE aFillMode ) { m_fill = aFillMode; } - FILL_TYPE GetFillMode() const { return m_fill; } - #if defined(DEBUG) void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); } #endif @@ -332,12 +321,7 @@ protected: */ int m_convert; - /** - * The body fill type. This has meaning only for some items. For a list of fill types - * see #FILL_TYPE. - */ - FILL_TYPE m_fill; - bool m_isFillable; + int m_editState; }; diff --git a/eeschema/lib_pin.cpp b/eeschema/lib_pin.cpp index cf35515499..be7fe1762e 100644 --- a/eeschema/lib_pin.cpp +++ b/eeschema/lib_pin.cpp @@ -571,7 +571,7 @@ void LIB_PIN::PlotSymbol( PLOTTER* aPlotter, const wxPoint& aPosition, int aOrie { const int radius = externalPinDecoSize( aPlotter->RenderSettings(), *this ); aPlotter->Circle( wxPoint( MapX1 * radius + x1, MapY1 * radius + y1 ), radius * 2, - FILL_TYPE::NO_FILL, penWidth ); + FILL_T::NO_FILL, penWidth ); aPlotter->MoveTo( wxPoint( MapX1 * radius * 2 + x1, MapY1 * radius * 2 + y1 ) ); aPlotter->FinishTo( aPosition ); diff --git a/eeschema/lib_pin.h b/eeschema/lib_pin.h index 77585c2efb..ffcf85593f 100644 --- a/eeschema/lib_pin.h +++ b/eeschema/lib_pin.h @@ -219,10 +219,6 @@ public: void Plot( PLOTTER* aPlotter, const wxPoint& aPffset, bool aFill, const TRANSFORM& aTransform ) const override; - // Get/SetWidth() not used for pins. Use GetPenWidth() for drawing. - int GetWidth() const override { return 1; } - void SetWidth( int aWidth ) override { }; - BITMAPS GetMenuImage() const override; wxString GetSelectMenuText( EDA_UNITS aUnits ) const override; diff --git a/eeschema/lib_polyline.cpp b/eeschema/lib_polyline.cpp deleted file mode 100644 index 0b3faa3669..0000000000 --- a/eeschema/lib_polyline.cpp +++ /dev/null @@ -1,390 +0,0 @@ -/* - * This program source code file is part of KiCad, a free EDA CAD application. - * - * Copyright (C) 2017 Jean-Pierre Charras, jp.charras at wanadoo.fr - * Copyright (C) 2004-2021 KiCad Developers, see AUTHORS.txt for contributors. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, you may find one here: - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * or you may search the http://www.gnu.org website for the version 2 license, - * or you may write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -LIB_POLYLINE::LIB_POLYLINE( LIB_SYMBOL* aParent ) : - LIB_ITEM( LIB_POLYLINE_T, aParent ) -{ - m_fill = FILL_TYPE::NO_FILL; - m_Width = 0; - m_isFillable = true; -} - - -EDA_ITEM* LIB_POLYLINE::Clone() const -{ - return new LIB_POLYLINE( *this ); -} - - -int LIB_POLYLINE::compare( const LIB_ITEM& aOther, LIB_ITEM::COMPARE_FLAGS aCompareFlags ) const -{ - wxASSERT( aOther.Type() == LIB_POLYLINE_T ); - - int retv = LIB_ITEM::compare( aOther ); - - if( retv ) - return retv; - - const LIB_POLYLINE* tmp = (LIB_POLYLINE*) &aOther; - - if( m_PolyPoints.size() != tmp->m_PolyPoints.size() ) - return m_PolyPoints.size() - tmp->m_PolyPoints.size(); - - for( size_t i = 0; i < m_PolyPoints.size(); i++ ) - { - if( m_PolyPoints[i].x != tmp->m_PolyPoints[i].x ) - return m_PolyPoints[i].x - tmp->m_PolyPoints[i].x; - - if( m_PolyPoints[i].y != tmp->m_PolyPoints[i].y ) - return m_PolyPoints[i].y - tmp->m_PolyPoints[i].y; - } - - return 0; -} - - -void LIB_POLYLINE::Offset( const wxPoint& aOffset ) -{ - for( wxPoint& point : m_PolyPoints ) - point += aOffset; -} - - -void LIB_POLYLINE::MoveTo( const wxPoint& aPosition ) -{ - Offset( aPosition - m_PolyPoints[ 0 ] ); -} - - -void LIB_POLYLINE::MirrorHorizontal( const wxPoint& aCenter ) -{ - for( wxPoint& point : m_PolyPoints ) - { - point.x -= aCenter.x; - point.x *= -1; - point.x += aCenter.x; - } -} - -void LIB_POLYLINE::MirrorVertical( const wxPoint& aCenter ) -{ - for( wxPoint& point : m_PolyPoints ) - { - point.y -= aCenter.y; - point.y *= -1; - point.y += aCenter.y; - } -} - -void LIB_POLYLINE::Rotate( const wxPoint& aCenter, bool aRotateCCW ) -{ - for( wxPoint& point : m_PolyPoints ) - RotatePoint( &point, aCenter, aRotateCCW ? -900 : 900 ); -} - - -void LIB_POLYLINE::Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill, - const TRANSFORM& aTransform ) const -{ - wxASSERT( aPlotter != nullptr ); - - static std::vector< wxPoint > cornerList; - cornerList.clear(); - - for( wxPoint pos : m_PolyPoints ) - { - pos = aTransform.TransformCoordinate( pos ) + aOffset; - cornerList.push_back( pos ); - } - - if( aFill && m_fill == FILL_TYPE::FILLED_WITH_BG_BODYCOLOR ) - { - aPlotter->SetColor( aPlotter->RenderSettings()->GetLayerColor( LAYER_DEVICE_BACKGROUND ) ); - aPlotter->PlotPoly( cornerList, FILL_TYPE::FILLED_WITH_BG_BODYCOLOR, 0 ); - } - - bool already_filled = m_fill == FILL_TYPE::FILLED_WITH_BG_BODYCOLOR; - int pen_size = GetEffectivePenWidth( aPlotter->RenderSettings() ); - - if( !already_filled || pen_size > 0 ) - { - aPlotter->SetColor( aPlotter->RenderSettings()->GetLayerColor( LAYER_DEVICE ) ); - aPlotter->PlotPoly( cornerList, already_filled ? FILL_TYPE::NO_FILL : m_fill, pen_size ); - } -} - - -void LIB_POLYLINE::AddPoint( const wxPoint& aPosition ) -{ - m_PolyPoints.push_back( aPosition ); -} - - -void LIB_POLYLINE::AddCorner( const wxPoint& aPosition ) -{ - int currentMinDistance = INT_MAX; - int closestLineStart = 0; - - for( unsigned i = 0; i < m_PolyPoints.size() - 1; ++i ) - { - int distance = (int) DistanceLinePoint( m_PolyPoints[i], m_PolyPoints[i + 1], aPosition ); - - if( distance < currentMinDistance ) - { - currentMinDistance = distance; - closestLineStart = i; - } - } - - m_PolyPoints.insert( m_PolyPoints.begin() + closestLineStart, aPosition ); -} - - -void LIB_POLYLINE::RemoveCorner( int aIdx ) -{ - m_PolyPoints.erase( m_PolyPoints.begin() + aIdx ); -} - - -int LIB_POLYLINE::GetPenWidth() const -{ - return m_Width; -} - - -void LIB_POLYLINE::print( const RENDER_SETTINGS* aSettings, const wxPoint& aOffset, void* aData, - const TRANSFORM& aTransform ) -{ - bool forceNoFill = static_cast( aData ); - int penWidth = GetEffectivePenWidth( aSettings ); - - if( forceNoFill && m_fill != FILL_TYPE::NO_FILL && penWidth == 0 ) - return; - - wxDC* DC = aSettings->GetPrintDC(); - COLOR4D color = aSettings->GetLayerColor( LAYER_DEVICE ); - wxPoint* buffer = new wxPoint[ m_PolyPoints.size() ]; - - for( unsigned ii = 0; ii < m_PolyPoints.size(); ii++ ) - buffer[ii] = aTransform.TransformCoordinate( m_PolyPoints[ii] ) + aOffset; - - if( forceNoFill || m_fill == FILL_TYPE::NO_FILL ) - { - GRPoly( nullptr, DC, m_PolyPoints.size(), buffer, false, penWidth, color, color ); - } - else - { - if( m_fill == FILL_TYPE::FILLED_WITH_BG_BODYCOLOR ) - color = aSettings->GetLayerColor( LAYER_DEVICE_BACKGROUND ); - - GRPoly( nullptr, DC, m_PolyPoints.size(), buffer, true, penWidth, color, color ); - } - - delete[] buffer; -} - - -bool LIB_POLYLINE::HitTest( const wxPoint& aPosition, int aAccuracy ) const -{ - int delta = std::max( aAccuracy + GetPenWidth() / 2, Mils2iu( MINIMUM_SELECTION_DISTANCE ) ); - SHAPE_LINE_CHAIN shape; - - for( wxPoint pt : m_PolyPoints ) - shape.Append( DefaultTransform.TransformCoordinate( pt ) ); - - if( m_fill != FILL_TYPE::NO_FILL && m_PolyPoints.size() > 2 ) - { - shape.SetClosed( true ); - return shape.PointInside( aPosition, delta ); - } - else - return shape.PointOnEdge( aPosition, delta ); -} - - -bool LIB_POLYLINE::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const -{ - if( m_flags & (STRUCT_DELETED | SKIP_STRUCT ) ) - return false; - - EDA_RECT sel = aRect; - - if ( aAccuracy ) - sel.Inflate( aAccuracy ); - - if( aContained ) - return sel.Contains( GetBoundingBox() ); - - // Fast test: if rect is outside the polygon bounding box, then they cannot intersect - if( !sel.Intersects( GetBoundingBox() ) ) - return false; - - // Account for the width of the line - sel.Inflate( ( GetPenWidth() / 2 ) + 1 ); - - for( size_t ii = 0; ii < m_PolyPoints.size(); ii++ ) - { - wxPoint pt = DefaultTransform.TransformCoordinate( m_PolyPoints[ ii ] ); - - // Test if the point is within aRect - if( sel.Contains( pt ) ) - return true; - - if( ii + 1 < m_PolyPoints.size() ) - { - wxPoint ptNext = DefaultTransform.TransformCoordinate( m_PolyPoints[ ii + 1 ] ); - - // Test if this edge intersects aRect - if( sel.Intersects( pt, ptNext ) ) - return true; - } - else if( m_fill != FILL_TYPE::NO_FILL ) - { - wxPoint ptNext = DefaultTransform.TransformCoordinate( m_PolyPoints[ 0 ] ); - - // Test if this edge intersects aRect - if( sel.Intersects( pt, ptNext ) ) - return true; - } - } - - return false; -} - - -const EDA_RECT LIB_POLYLINE::GetBoundingBox() const -{ - EDA_RECT rect; - int xmin, xmax, ymin, ymax; - - xmin = xmax = m_PolyPoints[0].x; - ymin = ymax = m_PolyPoints[0].y; - - for( unsigned ii = 1; ii < GetCornerCount(); ii++ ) - { - xmin = std::min( xmin, m_PolyPoints[ii].x ); - xmax = std::max( xmax, m_PolyPoints[ii].x ); - ymin = std::min( ymin, m_PolyPoints[ii].y ); - ymax = std::max( ymax, m_PolyPoints[ii].y ); - } - - rect.SetOrigin( xmin, ymin ); - rect.SetEnd( xmax, ymax ); - rect.Inflate( ( GetPenWidth() / 2 ) + 1 ); - - rect.RevertYAxis(); - - return rect; -} - - -void LIB_POLYLINE::DeleteSegment( const wxPoint aPosition ) -{ - // First segment is kept, only its end point is changed - while( GetCornerCount() > 2 ) - { - m_PolyPoints.pop_back(); - - if( m_PolyPoints[ GetCornerCount() - 1 ] != aPosition ) - { - m_PolyPoints[ GetCornerCount() - 1 ] = aPosition; - break; - } - } -} - - -void LIB_POLYLINE::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector& aList ) -{ - EDA_RECT bBox = GetBoundingBox(); - - LIB_ITEM::GetMsgPanelInfo( aFrame, aList ); - - aList.emplace_back( _( "Line Width" ), MessageTextFromValue( aFrame->GetUserUnits(), m_Width ) ); - - aList.emplace_back( _( "Bounding Box" ), wxString::Format( wxT( "(%d, %d, %d, %d)" ), - bBox.GetOrigin().x, - bBox.GetOrigin().y, - bBox.GetEnd().x, - bBox.GetEnd().y ) ); -} - - -wxString LIB_POLYLINE::GetSelectMenuText( EDA_UNITS aUnits ) const -{ - return wxString::Format( _( "Polyline, %d points" ), int( m_PolyPoints.size() ) ); -} - - -BITMAPS LIB_POLYLINE::GetMenuImage() const -{ - return BITMAPS::add_graphical_segments; -} - - -void LIB_POLYLINE::BeginEdit( const wxPoint& aPosition ) -{ - m_PolyPoints.push_back( aPosition ); // Start point of first segment. - m_PolyPoints.push_back( aPosition ); // End point of first segment. -} - - -bool LIB_POLYLINE::ContinueEdit( const wxPoint& aPosition ) -{ - // do not add zero length segments - if( m_PolyPoints[m_PolyPoints.size() - 2] != m_PolyPoints.back() ) - m_PolyPoints.push_back( aPosition ); - - return true; -} - - -void LIB_POLYLINE::EndEdit() -{ - // do not include last point twice - if( m_PolyPoints.size() > 2 ) - { - if( m_PolyPoints[ m_PolyPoints.size() - 2 ] == m_PolyPoints.back() ) - m_PolyPoints.pop_back(); - } -} - - -void LIB_POLYLINE::CalcEdit( const wxPoint& aPosition ) -{ - m_PolyPoints[ GetCornerCount() - 1 ] = aPosition; -} diff --git a/eeschema/lib_polyline.h b/eeschema/lib_polyline.h deleted file mode 100644 index 7516c39c05..0000000000 --- a/eeschema/lib_polyline.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * This program source code file is part of KiCad, a free EDA CAD application. - * - * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com - * Copyright (C) 2004-2021 KiCad Developers, see AUTHORS.txt for contributors. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, you may find one here: - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * or you may search the http://www.gnu.org website for the version 2 license, - * or you may write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#ifndef _LIB_POLYLINE_H_ -#define _LIB_POLYLINE_H_ - -#include - - -class LIB_POLYLINE : public LIB_ITEM -{ -public: - LIB_POLYLINE( LIB_SYMBOL* aParent ); - - // Do not create a copy constructor. The one generated by the compiler is adequate. - - ~LIB_POLYLINE() { } - - wxString GetClass() const override - { - return wxT( "LIB_POLYLINE" ); - } - - wxString GetTypeName() const override - { - return _( "PolyLine" ); - } - - void ClearPoints() { m_PolyPoints.clear(); } - void Reserve( size_t aPointCount ) { m_PolyPoints.reserve( aPointCount ); } - void AddPoint( const wxPoint& aPoint ); - - const std::vector< wxPoint >& GetPolyPoints() const { return m_PolyPoints; } - - /** - * Delete the segment at \a aPosition. - */ - void DeleteSegment( const wxPoint aPosition ); - - void AddCorner( const wxPoint& aPosition ); - void RemoveCorner( int aIdx ); - - /** - * @return the number of corners - */ - unsigned GetCornerCount() const { return m_PolyPoints.size(); } - - bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override; - bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override; - - const EDA_RECT GetBoundingBox() const override; - - int GetPenWidth() const override; - - void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector& aList ) override; - - void BeginEdit( const wxPoint& aStartPoint ) override; - void CalcEdit( const wxPoint& aPosition ) override; - bool ContinueEdit( const wxPoint& aNextPoint ) override; - void EndEdit() override; - - void Offset( const wxPoint& aOffset ) override; - - void MoveTo( const wxPoint& aPosition ) override; - - wxPoint GetPosition() const override { return m_PolyPoints[0]; } - - void MirrorHorizontal( const wxPoint& aCenter ) override; - void MirrorVertical( const wxPoint& aCenter ) override; - void Rotate( const wxPoint& aCenter, bool aRotateCCW = true ) override; - - void Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill, - const TRANSFORM& aTransform ) const override; - - int GetWidth() const override { return m_Width; } - void SetWidth( int aWidth ) override { m_Width = aWidth; } - - wxString GetSelectMenuText( EDA_UNITS aUnits ) const override; - - BITMAPS GetMenuImage() const override; - - EDA_ITEM* Clone() const override; - -private: - - /** - * @copydoc LIB_ITEM::compare() - * - * The sort order for specific to each polyline segment point is as follows: - * - Line segment point horizontal (X) position. - * - Line segment point vertical (Y) position. - */ - int compare( const LIB_ITEM& aOther, - LIB_ITEM::COMPARE_FLAGS aCompareFlags = LIB_ITEM::COMPARE_FLAGS::NORMAL ) const override; - - void print( const RENDER_SETTINGS* aSettings, const wxPoint& aOffset, void* aData, - const TRANSFORM& aTransform ) override; - - int m_Width; // Line width - std::vector m_PolyPoints; // list of points (>= 2) -}; - - -#endif // _LIB_POLYLINE_H_ diff --git a/eeschema/lib_rectangle.cpp b/eeschema/lib_rectangle.cpp deleted file mode 100644 index 14e03cc259..0000000000 --- a/eeschema/lib_rectangle.cpp +++ /dev/null @@ -1,292 +0,0 @@ -/* - * This program source code file is part of KiCad, a free EDA CAD application. - * - * Copyright (C) 2017 Jean-Pierre Charras, jp.charras at wanadoo.fr - * Copyright (C) 2004-2021 KiCad Developers, see AUTHORS.txt for contributors. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, you may find one here: - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * or you may search the http://www.gnu.org website for the version 2 license, - * or you may write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -LIB_RECTANGLE::LIB_RECTANGLE( LIB_SYMBOL* aParent ) : LIB_ITEM( LIB_RECTANGLE_T, aParent ) -{ - m_Width = 0; - m_fill = FILL_TYPE::NO_FILL; - m_isFillable = true; -} - - -EDA_ITEM* LIB_RECTANGLE::Clone() const -{ - return new LIB_RECTANGLE( *this ); -} - - -int LIB_RECTANGLE::compare( const LIB_ITEM& aOther, LIB_ITEM::COMPARE_FLAGS aCompareFlags ) const -{ - wxASSERT( aOther.Type() == LIB_RECTANGLE_T ); - - int retv = LIB_ITEM::compare( aOther ); - - if( retv ) - return retv; - - const LIB_RECTANGLE* tmp = ( LIB_RECTANGLE* ) &aOther; - - if( m_Pos.x != tmp->m_Pos.x ) - return m_Pos.x - tmp->m_Pos.x; - - if( m_Pos.y != tmp->m_Pos.y ) - return m_Pos.y - tmp->m_Pos.y; - - if( m_End.x != tmp->m_End.x ) - return m_End.x - tmp->m_End.x; - - if( m_End.y != tmp->m_End.y ) - return m_End.y - tmp->m_End.y; - - return 0; -} - - -void LIB_RECTANGLE::Offset( const wxPoint& aOffset ) -{ - m_Pos += aOffset; - m_End += aOffset; -} - - -void LIB_RECTANGLE::MoveTo( const wxPoint& aPosition ) -{ - wxPoint size = m_End - m_Pos; - m_Pos = aPosition; - m_End = aPosition + size; -} - - -void LIB_RECTANGLE::MirrorHorizontal( const wxPoint& aCenter ) -{ - m_Pos.x -= aCenter.x; - m_Pos.x *= -1; - m_Pos.x += aCenter.x; - m_End.x -= aCenter.x; - m_End.x *= -1; - m_End.x += aCenter.x; -} - - -void LIB_RECTANGLE::MirrorVertical( const wxPoint& aCenter ) -{ - m_Pos.y -= aCenter.y; - m_Pos.y *= -1; - m_Pos.y += aCenter.y; - m_End.y -= aCenter.y; - m_End.y *= -1; - m_End.y += aCenter.y; -} - - -void LIB_RECTANGLE::Rotate( const wxPoint& aCenter, bool aRotateCCW ) -{ - int rot_angle = aRotateCCW ? -900 : 900; - RotatePoint( &m_Pos, aCenter, rot_angle ); - RotatePoint( &m_End, aCenter, rot_angle ); -} - - -void LIB_RECTANGLE::Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill, - const TRANSFORM& aTransform ) const -{ - wxASSERT( aPlotter != nullptr ); - - wxPoint pos = aTransform.TransformCoordinate( m_Pos ) + aOffset; - wxPoint end = aTransform.TransformCoordinate( m_End ) + aOffset; - - if( aFill && m_fill == FILL_TYPE::FILLED_WITH_BG_BODYCOLOR ) - { - aPlotter->SetColor( aPlotter->RenderSettings()->GetLayerColor( LAYER_DEVICE_BACKGROUND ) ); - aPlotter->Rect( pos, end, FILL_TYPE::FILLED_WITH_BG_BODYCOLOR, 0 ); - } - - bool already_filled = m_fill == FILL_TYPE::FILLED_WITH_BG_BODYCOLOR; - int pen_size = GetEffectivePenWidth( aPlotter->RenderSettings() ); - - if( !already_filled || pen_size > 0 ) - { - aPlotter->SetColor( aPlotter->RenderSettings()->GetLayerColor( LAYER_DEVICE ) ); - aPlotter->Rect( pos, end, already_filled ? FILL_TYPE::NO_FILL : m_fill, pen_size ); - } -} - - -int LIB_RECTANGLE::GetPenWidth() const -{ - return m_Width; -} - - -void LIB_RECTANGLE::print( const RENDER_SETTINGS* aSettings, const wxPoint& aOffset, - void* aData, const TRANSFORM& aTransform ) -{ - bool forceNoFill = static_cast( aData ); - int penWidth = GetEffectivePenWidth( aSettings ); - - if( forceNoFill && m_fill != FILL_TYPE::NO_FILL && penWidth == 0 ) - return; - - wxDC* DC = aSettings->GetPrintDC(); - COLOR4D color = aSettings->GetLayerColor( LAYER_DEVICE ); - wxPoint pt1 = aTransform.TransformCoordinate( m_Pos ) + aOffset; - wxPoint pt2 = aTransform.TransformCoordinate( m_End ) + aOffset; - - if( forceNoFill || m_fill == FILL_TYPE::NO_FILL ) - { - GRRect( nullptr, DC, pt1.x, pt1.y, pt2.x, pt2.y, penWidth, color ); - } - else - { - if( m_fill == FILL_TYPE::FILLED_WITH_BG_BODYCOLOR ) - color = aSettings->GetLayerColor( LAYER_DEVICE_BACKGROUND ); - - GRFilledRect( nullptr, DC, pt1.x, pt1.y, pt2.x, pt2.y, penWidth, color, color ); - } -} - - -void LIB_RECTANGLE::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector& aList ) -{ - LIB_ITEM::GetMsgPanelInfo( aFrame, aList ); - - aList.emplace_back( _( "Line Width" ), MessageTextFromValue( aFrame->GetUserUnits(), m_Width ) ); -} - - -const EDA_RECT LIB_RECTANGLE::GetBoundingBox() const -{ - EDA_RECT rect; - - rect.SetOrigin( m_Pos ); - rect.SetEnd( m_End ); - rect.Inflate( ( GetPenWidth() / 2 ) + 1 ); - - rect.RevertYAxis(); - - return rect; -} - - -bool LIB_RECTANGLE::HitTest( const wxPoint& aPosition, int aAccuracy ) const -{ - int mindist = std::max( aAccuracy + GetPenWidth() / 2, - Mils2iu( MINIMUM_SELECTION_DISTANCE ) ); - wxPoint actualStart = DefaultTransform.TransformCoordinate( m_Pos ); - wxPoint actualEnd = DefaultTransform.TransformCoordinate( m_End ); - - // locate lower segment - wxPoint start, end; - - start = actualStart; - end.x = actualEnd.x; - end.y = actualStart.y; - - if( TestSegmentHit( aPosition, start, end, mindist ) ) - return true; - - // locate right segment - start.x = actualEnd.x; - end.y = actualEnd.y; - - if( TestSegmentHit( aPosition, start, end, mindist ) ) - return true; - - // locate upper segment - start.y = actualEnd.y; - end.x = actualStart.x; - - if( TestSegmentHit( aPosition, start, end, mindist ) ) - return true; - - // locate left segment - start = actualStart; - end.x = actualStart.x; - end.y = actualEnd.y; - - if( TestSegmentHit( aPosition, start, end, mindist ) ) - return true; - - if( m_fill == FILL_TYPE::NO_FILL ) - return false; - - return GetBoundingBox().Contains( aPosition ); -} - - -bool LIB_RECTANGLE::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const -{ - if( m_flags & (STRUCT_DELETED | SKIP_STRUCT ) ) - return false; - - EDA_RECT sel = aRect; - - if ( aAccuracy ) - sel.Inflate( aAccuracy ); - - if( aContained ) - return sel.Contains( GetBoundingBox() ); - - return sel.Intersects( GetBoundingBox() ); -} - - -wxString LIB_RECTANGLE::GetSelectMenuText( EDA_UNITS aUnits ) const -{ - return wxString::Format( _( "Rectangle, width %s height %s" ), - MessageTextFromValue( aUnits, std::abs( m_Pos.x - m_End.x ) ), - MessageTextFromValue( aUnits, std::abs( m_Pos.y - m_End.y ) ) ); -} - - -BITMAPS LIB_RECTANGLE::GetMenuImage() const -{ - return BITMAPS::add_rectangle; -} - - -void LIB_RECTANGLE::BeginEdit( const wxPoint& aPosition ) -{ - m_Pos = m_End = aPosition; -} - - -void LIB_RECTANGLE::CalcEdit( const wxPoint& aPosition ) -{ - m_End = aPosition; -} diff --git a/eeschema/lib_rectangle.h b/eeschema/lib_rectangle.h deleted file mode 100644 index afc5e0e312..0000000000 --- a/eeschema/lib_rectangle.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * This program source code file is part of KiCad, a free EDA CAD application. - * - * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com - * Copyright (C) 2004-2021 KiCad Developers, see AUTHOR.txt for contributors. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, you may find one here: - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * or you may search the http://www.gnu.org website for the version 2 license, - * or you may write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#ifndef LIB_RECTANGLE_H -#define LIB_RECTANGLE_H - -#include - - -class LIB_RECTANGLE : public LIB_ITEM -{ -public: - LIB_RECTANGLE( LIB_SYMBOL* aParent ); - - // Do not create a copy constructor. The one generated by the compiler is adequate. - - ~LIB_RECTANGLE() { } - - wxString GetClass() const override - { - return wxT( "LIB_RECTANGLE" ); - } - - wxString GetTypeName() const override - { - return _( "Rectangle" ); - } - - void SetEndPosition( const wxPoint& aPosition ) { m_End = aPosition; } - - bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override; - - bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override; - - int GetPenWidth() const override; - - const EDA_RECT GetBoundingBox() const override; - - void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector& aList ) override; - - void BeginEdit( const wxPoint& aStartPoint ) override; - void CalcEdit( const wxPoint& aPosition ) override; - - void Offset( const wxPoint& aOffset ) override; - - void MoveTo( const wxPoint& aPosition ) override; - - wxPoint GetPosition() const override { return m_Pos; } - - void MirrorHorizontal( const wxPoint& aCenter ) override; - void MirrorVertical( const wxPoint& aCenter ) override; - void Rotate( const wxPoint& aCenter, bool aRotateCCW = true ) override; - - void Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill, - const TRANSFORM& aTransform ) const override; - - int GetWidth() const override { return m_Width; } - void SetWidth( int aWidth ) override { m_Width = aWidth; } - - void SetEnd( const wxPoint& aEnd ) { m_End = aEnd; } - wxPoint GetEnd() const { return m_End; } - - wxString GetSelectMenuText( EDA_UNITS aUnits ) const override; - - BITMAPS GetMenuImage() const override; - - EDA_ITEM* Clone() const override; - -private: - /** - * @copydoc LIB_ITEM::compare() - * - * The rectangle specific sort order is as follows: - * - Rectangle horizontal (X) start position. - * - Rectangle vertical (Y) start position. - * - Rectangle horizontal (X) end position. - * - Rectangle vertical (Y) end position. - */ - int compare( const LIB_ITEM& aOther, - LIB_ITEM::COMPARE_FLAGS aCompareFlags = LIB_ITEM::COMPARE_FLAGS::NORMAL ) const override; - - void print( const RENDER_SETTINGS* aSettings, const wxPoint& aOffset, - void* aData, const TRANSFORM& aTransform ) override; - - wxPoint m_End; // Rectangle end point. - wxPoint m_Pos; // Rectangle start point. - int m_Width; // Line width -}; - - -#endif // LIB_RECTANGLE_H diff --git a/eeschema/lib_shape.cpp b/eeschema/lib_shape.cpp index 0ef902e5b6..c32c570ba8 100644 --- a/eeschema/lib_shape.cpp +++ b/eeschema/lib_shape.cpp @@ -23,7 +23,8 @@ */ #include -#include +#include +#include #include #include #include @@ -37,6 +38,7 @@ LIB_SHAPE::LIB_SHAPE( LIB_SYMBOL* aParent, SHAPE_T aShape, int aDefaultLineWidth LIB_ITEM( LIB_SHAPE_T, aParent ), EDA_SHAPE( aShape, aDefaultLineWidth, aFillType ) { + m_editState = 0; } @@ -54,7 +56,7 @@ bool LIB_SHAPE::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) if( m_flags & (STRUCT_DELETED | SKIP_STRUCT ) ) return false; - return hitTest( aRect, aContained, aAccuracy ); + return hitTest( DefaultTransform.TransformCoordinate( aRect ), aContained, aAccuracy ); } @@ -115,19 +117,20 @@ void LIB_SHAPE::Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill, wxPoint center; int startAngle; int endAngle; - int pen_size = GetPenWidth(); - FILL_T fill = aFill ? m_fill : FILL_TYPE::NO_FILL; + int pen_size = GetEffectivePenWidth( aPlotter->RenderSettings() ); + FILL_T fill = aFill ? m_fill : FILL_T::NO_FILL; static std::vector cornerList; - if( GetShape() == SHAPE_T::POLYGON ) + if( GetShape() == SHAPE_T::POLY ) { + const SHAPE_LINE_CHAIN& poly = m_poly.Outline( 0 ); cornerList.clear(); - for( const VECTOR2I& pt : m_poly.Outline( 0 ).CPoints() ) + for( const VECTOR2I& pt : poly.CPoints() ) cornerList.push_back( aTransform.TransformCoordinate( (wxPoint) pt ) + aOffset ); } - else if( GetShape() == SHAPE_T::CURVE ) + else if( GetShape() == SHAPE_T::BEZIER ) { cornerList.clear(); @@ -137,8 +140,8 @@ void LIB_SHAPE::Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill, else if( GetShape() == SHAPE_T::ARC ) { center = aTransform.TransformCoordinate( getCenter() ) + aOffset; - startAngle = GetArcAngleStart(); - endAngle = GetArcAngleEnd(); + + CalcArcAngles( startAngle, endAngle ); aTransform.MapAngles( &startAngle, &endAngle ); } @@ -160,13 +163,13 @@ void LIB_SHAPE::Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill, aPlotter->Rect( start, end, fill, 0 ); break; - case SHAPE_T::POLYGON: - case SHAPE_T::CURVE: + case SHAPE_T::POLY: + case SHAPE_T::BEZIER: aPlotter->PlotPoly( cornerList, fill, 0 ); break; default: - wxFAIL_MSG( "LIB_SHAPE::Plot not implemented for " + SHAPE_T_asString() ); + UNIMPLEMENTED_FOR( SHAPE_T_asString() ); } if( pen_size <= 0 ) @@ -175,8 +178,6 @@ void LIB_SHAPE::Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill, fill = FILL_T::NO_FILL; } - pen_size = std::max( pen_size, aPlotter->RenderSettings()->GetMinPenWidth() ); - aPlotter->SetColor( aPlotter->RenderSettings()->GetLayerColor( LAYER_DEVICE ) ); switch( GetShape() ) @@ -193,24 +194,20 @@ void LIB_SHAPE::Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill, aPlotter->Rect( start, end, fill, pen_size ); break; - case SHAPE_T::POLYGON: - case SHAPE_T::CURVE: + case SHAPE_T::POLY: + case SHAPE_T::BEZIER: aPlotter->PlotPoly( cornerList, fill, pen_size ); break; default: - wxFAIL_MSG( "LIB_SHAPE::Plot not implemented for " + SHAPE_T_asString() ); + UNIMPLEMENTED_FOR( SHAPE_T_asString() ); } } int LIB_SHAPE::GetPenWidth() const { - // Historically 0 meant "default width" and negative numbers meant "don't stroke". - if( GetWidth() < 0 && GetFillType() != FILL_T::NO_FILL ) - return 0; - else - return std::max( GetWidth(), 1 ); + return GetWidth(); } @@ -234,9 +231,9 @@ void LIB_SHAPE::print( const RENDER_SETTINGS* aSettings, const wxPoint& aOffset, unsigned ptCount = 0; wxPoint* buffer = nullptr; - if( GetShape() == SHAPE_T::POLYGON ) + if( GetShape() == SHAPE_T::POLY ) { - SHAPE_LINE_CHAIN poly = m_poly.Outline( 0 ); + const SHAPE_LINE_CHAIN& poly = m_poly.Outline( 0 ); ptCount = poly.GetPointCount(); buffer = new wxPoint[ ptCount ]; @@ -244,7 +241,7 @@ void LIB_SHAPE::print( const RENDER_SETTINGS* aSettings, const wxPoint& aOffset, for( unsigned ii = 0; ii < ptCount; ++ii ) buffer[ii] = aTransform.TransformCoordinate( (wxPoint) poly.CPoint( ii ) ) + aOffset; } - else if( GetShape() == SHAPE_T::CURVE ) + else if( GetShape() == SHAPE_T::BEZIER ) { ptCount = m_bezierPoints.size(); buffer = new wxPoint[ ptCount ]; @@ -255,8 +252,8 @@ void LIB_SHAPE::print( const RENDER_SETTINGS* aSettings, const wxPoint& aOffset, else if( GetShape() == SHAPE_T::ARC ) { c = aTransform.TransformCoordinate( getCenter() ) + aOffset; - t1 = GetArcAngleStart(); - t2 = GetArcAngleEnd(); + + CalcArcAngles( t1, t2 ); aTransform.MapAngles( &t1, &t2 ); } @@ -278,16 +275,16 @@ void LIB_SHAPE::print( const RENDER_SETTINGS* aSettings, const wxPoint& aOffset, GRRect( nullptr, DC, pt1.x, pt1.y, pt2.x, pt2.y, penWidth, color ); break; - case SHAPE_T::POLYGON: + case SHAPE_T::POLY: GRPoly( nullptr, DC, ptCount, buffer, false, penWidth, color, color ); break; - case SHAPE_T::CURVE: + case SHAPE_T::BEZIER: GRPoly( nullptr, DC, ptCount, buffer, false, penWidth, color, color ); break; default: - wxFAIL_MSG( "LIB_SHAPE::print not implemented for " + SHAPE_T_asString() ); + UNIMPLEMENTED_FOR( SHAPE_T_asString() ); } } else @@ -309,16 +306,16 @@ void LIB_SHAPE::print( const RENDER_SETTINGS* aSettings, const wxPoint& aOffset, GRFilledRect( nullptr, DC, pt1.x, pt1.y, pt2.x, pt2.y, penWidth, color, color ); break; - case SHAPE_T::POLYGON: + case SHAPE_T::POLY: GRPoly( nullptr, DC, ptCount, buffer, true, penWidth, color, color ); break; - case SHAPE_T::CURVE: + case SHAPE_T::BEZIER: GRPoly( nullptr, DC, ptCount, buffer, true, penWidth, color, color ); break; default: - wxFAIL_MSG( "LIB_SHAPE::print not implemented for " + SHAPE_T_asString() ); + UNIMPLEMENTED_FOR( SHAPE_T_asString() ); } } @@ -361,16 +358,16 @@ wxString LIB_SHAPE::GetSelectMenuText( EDA_UNITS aUnits ) const MessageTextFromValue( aUnits, std::abs( m_start.x - m_end.x ) ), MessageTextFromValue( aUnits, std::abs( m_start.y - m_end.y ) ) ); - case SHAPE_T::POLYGON: + case SHAPE_T::POLY: return wxString::Format( _( "Polyline, %d points" ), int( m_poly.Outline( 0 ).GetPointCount() ) ); - case SHAPE_T::CURVE: + case SHAPE_T::BEZIER: return wxString::Format( _( "Bezier Curve, %d points" ), int( m_bezierPoints.size() ) ); default: - wxFAIL_MSG( "LIB_SHAPE::GetSelectMenuText unimplemented for " + SHAPE_T_asString() ); + UNIMPLEMENTED_FOR( SHAPE_T_asString() ); return wxEmptyString; } } @@ -380,14 +377,14 @@ BITMAPS LIB_SHAPE::GetMenuImage() const { switch( GetShape() ) { - case SHAPE_T::SEGMENT: return BITMAPS::add_line; - case SHAPE_T::ARC: return BITMAPS::add_arc; - case SHAPE_T::CIRCLE: return BITMAPS::add_circle; - case SHAPE_T::RECT: return BITMAPS::add_rectangle; - case SHAPE_T::POLYGON: return BITMAPS::add_graphical_segments; + case SHAPE_T::SEGMENT: return BITMAPS::add_line; + case SHAPE_T::ARC: return BITMAPS::add_arc; + case SHAPE_T::CIRCLE: return BITMAPS::add_circle; + case SHAPE_T::RECT: return BITMAPS::add_rectangle; + case SHAPE_T::POLY: return BITMAPS::add_graphical_segments; default: - wxFAIL_MSG( "LIB_SHAPE::GetMenuImage unimplemented for " + SHAPE_T_asString() ); + UNIMPLEMENTED_FOR( SHAPE_T_asString() ); return BITMAPS::question_mark; } } @@ -405,19 +402,21 @@ void LIB_SHAPE::BeginEdit( const wxPoint& aPosition ) break; case SHAPE_T::ARC: - SetStart( aPosition ); - SetEnd( aPosition ); + SetArcGeometry( aPosition, aPosition, aPosition ); SetEditState( 1 ); break; - case SHAPE_T::POLYGON: + case SHAPE_T::POLY: + m_poly.NewOutline(); + m_poly.Outline( 0 ).SetClosed( false ); + // Start and end of the first segment (co-located for now) m_poly.Outline( 0 ).Append( aPosition ); m_poly.Outline( 0 ).Append( aPosition, true ); break; default: - wxFAIL_MSG( "LIB_SHAPE::BeginEdit not implemented for " + SHAPE_T_asString() ); + UNIMPLEMENTED_FOR( SHAPE_T_asString() ); } } @@ -426,23 +425,24 @@ bool LIB_SHAPE::ContinueEdit( const wxPoint& aPosition ) { switch( GetShape() ) { + case SHAPE_T::ARC: case SHAPE_T::SEGMENT: case SHAPE_T::CIRCLE: case SHAPE_T::RECT: return false; - case SHAPE_T::POLYGON: + case SHAPE_T::POLY: { SHAPE_LINE_CHAIN& poly = m_poly.Outline( 0 ); // do not add zero-length segments if( poly.CPoint( poly.GetPointCount() - 2 ) != poly.CLastPoint() ) - poly.Append( aPosition ); + poly.Append( aPosition, true ); } return true; default: - wxFAIL_MSG( "LIB_SHAPE::ContinueEdit not implemented for " + SHAPE_T_asString() ); + UNIMPLEMENTED_FOR( SHAPE_T_asString() ); return false; } } @@ -460,11 +460,10 @@ void LIB_SHAPE::CalcEdit( const wxPoint& aPosition ) SetEnd( aPosition ); break; - case SHAPE_T::POLYGON: - m_poly.Outline( 0 ).SetPoint( m_poly.Outline( 0 ).GetPointCount() - 1, aPosition ); - break; - case SHAPE_T::ARC: + { + int radius = GetRadius(); + // Edit state 0: drawing: place start // Edit state 1: drawing: place end (center calculated for 90-degree subtended angle) // Edit state 2: point edit: move start (center calculated for invariant subtended angle) @@ -479,46 +478,98 @@ void LIB_SHAPE::CalcEdit( const wxPoint& aPosition ) return; case 1: - { - wxPoint start = GetStart(); - wxPoint end = aPosition; - wxPoint center = CalcArcCenter( start, end, 90.0 ); - wxPoint mid = (wxPoint) CalcArcMid( start, end, center, true ); - - SetArcGeometry( start, mid, aPosition ); - } + m_end = aPosition; + radius = KiROUND( sqrt( sq( GetLineLength( m_start, m_end ) ) / 2.0 ) ); + break; break; case 2: - { - wxPoint delta = aPosition - GetStart(); - - SetArcGeometry( aPosition, GetArcMid() + delta/2, GetEnd() ); - } - break; - case 3: { - wxPoint delta = aPosition - GetEnd(); + wxPoint v = m_start - m_end; + double chordBefore = sq( v.x ) + sq( v.y ); - SetArcGeometry( GetStart(), GetArcMid() + delta/2, aPosition ); + if( m_editState == 2 ) + m_start = aPosition; + else + m_end = aPosition; + + v = m_start - m_end; + double chordAfter = sq( v.x ) + sq( v.y ); + double ratio = chordAfter / chordBefore; + + if( ratio != 0 ) + { + radius = std::max( int( sqrt( sq( radius ) * ratio ) ) + 1, + int( sqrt( chordAfter ) / 2 ) + 1 ); + } } break; case 4: - MoveTo( aPosition ); + { + double chordA = GetLineLength( m_start, aPosition ); + double chordB = GetLineLength( m_end, aPosition ); + radius = int( ( chordA + chordB ) / 2.0 ) + 1; + } break; case 5: SetArcGeometry( GetStart(), aPosition, GetEnd() ); - break; - + return; } + // Calculate center based on start, end, and radius + // + // Let 'l' be the length of the chord and 'm' the middle point of the chord + double l = GetLineLength( m_start, m_end ); + wxPoint m = ( m_start + m_end ) / 2; + + // Calculate 'd', the vector from the chord midpoint to the center + wxPoint d; + d.x = KiROUND( sqrt( sq( radius ) - sq( l/2 ) ) * ( m_start.y - m_end.y ) / l ); + d.y = KiROUND( sqrt( sq( radius ) - sq( l/2 ) ) * ( m_end.x - m_start.x ) / l ); + + wxPoint c1 = m + d; + wxPoint c2 = m - d; + + // Solution gives us 2 centers; we need to pick one: + switch( m_editState ) + { + case 1: + { + // Keep center clockwise from chord while drawing + wxPoint chordVector = m_end - m_start; + double chordAngle = ArcTangente( chordVector.y, chordVector.x ); + NORMALIZE_ANGLE_POS( chordAngle ); + + wxPoint c1Test = c1; + RotatePoint( &c1Test, m_start, -chordAngle ); + + m_arcCenter = c1Test.x > 0 ? c2 : c1; + } + break; + + case 2: + case 3: + // Pick the one closer to the old center + m_arcCenter = GetLineLength( c1, m_arcCenter ) < GetLineLength( c2, m_arcCenter ) ? c1 : c2; + break; + + case 4: + // Pick the one closer to the mouse position + m_arcCenter = GetLineLength( c1, aPosition ) < GetLineLength( c2, aPosition ) ? c1 : c2; + break; + } + } + break; + + case SHAPE_T::POLY: + m_poly.Outline( 0 ).SetPoint( m_poly.Outline( 0 ).GetPointCount() - 1, aPosition ); break; default: - wxFAIL_MSG( "LIB_SHAPE::CalcEdit not implemented for " + SHAPE_T_asString() ); + UNIMPLEMENTED_FOR( SHAPE_T_asString() ); } } @@ -533,15 +584,21 @@ void LIB_SHAPE::EndEdit() case SHAPE_T::RECT: break; - case SHAPE_T::POLYGON: + case SHAPE_T::POLY: { SHAPE_LINE_CHAIN& poly = m_poly.Outline( 0 ); - // do not include last point twice if( poly.GetPointCount() > 2 ) { if( poly.CPoint( poly.GetPointCount() - 2 ) == poly.CLastPoint() ) + { + poly.SetClosed( true ); poly.Remove( poly.GetPointCount() - 1 ); + } + else + { + poly.SetClosed( false ); + } } } break; @@ -554,7 +611,7 @@ void LIB_SHAPE::EndEdit() void LIB_SHAPE::AddPoint( const wxPoint& aPosition ) { - if( GetShape() == SHAPE_T::POLYGON ) + if( GetShape() == SHAPE_T::POLY ) { if( m_poly.IsEmpty() ) m_poly.NewOutline(); @@ -568,3 +625,65 @@ void LIB_SHAPE::AddPoint( const wxPoint& aPosition ) } +double LIB_SHAPE::GetArcAngleStart() const +{ + int startAngle, endAngle; + CalcArcAngles( startAngle, endAngle ); + + if( startAngle > endAngle ) + TRANSFORM().MapAngles( &startAngle, &endAngle ); + + return startAngle; +} + + +double LIB_SHAPE::GetArcAngleEnd() const +{ + int startAngle, endAngle; + CalcArcAngles( startAngle, endAngle ); + + if( startAngle > endAngle ) + TRANSFORM().MapAngles( &startAngle, &endAngle ); + + return endAngle; +} + + +void LIB_SHAPE::CalcArcAngles( int& aStartAngle, int& aEndAngle ) const +{ + wxPoint centerStartVector = GetStart() - GetCenter(); + wxPoint centerEndVector = GetEnd() - GetCenter(); + + // Angles in Eeschema are still integers + aStartAngle = KiROUND( ArcTangente( centerStartVector.y, centerStartVector.x ) ); + aEndAngle = KiROUND( ArcTangente( centerEndVector.y, centerEndVector.x ) ); + + NORMALIZE_ANGLE_POS( aStartAngle ); + NORMALIZE_ANGLE_POS( aEndAngle ); // angles = 0 .. 3600 + + // Restrict angle to less than 180 to avoid PBS display mirror Trace because it is + // assumed that the arc is less than 180 deg to find orientation after rotate or mirror. + if( ( aEndAngle - aStartAngle ) > 1800 ) + aEndAngle -= 3600; + else if( ( aEndAngle - aStartAngle ) <= -1800 ) + aEndAngle += 3600; + + while( ( aEndAngle - aStartAngle ) >= 1800 ) + { + aEndAngle--; + aStartAngle++; + } + + while( ( aStartAngle - aEndAngle ) >= 1800 ) + { + aEndAngle++; + aStartAngle--; + } + + NORMALIZE_ANGLE_POS( aStartAngle ); + + if( !IsMoving() ) + NORMALIZE_ANGLE_POS( aEndAngle ); +} + + diff --git a/eeschema/lib_shape.h b/eeschema/lib_shape.h index 197e769857..9e6f186e9a 100644 --- a/eeschema/lib_shape.h +++ b/eeschema/lib_shape.h @@ -54,6 +54,19 @@ public: int GetPenWidth() const override; + int GetEffectivePenWidth( const RENDER_SETTINGS* aSettings ) const override + { + // For historical reasons, a stored value of 0 means "default width" and negative + // numbers meant "don't stroke". + + if( GetPenWidth() < 0 && GetFillType() != FILL_T::NO_FILL ) + return 0; + else if( GetPenWidth() == 0 ) + return aSettings->GetDefaultPenWidth(); + else + return std::max( GetPenWidth(), aSettings->GetMinPenWidth() ); + } + const EDA_RECT GetBoundingBox() const override; void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector& aList ) override; @@ -72,6 +85,12 @@ public: wxPoint GetPosition() const override { return getPosition(); } void SetPosition( const wxPoint& aPosition ) override { setPosition( aPosition ); } + wxPoint GetCenter() const { return getCenter(); } + + double GetArcAngleStart() const override; + double GetArcAngleEnd() const override; + void CalcArcAngles( int& aStartAngle, int& aEndAngle ) const; + void MirrorHorizontal( const wxPoint& aCenter ) override; void MirrorVertical( const wxPoint& aCenter ) override; void Rotate( const wxPoint& aCenter, bool aRotateCCW = true ) override; diff --git a/eeschema/lib_symbol.cpp b/eeschema/lib_symbol.cpp index b6ad4c6d6a..68433af3e3 100644 --- a/eeschema/lib_symbol.cpp +++ b/eeschema/lib_symbol.cpp @@ -32,9 +32,8 @@ #include #include #include -#include #include - +#include // the separator char between the subpart id and the reference // 0 (no separator) or '.' or some other character @@ -475,7 +474,7 @@ wxString LIB_SYMBOL::SubReference( int aUnit, bool aAddSeparator ) void LIB_SYMBOL::Print( const RENDER_SETTINGS* aSettings, const wxPoint& aOffset, - int aMulti, int aConvert, const LIB_SYMBOL_OPTIONS& aOpts ) + int aUnit, int aConvert, const LIB_SYMBOL_OPTIONS& aOpts ) { /* draw background for filled items using background option * Solid lines will be drawn after the background @@ -483,39 +482,37 @@ void LIB_SYMBOL::Print( const RENDER_SETTINGS* aSettings, const wxPoint& aOffset */ if( !GetGRForceBlackPenState() ) { - for( LIB_ITEM& drawItem : m_drawings ) + for( LIB_ITEM& item : m_drawings ) { - if( drawItem.m_fill != FILL_TYPE::FILLED_WITH_BG_BODYCOLOR ) - continue; + if( item.Type() == LIB_SHAPE_T ) + { + LIB_SHAPE& shape = static_cast( item ); - // Do not draw items not attached to the current part - if( aMulti && drawItem.m_unit && ( drawItem.m_unit != aMulti ) ) - continue; + // Do not draw items not attached to the current part + if( aUnit && shape.m_unit && ( shape.m_unit != aUnit ) ) + continue; - if( aConvert && drawItem.m_convert && ( drawItem.m_convert != aConvert ) ) - continue; + if( aConvert && shape.m_convert && ( shape.m_convert != aConvert ) ) + continue; - if( drawItem.Type() == LIB_FIELD_T ) - continue; - - // Now, draw only the background for items with - // m_fill == FILLED_WITH_BG_BODYCOLOR: - drawItem.Print( aSettings, aOffset, (void*) false, aOpts.transform ); + if( shape.GetFillType() == FILL_T::FILLED_WITH_BG_BODYCOLOR ) + shape.Print( aSettings, aOffset, (void*) false, aOpts.transform ); + } } } - for( LIB_ITEM& drawItem : m_drawings ) + for( LIB_ITEM& item : m_drawings ) { // Do not draw items not attached to the current part - if( aMulti && drawItem.m_unit && ( drawItem.m_unit != aMulti ) ) + if( aUnit && item.m_unit && ( item.m_unit != aUnit ) ) continue; - if( aConvert && drawItem.m_convert && ( drawItem.m_convert != aConvert ) ) + if( aConvert && item.m_convert && ( item.m_convert != aConvert ) ) continue; - if( drawItem.Type() == LIB_FIELD_T ) + if( item.Type() == LIB_FIELD_T ) { - LIB_FIELD& field = static_cast( drawItem ); + LIB_FIELD& field = static_cast( item ); if( field.IsVisible() && !aOpts.draw_visible_fields ) continue; @@ -524,18 +521,24 @@ void LIB_SYMBOL::Print( const RENDER_SETTINGS* aSettings, const wxPoint& aOffset continue; } - if( drawItem.Type() == LIB_PIN_T ) + if( item.Type() == LIB_PIN_T ) { - drawItem.Print( aSettings, aOffset, (void*) &aOpts, aOpts.transform ); + item.Print( aSettings, aOffset, (void*) &aOpts, aOpts.transform ); } - else if( drawItem.Type() == LIB_FIELD_T ) + else if( item.Type() == LIB_FIELD_T ) { - drawItem.Print( aSettings, aOffset, (void*) nullptr, aOpts.transform ); + item.Print( aSettings, aOffset, (void*) NULL, aOpts.transform ); + } + else if( item.Type() == LIB_SHAPE_T ) + { + LIB_SHAPE& shape = static_cast( item ); + bool forceNoFill = shape.GetFillType() == FILL_T::FILLED_WITH_BG_BODYCOLOR; + + shape.Print( aSettings, aOffset, (void*) forceNoFill, aOpts.transform ); } else { - bool forceNoFill = drawItem.m_fill == FILL_TYPE::FILLED_WITH_BG_BODYCOLOR; - drawItem.Print( aSettings, aOffset, (void*) forceNoFill, aOpts.transform ); + item.Print( aSettings, aOffset, (void*) false, aOpts.transform ); } } } @@ -552,6 +555,26 @@ void LIB_SYMBOL::Plot( PLOTTER* aPlotter, int aUnit, int aConvert, const wxPoint // draw background for filled items using background option // Solid lines will be drawn after the background for( const LIB_ITEM& item : m_drawings ) + { + if( item.Type() == LIB_SHAPE_T ) + { + const LIB_SHAPE& shape = static_cast( item ); + + // Do not draw items not attached to the current part + if( aUnit && shape.m_unit && ( shape.m_unit != aUnit ) ) + continue; + + if( aConvert && shape.m_convert && ( shape.m_convert != aConvert ) ) + continue; + + if( shape.GetFillType() == FILL_T::FILLED_WITH_BG_BODYCOLOR ) + shape.Plot( aPlotter, aOffset, fill, aTransform ); + } + } + + // Not filled items and filled shapes are now plotted + // Items that have BG fills only get re-stroked to ensure the edges are in the foreground + for( const LIB_ITEM& item : m_drawings ) { // Lib Fields are not plotted here, because this plot function // is used to plot schematic items, which have they own fields @@ -564,25 +587,15 @@ void LIB_SYMBOL::Plot( PLOTTER* aPlotter, int aUnit, int aConvert, const wxPoint if( aConvert && item.m_convert && ( item.m_convert != aConvert ) ) continue; - if( item.m_fill == FILL_TYPE::FILLED_WITH_BG_BODYCOLOR ) - item.Plot( aPlotter, aOffset, fill, aTransform ); - } + bool forceNoFill = false; - // Not filled items and filled shapes are now plotted - // Items that have BG fills only get re-stroked to ensure the edges are in the foreground - for( const LIB_ITEM& item : m_drawings ) - { - if( item.Type() == LIB_FIELD_T ) - continue; + if( item.Type() == LIB_SHAPE_T ) + { + const LIB_SHAPE& shape = static_cast( item ); + forceNoFill = shape.GetFillType() == FILL_T::FILLED_WITH_BG_BODYCOLOR; + } - if( aUnit && item.m_unit && ( item.m_unit != aUnit ) ) - continue; - - if( aConvert && item.m_convert && ( item.m_convert != aConvert ) ) - continue; - - item.Plot( aPlotter, aOffset, - fill && ( item.m_fill != FILL_TYPE::FILLED_WITH_BG_BODYCOLOR ), aTransform ); + item.Plot( aPlotter, aOffset, fill && !forceNoFill, aTransform ); } } diff --git a/eeschema/lib_symbol.h b/eeschema/lib_symbol.h index acccf72421..e409039405 100644 --- a/eeschema/lib_symbol.h +++ b/eeschema/lib_symbol.h @@ -44,7 +44,7 @@ class TEST_LIB_SYMBOL_FIXTURE; typedef std::shared_ptr LIB_SYMBOL_SPTR; ///< shared pointer to LIB_SYMBOL typedef std::weak_ptr LIB_SYMBOL_REF; ///< weak pointer to LIB_SYMBOL -typedef MULTIVECTOR LIB_ITEMS_CONTAINER; +typedef MULTIVECTOR LIB_ITEMS_CONTAINER; typedef LIB_ITEMS_CONTAINER::ITEM_PTR_VECTOR LIB_ITEMS; diff --git a/eeschema/lib_text.h b/eeschema/lib_text.h index 75ce03889a..5082120ec2 100644 --- a/eeschema/lib_text.h +++ b/eeschema/lib_text.h @@ -99,9 +99,6 @@ public: void Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill, const TRANSFORM& aTransform ) const override; - int GetWidth() const override { return GetTextThickness(); } - void SetWidth( int aWidth ) override { SetTextThickness( aWidth ); } - wxString GetSelectMenuText( EDA_UNITS aUnits ) const override; void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector& aList ) override; diff --git a/eeschema/sch_junction.cpp b/eeschema/sch_junction.cpp index 2a065ddb2a..42222854f4 100644 --- a/eeschema/sch_junction.cpp +++ b/eeschema/sch_junction.cpp @@ -235,7 +235,7 @@ void SCH_JUNCTION::Plot( PLOTTER* aPlotter ) const aPlotter->SetColor( color ); - aPlotter->Circle( m_pos, GetEffectiveDiameter(), FILL_TYPE::FILLED_SHAPE ); + aPlotter->Circle( m_pos, GetEffectiveDiameter(), FILL_T::FILLED_SHAPE ); } diff --git a/eeschema/sch_painter.cpp b/eeschema/sch_painter.cpp index a5b188ae84..9bcc6269f5 100644 --- a/eeschema/sch_painter.cpp +++ b/eeschema/sch_painter.cpp @@ -34,14 +34,10 @@ #include #include #include -#include -#include -#include +#include #include #include #include -#include -#include #include #include #include @@ -142,10 +138,10 @@ static LIB_SYMBOL* dummy() { symbol = new LIB_SYMBOL( wxEmptyString ); - LIB_RECTANGLE* square = new LIB_RECTANGLE( symbol ); + LIB_SHAPE* square = new LIB_SHAPE( symbol, SHAPE_T::RECT ); square->MoveTo( wxPoint( Mils2iu( -200 ), Mils2iu( 200 ) ) ); - square->SetEndPosition( wxPoint( Mils2iu( 200 ), Mils2iu( -200 ) ) ); + square->SetEnd( wxPoint( Mils2iu( 200 ), Mils2iu( -200 ) ) ); LIB_TEXT* text = new LIB_TEXT( symbol ); @@ -215,14 +211,10 @@ bool SCH_PAINTER::Draw( const VIEW_ITEM *aItem, int aLayer ) switch( item->Type() ) { HANDLE_ITEM( LIB_SYMBOL_T, LIB_SYMBOL ); - HANDLE_ITEM( LIB_RECTANGLE_T, LIB_RECTANGLE ); - HANDLE_ITEM( LIB_POLYLINE_T, LIB_POLYLINE ); - HANDLE_ITEM( LIB_CIRCLE_T, LIB_CIRCLE ); + HANDLE_ITEM( LIB_SHAPE_T, LIB_SHAPE ); HANDLE_ITEM( LIB_PIN_T, LIB_PIN ); - HANDLE_ITEM( LIB_ARC_T, LIB_ARC ); HANDLE_ITEM( LIB_FIELD_T, LIB_FIELD ); HANDLE_ITEM( LIB_TEXT_T, LIB_TEXT ); - HANDLE_ITEM( LIB_BEZIER_T, LIB_BEZIER ); HANDLE_ITEM( SCH_SYMBOL_T, SCH_SYMBOL ); HANDLE_ITEM( SCH_JUNCTION_T, SCH_JUNCTION ); HANDLE_ITEM( SCH_LINE_T, SCH_LINE ); @@ -488,6 +480,8 @@ void SCH_PAINTER::draw( const LIB_SYMBOL *aSymbol, int aLayer, bool aDrawFields, bool SCH_PAINTER::setDeviceColors( const LIB_ITEM* aItem, int aLayer ) { + const EDA_SHAPE* shape = dynamic_cast( aItem ); + switch( aLayer ) { case LAYER_SELECTION_SHADOWS: @@ -504,11 +498,11 @@ bool SCH_PAINTER::setDeviceColors( const LIB_ITEM* aItem, int aLayer ) return false; case LAYER_DEVICE_BACKGROUND: - if( aItem->GetFillMode() == FILL_TYPE::FILLED_WITH_BG_BODYCOLOR ) + if( shape && shape->GetFillType() == FILL_T::FILLED_WITH_BG_BODYCOLOR ) { COLOR4D fillColor = getRenderColor( aItem, LAYER_DEVICE_BACKGROUND, false ); - m_gal->SetIsFill( aItem->GetFillMode() == FILL_TYPE::FILLED_WITH_BG_BODYCOLOR ); + m_gal->SetIsFill( shape->GetFillType() == FILL_T::FILLED_WITH_BG_BODYCOLOR ); m_gal->SetFillColor( fillColor ); m_gal->SetIsStroke( false ); return true; @@ -517,10 +511,10 @@ bool SCH_PAINTER::setDeviceColors( const LIB_ITEM* aItem, int aLayer ) return false; case LAYER_DEVICE: - m_gal->SetIsFill( aItem->GetFillMode() == FILL_TYPE::FILLED_SHAPE ); + m_gal->SetIsFill( shape && shape->GetFillType() == FILL_T::FILLED_SHAPE ); m_gal->SetFillColor( getRenderColor( aItem, LAYER_DEVICE, false ) ); - if( aItem->GetPenWidth() >= 0 || aItem->GetFillMode() == FILL_TYPE::NO_FILL ) + if( aItem->GetPenWidth() >= 0 || !shape || !shape->IsFilled() ) { m_gal->SetIsStroke( true ); m_gal->SetLineWidth( getLineWidth( aItem, false ) ); @@ -546,66 +540,66 @@ void SCH_PAINTER::fillIfSelection( int aLayer ) } -void SCH_PAINTER::draw( const LIB_RECTANGLE *aRect, int aLayer ) +void SCH_PAINTER::draw( const LIB_SHAPE *aShape, int aLayer ) { - if( !isUnitAndConversionShown( aRect ) ) + if( !isUnitAndConversionShown( aShape ) ) return; - if( setDeviceColors( aRect, aLayer ) ) + if( setDeviceColors( aShape, aLayer ) ) { fillIfSelection( aLayer ); - m_gal->DrawRectangle( mapCoords( aRect->GetPosition() ), mapCoords( aRect->GetEnd() ) ); - } -} + switch( aShape->GetShape() ) + { + case SHAPE_T::ARC: + { + int startAngle; + int endAngle; + aShape->CalcArcAngles( startAngle, endAngle ); -void SCH_PAINTER::draw( const LIB_CIRCLE *aCircle, int aLayer ) -{ - if( !isUnitAndConversionShown( aCircle ) ) - return; + TRANSFORM().MapAngles( &startAngle, &endAngle ); - if( setDeviceColors( aCircle, aLayer ) ) - { - fillIfSelection( aLayer ); - m_gal->DrawCircle( mapCoords( aCircle->GetPosition() ), aCircle->GetRadius() ); - } -} + m_gal->DrawArc( mapCoords( aShape->GetCenter() ), aShape->GetRadius(), + DECIDEG2RAD( startAngle ), DECIDEG2RAD( endAngle ) ); + } + break; + case SHAPE_T::CIRCLE: + m_gal->DrawCircle( mapCoords( aShape->GetPosition() ), aShape->GetRadius() ); + break; -void SCH_PAINTER::draw( const LIB_ARC *aArc, int aLayer ) -{ - if( !isUnitAndConversionShown( aArc ) ) - return; + case SHAPE_T::RECT: + m_gal->DrawRectangle( mapCoords( aShape->GetPosition() ), + mapCoords( aShape->GetEnd() ) ); + break; - if( setDeviceColors( aArc, aLayer ) ) - { - int startAngle; - int endAngle; - aArc->CalcAngles( startAngle, endAngle ); + case SHAPE_T::POLY: + { + const SHAPE_LINE_CHAIN poly = aShape->GetPolyShape().Outline( 0 ); + std::deque mappedPts; - TRANSFORM().MapAngles( &startAngle, &endAngle ); + for( const VECTOR2I& pt : poly.CPoints() ) + mappedPts.push_back( mapCoords( (wxPoint) pt ) ); - m_gal->DrawArc( mapCoords( aArc->GetCenter() ), aArc->GetRadius(), - DECIDEG2RAD( startAngle ), DECIDEG2RAD( endAngle ) ); - } -} + fillIfSelection( aLayer ); + m_gal->DrawPolygon( mappedPts ); + } + break; + case SHAPE_T::BEZIER: + { + std::deque mappedPts; -void SCH_PAINTER::draw( const LIB_POLYLINE *aLine, int aLayer ) -{ - if( !isUnitAndConversionShown( aLine ) ) - return; + for( const VECTOR2I &p : aShape->GetPolyShape().Outline( 0 ).CPoints() ) + mappedPts.push_back( mapCoords( (wxPoint) p ) ); - if( setDeviceColors( aLine, aLayer ) ) - { - const std::vector& pts = aLine->GetPolyPoints(); - std::deque vtx; + m_gal->DrawPolygon( mappedPts ); + } + break; - for( auto p : pts ) - vtx.push_back( mapCoords( p ) ); - - fillIfSelection( aLayer ); - m_gal->DrawPolygon( vtx ); + default: + wxFAIL_MSG( "SCH_PAINTER::draw not implemented for " + aShape->SHAPE_T_asString() ); + } } } @@ -1195,26 +1189,6 @@ void SCH_PAINTER::draw( LIB_PIN *aPin, int aLayer ) } -void SCH_PAINTER::draw( const LIB_BEZIER *aCurve, int aLayer ) -{ - if( !isUnitAndConversionShown( aCurve ) ) - return; - - if( setDeviceColors( aCurve, aLayer ) ) - { - BEZIER_POLY poly ( aCurve->GetPoints() ); - std::vector pts; - std::deque pts_xformed; - poly.GetPoly( pts ); - - for( const wxPoint &p : pts ) - pts_xformed.push_back( mapCoords( p ) ); - - m_gal->DrawPolygon( pts_xformed ); - } -} - - // Draw the target (an open square) for a wire or label which has no connection or is // being moved. void SCH_PAINTER::drawDanglingSymbol( const wxPoint& aPos, int aWidth, bool aDrawingShadows ) diff --git a/eeschema/sch_painter.h b/eeschema/sch_painter.h index 83d61a76f6..573cb51f46 100644 --- a/eeschema/sch_painter.h +++ b/eeschema/sch_painter.h @@ -32,16 +32,12 @@ #include -class LIB_RECTANGLE; class LIB_PIN; -class LIB_CIRCLE; +class LIB_SHAPE; class LIB_ITEM; class LIB_SYMBOL; -class LIB_POLYLINE; -class LIB_ARC; class LIB_FIELD; class LIB_TEXT; -class LIB_BEZIER; class SCH_SYMBOL; class SCH_FIELD; class SCH_JUNCTION; @@ -153,16 +149,12 @@ public: } private: - void draw( const LIB_RECTANGLE* aRect, int aLayer ); void draw( LIB_PIN* aPin, int aLayer ); - void draw( const LIB_CIRCLE* aCircle, int aLayer ); + void draw( const LIB_SHAPE* aCircle, int aLayer ); void draw( const LIB_SYMBOL* aSymbol, int, bool aDrawFields = true, int aUnit = 0, int aConvert = 0 ); - void draw( const LIB_ARC* aArc, int aLayer ); - void draw( const LIB_POLYLINE* aLine, int aLayer ); void draw( const LIB_FIELD* aField, int aLayer ); void draw( const LIB_TEXT* aText, int aLayer ); - void draw( const LIB_BEZIER* aCurve, int aLayer ); void draw( SCH_SYMBOL* aSymbol, int aLayer ); void draw( const SCH_JUNCTION* aJct, int aLayer ); void draw( const SCH_FIELD* aField, int aLayer ); diff --git a/eeschema/sch_plugins/altium/sch_altium_plugin.cpp b/eeschema/sch_plugins/altium/sch_altium_plugin.cpp index c14328d707..bd27b83389 100644 --- a/eeschema/sch_plugins/altium/sch_altium_plugin.cpp +++ b/eeschema/sch_plugins/altium/sch_altium_plugin.cpp @@ -31,14 +31,10 @@ #include -#include -#include -#include +#include #include #include #include -#include -#include #include #include @@ -1050,7 +1046,7 @@ void SCH_ALTIUM_PLUGIN::ParseBezier( const std::map& aProper if( i + 2 == elem.points.size() ) { // special case: single line - LIB_POLYLINE* line = new LIB_POLYLINE( libSymbolIt->second ); + LIB_SHAPE* line = new LIB_SHAPE( libSymbolIt->second, SHAPE_T::POLY ); libSymbolIt->second->AddDrawItem( line ); line->SetUnit( elem.ownerpartid ); @@ -1069,7 +1065,7 @@ void SCH_ALTIUM_PLUGIN::ParseBezier( const std::map& aProper // I haven't a clue what this is all about, but the sample document we have in // https://gitlab.com/kicad/code/kicad/-/issues/8974 responds best by treating it // as another single line special case. - LIB_POLYLINE* line = new LIB_POLYLINE( libSymbolIt->second ); + LIB_SHAPE* line = new LIB_SHAPE( libSymbolIt->second, SHAPE_T::POLY ); libSymbolIt->second->AddDrawItem( line ); line->SetUnit( elem.ownerpartid ); @@ -1084,8 +1080,8 @@ void SCH_ALTIUM_PLUGIN::ParseBezier( const std::map& aProper } else { - // Bezier must have exactly 4 control points - LIB_BEZIER* bezier = new LIB_BEZIER( libSymbolIt->second ); + // Bezier always has exactly 4 control points + LIB_SHAPE* bezier = new LIB_SHAPE( libSymbolIt->second, SHAPE_T::BEZIER ); libSymbolIt->second->AddDrawItem( bezier ); bezier->SetUnit( elem.ownerpartid ); @@ -1148,8 +1144,8 @@ void SCH_ALTIUM_PLUGIN::ParsePolyline( const std::map& aProp if( !IsComponentPartVisible( elem.ownerindex, elem.ownerpartdisplaymode ) ) return; - SCH_SYMBOL* symbol = m_symbols.at( libSymbolIt->first ); - LIB_POLYLINE* line = new LIB_POLYLINE( libSymbolIt->second ); + SCH_SYMBOL* symbol = m_symbols.at( libSymbolIt->first ); + LIB_SHAPE* line = new LIB_SHAPE( libSymbolIt->second, SHAPE_T::POLY ); libSymbolIt->second->AddDrawItem( line ); line->SetUnit( elem.ownerpartid ); @@ -1207,8 +1203,8 @@ void SCH_ALTIUM_PLUGIN::ParsePolygon( const std::map& aPrope if( !IsComponentPartVisible( elem.ownerindex, elem.ownerpartdisplaymode ) ) return; - SCH_SYMBOL* symbol = m_symbols.at( libSymbolIt->first ); - LIB_POLYLINE* line = new LIB_POLYLINE( libSymbolIt->second ); + SCH_SYMBOL* symbol = m_symbols.at( libSymbolIt->first ); + LIB_SHAPE* line = new LIB_SHAPE( libSymbolIt->second, SHAPE_T::POLY ); libSymbolIt->second->AddDrawItem( line ); line->SetUnit( elem.ownerpartid ); @@ -1221,11 +1217,11 @@ void SCH_ALTIUM_PLUGIN::ParsePolygon( const std::map& aPrope line->SetWidth( elem.lineWidth ); if( !elem.isSolid ) - line->SetFillMode( FILL_TYPE::NO_FILL ); + line->SetFillMode( FILL_T::NO_FILL ); else if( elem.color == elem.areacolor ) - line->SetFillMode( FILL_TYPE::FILLED_SHAPE ); + line->SetFillMode( FILL_T::FILLED_SHAPE ); else - line->SetFillMode( FILL_TYPE::FILLED_WITH_BG_BODYCOLOR ); + line->SetFillMode( FILL_T::FILLED_WITH_BG_BODYCOLOR ); } } @@ -1288,10 +1284,9 @@ void SCH_ALTIUM_PLUGIN::ParseRoundRectangle( const std::map& if( !IsComponentPartVisible( elem.ownerindex, elem.ownerpartdisplaymode ) ) return; - SCH_SYMBOL* symbol = m_symbols.at( libSymbolIt->first ); - + SCH_SYMBOL* symbol = m_symbols.at( libSymbolIt->first ); // TODO: misses rounded edges - LIB_RECTANGLE* rect = new LIB_RECTANGLE( libSymbolIt->second ); + LIB_SHAPE* rect = new LIB_SHAPE( libSymbolIt->second, SHAPE_T::RECT ); libSymbolIt->second->AddDrawItem( rect ); rect->SetUnit( elem.ownerpartid ); @@ -1301,11 +1296,11 @@ void SCH_ALTIUM_PLUGIN::ParseRoundRectangle( const std::map& rect->SetWidth( elem.lineWidth ); if( !elem.isSolid ) - rect->SetFillMode( FILL_TYPE::NO_FILL ); + rect->SetFillMode( FILL_T::NO_FILL ); else if( elem.color == elem.areacolor ) - rect->SetFillMode( FILL_TYPE::FILLED_SHAPE ); + rect->SetFillMode( FILL_T::FILLED_SHAPE ); else - rect->SetFillMode( FILL_TYPE::FILLED_WITH_BG_BODYCOLOR ); + rect->SetFillMode( FILL_T::FILLED_WITH_BG_BODYCOLOR ); } } @@ -1339,18 +1334,18 @@ void SCH_ALTIUM_PLUGIN::ParseArc( const std::map& aPropertie if( elem.startAngle == 0 && ( elem.endAngle == 0 || elem.endAngle == 360 ) ) { - LIB_CIRCLE* circle = new LIB_CIRCLE( libSymbolIt->second ); + LIB_SHAPE* circle = new LIB_SHAPE( libSymbolIt->second, SHAPE_T::CIRCLE ); libSymbolIt->second->AddDrawItem( circle ); circle->SetUnit( elem.ownerpartid ); circle->SetPosition( GetRelativePosition( elem.center + m_sheetOffset, symbol ) ); - circle->SetRadius( elem.radius ); + circle->SetEnd( circle->GetPosition() + wxPoint( elem.radius, 0 ) ); circle->SetWidth( elem.lineWidth ); } else { - LIB_ARC* arc = new LIB_ARC( libSymbolIt->second ); + LIB_SHAPE* arc = new LIB_SHAPE( libSymbolIt->second, SHAPE_T::ARC ); libSymbolIt->second->AddDrawItem( arc ); arc->SetUnit( elem.ownerpartid ); @@ -1403,8 +1398,8 @@ void SCH_ALTIUM_PLUGIN::ParseLine( const std::map& aProperti if( !IsComponentPartVisible( elem.ownerindex, elem.ownerpartdisplaymode ) ) return; - SCH_SYMBOL* symbol = m_symbols.at( libSymbolIt->first ); - LIB_POLYLINE* line = new LIB_POLYLINE( libSymbolIt->second ); + SCH_SYMBOL* symbol = m_symbols.at( libSymbolIt->first ); + LIB_SHAPE* line = new LIB_SHAPE( libSymbolIt->second, SHAPE_T::POLY ); libSymbolIt->second->AddDrawItem( line ); line->SetUnit( elem.ownerpartid ); @@ -1474,8 +1469,8 @@ void SCH_ALTIUM_PLUGIN::ParseRectangle( const std::map& aPro if( !IsComponentPartVisible( elem.ownerindex, elem.ownerpartdisplaymode ) ) return; - SCH_SYMBOL* symbol = m_symbols.at( libSymbolIt->first ); - LIB_RECTANGLE* rect = new LIB_RECTANGLE( libSymbolIt->second ); + SCH_SYMBOL* symbol = m_symbols.at( libSymbolIt->first ); + LIB_SHAPE* rect = new LIB_SHAPE( libSymbolIt->second, SHAPE_T::RECT ); libSymbolIt->second->AddDrawItem( rect ); rect->SetUnit( elem.ownerpartid ); @@ -1485,11 +1480,11 @@ void SCH_ALTIUM_PLUGIN::ParseRectangle( const std::map& aPro rect->SetWidth( elem.lineWidth ); if( !elem.isSolid ) - rect->SetFillMode( FILL_TYPE::NO_FILL ); + rect->SetFillMode( FILL_T::NO_FILL ); else if( elem.color == elem.areacolor ) - rect->SetFillMode( FILL_TYPE::FILLED_SHAPE ); + rect->SetFillMode( FILL_T::FILLED_SHAPE ); else - rect->SetFillMode( FILL_TYPE::FILLED_WITH_BG_BODYCOLOR ); + rect->SetFillMode( FILL_T::FILLED_WITH_BG_BODYCOLOR ); } } @@ -1599,7 +1594,7 @@ wxPoint HelperGeneratePowerPortGraphics( LIB_SYMBOL* aKsymbol, ASCH_POWER_PORT_S { if( aStyle == ASCH_POWER_PORT_STYLE::CIRCLE || aStyle == ASCH_POWER_PORT_STYLE::ARROW ) { - LIB_POLYLINE* line1 = new LIB_POLYLINE( aKsymbol ); + LIB_SHAPE* line1 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY ); aKsymbol->AddDrawItem( line1 ); line1->SetWidth( Mils2iu( 10 ) ); line1->AddPoint( { 0, 0 } ); @@ -1607,15 +1602,15 @@ wxPoint HelperGeneratePowerPortGraphics( LIB_SYMBOL* aKsymbol, ASCH_POWER_PORT_S if( aStyle == ASCH_POWER_PORT_STYLE::CIRCLE ) { - LIB_CIRCLE* circle = new LIB_CIRCLE( aKsymbol ); + LIB_SHAPE* circle = new LIB_SHAPE( aKsymbol, SHAPE_T::CIRCLE ); aKsymbol->AddDrawItem( circle ); circle->SetWidth( Mils2iu( 5 ) ); - circle->SetRadius( Mils2iu( 25 ) ); circle->SetPosition( { Mils2iu( 0 ), Mils2iu( -75 ) } ); + circle->SetEnd( circle->GetPosition() + wxPoint( Mils2iu( 25 ), 0 ) ); } else { - LIB_POLYLINE* line2 = new LIB_POLYLINE( aKsymbol ); + LIB_SHAPE* line2 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY ); aKsymbol->AddDrawItem( line2 ); line2->SetWidth( Mils2iu( 10 ) ); line2->AddPoint( { Mils2iu( -25 ), Mils2iu( -50 ) } ); @@ -1628,13 +1623,13 @@ wxPoint HelperGeneratePowerPortGraphics( LIB_SYMBOL* aKsymbol, ASCH_POWER_PORT_S } else if( aStyle == ASCH_POWER_PORT_STYLE::WAVE ) { - LIB_POLYLINE* line = new LIB_POLYLINE( aKsymbol ); + LIB_SHAPE* line = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY ); aKsymbol->AddDrawItem( line ); line->SetWidth( Mils2iu( 10 ) ); line->AddPoint( { 0, 0 } ); line->AddPoint( { 0, Mils2iu( -72 ) } ); - LIB_BEZIER* bezier = new LIB_BEZIER( aKsymbol ); + LIB_SHAPE* bezier = new LIB_SHAPE( aKsymbol, SHAPE_T::BEZIER ); aKsymbol->AddDrawItem( bezier ); bezier->SetWidth( Mils2iu( 5 ) ); bezier->AddPoint( { Mils2iu( 30 ), Mils2iu( -50 ) } ); @@ -1649,7 +1644,7 @@ wxPoint HelperGeneratePowerPortGraphics( LIB_SYMBOL* aKsymbol, ASCH_POWER_PORT_S || aStyle == ASCH_POWER_PORT_STYLE::EARTH || aStyle == ASCH_POWER_PORT_STYLE::GOST_ARROW ) { - LIB_POLYLINE* line1 = new LIB_POLYLINE( aKsymbol ); + LIB_SHAPE* line1 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY ); aKsymbol->AddDrawItem( line1 ); line1->SetWidth( Mils2iu( 10 ) ); line1->AddPoint( { 0, 0 } ); @@ -1657,25 +1652,25 @@ wxPoint HelperGeneratePowerPortGraphics( LIB_SYMBOL* aKsymbol, ASCH_POWER_PORT_S if( aStyle == ASCH_POWER_PORT_STYLE::POWER_GROUND ) { - LIB_POLYLINE* line2 = new LIB_POLYLINE( aKsymbol ); + LIB_SHAPE* line2 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY ); aKsymbol->AddDrawItem( line2 ); line2->SetWidth( Mils2iu( 10 ) ); line2->AddPoint( { Mils2iu( -100 ), Mils2iu( -100 ) } ); line2->AddPoint( { Mils2iu( 100 ), Mils2iu( -100 ) } ); - LIB_POLYLINE* line3 = new LIB_POLYLINE( aKsymbol ); + LIB_SHAPE* line3 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY ); aKsymbol->AddDrawItem( line3 ); line3->SetWidth( Mils2iu( 10 ) ); line3->AddPoint( { Mils2iu( -70 ), Mils2iu( -130 ) } ); line3->AddPoint( { Mils2iu( 70 ), Mils2iu( -130 ) } ); - LIB_POLYLINE* line4 = new LIB_POLYLINE( aKsymbol ); + LIB_SHAPE* line4 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY ); aKsymbol->AddDrawItem( line4 ); line4->SetWidth( Mils2iu( 10 ) ); line4->AddPoint( { Mils2iu( -40 ), Mils2iu( -160 ) } ); line4->AddPoint( { Mils2iu( 40 ), Mils2iu( -160 ) } ); - LIB_POLYLINE* line5 = new LIB_POLYLINE( aKsymbol ); + LIB_SHAPE* line5 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY ); aKsymbol->AddDrawItem( line5 ); line5->SetWidth( Mils2iu( 10 ) ); line5->AddPoint( { Mils2iu( -10 ), Mils2iu( -190 ) } ); @@ -1683,7 +1678,7 @@ wxPoint HelperGeneratePowerPortGraphics( LIB_SYMBOL* aKsymbol, ASCH_POWER_PORT_S } else if( aStyle == ASCH_POWER_PORT_STYLE::SIGNAL_GROUND ) { - LIB_POLYLINE* line2 = new LIB_POLYLINE( aKsymbol ); + LIB_SHAPE* line2 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY ); aKsymbol->AddDrawItem( line2 ); line2->SetWidth( Mils2iu( 10 ) ); line2->AddPoint( { Mils2iu( -100 ), Mils2iu( -100 ) } ); @@ -1693,7 +1688,7 @@ wxPoint HelperGeneratePowerPortGraphics( LIB_SYMBOL* aKsymbol, ASCH_POWER_PORT_S } else if( aStyle == ASCH_POWER_PORT_STYLE::EARTH ) { - LIB_POLYLINE* line2 = new LIB_POLYLINE( aKsymbol ); + LIB_SHAPE* line2 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY ); aKsymbol->AddDrawItem( line2 ); line2->SetWidth( Mils2iu( 10 ) ); line2->AddPoint( { Mils2iu( -150 ), Mils2iu( -200 ) } ); @@ -1701,7 +1696,7 @@ wxPoint HelperGeneratePowerPortGraphics( LIB_SYMBOL* aKsymbol, ASCH_POWER_PORT_S line2->AddPoint( { Mils2iu( 100 ), Mils2iu( -100 ) } ); line2->AddPoint( { Mils2iu( 50 ), Mils2iu( -200 ) } ); - LIB_POLYLINE* line3 = new LIB_POLYLINE( aKsymbol ); + LIB_SHAPE* line3 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY ); aKsymbol->AddDrawItem( line3 ); line3->SetWidth( Mils2iu( 10 ) ); line3->AddPoint( { Mils2iu( 0 ), Mils2iu( -100 ) } ); @@ -1709,7 +1704,7 @@ wxPoint HelperGeneratePowerPortGraphics( LIB_SYMBOL* aKsymbol, ASCH_POWER_PORT_S } else // ASCH_POWER_PORT_STYLE::GOST_ARROW { - LIB_POLYLINE* line2 = new LIB_POLYLINE( aKsymbol ); + LIB_SHAPE* line2 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY ); aKsymbol->AddDrawItem( line2 ); line2->SetWidth( Mils2iu( 10 ) ); line2->AddPoint( { Mils2iu( -25 ), Mils2iu( -50 ) } ); @@ -1724,25 +1719,25 @@ wxPoint HelperGeneratePowerPortGraphics( LIB_SYMBOL* aKsymbol, ASCH_POWER_PORT_S else if( aStyle == ASCH_POWER_PORT_STYLE::GOST_POWER_GROUND || aStyle == ASCH_POWER_PORT_STYLE::GOST_EARTH ) { - LIB_POLYLINE* line1 = new LIB_POLYLINE( aKsymbol ); + LIB_SHAPE* line1 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY ); aKsymbol->AddDrawItem( line1 ); line1->SetWidth( Mils2iu( 10 ) ); line1->AddPoint( { 0, 0 } ); line1->AddPoint( { 0, Mils2iu( -160 ) } ); - LIB_POLYLINE* line2 = new LIB_POLYLINE( aKsymbol ); + LIB_SHAPE* line2 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY ); aKsymbol->AddDrawItem( line2 ); line2->SetWidth( Mils2iu( 10 ) ); line2->AddPoint( { Mils2iu( -100 ), Mils2iu( -160 ) } ); line2->AddPoint( { Mils2iu( 100 ), Mils2iu( -160 ) } ); - LIB_POLYLINE* line3 = new LIB_POLYLINE( aKsymbol ); + LIB_SHAPE* line3 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY ); aKsymbol->AddDrawItem( line3 ); line3->SetWidth( Mils2iu( 10 ) ); line3->AddPoint( { Mils2iu( -60 ), Mils2iu( -200 ) } ); line3->AddPoint( { Mils2iu( 60 ), Mils2iu( -200 ) } ); - LIB_POLYLINE* line4 = new LIB_POLYLINE( aKsymbol ); + LIB_SHAPE* line4 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY ); aKsymbol->AddDrawItem( line4 ); line4->SetWidth( Mils2iu( 10 ) ); line4->AddPoint( { Mils2iu( -20 ), Mils2iu( -240 ) } ); @@ -1751,23 +1746,23 @@ wxPoint HelperGeneratePowerPortGraphics( LIB_SYMBOL* aKsymbol, ASCH_POWER_PORT_S if( aStyle == ASCH_POWER_PORT_STYLE::GOST_POWER_GROUND ) return { 0, Mils2iu( 300 ) }; - LIB_CIRCLE* circle = new LIB_CIRCLE( aKsymbol ); + LIB_SHAPE* circle = new LIB_SHAPE( aKsymbol, SHAPE_T::CIRCLE ); aKsymbol->AddDrawItem( circle ); circle->SetWidth( Mils2iu( 10 ) ); - circle->SetRadius( Mils2iu( 120 ) ); circle->SetPosition( { Mils2iu( 0 ), Mils2iu( -160 ) } ); + circle->SetEnd( circle->GetPosition() + wxPoint( Mils2iu( 120 ), 0 ) ); return { 0, Mils2iu( 350 ) }; } else if( aStyle == ASCH_POWER_PORT_STYLE::GOST_BAR ) { - LIB_POLYLINE* line1 = new LIB_POLYLINE( aKsymbol ); + LIB_SHAPE* line1 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY ); aKsymbol->AddDrawItem( line1 ); line1->SetWidth( Mils2iu( 10 ) ); line1->AddPoint( { 0, 0 } ); line1->AddPoint( { 0, Mils2iu( -200 ) } ); - LIB_POLYLINE* line2 = new LIB_POLYLINE( aKsymbol ); + LIB_SHAPE* line2 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY ); aKsymbol->AddDrawItem( line2 ); line2->SetWidth( Mils2iu( 10 ) ); line2->AddPoint( { Mils2iu( -100 ), Mils2iu( -200 ) } ); @@ -1783,13 +1778,13 @@ wxPoint HelperGeneratePowerPortGraphics( LIB_SYMBOL* aKsymbol, ASCH_POWER_PORT_S RPT_SEVERITY_WARNING ); } - LIB_POLYLINE* line1 = new LIB_POLYLINE( aKsymbol ); + LIB_SHAPE* line1 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY ); aKsymbol->AddDrawItem( line1 ); line1->SetWidth( Mils2iu( 10 ) ); line1->AddPoint( { 0, 0 } ); line1->AddPoint( { 0, Mils2iu( -100 ) } ); - LIB_POLYLINE* line2 = new LIB_POLYLINE( aKsymbol ); + LIB_SHAPE* line2 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY ); aKsymbol->AddDrawItem( line2 ); line2->SetWidth( Mils2iu( 10 ) ); line2->AddPoint( { Mils2iu( -50 ), Mils2iu( -100 ) } ); @@ -1837,8 +1832,7 @@ void SCH_ALTIUM_PLUGIN::ParsePowerPort( const std::map& aPro pin->SetType( ELECTRICAL_PINTYPE::PT_POWER_IN ); pin->SetVisible( false ); - wxPoint valueFieldPos = HelperGeneratePowerPortGraphics( libSymbol, elem.style, - m_reporter ); + wxPoint valueFieldPos = HelperGeneratePowerPortGraphics( libSymbol, elem.style, m_reporter ); libSymbol->GetValueField().SetPosition( valueFieldPos ); diff --git a/eeschema/sch_plugins/cadstar/cadstar_sch_archive_loader.cpp b/eeschema/sch_plugins/cadstar/cadstar_sch_archive_loader.cpp index aa870f5370..bf24c316c8 100644 --- a/eeschema/sch_plugins/cadstar/cadstar_sch_archive_loader.cpp +++ b/eeschema/sch_plugins/cadstar/cadstar_sch_archive_loader.cpp @@ -28,8 +28,7 @@ #include #include #include -#include -#include +#include #include #include #include @@ -1605,11 +1604,11 @@ void CADSTAR_SCH_ARCHIVE_LOADER::loadLibrarySymbolShapeVertices( const std::vect { cur = &aCadstarVertices.at( i ); - LIB_ITEM* segment = nullptr; - bool cw = false; - wxPoint startPoint = getKiCadLibraryPoint( prev->End, aSymbolOrigin ); - wxPoint endPoint = getKiCadLibraryPoint( cur->End, aSymbolOrigin ); - wxPoint centerPoint; + LIB_SHAPE* shape = nullptr; + bool cw = false; + wxPoint startPoint = getKiCadLibraryPoint( prev->End, aSymbolOrigin ); + wxPoint endPoint = getKiCadLibraryPoint( cur->End, aSymbolOrigin ); + wxPoint centerPoint; if( cur->Type == VERTEX_TYPE::ANTICLOCKWISE_SEMICIRCLE || cur->Type == VERTEX_TYPE::CLOCKWISE_SEMICIRCLE ) @@ -1625,9 +1624,9 @@ void CADSTAR_SCH_ARCHIVE_LOADER::loadLibrarySymbolShapeVertices( const std::vect switch( cur->Type ) { case VERTEX_TYPE::POINT: - segment = new LIB_POLYLINE( aSymbol ); - ( (LIB_POLYLINE*) segment )->AddPoint( startPoint ); - ( (LIB_POLYLINE*) segment )->AddPoint( endPoint ); + shape = new LIB_SHAPE( aSymbol, SHAPE_T::POLY ); + shape->AddPoint( startPoint ); + shape->AddPoint( endPoint ); break; case VERTEX_TYPE::CLOCKWISE_SEMICIRCLE: @@ -1637,27 +1636,27 @@ void CADSTAR_SCH_ARCHIVE_LOADER::loadLibrarySymbolShapeVertices( const std::vect case VERTEX_TYPE::ANTICLOCKWISE_SEMICIRCLE: case VERTEX_TYPE::ANTICLOCKWISE_ARC: - segment = new LIB_ARC( aSymbol ); + shape = new LIB_SHAPE( aSymbol, SHAPE_T::ARC ); - ( (LIB_ARC*) segment )->SetPosition( centerPoint ); + shape->SetPosition( centerPoint ); if( cw ) { - ( (LIB_ARC*) segment )->SetStart( endPoint ); - ( (LIB_ARC*) segment )->SetEnd( startPoint ); + shape->SetStart( endPoint ); + shape->SetEnd( startPoint ); } else { - ( (LIB_ARC*) segment )->SetStart( startPoint ); - ( (LIB_ARC*) segment )->SetEnd( endPoint ); + shape->SetStart( startPoint ); + shape->SetEnd( endPoint ); } break; } - segment->SetUnit( aGateNumber ); - segment->SetWidth( aLineThickness ); - aSymbol->AddDrawItem( segment ); + shape->SetUnit( aGateNumber ); + shape->SetWidth( aLineThickness ); + aSymbol->AddDrawItem( shape ); prev = cur; } @@ -2043,8 +2042,7 @@ void CADSTAR_SCH_ARCHIVE_LOADER::loadShapeVertices( const std::vector& a else arcAngleDeciDeg = NormalizeAngleNeg( arcAngleDeciDeg ); - SHAPE_ARC tempArc( VECTOR2I(centerPoint), VECTOR2I(startPoint), - arcAngleDeciDeg / 10.0 ); + SHAPE_ARC tempArc( centerPoint, startPoint, arcAngleDeciDeg / 10.0 ); SHAPE_LINE_CHAIN arcSegments = tempArc.ConvertToPolyline( Millimeter2iu( 0.1 ) ); // Load the arc as a series of piece-wise segments @@ -2768,30 +2766,29 @@ LIB_SYMBOL* CADSTAR_SCH_ARCHIVE_LOADER::getScaledLibPart( const LIB_SYMBOL* aSym LIB_ITEMS_CONTAINER& items = retval->GetDrawItems(); - for( auto& item : items ) + for( LIB_ITEM& item : items ) { switch( item.Type() ) { - case KICAD_T::LIB_ARC_T: + case KICAD_T::LIB_SHAPE_T: { - LIB_ARC& arc = static_cast( item ); - arc.SetPosition( scalePt( arc.GetPosition() ) ); - arc.SetStart( scalePt( arc.GetStart() ) ); - arc.SetEnd( scalePt( arc.GetEnd() ) ); + LIB_SHAPE& shape = static_cast( item ); + + if( shape.GetShape() == SHAPE_T::ARC ) + { + shape.SetPosition( scalePt( shape.GetPosition() ) ); + shape.SetStart( scalePt( shape.GetStart() ) ); + shape.SetEnd( scalePt( shape.GetEnd() ) ); + } + else if( shape.GetShape() == SHAPE_T::POLY ) + { + SHAPE_LINE_CHAIN& poly = shape.GetPolyShape().Outline( 0 ); + + for( size_t ii = 0; ii < poly.GetPointCount(); ++ii ) + poly.SetPoint( ii, scalePt( (wxPoint) poly.CPoint( ii ) ) ); + } } - break; - - case KICAD_T::LIB_POLYLINE_T: - { - LIB_POLYLINE& poly = static_cast( item ); - - std::vector originalPts = poly.GetPolyPoints(); - poly.ClearPoints(); - - for( wxPoint& pt : originalPts ) - poly.AddPoint( scalePt( pt ) ); - } - break; + break; case KICAD_T::LIB_PIN_T: { @@ -2800,7 +2797,7 @@ LIB_SYMBOL* CADSTAR_SCH_ARCHIVE_LOADER::getScaledLibPart( const LIB_SYMBOL* aSym pin.SetPosition( scalePt( pin.GetPosition() ) ); pin.SetLength( scaleLen( pin.GetLength() ) ); } - break; + break; case KICAD_T::LIB_TEXT_T: { @@ -2809,9 +2806,10 @@ LIB_SYMBOL* CADSTAR_SCH_ARCHIVE_LOADER::getScaledLibPart( const LIB_SYMBOL* aSym txt.SetPosition( scalePt( txt.GetPosition() ) ); txt.SetTextSize( scaleSize( txt.GetTextSize() ) ); } - break; + break; - default: break; + default: + break; } } @@ -2824,47 +2822,48 @@ void CADSTAR_SCH_ARCHIVE_LOADER::fixUpLibraryPins( LIB_SYMBOL* aSymbolToFix, int { // Store a list of segments that are not connected to other segments and are vertical or // horizontal. - std::map twoPointUniqueSegments; + std::map uniqueSegments; - LIB_ITEMS_CONTAINER::ITERATOR polylineiter = - aSymbolToFix->GetDrawItems().begin( LIB_POLYLINE_T ); + LIB_ITEMS_CONTAINER::ITERATOR shapeIt = aSymbolToFix->GetDrawItems().begin( LIB_SHAPE_T ); - for( ; polylineiter != aSymbolToFix->GetDrawItems().end( LIB_POLYLINE_T ); ++polylineiter ) + for( ; shapeIt != aSymbolToFix->GetDrawItems().end( LIB_SHAPE_T ); ++shapeIt ) { - LIB_POLYLINE& polyline = static_cast( *polylineiter ); + LIB_SHAPE& shape = static_cast( *shapeIt ); - if( aGateNumber > 0 && polyline.GetUnit() != aGateNumber ) + if( aGateNumber > 0 && shape.GetUnit() != aGateNumber ) continue; - const std::vector& pts = polyline.GetPolyPoints(); + if( shape.GetShape() != SHAPE_T::POLY ) + continue; - bool isUnique = true; + SHAPE_LINE_CHAIN& poly = shape.GetPolyShape().Outline( 0 ); + bool isUnique = true; auto removeSegment = - [&]( LIB_POLYLINE* aLineToRemove ) - { - twoPointUniqueSegments.erase( aLineToRemove->GetPolyPoints().at( 0 ) ); - twoPointUniqueSegments.erase( aLineToRemove->GetPolyPoints().at( 1 ) ); - isUnique = false; - }; + [&]( SHAPE_LINE_CHAIN& aLineToRemove ) + { + uniqueSegments.erase( aLineToRemove.CPoint( 0 ) ); + uniqueSegments.erase( aLineToRemove.CPoint( 1 ) ); + isUnique = false; + }; - if( pts.size() == 2 ) + if( poly.GetPointCount() == 2 ) { - const wxPoint& pt0 = pts.at( 0 ); - const wxPoint& pt1 = pts.at( 1 ); + const VECTOR2I& pt0 = poly.CPoint( 0 ); + const VECTOR2I& pt1 = poly.CPoint( 1 ); - if( twoPointUniqueSegments.count( pt0 ) ) - removeSegment( twoPointUniqueSegments.at( pt0 ) ); + if( uniqueSegments.count( pt0 ) ) + removeSegment( uniqueSegments.at( pt0 ) ); - if( twoPointUniqueSegments.count( pt1 ) ) - removeSegment( twoPointUniqueSegments.at( pt1 ) ); + if( uniqueSegments.count( pt1 ) ) + removeSegment( uniqueSegments.at( pt1 ) ); if( isUnique && pt0 != pt1 ) { if( pt0.x == pt1.x || pt0.y == pt1.y ) { - twoPointUniqueSegments.insert( { pts.at( 0 ), &polyline } ); - twoPointUniqueSegments.insert( { pts.at( 1 ), &polyline } ); + uniqueSegments.insert( { poly.CPoint( 0 ), poly } ); + uniqueSegments.insert( { poly.CPoint( 1 ), poly } ); } } } @@ -2890,14 +2889,14 @@ void CADSTAR_SCH_ARCHIVE_LOADER::fixUpLibraryPins( LIB_SYMBOL* aSymbolToFix, int pin->SetOrientation( 'D' ); // -90 degrees }; - if( twoPointUniqueSegments.count( pin->GetPosition() ) ) + if( uniqueSegments.count( pin->GetPosition() ) ) { - LIB_POLYLINE* poly = twoPointUniqueSegments.at( pin->GetPosition() ); + SHAPE_LINE_CHAIN& poly = uniqueSegments.at( pin->GetPosition() ); - wxPoint otherPt = poly->GetPolyPoints().at( 0 ); + VECTOR2I otherPt = poly.CPoint( 0 ); if( otherPt == pin->GetPosition() ) - otherPt = poly->GetPolyPoints().at( 1 ); + otherPt = poly.CPoint( 1 ); VECTOR2I vec( otherPt - pin->GetPosition() ); diff --git a/eeschema/sch_plugins/eagle/sch_eagle_plugin.cpp b/eeschema/sch_plugins/eagle/sch_eagle_plugin.cpp index 30658457a7..ea00e7d612 100644 --- a/eeschema/sch_plugins/eagle/sch_eagle_plugin.cpp +++ b/eeschema/sch_plugins/eagle/sch_eagle_plugin.cpp @@ -38,13 +38,10 @@ #include #include #include -#include -#include +#include #include #include #include -#include -#include #include #include #include @@ -1730,29 +1727,28 @@ bool SCH_EAGLE_PLUGIN::loadSymbol( wxXmlNode* aSymbolNode, std::unique_ptr& aSymbol, - wxXmlNode* aCircleNode, int aGateNumber ) +LIB_SHAPE* SCH_EAGLE_PLUGIN::loadSymbolCircle( std::unique_ptr& aSymbol, + wxXmlNode* aCircleNode, int aGateNumber ) { // Parse the circle properties - ECIRCLE c( aCircleNode ); + ECIRCLE c( aCircleNode ); + LIB_SHAPE* circle = new LIB_SHAPE( aSymbol.get(), SHAPE_T::CIRCLE ); + wxPoint center( c.x.ToSchUnits(), c.y.ToSchUnits() ); - unique_ptr circle( new LIB_CIRCLE( aSymbol.get() ) ); - - circle->SetPosition( wxPoint( c.x.ToSchUnits(), c.y.ToSchUnits() ) ); - circle->SetRadius( c.radius.ToSchUnits() ); + circle->SetPosition( center ); + circle->SetEnd( wxPoint( center.x + c.radius.ToSchUnits(), center.y ) ); circle->SetWidth( c.width.ToSchUnits() ); circle->SetUnit( aGateNumber ); - return circle.release(); + return circle; } -LIB_RECTANGLE* SCH_EAGLE_PLUGIN::loadSymbolRectangle( std::unique_ptr& aSymbol, - wxXmlNode* aRectNode, int aGateNumber ) +LIB_SHAPE* SCH_EAGLE_PLUGIN::loadSymbolRectangle( std::unique_ptr& aSymbol, + wxXmlNode* aRectNode, int aGateNumber ) { - ERECT rect( aRectNode ); - - unique_ptr rectangle( new LIB_RECTANGLE( aSymbol.get() ) ); + ERECT rect( aRectNode ); + LIB_SHAPE* rectangle = new LIB_SHAPE( aSymbol.get(), SHAPE_T::RECT ); rectangle->SetPosition( wxPoint( rect.x1.ToSchUnits(), rect.y1.ToSchUnits() ) ); rectangle->SetEnd( wxPoint( rect.x2.ToSchUnits(), rect.y2.ToSchUnits() ) ); @@ -1760,9 +1756,9 @@ LIB_RECTANGLE* SCH_EAGLE_PLUGIN::loadSymbolRectangle( std::unique_ptrSetUnit( aGateNumber ); // Eagle rectangles are filled by definition. - rectangle->SetFillMode( FILL_TYPE::FILLED_SHAPE ); + rectangle->SetFillMode( FILL_T::FILLED_SHAPE ); - return rectangle.release(); + return rectangle; } @@ -1784,12 +1780,11 @@ LIB_ITEM* SCH_EAGLE_PLUGIN::loadSymbolWire( std::unique_ptr& aSymbol // if the wire is an arc if( ewire.curve ) { - std::unique_ptr arc = std::make_unique( aSymbol.get() ); - wxPoint center = ConvertArcCenter( begin, end, *ewire.curve * -1 ); - - double radius = sqrt( abs( ( ( center.x - begin.x ) * ( center.x - begin.x ) ) - + ( ( center.y - begin.y ) * ( center.y - begin.y ) ) ) ) - * 2; + LIB_SHAPE* arc = new LIB_SHAPE( aSymbol.get(), SHAPE_T::ARC ); + wxPoint center = ConvertArcCenter( begin, end, *ewire.curve * -1 ); + double radius = sqrt( abs( ( ( center.x - begin.x ) * ( center.x - begin.x ) ) + + ( ( center.y - begin.y ) * ( center.y - begin.y ) ) ) ) + * 2; // this emulates the filled semicircles created by a thick arc with flat ends caps. if( ewire.width.ToSchUnits() * 2 > radius ) @@ -1811,49 +1806,39 @@ LIB_ITEM* SCH_EAGLE_PLUGIN::loadSymbolWire( std::unique_ptr& aSymbol * 2; arc->SetWidth( 1 ); - arc->SetFillMode( FILL_TYPE::FILLED_SHAPE ); + arc->SetFillMode( FILL_T::FILLED_SHAPE ); } else { arc->SetWidth( ewire.width.ToSchUnits() ); } - arc->SetPosition( center ); - - if( *ewire.curve > 0 ) - { - arc->SetStart( begin ); - arc->SetEnd( end ); - } - else - { - arc->SetStart( end ); - arc->SetEnd( begin ); - } + if( *ewire.curve <= 0 ) + std::swap( begin, end ); + arc->SetArcGeometry( begin, (wxPoint) CalcArcMid( begin, end, center ), end ); arc->SetUnit( aGateNumber ); - return (LIB_ITEM*) arc.release(); + return arc; } else { - std::unique_ptr polyLine = std::make_unique( aSymbol.get() ); + LIB_SHAPE* poly = new LIB_SHAPE( aSymbol.get(), SHAPE_T::POLY ); - polyLine->AddPoint( begin ); - polyLine->AddPoint( end ); - polyLine->SetUnit( aGateNumber ); - polyLine->SetWidth( ewire.width.ToSchUnits() ); + poly->AddPoint( begin ); + poly->AddPoint( end ); + poly->SetUnit( aGateNumber ); + poly->SetWidth( ewire.width.ToSchUnits() ); - return (LIB_ITEM*) polyLine.release(); + return poly; } } -LIB_POLYLINE* SCH_EAGLE_PLUGIN::loadSymbolPolyLine( std::unique_ptr& aSymbol, - wxXmlNode* aPolygonNode, int aGateNumber ) +LIB_SHAPE* SCH_EAGLE_PLUGIN::loadSymbolPolyLine( std::unique_ptr& aSymbol, + wxXmlNode* aPolygonNode, int aGateNumber ) { - std::unique_ptr polyLine = std::make_unique( aSymbol.get() ); - + LIB_SHAPE* poly = new LIB_SHAPE( aSymbol.get(), SHAPE_T::POLY ); EPOLYGON epoly( aPolygonNode ); wxXmlNode* vertex = aPolygonNode->GetChildren(); wxPoint pt; @@ -1864,16 +1849,16 @@ LIB_POLYLINE* SCH_EAGLE_PLUGIN::loadSymbolPolyLine( std::unique_ptr& { EVERTEX evertex( vertex ); pt = wxPoint( evertex.x.ToSchUnits(), evertex.y.ToSchUnits() ); - polyLine->AddPoint( pt ); + poly->AddPoint( pt ); } vertex = vertex->GetNext(); } - polyLine->SetFillMode( FILL_TYPE::FILLED_SHAPE ); - polyLine->SetUnit( aGateNumber ); + poly->SetFillMode( FILL_T::FILLED_SHAPE ); + poly->SetUnit( aGateNumber ); - return polyLine.release(); + return poly; } @@ -1994,7 +1979,7 @@ void SCH_EAGLE_PLUGIN::loadFrame( wxXmlNode* aFrameNode, std::vector& if( yMin > yMax ) std::swap( yMin, yMax ); - LIB_POLYLINE* lines = new LIB_POLYLINE( nullptr ); + LIB_SHAPE* lines = new LIB_SHAPE( nullptr, SHAPE_T::POLY ); lines->AddPoint( wxPoint( xMin, yMin ) ); lines->AddPoint( wxPoint( xMax, yMin ) ); lines->AddPoint( wxPoint( xMax, yMax ) ); @@ -2004,7 +1989,7 @@ void SCH_EAGLE_PLUGIN::loadFrame( wxXmlNode* aFrameNode, std::vector& if( !eframe.border_left ) { - lines = new LIB_POLYLINE( nullptr ); + lines = new LIB_SHAPE( nullptr, SHAPE_T::POLY ); lines->AddPoint( wxPoint( xMin + Mils2iu( 150 ), yMin + Mils2iu( 150 ) ) ); lines->AddPoint( wxPoint( xMin + Mils2iu( 150 ), yMax - Mils2iu( 150 ) ) ); aItems.push_back( lines ); @@ -2020,7 +2005,7 @@ void SCH_EAGLE_PLUGIN::loadFrame( wxXmlNode* aFrameNode, std::vector& for( i = 1; i < eframe.rows; i++ ) { int newY = KiROUND( yMin + ( rowSpacing * (double) i ) ); - lines = new LIB_POLYLINE( nullptr ); + lines = new LIB_SHAPE( nullptr, SHAPE_T::POLY ); lines->AddPoint( wxPoint( x1, newY ) ); lines->AddPoint( wxPoint( x2, newY ) ); aItems.push_back( lines ); @@ -2042,7 +2027,7 @@ void SCH_EAGLE_PLUGIN::loadFrame( wxXmlNode* aFrameNode, std::vector& if( !eframe.border_right ) { - lines = new LIB_POLYLINE( nullptr ); + lines = new LIB_SHAPE( nullptr, SHAPE_T::POLY ); lines->AddPoint( wxPoint( xMax - Mils2iu( 150 ), yMin + Mils2iu( 150 ) ) ); lines->AddPoint( wxPoint( xMax - Mils2iu( 150 ), yMax - Mils2iu( 150 ) ) ); aItems.push_back( lines ); @@ -2058,7 +2043,7 @@ void SCH_EAGLE_PLUGIN::loadFrame( wxXmlNode* aFrameNode, std::vector& for( i = 1; i < eframe.rows; i++ ) { int newY = KiROUND( yMin + ( rowSpacing * (double) i ) ); - lines = new LIB_POLYLINE( nullptr ); + lines = new LIB_SHAPE( nullptr, SHAPE_T::POLY ); lines->AddPoint( wxPoint( x1, newY ) ); lines->AddPoint( wxPoint( x2, newY ) ); aItems.push_back( lines ); @@ -2080,7 +2065,7 @@ void SCH_EAGLE_PLUGIN::loadFrame( wxXmlNode* aFrameNode, std::vector& if( !eframe.border_top ) { - lines = new LIB_POLYLINE( nullptr ); + lines = new LIB_SHAPE( nullptr, SHAPE_T::POLY ); lines->AddPoint( wxPoint( xMax - Mils2iu( 150 ), yMax - Mils2iu( 150 ) ) ); lines->AddPoint( wxPoint( xMin + Mils2iu( 150 ), yMax - Mils2iu( 150 ) ) ); aItems.push_back( lines ); @@ -2096,7 +2081,7 @@ void SCH_EAGLE_PLUGIN::loadFrame( wxXmlNode* aFrameNode, std::vector& for( i = 1; i < eframe.columns; i++ ) { int newX = KiROUND( xMin + ( columnSpacing * (double) i ) ); - lines = new LIB_POLYLINE( nullptr ); + lines = new LIB_SHAPE( nullptr, SHAPE_T::POLY ); lines->AddPoint( wxPoint( newX, y1 ) ); lines->AddPoint( wxPoint( newX, y2 ) ); aItems.push_back( lines ); @@ -2118,7 +2103,7 @@ void SCH_EAGLE_PLUGIN::loadFrame( wxXmlNode* aFrameNode, std::vector& if( !eframe.border_bottom ) { - lines = new LIB_POLYLINE( nullptr ); + lines = new LIB_SHAPE( nullptr, SHAPE_T::POLY ); lines->AddPoint( wxPoint( xMax - Mils2iu( 150 ), yMin + Mils2iu( 150 ) ) ); lines->AddPoint( wxPoint( xMin + Mils2iu( 150 ), yMin + Mils2iu( 150 ) ) ); aItems.push_back( lines ); @@ -2134,7 +2119,7 @@ void SCH_EAGLE_PLUGIN::loadFrame( wxXmlNode* aFrameNode, std::vector& for( i = 1; i < eframe.columns; i++ ) { int newX = KiROUND( xMin + ( columnSpacing * (double) i ) ); - lines = new LIB_POLYLINE( nullptr ); + lines = new LIB_SHAPE( nullptr, SHAPE_T::POLY ); lines->AddPoint( wxPoint( newX, y1 ) ); lines->AddPoint( wxPoint( newX, y2 ) ); aItems.push_back( lines ); diff --git a/eeschema/sch_plugins/eagle/sch_eagle_plugin.h b/eeschema/sch_plugins/eagle/sch_eagle_plugin.h index bebe85b44c..ec586ed06d 100644 --- a/eeschema/sch_plugins/eagle/sch_eagle_plugin.h +++ b/eeschema/sch_plugins/eagle/sch_eagle_plugin.h @@ -51,7 +51,7 @@ class PROPERTIES; class SCH_EAGLE_PLUGIN_CACHE; class LIB_SYMBOL; class SYMBOL_LIB; -class LIB_CIRCLE; +class LIB_SHAPE; class LIB_FIELD; class LIB_RECTANGLE; class LIB_POLYLINE; @@ -128,32 +128,32 @@ private: std::pair findNearestLinePoint( const wxPoint& aPoint, const std::vector& aLines ) const; - void loadSegments( wxXmlNode* aSegmentsNode, const wxString& aNetName, - const wxString& aNetClass ); - SCH_LINE* loadWire( wxXmlNode* aWireNode ); - SCH_TEXT* loadLabel( wxXmlNode* aLabelNode, const wxString& aNetName ); - SCH_JUNCTION* loadJunction( wxXmlNode* aJunction ); - SCH_TEXT* loadPlainText( wxXmlNode* aSchText ); - void loadFrame( wxXmlNode* aFrameNode, std::vector& aLines ); + void loadSegments( wxXmlNode* aSegmentsNode, const wxString& aNetName, + const wxString& aNetClass ); + SCH_LINE* loadWire( wxXmlNode* aWireNode ); + SCH_TEXT* loadLabel( wxXmlNode* aLabelNode, const wxString& aNetName ); + SCH_JUNCTION* loadJunction( wxXmlNode* aJunction ); + SCH_TEXT* loadPlainText( wxXmlNode* aSchText ); + void loadFrame( wxXmlNode* aFrameNode, std::vector& aLines ); - bool loadSymbol( wxXmlNode* aSymbolNode, std::unique_ptr& aSymbol, - EDEVICE* aDevice, int aGateNumber, const wxString& aGateName ); - LIB_CIRCLE* loadSymbolCircle( std::unique_ptr& aSymbol, wxXmlNode* aCircleNode, - int aGateNumber ); - LIB_RECTANGLE* loadSymbolRectangle( std::unique_ptr& aSymbol, wxXmlNode* aRectNode, - int aGateNumber ); - LIB_POLYLINE* loadSymbolPolyLine( std::unique_ptr& aSymbol, - wxXmlNode* aPolygonNode, int aGateNumber ); - LIB_ITEM* loadSymbolWire( std::unique_ptr& aSymbol, wxXmlNode* aWireNode, + bool loadSymbol( wxXmlNode* aSymbolNode, std::unique_ptr& aSymbol, + EDEVICE* aDevice, int aGateNumber, const wxString& aGateName ); + LIB_SHAPE* loadSymbolCircle( std::unique_ptr& aSymbol, wxXmlNode* aCircleNode, int aGateNumber ); - LIB_PIN* loadPin( std::unique_ptr& aSymbol, wxXmlNode*, EPIN* epin, - int aGateNumber ); - LIB_TEXT* loadSymbolText( std::unique_ptr& aSymbol, wxXmlNode* aLibText, - int aGateNumber ); - void loadFrame( wxXmlNode* aFrameNode, std::vector& aLines ); + LIB_SHAPE* loadSymbolRectangle( std::unique_ptr& aSymbol, wxXmlNode* aRectNode, + int aGateNumber ); + LIB_SHAPE* loadSymbolPolyLine( std::unique_ptr& aSymbol, + wxXmlNode* aPolygonNode, int aGateNumber ); + LIB_ITEM* loadSymbolWire( std::unique_ptr& aSymbol, wxXmlNode* aWireNode, + int aGateNumber ); + LIB_PIN* loadPin( std::unique_ptr& aSymbol, wxXmlNode*, EPIN* epin, + int aGateNumber ); + LIB_TEXT* loadSymbolText( std::unique_ptr& aSymbol, wxXmlNode* aLibText, + int aGateNumber ); + void loadFrame( wxXmlNode* aFrameNode, std::vector& aLines ); - void loadTextAttributes( EDA_TEXT* aText, const ETEXT& aAttribs ) const; - void loadFieldAttributes( LIB_FIELD* aField, const LIB_TEXT* aText ) const; + void loadTextAttributes( EDA_TEXT* aText, const ETEXT& aAttribs ) const; + void loadFieldAttributes( LIB_FIELD* aField, const LIB_TEXT* aText ) const; ///< Move net labels that are detached from any wire to the nearest wire void adjustNetLabels(); diff --git a/eeschema/sch_plugins/kicad/sch_sexpr_parser.cpp b/eeschema/sch_plugins/kicad/sch_sexpr_parser.cpp index f62c7530f9..1920983847 100644 --- a/eeschema/sch_plugins/kicad/sch_sexpr_parser.cpp +++ b/eeschema/sch_plugins/kicad/sch_sexpr_parser.cpp @@ -33,12 +33,8 @@ #include #include -#include -#include -#include +#include #include -#include -#include #include #include // KiROUND, Clamp #include @@ -543,7 +539,7 @@ void SCH_SEXPR_PARSER::parseFill( FILL_PARAMS& aFill ) wxCHECK_RET( CurTok() == T_fill, wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as fill." ) ); - aFill.m_FillType = FILL_TYPE::NO_FILL; + aFill.m_FillType = FILL_T::NO_FILL; aFill.m_Color = COLOR4D::UNSPECIFIED; T token; @@ -563,9 +559,9 @@ void SCH_SEXPR_PARSER::parseFill( FILL_PARAMS& aFill ) switch( token ) { - case T_none: aFill.m_FillType = FILL_TYPE::NO_FILL; break; - case T_outline: aFill.m_FillType = FILL_TYPE::FILLED_SHAPE; break; - case T_background: aFill.m_FillType = FILL_TYPE::FILLED_WITH_BG_BODYCOLOR; break; + case T_none: aFill.m_FillType = FILL_T::NO_FILL; break; + case T_outline: aFill.m_FillType = FILL_T::FILLED_SHAPE; break; + case T_background: aFill.m_FillType = FILL_T::FILLED_WITH_BG_BODYCOLOR; break; default: Expecting( "none, outline, or background" ); } @@ -906,10 +902,10 @@ LIB_FIELD* SCH_SEXPR_PARSER::parseProperty( std::unique_ptr& aSymbol } -LIB_ARC* SCH_SEXPR_PARSER::parseArc() +LIB_SHAPE* SCH_SEXPR_PARSER::parseArc() { wxCHECK_MSG( CurTok() == T_arc, nullptr, - wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as an arc token." ) ); + wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as an arc." ) ); T token; wxPoint startPoint; @@ -920,7 +916,8 @@ LIB_ARC* SCH_SEXPR_PARSER::parseArc() int endAngle; FILL_PARAMS fill; bool hasMidPoint = false; - std::unique_ptr arc = std::make_unique( nullptr ); + bool hasAngles = false; + std::unique_ptr arc = std::make_unique( nullptr, SHAPE_T::ARC ); arc->SetUnit( m_unit ); arc->SetConvert( m_convert ); @@ -977,6 +974,7 @@ LIB_ARC* SCH_SEXPR_PARSER::parseArc() NORMALIZE_ANGLE_POS( startAngle ); NORMALIZE_ANGLE_POS( endAngle ); NeedRIGHT(); + hasAngles = true; break; } @@ -1005,22 +1003,22 @@ LIB_ARC* SCH_SEXPR_PARSER::parseArc() break; default: - Expecting( "start, end, radius, stroke, or fill" ); + Expecting( "start, mid, end, radius, stroke, or fill" ); } } - arc->SetPosition( pos ); arc->SetStart( startPoint ); arc->SetEnd( endPoint ); if( hasMidPoint ) { - VECTOR2I center = CalcArcCenter( arc->GetStart(), midPoint, arc->GetEnd()); + VECTOR2I center = CalcArcCenter( arc->GetStart(), midPoint, arc->GetEnd() ); arc->SetCenter( (wxPoint) center ); } - else + else if( hasAngles ) { + arc->SetCenter( pos ); /** * This accounts for an oddity in the old library format, where the symbol is overdefined. * The previous draw (based on wxwidgets) used start point and end point and always drew @@ -1035,19 +1033,21 @@ LIB_ARC* SCH_SEXPR_PARSER::parseArc() arc->SetEnd( temp ); } } + else + wxFAIL_MSG( "Setting arc without either midpoint or angles not implemented." ); return arc.release(); } -LIB_BEZIER* SCH_SEXPR_PARSER::parseBezier() +LIB_SHAPE* SCH_SEXPR_PARSER::parseBezier() { wxCHECK_MSG( CurTok() == T_bezier, nullptr, wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as a bezier." ) ); T token; FILL_PARAMS fill; - std::unique_ptr bezier = std::make_unique( nullptr ); + std::unique_ptr bezier = std::make_unique( nullptr, SHAPE_T::BEZIER ); bezier->SetUnit( m_unit ); bezier->SetConvert( m_convert ); @@ -1105,15 +1105,16 @@ LIB_BEZIER* SCH_SEXPR_PARSER::parseBezier() } -LIB_CIRCLE* SCH_SEXPR_PARSER::parseCircle() +LIB_SHAPE* SCH_SEXPR_PARSER::parseCircle() { wxCHECK_MSG( CurTok() == T_circle, nullptr, - wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + - wxT( " as a circle token." ) ); + wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as a circle." ) ); T token; + wxPoint center; + int radius; FILL_PARAMS fill; - std::unique_ptr circle = std::make_unique( nullptr ); + std::unique_ptr circle = std::make_unique( nullptr, SHAPE_T::CIRCLE ); circle->SetUnit( m_unit ); circle->SetConvert( m_convert ); @@ -1128,12 +1129,12 @@ LIB_CIRCLE* SCH_SEXPR_PARSER::parseCircle() switch( token ) { case T_center: - circle->SetPosition( parseXY() ); + center = parseXY(); NeedRIGHT(); break; case T_radius: - circle->SetRadius( parseInternalUnits( "radius length" ) ); + radius = parseInternalUnits( "radius length" ); NeedRIGHT(); break; @@ -1155,10 +1156,13 @@ LIB_CIRCLE* SCH_SEXPR_PARSER::parseCircle() break; default: - Expecting( "start, end, radius, stroke, or fill" ); + Expecting( "center, radius, stroke, or fill" ); } } + circle->SetCenter( center ); + circle->SetEnd( wxPoint( center.x + radius, center.y ) ); + return circle.release(); } @@ -1386,17 +1390,17 @@ LIB_PIN* SCH_SEXPR_PARSER::parsePin() } -LIB_POLYLINE* SCH_SEXPR_PARSER::parsePolyLine() +LIB_SHAPE* SCH_SEXPR_PARSER::parsePolyLine() { wxCHECK_MSG( CurTok() == T_polyline, nullptr, - wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as a polyline." ) ); + wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as a poly." ) ); T token; FILL_PARAMS fill; - std::unique_ptr polyLine = std::make_unique( nullptr ); + std::unique_ptr poly = std::make_unique( nullptr, SHAPE_T::POLY ); - polyLine->SetUnit( m_unit ); - polyLine->SetConvert( m_convert ); + poly->SetUnit( m_unit ); + poly->SetConvert( m_convert ); for( token = NextTok(); token != T_RIGHT; token = NextTok() ) { @@ -1418,7 +1422,7 @@ LIB_POLYLINE* SCH_SEXPR_PARSER::parsePolyLine() if( token != T_xy ) Expecting( "xy" ); - polyLine->AddPoint( parseXY() ); + poly->AddPoint( parseXY() ); NeedRIGHT(); } @@ -1432,14 +1436,14 @@ LIB_POLYLINE* SCH_SEXPR_PARSER::parsePolyLine() if( token != T_width ) Expecting( "width" ); - polyLine->SetWidth( parseInternalUnits( "stroke width" ) ); + poly->SetWidth( parseInternalUnits( "stroke width" ) ); NeedRIGHT(); // Closes width token; NeedRIGHT(); // Closes stroke token; break; case T_fill: parseFill( fill ); - polyLine->SetFillMode( fill.m_FillType ); + poly->SetFillMode( fill.m_FillType ); break; default: @@ -1447,19 +1451,18 @@ LIB_POLYLINE* SCH_SEXPR_PARSER::parsePolyLine() } } - return polyLine.release(); + return poly.release(); } -LIB_RECTANGLE* SCH_SEXPR_PARSER::parseRectangle() +LIB_SHAPE* SCH_SEXPR_PARSER::parseRectangle() { wxCHECK_MSG( CurTok() == T_rectangle, nullptr, - wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + - wxT( " as a rectangle token." ) ); + wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as a rectangle." ) ); T token; FILL_PARAMS fill; - std::unique_ptr rectangle = std::make_unique( nullptr ); + std::unique_ptr rectangle = std::make_unique( nullptr, SHAPE_T::RECT ); rectangle->SetUnit( m_unit ); rectangle->SetConvert( m_convert ); diff --git a/eeschema/sch_plugins/kicad/sch_sexpr_parser.h b/eeschema/sch_plugins/kicad/sch_sexpr_parser.h index 05f1ae2c63..5e0ae6fe17 100644 --- a/eeschema/sch_plugins/kicad/sch_sexpr_parser.h +++ b/eeschema/sch_plugins/kicad/sch_sexpr_parser.h @@ -40,12 +40,9 @@ #include // For some default values -class LIB_ARC; -class LIB_BEZIER; -class LIB_CIRCLE; +class LIB_SHAPE; class LIB_ITEM; class LIB_PIN; -class LIB_POLYLINE; class LIB_TEXT; class PAGE_INFO; class SCH_BITMAP; @@ -68,7 +65,7 @@ class TITLE_BLOCK; class FILL_PARAMS { public: - FILL_TYPE m_FillType; + FILL_T m_FillType; COLOR4D m_Color; }; @@ -165,12 +162,12 @@ class SCH_SEXPR_PARSER : public SCHEMATIC_LEXER LIB_FIELD* parseProperty( std::unique_ptr& aSymbol ); - LIB_ARC* parseArc(); - LIB_BEZIER* parseBezier(); - LIB_CIRCLE* parseCircle(); + LIB_SHAPE* parseArc(); + LIB_SHAPE* parseBezier(); + LIB_SHAPE* parseCircle(); LIB_PIN* parsePin(); - LIB_POLYLINE* parsePolyLine(); - LIB_RECTANGLE* parseRectangle(); + LIB_SHAPE* parsePolyLine(); + LIB_SHAPE* parseRectangle(); LIB_TEXT* parseText(); void parsePAGE_INFO( PAGE_INFO& aPageInfo ); diff --git a/eeschema/sch_plugins/kicad/sch_sexpr_plugin.cpp b/eeschema/sch_plugins/kicad/sch_sexpr_plugin.cpp index 6bed63dac6..a66db999e6 100644 --- a/eeschema/sch_plugins/kicad/sch_sexpr_plugin.cpp +++ b/eeschema/sch_plugins/kicad/sch_sexpr_plugin.cpp @@ -45,13 +45,9 @@ #include #include #include -#include -#include -#include +#include #include #include -#include -#include #include #include // for MAX_UNIT_COUNT_PER_PACKAGE definition #include @@ -77,18 +73,16 @@ static const char* emptyString = ""; /** * Fill token formatting helper. */ -static void formatFill( const LIB_ITEM* aItem, OUTPUTFORMATTER& aFormatter, int aNestLevel ) +static void formatFill( const LIB_SHAPE* aItem, OUTPUTFORMATTER& aFormatter, int aNestLevel ) { - wxCHECK_RET( aItem && aItem->IsFillable(), "Invalid fill item." ); - const char* fillType; - switch( aItem->GetFillMode() ) + switch( aItem->GetFillType() ) { - case FILL_TYPE::FILLED_SHAPE: fillType = "outline"; break; - case FILL_TYPE::FILLED_WITH_BG_BODYCOLOR: fillType = "background"; break; - case FILL_TYPE::NO_FILL: KI_FALLTHROUGH; - default: fillType = "none"; + default: + case FILL_T::NO_FILL: fillType = "none"; break; + case FILL_T::FILLED_SHAPE: fillType = "outline"; break; + case FILL_T::FILLED_WITH_BG_BODYCOLOR: fillType = "background"; break; } aFormatter.Print( aNestLevel, "(fill (type %s))", fillType ); @@ -302,26 +296,22 @@ class SCH_SEXPR_PLUGIN_CACHE int m_versionMajor; SCH_LIB_TYPE m_libType; // Is this cache a symbol or symbol library. - LIB_SYMBOL* removeSymbol( LIB_SYMBOL* aAlias ); + LIB_SYMBOL* removeSymbol( LIB_SYMBOL* aAlias ); - static void saveSymbolDrawItem( LIB_ITEM* aItem, OUTPUTFORMATTER& aFormatter, - int aNestLevel ); - static void saveArc( LIB_ARC* aArc, OUTPUTFORMATTER& aFormatter, int aNestLevel = 0 ); - static void saveBezier( LIB_BEZIER* aBezier, OUTPUTFORMATTER& aFormatter, - int aNestLevel = 0 ); - static void saveCircle( LIB_CIRCLE* aCircle, OUTPUTFORMATTER& aFormatter, - int aNestLevel = 0 ); - static void saveField( LIB_FIELD* aField, OUTPUTFORMATTER& aFormatter, - int& aNextFreeFieldId, int aNestLevel ); - static void savePin( LIB_PIN* aPin, OUTPUTFORMATTER& aFormatter, int aNestLevel = 0 ); - static void savePolyLine( LIB_POLYLINE* aPolyLine, OUTPUTFORMATTER& aFormatter, - int aNestLevel = 0 ); - static void saveRectangle( LIB_RECTANGLE* aRectangle, OUTPUTFORMATTER& aFormatter, - int aNestLevel = 0 ); - static void saveText( LIB_TEXT* aText, OUTPUTFORMATTER& aFormatter, int aNestLevel = 0 ); + static void saveSymbolDrawItem( LIB_ITEM* aItem, OUTPUTFORMATTER& aFormatter, + int aNestLevel ); + static void saveArc( LIB_SHAPE* aArc, OUTPUTFORMATTER& aFormatter, int aNestLevel = 0 ); + static void saveBezier( LIB_SHAPE* aBezier, OUTPUTFORMATTER& aFormatter, int aNestLevel = 0 ); + static void saveCircle( LIB_SHAPE* aCircle, OUTPUTFORMATTER& aFormatter, int aNestLevel = 0 ); + static void saveField( LIB_FIELD* aField, OUTPUTFORMATTER& aFormatter, int& aNextFreeFieldId, + int aNestLevel ); + static void savePin( LIB_PIN* aPin, OUTPUTFORMATTER& aFormatter, int aNestLevel = 0 ); + static void savePolyLine( LIB_SHAPE* aPolyLine, OUTPUTFORMATTER& aFormatter, int aNestLevel = 0 ); + static void saveRectangle( LIB_SHAPE* aRect, OUTPUTFORMATTER& aFormatter, int aNestLevel = 0 ); + static void saveText( LIB_TEXT* aText, OUTPUTFORMATTER& aFormatter, int aNestLevel = 0 ); - static void saveDcmInfoAsFields( LIB_SYMBOL* aSymbol, OUTPUTFORMATTER& aFormatter, - int& aNextFreeFieldId, int aNestLevel ); + static void saveDcmInfoAsFields( LIB_SYMBOL* aSymbol, OUTPUTFORMATTER& aFormatter, + int& aNextFreeFieldId, int aNestLevel ); friend SCH_SEXPR_PLUGIN; @@ -1771,49 +1761,44 @@ void SCH_SEXPR_PLUGIN_CACHE::saveSymbolDrawItem( LIB_ITEM* aItem, OUTPUTFORMATTE switch( aItem->Type() ) { - case LIB_ARC_T: - saveArc( (LIB_ARC*) aItem, aFormatter, aNestLevel ); - break; + case LIB_SHAPE_T: + { + LIB_SHAPE* shape = static_cast( aItem ); - case LIB_BEZIER_T: - saveBezier( (LIB_BEZIER*) aItem, aFormatter, aNestLevel ); - break; + switch( shape->GetShape() ) + { + case SHAPE_T::ARC: saveArc( shape, aFormatter, aNestLevel ); break; + case SHAPE_T::CIRCLE: saveCircle( shape, aFormatter, aNestLevel ); break; + case SHAPE_T::RECT: saveRectangle( shape, aFormatter, aNestLevel ); break; + case SHAPE_T::BEZIER: saveBezier( shape, aFormatter, aNestLevel ); break; + case SHAPE_T::POLY: savePolyLine( shape, aFormatter, aNestLevel ); break; + default: + UNIMPLEMENTED_FOR( shape->SHAPE_T_asString() ); + } - case LIB_CIRCLE_T: - saveCircle( ( LIB_CIRCLE* ) aItem, aFormatter, aNestLevel ); break; + } case LIB_PIN_T: savePin( (LIB_PIN* ) aItem, aFormatter, aNestLevel ); break; - case LIB_POLYLINE_T: - savePolyLine( ( LIB_POLYLINE* ) aItem, aFormatter, aNestLevel ); - break; - - case LIB_RECTANGLE_T: - saveRectangle( ( LIB_RECTANGLE* ) aItem, aFormatter, aNestLevel ); - break; - case LIB_TEXT_T: saveText( ( LIB_TEXT* ) aItem, aFormatter, aNestLevel ); break; default: - ; + UNIMPLEMENTED_FOR( aItem->GetClass() ); } } -void SCH_SEXPR_PLUGIN_CACHE::saveArc( LIB_ARC* aArc, OUTPUTFORMATTER& aFormatter, - int aNestLevel ) +void SCH_SEXPR_PLUGIN_CACHE::saveArc( LIB_SHAPE* aArc, OUTPUTFORMATTER& aFormatter, int aNestLevel ) { - wxCHECK_RET( aArc && aArc->Type() == LIB_ARC_T, "Invalid LIB_ARC object." ); - int x1; int x2; - aArc->CalcAngles( x1, x2 ); + aArc->CalcArcAngles( x1, x2 ); if( x1 > 1800 ) x1 -= 3600; @@ -1828,8 +1813,8 @@ void SCH_SEXPR_PLUGIN_CACHE::saveArc( LIB_ARC* aArc, OUTPUTFORMATTER& aFormatter FormatInternalUnits( aArc->GetStart().y ).c_str(), FormatInternalUnits( aArc->GetEnd().x ).c_str(), FormatInternalUnits( aArc->GetEnd().y ).c_str(), - FormatInternalUnits( aArc->GetPosition().x ).c_str(), - FormatInternalUnits( aArc->GetPosition().y ).c_str(), + FormatInternalUnits( aArc->GetCenter().x ).c_str(), + FormatInternalUnits( aArc->GetCenter().y ).c_str(), FormatInternalUnits( aArc->GetRadius() ).c_str(), static_cast( x1 ) / 10.0, static_cast( x2 ) / 10.0 ); @@ -1838,76 +1823,47 @@ void SCH_SEXPR_PLUGIN_CACHE::saveArc( LIB_ARC* aArc, OUTPUTFORMATTER& aFormatter aFormatter.Print( aNestLevel + 1, "(stroke (width %s)) ", FormatInternalUnits( aArc->GetWidth() ).c_str() ); - formatFill( static_cast< LIB_ITEM* >( aArc ), aFormatter, 0 ); + formatFill( aArc, aFormatter, 0 ); aFormatter.Print( 0, "\n" ); aFormatter.Print( aNestLevel, ")\n" ); } -void SCH_SEXPR_PLUGIN_CACHE::saveBezier( LIB_BEZIER* aBezier, - OUTPUTFORMATTER& aFormatter, +void SCH_SEXPR_PLUGIN_CACHE::saveBezier( LIB_SHAPE* aBezier, OUTPUTFORMATTER& aFormatter, int aNestLevel ) { - wxCHECK_RET( aBezier && aBezier->Type() == LIB_BEZIER_T, "Invalid LIB_BEZIER object." ); - - int newLine = 0; - int lineCount = 1; aFormatter.Print( aNestLevel, "(bezier\n" ); aFormatter.Print( aNestLevel + 1, "(pts " ); - for( const auto& pt : aBezier->GetPoints() ) + for( const wxPoint& pt : { aBezier->GetStart(), aBezier->GetBezierC1(), + aBezier->GetBezierC2(), aBezier->GetEnd() } ) { - if( newLine == 4 ) - { - aFormatter.Print( 0, "\n" ); - aFormatter.Print( aNestLevel + 3, " (xy %s %s)", - FormatInternalUnits( pt.x ).c_str(), - FormatInternalUnits( pt.y ).c_str() ); - newLine = 0; - lineCount += 1; - } - else - { - aFormatter.Print( 0, " (xy %s %s)", - FormatInternalUnits( pt.x ).c_str(), - FormatInternalUnits( pt.y ).c_str() ); - } - - newLine += 1; + aFormatter.Print( 0, " (xy %s %s)", + FormatInternalUnits( pt.x ).c_str(), + FormatInternalUnits( pt.y ).c_str() ); } - if( lineCount == 1 ) - { - aFormatter.Print( 0, ")\n" ); // Closes pts token on same line. - } - else - { - aFormatter.Print( 0, "\n" ); - aFormatter.Print( aNestLevel + 1, ")\n" ); // Closes pts token with multiple lines. - } + aFormatter.Print( 0, ")\n" ); // Closes pts token on same line. aFormatter.Print( aNestLevel + 1, "(stroke (width %s)) ", FormatInternalUnits( aBezier->GetWidth() ).c_str() ); - formatFill( static_cast< LIB_ITEM* >( aBezier ), aFormatter, 0 ); + formatFill( aBezier, aFormatter, 0 ); aFormatter.Print( 0, "\n" ); aFormatter.Print( aNestLevel, ")\n" ); } -void SCH_SEXPR_PLUGIN_CACHE::saveCircle( LIB_CIRCLE* aCircle, - OUTPUTFORMATTER& aFormatter, +void SCH_SEXPR_PLUGIN_CACHE::saveCircle( LIB_SHAPE* aCircle, OUTPUTFORMATTER& aFormatter, int aNestLevel ) { - wxCHECK_RET( aCircle && aCircle->Type() == LIB_CIRCLE_T, "Invalid LIB_CIRCLE object." ); - aFormatter.Print( aNestLevel, "(circle (center %s %s) (radius %s) (stroke (width %s)) ", FormatInternalUnits( aCircle->GetPosition().x ).c_str(), FormatInternalUnits( aCircle->GetPosition().y ).c_str(), FormatInternalUnits( aCircle->GetRadius() ).c_str(), FormatInternalUnits( aCircle->GetWidth() ).c_str() ); - formatFill( static_cast< LIB_ITEM* >( aCircle ), aFormatter, 0 ); + formatFill( aCircle, aFormatter, 0 ); aFormatter.Print( 0, ")\n" ); } @@ -1988,17 +1944,15 @@ void SCH_SEXPR_PLUGIN_CACHE::savePin( LIB_PIN* aPin, OUTPUTFORMATTER& aFormatter } -void SCH_SEXPR_PLUGIN_CACHE::savePolyLine( LIB_POLYLINE* aPolyLine, OUTPUTFORMATTER& aFormatter, +void SCH_SEXPR_PLUGIN_CACHE::savePolyLine( LIB_SHAPE* aPolyLine, OUTPUTFORMATTER& aFormatter, int aNestLevel ) { - wxCHECK_RET( aPolyLine && aPolyLine->Type() == LIB_POLYLINE_T, "Invalid LIB_POLYLINE object." ); - int newLine = 0; int lineCount = 1; aFormatter.Print( aNestLevel, "(polyline\n" ); aFormatter.Print( aNestLevel + 1, "(pts" ); - for( const auto& pt : aPolyLine->GetPolyPoints() ) + for( const VECTOR2I& pt : aPolyLine->GetPolyShape().Outline( 0 ).CPoints() ) { if( newLine == 4 || !ADVANCED_CFG::GetCfg().m_CompactSave ) { @@ -2031,26 +1985,23 @@ void SCH_SEXPR_PLUGIN_CACHE::savePolyLine( LIB_POLYLINE* aPolyLine, OUTPUTFORMAT aFormatter.Print( aNestLevel + 1, "(stroke (width %s)) ", FormatInternalUnits( aPolyLine->GetWidth() ).c_str() ); - formatFill( static_cast< LIB_ITEM* >( aPolyLine ), aFormatter, 0 ); + formatFill( aPolyLine, aFormatter, 0 ); aFormatter.Print( 0, "\n" ); aFormatter.Print( aNestLevel, ")\n" ); } -void SCH_SEXPR_PLUGIN_CACHE::saveRectangle( LIB_RECTANGLE* aRectangle, OUTPUTFORMATTER& aFormatter, +void SCH_SEXPR_PLUGIN_CACHE::saveRectangle( LIB_SHAPE* aRect, OUTPUTFORMATTER& aFormatter, int aNestLevel ) { - wxCHECK_RET( aRectangle && aRectangle->Type() == LIB_RECTANGLE_T, - "Invalid LIB_RECTANGLE object." ); - aFormatter.Print( aNestLevel, "(rectangle (start %s %s) (end %s %s)\n", - FormatInternalUnits( aRectangle->GetPosition().x ).c_str(), - FormatInternalUnits( aRectangle->GetPosition().y ).c_str(), - FormatInternalUnits( aRectangle->GetEnd().x ).c_str(), - FormatInternalUnits( aRectangle->GetEnd().y ).c_str() ); + FormatInternalUnits( aRect->GetPosition().x ).c_str(), + FormatInternalUnits( aRect->GetPosition().y ).c_str(), + FormatInternalUnits( aRect->GetEnd().x ).c_str(), + FormatInternalUnits( aRect->GetEnd().y ).c_str() ); aFormatter.Print( aNestLevel + 1, "(stroke (width %s)) ", - FormatInternalUnits( aRectangle->GetWidth() ).c_str() ); - formatFill( static_cast< LIB_ITEM* >( aRectangle ), aFormatter, 0 ); + FormatInternalUnits( aRect->GetWidth() ).c_str() ); + formatFill( aRect, aFormatter, 0 ); aFormatter.Print( 0, "\n" ); aFormatter.Print( aNestLevel, ")\n" ); } diff --git a/eeschema/sch_plugins/legacy/sch_legacy_plugin.cpp b/eeschema/sch_plugins/legacy/sch_legacy_plugin.cpp index bf4f4b6db1..af5cab5ce1 100644 --- a/eeschema/sch_plugins/legacy/sch_legacy_plugin.cpp +++ b/eeschema/sch_plugins/legacy/sch_legacy_plugin.cpp @@ -56,13 +56,9 @@ #include #include #include -#include -#include -#include +#include #include #include -#include -#include #include #include // for MAX_UNIT_COUNT_PER_PACKAGE definition #include @@ -482,40 +478,28 @@ class SCH_LEGACY_PLUGIN_CACHE int m_versionMinor; SCH_LIB_TYPE m_libType; // Is this cache a symbol or symbol library. - void loadHeader( FILE_LINE_READER& aReader ); - static void loadAliases( std::unique_ptr& aSymbol, LINE_READER& aReader, - LIB_SYMBOL_MAP* aMap = nullptr ); - static void loadField( std::unique_ptr& aSymbol, LINE_READER& aReader ); - static void loadDrawEntries( std::unique_ptr& aSymbol, - LINE_READER& aReader, - int aMajorVersion, int aMinorVersion ); - static void loadFootprintFilters( std::unique_ptr& aSymbol, - LINE_READER& aReader ); - void loadDocs(); - static LIB_ARC* loadArc( std::unique_ptr& aSymbol, LINE_READER& aReader ); - static LIB_CIRCLE* loadCircle( std::unique_ptr& aSymbol, LINE_READER& aReader ); - static LIB_TEXT* loadText( std::unique_ptr& aSymbol, LINE_READER& aReader, - int aMajorVersion, int aMinorVersion ); - static LIB_RECTANGLE* loadRectangle( std::unique_ptr& aSymbol, - LINE_READER& aReader ); - static LIB_PIN* loadPin( std::unique_ptr& aSymbol, LINE_READER& aReader ); - static LIB_POLYLINE* loadPolyLine( std::unique_ptr& aSymbol, - LINE_READER& aReader ); - static LIB_BEZIER* loadBezier( std::unique_ptr& aSymbol, LINE_READER& aReader ); + void loadHeader( FILE_LINE_READER& aReader ); + static void loadAliases( std::unique_ptr& aSymbol, LINE_READER& aReader, + LIB_SYMBOL_MAP* aMap = nullptr ); + static void loadField( std::unique_ptr& aSymbol, LINE_READER& aReader ); + static void loadDrawEntries( std::unique_ptr& aSymbol, LINE_READER& aReader, + int aMajorVersion, int aMinorVersion ); + static void loadFootprintFilters( std::unique_ptr& aSymbol, + LINE_READER& aReader ); + void loadDocs(); + static LIB_SHAPE* loadArc( std::unique_ptr& aSymbol, LINE_READER& aReader ); + static LIB_SHAPE* loadCircle( std::unique_ptr& aSymbol, LINE_READER& aReader ); + static LIB_TEXT* loadText( std::unique_ptr& aSymbol, LINE_READER& aReader, + int aMajorVersion, int aMinorVersion ); + static LIB_SHAPE* loadRect( std::unique_ptr& aSymbol, LINE_READER& aReader ); + static LIB_PIN* loadPin( std::unique_ptr& aSymbol, LINE_READER& aReader ); + static LIB_SHAPE* loadPolyLine( std::unique_ptr& aSymbol, LINE_READER& aReader ); + static LIB_SHAPE* loadBezier( std::unique_ptr& aSymbol, LINE_READER& aReader ); - static FILL_TYPE parseFillMode( LINE_READER& aReader, const char* aLine, - const char** aOutput ); - LIB_SYMBOL* removeSymbol( LIB_SYMBOL* aAlias ); + static FILL_T parseFillMode( LINE_READER& aReader, const char* aLine, const char** aOutput ); + LIB_SYMBOL* removeSymbol( LIB_SYMBOL* aAlias ); void saveDocFile(); - static void saveArc( LIB_ARC* aArc, OUTPUTFORMATTER& aFormatter ); - static void saveBezier( LIB_BEZIER* aBezier, OUTPUTFORMATTER& aFormatter ); - static void saveCircle( LIB_CIRCLE* aCircle, OUTPUTFORMATTER& aFormatter ); - static void saveField( const LIB_FIELD* aField, OUTPUTFORMATTER& aFormatter ); - static void savePin( const LIB_PIN* aPin, OUTPUTFORMATTER& aFormatter ); - static void savePolyLine( LIB_POLYLINE* aPolyLine, OUTPUTFORMATTER& aFormatter ); - static void saveRectangle( LIB_RECTANGLE* aRectangle, OUTPUTFORMATTER& aFormatter ); - static void saveText( const LIB_TEXT* aText, OUTPUTFORMATTER& aFormatter ); friend SCH_LEGACY_PLUGIN; @@ -3217,7 +3201,7 @@ void SCH_LEGACY_PLUGIN_CACHE::loadDrawEntries( std::unique_ptr& aSym break; case 'S': // Square - aSymbol->AddDrawItem( loadRectangle( aSymbol, aReader ), false ); + aSymbol->AddDrawItem( loadRect( aSymbol, aReader ), false ); break; case 'X': // Pin Description @@ -3249,30 +3233,30 @@ void SCH_LEGACY_PLUGIN_CACHE::loadDrawEntries( std::unique_ptr& aSym } -FILL_TYPE SCH_LEGACY_PLUGIN_CACHE::parseFillMode( LINE_READER& aReader, const char* aLine, +FILL_T SCH_LEGACY_PLUGIN_CACHE::parseFillMode( LINE_READER& aReader, const char* aLine, const char** aOutput ) { switch ( parseChar( aReader, aLine, aOutput ) ) { - case 'F': return FILL_TYPE::FILLED_SHAPE; - case 'f': return FILL_TYPE::FILLED_WITH_BG_BODYCOLOR; - case 'N': return FILL_TYPE::NO_FILL; + case 'F': return FILL_T::FILLED_SHAPE; + case 'f': return FILL_T::FILLED_WITH_BG_BODYCOLOR; + case 'N': return FILL_T::NO_FILL; default: SCH_PARSE_ERROR( "invalid fill type, expected f, F, or N", aReader, aLine ); } // This will never be reached but quiets the compiler warnings - return FILL_TYPE::NO_FILL; + return FILL_T::NO_FILL; } -LIB_ARC* SCH_LEGACY_PLUGIN_CACHE::loadArc( std::unique_ptr& aSymbol, - LINE_READER& aReader ) +LIB_SHAPE* SCH_LEGACY_PLUGIN_CACHE::loadArc( std::unique_ptr& aSymbol, + LINE_READER& aReader ) { const char* line = aReader.Line(); - wxCHECK_MSG( strCompare( "A", line, &line ), nullptr, "Invalid LIB_ARC definition" ); + wxCHECK_MSG( strCompare( "A", line, &line ), nullptr, "Invalid arc definition" ); - LIB_ARC* arc = new LIB_ARC( aSymbol.get() ); + LIB_SHAPE* arc = new LIB_SHAPE( aSymbol.get(), SHAPE_T::ARC ); wxPoint center; @@ -3343,22 +3327,24 @@ LIB_ARC* SCH_LEGACY_PLUGIN_CACHE::loadArc( std::unique_ptr& aSymbol, } -LIB_CIRCLE* SCH_LEGACY_PLUGIN_CACHE::loadCircle( std::unique_ptr& aSymbol, - LINE_READER& aReader ) +LIB_SHAPE* SCH_LEGACY_PLUGIN_CACHE::loadCircle( std::unique_ptr& aSymbol, + LINE_READER& aReader ) { const char* line = aReader.Line(); - wxCHECK_MSG( strCompare( "C", line, &line ), nullptr, "Invalid LIB_CIRCLE definition" ); + wxCHECK_MSG( strCompare( "C", line, &line ), nullptr, "Invalid circle definition" ); - LIB_CIRCLE* circle = new LIB_CIRCLE( aSymbol.get() ); + LIB_SHAPE* circle = new LIB_SHAPE( aSymbol.get(), SHAPE_T::CIRCLE ); wxPoint center; center.x = Mils2Iu( parseInt( aReader, line, &line ) ); center.y = Mils2Iu( parseInt( aReader, line, &line ) ); - circle->SetPosition( center ); - circle->SetRadius( Mils2Iu( parseInt( aReader, line, &line ) ) ); + int radius = Mils2Iu( parseInt( aReader, line, &line ) ); + + circle->SetStart( center ); + circle->SetEnd( wxPoint( center.x + radius, center.y ) ); circle->SetUnit( parseInt( aReader, line, &line ) ); circle->SetConvert( parseInt( aReader, line, &line ) ); circle->SetWidth( Mils2Iu( parseInt( aReader, line, &line ) ) ); @@ -3467,14 +3453,14 @@ LIB_TEXT* SCH_LEGACY_PLUGIN_CACHE::loadText( std::unique_ptr& aSymbo } -LIB_RECTANGLE* SCH_LEGACY_PLUGIN_CACHE::loadRectangle( std::unique_ptr& aSymbol, - LINE_READER& aReader ) +LIB_SHAPE* SCH_LEGACY_PLUGIN_CACHE::loadRect( std::unique_ptr& aSymbol, + LINE_READER& aReader ) { const char* line = aReader.Line(); - wxCHECK_MSG( strCompare( "S", line, &line ), nullptr, "Invalid LIB_RECTANGLE definition" ); + wxCHECK_MSG( strCompare( "S", line, &line ), nullptr, "Invalid rectangle definition" ); - LIB_RECTANGLE* rectangle = new LIB_RECTANGLE( aSymbol.get() ); + LIB_SHAPE* rectangle = new LIB_SHAPE( aSymbol.get(), SHAPE_T::RECT ); wxPoint pos; @@ -3698,20 +3684,19 @@ LIB_PIN* SCH_LEGACY_PLUGIN_CACHE::loadPin( std::unique_ptr& aSymbol, } -LIB_POLYLINE* SCH_LEGACY_PLUGIN_CACHE::loadPolyLine( std::unique_ptr& aSymbol, - LINE_READER& aReader ) +LIB_SHAPE* SCH_LEGACY_PLUGIN_CACHE::loadPolyLine( std::unique_ptr& aSymbol, + LINE_READER& aReader ) { const char* line = aReader.Line(); - wxCHECK_MSG( strCompare( "P", line, &line ), nullptr, "Invalid LIB_POLYLINE definition" ); + wxCHECK_MSG( strCompare( "P", line, &line ), nullptr, "Invalid poly definition" ); - LIB_POLYLINE* polyLine = new LIB_POLYLINE( aSymbol.get() ); + LIB_SHAPE* polyLine = new LIB_SHAPE( aSymbol.get(), SHAPE_T::POLY ); int points = parseInt( aReader, line, &line ); polyLine->SetUnit( parseInt( aReader, line, &line ) ); polyLine->SetConvert( parseInt( aReader, line, &line ) ); polyLine->SetWidth( Mils2Iu( parseInt( aReader, line, &line ) ) ); - polyLine->Reserve( points ); wxPoint pt; @@ -3729,29 +3714,36 @@ LIB_POLYLINE* SCH_LEGACY_PLUGIN_CACHE::loadPolyLine( std::unique_ptr } -LIB_BEZIER* SCH_LEGACY_PLUGIN_CACHE::loadBezier( std::unique_ptr& aSymbol, - LINE_READER& aReader ) +LIB_SHAPE* SCH_LEGACY_PLUGIN_CACHE::loadBezier( std::unique_ptr& aSymbol, + LINE_READER& aReader ) { const char* line = aReader.Line(); - wxCHECK_MSG( strCompare( "B", line, &line ), nullptr, "Invalid LIB_BEZIER definition" ); - - LIB_BEZIER* bezier = new LIB_BEZIER( aSymbol.get() ); + wxCHECK_MSG( strCompare( "B", line, &line ), nullptr, "Invalid Bezier definition" ); int points = parseInt( aReader, line, &line ); + + wxCHECK_MSG( points == 4, NULL, "Invalid Bezier curve definition" ); + + LIB_SHAPE* bezier = new LIB_SHAPE( aSymbol.get(), SHAPE_T::BEZIER ); + bezier->SetUnit( parseInt( aReader, line, &line ) ); bezier->SetConvert( parseInt( aReader, line, &line ) ); bezier->SetWidth( Mils2Iu( parseInt( aReader, line, &line ) ) ); - wxPoint pt; - bezier->Reserve( points ); + bezier->SetStart( wxPoint( Mils2Iu( parseInt( aReader, line, &line ) ), + Mils2Iu( parseInt( aReader, line, &line ) ) ) ); - for( int i = 0; i < points; i++ ) - { - pt.x = Mils2Iu( parseInt( aReader, line, &line ) ); - pt.y = Mils2Iu( parseInt( aReader, line, &line ) ); - bezier->AddPoint( pt ); - } + bezier->SetBezierC1( wxPoint( Mils2Iu( parseInt( aReader, line, &line ) ), + Mils2Iu( parseInt( aReader, line, &line ) ) ) ); + + bezier->SetBezierC2( wxPoint( Mils2Iu( parseInt( aReader, line, &line ) ), + Mils2Iu( parseInt( aReader, line, &line ) ) ) ); + + bezier->SetEnd( wxPoint( Mils2Iu( parseInt( aReader, line, &line ) ), + Mils2Iu( parseInt( aReader, line, &line ) ) ) ); + + bezier->RebuildBezierToSegmentsPointsList( bezier->GetWidth() ); if( *line != 0 ) bezier->SetFillMode( parseFillMode( aReader, line, &line ) ); @@ -3824,408 +3816,13 @@ void SCH_LEGACY_PLUGIN_CACHE::Save( bool aSaveDocFile ) void SCH_LEGACY_PLUGIN_CACHE::SaveSymbol( LIB_SYMBOL* aSymbol, OUTPUTFORMATTER& aFormatter, LIB_SYMBOL_MAP* aMap ) { - wxCHECK_RET( aSymbol && aSymbol->IsRoot(), "Invalid LIB_SYMBOL pointer." ); - - // LIB_ALIAS objects are deprecated but we still need to gather up the derived symbols - // and save their names for the old file format. - wxArrayString aliasNames; - - if( aMap ) - { - for( auto entry : *aMap ) - { - LIB_SYMBOL* symbol = entry.second; - - if( symbol->IsAlias() && symbol->GetParent().lock() == aSymbol->SharedPtr() ) - aliasNames.Add( symbol->GetName() ); - } - } - - LIB_FIELD& value = aSymbol->GetValueField(); - - // First line: it s a comment (symbol name for readers) - aFormatter.Print( 0, "#\n# %s\n#\n", TO_UTF8( value.GetText() ) ); - - // Save data - aFormatter.Print( 0, "DEF" ); - aFormatter.Print( 0, " %s", TO_UTF8( value.GetText() ) ); - - LIB_FIELD& reference = aSymbol->GetReferenceField(); - - if( !reference.GetText().IsEmpty() ) - { - aFormatter.Print( 0, " %s", TO_UTF8( reference.GetText() ) ); - } - else - { - aFormatter.Print( 0, " ~" ); - } - - aFormatter.Print( 0, " %d %d %c %c %d %c %c\n", - 0, Iu2Mils( aSymbol->GetPinNameOffset() ), - aSymbol->ShowPinNumbers() ? 'Y' : 'N', - aSymbol->ShowPinNames() ? 'Y' : 'N', - aSymbol->GetUnitCount(), aSymbol->UnitsLocked() ? 'L' : 'F', - aSymbol->IsPower() ? 'P' : 'N' ); - - timestamp_t dateModified = aSymbol->GetLastModDate(); - - if( dateModified != 0 ) - { - int sec = dateModified & 63; - int min = ( dateModified >> 6 ) & 63; - int hour = ( dateModified >> 12 ) & 31; - int day = ( dateModified >> 17 ) & 31; - int mon = ( dateModified >> 22 ) & 15; - int year = ( dateModified >> 26 ) + 1990; - - aFormatter.Print( 0, "Ti %d/%d/%d %d:%d:%d\n", year, mon, day, hour, min, sec ); - } - - std::vector fields; - aSymbol->GetFields( fields ); - - // Mandatory fields: - // may have their own save policy so there is a separate loop for them. - // Empty fields are saved, because the user may have set visibility, - // size and orientation - for( int i = 0; i < MANDATORY_FIELDS; ++i ) - saveField( fields[i], aFormatter ); - - // User defined fields: - // may have their own save policy so there is a separate loop for them. - int fieldId = MANDATORY_FIELDS; // really wish this would go away. - - for( unsigned i = MANDATORY_FIELDS; i < fields.size(); ++i ) - { - // There is no need to save empty fields, i.e. no reason to preserve field - // names now that fields names come in dynamically through the template - // fieldnames. - if( !fields[i]->GetText().IsEmpty() ) - { - fields[i]->SetId( fieldId++ ); - saveField( fields[i], aFormatter ); - } - } - - // Save the alias list: a line starting by "ALIAS". - if( !aliasNames.IsEmpty() ) - { - aFormatter.Print( 0, "ALIAS" ); - - for( unsigned i = 0; i < aliasNames.GetCount(); i++ ) - aFormatter.Print( 0, " %s", TO_UTF8( aliasNames[i] ) ); - - aFormatter.Print( 0, "\n" ); - } - - wxArrayString footprints = aSymbol->GetFPFilters(); - - // Write the footprint filter list - if( footprints.GetCount() != 0 ) - { - aFormatter.Print( 0, "$FPLIST\n" ); - - for( unsigned i = 0; i < footprints.GetCount(); i++ ) - aFormatter.Print( 0, " %s\n", TO_UTF8( footprints[i] ) ); - - aFormatter.Print( 0, "$ENDFPLIST\n" ); - } - - // Save graphics items (including pins) - if( !aSymbol->GetDrawItems().empty() ) - { - // Sort the draw items in order to editing a file editing by hand. - aSymbol->GetDrawItems().sort(); - - aFormatter.Print( 0, "DRAW\n" ); - - for( LIB_ITEM& item : aSymbol->GetDrawItems() ) - { - switch( item.Type() ) - { - default: - case LIB_FIELD_T: /* Fields have already been saved above. */ break; - case LIB_ARC_T: saveArc( (LIB_ARC*) &item, aFormatter ); break; - case LIB_BEZIER_T: saveBezier( (LIB_BEZIER*) &item, aFormatter ); break; - case LIB_CIRCLE_T: saveCircle( ( LIB_CIRCLE* ) &item, aFormatter ); break; - case LIB_PIN_T: savePin( (LIB_PIN* ) &item, aFormatter ); break; - case LIB_POLYLINE_T: savePolyLine( ( LIB_POLYLINE* ) &item, aFormatter ); break; - case LIB_RECTANGLE_T: saveRectangle( ( LIB_RECTANGLE* ) &item, aFormatter ); break; - case LIB_TEXT_T: saveText( ( LIB_TEXT* ) &item, aFormatter ); break; - } - } - - aFormatter.Print( 0, "ENDDRAW\n" ); - } - - aFormatter.Print( 0, "ENDDEF\n" ); -} - - -void SCH_LEGACY_PLUGIN_CACHE::saveArc( LIB_ARC* aArc, OUTPUTFORMATTER& aFormatter ) -{ - wxCHECK_RET( aArc && aArc->Type() == LIB_ARC_T, "Invalid LIB_ARC object." ); - - int x1; - int x2; - - aArc->CalcAngles( x1, x2 ); - - if( x1 > 1800 ) - x1 -= 3600; - - if( x2 > 1800 ) - x2 -= 3600; - - aFormatter.Print( 0, "A %d %d %d %d %d %d %d %d %c %d %d %d %d\n", - Iu2Mils( aArc->GetPosition().x ), Iu2Mils( aArc->GetPosition().y ), - Iu2Mils( aArc->GetRadius() ), x1, x2, aArc->GetUnit(), aArc->GetConvert(), - Iu2Mils( aArc->GetWidth() ), fill_tab[ (int) aArc->GetFillMode() ], - Iu2Mils( aArc->GetStart().x ), Iu2Mils( aArc->GetStart().y ), - Iu2Mils( aArc->GetEnd().x ), Iu2Mils( aArc->GetEnd().y ) ); -} - - -void SCH_LEGACY_PLUGIN_CACHE::saveBezier( LIB_BEZIER* aBezier, OUTPUTFORMATTER& aFormatter ) -{ - wxCHECK_RET( aBezier && aBezier->Type() == LIB_BEZIER_T, "Invalid LIB_BEZIER object." ); - - aFormatter.Print( 0, "B %u %d %d %d", (unsigned)aBezier->GetPoints().size(), - aBezier->GetUnit(), aBezier->GetConvert(), Iu2Mils( aBezier->GetWidth() ) ); - - for( const wxPoint& pt : aBezier->GetPoints() ) - aFormatter.Print( 0, " %d %d", Iu2Mils( pt.x ), Iu2Mils( pt.y ) ); - - aFormatter.Print( 0, " %c\n", fill_tab[static_cast( aBezier->GetFillMode() )] ); -} - - -void SCH_LEGACY_PLUGIN_CACHE::saveCircle( LIB_CIRCLE* aCircle, OUTPUTFORMATTER& aFormatter ) -{ - wxCHECK_RET( aCircle && aCircle->Type() == LIB_CIRCLE_T, "Invalid LIB_CIRCLE object." ); - - aFormatter.Print( 0, "C %d %d %d %d %d %d %c\n", - Iu2Mils( aCircle->GetPosition().x ), Iu2Mils( aCircle->GetPosition().y ), - Iu2Mils( aCircle->GetRadius() ), aCircle->GetUnit(), aCircle->GetConvert(), - Iu2Mils( aCircle->GetWidth() ), - fill_tab[static_cast( aCircle->GetFillMode() )] ); -} - - -void SCH_LEGACY_PLUGIN_CACHE::saveField( const LIB_FIELD* aField, OUTPUTFORMATTER& aFormatter ) -{ - wxCHECK_RET( aField && aField->Type() == LIB_FIELD_T, "Invalid LIB_FIELD object." ); - - int hjustify, vjustify; - int id = aField->GetId(); - wxString text = aField->GetText(); - - hjustify = 'C'; - - if( aField->GetHorizJustify() == GR_TEXT_HJUSTIFY_LEFT ) - hjustify = 'L'; - else if( aField->GetHorizJustify() == GR_TEXT_HJUSTIFY_RIGHT ) - hjustify = 'R'; - - vjustify = 'C'; - - if( aField->GetVertJustify() == GR_TEXT_VJUSTIFY_BOTTOM ) - vjustify = 'B'; - else if( aField->GetVertJustify() == GR_TEXT_VJUSTIFY_TOP ) - vjustify = 'T'; - - aFormatter.Print( 0, "F%d %s %d %d %d %c %c %c %c%c%c", - id, - EscapedUTF8( text ).c_str(), // wraps in quotes - Iu2Mils( aField->GetTextPos().x ), Iu2Mils( aField->GetTextPos().y ), - Iu2Mils( aField->GetTextWidth() ), - aField->GetTextAngle() == 0 ? 'H' : 'V', - aField->IsVisible() ? 'V' : 'I', - hjustify, vjustify, - aField->IsItalic() ? 'I' : 'N', - aField->IsBold() ? 'B' : 'N' ); - - /* Save field name, if necessary - * Field name is saved only if it is not the default name. - * Just because default name depends on the language and can change from - * a country to another - */ - wxString defName = TEMPLATE_FIELDNAME::GetDefaultFieldName( id ); - - if( id >= MANDATORY_FIELDS && !aField->m_name.IsEmpty() && aField->m_name != defName ) - aFormatter.Print( 0, " %s", EscapedUTF8( aField->m_name ).c_str() ); - - aFormatter.Print( 0, "\n" ); -} - - -void SCH_LEGACY_PLUGIN_CACHE::savePin( const LIB_PIN* aPin, OUTPUTFORMATTER& aFormatter ) -{ - wxCHECK_RET( aPin && aPin->Type() == LIB_PIN_T, "Invalid LIB_PIN object." ); - - int Etype; - - switch( aPin->GetType() ) - { - default: - case ELECTRICAL_PINTYPE::PT_INPUT: Etype = 'I'; break; - case ELECTRICAL_PINTYPE::PT_OUTPUT: Etype = 'O'; break; - case ELECTRICAL_PINTYPE::PT_BIDI: Etype = 'B'; break; - case ELECTRICAL_PINTYPE::PT_TRISTATE: Etype = 'T'; break; - case ELECTRICAL_PINTYPE::PT_PASSIVE: Etype = 'P'; break; - case ELECTRICAL_PINTYPE::PT_UNSPECIFIED: Etype = 'U'; break; - case ELECTRICAL_PINTYPE::PT_POWER_IN: Etype = 'W'; break; - case ELECTRICAL_PINTYPE::PT_POWER_OUT: Etype = 'w'; break; - case ELECTRICAL_PINTYPE::PT_OPENCOLLECTOR: Etype = 'C'; break; - case ELECTRICAL_PINTYPE::PT_OPENEMITTER: Etype = 'E'; break; - case ELECTRICAL_PINTYPE::PT_NC: Etype = 'N'; break; - } - - if( !aPin->GetName().IsEmpty() ) - aFormatter.Print( 0, "X %s", TO_UTF8( aPin->GetName() ) ); - else - aFormatter.Print( 0, "X ~" ); - - aFormatter.Print( 0, " %s %d %d %d %c %d %d %d %d %c", - aPin->GetNumber().IsEmpty() ? "~" : TO_UTF8( aPin->GetNumber() ), - Iu2Mils( aPin->GetPosition().x ), Iu2Mils( aPin->GetPosition().y ), - Iu2Mils( (int) aPin->GetLength() ), (int) aPin->GetOrientation(), - Iu2Mils( aPin->GetNumberTextSize() ), Iu2Mils( aPin->GetNameTextSize() ), - aPin->GetUnit(), aPin->GetConvert(), Etype ); - - if( aPin->GetShape() != GRAPHIC_PINSHAPE::LINE || !aPin->IsVisible() ) - aFormatter.Print( 0, " " ); - - if( !aPin->IsVisible() ) - aFormatter.Print( 0, "N" ); - - switch( aPin->GetShape() ) - { - case GRAPHIC_PINSHAPE::LINE: break; - case GRAPHIC_PINSHAPE::INVERTED: aFormatter.Print( 0, "I" ); break; - case GRAPHIC_PINSHAPE::CLOCK: aFormatter.Print( 0, "C" ); break; - case GRAPHIC_PINSHAPE::INVERTED_CLOCK: aFormatter.Print( 0, "IC" ); break; - case GRAPHIC_PINSHAPE::INPUT_LOW: aFormatter.Print( 0, "L" ); break; - case GRAPHIC_PINSHAPE::CLOCK_LOW: aFormatter.Print( 0, "CL" ); break; - case GRAPHIC_PINSHAPE::OUTPUT_LOW: aFormatter.Print( 0, "V" ); break; - case GRAPHIC_PINSHAPE::FALLING_EDGE_CLOCK: aFormatter.Print( 0, "F" ); break; - case GRAPHIC_PINSHAPE::NONLOGIC: aFormatter.Print( 0, "X" ); break; - default: wxFAIL_MSG( "Invalid pin shape" ); - } - - aFormatter.Print( 0, "\n" ); - - const_cast( aPin )->ClearFlags( IS_CHANGED ); -} - - -void SCH_LEGACY_PLUGIN_CACHE::savePolyLine( LIB_POLYLINE* aPolyLine, - OUTPUTFORMATTER& aFormatter ) -{ - wxCHECK_RET( aPolyLine && aPolyLine->Type() == LIB_POLYLINE_T, "Invalid LIB_POLYLINE object." ); - - int ccount = aPolyLine->GetCornerCount(); - - aFormatter.Print( 0, "P %d %d %d %d", ccount, aPolyLine->GetUnit(), aPolyLine->GetConvert(), - Iu2Mils( aPolyLine->GetWidth() ) ); - - for( const auto& pt : aPolyLine->GetPolyPoints() ) - { - aFormatter.Print( 0, " %d %d", Iu2Mils( pt.x ), Iu2Mils( pt.y ) ); - } - - aFormatter.Print( 0, " %c\n", fill_tab[static_cast( aPolyLine->GetFillMode() )] ); -} - - -void SCH_LEGACY_PLUGIN_CACHE::saveRectangle( LIB_RECTANGLE* aRectangle, - OUTPUTFORMATTER& aFormatter ) -{ - wxCHECK_RET( aRectangle && aRectangle->Type() == LIB_RECTANGLE_T, - "Invalid LIB_RECTANGLE object." ); - - aFormatter.Print( 0, "S %d %d %d %d %d %d %d %c\n", - Iu2Mils( aRectangle->GetPosition().x ), - Iu2Mils( aRectangle->GetPosition().y ), - Iu2Mils( aRectangle->GetEnd().x ), Iu2Mils( aRectangle->GetEnd().y ), - aRectangle->GetUnit(), aRectangle->GetConvert(), - Iu2Mils( aRectangle->GetWidth() ), - fill_tab[static_cast( aRectangle->GetFillMode() )] ); -} - - -void SCH_LEGACY_PLUGIN_CACHE::saveText( const LIB_TEXT* aText, OUTPUTFORMATTER& aFormatter ) -{ - wxCHECK_RET( aText && aText->Type() == LIB_TEXT_T, "Invalid LIB_TEXT object." ); - - wxString text = aText->GetText(); - - if( text.Contains( wxT( " " ) ) || text.Contains( wxT( "~" ) ) || text.Contains( wxT( "\"" ) ) ) - { - // convert double quote to similar-looking two apostrophes - text.Replace( wxT( "\"" ), wxT( "''" ) ); - text = wxT( "\"" ) + text + wxT( "\"" ); - } - - aFormatter.Print( 0, "T %g %d %d %d %d %d %d %s", aText->GetTextAngle(), - Iu2Mils( aText->GetTextPos().x ), Iu2Mils( aText->GetTextPos().y ), - Iu2Mils( aText->GetTextWidth() ), !aText->IsVisible(), - aText->GetUnit(), aText->GetConvert(), TO_UTF8( text ) ); - - aFormatter.Print( 0, " %s %d", aText->IsItalic() ? "Italic" : "Normal", aText->IsBold() ); - - char hjustify = 'C'; - - if( aText->GetHorizJustify() == GR_TEXT_HJUSTIFY_LEFT ) - hjustify = 'L'; - else if( aText->GetHorizJustify() == GR_TEXT_HJUSTIFY_RIGHT ) - hjustify = 'R'; - - char vjustify = 'C'; - - if( aText->GetVertJustify() == GR_TEXT_VJUSTIFY_BOTTOM ) - vjustify = 'B'; - else if( aText->GetVertJustify() == GR_TEXT_VJUSTIFY_TOP ) - vjustify = 'T'; - - aFormatter.Print( 0, " %c %c\n", hjustify, vjustify ); + wxFAIL_MSG( "Writing of legacy format no longer supported." ); } void SCH_LEGACY_PLUGIN_CACHE::saveDocFile() { - wxFileName fileName = m_libFileName; - - fileName.SetExt( DOC_EXT ); - FILE_OUTPUTFORMATTER formatter( fileName.GetFullPath() ); - - formatter.Print( 0, "%s\n", DOCFILE_IDENT ); - - for( LIB_SYMBOL_MAP::iterator it = m_symbols.begin(); it != m_symbols.end(); ++it ) - { - wxString description = it->second->GetDescription(); - wxString keyWords = it->second->GetKeyWords(); - wxString docFileName = it->second->GetDatasheetField().GetText(); - - if( description.IsEmpty() && keyWords.IsEmpty() && docFileName.IsEmpty() ) - continue; - - formatter.Print( 0, "#\n$CMP %s\n", TO_UTF8( it->second->GetName() ) ); - - if( !description.IsEmpty() ) - formatter.Print( 0, "D %s\n", TO_UTF8( description ) ); - - if( !keyWords.IsEmpty() ) - formatter.Print( 0, "K %s\n", TO_UTF8( keyWords ) ); - - if( !docFileName.IsEmpty() ) - formatter.Print( 0, "F %s\n", TO_UTF8( docFileName ) ); - - formatter.Print( 0, "$ENDCMP\n" ); - } - - formatter.Print( 0, "#\n#End Doc Library\n" ); + wxFAIL_MSG( "Writing of legacy format no longer supported." ); } diff --git a/eeschema/sch_sheet.cpp b/eeschema/sch_sheet.cpp index 26acb1f5c3..281ac69222 100644 --- a/eeschema/sch_sheet.cpp +++ b/eeschema/sch_sheet.cpp @@ -985,13 +985,13 @@ void SCH_SHEET::Plot( PLOTTER* aPlotter ) const if( fill ) { aPlotter->SetColor( backgroundColor ); - aPlotter->Rect( m_pos, m_pos + m_size, FILL_TYPE::FILLED_SHAPE, 1 ); + aPlotter->Rect( m_pos, m_pos + m_size, FILL_T::FILLED_SHAPE, 1 ); } aPlotter->SetColor( borderColor ); int penWidth = std::max( GetPenWidth(), aPlotter->RenderSettings()->GetMinPenWidth() ); - aPlotter->Rect( m_pos, m_pos + m_size, FILL_TYPE::NO_FILL, penWidth ); + aPlotter->Rect( m_pos, m_pos + m_size, FILL_T::NO_FILL, penWidth ); // Plot sheet pins for( SCH_SHEET_PIN* sheetPin : m_pins ) diff --git a/eeschema/sch_symbol.cpp b/eeschema/sch_symbol.cpp index d51d66b61b..799c4105c7 100644 --- a/eeschema/sch_symbol.cpp +++ b/eeschema/sch_symbol.cpp @@ -26,9 +26,9 @@ #include #include #include -#include #include #include +#include #include #include #include @@ -77,10 +77,10 @@ static LIB_SYMBOL* dummy() { symbol = new LIB_SYMBOL( wxEmptyString ); - LIB_RECTANGLE* square = new LIB_RECTANGLE( symbol ); + LIB_SHAPE* square = new LIB_SHAPE( symbol, SHAPE_T::RECT ); square->MoveTo( wxPoint( Mils2iu( -200 ), Mils2iu( 200 ) ) ); - square->SetEndPosition( wxPoint( Mils2iu( 200 ), Mils2iu( -200 ) ) ); + square->SetEnd( wxPoint( Mils2iu( 200 ), Mils2iu( -200 ) ) ); LIB_TEXT* text = new LIB_TEXT( symbol ); diff --git a/eeschema/sch_text.cpp b/eeschema/sch_text.cpp index 61bee381d6..61b24795bf 100644 --- a/eeschema/sch_text.cpp +++ b/eeschema/sch_text.cpp @@ -732,7 +732,7 @@ void SCH_TEXT::Plot( PLOTTER* aPlotter ) const CreateGraphicShape( aPlotter->RenderSettings(), s_poly, GetTextPos() ); if( s_poly.size() ) - aPlotter->PlotPoly( s_poly, FILL_TYPE::NO_FILL, penWidth ); + aPlotter->PlotPoly( s_poly, FILL_T::NO_FILL, penWidth ); } diff --git a/eeschema/tools/ee_actions.cpp b/eeschema/tools/ee_actions.cpp index c2009d5fcf..0921e02850 100644 --- a/eeschema/tools/ee_actions.cpp +++ b/eeschema/tools/ee_actions.cpp @@ -228,22 +228,22 @@ TOOL_ACTION EE_ACTIONS::placeSymbolText( "eeschema.SymbolDrawing.placeSymbolText TOOL_ACTION EE_ACTIONS::drawSymbolRectangle( "eeschema.SymbolDrawing.drawSymbolRectangle", AS_GLOBAL, 0, "", _( "Add Rectangle" ), _( "Add a rectangle" ), - BITMAPS::add_rectangle, AF_ACTIVATE, (void*) LIB_RECTANGLE_T ); + BITMAPS::add_rectangle, AF_ACTIVATE, (void*) SHAPE_T::RECT ); TOOL_ACTION EE_ACTIONS::drawSymbolCircle( "eeschema.SymbolDrawing.drawSymbolCircle", AS_GLOBAL, 0, "", _( "Add Circle" ), _( "Add a circle" ), - BITMAPS::add_circle, AF_ACTIVATE, (void*) LIB_CIRCLE_T ); + BITMAPS::add_circle, AF_ACTIVATE, (void*) SHAPE_T::CIRCLE ); TOOL_ACTION EE_ACTIONS::drawSymbolArc( "eeschema.SymbolDrawing.drawSymbolArc", AS_GLOBAL, 0, "", _( "Add Arc" ), _( "Add an arc" ), - BITMAPS::add_arc, AF_ACTIVATE, (void*) LIB_ARC_T ); + BITMAPS::add_arc, AF_ACTIVATE, (void*) SHAPE_T::ARC ); TOOL_ACTION EE_ACTIONS::drawSymbolLines( "eeschema.SymbolDrawing.drawSymbolLines", AS_GLOBAL, 0, "", _( "Add Lines" ), _( "Add connected graphic lines" ), - BITMAPS::add_graphical_segments, AF_ACTIVATE, (void*) LIB_POLYLINE_T ); + BITMAPS::add_graphical_segments, AF_ACTIVATE, (void*) SHAPE_T::POLY ); TOOL_ACTION EE_ACTIONS::placeSymbolAnchor( "eeschema.SymbolDrawing.placeSymbolAnchor", AS_GLOBAL, 0, "", diff --git a/eeschema/tools/ee_point_editor.cpp b/eeschema/tools/ee_point_editor.cpp index 1e65b449b0..4fa00f7065 100644 --- a/eeschema/tools/ee_point_editor.cpp +++ b/eeschema/tools/ee_point_editor.cpp @@ -38,10 +38,7 @@ using namespace std::placeholders; #include #include #include -#include -#include -#include -#include +#include // Few constants to avoid using bare numbers for point indices @@ -78,52 +75,59 @@ public: // Generate list of edit points based on the item type switch( aItem->Type() ) { - case LIB_ARC_T: + case LIB_SHAPE_T: { - LIB_ARC* arc = (LIB_ARC*) aItem; + LIB_SHAPE* shape = static_cast( aItem ); - points->AddPoint( mapCoords( arc->GetPosition() ) ); - points->AddPoint( mapCoords( arc->GetStart() ) ); - points->AddPoint( mapCoords( arc->GetEnd() ) ); - break; + switch( shape->GetShape() ) + { + case SHAPE_T::ARC: + points->AddPoint( mapCoords( shape->GetPosition() ) ); + points->AddPoint( mapCoords( shape->GetStart() ) ); + points->AddPoint( mapCoords( shape->GetEnd() ) ); + break; + + case SHAPE_T::CIRCLE: + points->AddPoint( mapCoords( shape->GetPosition() ) ); + points->AddPoint( mapCoords( shape->GetEnd() ) ); + break; + + case SHAPE_T::RECT: + { + // point editor works only with rectangles having width and height > 0 + // Some symbols can have rectangles with width or height < 0 + // So normalize the size: + BOX2I dummy; + dummy.SetOrigin( mapCoords( shape->GetPosition() ) ); + dummy.SetEnd( mapCoords( shape->GetEnd() ) ); + dummy.Normalize(); + VECTOR2I topLeft = dummy.GetPosition(); + VECTOR2I botRight = dummy.GetEnd(); + + points->AddPoint( topLeft ); + points->AddPoint( VECTOR2I( botRight.x, topLeft.y ) ); + points->AddPoint( VECTOR2I( topLeft.x, botRight.y ) ); + points->AddPoint( botRight ); + } + break; + + case SHAPE_T::POLY: + for( const VECTOR2I& pt : shape->GetPolyShape().Outline( 0 ).CPoints() ) + points->AddPoint( mapCoords( pt ) ); + + break; + + case SHAPE_T::BEZIER: + // TODO + break; + + default: + wxFAIL_MSG( "EDIT_POINTS_FACTORY::Make not implemented for " + + shape->SHAPE_T_asString() ); + } } - case LIB_CIRCLE_T: - { - LIB_CIRCLE* circle = (LIB_CIRCLE*) aItem; - - points->AddPoint( mapCoords( circle->GetPosition() ) ); - points->AddPoint( mapCoords( circle->GetEnd() ) ); break; - } - case LIB_POLYLINE_T: - { - LIB_POLYLINE* lines = (LIB_POLYLINE*) aItem; - const std::vector& pts = lines->GetPolyPoints(); - for( wxPoint pt : pts ) - points->AddPoint( mapCoords( pt ) ); - - break; - } - case LIB_RECTANGLE_T: - { - LIB_RECTANGLE* rect = (LIB_RECTANGLE*) aItem; - // point editor works only with rectangles having width and height > 0 - // Some symbols can have rectangles with width or height < 0 - // So normalize the size: - BOX2I dummy; - dummy.SetOrigin( mapCoords( rect->GetPosition() ) ); - dummy.SetEnd( mapCoords( rect->GetEnd() ) ); - dummy.Normalize(); - VECTOR2I topLeft = dummy.GetPosition(); - VECTOR2I botRight = dummy.GetEnd(); - - points->AddPoint( topLeft ); - points->AddPoint( VECTOR2I( botRight.x, topLeft.y ) ); - points->AddPoint( VECTOR2I( topLeft.x, botRight.y ) ); - points->AddPoint( botRight ); - break; - } case SCH_SHEET_T: { SCH_SHEET* sheet = (SCH_SHEET*) aItem; @@ -134,8 +138,9 @@ public: points->AddPoint( wxPoint( botRight.x, topLeft.y ) ); points->AddPoint( wxPoint( topLeft.x, botRight.y ) ); points->AddPoint( (wxPoint) botRight ); - break; } + break; + case SCH_BITMAP_T: { SCH_BITMAP* bitmap = (SCH_BITMAP*) aItem; @@ -146,8 +151,9 @@ public: points->AddPoint( wxPoint( botRight.x, topLeft.y ) ); points->AddPoint( wxPoint( topLeft.x, botRight.y ) ); points->AddPoint( (wxPoint) botRight ); - break; } + break; + case SCH_LINE_T: { SCH_LINE* line = (SCH_LINE*) aItem; @@ -182,11 +188,11 @@ public: } } - points->AddPoint( line->GetStartPoint(), connectedStart ); points->AddPoint( line->GetEndPoint(), connectedEnd ); - break; } + break; + default: points.reset(); break; @@ -267,10 +273,7 @@ void EE_POINT_EDITOR::updateEditedPoint( const TOOL_EVENT& aEvent ) int EE_POINT_EDITOR::Main( const TOOL_EVENT& aEvent ) { static KICAD_T supportedTypes[] = { - LIB_ARC_T, - LIB_CIRCLE_T, - LIB_POLYLINE_T, - LIB_RECTANGLE_T, + LIB_SHAPE_T, SCH_SHEET_T, SCH_LINE_LOCATE_GRAPHIC_LINE_T, SCH_BITMAP_T, @@ -325,8 +328,12 @@ int EE_POINT_EDITOR::Main( const TOOL_EVENT& aEvent ) bool snap = !evt->DisableGridSnapping(); - if( item->Type() == LIB_ARC_T && getEditedPointIndex() == ARC_CENTER ) + if( item->Type() == LIB_SHAPE_T + && static_cast( item )->GetShape() == SHAPE_T::ARC + && getEditedPointIndex() == ARC_CENTER ) + { snap = false; + } m_editedPoint->SetPosition( controls->GetCursorPosition( snap ) ); @@ -481,66 +488,69 @@ void EE_POINT_EDITOR::updateParentItem() const switch( item->Type() ) { - case LIB_ARC_T: + case LIB_SHAPE_T: { - LIB_ARC* arc = (LIB_ARC*) item; - int i = getEditedPointIndex(); + LIB_SHAPE* shape = static_cast( item ); - if( i == ARC_CENTER ) + switch( shape->GetShape() ) { - arc->SetEditState( 4 ); - arc->CalcEdit( mapCoords( m_editPoints->Point( ARC_CENTER ).GetPosition() ) ); - } - else if( i == ARC_START ) + case SHAPE_T::ARC: + if( getEditedPointIndex() == ARC_CENTER ) + { + shape->SetEditState( 4 ); + shape->CalcEdit( mapCoords( m_editPoints->Point( ARC_CENTER ).GetPosition() ) ); + } + else if( getEditedPointIndex() == ARC_START ) + { + shape->SetEditState( 2 ); + shape->CalcEdit( mapCoords( m_editPoints->Point( ARC_START ).GetPosition() ) ); + } + else if( getEditedPointIndex() == ARC_END ) + { + shape->SetEditState( 3 ); + shape->CalcEdit( mapCoords( m_editPoints->Point( ARC_END ).GetPosition() ) ); + } + break; + + case SHAPE_T::CIRCLE: + shape->SetPosition( mapCoords( m_editPoints->Point( CIRC_CENTER ).GetPosition() ) ); + shape->SetEnd( mapCoords( m_editPoints->Point( CIRC_END ).GetPosition() ) ); + break; + + case SHAPE_T::POLY: + shape->GetPolyShape().RemoveAllContours(); + shape->GetPolyShape().NewOutline(); + + for( unsigned i = 0; i < m_editPoints->PointsSize(); ++i ) + shape->GetPolyShape().Append( mapCoords( m_editPoints->Point( i ).GetPosition() ) ); + + break; + + case SHAPE_T::RECT: { - arc->SetEditState( 2 ); - arc->CalcEdit( mapCoords( m_editPoints->Point( ARC_START ).GetPosition() ) ); + VECTOR2I topLeft = m_editPoints->Point( RECT_TOPLEFT ).GetPosition(); + VECTOR2I topRight = m_editPoints->Point( RECT_TOPRIGHT ).GetPosition(); + VECTOR2I botLeft = m_editPoints->Point( RECT_BOTLEFT ).GetPosition(); + VECTOR2I botRight = m_editPoints->Point( RECT_BOTRIGHT ).GetPosition(); + + pinEditedCorner( getEditedPointIndex(), Mils2iu( 1 ), Mils2iu( 1 ), + topLeft, topRight, botLeft, botRight ); + + shape->SetPosition( mapCoords( topLeft ) ); + shape->SetEnd( mapCoords( botRight ) ); } - else if( i == ARC_END ) - { - arc->SetEditState( 3 ); - arc->CalcEdit( mapCoords( m_editPoints->Point( ARC_END ).GetPosition() ) ); + break; + + case SHAPE_T::BEZIER: + // TODO + break; + + default: + wxFAIL_MSG( "EE_POINT_EDITOR::updateParentItem not implemented for " + + shape->SHAPE_T_asString() ); } - - break; } - - case LIB_CIRCLE_T: - { - LIB_CIRCLE* circle = (LIB_CIRCLE*) item; - - circle->SetPosition( mapCoords( m_editPoints->Point( CIRC_CENTER ).GetPosition() ) ); - circle->SetEnd( mapCoords( m_editPoints->Point( CIRC_END ).GetPosition() ) ); break; - } - - case LIB_POLYLINE_T: - { - LIB_POLYLINE* lines = (LIB_POLYLINE*) item; - - lines->ClearPoints(); - - for( unsigned i = 0; i < m_editPoints->PointsSize(); ++i ) - lines->AddPoint( mapCoords( m_editPoints->Point( i ).GetPosition() ) ); - - break; - } - - case LIB_RECTANGLE_T: - { - VECTOR2I topLeft = m_editPoints->Point( RECT_TOPLEFT ).GetPosition(); - VECTOR2I topRight = m_editPoints->Point( RECT_TOPRIGHT ).GetPosition(); - VECTOR2I botLeft = m_editPoints->Point( RECT_BOTLEFT ).GetPosition(); - VECTOR2I botRight = m_editPoints->Point( RECT_BOTRIGHT ).GetPosition(); - - pinEditedCorner( getEditedPointIndex(), Mils2iu( 1 ), Mils2iu( 1 ), - topLeft, topRight, botLeft, botRight ); - - LIB_RECTANGLE* rect = (LIB_RECTANGLE*) item; - rect->SetPosition( mapCoords( topLeft ) ); - rect->SetEnd( mapCoords( botRight ) ); - break; - } case SCH_BITMAP_T: { @@ -562,8 +572,8 @@ void EE_POINT_EDITOR::updateParentItem() const double heightRatio = newHeight / oldHeight; bitmap->SetImageScale( bitmap->GetImageScale() * std::min( widthRatio, heightRatio ) ); - break; } + break; case SCH_SHEET_T: { @@ -613,9 +623,8 @@ void EE_POINT_EDITOR::updateParentItem() const pin->SetPosition( pos ); } - - break; } + break; case SCH_LINE_T: { @@ -647,9 +656,8 @@ void EE_POINT_EDITOR::updateParentItem() const getView()->Update( connected.first, KIGFX::GEOMETRY ); } - - break; } + break; default: break; @@ -672,65 +680,72 @@ void EE_POINT_EDITOR::updatePoints() switch( item->Type() ) { - case LIB_ARC_T: + case LIB_SHAPE_T: { - LIB_ARC* arc = (LIB_ARC*) item; + LIB_SHAPE* shape = static_cast( item ); - m_editPoints->Point( ARC_CENTER ).SetPosition( mapCoords( arc->GetPosition() ) ); - m_editPoints->Point( ARC_START ).SetPosition( mapCoords( arc->GetStart() ) ); - m_editPoints->Point( ARC_END ).SetPosition( mapCoords( arc->GetEnd() ) ); - break; - } - - case LIB_CIRCLE_T: - { - LIB_CIRCLE* circle = (LIB_CIRCLE*) item; - - m_editPoints->Point( CIRC_CENTER ).SetPosition( mapCoords( circle->GetPosition() ) ); - m_editPoints->Point( CIRC_END ).SetPosition( mapCoords( circle->GetEnd() ) ); - break; - } - - case LIB_POLYLINE_T: - { - LIB_POLYLINE* lines = (LIB_POLYLINE*) item; - const std::vector& pts = lines->GetPolyPoints(); - - if( m_editPoints->PointsSize() != (unsigned) pts.size() ) + switch( shape->GetShape() ) { - getView()->Remove( m_editPoints.get() ); - m_editedPoint = nullptr; - m_editPoints = EDIT_POINTS_FACTORY::Make( item, m_frame ); - getView()->Add(m_editPoints.get() ); - } - else + case SHAPE_T::ARC: + m_editPoints->Point( ARC_CENTER ).SetPosition( mapCoords( shape->GetPosition() ) ); + m_editPoints->Point( ARC_START ).SetPosition( mapCoords( shape->GetStart() ) ); + m_editPoints->Point( ARC_END ).SetPosition( mapCoords( shape->GetEnd() ) ); + break; + + case SHAPE_T::CIRCLE: + m_editPoints->Point( CIRC_CENTER ).SetPosition( mapCoords( shape->GetPosition() ) ); + m_editPoints->Point( CIRC_END ).SetPosition( mapCoords( shape->GetEnd() ) ); + break; + + case SHAPE_T::POLY: { - for( unsigned i = 0; i < pts.size(); i++ ) - m_editPoints->Point( i ).SetPosition( mapCoords( pts[i] ) ); + if( (int) m_editPoints->PointsSize() != shape->GetPointCount() ) + { + getView()->Remove( m_editPoints.get() ); + m_editedPoint = nullptr; + m_editPoints = EDIT_POINTS_FACTORY::Make( item, m_frame ); + getView()->Add( m_editPoints.get() ); + } + else + { + int ii = 0; + + for( const VECTOR2I& pt : shape->GetPolyShape().Outline( 0 ).CPoints() ) + m_editPoints->Point( ii++ ).SetPosition( mapCoords( pt ) ); + } + + break; } - break; - } + case SHAPE_T::RECT: + { + // point editor works only with rectangles having width and height > 0 + // Some symbols can have rectangles with width or height < 0 + // So normalize the size: + BOX2I dummy; + dummy.SetOrigin( mapCoords( shape->GetPosition() ) ); + dummy.SetEnd( mapCoords( shape->GetEnd() ) ); + dummy.Normalize(); + VECTOR2I topLeft = dummy.GetPosition(); + VECTOR2I botRight = dummy.GetEnd(); - case LIB_RECTANGLE_T: - { - LIB_RECTANGLE* rect = (LIB_RECTANGLE*) item; - // point editor works only with rectangles having width and height > 0 - // Some symbols can have rectangles with width or height < 0 - // So normalize the size: - BOX2I dummy; - dummy.SetOrigin( mapCoords( rect->GetPosition() ) ); - dummy.SetEnd( mapCoords( rect->GetEnd() ) ); - dummy.Normalize(); - VECTOR2I topLeft = dummy.GetPosition(); - VECTOR2I botRight = dummy.GetEnd(); + m_editPoints->Point( RECT_TOPLEFT ).SetPosition( topLeft ); + m_editPoints->Point( RECT_TOPRIGHT ).SetPosition( VECTOR2I( botRight.x, topLeft.y ) ); + m_editPoints->Point( RECT_BOTLEFT ).SetPosition( VECTOR2I( topLeft.x, botRight.y ) ); + m_editPoints->Point( RECT_BOTRIGHT ).SetPosition( botRight ); + } + break; - m_editPoints->Point( RECT_TOPLEFT ).SetPosition( topLeft ); - m_editPoints->Point( RECT_TOPRIGHT ).SetPosition( VECTOR2I( botRight.x, topLeft.y ) ); - m_editPoints->Point( RECT_BOTLEFT ).SetPosition( VECTOR2I( topLeft.x, botRight.y ) ); - m_editPoints->Point( RECT_BOTRIGHT ).SetPosition( botRight ); - break; + case SHAPE_T::BEZIER: + // TODO + break; + + default: + wxFAIL_MSG( "EE_POINT_EDITOR::updatePoints not implemented for " + + shape->SHAPE_T_asString() ); + } } + break; case SCH_BITMAP_T: { @@ -742,8 +757,8 @@ void EE_POINT_EDITOR::updatePoints() m_editPoints->Point( RECT_TOPRIGHT ).SetPosition( botRight.x, topLeft.y ); m_editPoints->Point( RECT_BOTLEFT ).SetPosition( topLeft.x, botRight.y ); m_editPoints->Point( RECT_BOTRIGHT ).SetPosition( botRight ); - break; } + break; case SCH_SHEET_T: { @@ -755,8 +770,8 @@ void EE_POINT_EDITOR::updatePoints() m_editPoints->Point( RECT_TOPRIGHT ).SetPosition( botRight.x, topLeft.y ); m_editPoints->Point( RECT_BOTLEFT ).SetPosition( topLeft.x, botRight.y ); m_editPoints->Point( RECT_BOTRIGHT ).SetPosition( botRight ); - break; } + break; case SCH_LINE_T: { @@ -764,8 +779,8 @@ void EE_POINT_EDITOR::updatePoints() m_editPoints->Point( LINE_START ).SetPosition( line->GetStartPoint() ); m_editPoints->Point( LINE_END ).SetPosition( line->GetEndPoint() ); - break; } + break; default: break; @@ -799,19 +814,18 @@ void EE_POINT_EDITOR::setEditedPoint( EDIT_POINT* aPoint ) bool EE_POINT_EDITOR::removeCornerCondition( const SELECTION& ) { - if( !m_editPoints || !m_editedPoint ) + if( !m_editPoints || !m_editedPoint || m_editPoints->GetParent()->Type() != LIB_SHAPE_T ) return false; - LIB_POLYLINE* polyLine = dynamic_cast( m_editPoints->GetParent() ); + LIB_SHAPE* shape = static_cast( m_editPoints->GetParent() ); + SHAPE_LINE_CHAIN& poly = shape->GetPolyShape().Outline( 0 ); - if( !polyLine || polyLine->GetCornerCount() < 3 ) + if( poly.GetPointCount() < 3 ) return false; - const std::vector& pts = polyLine->GetPolyPoints(); - - for( unsigned i = 0; i < polyLine->GetCornerCount(); ++i ) + for( const VECTOR2I& pt : poly.CPoints() ) { - if( pts[i] == mapCoords( m_editedPoint->GetPosition() ) ) + if( pt == mapCoords( m_editedPoint->GetPosition() ) ) return true; } @@ -821,35 +835,49 @@ bool EE_POINT_EDITOR::removeCornerCondition( const SELECTION& ) bool EE_POINT_EDITOR::addCornerCondition( const SELECTION& ) { - if( !m_editPoints || !m_editedPoint ) + if( !m_editPoints || m_editPoints->GetParent()->Type() != LIB_SHAPE_T ) return false; - LIB_POLYLINE* polyLine = dynamic_cast( m_editPoints->GetParent() ); + LIB_SHAPE* shape = static_cast( m_editPoints->GetParent() ); - if( !polyLine ) + if( shape->GetShape() != SHAPE_T::POLY ) return false; VECTOR2I cursorPos = getViewControls()->GetCursorPosition(); double threshold = getView()->ToWorld( EDIT_POINT::POINT_SIZE ); - return polyLine->HitTest( mapCoords( cursorPos ), (int) threshold ); + return shape->HitTest( mapCoords( cursorPos ), (int) threshold ); } int EE_POINT_EDITOR::addCorner( const TOOL_EVENT& aEvent ) { - if( !m_editPoints ) + if( !m_editPoints || m_editPoints->GetParent()->Type() != LIB_SHAPE_T ) return 0; - LIB_POLYLINE* polyLine = dynamic_cast( m_editPoints->GetParent() ); + LIB_SHAPE* shape = static_cast( m_editPoints->GetParent() ); + SHAPE_LINE_CHAIN& poly = shape->GetPolyShape().Outline( 0 ); - if( !polyLine ) - return false; + VECTOR2I cursor = getViewControls()->GetCursorPosition( !aEvent.DisableGridSnapping() ); + wxPoint pos = mapCoords( cursor ); + int currentMinDistance = INT_MAX; + int closestLineStart = 0; - VECTOR2I cursorPos = getViewControls()->GetCursorPosition( !aEvent.DisableGridSnapping() ); - polyLine->AddCorner( mapCoords( cursorPos ) ); + for( unsigned i = 0; i < poly.GetPointCount() - 1; ++i ) + { + int distance = (int) DistanceLinePoint( (wxPoint) poly.CPoint( i ), + (wxPoint) poly.CPoint( i + 1 ), pos ); - updateItem( polyLine, true ); + if( distance < currentMinDistance ) + { + currentMinDistance = distance; + closestLineStart = i; + } + } + + poly.Insert( closestLineStart, pos ); + + updateItem( shape, true ); updatePoints(); return 0; @@ -858,17 +886,18 @@ int EE_POINT_EDITOR::addCorner( const TOOL_EVENT& aEvent ) int EE_POINT_EDITOR::removeCorner( const TOOL_EVENT& aEvent ) { - if( !m_editPoints || !m_editedPoint ) + if( !m_editPoints || !m_editedPoint || m_editPoints->GetParent()->Type() != LIB_SHAPE_T ) return 0; - LIB_POLYLINE* polyLine = dynamic_cast( m_editPoints->GetParent() ); + LIB_SHAPE* shape = static_cast( m_editPoints->GetParent() ); + SHAPE_LINE_CHAIN& poly = shape->GetPolyShape().Outline( 0 ); - if( !polyLine || polyLine->GetCornerCount() < 3 ) + if( poly.GetPointCount() < 3 ) return 0; - polyLine->RemoveCorner( getEditedPointIndex() ); + poly.Remove( getEditedPointIndex() ); - updateItem( polyLine, true ); + updateItem( shape, true ); updatePoints(); return 0; diff --git a/eeschema/tools/ee_selection_tool.cpp b/eeschema/tools/ee_selection_tool.cpp index 91fbbb9322..9f17921425 100644 --- a/eeschema/tools/ee_selection_tool.cpp +++ b/eeschema/tools/ee_selection_tool.cpp @@ -304,12 +304,8 @@ const KICAD_T movableSchematicItems[] = const KICAD_T movableSymbolItems[] = { - LIB_ARC_T, - LIB_CIRCLE_T, + LIB_SHAPE_T, LIB_TEXT_T, - LIB_RECTANGLE_T, - LIB_POLYLINE_T, - LIB_BEZIER_T, LIB_PIN_T, LIB_FIELD_T, EOT @@ -1722,12 +1718,8 @@ bool EE_SELECTION_TOOL::Selectable( const EDA_ITEM* aItem, const VECTOR2I* aPos, case LIB_FIELD_T: // LIB_FIELD object can always be edited. break; - case LIB_ARC_T: - case LIB_CIRCLE_T: + case LIB_SHAPE_T: case LIB_TEXT_T: - case LIB_RECTANGLE_T: - case LIB_POLYLINE_T: - case LIB_BEZIER_T: case LIB_PIN_T: if( symEditFrame ) { diff --git a/eeschema/tools/sch_edit_tool.cpp b/eeschema/tools/sch_edit_tool.cpp index c430615918..8634d91d14 100644 --- a/eeschema/tools/sch_edit_tool.cpp +++ b/eeschema/tools/sch_edit_tool.cpp @@ -149,13 +149,13 @@ bool SCH_EDIT_TOOL::Init() wxASSERT_MSG( drawingTools, "eeshema.InteractiveDrawing tool is not available" ); auto hasElements = - [ this ] ( const SELECTION& aSel ) + [this]( const SELECTION& aSel ) { return !m_frame->GetScreen()->Items().empty(); }; auto sheetHasUndefinedPins = - [ this ] ( const SELECTION& aSel ) + []( const SELECTION& aSel ) { if( aSel.Size() != 1 ) return false; @@ -175,7 +175,7 @@ bool SCH_EDIT_TOOL::Init() }; auto anyTextTool = - [ this ] ( const SELECTION& aSel ) + [this]( const SELECTION& aSel ) { return ( m_frame->IsCurrentTool( EE_ACTIONS::placeLabel ) || m_frame->IsCurrentTool( EE_ACTIONS::placeGlobalLabel ) @@ -184,7 +184,7 @@ bool SCH_EDIT_TOOL::Init() }; auto duplicateCondition = - [] ( const SELECTION& aSel ) + []( const SELECTION& aSel ) { if( SCH_LINE_WIRE_BUS_TOOL::IsDrawingLineWireOrBus( aSel ) ) return false; @@ -193,7 +193,7 @@ bool SCH_EDIT_TOOL::Init() }; auto orientCondition = - [] ( const SELECTION& aSel ) + []( const SELECTION& aSel ) { if( aSel.Empty() ) return false; @@ -269,7 +269,7 @@ bool SCH_EDIT_TOOL::Init() }; auto autoplaceCondition = - [] ( const SELECTION& aSel ) + []( const SELECTION& aSel ) { for( const EDA_ITEM* item : aSel ) { diff --git a/eeschema/tools/symbol_editor_drawing_tools.cpp b/eeschema/tools/symbol_editor_drawing_tools.cpp index 32232ef16b..ba99507805 100644 --- a/eeschema/tools/symbol_editor_drawing_tools.cpp +++ b/eeschema/tools/symbol_editor_drawing_tools.cpp @@ -29,10 +29,7 @@ #include #include #include -#include -#include -#include -#include +#include #include #include #include @@ -44,7 +41,7 @@ static void* g_lastPinWeakPtr; SYMBOL_EDITOR_DRAWING_TOOLS::SYMBOL_EDITOR_DRAWING_TOOLS() : EE_TOOL_BASE( "eeschema.SymbolDrawing" ), m_lastTextAngle( 0.0 ), - m_lastFillStyle( FILL_TYPE::NO_FILL ), + m_lastFillStyle( FILL_T::NO_FILL ), m_drawSpecificConvert( true ), m_drawSpecificUnit( false ) { @@ -265,7 +262,7 @@ int SYMBOL_EDITOR_DRAWING_TOOLS::DrawShape( const TOOL_EVENT& aEvent ) { SETTINGS_MANAGER& settingsMgr = Pgm().GetSettingsManager(); SYMBOL_EDITOR_SETTINGS* settings = settingsMgr.GetAppSettings(); - KICAD_T type = aEvent.Parameter(); + SHAPE_T type = aEvent.Parameter(); LIB_SYMBOL* symbol = m_frame->GetCurSymbol(); LIB_ITEM* item = nullptr; @@ -347,19 +344,9 @@ int SYMBOL_EDITOR_DRAWING_TOOLS::DrawShape( const TOOL_EVENT& aEvent ) m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true ); - switch( type ) - { - case LIB_ARC_T: item = new LIB_ARC( symbol ); break; - case LIB_CIRCLE_T: item = new LIB_CIRCLE( symbol ); break; - case LIB_POLYLINE_T: item = new LIB_POLYLINE( symbol ); break; - case LIB_RECTANGLE_T: item = new LIB_RECTANGLE( symbol ); break; - default: break; // keep compiler quiet - } + int lineWidth = Mils2iu( settings->m_Defaults.line_width ); - wxCHECK( item, 0 ); - - item->SetWidth( Mils2iu( settings->m_Defaults.line_width ) ); - item->SetFillMode( m_lastFillStyle ); + item = new LIB_SHAPE( symbol, type, lineWidth, m_lastFillStyle ); item->SetFlags( IS_NEW ); item->BeginEdit( wxPoint( cursorPos.x, -cursorPos.y ) ); diff --git a/eeschema/tools/symbol_editor_drawing_tools.h b/eeschema/tools/symbol_editor_drawing_tools.h index e786360dc4..e7aacfe9eb 100644 --- a/eeschema/tools/symbol_editor_drawing_tools.h +++ b/eeschema/tools/symbol_editor_drawing_tools.h @@ -66,7 +66,7 @@ private: private: double m_lastTextAngle; - FILL_TYPE m_lastFillStyle; + FILL_T m_lastFillStyle; bool m_drawSpecificConvert; bool m_drawSpecificUnit; }; diff --git a/eeschema/tools/symbol_editor_edit_tool.cpp b/eeschema/tools/symbol_editor_edit_tool.cpp index 89d62873fc..c8841533ed 100644 --- a/eeschema/tools/symbol_editor_edit_tool.cpp +++ b/eeschema/tools/symbol_editor_edit_tool.cpp @@ -240,12 +240,8 @@ int SYMBOL_EDITOR_EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent ) static KICAD_T nonFields[] = { LIB_SYMBOL_T, - LIB_ARC_T, - LIB_CIRCLE_T, + LIB_SHAPE_T, LIB_TEXT_T, - LIB_RECTANGLE_T, - LIB_POLYLINE_T, - LIB_BEZIER_T, LIB_PIN_T, EOT }; @@ -433,14 +429,11 @@ int SYMBOL_EDITOR_EDIT_TOOL::Properties( const TOOL_EVENT& aEvent ) if( pinTool ) pinTool->EditPinProperties( (LIB_PIN*) item ); - - break; } - case LIB_ARC_T: - case LIB_CIRCLE_T: - case LIB_RECTANGLE_T: - case LIB_POLYLINE_T: - editGraphicProperties( item ); + break; + + case LIB_SHAPE_T: + editShapeProperties( item ); break; case LIB_TEXT_T: @@ -466,7 +459,7 @@ int SYMBOL_EDITOR_EDIT_TOOL::Properties( const TOOL_EVENT& aEvent ) } -void SYMBOL_EDITOR_EDIT_TOOL::editGraphicProperties( LIB_ITEM* aItem ) +void SYMBOL_EDITOR_EDIT_TOOL::editShapeProperties( LIB_ITEM* aItem ) { DIALOG_LIB_SHAPE_PROPERTIES dlg( m_frame, aItem ); diff --git a/eeschema/tools/symbol_editor_edit_tool.h b/eeschema/tools/symbol_editor_edit_tool.h index ac2973824a..b88aed0af8 100644 --- a/eeschema/tools/symbol_editor_edit_tool.h +++ b/eeschema/tools/symbol_editor_edit_tool.h @@ -64,7 +64,7 @@ public: int DeleteItemCursor( const TOOL_EVENT& aEvent ); private: - void editGraphicProperties( LIB_ITEM* aItem ); + void editShapeProperties( LIB_ITEM* aItem ); void editTextProperties( LIB_ITEM* aItem ); void editFieldProperties( LIB_FIELD* aField ); void editSymbolProperties(); diff --git a/include/core/typeinfo.h b/include/core/typeinfo.h index e7062e9acf..8b6dc6a8e7 100644 --- a/include/core/typeinfo.h +++ b/include/core/typeinfo.h @@ -175,12 +175,8 @@ enum KICAD_T */ LIB_SYMBOL_T, LIB_ALIAS_T, - LIB_ARC_T, - LIB_CIRCLE_T, + LIB_SHAPE_T, LIB_TEXT_T, - LIB_RECTANGLE_T, - LIB_POLYLINE_T, - LIB_BEZIER_T, LIB_PIN_T, /* diff --git a/include/eda_shape.h b/include/eda_shape.h index 1f3acf460f..6e2f239aca 100644 --- a/include/eda_shape.h +++ b/include/eda_shape.h @@ -27,7 +27,6 @@ #include #include -#include #include #include #include @@ -50,10 +49,19 @@ enum class SHAPE_T : int }; +enum class FILL_T : int +{ + NO_FILL = 1, + FILLED_SHAPE, // Fill with object color + FILLED_WITH_BG_BODYCOLOR, // Fill with background body color + FILLED_WITH_COLOR // Fill with a separate color +}; + + class EDA_SHAPE { public: - EDA_SHAPE( SHAPE_T aType, int aDefaultLineWidth ); + EDA_SHAPE( SHAPE_T aType, int aLineWidth, FILL_T aFill ); // Do not create a copy constructor & operator=. // The ones generated by the compiler are adequate. @@ -66,34 +74,21 @@ public: wxString SHAPE_T_asString() const; - void SetFilled( bool aFlag ) { m_filled = aFlag; } + void SetFillMode( FILL_T aFill ) { m_fill = aFill; } + FILL_T GetFillType() const { return m_fill; } - bool IsFilled() const + bool IsFilled() const { return GetFillType() != FILL_T::NO_FILL; } + + void SetFilled( bool aFlag ) { - switch( m_shape ) - { - case SHAPE_T::RECT: - case SHAPE_T::CIRCLE: - case SHAPE_T::POLY: - return m_filled; - - case SHAPE_T::SEGMENT: - case SHAPE_T::ARC: - case SHAPE_T::BEZIER: - return false; - - case SHAPE_T::LAST: // Make CLang compiler happy - return false; - } - - return false; // Make GCC compiler happy + m_fill = aFlag ? FILL_T::FILLED_SHAPE : FILL_T::NO_FILL; } - void SetWidth( int aWidth ) { m_width = aWidth; } - int GetWidth() const { return m_width; } + void SetWidth( int aWidth ) { m_width = aWidth; } + int GetWidth() const { return m_width; } - void SetShape( SHAPE_T aShape ) { m_shape = aShape; } - SHAPE_T GetShape() const { return m_shape; } + void SetShape( SHAPE_T aShape ) { m_shape = aShape; } + SHAPE_T GetShape() const { return m_shape; } /** * Return the starting point of the graphic. @@ -115,15 +110,6 @@ public: void SetEndY( int y ) { m_end.y = y; } void SetEndX( int x ) { m_end.x = x; } - /** - * Set the angle for arcs, and normalizes it within the range 0 - 360 degrees. - * - * @param aAngle is tenths of degrees, but will soon be degrees. - */ - virtual void SetArcAngle( double aAngle ); - virtual void SetArcAngleAndEnd( double aAngle ); - double GetArcAngle() const { return m_arcAngle; } - void SetBezierC1( const wxPoint& aPt ) { m_bezierC1 = aPt; } const wxPoint& GetBezierC1() const { return m_bezierC1; } @@ -133,6 +119,15 @@ public: wxPoint getCenter() const; void SetCenter( const wxPoint& aCenter ); + /** + * Set the angle for arcs, and normalizes it within the range 0 - 360 degrees. + * + * @param aAngle is tenths of degrees, but will soon be degrees. + */ + void SetArcAngle( double aAngle ); + void SetArcAngleAndEnd( double aAngle ); + double GetArcAngle() const { return m_arcAngle; } + // Some attributes are read only, since they are derived from m_Start, m_End, and m_Angle. // No Set...() function for these attributes. @@ -142,12 +137,12 @@ public: /** * @return the angle of the starting point of this arc, between 0 and 3600 in 0.1 deg. */ - double GetArcAngleStart() const; + virtual double GetArcAngleStart() const; /** * @return the angle of the ending point of this arc, between 0 and 3600 in 0.1 deg. */ - double GetArcAngleEnd() const; + virtual double GetArcAngleEnd() const; int GetRadius() const; @@ -260,7 +255,7 @@ protected: protected: SHAPE_T m_shape; // Shape: line, Circle, Arc int m_width; // thickness of lines ... - bool m_filled; // Pretty much what it says on the tin... + FILL_T m_fill; wxPoint m_start; // Line start point or Circle center wxPoint m_end; // Line end point or Circle 3 o'clock point diff --git a/include/fill_type.h b/include/fill_type.h deleted file mode 100644 index bfe1b5a959..0000000000 --- a/include/fill_type.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * This program source code file is part of KiCad, a free EDA CAD application. - * - * Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors. - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef FILL_TYPE_H -#define FILL_TYPE_H - -/** - * The set of fill types used in plotting or drawing enclosed areas. - * - * @warning Do not renumber this enum, the legacy schematic plugin demands on these values. - */ -enum class FILL_TYPE : int -{ - NO_FILL = 0, - FILLED_SHAPE = 1, // Fill with object color ("Solid shape") - FILLED_WITH_BG_BODYCOLOR = 2, // Fill with background body color - // (not filled in B&W mode when plotting or printing) - FILLED_WITH_COLOR =3 // Fill with a user-defined color (currently sheets only) -}; - -#endif diff --git a/include/plotters/plotter.h b/include/plotters/plotter.h index 54052b6dab..0f214449e4 100644 --- a/include/plotters/plotter.h +++ b/include/plotters/plotter.h @@ -31,7 +31,7 @@ #ifndef PLOT_COMMON_H_ #define PLOT_COMMON_H_ -#include +#include #include #include #include @@ -228,16 +228,16 @@ public: int GetPlotterArcHighDef() const { return m_IUsPerDecimil * 2; } // Low level primitives - virtual void Rect( const wxPoint& p1, const wxPoint& p2, FILL_TYPE fill, + virtual void Rect( const wxPoint& p1, const wxPoint& p2, FILL_T fill, int width = USE_DEFAULT_LINE_WIDTH ) = 0; - virtual void Circle( const wxPoint& pos, int diametre, FILL_TYPE fill, + virtual void Circle( const wxPoint& pos, int diametre, FILL_T fill, int width = USE_DEFAULT_LINE_WIDTH ) = 0; /** * Generic fallback: arc rendered as a polyline. */ - virtual void Arc( const wxPoint& centre, double StAngle, double EndAngle, - int rayon, FILL_TYPE fill, int width = USE_DEFAULT_LINE_WIDTH ); + virtual void Arc( const wxPoint& centre, double StAngle, double EndAngle, int rayon, + FILL_T fill, int width = USE_DEFAULT_LINE_WIDTH ); virtual void Arc( const SHAPE_ARC& aArc ); /** @@ -290,7 +290,7 @@ public: * @param aWidth is the line width. * @param aData is an auxiliary info (mainly for gerber format). */ - virtual void PlotPoly( const std::vector< wxPoint >& aCornerList, FILL_TYPE aFill, + virtual void PlotPoly( const std::vector< wxPoint >& aCornerList, FILL_T aFill, int aWidth = USE_DEFAULT_LINE_WIDTH, void* aData = nullptr ) = 0; /** @@ -301,7 +301,7 @@ public: * @param aWidth is the line width. * @param aData is an auxiliary info (mainly for gerber format). */ - virtual void PlotPoly( const SHAPE_LINE_CHAIN& aCornerList, FILL_TYPE aFill, + virtual void PlotPoly( const SHAPE_LINE_CHAIN& aCornerList, FILL_T aFill, int aWidth = USE_DEFAULT_LINE_WIDTH, void* aData = nullptr ); /** diff --git a/include/plotters/plotter_dxf.h b/include/plotters/plotter_dxf.h index 13ea51ed32..29bacb5a7d 100644 --- a/include/plotters/plotter_dxf.h +++ b/include/plotters/plotter_dxf.h @@ -89,7 +89,7 @@ public: /** * DXF rectangle: fill not supported. */ - virtual void Rect( const wxPoint& p1, const wxPoint& p2, FILL_TYPE fill, + virtual void Rect( const wxPoint& p1, const wxPoint& p2, FILL_T fill, int width = USE_DEFAULT_LINE_WIDTH ) override; /** @@ -98,7 +98,7 @@ public: * * I could use this trick to do other filled primitives. */ - virtual void Circle( const wxPoint& pos, int diametre, FILL_TYPE fill, + virtual void Circle( const wxPoint& pos, int diametre, FILL_T fill, int width = USE_DEFAULT_LINE_WIDTH ) override; /** @@ -108,12 +108,12 @@ public: * It does not know thick segments, therefore filled polygons with thick outline * are converted to inflated polygon by aWidth/2. */ - virtual void PlotPoly( const std::vector< wxPoint >& aCornerList, FILL_TYPE aFill, + virtual void PlotPoly( const std::vector< wxPoint >& aCornerList, FILL_T aFill, int aWidth = USE_DEFAULT_LINE_WIDTH, void* aData = nullptr ) override; virtual void ThickSegment( const wxPoint& start, const wxPoint& end, int width, OUTLINE_MODE tracemode, void* aData ) override; virtual void Arc( const wxPoint& centre, double StAngle, double EndAngle, - int rayon, FILL_TYPE fill, int width = USE_DEFAULT_LINE_WIDTH ) override; + int rayon, FILL_T fill, int width = USE_DEFAULT_LINE_WIDTH ) override; virtual void PenTo( const wxPoint& pos, char plume ) override; /** diff --git a/include/plotters/plotter_gerber.h b/include/plotters/plotter_gerber.h index a27014b9c9..a2cbe8c82c 100644 --- a/include/plotters/plotter_gerber.h +++ b/include/plotters/plotter_gerber.h @@ -65,12 +65,12 @@ public: double aScale, bool aMirror ) override; // Basic plot primitives - virtual void Rect( const wxPoint& p1, const wxPoint& p2, FILL_TYPE fill, + virtual void Rect( const wxPoint& p1, const wxPoint& p2, FILL_T fill, int width = USE_DEFAULT_LINE_WIDTH ) override; - virtual void Circle( const wxPoint& pos, int diametre, FILL_TYPE fill, + virtual void Circle( const wxPoint& pos, int diametre, FILL_T fill, int width = USE_DEFAULT_LINE_WIDTH ) override; - virtual void Arc( const wxPoint& aCenter, double aStAngle, double aEndAngle, - int aRadius, FILL_TYPE aFill, int aWidth = USE_DEFAULT_LINE_WIDTH ) override; + virtual void Arc( const wxPoint& aCenter, double aStAngle, double aEndAngle, int aRadius, + FILL_T aFill, int aWidth = USE_DEFAULT_LINE_WIDTH ) override; virtual void Arc( const SHAPE_ARC& aArc ) override; @@ -91,10 +91,10 @@ public: * Gerber polygon: they can (and *should*) be filled with the * appropriate G36/G37 sequence */ - virtual void PlotPoly( const std::vector< wxPoint >& aCornerList, FILL_TYPE aFill, + virtual void PlotPoly( const std::vector< wxPoint >& aCornerList, FILL_T aFill, int aWidth = USE_DEFAULT_LINE_WIDTH, void* aData = nullptr ) override; - virtual void PlotPoly( const SHAPE_LINE_CHAIN& aCornerList, FILL_TYPE aFill, + virtual void PlotPoly( const SHAPE_LINE_CHAIN& aCornerList, FILL_T aFill, int aWidth = USE_DEFAULT_LINE_WIDTH, void* aData = nullptr ) override; virtual void PenTo( const wxPoint& pos, char plume ) override; diff --git a/include/plotters/plotter_hpgl.h b/include/plotters/plotter_hpgl.h index fa88e7f2b7..a7f9924172 100644 --- a/include/plotters/plotter_hpgl.h +++ b/include/plotters/plotter_hpgl.h @@ -96,13 +96,12 @@ public: virtual void SetViewport( const wxPoint& aOffset, double aIusPerDecimil, double aScale, bool aMirror ) override; - virtual void Rect( const wxPoint& p1, const wxPoint& p2, FILL_TYPE fill, + virtual void Rect( const wxPoint& p1, const wxPoint& p2, FILL_T fill, int width = USE_DEFAULT_LINE_WIDTH ) override; - virtual void Circle( const wxPoint& pos, int diametre, FILL_TYPE fill, + virtual void Circle( const wxPoint& pos, int diametre, FILL_T fill, int width = USE_DEFAULT_LINE_WIDTH ) override; - virtual void PlotPoly( const std::vector< wxPoint >& aCornerList, - FILL_TYPE aFill, int aWidth = USE_DEFAULT_LINE_WIDTH, - void* aData = nullptr ) override; + virtual void PlotPoly( const std::vector< wxPoint >& aCornerList, FILL_T aFill, + int aWidth = USE_DEFAULT_LINE_WIDTH, void* aData = nullptr ) override; virtual void ThickSegment( const wxPoint& start, const wxPoint& end, int width, OUTLINE_MODE tracemode, void* aData ) override; @@ -119,8 +118,8 @@ public: * EndAngle is end angle the arc. * Radius is the radius of the arc. */ - virtual void Arc( const wxPoint& centre, double StAngle, double EndAngle, - int rayon, FILL_TYPE fill, int width = USE_DEFAULT_LINE_WIDTH ) override; + virtual void Arc( const wxPoint& centre, double StAngle, double EndAngle, int rayon, + FILL_T fill, int width = USE_DEFAULT_LINE_WIDTH ) override; virtual void PenTo( const wxPoint& pos, char plume ) override; virtual void FlashPadCircle( const wxPoint& aPadPos, int aDiameter, OUTLINE_MODE aTraceMode, void* aData ) override; diff --git a/include/plotters/plotters_pslike.h b/include/plotters/plotters_pslike.h index b28c373955..3214781e8a 100644 --- a/include/plotters/plotters_pslike.h +++ b/include/plotters/plotters_pslike.h @@ -197,14 +197,14 @@ public: virtual void SetViewport( const wxPoint& aOffset, double aIusPerDecimil, double aScale, bool aMirror ) override; - virtual void Rect( const wxPoint& p1, const wxPoint& p2, FILL_TYPE fill, + virtual void Rect( const wxPoint& p1, const wxPoint& p2, FILL_T fill, int width = USE_DEFAULT_LINE_WIDTH ) override; - virtual void Circle( const wxPoint& pos, int diametre, FILL_TYPE fill, + virtual void Circle( const wxPoint& pos, int diametre, FILL_T fill, int width = USE_DEFAULT_LINE_WIDTH ) override; - virtual void Arc( const wxPoint& centre, double StAngle, double EndAngle, - int rayon, FILL_TYPE fill, int width = USE_DEFAULT_LINE_WIDTH ) override; + virtual void Arc( const wxPoint& centre, double StAngle, double EndAngle, int rayon, + FILL_T fill, int width = USE_DEFAULT_LINE_WIDTH ) override; - virtual void PlotPoly( const std::vector< wxPoint >& aCornerList, FILL_TYPE aFill, + virtual void PlotPoly( const std::vector< wxPoint >& aCornerList, FILL_T aFill, int aWidth = USE_DEFAULT_LINE_WIDTH, void* aData = nullptr ) override; /** @@ -306,26 +306,26 @@ public: /** * Rectangles in PDF. Supported by the native operator. */ - virtual void Rect( const wxPoint& p1, const wxPoint& p2, FILL_TYPE fill, + virtual void Rect( const wxPoint& p1, const wxPoint& p2, FILL_T fill, int width = USE_DEFAULT_LINE_WIDTH ) override; /** * Circle drawing for PDF. They're approximated by curves, but fill is supported */ - virtual void Circle( const wxPoint& pos, int diametre, FILL_TYPE fill, + virtual void Circle( const wxPoint& pos, int diametre, FILL_T fill, int width = USE_DEFAULT_LINE_WIDTH ) override; /** * The PDF engine can't directly plot arcs, it uses the base emulation. * So no filled arcs (not a great loss... ) */ - virtual void Arc( const wxPoint& centre, double StAngle, double EndAngle, - int rayon, FILL_TYPE fill, int width = USE_DEFAULT_LINE_WIDTH ) override; + virtual void Arc( const wxPoint& centre, double StAngle, double EndAngle, int rayon, + FILL_T fill, int width = USE_DEFAULT_LINE_WIDTH ) override; /** * Polygon plotting for PDF. Everything is supported */ - virtual void PlotPoly( const std::vector< wxPoint >& aCornerList, FILL_TYPE aFill, + virtual void PlotPoly( const std::vector< wxPoint >& aCornerList, FILL_T aFill, int aWidth = USE_DEFAULT_LINE_WIDTH, void* aData = nullptr ) override; virtual void PenTo( const wxPoint& pos, char plume ) override; @@ -442,21 +442,20 @@ public: virtual void SetViewport( const wxPoint& aOffset, double aIusPerDecimil, double aScale, bool aMirror ) override; - virtual void Rect( const wxPoint& p1, const wxPoint& p2, FILL_TYPE fill, + virtual void Rect( const wxPoint& p1, const wxPoint& p2, FILL_T fill, int width = USE_DEFAULT_LINE_WIDTH ) override; - virtual void Circle( const wxPoint& pos, int diametre, FILL_TYPE fill, + virtual void Circle( const wxPoint& pos, int diametre, FILL_T fill, int width = USE_DEFAULT_LINE_WIDTH ) override; - virtual void Arc( const wxPoint& centre, double StAngle, double EndAngle, - int rayon, FILL_TYPE fill, int width = USE_DEFAULT_LINE_WIDTH ) override; + virtual void Arc( const wxPoint& centre, double StAngle, double EndAngle, int rayon, + FILL_T fill, int width = USE_DEFAULT_LINE_WIDTH ) override; virtual void BezierCurve( const wxPoint& aStart, const wxPoint& aControl1, const wxPoint& aControl2, const wxPoint& aEnd, int aTolerance, int aLineThickness = USE_DEFAULT_LINE_WIDTH ) override; - virtual void PlotPoly( const std::vector< wxPoint >& aCornerList, - FILL_TYPE aFill, int aWidth = USE_DEFAULT_LINE_WIDTH, - void * aData = nullptr ) override; + virtual void PlotPoly( const std::vector< wxPoint >& aCornerList, FILL_T aFill, + int aWidth = USE_DEFAULT_LINE_WIDTH, void * aData = nullptr ) override; /** * PostScript-likes at the moment are the only plot engines supporting bitmaps. @@ -524,9 +523,9 @@ protected: /** * Prepare parameters for setSVGPlotStyle() */ - void setFillMode( FILL_TYPE fill ); + void setFillMode( FILL_T fill ); - FILL_TYPE m_fillMode; // true if the current contour + FILL_T m_fillMode; // true if the current contour // rect, arc, circle, polygon must be filled long m_pen_rgb_color; // current rgb color value: each color has // a value 0 ... 255, and the 3 colors are diff --git a/pcbnew/drc/drc_test_provider_copper_clearance.cpp b/pcbnew/drc/drc_test_provider_copper_clearance.cpp index 4feb7b2c55..2cb1824225 100644 --- a/pcbnew/drc/drc_test_provider_copper_clearance.cpp +++ b/pcbnew/drc/drc_test_provider_copper_clearance.cpp @@ -22,6 +22,7 @@ */ #include +#include #include #include #include diff --git a/pcbnew/exporters/gerber_placefile_writer.cpp b/pcbnew/exporters/gerber_placefile_writer.cpp index a9f43654f2..c997aaf0f1 100644 --- a/pcbnew/exporters/gerber_placefile_writer.cpp +++ b/pcbnew/exporters/gerber_placefile_writer.cpp @@ -195,8 +195,7 @@ int PLACEFILE_GERBER_WRITER::CreatePlaceFile( wxString& aFullFilename, PCB_LAYER continue; useFpPadsBbox = false; - plotter.PLOTTER::PlotPoly( poly, FILL_TYPE::NO_FILL, line_thickness, - &gbr_metadata ); + plotter.PLOTTER::PlotPoly( poly, FILL_T::NO_FILL, line_thickness, &gbr_metadata ); } } @@ -221,7 +220,7 @@ int PLACEFILE_GERBER_WRITER::CreatePlaceFile( wxString& aFullFilename, PCB_LAYER poly.Rotate( -footprint->GetOrientationRadians(), VECTOR2I( 0, 0 ) ); poly.Move( footprint->GetPosition() ); - plotter.PLOTTER::PlotPoly( poly, FILL_TYPE::NO_FILL, line_thickness, &gbr_metadata ); + plotter.PLOTTER::PlotPoly( poly, FILL_T::NO_FILL, line_thickness, &gbr_metadata ); } std::vectorpad_key_list; diff --git a/pcbnew/fp_shape.cpp b/pcbnew/fp_shape.cpp index a4c6090103..f1774b417d 100644 --- a/pcbnew/fp_shape.cpp +++ b/pcbnew/fp_shape.cpp @@ -172,12 +172,6 @@ void FP_SHAPE::SetCenter0( const wxPoint& aCenter ) } -void FP_SHAPE::SetArcAngle( double aAngle ) -{ - PCB_SHAPE::SetArcAngle( aAngle ); -} - - void FP_SHAPE::SetArcAngleAndEnd0( double aAngle ) { PCB_SHAPE::SetArcAngle( aAngle ); @@ -195,13 +189,9 @@ void FP_SHAPE::Flip( const wxPoint& aCentre, bool aFlipLeftRight ) switch( GetShape() ) { case SHAPE_T::ARC: - // Update arc angle but do not yet update m_arcCenter0 and m_arcCenter, - // arc center and start point must be updated before calculation arc end. - SetArcAngle( -GetArcAngle() ); - KI_FALLTHROUGH; - - default: case SHAPE_T::SEGMENT: + case SHAPE_T::RECT: + case SHAPE_T::CIRCLE: case SHAPE_T::BEZIER: // If Start0 and Start are equal (ie: Footprint Editor), then flip both sets around the // centre point. @@ -235,13 +225,18 @@ void FP_SHAPE::Flip( const wxPoint& aCentre, bool aFlipLeftRight ) MIRROR( m_bezierC2_0.y, pt.y ); } - RebuildBezierToSegmentsPointsList( m_width ); + if( GetShape() == SHAPE_T::BEZIER ) + RebuildBezierToSegmentsPointsList( m_width ); + break; case SHAPE_T::POLY: // polygon corners coordinates are relative to the footprint position, orientation 0 m_poly.Mirror( aFlipLeftRight, !aFlipLeftRight ); break; + + default: + UNIMPLEMENTED_FOR( SHAPE_T_asString() ); } SetLayer( FlipLayer( GetLayer(), GetBoard()->GetCopperLayerCount() ) ); @@ -262,14 +257,10 @@ void FP_SHAPE::Mirror( const wxPoint& aCentre, bool aMirrorAroundXAxis ) switch( GetShape() ) { case SHAPE_T::ARC: - // Update arc angle but do not yet update m_arcCenter0 and m_arcCenter, - // arc center and start point must be updated before calculation arc end. - SetArcAngle( -GetArcAngle() ); - KI_FALLTHROUGH; - - default: - case SHAPE_T::BEZIER: case SHAPE_T::SEGMENT: + case SHAPE_T::RECT: + case SHAPE_T::CIRCLE: + case SHAPE_T::BEZIER: if( aMirrorAroundXAxis ) { MIRROR( m_start0.y, aCentre.y ); @@ -287,13 +278,8 @@ void FP_SHAPE::Mirror( const wxPoint& aCentre, bool aMirrorAroundXAxis ) MIRROR( m_bezierC2_0.x, aCentre.x ); } - for( unsigned ii = 0; ii < m_bezierPoints.size(); ii++ ) - { - if( aMirrorAroundXAxis ) - MIRROR( m_bezierPoints[ii].y, aCentre.y ); - else - MIRROR( m_bezierPoints[ii].x, aCentre.x ); - } + if( GetShape() == SHAPE_T::BEZIER ) + RebuildBezierToSegmentsPointsList( m_width ); break; @@ -302,6 +288,9 @@ void FP_SHAPE::Mirror( const wxPoint& aCentre, bool aMirrorAroundXAxis ) // footprint position, orientation 0 m_poly.Mirror( !aMirrorAroundXAxis, aMirrorAroundXAxis ); break; + + default: + UNIMPLEMENTED_FOR( SHAPE_T_asString() ); } SetDrawCoord(); @@ -323,15 +312,19 @@ void FP_SHAPE::Move( const wxPoint& aMoveVector ) { // Move an edge of the footprint. // This is a footprint shape modification. - m_start0 += aMoveVector; - m_end0 += aMoveVector; - m_arcCenter0 += aMoveVector; - m_bezierC1_0 += aMoveVector; - m_bezierC2_0 += aMoveVector; switch( GetShape() ) { - default: + case SHAPE_T::ARC: + case SHAPE_T::SEGMENT: + case SHAPE_T::RECT: + case SHAPE_T::CIRCLE: + case SHAPE_T::BEZIER: + m_start0 += aMoveVector; + m_end0 += aMoveVector; + m_arcCenter0 += aMoveVector; + m_bezierC1_0 += aMoveVector; + m_bezierC2_0 += aMoveVector; break; case SHAPE_T::POLY: @@ -340,6 +333,9 @@ void FP_SHAPE::Move( const wxPoint& aMoveVector ) m_poly.Move( VECTOR2I( aMoveVector ) ); break; + + default: + UNIMPLEMENTED_FOR( SHAPE_T_asString() ); } SetDrawCoord(); diff --git a/pcbnew/fp_shape.h b/pcbnew/fp_shape.h index 3e89087e9a..d8cd01fc1a 100644 --- a/pcbnew/fp_shape.h +++ b/pcbnew/fp_shape.h @@ -71,7 +71,6 @@ public: * Sets the angle for arcs, and normalizes it within the range 0 - 360 degrees. * @param aAngle is tenths of degrees, but will soon be degrees. */ - void SetArcAngle( double aAngle ) override; void SetArcAngleAndEnd0( double aAngle ); /** diff --git a/pcbnew/pcb_shape.cpp b/pcbnew/pcb_shape.cpp index f5bb53f6d8..f3fe66f370 100644 --- a/pcbnew/pcb_shape.cpp +++ b/pcbnew/pcb_shape.cpp @@ -35,14 +35,14 @@ PCB_SHAPE::PCB_SHAPE( BOARD_ITEM* aParent, KICAD_T idtype, SHAPE_T shapetype ) : BOARD_ITEM( aParent, idtype ), - EDA_SHAPE( shapetype, Millimeter2iu( DEFAULT_LINE_WIDTH ) ) + EDA_SHAPE( shapetype, Millimeter2iu( DEFAULT_LINE_WIDTH ), FILL_T::NO_FILL ) { } PCB_SHAPE::PCB_SHAPE( BOARD_ITEM* aParent, SHAPE_T shapetype ) : BOARD_ITEM( aParent, PCB_SHAPE_T ), - EDA_SHAPE( shapetype, Millimeter2iu( DEFAULT_LINE_WIDTH ) ) + EDA_SHAPE( shapetype, Millimeter2iu( DEFAULT_LINE_WIDTH ), FILL_T::NO_FILL ) { } diff --git a/pcbnew/plot_board_layers.cpp b/pcbnew/plot_board_layers.cpp index 3b59ef119c..3891b6a695 100644 --- a/pcbnew/plot_board_layers.cpp +++ b/pcbnew/plot_board_layers.cpp @@ -729,7 +729,7 @@ void PlotLayerOutlines( BOARD* aBoard, PLOTTER* aPlotter, LSET aLayerMask, const SHAPE_LINE_CHAIN& path = ( kk == 0 ) ? outlines.COutline( ii ) : outlines.CHole( ii, kk - 1 ); - aPlotter->PlotPoly( path, FILL_TYPE::NO_FILL ); + aPlotter->PlotPoly( path, FILL_T::NO_FILL ); } } @@ -751,7 +751,7 @@ void PlotLayerOutlines( BOARD* aBoard, PLOTTER* aPlotter, LSET aLayerMask, if( hole.x == hole.y ) { hole.x = std::min( smallDrill, hole.x ); - aPlotter->Circle( pad->GetPosition(), hole.x, FILL_TYPE::NO_FILL ); + aPlotter->Circle( pad->GetPosition(), hole.x, FILL_T::NO_FILL ); } else { @@ -771,9 +771,7 @@ void PlotLayerOutlines( BOARD* aBoard, PLOTTER* aPlotter, LSET aLayerMask, const PCB_VIA* via = dyn_cast( track ); if( via && via->IsOnLayer( layer ) ) // via holes can be not through holes - { - aPlotter->Circle( via->GetPosition(), via->GetDrillValue(), FILL_TYPE::NO_FILL ); - } + aPlotter->Circle( via->GetPosition(), via->GetDrillValue(), FILL_T::NO_FILL ); } } } @@ -990,7 +988,7 @@ void PlotSolderMaskLayer( BOARD *aBoard, PLOTTER* aPlotter, LSET aLayerMask, if( curr_area < poly_min_area_mm2 ) continue; - aPlotter->PlotPoly( path, FILL_TYPE::FILLED_SHAPE ); + aPlotter->PlotPoly( path, FILL_T::FILLED_SHAPE ); } #endif } @@ -1096,7 +1094,7 @@ static void FillNegativeKnockout( PLOTTER *aPlotter, const EDA_RECT &aBbbox ) aPlotter->SetColor( WHITE ); // Which will be plotted as black EDA_RECT area = aBbbox; area.Inflate( margin ); - aPlotter->Rect( area.GetOrigin(), area.GetEnd(), FILL_TYPE::FILLED_SHAPE ); + aPlotter->Rect( area.GetOrigin(), area.GetEnd(), FILL_T::FILLED_SHAPE ); aPlotter->SetColor( BLACK ); } diff --git a/pcbnew/plot_brditems_plotter.cpp b/pcbnew/plot_brditems_plotter.cpp index 024aada574..fcc7b47766 100644 --- a/pcbnew/plot_brditems_plotter.cpp +++ b/pcbnew/plot_brditems_plotter.cpp @@ -589,7 +589,7 @@ void BRDITEMS_PLOTTER::PlotFootprintGraphicItem( const FP_SHAPE* aShape ) for( const wxPoint& pt : pts ) poly.Append( pt ); - m_plotter->PlotPoly( poly, FILL_TYPE::FILLED_SHAPE, -1, &gbr_metadata ); + m_plotter->PlotPoly( poly, FILL_T::FILLED_SHAPE, -1, &gbr_metadata ); } } break; @@ -679,7 +679,7 @@ void BRDITEMS_PLOTTER::PlotFootprintGraphicItem( const FP_SHAPE* aShape ) for( int jj = 0; jj < tmpPoly.OutlineCount(); ++jj ) { SHAPE_LINE_CHAIN &poly = tmpPoly.Outline( jj ); - m_plotter->PlotPoly( poly, FILL_TYPE::FILLED_SHAPE, thickness, &gbr_metadata ); + m_plotter->PlotPoly( poly, FILL_T::FILLED_SHAPE, thickness, &gbr_metadata ); } } } @@ -811,8 +811,8 @@ void BRDITEMS_PLOTTER::PlotFilledAreas( const ZONE* aZone, const SHAPE_POLY_SET& { if( outline_thickness > 0 ) { - m_plotter->PlotPoly( outline, FILL_TYPE::NO_FILL, - outline_thickness, &gbr_metadata ); + m_plotter->PlotPoly( outline, FILL_T::NO_FILL, outline_thickness, + &gbr_metadata ); // Ensure the outline is closed: int last_idx = outline.PointCount() - 1; @@ -821,8 +821,7 @@ void BRDITEMS_PLOTTER::PlotFilledAreas( const ZONE* aZone, const SHAPE_POLY_SET& { m_plotter->ThickSegment( wxPoint( outline.CPoint( 0 ) ), wxPoint( outline.CPoint( last_idx ) ), - outline_thickness, - GetPlotMode(), &gbr_metadata ); + outline_thickness, GetPlotMode(), &gbr_metadata ); } } @@ -831,8 +830,8 @@ void BRDITEMS_PLOTTER::PlotFilledAreas( const ZONE* aZone, const SHAPE_POLY_SET& } else { - m_plotter->PlotPoly( outline, FILL_TYPE::FILLED_SHAPE, - outline_thickness, &gbr_metadata ); + m_plotter->PlotPoly( outline, FILL_T::FILLED_SHAPE, outline_thickness, + &gbr_metadata ); } } else @@ -962,7 +961,7 @@ void BRDITEMS_PLOTTER::PlotPcbShape( const PCB_SHAPE* aShape ) for( int jj = 0; jj < tmpPoly.OutlineCount(); ++jj ) { SHAPE_LINE_CHAIN& poly = tmpPoly.Outline( jj ); - m_plotter->PlotPoly( poly, FILL_TYPE::FILLED_SHAPE, thickness, &gbr_metadata ); + m_plotter->PlotPoly( poly, FILL_T::FILLED_SHAPE, thickness, &gbr_metadata ); } } } @@ -987,7 +986,7 @@ void BRDITEMS_PLOTTER::PlotPcbShape( const PCB_SHAPE* aShape ) for( const wxPoint& pt : pts ) poly.Append( pt ); - m_plotter->PlotPoly( poly, FILL_TYPE::FILLED_SHAPE, -1, &gbr_metadata ); + m_plotter->PlotPoly( poly, FILL_T::FILLED_SHAPE, -1, &gbr_metadata ); } break; diff --git a/qa/eeschema/test_lib_part.cpp b/qa/eeschema/test_lib_part.cpp index aa337c453b..b0a7bfb85e 100644 --- a/qa/eeschema/test_lib_part.cpp +++ b/qa/eeschema/test_lib_part.cpp @@ -29,8 +29,7 @@ #include // Code under test -#include -#include +#include #include #include "lib_field_test_utils.h" @@ -266,25 +265,25 @@ BOOST_AUTO_TEST_CASE( Compare ) m_part_no_data.SetNormal(); // Draw item list size comparison tests. - testPart.AddDrawItem( new LIB_RECTANGLE( &testPart ) ); - m_part_no_data.AddDrawItem( new LIB_RECTANGLE( &m_part_no_data ) ); + testPart.AddDrawItem( new LIB_SHAPE( &testPart, SHAPE_T::RECT ) ); + m_part_no_data.AddDrawItem( new LIB_SHAPE( &m_part_no_data, SHAPE_T::RECT ) ); BOOST_CHECK_EQUAL( m_part_no_data.Compare( testPart ), 0 ); - m_part_no_data.RemoveDrawItem( m_part_no_data.GetNextDrawItem( nullptr, LIB_RECTANGLE_T ) ); + m_part_no_data.RemoveDrawItem( m_part_no_data.GetNextDrawItem( nullptr, LIB_SHAPE_T ) ); BOOST_CHECK( m_part_no_data.Compare( testPart ) < 0 ); - testPart.RemoveDrawItem( testPart.GetNextDrawItem( nullptr, LIB_RECTANGLE_T ) ); - m_part_no_data.AddDrawItem( new LIB_RECTANGLE( &m_part_no_data ) ); + testPart.RemoveDrawItem( testPart.GetNextDrawItem( nullptr, LIB_SHAPE_T ) ); + m_part_no_data.AddDrawItem( new LIB_SHAPE( &m_part_no_data, SHAPE_T::RECT ) ); BOOST_CHECK( m_part_no_data.Compare( testPart ) > 0 ); - m_part_no_data.RemoveDrawItem( m_part_no_data.GetNextDrawItem( nullptr, LIB_RECTANGLE_T ) ); + m_part_no_data.RemoveDrawItem( m_part_no_data.GetNextDrawItem( nullptr, LIB_SHAPE_T ) ); // Draw item list contents comparison tests. - testPart.AddDrawItem( new LIB_RECTANGLE( &testPart ) ); - m_part_no_data.AddDrawItem( new LIB_ARC( &m_part_no_data ) ); + testPart.AddDrawItem( new LIB_SHAPE( &testPart, SHAPE_T::RECT ) ); + m_part_no_data.AddDrawItem( new LIB_SHAPE( &m_part_no_data, SHAPE_T::ARC ) ); BOOST_CHECK( m_part_no_data.Compare( testPart ) < 0 ); - m_part_no_data.RemoveDrawItem( m_part_no_data.GetNextDrawItem( nullptr, LIB_ARC_T ) ); + m_part_no_data.RemoveDrawItem( m_part_no_data.GetNextDrawItem( nullptr, LIB_SHAPE_T ) ); m_part_no_data.AddDrawItem( new LIB_PIN( &m_part_no_data ) ); BOOST_CHECK( m_part_no_data.Compare( testPart ) > 0 ); m_part_no_data.RemoveDrawItem( m_part_no_data.GetNextDrawItem( nullptr, LIB_PIN_T ) ); - testPart.RemoveDrawItem( testPart.GetNextDrawItem( nullptr, LIB_RECTANGLE_T ) ); + testPart.RemoveDrawItem( testPart.GetNextDrawItem( nullptr, LIB_SHAPE_T ) ); // Footprint filter array comparison tests. wxArrayString footPrintFilters;