From 7d032f9c2ff08cbed282930a6e1b6d9802430178 Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Mon, 10 Jan 2022 01:53:01 +0000 Subject: [PATCH] Outline font rendering for Cairo, plotter, printer and 3D viewer. Fixes https://gitlab.com/kicad/code/kicad/issues/10319 --- .../3d_canvas/create_3Dgraphic_brd_items.cpp | 119 ++++++------ common/CMakeLists.txt | 2 +- common/basic_gal.cpp | 183 ------------------ common/callback_gal.cpp | 53 +++++ common/eda_text.cpp | 123 +++++------- common/font/fontconfig.cpp | 40 ++-- common/font/glyph.cpp | 6 +- common/font/outline_font.cpp | 3 - common/gal/cairo/cairo_gal.cpp | 48 ++--- common/gal/opengl/opengl_gal.cpp | 9 +- common/gr_basic.cpp | 2 +- common/gr_text.cpp | 90 ++++++--- common/plotters/plotter.cpp | 31 ++- eeschema/lib_field.cpp | 4 +- eeschema/lib_pin.cpp | 73 ++++--- eeschema/lib_text.cpp | 4 +- eeschema/sch_field.cpp | 4 +- include/basic_gal.h | 181 ----------------- include/callback_gal.h | 60 ++++++ include/eda_text.h | 29 +-- include/font/glyph.h | 7 +- include/gr_text.h | 73 ++++--- include/plotters/plotter.h | 2 +- .../dialogs/dialog_text_properties_base.cpp | 4 +- .../dialogs/dialog_text_properties_base.fbp | 4 +- pcbnew/fp_text.cpp | 29 ++- pcbnew/pcb_text.cpp | 28 ++- 27 files changed, 491 insertions(+), 720 deletions(-) delete mode 100644 common/basic_gal.cpp create mode 100644 common/callback_gal.cpp delete mode 100644 include/basic_gal.h create mode 100644 include/callback_gal.h diff --git a/3d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp b/3d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp index d9c4a598dd..31b961cec5 100644 --- a/3d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp +++ b/3d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2015-2016 Mario Luzeiro - * Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 1992-2022 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 @@ -56,38 +56,6 @@ #include -struct CALLBACK_DATA -{ - const BOARD_ITEM* m_BoardItem; - CONTAINER_2D_BASE* m_Container; - int m_TextWidth; - float m_BiuTo3Dunits; -}; - - -// This is a call back function, used by GRText to draw the 3D text shape: -void addTextSegmToContainer( int x0, int y0, int xf, int yf, void* aData ) -{ - CALLBACK_DATA* data = static_cast( aData ); - - const SFVEC2F start3DU( x0 * data->m_BiuTo3Dunits, -y0 * data->m_BiuTo3Dunits ); - const SFVEC2F end3DU ( xf * data->m_BiuTo3Dunits, -yf * data->m_BiuTo3Dunits ); - - if( Is_segment_a_circle( start3DU, end3DU ) ) - { - data->m_Container->Add( new FILLED_CIRCLE_2D( start3DU, - data->m_TextWidth * data->m_BiuTo3Dunits / 2, - *data->m_BoardItem ) ); - } - else - { - data->m_Container->Add( new ROUND_SEGMENT_2D( start3DU, end3DU, - data->m_TextWidth * data->m_BiuTo3Dunits, - *data->m_BoardItem ) ); - } -} - - // Based on // void PCB_TEXT::TransformTextShapeWithClearanceToPolygon // board_items_to_polygon_shape_transform.cpp @@ -99,23 +67,40 @@ void BOARD_ADAPTER::addShapeWithClearance( const PCB_TEXT* aText, CONTAINER_2D_B if( aText->IsMirrored() ) size.x = -size.x; - CALLBACK_DATA callbackData; - callbackData.m_BoardItem = aText; - callbackData.m_Container = aDstContainer; - callbackData.m_TextWidth = aText->GetEffectiveTextPenWidth() + ( 2 * aClearanceValue ); - callbackData.m_BiuTo3Dunits = m_biuTo3Dunits; - - // not actually used, but needed by GRText - const COLOR4D dummy_color; - // Use the actual text width to generate segments. The segment position depend on // text thickness and justification - bool isBold = aText->IsBold(); - int penWidth = aText->GetEffectiveTextPenWidth(); + int penWidth = aText->GetEffectiveTextPenWidth(); + int adjustedWidth = penWidth + ( 2 * aClearanceValue ); - GRText( nullptr, aText->GetTextPos(), dummy_color, aText->GetShownText(), aText->GetTextAngle(), - size, aText->GetHorizJustify(), aText->GetVertJustify(), penWidth, aText->IsItalic(), - isBold, aText->GetDrawFont(), addTextSegmToContainer, &callbackData ); + GRText( aText->GetTextPos(), aText->GetShownText(), aText->GetTextAngle(), size, + aText->GetHorizJustify(), aText->GetVertJustify(), penWidth, aText->IsItalic(), + aText->IsBold(), aText->GetDrawFont(), + [&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2 ) + { + const SFVEC2F start3DU( aPt1.x * m_biuTo3Dunits, -aPt1.y * m_biuTo3Dunits ); + const SFVEC2F end3DU ( aPt1.x * m_biuTo3Dunits, -aPt2.y * m_biuTo3Dunits ); + + if( Is_segment_a_circle( start3DU, end3DU ) ) + { + aDstContainer->Add( new FILLED_CIRCLE_2D( start3DU, + adjustedWidth * m_biuTo3Dunits / 2, + *aText ) ); + } + else + { + aDstContainer->Add( new ROUND_SEGMENT_2D( start3DU, end3DU, + adjustedWidth * m_biuTo3Dunits, + *aText ) ); + } + }, + [&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2, const VECTOR2I& aPt3 ) + { + const SFVEC2F a3DU( aPt1.x * m_biuTo3Dunits, -aPt1.y * m_biuTo3Dunits ); + const SFVEC2F b3DU( aPt2.x * m_biuTo3Dunits, -aPt2.y * m_biuTo3Dunits ); + const SFVEC2F c3DU( aPt3.x * m_biuTo3Dunits, -aPt3.y * m_biuTo3Dunits ); + + aDstContainer->Add( new TRIANGLE_2D( a3DU, b3DU, c3DU, *aText ) ); + } ); } @@ -161,9 +146,7 @@ void BOARD_ADAPTER::addShapeWithClearance( const PCB_DIMENSION_BASE* aDimension, default: break; } - } - } @@ -228,22 +211,38 @@ void BOARD_ADAPTER::addFootprintShapesWithClearance( const FOOTPRINT* aFootprint for( FP_TEXT* text : texts ) { - CALLBACK_DATA callbackData; - callbackData.m_BoardItem = &aFootprint->Value(); - callbackData.m_Container = aDstContainer; - callbackData.m_BiuTo3Dunits = m_biuTo3Dunits; - callbackData.m_TextWidth = text->GetEffectiveTextPenWidth() + ( 2 * aInflateValue ); - VECTOR2I size = text->GetTextSize(); - bool isBold = text->IsBold(); - int penWidth = text->GetEffectiveTextPenWidth(); + int penWidth = text->GetEffectiveTextPenWidth(); + int adjustedWidth = penWidth + ( 2 * aInflateValue ); if( text->IsMirrored() ) size.x = -size.x; - GRText( nullptr, text->GetTextPos(), BLACK, text->GetShownText(), text->GetDrawRotation(), - size, text->GetHorizJustify(), text->GetVertJustify(), penWidth, text->IsItalic(), - isBold, text->GetDrawFont(), addTextSegmToContainer, &callbackData ); + GRText( text->GetTextPos(), text->GetShownText(), text->GetTextAngle(), size, + text->GetHorizJustify(), text->GetVertJustify(), penWidth, text->IsItalic(), + text->IsBold(), text->GetDrawFont(), + [&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2 ) + { + const SFVEC2F start3DU( aPt1.x * m_biuTo3Dunits, -aPt1.y * m_biuTo3Dunits ); + const SFVEC2F end3DU ( aPt1.x * m_biuTo3Dunits, -aPt2.y * m_biuTo3Dunits ); + + if( Is_segment_a_circle( start3DU, end3DU ) ) + { + aDstContainer->Add( new FILLED_CIRCLE_2D( start3DU, + adjustedWidth * m_biuTo3Dunits / 2, + aFootprint->Value() ) ); + } + else + { + aDstContainer->Add( new ROUND_SEGMENT_2D( start3DU, end3DU, + adjustedWidth * m_biuTo3Dunits, + aFootprint->Value() ) ); + } + }, + [&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2, const VECTOR2I& aPt3 ) + { + //FONT TODO: add triangle to container + } ); } } diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 2915ef9fb4..5647858755 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -21,7 +21,7 @@ include_directories( set( GAL_SRCS # Common part - basic_gal.cpp + callback_gal.cpp draw_panel_gal.cpp gl_context_mgr.cpp newstroke_font.cpp diff --git a/common/basic_gal.cpp b/common/basic_gal.cpp deleted file mode 100644 index 05791f870c..0000000000 --- a/common/basic_gal.cpp +++ /dev/null @@ -1,183 +0,0 @@ -/* - * This program source code file is part of KiCad, a free EDA CAD application. - * - * Copyright (C) 2018 Jean-Pierre Charras, jp.charras at wanadoo.fr - * Copyright (C) 1992-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 - */ - -/** - * Implement a very basic GAL used to draw, plot and convert texts in segments - * for DRC functions, using the common GAL functions. - * Draw functions use wxDC. - * Plot functions use a PLOTTER - * Convert texts in segments use a callback function created by the caller - * @file basic_gal.cpp - */ - -#include -#include -#include - -#include - -using namespace KIGFX; - -KIGFX::GAL_DISPLAY_OPTIONS basic_displayOptions; - -// the basic GAL doesn't get an external display option object -BASIC_GAL basic_gal( basic_displayOptions ); - - -const VECTOR2D BASIC_GAL::transform( const VECTOR2D& aPoint ) const -{ - VECTOR2D point = aPoint + m_transform.m_moveOffset - m_transform.m_rotCenter; - point = point.Rotate( m_transform.m_rotAngle ) + m_transform.m_rotCenter; - return point; -} - - -void BASIC_GAL::doDrawPolyline( const std::vector& aLocalPointList ) -{ - if( m_DC ) - { - if( m_isFillEnabled ) - { - GRPoly( m_isClipped ? &m_clipBox : nullptr, m_DC, aLocalPointList.size(), - &aLocalPointList[0], 0, GetLineWidth(), m_Color, m_Color ); - } - else - { - for( unsigned ii = 1; ii < aLocalPointList.size(); ++ii ) - { - GRCSegm( m_isClipped ? &m_clipBox : nullptr, m_DC, aLocalPointList[ ii - 1], - aLocalPointList[ii], GetLineWidth(), m_Color ); - } - } - } - else if( m_plotter ) - { - m_plotter->MoveTo( aLocalPointList[0] ); - - for( unsigned ii = 1; ii < aLocalPointList.size(); ii++ ) - { - m_plotter->LineTo( aLocalPointList[ii] ); - } - - m_plotter->PenFinish(); - } - else if( m_callback ) - { - for( unsigned ii = 1; ii < aLocalPointList.size(); ii++ ) - { - m_callback( aLocalPointList[ ii - 1].x, aLocalPointList[ ii - 1].y, - aLocalPointList[ii].x, aLocalPointList[ii].y, m_callbackData ); - } - } -} - - -void BASIC_GAL::DrawPolyline( const std::deque& aPointList ) -{ - if( aPointList.size() < 2 ) - return; - - std::vector polyline_corners; - - for( const VECTOR2D& pt : aPointList ) - polyline_corners.emplace_back( (VECTOR2I) transform( pt ) ); - - doDrawPolyline( polyline_corners ); -} - - -void BASIC_GAL::DrawPolyline( const std::vector& aPointList ) -{ - if( aPointList.size() < 2 ) - return; - - std::vector polyline_corners; - - for( const VECTOR2D& pt : aPointList ) - polyline_corners.emplace_back( (VECTOR2I) transform( pt ) ); - - doDrawPolyline( polyline_corners ); -} - - -void BASIC_GAL::DrawPolyline( const VECTOR2D aPointList[], int aListSize ) -{ - if( aListSize < 2 ) - return; - - std::vector polyline_corners; - - for( int ii = 0; ii < aListSize; ++ii ) - polyline_corners.emplace_back( (VECTOR2I) transform( aPointList[ii] ) ); - - doDrawPolyline( polyline_corners ); -} - - -void BASIC_GAL::DrawLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint ) -{ - VECTOR2D startVector = transform( aStartPoint ); - VECTOR2D endVector = transform( aEndPoint ); - - if( m_DC ) - { - if( m_isFillEnabled ) - { - GRLine( m_isClipped ? &m_clipBox : nullptr, m_DC, startVector.x, startVector.y, - endVector.x, endVector.y, GetLineWidth(), m_Color ); - } - else - { - GRCSegm( m_isClipped ? &m_clipBox : nullptr, m_DC, startVector.x, startVector.y, - endVector.x, endVector.y, GetLineWidth(), 0, m_Color ); - } - } - else if( m_plotter ) - { - m_plotter->MoveTo( wxPoint( startVector.x, startVector.y ) ); - m_plotter->LineTo( wxPoint( endVector.x, endVector.y ) ); - m_plotter->PenFinish(); - } - else if( m_callback ) - { - m_callback( startVector.x, startVector.y, endVector.x, endVector.y, m_callbackData ); - } -} - - -void BASIC_GAL::DrawGlyph( const KIFONT::GLYPH& aGlyph, int aNth, int aTotal ) -{ - if( aGlyph.IsStroke() ) - { - const auto& strokeGlyph = static_cast( aGlyph ); - - for( const std::vector& pointList : strokeGlyph ) - DrawPolyline( pointList ); - } -#if 0 // FONT TODO - else if( aGlyph.IsOutline() ) - { - } -#endif -} diff --git a/common/callback_gal.cpp b/common/callback_gal.cpp new file mode 100644 index 0000000000..3d26ce0b56 --- /dev/null +++ b/common/callback_gal.cpp @@ -0,0 +1,53 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2022 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 + + +using namespace KIGFX; + + +void CALLBACK_GAL::DrawGlyph( const KIFONT::GLYPH& aGlyph, int aNth, int aTotal ) +{ + if( aGlyph.IsStroke() ) + { + const KIFONT::STROKE_GLYPH& glyph = static_cast( aGlyph ); + + for( const std::vector& pointList : glyph ) + { + for( size_t ii = 1; ii < pointList.size(); ii++ ) + m_strokeCallback( pointList[ ii - 1], pointList[ii] ); + } + } + else if( aGlyph.IsOutline() ) + { + const KIFONT::OUTLINE_GLYPH& glyph = static_cast( aGlyph ); + + glyph.Triangulate( m_triangleCallback ); + } +} + + diff --git a/common/eda_text.cpp b/common/eda_text.cpp index 28b7a41a5e..5da7791dcd 100644 --- a/common/eda_text.cpp +++ b/common/eda_text.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr - * Copyright (C) 2004-2021 KiCad Developers, see change_log.txt for contributors. + * Copyright (C) 2004-2022 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 @@ -30,20 +30,19 @@ #include // for max #include // for NULL #include // for swap -#include // for vector +#include -#include // for EDA_ITEM +#include #include -#include // for BASIC_GAL, basic_gal +#include #include // for Mils2iu -#include -#include // for EDA_RECT +#include #include // for EDA_TEXT, TEXT_EFFECTS, GR_TEXT_VJUSTIF... #include // for COLOR4D, COLOR4D::BLACK -#include // for GRText +#include #include // for UnescapeString #include // for KiROUND -#include // for VECTOR2D +#include #include #include #include // for RotatePoint @@ -55,29 +54,13 @@ #include #include // for wxASSERT -#include // wxString, wxArrayString -#include // for wxPoint,wxSize +#include +#include // for wxPoint, wxSize class OUTPUTFORMATTER; class wxFindReplaceData; -void addTextSegmToPoly( int x0, int y0, int xf, int yf, void* aData ) -{ - TSEGM_2_POLY_PRMS* prm = static_cast( aData ); - TransformOvalToPolygon( *prm->m_cornerBuffer, VECTOR2I( x0, y0 ), VECTOR2I( xf, yf ), - prm->m_textWidth, prm->m_error, ERROR_INSIDE ); -} - - -void addTextSegmToShape( int x0, int y0, int xf, int yf, void* aData ) -{ - TSEGM_2_SHAPE_PRMS* prm = static_cast( aData ); - prm->m_shape->AddShape( new SHAPE_SEGMENT( VECTOR2I( x0, y0 ), VECTOR2I( xf, yf ), - prm->m_penWidth ) ); -} - - GR_TEXT_H_ALIGN_T EDA_TEXT::MapHorizJustify( int aHorizJustify ) { wxASSERT( aHorizJustify >= GR_TEXT_H_ALIGN_LEFT && aHorizJustify <= GR_TEXT_H_ALIGN_RIGHT ); @@ -726,8 +709,8 @@ void EDA_TEXT::printOneLineOfText( const RENDER_SETTINGS* aSettings, const VECTO if( IsMirrored() ) size.x = -size.x; - GRText( DC, aOffset + aPos, aColor, aText, GetTextAngle(), size, GetHorizJustify(), - GetVertJustify(), penWidth, IsItalic(), IsBold(), GetDrawFont() ); + GRPrintText( DC, aOffset + aPos, aColor, aText, GetTextAngle(), size, GetHorizJustify(), + GetVertJustify(), penWidth, IsItalic(), IsBold(), GetDrawFont() ); } @@ -844,64 +827,48 @@ std::shared_ptr EDA_TEXT::GetEffectiveTextShape( ) const { std::shared_ptr shape = std::make_shared(); KIFONT::FONT* font = GetDrawFont(); + wxSize size = GetTextSize(); + int penWidth = GetEffectiveTextPenWidth(); + bool forceBold = true; - if( font->IsOutline() ) + if( IsMirrored() ) + size.x = -size.x; + + wxArrayString strings_list; + std::vector positions; + + if( IsMultilineAllowed() ) { - // Make sure the cache is up-to-date before using it - (void) GetRenderCache( m_render_cache_text ); - - for( std::unique_ptr& baseGlyph : m_render_cache ) - { - KIFONT::OUTLINE_GLYPH* glyph = static_cast( baseGlyph.get() ); - - glyph->Triangulate( - [&]( int aPolygonIndex, const VECTOR2D& aVertex1, const VECTOR2D& aVertex2, - const VECTOR2D& aVertex3 ) - { - SHAPE_SIMPLE* triShape = new SHAPE_SIMPLE; - - triShape->Append( aVertex1 ); - triShape->Append( aVertex2 ); - triShape->Append( aVertex3 ); - - shape->AddShape( triShape ); - } ); - } + wxStringSplit( GetShownText(), strings_list, wxChar('\n') ); + positions.reserve( strings_list.Count() ); + GetLinePositions( positions, strings_list.Count() ); } else { - wxSize size = GetTextSize(); - int penWidth = GetEffectiveTextPenWidth(); - bool forceBold = true; + strings_list.Add( GetShownText() ); + positions.push_back( GetDrawPos() ); + } - TSEGM_2_SHAPE_PRMS prms; - prms.m_penWidth = penWidth; - prms.m_shape = shape.get(); + for( unsigned ii = 0; ii < strings_list.Count(); ii++ ) + { + GRText( positions[ii], strings_list.Item( ii ), GetDrawRotation(), size, + GetDrawHorizJustify(), GetDrawVertJustify(), penWidth, IsItalic(), forceBold, font, + // Stroke callback + [&]( const VECTOR2D& aPt1, const VECTOR2D& aPt2 ) + { + shape->AddShape( new SHAPE_SEGMENT( aPt1, aPt2, penWidth ) ); + }, + // Triangulation callback + [&]( const VECTOR2D& aPt1, const VECTOR2D& aPt2, const VECTOR2D& aPt3 ) + { + SHAPE_SIMPLE* triShape = new SHAPE_SIMPLE; - if( IsMirrored() ) - size.x = -size.x; + triShape->Append( aPt1 ); + triShape->Append( aPt2 ); + triShape->Append( aPt3 ); - if( IsMultilineAllowed() ) - { - wxArrayString strings_list; - wxStringSplit( GetShownText(), strings_list, wxChar('\n') ); - std::vector positions; - positions.reserve( strings_list.Count() ); - GetLinePositions( positions, strings_list.Count() ); - - for( unsigned ii = 0; ii < strings_list.Count(); ii++ ) - { - GRText( nullptr, positions[ii], COLOR4D::BLACK, strings_list.Item( ii ), - GetDrawRotation(), size, GetDrawHorizJustify(), GetDrawVertJustify(), - penWidth, IsItalic(), forceBold, font, addTextSegmToShape, &prms ); - } - } - else - { - GRText( nullptr, GetDrawPos(), COLOR4D::BLACK, GetShownText(), - GetDrawRotation(), size, GetDrawHorizJustify(), GetDrawVertJustify(), - penWidth, IsItalic(), forceBold, font, addTextSegmToShape, &prms ); - } + shape->AddShape( triShape ); + } ); } return shape; diff --git a/common/font/fontconfig.cpp b/common/font/fontconfig.cpp index 5bdf8fc904..61bed644f2 100644 --- a/common/font/fontconfig.cpp +++ b/common/font/fontconfig.cpp @@ -61,7 +61,9 @@ bool FONTCONFIG::FindFont( const wxString& aFontName, wxString& aFontFile ) FcResult r = FcResultNoMatch; FcPattern* font = FcFontMatch( nullptr, pat, &r ); - bool ok = false; + wxString fontName; + bool ok = false; + bool substituted = false; if( font ) { @@ -74,23 +76,29 @@ bool FONTCONFIG::FindFont( const wxString& aFontName, wxString& aFontFile ) FcChar8* family = nullptr; FcChar8* style = nullptr; - FcPatternGetString( font, FC_FAMILY, 0, &family ); - FcPatternGetString( font, FC_STYLE, 0, &style ); - - wxString fontName( family ); - wxString styleStr( style ); - - if( !styleStr.IsEmpty() ) + if( FcPatternGetString( font, FC_FAMILY, 0, &family ) == FcResultMatch ) { - styleStr.Replace( " ", ":" ); - fontName += ":" + styleStr; + fontName = wxString::FromUTF8( (char*) family ); + + if( FcPatternGetString( font, FC_STYLE, 0, &style ) == FcResultMatch ) + { + wxString styleStr = wxString::FromUTF8( (char*) style ); + + if( !styleStr.IsEmpty() ) + { + styleStr.Replace( " ", ":" ); + fontName += ":" + styleStr; + } + } + + // TODO: report Regular vs Book, Italic vs Oblique, etc. or filter them out? + + if( aFontName.Contains( ":" ) ) + substituted = aFontName.CmpNoCase( fontName ) != 0; + else + substituted = !fontName.StartsWith( aFontName ); } - // TODO: report Regular vs Book, Italic vs Oblique, etc. or filter them out? - - if( aFontName.CmpNoCase( fontName ) != 0 ) - wxLogWarning( _( "Font '%s' not found; substituting '%s'." ), aFontName, fontName ); - ok = true; } @@ -99,6 +107,8 @@ bool FONTCONFIG::FindFont( const wxString& aFontName, wxString& aFontFile ) if( !ok ) wxLogWarning( _( "Error loading font '%s'." ), aFontName ); + else if( substituted ) + wxLogWarning( _( "Font '%s' not found; substituting '%s'." ), aFontName, fontName ); FcPatternDestroy( pat ); return ok; diff --git a/common/font/glyph.cpp b/common/font/glyph.cpp index d1e0b49dae..eaea30c88d 100644 --- a/common/font/glyph.cpp +++ b/common/font/glyph.cpp @@ -116,7 +116,9 @@ BOX2D OUTLINE_GLYPH::BoundingBox() } -void OUTLINE_GLYPH::Triangulate( TRIANGULATE_CALLBACK aCallback ) const +void OUTLINE_GLYPH::Triangulate( std::function aCallback ) const { const_cast( this )->CacheTriangulation(); @@ -128,7 +130,7 @@ void OUTLINE_GLYPH::Triangulate( TRIANGULATE_CALLBACK aCallback ) const { VECTOR2I a, b, c; polygon->GetTriangle( j, a, b, c ); - aCallback( i, a, b, c ); + aCallback( a, b, c ); } } } diff --git a/common/font/outline_font.cpp b/common/font/outline_font.cpp index c1c06a5f45..cc6803f257 100644 --- a/common/font/outline_font.cpp +++ b/common/font/outline_font.cpp @@ -73,9 +73,6 @@ OUTLINE_FONT* OUTLINE_FONT::LoadFont( const wxString& aFontName, bool aBold, boo wxString fontFile; wxString qualifiedFontName = aFontName; - if( !aBold && !aItalic ) - qualifiedFontName << ":Regular"; - if( aBold ) qualifiedFontName << ":Bold"; diff --git a/common/gal/cairo/cairo_gal.cpp b/common/gal/cairo/cairo_gal.cpp index ca2874686e..8ab43491fe 100644 --- a/common/gal/cairo/cairo_gal.cpp +++ b/common/gal/cairo/cairo_gal.cpp @@ -1765,14 +1765,15 @@ void CAIRO_GAL_BASE::DrawGlyph( const KIFONT::GLYPH& aGlyph, int aNth, int aTota { if( aGlyph.IsStroke() ) { - const auto& strokeGlyph = static_cast( aGlyph ); + const KIFONT::STROKE_GLYPH& glyph = static_cast( aGlyph ); - for( const std::vector& pointList : strokeGlyph ) + for( const std::vector& pointList : glyph ) drawPoly( pointList ); } -#if 0 // FONT TODO else if( aGlyph.IsOutline() ) { + const KIFONT::OUTLINE_GLYPH& glyph = static_cast( aGlyph ); + if( aNth == 0 ) { cairo_close_path( m_currentContext ); @@ -1786,46 +1787,24 @@ void CAIRO_GAL_BASE::DrawGlyph( const KIFONT::GLYPH& aGlyph, int aNth, int aTota // eventually glyphs should not be drawn as polygons at all, // but as bitmaps with antialiasing, this is just a stopgap measure // of getting some form of outline font display - auto triangleCallback = - [&]( int aPolygonIndex, const VECTOR2D& aVertex1, const VECTOR2D& aVertex2, - const VECTOR2D& aVertex3, void* aCallbackData ) + + glyph.Triangulate( + [&]( const VECTOR2D& aVertex1, const VECTOR2D& aVertex2, const VECTOR2D& aVertex3 ) { -#if 1 syncLineWidth(); - const auto p0 = roundp( xform( aVertex1 ) ); - const auto p1 = roundp( xform( aVertex2 ) ); - const auto p2 = roundp( xform( aVertex3 ) ); + const VECTOR2D p0 = roundp( xform( aVertex1 ) ); + const VECTOR2D p1 = roundp( xform( aVertex2 ) ); + const VECTOR2D p2 = roundp( xform( aVertex3 ) ); - /* - cairo_move_to( currentContext, aVertex1.x, aVertex1.y ); - cairo_line_to( currentContext, aVertex2.x, aVertex2.y ); - cairo_line_to( currentContext, aVertex3.x, aVertex3.y ); - cairo_line_to( currentContext, aVertex1.x, aVertex1.y ); - */ cairo_move_to( m_currentContext, p0.x, p0.y ); cairo_line_to( m_currentContext, p1.x, p1.y ); cairo_line_to( m_currentContext, p2.x, p2.y ); cairo_close_path( m_currentContext ); - /* - setSourceRgba( currentContext, fillColor ); - SetIsFill( true ); - cairo_set_fill_rule( currentContext, CAIRO_FILL_RULE_EVEN_ODD ); + cairo_set_fill_rule( m_currentContext, CAIRO_FILL_RULE_EVEN_ODD ); flushPath(); - */ - //cairo_fill( currentContext ); -#else - // just a silly test - /* - DrawRectangle(aVertex1, aVertex2); - DrawRectangle(aVertex2, aVertex3); - DrawRectangle(aVertex3, aVertex1); - */ - DrawTriangle( aVertex1, aVertex2, aVertex3 ); -#endif - }; - - Triangulate( aGlyph, triangleCallback ); + cairo_fill( m_currentContext ); + } ); if( aNth == aTotal - 1 ) { @@ -1841,5 +1820,4 @@ void CAIRO_GAL_BASE::DrawGlyph( const KIFONT::GLYPH& aGlyph, int aNth, int aTota m_isElementAdded = true; } } -#endif } diff --git a/common/gal/opengl/opengl_gal.cpp b/common/gal/opengl/opengl_gal.cpp index fbdf4076b6..2f66f817da 100644 --- a/common/gal/opengl/opengl_gal.cpp +++ b/common/gal/opengl/opengl_gal.cpp @@ -2428,12 +2428,11 @@ void OPENGL_GAL::DrawGlyph( const KIFONT::GLYPH& aGlyph, int aNth, int aTotal ) m_currentManager->Color( m_fillColor ); outlineGlyph.Triangulate( - [&]( int aPolygonIndex, const VECTOR2D& aVertex1, const VECTOR2D& aVertex2, - const VECTOR2D& aVertex3 ) + [&]( const VECTOR2D& aPt1, const VECTOR2D& aPt2, const VECTOR2D& aPt3 ) { - m_currentManager->Vertex( aVertex1.x, aVertex1.y, m_layerDepth ); - m_currentManager->Vertex( aVertex2.x, aVertex2.y, m_layerDepth ); - m_currentManager->Vertex( aVertex3.x, aVertex3.y, m_layerDepth ); + m_currentManager->Vertex( aPt1.x, aPt1.y, m_layerDepth ); + m_currentManager->Vertex( aPt2.x, aPt2.y, m_layerDepth ); + m_currentManager->Vertex( aPt3.x, aPt3.y, m_layerDepth ); } ); } } diff --git a/common/gr_basic.cpp b/common/gr_basic.cpp index 70155827b3..d8b8bfbb7e 100644 --- a/common/gr_basic.cpp +++ b/common/gr_basic.cpp @@ -120,7 +120,7 @@ void GRSetColorPen( wxDC* DC, const COLOR4D& Color, int width, wxPenStyle style // Under OSX and while printing when wxPen is set to 0, renderer follows the request drawing // nothing & in the bitmap world the minimum is enough to light a pixel, in vectorial one not - if( width <= 1 ) + if( width <= 1 && DC->GetBrush().GetStyle() != wxBRUSHSTYLE_SOLID ) width = DC->DeviceToLogicalXRel( 1 ); if( s_ForceBlackPen ) diff --git a/common/gr_text.cpp b/common/gr_text.cpp index bb19047107..5dc191d7b9 100644 --- a/common/gr_text.cpp +++ b/common/gr_text.cpp @@ -4,7 +4,7 @@ * Copyright (C) 2018 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck * Copyright (C) 2012 Wayne Stambaugh - * Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 1992-2022 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 @@ -30,7 +30,7 @@ #include // for KiROUND #include -#include +#include /** @@ -107,9 +107,9 @@ int GraphicTextWidth( const wxString& aText, KIFONT::FONT* aFont, const VECTOR2I /** - * Draw a graphic text (like footprint texts). + * Print a graphic text through wxDC. * - * @param aDC is the current Device Context. NULL if draw within a 3D GL Canvas. + * @param aDC is the current Device Context. * @param aPos is the text position (according to h_justify, v_justify). * @param aColor is the text color. * @param aText is the text to draw. @@ -123,19 +123,11 @@ int GraphicTextWidth( const wxString& aText, KIFONT::FONT* aFont, const VECTOR2I * @param aItalic is the true to simulate an italic font. * @param aBold use true to use a bold font. Useful only with default width value (aWidth = 0). * @param aFont is the font to use, or nullptr for the KiCad stroke font - * @param aCallback( int x0, int y0, int xf, int yf, void* aData ) is a function called - * (if non null) to draw each segment. used to draw 3D texts or for plotting. - * NULL for normal drawings - * @param aCallbackData is the auxiliary parameter aData for the callback function. - * can be nullptr if no auxiliary parameter is needed - * @param aPlotter is a PLOTTER instance, when this function is used to plot - * the text. NULL to draw this text. */ -void GRText( wxDC* aDC, const VECTOR2I& aPos, const COLOR4D& aColor, const wxString& aText, - const EDA_ANGLE& aOrient, const VECTOR2I& aSize, enum GR_TEXT_H_ALIGN_T aH_justify, - enum GR_TEXT_V_ALIGN_T aV_justify, int aWidth, bool aItalic, bool aBold, - KIFONT::FONT* aFont, void (* aCallback)( int x0, int y0, int xf, int yf, void* aData ), - void* aCallbackData, PLOTTER* aPlotter ) +void GRPrintText( wxDC* aDC, const VECTOR2I& aPos, const COLOR4D& aColor, const wxString& aText, + const EDA_ANGLE& aOrient, const VECTOR2I& aSize, + enum GR_TEXT_H_ALIGN_T aH_justify, enum GR_TEXT_V_ALIGN_T aV_justify, + int aWidth, bool aItalic, bool aBold, KIFONT::FONT* aFont ) { bool fill_mode = true; @@ -151,13 +143,63 @@ void GRText( wxDC* aDC, const VECTOR2I& aPos, const COLOR4D& aColor, const wxStr fill_mode = false; } - basic_gal.SetIsFill( fill_mode ); - basic_gal.SetLineWidth( aWidth ); - basic_gal.SetPlotter( aPlotter ); - basic_gal.SetCallback( aCallback, aCallbackData ); - basic_gal.m_DC = aDC; - basic_gal.m_Color = aColor; - basic_gal.SetClipBox( nullptr ); + GRText( aPos, aText, aOrient, aSize, aH_justify, aV_justify, aWidth, aItalic, aBold, aFont, + // Stroke callback + [&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2 ) + { + if( fill_mode ) + GRLine( nullptr, aDC, aPt1.x, aPt1.y, aPt2.x, aPt2.y, aWidth, aColor ); + else + GRCSegm( nullptr, aDC, aPt1.x, aPt1.y, aPt2.x, aPt2.y, aWidth, 0, aColor ); + }, + // Triangulation callback + [&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2, const VECTOR2I& aPt3 ) + { + VECTOR2I pts[3] = { aPt1, aPt2, aPt3 }; + GRClosedPoly( nullptr, aDC, 3, pts, true, 0, aColor, aColor ); + } ); +} + + +/** + * De-compose graphic text into either strokes and/or triangles. + * + * @param aPos is the text position (according to h_justify, v_justify). + * @param aText is the text to draw. + * @param aOrient is the angle. + * @param aSize is the text size (size.x or size.y can be < 0 for mirrored texts). + * @param aH_justify is the horizontal justification (Left, center, right). + * @param aV_justify is the vertical justification (bottom, center, top). + * @param aWidth is the line width (pen width) (use default width if aWidth = 0). + * if width < 0 : draw segments in sketch mode, width = abs(width) + * Use a value min(aSize.x, aSize.y) / 5 for a bold text. + * @param aItalic is the true to simulate an italic font. + * @param aBold use true to use a bold font. Useful only with default width value (aWidth = 0). + * @param aFont is the font to use, or nullptr for the KiCad stroke font + * @param aStrokeCallback is a two-point stroking callback + * @param aTriangleCallback is a three-point triangulation callback + */ +void GRText( const VECTOR2I& aPos, const wxString& aText, const EDA_ANGLE& aOrient, + const VECTOR2I& aSize, enum GR_TEXT_H_ALIGN_T aH_justify, + enum GR_TEXT_V_ALIGN_T aV_justify, int aWidth, bool aItalic, bool aBold, + KIFONT::FONT* aFont, + std::function aStrokeCallback, + std::function aTriangleCallback ) +{ + if( !aFont ) + aFont = KIFONT::FONT::GetFont(); + + KIGFX::GAL_DISPLAY_OPTIONS empty_opts; + CALLBACK_GAL callback_gal( empty_opts, aStrokeCallback, aTriangleCallback ); + + if( aWidth == 0 && aBold ) // Use default values if aWidth == 0 + aWidth = GetPenSizeForBold( std::min( aSize.x, aSize.y ) ); + + if( aWidth < 0 ) + aWidth = -aWidth; TEXT_ATTRIBUTES attributes; attributes.m_Angle = aOrient; @@ -175,7 +217,7 @@ void GRText( wxDC* aDC, const VECTOR2I& aPos, const COLOR4D& aColor, const wxStr attributes.m_Size = size; - aFont->Draw( &basic_gal, aText, VECTOR2D( aPos ), attributes ); + aFont->Draw( &callback_gal, aText, VECTOR2D( aPos ), attributes ); } diff --git a/common/plotters/plotter.cpp b/common/plotters/plotter.cpp index 58fd64634e..de0cf6ea50 100644 --- a/common/plotters/plotter.cpp +++ b/common/plotters/plotter.cpp @@ -647,7 +647,7 @@ void PLOTTER::PlotPoly( const SHAPE_LINE_CHAIN& aCornerList, FILL_T aFill, int a * @param aV_justify is the vertical justification (bottom, center, top). * @param aPenWidth is the line width (if = 0, use plot default line width). * @param aItalic is the true to simulate an italic font. - * @param aBold use true to use a bold font Useful only with default width value (aWidth = 0). + * @param aBold use true to use a bold font Useful only with default width value (aPenWidth = 0). * @param aMultilineAllowed use true to plot text as multiline, otherwise single line. * @param aData is a parameter used by some plotters in SetCurrentLineWidth(), * not directly used here. @@ -656,7 +656,7 @@ void PLOTTER::Text( const VECTOR2I& aPos, const COLOR4D& aColor, const wxString& aText, const EDA_ANGLE& aOrient, - const VECTOR2I& aSize, + const VECTOR2I& aSize, enum GR_TEXT_H_ALIGN_T aH_justify, enum GR_TEXT_V_ALIGN_T aV_justify, int aPenWidth, @@ -669,6 +669,29 @@ void PLOTTER::Text( const VECTOR2I& aPos, SetColor( aColor ); SetCurrentLineWidth( aPenWidth, aData ); - GRText( nullptr, aPos, aColor, aText, aOrient, aSize, aH_justify, aV_justify, aPenWidth, - aItalic, aBold, aFont, nullptr, nullptr, this ); + if( aPenWidth == 0 && aBold ) // Use default values if aPenWidth == 0 + aPenWidth = GetPenSizeForBold( std::min( aSize.x, aSize.y ) ); + + if( aPenWidth < 0 ) + aPenWidth = -aPenWidth; + + GRText( aPos, aText, aOrient, aSize, aH_justify, aV_justify, aPenWidth, aItalic, aBold, aFont, + // Stroke callback + [&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2 ) + { + MoveTo( (wxPoint) aPt1 ); + LineTo( (wxPoint) aPt2 ); + PenFinish(); + }, + // Triangulation callback + [&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2, const VECTOR2I& aPt3 ) + { + std::vector cornerList; + cornerList.reserve( 3 ); + + for( const VECTOR2I& pt : { aPt1, aPt2, aPt3, aPt1 } ) + cornerList.emplace_back( pt ); + + PlotPoly( cornerList, FILL_T::FILLED_SHAPE, 0, aData ); + } ); } diff --git a/eeschema/lib_field.cpp b/eeschema/lib_field.cpp index 5ec9561cf1..ca1acfff61 100644 --- a/eeschema/lib_field.cpp +++ b/eeschema/lib_field.cpp @@ -131,8 +131,8 @@ void LIB_FIELD::print( const RENDER_SETTINGS* aSettings, const VECTOR2I& aOffset VECTOR2I text_pos = aTransform.TransformCoordinate( GetTextPos() ) + aOffset; wxString text = aData ? *static_cast( aData ) : GetText(); - GRText( DC, text_pos, color, text, GetTextAngle(), GetTextSize(), GetHorizJustify(), - GetVertJustify(), penWidth, IsItalic(), IsBold(), GetDrawFont() ); + GRPrintText( DC, text_pos, color, text, GetTextAngle(), GetTextSize(), GetHorizJustify(), + GetVertJustify(), penWidth, IsItalic(), IsBold(), GetDrawFont() ); } diff --git a/eeschema/lib_pin.cpp b/eeschema/lib_pin.cpp index 6af6a932f4..a2d3349160 100644 --- a/eeschema/lib_pin.cpp +++ b/eeschema/lib_pin.cpp @@ -3,7 +3,7 @@ * * Copyright (C) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 2015 Wayne Stambaugh - * Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 1992-2022 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 @@ -32,7 +32,6 @@ #include #include #include -#include #include "sch_painter.h" // small margin in internal units between the pin text and the pin line @@ -403,24 +402,24 @@ void LIB_PIN::printPinTexts( const RENDER_SETTINGS* aSettings, VECTOR2I& aPinPos if( aPinOrient == PIN_RIGHT ) { x = x1 + aTextInside; - GRText( DC, VECTOR2I( x, y1 ), NameColor, name, EDA_ANGLE::HORIZONTAL, - pinNameSize, GR_TEXT_H_ALIGN_LEFT, GR_TEXT_V_ALIGN_CENTER, namePenWidth, - false, false, font ); + GRPrintText( DC, VECTOR2I( x, y1 ), NameColor, name, EDA_ANGLE::HORIZONTAL, + pinNameSize, GR_TEXT_H_ALIGN_LEFT, GR_TEXT_V_ALIGN_CENTER, + namePenWidth, false, false, font ); } else // Orient == PIN_LEFT { x = x1 - aTextInside; - GRText( DC, VECTOR2I( x, y1 ), NameColor, name, EDA_ANGLE::HORIZONTAL, - pinNameSize, GR_TEXT_H_ALIGN_RIGHT, GR_TEXT_V_ALIGN_CENTER, namePenWidth, - false, false, font ); + GRPrintText( DC, VECTOR2I( x, y1 ), NameColor, name, EDA_ANGLE::HORIZONTAL, + pinNameSize, GR_TEXT_H_ALIGN_RIGHT, GR_TEXT_V_ALIGN_CENTER, + namePenWidth, false, false, font ); } } if( aDrawPinNum ) { - GRText( DC, VECTOR2I(( x1 + aPinPos.x) / 2, y1 - num_offset ), NumColor, number, - EDA_ANGLE::HORIZONTAL, pinNumSize, GR_TEXT_H_ALIGN_CENTER, - GR_TEXT_V_ALIGN_BOTTOM, numPenWidth, false, false, font ); + GRPrintText( DC, VECTOR2I(( x1 + aPinPos.x) / 2, y1 - num_offset ), NumColor, + number, EDA_ANGLE::HORIZONTAL, pinNumSize, GR_TEXT_H_ALIGN_CENTER, + GR_TEXT_V_ALIGN_BOTTOM, numPenWidth, false, false, font ); } } else /* Its a vertical line. */ @@ -432,16 +431,16 @@ void LIB_PIN::printPinTexts( const RENDER_SETTINGS* aSettings, VECTOR2I& aPinPos if( aDrawPinName ) { - GRText( DC, VECTOR2I( x1, y ), NameColor, name, EDA_ANGLE::VERTICAL, pinNameSize, - GR_TEXT_H_ALIGN_RIGHT, GR_TEXT_V_ALIGN_CENTER, namePenWidth, false, - false, font ); + GRPrintText( DC, VECTOR2I( x1, y ), NameColor, name, EDA_ANGLE::VERTICAL, + pinNameSize, GR_TEXT_H_ALIGN_RIGHT, GR_TEXT_V_ALIGN_CENTER, + namePenWidth, false, false, font ); } if( aDrawPinNum ) { - GRText( DC, VECTOR2I( x1 - num_offset, ( y1 + aPinPos.y) / 2 ), NumColor, - number, EDA_ANGLE::VERTICAL, pinNumSize, GR_TEXT_H_ALIGN_CENTER, - GR_TEXT_V_ALIGN_BOTTOM, numPenWidth, false, false, font ); + GRPrintText( DC, VECTOR2I( x1 - num_offset, ( y1 + aPinPos.y) / 2 ), NumColor, + number, EDA_ANGLE::VERTICAL, pinNumSize, GR_TEXT_H_ALIGN_CENTER, + GR_TEXT_V_ALIGN_BOTTOM, numPenWidth, false, false, font ); } } else /* PIN_UP */ @@ -450,16 +449,16 @@ void LIB_PIN::printPinTexts( const RENDER_SETTINGS* aSettings, VECTOR2I& aPinPos if( aDrawPinName ) { - GRText( DC, VECTOR2I( x1, y ), NameColor, name, EDA_ANGLE::VERTICAL, pinNameSize, - GR_TEXT_H_ALIGN_LEFT, GR_TEXT_V_ALIGN_CENTER, namePenWidth, false, - false, font ); + GRPrintText( DC, VECTOR2I( x1, y ), NameColor, name, EDA_ANGLE::VERTICAL, + pinNameSize, GR_TEXT_H_ALIGN_LEFT, GR_TEXT_V_ALIGN_CENTER, + namePenWidth, false, false, font ); } if( aDrawPinNum ) { - GRText( DC, VECTOR2I( x1 - num_offset, ( y1 + aPinPos.y) / 2 ), NumColor, - number, EDA_ANGLE::VERTICAL, pinNumSize, GR_TEXT_H_ALIGN_CENTER, - GR_TEXT_V_ALIGN_BOTTOM, numPenWidth, false, false, font ); + GRPrintText( DC, VECTOR2I( x1 - num_offset, ( y1 + aPinPos.y) / 2 ), NumColor, + number, EDA_ANGLE::VERTICAL, pinNumSize, GR_TEXT_H_ALIGN_CENTER, + GR_TEXT_V_ALIGN_BOTTOM, numPenWidth, false, false, font ); } } } @@ -472,16 +471,16 @@ void LIB_PIN::printPinTexts( const RENDER_SETTINGS* aSettings, VECTOR2I& aPinPos if( aDrawPinName ) { x = ( x1 + aPinPos.x) / 2; - GRText( DC, VECTOR2I( x, y1 - name_offset ), NameColor, name, EDA_ANGLE::HORIZONTAL, - pinNameSize, GR_TEXT_H_ALIGN_CENTER, GR_TEXT_V_ALIGN_BOTTOM, - namePenWidth, false, false, font ); + GRPrintText( DC, VECTOR2I( x, y1 - name_offset ), NameColor, name, + EDA_ANGLE::HORIZONTAL, pinNameSize, GR_TEXT_H_ALIGN_CENTER, + GR_TEXT_V_ALIGN_BOTTOM, namePenWidth, false, false, font ); } if( aDrawPinNum ) { x = ( x1 + aPinPos.x) / 2; - GRText( DC, VECTOR2I( x, y1 + num_offset ), NumColor, number, EDA_ANGLE::HORIZONTAL, - pinNumSize, GR_TEXT_H_ALIGN_CENTER, GR_TEXT_V_ALIGN_TOP, numPenWidth, - false, false, font ); + GRPrintText( DC, VECTOR2I( x, y1 + num_offset ), NumColor, number, + EDA_ANGLE::HORIZONTAL, pinNumSize, GR_TEXT_H_ALIGN_CENTER, + GR_TEXT_V_ALIGN_TOP, numPenWidth, false, false, font ); } } else /* Its a vertical line. */ @@ -489,16 +488,16 @@ void LIB_PIN::printPinTexts( const RENDER_SETTINGS* aSettings, VECTOR2I& aPinPos if( aDrawPinName ) { y = ( y1 + aPinPos.y) / 2; - GRText( DC, VECTOR2I( x1 - name_offset, y ), NameColor, name, EDA_ANGLE::VERTICAL, - pinNameSize, GR_TEXT_H_ALIGN_CENTER, GR_TEXT_V_ALIGN_BOTTOM, - namePenWidth, false, false, font ); + GRPrintText( DC, VECTOR2I( x1 - name_offset, y ), NameColor, name, + EDA_ANGLE::VERTICAL, pinNameSize, GR_TEXT_H_ALIGN_CENTER, + GR_TEXT_V_ALIGN_BOTTOM, namePenWidth, false, false, font ); } if( aDrawPinNum ) { - GRText( DC, VECTOR2I( x1 + num_offset, ( y1 + aPinPos.y) / 2 ), NumColor, number, - EDA_ANGLE::VERTICAL, pinNumSize, GR_TEXT_H_ALIGN_CENTER, GR_TEXT_V_ALIGN_TOP, - numPenWidth, false, false, font ); + GRPrintText( DC, VECTOR2I( x1 + num_offset, ( y1 + aPinPos.y) / 2 ), NumColor, + number, EDA_ANGLE::VERTICAL, pinNumSize, GR_TEXT_H_ALIGN_CENTER, + GR_TEXT_V_ALIGN_TOP, numPenWidth, false, false, font ); } } } @@ -554,8 +553,8 @@ void LIB_PIN::printPinElectricalTypeName( const RENDER_SETTINGS* aSettings, VECT break; } - GRText( DC, txtpos, color, typeName, orient, wxSize( textSize, textSize ), hjustify, - GR_TEXT_V_ALIGN_CENTER, pensize, false, false, GetDrawFont() ); + GRPrintText( DC, txtpos, color, typeName, orient, wxSize( textSize, textSize ), hjustify, + GR_TEXT_V_ALIGN_CENTER, pensize, false, false, GetDrawFont() ); } diff --git a/eeschema/lib_text.cpp b/eeschema/lib_text.cpp index 53e826b9c7..9be2496807 100644 --- a/eeschema/lib_text.cpp +++ b/eeschema/lib_text.cpp @@ -345,8 +345,8 @@ void LIB_TEXT::print( const RENDER_SETTINGS* aSettings, const VECTOR2I& aOffset, // Calculate pos according to mirror/rotation. txtpos = aTransform.TransformCoordinate( txtpos ) + aOffset; - GRText( DC, txtpos, color, GetShownText(), orient, GetTextSize(), GR_TEXT_H_ALIGN_CENTER, - GR_TEXT_V_ALIGN_CENTER, penWidth, IsItalic(), IsBold(), GetDrawFont() ); + GRPrintText( DC, txtpos, color, GetShownText(), orient, GetTextSize(), GR_TEXT_H_ALIGN_CENTER, + GR_TEXT_V_ALIGN_CENTER, penWidth, IsItalic(), IsBold(), GetDrawFont() ); } diff --git a/eeschema/sch_field.cpp b/eeschema/sch_field.cpp index b6c070e406..cb5778447b 100644 --- a/eeschema/sch_field.cpp +++ b/eeschema/sch_field.cpp @@ -357,8 +357,8 @@ void SCH_FIELD::Print( const RENDER_SETTINGS* aSettings, const VECTOR2I& aOffset */ textpos = GetBoundingBox().Centre() + aOffset; - GRText( DC, textpos, color, GetShownText(), orient, GetTextSize(), GR_TEXT_H_ALIGN_CENTER, - GR_TEXT_V_ALIGN_CENTER, penWidth, IsItalic(), IsBold(), GetDrawFont() ); + GRPrintText( DC, textpos, color, GetShownText(), orient, GetTextSize(), GR_TEXT_H_ALIGN_CENTER, + GR_TEXT_V_ALIGN_CENTER, penWidth, IsItalic(), IsBold(), GetDrawFont() ); } diff --git a/include/basic_gal.h b/include/basic_gal.h deleted file mode 100644 index 34a86b147d..0000000000 --- a/include/basic_gal.h +++ /dev/null @@ -1,181 +0,0 @@ -/* - * This program source code file is part of KiCad, a free EDA CAD application. - * - * Copyright (C) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr - * Copyright (C) 1992-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 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 BASIC_GAL_H -#define BASIC_GAL_H - -#include -#include - -class PLOTTER; - - -/* - * A minimal GAL implementation to draw, plot and convert stroke texts to a set of segments - * for DRC tests, and to calculate text sizes. - * - * Currently it allows one to use GAL and STROKE_FONT methods in legacy draw mode - * (using wxDC functions) in plot functions only for texts. - * It is used also to calculate the text bounding boxes - * - * The main purpose is to avoid duplicate code to do the same thing in GAL canvas, - * print & plotter canvasses and DRC. - * - * It will be certainly removed when a full GAL canvas using wxDC is implemented - * (or at least restricted to plotter and DRC "canvas") - */ - -struct TRANSFORM_PRM // A helper class to transform coordinates in BASIC_GAL canvas -{ - VECTOR2D m_rotCenter; - VECTOR2D m_moveOffset; - double m_rotAngle; -}; - - -class BASIC_GAL: public KIGFX::GAL -{ -public: - BASIC_GAL( KIGFX::GAL_DISPLAY_OPTIONS& aDisplayOptions ) : - GAL( aDisplayOptions ), - m_callback( nullptr ), - m_DC( nullptr ), - m_Color( RED ), - m_transform(), - m_clipBox(), - m_isClipped( false ), - m_callbackData( nullptr ), - m_plotter( nullptr ) - { - } - - void SetPlotter( PLOTTER* aPlotter ) - { - m_plotter = aPlotter; - } - - void SetCallback( void (* aCallback)( int x0, int y0, int xf, int yf, void* aData ), - void* aData ) - { - m_callback = aCallback; - m_callbackData = aData; - } - - /// Set a clip box for drawings - /// If NULL, no clip will be made - void SetClipBox( EDA_RECT* aClipBox ) - { - m_isClipped = aClipBox != nullptr; - - if( aClipBox ) - m_clipBox = *aClipBox; - } - - /// Save the context. - void Save() override - { - m_transformHistory.push( m_transform ); - } - - void Restore() override - { - m_transform = m_transformHistory.top(); - m_transformHistory.pop(); - } - - /** - * Draw a polyline - * - * @param aPointList is a list of 2D-Vectors containing the polyline points. - */ - void DrawPolyline( const std::deque& aPointList ) override; - void DrawPolyline( const std::vector& aPointList ) override; - void DrawPolyline( const VECTOR2D aPointList[], int aListSize ) override; - - /** - * Start and end points are defined as 2D-Vectors. - * - * @param aStartPoint is the start point of the line. - * @param aEndPoint is the end point of the line. - */ - void DrawLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint ) override; - - /** - * Draw a polygon representing an outline font glyph. - */ - void DrawGlyph( const KIFONT::GLYPH& aGlyph, int aNth, int aTotal ) override; - - /** - * Translate the context. - * - * @param aTranslation is the translation vector. - */ - void Translate( const VECTOR2D& aTranslation ) override - { - m_transform.m_moveOffset += aTranslation; - } - - /** - * Rotate the context. - * - * @param aAngle is the rotation angle in radians. - */ - void Rotate( double aAngle ) override - { - m_transform.m_rotAngle = aAngle; - m_transform.m_rotCenter = m_transform.m_moveOffset; - } - -private: - void doDrawPolyline( const std::vector& aLocalPointList ); - - // Apply the rotation/translation transform to aPoint - const VECTOR2D transform( const VECTOR2D& aPoint ) const; - - // When calling the draw functions outside a wxDC, to get the basic drawings lines / - // polylines ..., a callback function (used in DRC) to store coordinates of each segment: - void (* m_callback)( int x0, int y0, int xf, int yf, void* aData ); - -public: - wxDC* m_DC; - KIGFX::COLOR4D m_Color; - -private: - TRANSFORM_PRM m_transform; - std::stack m_transformHistory; - - // A clip box, to clip drawings in a wxDC (mandatory to avoid draw issues) - EDA_RECT m_clipBox; // The clip box - bool m_isClipped; // Allows/disallows clipping - - void* m_callbackData; // a optional parameter for m_callback - - PLOTTER* m_plotter; // When calling the draw functions for plot, the - // plotter acts as a wxDC to plot basic items. -}; - - -extern BASIC_GAL basic_gal; - -#endif // define BASIC_GAL_H diff --git a/include/callback_gal.h b/include/callback_gal.h new file mode 100644 index 0000000000..c1dde731fe --- /dev/null +++ b/include/callback_gal.h @@ -0,0 +1,60 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2022 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 CALLBACK_GAL_H +#define CALLBACK_GAL_H + +#include + + +class CALLBACK_GAL: public KIGFX::GAL +{ +public: + CALLBACK_GAL( KIGFX::GAL_DISPLAY_OPTIONS& aDisplayOptions, + std::function aStrokeCallback, + std::function aTriangleCallback ) : + GAL( aDisplayOptions ) + { + m_strokeCallback = aStrokeCallback; + m_triangleCallback = aTriangleCallback; + } + + /** + * Draw a polygon representing an outline font glyph. + */ + void DrawGlyph( const KIFONT::GLYPH& aGlyph, int aNth, int aTotal ) override; + +private: + std::function m_strokeCallback; + + std::function m_triangleCallback; +}; + + +#endif // define CALLBACK_GAL_H diff --git a/include/eda_text.h b/include/eda_text.h index a6b7f0998d..7a340a7b4b 100644 --- a/include/eda_text.h +++ b/include/eda_text.h @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr - * Copyright (C) 2004-2021 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2004-2022 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 @@ -39,33 +39,6 @@ class SHAPE_POLY_SET; class wxFindReplaceData; -/** - * A helper for the text to polygon callback function. - * - * These variables are parameters used in #addTextSegmToPoly but #addTextSegmToPoly is a - * callback function so the cannot be sent as arguments. - */ -struct TSEGM_2_POLY_PRMS -{ - int m_textWidth; - int m_error; - SHAPE_POLY_SET* m_cornerBuffer; -}; - - -struct TSEGM_2_SHAPE_PRMS -{ - int m_penWidth; - SHAPE_COMPOUND* m_shape; -}; - - -/** - * Callback function used to convert text segments to polygons. - */ -extern void addTextSegmToPoly( int x0, int y0, int xf, int yf, void* aData ); - - namespace KIGFX { class RENDER_SETTINGS; diff --git a/include/font/glyph.h b/include/font/glyph.h index 951586d9a0..3d8a010d5f 100644 --- a/include/font/glyph.h +++ b/include/font/glyph.h @@ -31,9 +31,6 @@ #include #include -typedef std::function - TRIANGULATE_CALLBACK; namespace KIFONT { @@ -69,7 +66,9 @@ public: BOX2D BoundingBox() override; - void Triangulate( TRIANGULATE_CALLBACK aCallback ) const; + void Triangulate( std::function aCallback ) const; }; diff --git a/include/gr_text.h b/include/gr_text.h index ba7d2eb7bc..3ed79e04de 100644 --- a/include/gr_text.h +++ b/include/gr_text.h @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2009-2014 Jerry Jacobs - * Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 1992-2022 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 @@ -88,37 +88,54 @@ int GraphicTextWidth( const wxString& aText, KIFONT::FONT* aFont, const VECTOR2I int aThickness, bool aBold, bool aItalic ); /** - * Draw a graphic text (like footprint text) + * Print a graphic text through wxDC. * - * @param aClipBox the clipping rect, or NULL if no clipping. - * @param aDC the current Device Context. NULL if draw within a 3D GL Canvas. - * @param aPos text position (according to h_justify, v_justify). - * @param aColor (COLOR4D) = text color. - * @param aText text to draw. - * @param aOrient angle. - * @param aSize text size (size.x or size.y can be < 0 for mirrored texts). - * @param aH_justify horizontal justification (Left, center, right). - * @param aV_justify vertical justification (bottom, center, top). - * @param aWidth line width (pen width) (default = 0). If width < 0 : draw segments in - * sketch mode, width = abs(width). Use a value min(aSize.x, aSize.y) / 5 - * for a bold text. - * @param aItalic true to simulate an italic font. - * @param aBold true to use a bold font. + * @param aDC is the current Device Context. + * @param aPos is the text position (according to h_justify, v_justify). + * @param aColor is the text color. + * @param aText is the text to draw. + * @param aOrient is the angle. + * @param aSize is the text size (size.x or size.y can be < 0 for mirrored texts). + * @param aH_justify is the horizontal justification (Left, center, right). + * @param aV_justify is the vertical justification (bottom, center, top). + * @param aWidth is the line width (pen width) (use default width if aWidth = 0). + * if width < 0 : draw segments in sketch mode, width = abs(width) + * Use a value min(aSize.x, aSize.y) / 5 for a bold text. + * @param aItalic is the true to simulate an italic font. + * @param aBold use true to use a bold font. Useful only with default width value (aWidth = 0). * @param aFont is the font to use, or nullptr for the KiCad stroke font - * @param aCallback ( int x0, int y0, int xf, int yf, void* aData ) is a function called - * (if non null) to draw each segment. used to draw 3D texts or for plotting. - * NULL for normal drawings. - * @param aCallbackData is the auxiliary parameter aData for the callback function. - * This can be nullptr if no auxiliary parameter is needed. - * @param aPlotter = a pointer to a PLOTTER instance, when this function is used to plot - * the text. NULL to draw this text. */ -void GRText( wxDC* aDC, const VECTOR2I& aPos, const KIGFX::COLOR4D& aColor, const wxString& aText, - const EDA_ANGLE& aOrient, const VECTOR2I& aSize, enum GR_TEXT_H_ALIGN_T aH_justify, +void GRPrintText( wxDC* aDC, const VECTOR2I& aPos, const KIGFX::COLOR4D& aColor, + const wxString& aText, const EDA_ANGLE& aOrient, const VECTOR2I& aSize, + enum GR_TEXT_H_ALIGN_T aH_justify, enum GR_TEXT_V_ALIGN_T aV_justify, + int aWidth, bool aItalic, bool aBold, KIFONT::FONT* aFont ); + +/** + * De-compose graphic text into either strokes and/or triangles. + * + * @param aPos is the text position (according to h_justify, v_justify). + * @param aText is the text to draw. + * @param aOrient is the angle. + * @param aSize is the text size (size.x or size.y can be < 0 for mirrored texts). + * @param aH_justify is the horizontal justification (Left, center, right). + * @param aV_justify is the vertical justification (bottom, center, top). + * @param aWidth is the line width (pen width) (use default width if aWidth = 0). + * if width < 0 : draw segments in sketch mode, width = abs(width) + * Use a value min(aSize.x, aSize.y) / 5 for a bold text. + * @param aItalic is the true to simulate an italic font. + * @param aBold use true to use a bold font. Useful only with default width value (aWidth = 0). + * @param aFont is the font to use, or nullptr for the KiCad stroke font + * @param aStrokeCallback is a two-point stroking callback + * @param aTriangleCallback is a three-point triangulation callback + */ +void GRText( const VECTOR2I& aPos, const wxString& aText, const EDA_ANGLE& aOrient, + const VECTOR2I& aSize, enum GR_TEXT_H_ALIGN_T aH_justify, enum GR_TEXT_V_ALIGN_T aV_justify, int aWidth, bool aItalic, bool aBold, KIFONT::FONT* aFont, - void (*aCallback)( int x0, int y0, int xf, int yf, void* aData ) = nullptr, - void* aCallbackData = nullptr, PLOTTER* aPlotter = nullptr ); - + std::function aStrokeCallback, + std::function aTriangleCallback ); #endif /* GR_TEXT_H */ diff --git a/include/plotters/plotter.h b/include/plotters/plotter.h index c43e87f205..99fa376c63 100644 --- a/include/plotters/plotter.h +++ b/include/plotters/plotter.h @@ -406,7 +406,7 @@ public: const VECTOR2I& aSize, enum GR_TEXT_H_ALIGN_T aH_justify, enum GR_TEXT_V_ALIGN_T aV_justify, - int aWidth, + int aPenWidth, bool aItalic, bool aBold, bool aMultilineAllowed = false, diff --git a/pcbnew/dialogs/dialog_text_properties_base.cpp b/pcbnew/dialogs/dialog_text_properties_base.cpp index ec4c8a4b58..88e849dba4 100644 --- a/pcbnew/dialogs/dialog_text_properties_base.cpp +++ b/pcbnew/dialogs/dialog_text_properties_base.cpp @@ -222,7 +222,7 @@ DIALOG_TEXT_PROPERTIES_BASE::DIALOG_TEXT_PROPERTIES_BASE( wxWindow* parent, wxWi m_PositionYUnits = new wxStaticText( this, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 ); m_PositionYUnits->Wrap( -1 ); - gbSizer1->Add( m_PositionYUnits, wxGBPosition( 5, 6 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 ); + gbSizer1->Add( m_PositionYUnits, wxGBPosition( 4, 6 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 ); m_OrientLabel = new wxStaticText( this, wxID_ANY, _("Orientation:"), wxDefaultPosition, wxDefaultSize, 0 ); m_OrientLabel->Wrap( -1 ); @@ -235,7 +235,7 @@ DIALOG_TEXT_PROPERTIES_BASE::DIALOG_TEXT_PROPERTIES_BASE( wxWindow* parent, wxWi m_OrientCtrl->Append( _("90.0") ); m_OrientCtrl->Append( _("-90.0") ); m_OrientCtrl->Append( _("180.0") ); - gbSizer1->Add( m_OrientCtrl, wxGBPosition( 5, 5 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 ); + gbSizer1->Add( m_OrientCtrl, wxGBPosition( 5, 5 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); bMainSizer->Add( gbSizer1, 0, wxEXPAND|wxRIGHT|wxLEFT, 10 ); diff --git a/pcbnew/dialogs/dialog_text_properties_base.fbp b/pcbnew/dialogs/dialog_text_properties_base.fbp index c154fb807a..e06aee356e 100644 --- a/pcbnew/dialogs/dialog_text_properties_base.fbp +++ b/pcbnew/dialogs/dialog_text_properties_base.fbp @@ -2483,7 +2483,7 @@ 1 6 wxALIGN_CENTER_VERTICAL - 5 + 4 1 1 @@ -2610,7 +2610,7 @@ 5 1 5 - wxALIGN_CENTER_VERTICAL + wxALIGN_CENTER_VERTICAL|wxEXPAND 5 1 diff --git a/pcbnew/fp_text.cpp b/pcbnew/fp_text.cpp index a30abf1b0e..ed171031cd 100644 --- a/pcbnew/fp_text.cpp +++ b/pcbnew/fp_text.cpp @@ -3,7 +3,7 @@ * * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck - * Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 1992-2022 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 @@ -35,6 +35,7 @@ #include #include #include +#include FP_TEXT::FP_TEXT( FOOTPRINT* aParentFootprint, TEXT_TYPE text_type ) : BOARD_ITEM( aParentFootprint, PCB_FP_TEXT_T ), @@ -464,20 +465,28 @@ void FP_TEXT::TransformTextShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerB PCB_LAYER_ID aLayer, int aClearance, int aError, ERROR_LOC aErrorLoc ) const { - struct TSEGM_2_POLY_PRMS prms; - - prms.m_cornerBuffer = &aCornerBuffer; - prms.m_textWidth = GetEffectiveTextPenWidth() + ( 2 * aClearance ); - prms.m_error = aError; wxSize size = GetTextSize(); - int penWidth = GetEffectiveTextPenWidth(); + int penWidth = GetEffectiveTextPenWidth(); if( IsMirrored() ) size.x = -size.x; - GRText( nullptr, GetTextPos(), BLACK, GetShownText(), GetDrawRotation(), size, - GetHorizJustify(), GetVertJustify(), penWidth, IsItalic(), IsBold(), GetDrawFont(), - addTextSegmToPoly, &prms ); + GRText( GetTextPos(), GetShownText(), GetDrawRotation(), size, GetHorizJustify(), + GetVertJustify(), penWidth, IsItalic(), IsBold(), GetDrawFont(), + // Stroke callback + [&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2 ) + { + TransformOvalToPolygon( aCornerBuffer, aPt1, aPt2, penWidth+ ( 2 * aClearance ), + aError, ERROR_INSIDE ); + }, + // Triangulation callback + [&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2, const VECTOR2I& aPt3 ) + { + aCornerBuffer.NewOutline(); + + for( const VECTOR2I& point : { aPt1, aPt2, aPt3 } ) + aCornerBuffer.Append( point.x, point.y ); + } ); } diff --git a/pcbnew/pcb_text.cpp b/pcbnew/pcb_text.cpp index 84dd5f34cf..12d8b67dee 100644 --- a/pcbnew/pcb_text.cpp +++ b/pcbnew/pcb_text.cpp @@ -3,7 +3,7 @@ * * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck - * Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 1992-2022 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 @@ -36,6 +36,7 @@ #include #include #include +#include using KIGFX::PCB_RENDER_SETTINGS; @@ -226,11 +227,9 @@ std::shared_ptr PCB_TEXT::GetEffectiveShape( PCB_LAYER_ID aLayer ) const void PCB_TEXT::TransformTextShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer, - PCB_LAYER_ID aLayer, int aClearanceValue, + PCB_LAYER_ID aLayer, int aClearance, int aError, ERROR_LOC aErrorLoc ) const { - struct TSEGM_2_POLY_PRMS prms; - wxSize size = GetTextSize(); if( IsMirrored() ) @@ -238,13 +237,22 @@ void PCB_TEXT::TransformTextShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCorner int penWidth = GetEffectiveTextPenWidth(); - prms.m_cornerBuffer = &aCornerBuffer; - prms.m_textWidth = GetEffectiveTextPenWidth() + ( 2 * aClearanceValue ); - prms.m_error = aError; + GRText( GetTextPos(), GetShownText(), GetTextAngle(), size, GetHorizJustify(), + GetVertJustify(), penWidth, IsItalic(), IsBold(), GetDrawFont(), + // Stroke callback + [&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2 ) + { + TransformOvalToPolygon( aCornerBuffer, aPt1, aPt2, penWidth+ ( 2 * aClearance ), + aError, ERROR_INSIDE ); + }, + // Triangulation callback + [&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2, const VECTOR2I& aPt3 ) + { + aCornerBuffer.NewOutline(); - GRText( nullptr, GetTextPos(), COLOR4D::BLACK, GetShownText(), GetTextAngle(), size, - GetHorizJustify(), GetVertJustify(), penWidth, IsItalic(), IsBold(), GetDrawFont(), - addTextSegmToPoly, &prms ); + for( const VECTOR2I& point : { aPt1, aPt2, aPt3 } ) + aCornerBuffer.Append( point.x, point.y ); + } ); }