sch_sexpr_parser.cpp: allows reading a polyline descr with more than 2 points

In symbols, a polyline descr is already a true polyline / polygon descr.
In schematic, a polyline descr was restricted to only 2 points (a line).
A true polyline / polygon descr is now allowed in schematic that support already
polygons.
For compatibility reason, a 2 points polygon (SCH_SHAPE) is converted to a SCH_LINE.
This commit is contained in:
jean-pierre charras 2022-03-27 10:31:21 +02:00
parent 48dd810cd1
commit 38bd612c01
3 changed files with 95 additions and 1 deletions

View File

@ -2289,6 +2289,35 @@ void SCH_SEXPR_PARSER::ParseSchematic( SCH_SHEET* aSheet, bool aIsCopyableOnly,
break; break;
case T_polyline: case T_polyline:
{
// polyline keyword is used in eeschema both for SCH_SHAPE and SCH_LINE items.
// In symbols it describes a polygon, having n corners and can be filled
// In schematic it describes a line (with no fill descr), but could be extended to a
// polygon (for instance when importing files) because the schematic handles all SCH_SHAPE.
// parseSchPolyLine() returns always a SCH_SHAPE, io convert it to a simple SCH_LINE
// For compatibility reasons, keep SCH_SHAPE for a polygon and convert to SCH_LINE
// when the item has only 2 corners, similar to a SCH_LINE
SCH_SHAPE* poly = parseSchPolyLine();
if( poly->GetPointCount() > 2 )
screen->Append( poly );
else
{
// For SCH_SHAPE having only 2 points, this is a "old" SCH_LINE entity.
// So convert the SCH_SHAPE to a simple SCH_LINE
SCH_LINE* line = new SCH_LINE( VECTOR2I(), LAYER_NOTES );
SHAPE_LINE_CHAIN& outline = poly->GetPolyShape().Outline(0);
line->SetStartPoint( outline.CPoint(0) );
line->SetEndPoint( outline.CPoint(1) );
line->SetStroke( poly->GetStroke() );
screen->Append( line );
delete poly;
}
}
break;
case T_bus: case T_bus:
case T_wire: case T_wire:
screen->Append( parseLine() ); screen->Append( parseLine() );
@ -2919,8 +2948,72 @@ SCH_BUS_WIRE_ENTRY* SCH_SEXPR_PARSER::parseBusEntry()
} }
SCH_SHAPE* SCH_SEXPR_PARSER::parseSchPolyLine()
{
T token;
STROKE_PARAMS stroke( Mils2iu( DEFAULT_LINE_WIDTH_MILS ), PLOT_DASH_TYPE::DEFAULT );
FILL_PARAMS fill;
int layer = LAYER_NOTES;
std::unique_ptr<SCH_SHAPE> polyline = std::make_unique<SCH_SHAPE>( SHAPE_T::POLY, layer );
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
{
if( token != T_LEFT )
Expecting( T_LEFT );
token = NextTok();
switch( token )
{
case T_pts:
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
{
if( token != T_LEFT )
Expecting( T_LEFT );
token = NextTok();
if( token != T_xy )
Expecting( "xy" );
polyline->AddPoint( parseXY() );
NeedRIGHT();
}
break;
case T_stroke:
parseStroke( stroke );
polyline->SetStroke( stroke );
break;
case T_fill:
parseFill( fill );
polyline->SetFillMode( fill.m_FillType );
polyline->SetFillColor( fill.m_Color );
break;
case T_uuid:
NeedSYMBOL();
const_cast<KIID&>( polyline->m_Uuid ) = parseKIID();
NeedRIGHT();
break;
default:
Expecting( "pts, uuid, stroke, or fill" );
}
}
return polyline.release();
}
SCH_LINE* SCH_SEXPR_PARSER::parseLine() SCH_LINE* SCH_SEXPR_PARSER::parseLine()
{ {
// Note: T_polyline is deprecated in this code: it is now handled by
// parseSchPolyLine() that can handle true polygons, and not only one segment.
T token; T token;
STROKE_PARAMS stroke( Mils2iu( DEFAULT_LINE_WIDTH_MILS ), PLOT_DASH_TYPE::DEFAULT ); STROKE_PARAMS stroke( Mils2iu( DEFAULT_LINE_WIDTH_MILS ), PLOT_DASH_TYPE::DEFAULT );
int layer; int layer;

View File

@ -195,6 +195,7 @@ class SCH_SEXPR_PARSER : public SCHEMATIC_LEXER
SCH_NO_CONNECT* parseNoConnect(); SCH_NO_CONNECT* parseNoConnect();
SCH_BUS_WIRE_ENTRY* parseBusEntry(); SCH_BUS_WIRE_ENTRY* parseBusEntry();
SCH_LINE* parseLine(); SCH_LINE* parseLine();
SCH_SHAPE* parseSchPolyLine();
SCH_SHAPE* parseSchArc(); SCH_SHAPE* parseSchArc();
SCH_SHAPE* parseSchCircle(); SCH_SHAPE* parseSchCircle();
SCH_SHAPE* parseSchRectangle(); SCH_SHAPE* parseSchRectangle();

View File

@ -145,7 +145,7 @@ protected:
if( m_isSymbolEditor ) if( m_isSymbolEditor )
{ {
SYMBOL_EDIT_FRAME* editFrame = dynamic_cast<SYMBOL_EDIT_FRAME*>( m_frame ); SYMBOL_EDIT_FRAME* editFrame = dynamic_cast<SYMBOL_EDIT_FRAME*>( m_frame );
wxASSERT( editFrame ); wxCHECK_RET( editFrame, wxT( "editFrame is null" ) );
editFrame->SaveCopyInUndoList( static_cast<LIB_ITEM*>( aItem ), aType, aAppend ); editFrame->SaveCopyInUndoList( static_cast<LIB_ITEM*>( aItem ), aType, aAppend );
} }