From 8e4a4306c7c6924def261683bfdf0e9f9052e772 Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Tue, 4 Jan 2022 00:44:59 +0000 Subject: [PATCH] Go back to using inter-character spacing from the stroke font. Fixes https://gitlab.com/kicad/code/kicad/issues/1078 --- common/basic_gal.cpp | 4 +- common/font/font.cpp | 38 +++-- common/font/glyph.cpp | 172 ++++------------------ common/font/stroke_font.cpp | 70 +++++---- common/gal/cairo/cairo_gal.cpp | 4 +- common/gal/graphics_abstraction_layer.cpp | 13 -- common/gal/opengl/opengl_gal.cpp | 4 +- include/font/font.h | 54 ++----- include/font/glyph.h | 150 ++----------------- include/font/stroke_font.h | 15 +- include/gal/graphics_abstraction_layer.h | 7 - 11 files changed, 137 insertions(+), 394 deletions(-) diff --git a/common/basic_gal.cpp b/common/basic_gal.cpp index baaf7b419d..05791f870c 100644 --- a/common/basic_gal.cpp +++ b/common/basic_gal.cpp @@ -170,7 +170,9 @@ void BASIC_GAL::DrawGlyph( const KIFONT::GLYPH& aGlyph, int aNth, int aTotal ) { if( aGlyph.IsStroke() ) { - for( const std::vector& pointList : aGlyph.GetPoints() ) + const auto& strokeGlyph = static_cast( aGlyph ); + + for( const std::vector& pointList : strokeGlyph ) DrawPolyline( pointList ); } #if 0 // FONT TODO diff --git a/common/font/font.cpp b/common/font/font.cpp index 2c11443ddc..8279bd4f53 100644 --- a/common/font/font.cpp +++ b/common/font/font.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KICAD, a free EDA CAD application. * * Copyright (C) 2021 Ola Rinta-Koski - * Copyright (C) 2021 Kicad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2021-2022 Kicad Developers, see AUTHORS.txt for contributors. * * Font abstract base class * @@ -70,20 +70,17 @@ FONT* FONT::GetFont( const wxString& aFontName, bool aBold, bool aItalic ) FONT* font = s_fontMap[key]; - if( !font ) - { - wxFont wx_font( wxFontInfo().FaceName( aFontName ).Bold( aBold ).Italic( aItalic ) ); - wxString fullfontname = wx_font.GetNativeFontInfoDesc(); - #if 0 // FONT TODO: load a real font - font->m_fontName = aFontName; + if( !font ) + font = OUTLINE_FONT::LoadFont( aFontName, aBold, aItalic ); #else + + if( !font ) font = getDefaultFont(); #endif - s_fontMap[key] = font; - } + s_fontMap[key] = font; return font; } @@ -264,7 +261,7 @@ VECTOR2D FONT::getBoundingBox( const UTF8& aText, TEXT_STYLE_FLAGS aTextStyle, } -void FONT::KiDrawText( KIGFX::GAL* aGal, const UTF8& aText, const VECTOR2D& aPosition, +void FONT::DrawText( KIGFX::GAL* aGal, const UTF8& aText, const VECTOR2D& aPosition, const TEXT_ATTRIBUTES& aAttributes ) const { // FONT TODO: do we need to set the attributes to the gal at all? @@ -340,7 +337,7 @@ VECTOR2D FONT::Draw( KIGFX::GAL* aGal, const UTF8& aText, const VECTOR2D& aPosit /** * @return position of cursor for drawing next substring */ -VECTOR2D FONT::drawMarkup( BOX2I* aBoundingBox, GLYPH_LIST& aGlyphs, +VECTOR2D FONT::drawMarkup( BOX2I* aBoundingBox, std::vector>& aGlyphs, const std::unique_ptr& aNode, const VECTOR2D& aPosition, const VECTOR2D& aGlyphSize, const EDA_ANGLE& aAngle, TEXT_STYLE_FLAGS aTextStyle, int aLevel ) const @@ -366,7 +363,7 @@ VECTOR2D FONT::drawMarkup( BOX2I* aBoundingBox, GLYPH_LIST& aGlyphs, wxPoint pt( aPosition.x, aPosition.y ); BOX2I bbox; - nextPosition = GetTextAsPolygon( &bbox, aGlyphs, txt, aGlyphSize, pt, aAngle, textStyle ); + nextPosition = GetTextAsGlyphs( &bbox, aGlyphs, txt, aGlyphSize, pt, aAngle, textStyle ); if( aBoundingBox ) { @@ -405,17 +402,16 @@ VECTOR2D FONT::drawSingleLineText( KIGFX::GAL* aGal, BOX2I* aBoundingBox, const if( aIsItalic ) textStyle |= TEXT_STYLE::ITALIC; + std::vector> glyphs; + VECTOR2D nextPosition = drawMarkup( aBoundingBox, glyphs, markupRoot, aPosition, aGlyphSize, + aAngle, textStyle ); - GLYPH_LIST glyphs; - VECTOR2D nextPosition = drawMarkup( aBoundingBox, glyphs, markupRoot, aPosition, aGlyphSize, - aAngle, textStyle ); - - for( const std::shared_ptr& glyph : glyphs ) + for( const std::unique_ptr& glyph : glyphs ) { if( aIsMirrored ) glyph->Mirror( aPosition ); - aGal->DrawGlyph( glyph ); + aGal->DrawGlyph( *glyph.get() ); } return nextPosition; @@ -433,9 +429,9 @@ VECTOR2D FONT::boundingBoxSingleLine( BOX2I* aBoundingBox, const UTF8& aText, if( aIsItalic ) textStyle |= TEXT_STYLE::ITALIC; - GLYPH_LIST glyphs; // ignored - VECTOR2D nextPosition = drawMarkup( aBoundingBox, glyphs, markupRoot, aPosition, aGlyphSize, - aAngle, false, textStyle ); + std::vector> glyphs; // ignored + VECTOR2D nextPosition = drawMarkup( aBoundingBox, glyphs, markupRoot, aPosition, aGlyphSize, + aAngle, false, textStyle ); return nextPosition; } diff --git a/common/font/glyph.cpp b/common/font/glyph.cpp index 1873b0e8dd..dadd4ce5c8 100644 --- a/common/font/glyph.cpp +++ b/common/font/glyph.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2021 Ola Rinta-Koski - * Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2021-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 @@ -26,8 +26,10 @@ using namespace KIFONT; STROKE_GLYPH::STROKE_GLYPH( const STROKE_GLYPH& aGlyph ) { - for( const std::vector& pointList : aGlyph.m_pointLists ) - m_pointLists.push_back( pointList ); + for( const std::vector& pointList : aGlyph ) + push_back( pointList ); + + m_boundingBox = aGlyph.m_boundingBox; } @@ -36,18 +38,18 @@ void STROKE_GLYPH::AddPoint( const VECTOR2D& aPoint ) if( !m_penIsDown ) { std::vector v; - m_pointLists.push_back( v ); + push_back( v ); m_penIsDown = true; } - m_pointLists.back().push_back( aPoint ); + back().push_back( aPoint ); } void STROKE_GLYPH::RaisePen() { if( m_penIsDown ) - m_pointLists.back().shrink_to_fit(); + back().shrink_to_fit(); m_penIsDown = false; } @@ -55,110 +57,28 @@ void STROKE_GLYPH::RaisePen() void STROKE_GLYPH::Finalize() { - if( !m_pointLists.empty() && !m_pointLists.back().empty() ) - m_pointLists.back().shrink_to_fit(); + if( !empty() && !back().empty() ) + back().shrink_to_fit(); } -BOX2D STROKE_GLYPH::BoundingBox() -{ - if( m_boundingBox.GetWidth() == 0 && m_boundingBox.GetHeight() == 0 ) - { - bool first = true; - - for( const std::vector& pointList : m_pointLists ) - { - for( const VECTOR2D& point : pointList ) - { - if( first ) - { - m_boundingBox.SetOrigin( point ); - first = false; - } - else - { - m_boundingBox.Merge( point ); - } - } - } - } - - return m_boundingBox; -} - - -std::shared_ptr STROKE_GLYPH::Resize( const VECTOR2D& aGlyphSize ) const -{ - std::shared_ptr glyph = std::make_shared( *this ); - - glyph->clearBoundingBox(); - - bool first = true; - - for( std::vector& pointList : glyph->m_pointLists ) - { - for( VECTOR2D& point : pointList ) - { - point.x = point.x * aGlyphSize.x; - point.y = point.y * aGlyphSize.y; - - if( first ) - { - glyph->m_boundingBox.SetOrigin( point ); - first = false; - } - else - { - glyph->m_boundingBox.Merge( point ); - } - } - } - - return glyph; -} - - -std::shared_ptr STROKE_GLYPH::Translate( const VECTOR2D& aOffset ) const -{ - auto glyph = std::make_shared( *this ); - - glyph->clearBoundingBox(); - - bool first = true; - - for( std::vector& pointList : glyph->m_pointLists ) - { - for( VECTOR2D& point : pointList ) - { - point.x += aOffset.x; - point.y += aOffset.y; - - if( first ) - { - glyph->m_boundingBox.SetOrigin( point ); - first = false; - } - else - { - glyph->m_boundingBox.Merge( point ); - } - } - } - - return glyph; -} - - -std::shared_ptr STROKE_GLYPH::Transform( const VECTOR2D& aGlyphSize, const VECTOR2D& aOffset, +std::unique_ptr STROKE_GLYPH::Transform( const VECTOR2D& aGlyphSize, const VECTOR2D& aOffset, double aTilt ) { - std::shared_ptr glyph = std::make_shared( *this ); + std::unique_ptr glyph = std::make_unique( *this ); - glyph->clearBoundingBox(); + VECTOR2D end = glyph->m_boundingBox.GetEnd(); - bool first = true; + end.x *= aGlyphSize.x; + end.y *= aGlyphSize.y; - for( std::vector& pointList : glyph->m_pointLists ) + if( aTilt ) + end.x -= end.y * aTilt; + + glyph->m_boundingBox.SetEnd( end ); + glyph->m_boundingBox.Offset( aOffset ); + + for( std::vector& pointList : *glyph.get() ) { for( VECTOR2D& point : pointList ) { @@ -170,16 +90,6 @@ std::shared_ptr STROKE_GLYPH::Transform( const VECTOR2D& aGlyphSize, cons point.x += aOffset.x; point.y += aOffset.y; - - if( first ) - { - glyph->m_boundingBox.SetOrigin( point ); - first = false; - } - else - { - glyph->m_boundingBox.Merge( point ); - } } } @@ -187,42 +97,22 @@ std::shared_ptr STROKE_GLYPH::Transform( const VECTOR2D& aGlyphSize, cons } -std::shared_ptr STROKE_GLYPH::Mirror( bool aMirror, const VECTOR2D& aMirrorOrigin ) const -{ - // TODO figure out a way to not make a copy if aMirror is false - auto glyph = std::make_shared( *this ); - - if( aMirror ) - glyph->Mirror( aMirrorOrigin ); - - return glyph; -} - - void STROKE_GLYPH::Mirror( const VECTOR2D& aMirrorOrigin ) { double originX = aMirrorOrigin.x; - clearBoundingBox(); + VECTOR2D pos = m_boundingBox.GetPosition(); + VECTOR2D end = m_boundingBox.GetEnd(); - bool first = true; + pos.x = originX - ( pos.x - originX ); + end.x = originX - ( end.x - originX ); - for( std::vector& pointList : m_pointLists ) + m_boundingBox.SetOrigin( pos ); + m_boundingBox.SetEnd( end ); + + for( std::vector& pointList : *this ) { for( VECTOR2D& point : pointList ) - { - if( first ) - { - //originX = point.x; - point.x = originX - ( point.x - originX ); - m_boundingBox.SetOrigin( point ); - first = false; - } - else - { - point.x = originX - ( point.x - originX ); - m_boundingBox.Merge( point ); - } - } + point.x = originX - ( point.x - originX ); } } diff --git a/common/font/stroke_font.cpp b/common/font/stroke_font.cpp index ec2955733a..4304ebb178 100644 --- a/common/font/stroke_font.cpp +++ b/common/font/stroke_font.cpp @@ -4,7 +4,7 @@ * Copyright (C) 2012 Torsten Hueter, torstenhtr gmx.de * Copyright (C) 2013 CERN * @author Maciej Suminski - * Copyright (C) 2016 Kicad Developers, see change_log.txt for contributors. + * Copyright (C) 2016-2022 Kicad Developers, see change_log.txt for contributors. * * Stroke font class * @@ -28,7 +28,6 @@ #include #include -#include #include #include #include @@ -46,19 +45,16 @@ static constexpr double OVERBAR_POSITION_FACTOR = 1.33; ///< Scale factor for a glyph static constexpr double STROKE_FONT_SCALE = 1.0 / 21.0; -///< Tilt factor for italic style (the is is the scaling factor -///< on dY relative coordinates to give a tilt shape +///< Tilt factor for italic style (this is the scaling factor on dY relative coordinates to +///< give a tilted shape) static constexpr double ITALIC_TILT = 1.0 / 8; -///< Factor that determines the pitch between 2 lines. -static constexpr double INTERLINE_PITCH_RATIO = 1.62; // The golden mean - static constexpr int FONT_OFFSET = -10; -bool g_defaultFontInitialized = false; -GLYPH_LIST g_defaultFontGlyphs; ///< Glyph list -std::vector* g_defaultFontGlyphBoundingBoxes; ///< Bounding boxes of the glyphs +bool g_defaultFontInitialized = false; +std::vector> g_defaultFontGlyphs; +std::vector* g_defaultFontGlyphBoundingBoxes; STROKE_FONT::STROKE_FONT() : @@ -83,6 +79,25 @@ STROKE_FONT* STROKE_FONT::LoadFont( const wxString& aFontName ) } } + +void buildGlyphBoundingBox( std::shared_ptr& aGlyph, double aGlyphWidth ) +{ + VECTOR2D min( 0, 0 ); + VECTOR2D max( aGlyphWidth, 0 ); + + for( const std::vector& pointList : *aGlyph ) + { + for( const VECTOR2D& point : pointList ) + { + min.y = std::min( min.y, point.y ); + max.y = std::max( max.y, point.y ); + } + } + + aGlyph->SetBoundingBox( BOX2D( min, max - min ) ); +} + + void STROKE_FONT::loadNewStrokeFont( const char* const aNewStrokeFont[], int aNewStrokeFontSize ) { if( !g_defaultFontInitialized ) @@ -96,6 +111,8 @@ void STROKE_FONT::loadNewStrokeFont( const char* const aNewStrokeFont[], int aNe { auto glyph = std::make_shared(); double glyphStartX = 0.0; + double glyphEndX = 0.0; + double glyphWidth = 0.0; std::vector* pointList = nullptr; @@ -104,9 +121,7 @@ void STROKE_FONT::loadNewStrokeFont( const char* const aNewStrokeFont[], int aNe while( aNewStrokeFont[j][i] ) { VECTOR2D point( 0.0, 0.0 ); - char coordinate[2] = { - 0, - }; + char coordinate[2] = { 0, }; for( int k : { 0, 1 } ) coordinate[k] = aNewStrokeFont[j][i + k]; @@ -115,6 +130,8 @@ void STROKE_FONT::loadNewStrokeFont( const char* const aNewStrokeFont[], int aNe { // The first two values contain the width of the char glyphStartX = ( coordinate[0] - 'R' ) * STROKE_FONT_SCALE; + glyphEndX = ( coordinate[1] - 'R' ) * STROKE_FONT_SCALE; + glyphWidth = glyphEndX - glyphStartX; } else if( ( coordinate[0] == ' ' ) && ( coordinate[1] == 'R' ) ) { @@ -149,10 +166,10 @@ void STROKE_FONT::loadNewStrokeFont( const char* const aNewStrokeFont[], int aNe glyph->Finalize(); // Compute the bounding box of the glyph + buildGlyphBoundingBox( glyph, glyphWidth ); g_defaultFontGlyphBoundingBoxes->emplace_back( glyph->BoundingBox() ); g_defaultFontGlyphs.push_back( glyph ); - m_maxGlyphWidth = std::max( m_maxGlyphWidth, - g_defaultFontGlyphBoundingBoxes->back().GetWidth() ); + m_maxGlyphWidth = std::max( m_maxGlyphWidth, glyphWidth ); } g_defaultFontInitialized = true; @@ -194,8 +211,8 @@ VECTOR2D STROKE_FONT::StringBoundaryLimits( const KIGFX::GAL* aGal, const UTF8& MARKUP::MARKUP_PARSER markupParser( aText ); auto root = markupParser.Parse(); - GLYPH_LIST glyphs; // ignored - BOX2I boundingBox; + std::vector> glyphs; // ignored + BOX2I boundingBox; (void) drawMarkup( &boundingBox, glyphs, root, VECTOR2D(), aGlyphSize, EDA_ANGLE::ANGLE_0, false, 0 /* TODO: this should really include italic */ ); @@ -212,10 +229,11 @@ VECTOR2D STROKE_FONT::getBoundingBox( const UTF8& aString, const VECTOR2D& aGlyp } -VECTOR2I STROKE_FONT::GetTextAsPolygon( BOX2I* aBoundingBox, GLYPH_LIST& aGlyphs, - const UTF8& aText, const VECTOR2D& aGlyphSize, - const wxPoint& aPosition, const EDA_ANGLE& aAngle, - TEXT_STYLE_FLAGS aTextStyle ) const +VECTOR2I STROKE_FONT::GetTextAsGlyphs( BOX2I* aBoundingBox, + std::vector>& aGlyphs, + const UTF8& aText, const VECTOR2D& aGlyphSize, + const wxPoint& aPosition, const EDA_ANGLE& aAngle, + TEXT_STYLE_FLAGS aTextStyle ) const { wxPoint cursor( aPosition ); VECTOR2D glyphSize( aGlyphSize ); @@ -266,13 +284,11 @@ VECTOR2I STROKE_FONT::GetTextAsPolygon( BOX2I* aBoundingBox, GLYPH_LIST& aGlyphs } else { - constexpr double interGlyphSpaceMultiplier = 0.15; - double interGlyphSpace = glyphSize.x * interGlyphSpaceMultiplier; - STROKE_GLYPH* source = static_cast( m_glyphs->at( dd ).get() ); + STROKE_GLYPH* source = static_cast( m_glyphs->at( dd ).get() ); aGlyphs.push_back( source->Transform( glyphSize, cursor, tilt ) ); - cursor.x = aGlyphs.back()->BoundingBox().GetEnd().x + interGlyphSpace; + cursor.x = aGlyphs.back()->BoundingBox().GetEnd().x; } } @@ -280,7 +296,7 @@ VECTOR2I STROKE_FONT::GetTextAsPolygon( BOX2I* aBoundingBox, GLYPH_LIST& aGlyphs if( aTextStyle & TEXT_STYLE::OVERBAR ) { - std::shared_ptr overbarGlyph = std::make_shared(); + std::unique_ptr overbarGlyph; barOffset.y = ComputeOverbarVerticalPosition( glyphSize.y ); @@ -291,7 +307,7 @@ VECTOR2I STROKE_FONT::GetTextAsPolygon( BOX2I* aBoundingBox, GLYPH_LIST& aGlyphs overbarGlyph->AddPoint( VECTOR2D( cursor.x + barOffset.x, cursor.y - barOffset.y ) ); overbarGlyph->Finalize(); - aGlyphs.push_back( overbarGlyph ); + aGlyphs.push_back( std::move( overbarGlyph ) ); } if( aBoundingBox ) diff --git a/common/gal/cairo/cairo_gal.cpp b/common/gal/cairo/cairo_gal.cpp index 81bcefba7e..4e6703b768 100644 --- a/common/gal/cairo/cairo_gal.cpp +++ b/common/gal/cairo/cairo_gal.cpp @@ -1765,7 +1765,9 @@ void CAIRO_GAL_BASE::DrawGlyph( const KIFONT::GLYPH& aGlyph, int aNth, int aTota { if( aGlyph.IsStroke() ) { - for( const std::vector& pointList : aGlyph.GetPoints() ) + const auto& strokeGlyph = static_cast( aGlyph ); + + for( const std::vector& pointList : strokeGlyph ) drawPoly( pointList ); } #if 0 // FONT TODO diff --git a/common/gal/graphics_abstraction_layer.cpp b/common/gal/graphics_abstraction_layer.cpp index 6122eabf03..e7c71ebfa1 100644 --- a/common/gal/graphics_abstraction_layer.cpp +++ b/common/gal/graphics_abstraction_layer.cpp @@ -279,19 +279,6 @@ void GAL::StrokeText( const wxString& aText, const VECTOR2D& aPosition, double a } -void GAL::DrawGlyphs( const KIFONT::GLYPH_LIST& aGlyphs ) -{ - int nth = 0; - int total = aGlyphs.size(); - - for( const std::shared_ptr& glyph : aGlyphs ) - { - DrawGlyph( glyph, nth, total ); - nth++; - } -} - - /* * Fallback for implementations that don't implement bitmap text: use stroke font */ diff --git a/common/gal/opengl/opengl_gal.cpp b/common/gal/opengl/opengl_gal.cpp index dcf044f01f..baf7e9a0a0 100644 --- a/common/gal/opengl/opengl_gal.cpp +++ b/common/gal/opengl/opengl_gal.cpp @@ -2415,7 +2415,9 @@ void OPENGL_GAL::DrawGlyph( const KIFONT::GLYPH& aGlyph, int aNth, int aTotal ) { if( aGlyph.IsStroke() ) { - for( const std::vector& pointList : aGlyph.GetPoints() ) + const auto& strokeGlyph = static_cast( aGlyph ); + + for( const std::vector& pointList : strokeGlyph ) DrawPolyline( pointList ); } #if 0 // FONT TODO diff --git a/include/font/font.h b/include/font/font.h index 383230ef96..1228d1359b 100644 --- a/include/font/font.h +++ b/include/font/font.h @@ -2,7 +2,7 @@ * This program source code file is part of KICAD, a free EDA CAD application. * * Copyright (C) 2021 Ola Rinta-Koski - * Copyright (C) 2021 Kicad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2021-2022 Kicad Developers, see AUTHORS.txt for contributors. * * Font abstract base class * @@ -35,12 +35,7 @@ #include #include #include - - -namespace MARKUP -{ -struct NODE; -} +#include namespace KIGFX { @@ -137,32 +132,8 @@ public: return Draw( aGal, aText, aPosition, VECTOR2D( 0, 0 ), aAttributes ); } - virtual void KiDrawText( KIGFX::GAL* aGal, const UTF8& aText, const VECTOR2D& aPosition, - const TEXT_ATTRIBUTES& aAttributes ) const; - - /** - * Draw a string. - * - * @param aGal is the graphics context - * @param aText is the text string - * @param aPosition is the text position in world coordinates - * @param aParse is true is aText should first be parsed for variable substition etc., - * otherwise false (default is false) - * @return bounding box - */ - VECTOR2D DrawString( KIGFX::GAL* aGal, const UTF8& aText, const VECTOR2D& aPosition, - bool aParse, const TEXT_ATTRIBUTES& aAttributes ) const - { - return doDrawString( aGal, aText, aPosition, aParse, aAttributes ); - } - - VECTOR2D DrawString( KIGFX::GAL* aGal, const UTF8& aText, const VECTOR2D& aPosition, - bool aParse, const EDA_ANGLE& aAngle ) const - { - TEXT_ATTRIBUTES attributes; - attributes.m_Angle = aAngle; - return doDrawString( aGal, aText, aPosition, aParse, attributes ); - } + virtual void DrawText( KIGFX::GAL* aGal, const UTF8& aText, const VECTOR2D& aPosition, + const TEXT_ATTRIBUTES& aAttributes ) const; /** * Compute the boundary limits of aText (the bounding box of all shapes). @@ -197,9 +168,10 @@ public: virtual VECTOR2D ComputeTextLineSize( const KIGFX::GAL* aGal, const UTF8& aText ) const = 0; /** - * Convert text string to polygon (outline font) or polyline (stroke font). + * Convert text string to an array of GLYPHs. * * @param aBoundingBox pointer to a BOX2I that will set to the bounding box, or nullptr + * @param aGlyphs storage for the returned GLYPHs * @param aText text to convert to polygon/polyline * @param aGlyphSize glyph size * @param aPosition position of text (cursor position before this text) @@ -207,10 +179,11 @@ public: * @param aTextStyle text style flags * @return text cursor position after this text */ - virtual VECTOR2I GetTextAsPolygon( BOX2I* aBoundingBox, GLYPH_LIST& aGlyphs, - const UTF8& aText, const VECTOR2D& aGlyphSize, - const wxPoint& aPosition, const EDA_ANGLE& aAngle, - TEXT_STYLE_FLAGS aTextStyle ) const = 0; + virtual VECTOR2I GetTextAsGlyphs( BOX2I* aBoundingBox, + std::vector>& aGlyphs, + const UTF8& aText, const VECTOR2D& aGlyphSize, + const wxPoint& aPosition, const EDA_ANGLE& aAngle, + TEXT_STYLE_FLAGS aTextStyle ) const = 0; protected: /** @@ -269,11 +242,14 @@ protected: virtual VECTOR2D getBoundingBox( const UTF8& aString, const VECTOR2D& aGlyphSize, TEXT_STYLE_FLAGS aTextStyle = 0 ) const = 0; - VECTOR2D drawMarkup( BOX2I* aBoundingBox, GLYPH_LIST& aGlyphs, + VECTOR2D drawMarkup( BOX2I* aBoundingBox, std::vector>& aGlyphs, const std::unique_ptr& aNode, const VECTOR2D& aPosition, const VECTOR2D& aGlyphSize, const EDA_ANGLE& aAngle, TEXT_STYLE_FLAGS aTextStyle, int aLevel = 0 ) const; + ///< Factor that determines the pitch between 2 lines. + static constexpr double INTERLINE_PITCH_RATIO = 1.62; // The golden mean + private: static FONT* getDefaultFont(); diff --git a/include/font/glyph.h b/include/font/glyph.h index bb929ca109..b89f6a4eae 100644 --- a/include/font/glyph.h +++ b/include/font/glyph.h @@ -2,7 +2,7 @@ * This program source code file is part of KICAD, a free EDA CAD application. * * Copyright (C) 2021 Ola Rinta-Koski - * Copyright (C) 2021 Kicad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2021-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 @@ -38,110 +38,16 @@ public: virtual ~GLYPH() {} - virtual void AddPoint( const VECTOR2D& aPoint ) = 0; - - virtual void RaisePen() = 0; - - virtual void Finalize() = 0; + virtual bool IsOutline() const { return false; } + virtual bool IsStroke() const { return false; } virtual BOX2D BoundingBox() = 0; - virtual std::shared_ptr Resize( const VECTOR2D& aGlyphSize ) const = 0; - - virtual std::shared_ptr Translate( const VECTOR2D& aOffset ) const = 0; - - virtual std::shared_ptr Mirror( bool aMirror, - const VECTOR2D& aMirrorOrigin = { 0, 0 } ) const = 0; - virtual void Mirror( const VECTOR2D& aMirrorOrigin = { 0, 0 } ) = 0; - - virtual const SHAPE_POLY_SET& GetPolylist() const = 0; - - virtual const std::vector>& GetPoints() const = 0; - - virtual bool IsOutline() const { return false; } - virtual bool IsStroke() const { return false; } -}; - -typedef std::vector> GLYPH_LIST; - - -class OUTLINE_GLYPH : public GLYPH -{ -public: - OUTLINE_GLYPH( const SHAPE_POLY_SET& poly ) - { - m_polySet = poly; - } - - const SHAPE_POLY_SET& GetPolylist() const override { return m_polySet; } - - bool IsOutline() const override - { - return true; - } - - // - void AddPoint( const VECTOR2D& aPoint ) override - { - wxFAIL_MSG( "unimplemented" ); - } - - void RaisePen() override - { - wxFAIL_MSG( "unimplemented" ); - } - - void Finalize() override - { - wxFAIL_MSG( "unimplemented" ); - } - - BOX2D BoundingBox() override - { - wxFAIL_MSG( "unimplemented" ); - return BOX2D(); - } - - std::shared_ptr Resize( const VECTOR2D& aGlyphSize ) const override - { - wxFAIL_MSG( "unimplemented" ); - return nullptr; - } - - std::shared_ptr Translate( const VECTOR2D& aOffset ) const override - { - wxFAIL_MSG( "unimplemented" ); - return nullptr; - } - - std::shared_ptr Mirror( bool aMirror, - const VECTOR2D& aMirrorOrigin = { 0, 0 } ) const override - { - wxFAIL_MSG( "unimplemented" ); - return nullptr; - } - - void Mirror( const VECTOR2D& aMirrorOrigin = VECTOR2D( 0, 0 ) ) override - { - wxFAIL_MSG( "unimplemented" ); - } - - const std::vector>& GetPoints() const override - { - wxFAIL_MSG( "unimplemented" ); - return m_dummy; - } - -private: - SHAPE_POLY_SET m_polySet; - - // For unimplemented return values - std::vector> m_dummy; }; -class STROKE_GLYPH : public GLYPH +class STROKE_GLYPH : public GLYPH, public std::vector> { public: STROKE_GLYPH() @@ -149,51 +55,23 @@ public: STROKE_GLYPH( const STROKE_GLYPH& aGlyph ); - void AddPoint( const VECTOR2D& aPoint ) override; + bool IsStroke() const override { return true; } - void RaisePen() override; + void AddPoint( const VECTOR2D& aPoint ); + void RaisePen(); + void Finalize(); - void Finalize() override; - - BOX2D BoundingBox() override; - - std::shared_ptr Resize( const VECTOR2D& aGlyphSize ) const override; - - std::shared_ptr Translate( const VECTOR2D& aOffset ) const override; - - std::shared_ptr Transform( const VECTOR2D& aGlyphSize, const VECTOR2D& aOffset, - double aTilt ); - - std::shared_ptr Mirror( bool aMirror, - const VECTOR2D& aMirrorOrigin = { 0, 0 } ) const override; + BOX2D BoundingBox() override { return m_boundingBox; } + void SetBoundingBox( const BOX2D& bbox ) { m_boundingBox = bbox; } void Mirror( const VECTOR2D& aMirrorOrigin = { 0, 0 } ) override; - bool IsStroke() const override { return true; } - - // - const SHAPE_POLY_SET& GetPolylist() const override - { - wxFAIL_MSG( "unimplemented" ); - return m_dummy; - } - - const std::vector>& GetPoints() const override { return m_pointLists; } + std::unique_ptr Transform( const VECTOR2D& aGlyphSize, const VECTOR2D& aOffset, + double aTilt ); private: - void clearBoundingBox() - { - m_boundingBox.SetOrigin( 0, 0 ); - m_boundingBox.SetSize( 0, 0 ); - } - -private: - bool m_penIsDown = false; - std::vector> m_pointLists; - BOX2D m_boundingBox; - - // For unimplemented return values - SHAPE_POLY_SET m_dummy; + bool m_penIsDown = false; + BOX2D m_boundingBox; }; diff --git a/include/font/stroke_font.h b/include/font/stroke_font.h index c7b31e38d3..48a1d56d0b 100644 --- a/include/font/stroke_font.h +++ b/include/font/stroke_font.h @@ -3,7 +3,7 @@ * * Copyright (C) 2012 Torsten Hueter, torstenhtr gmx.de * Copyright (C) 2013 CERN - * Copyright (C) 2016-2021 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2016-2022 KiCad Developers, see AUTHORS.txt for contributors. * * @author Maciej Suminski * @@ -90,9 +90,10 @@ public: */ VECTOR2D ComputeTextLineSize( const KIGFX::GAL* aGal, const UTF8& aText ) const override; - VECTOR2I GetTextAsPolygon( BOX2I* aBoundingBox, GLYPH_LIST& aGlyphs, const UTF8& aText, - const VECTOR2D& aGlyphSize, const wxPoint& aPosition, - const EDA_ANGLE& aAngle, TEXT_STYLE_FLAGS aTextStyle ) const override; + VECTOR2I GetTextAsGlyphs( BOX2I* aBoundingBox, std::vector>& aGlyphs, + const UTF8& aText, const VECTOR2D& aGlyphSize, + const wxPoint& aPosition, const EDA_ANGLE& aAngle, + TEXT_STYLE_FLAGS aTextStyle ) const override; protected: VECTOR2D getBoundingBox( const UTF8& aString, const VECTOR2D& aGlyphSize, @@ -108,9 +109,9 @@ private: void loadNewStrokeFont( const char* const aNewStrokeFont[], int aNewStrokeFontSize ); private: - const GLYPH_LIST* m_glyphs; ///< Glyph list - const GLYPH_BOUNDING_BOX_LIST* m_glyphBoundingBoxes; ///< Bounding boxes of the glyphs - double m_maxGlyphWidth; + const std::vector>* m_glyphs; + const GLYPH_BOUNDING_BOX_LIST* m_glyphBoundingBoxes; + double m_maxGlyphWidth; }; } //namespace KIFONT diff --git a/include/gal/graphics_abstraction_layer.h b/include/gal/graphics_abstraction_layer.h index 6ff518c110..96b1c642f6 100644 --- a/include/gal/graphics_abstraction_layer.h +++ b/include/gal/graphics_abstraction_layer.h @@ -176,13 +176,6 @@ public: */ virtual void DrawGlyph( const KIFONT::GLYPH& aGlyph, int aNth = 0, int aTotal = 1 ) {}; - void DrawGlyph( const std::shared_ptr& aGlyph, int aNth = 0, int aTotal = 1 ) - { - DrawGlyph( *aGlyph, aNth, aTotal ); - } - - void DrawGlyphs( const KIFONT::GLYPH_LIST& aGlyphs ); - /** * Draw a polygon. *