From e55263be007252d302fffa594177bf92150786da Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Wed, 24 May 2023 18:21:50 +0200 Subject: [PATCH] Pcbnew: fix crash when trying to save a board with a text with overbar and using a non Kicad font PCB_PLUGIN::formatRenderCache() was considering all shapes in cache are polygons, but this is not true: some items can be stroke shapes. From stable branch Fixes #14804 https://gitlab.com/kicad/code/kicad/-/issues/14804 --- pcbnew/plugins/kicad/pcb_plugin.cpp | 35 ++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/pcbnew/plugins/kicad/pcb_plugin.cpp b/pcbnew/plugins/kicad/pcb_plugin.cpp index d897285c54..fc13df542b 100644 --- a/pcbnew/plugins/kicad/pcb_plugin.cpp +++ b/pcbnew/plugins/kicad/pcb_plugin.cpp @@ -476,16 +476,45 @@ void PCB_PLUGIN::formatPolyPts( const SHAPE_LINE_CHAIN& outline, int aNestLevel, void PCB_PLUGIN::formatRenderCache( const EDA_TEXT* aText, int aNestLevel ) const { - const wxString& shownText = aText->GetShownText( true ); + wxString resolvedText( aText->GetShownText( true ) ); std::vector>* cache = aText->GetRenderCache( aText->GetFont(), - shownText ); + resolvedText ); m_out->Print( aNestLevel, "(render_cache %s %s\n", - m_out->Quotew( shownText ).c_str(), + m_out->Quotew( resolvedText ).c_str(), EDA_UNIT_UTILS::FormatAngle( aText->GetDrawRotation() ).c_str() ); for( const std::unique_ptr& baseGlyph : *cache ) { + // A glyph is not aways a polygon. it can be a stroke (for instance a text with overbar) + // we save only polygons from cache + // So convert any stroke to a polygon + if( baseGlyph->IsStroke() ) + { + const KIFONT::STROKE_GLYPH& strokeGlyph = static_cast( *baseGlyph ); + + for( const std::vector& points : strokeGlyph ) + { + SHAPE_LINE_CHAIN outline; + + for( size_t idx = 0; idx < points.size(); idx++ ) + outline.Append( (int)points[idx].x, (int)points[idx].y ); + + for( int idx = 1; idx < outline.PointCount(); idx++ ) + { + SHAPE_POLY_SET buffer; + TransformOvalToPolygon( buffer, outline.CPoint( idx-1 ), outline.CPoint( idx ), + aText->GetTextThickness(), ARC_LOW_DEF, ERROR_INSIDE ); + + m_out->Print( aNestLevel + 1, "(polygon\n" ); + formatPolyPts( buffer.Outline(0), aNestLevel + 2, true ); + m_out->Print( aNestLevel + 1, ")\n" ); + } + } + + continue; + } + KIFONT::OUTLINE_GLYPH* glyph = static_cast( baseGlyph.get() ); if( glyph->OutlineCount() > 0 )