From be9ce460f829edc40aaa4d19ec1bea2d5f2e397f Mon Sep 17 00:00:00 2001 From: Alex Shvartzkop Date: Wed, 2 Jul 2025 18:03:24 +0300 Subject: [PATCH] EasyEDA Std import: support multiple consecutive arc parameter sets. Fixes https://gitlab.com/kicad/code/kicad/-/issues/21238 (cherry picked from commit 90f5cbf0034a1f08a40836259bd3e2f65a59e193) --- common/io/easyeda/easyeda_parser_base.cpp | 72 ++++++++++++++--------- 1 file changed, 45 insertions(+), 27 deletions(-) diff --git a/common/io/easyeda/easyeda_parser_base.cpp b/common/io/easyeda/easyeda_parser_base.cpp index bc759c5dcb..1d0a69d90d 100644 --- a/common/io/easyeda/easyeda_parser_base.cpp +++ b/common/io/easyeda/easyeda_parser_base.cpp @@ -211,41 +211,59 @@ EASYEDA_PARSER_BASE::ParseLineChains( const wxString& data, int aMaxError, bool } else if( sym == 'A' ) { - wxString radX, radY, unknown, farFlag, cwFlag, endX, endY; + // Arc command can have multiple consecutive arc parameter sets + while( true ) + { + if( pos >= data.size() ) + break; - readNumber( radX ); - readNumber( radY ); - readNumber( unknown ); - readNumber( farFlag ); - readNumber( cwFlag ); - readNumber( endX ); - readNumber( endY ); + wxUniChar ch = data[pos]; - bool isFar = farFlag == wxS( "1" ); - bool cw = cwFlag == wxS( "1" ); - VECTOR2D rad( Convert( radX ), Convert( radY ) ); - VECTOR2D end( Convert( endX ), Convert( endY ) ); + while( ch == ' ' || ch == ',' ) + { + if( ++pos >= data.size() ) + break; - VECTOR2D start = prevPt; - VECTOR2D delta = end - start; + ch = data[pos]; + } - double d = delta.EuclideanNorm(); - double h = sqrt( std::max( 0.0, rad.x * rad.x - d * d / 4 ) ); + if( !isdigit( ch ) && ch != '-' ) + break; - //( !far && cw ) => h - //( far && cw ) => -h - //( !far && !cw ) => -h - //( far && !cw ) => h - VECTOR2D arcCenter = - start + delta / 2 + delta.Perpendicular().Resize( ( isFar ^ cw ) ? h : -h ); + wxString radX, radY, unknown, farFlag, cwFlag, endX, endY; - SHAPE_ARC arc; - arc.ConstructFromStartEndCenter( RelPos( start ), RelPos( end ), RelPos( arcCenter ), - !cw ); + readNumber( radX ); + readNumber( radY ); + readNumber( unknown ); + readNumber( farFlag ); + readNumber( cwFlag ); + readNumber( endX ); + readNumber( endY ); - chain.Append( arc, aMaxError ); + bool isFar = farFlag == wxS( "1" ); + bool cw = cwFlag == wxS( "1" ); + VECTOR2D rad( Convert( radX ), Convert( radY ) ); + VECTOR2D end( Convert( endX ), Convert( endY ) ); - prevPt = end; + VECTOR2D start = prevPt; + VECTOR2D delta = end - start; + + double d = delta.EuclideanNorm(); + double h = sqrt( std::max( 0.0, rad.x * rad.x - d * d / 4 ) ); + + //( !far && cw ) => h + //( far && cw ) => -h + //( !far && !cw ) => -h + //( far && !cw ) => h + VECTOR2D arcCenter = start + delta / 2 + delta.Perpendicular().Resize( ( isFar ^ cw ) ? h : -h ); + + SHAPE_ARC arc; + arc.ConstructFromStartEndCenter( RelPos( start ), RelPos( end ), RelPos( arcCenter ), !cw ); + + chain.Append( arc, aMaxError ); + + prevPt = end; + } } else if( sym == 'C' ) {