Go back to using inter-character spacing from the stroke font.
Fixes https://gitlab.com/kicad/code/kicad/issues/1078
This commit is contained in:
parent
6f52edd618
commit
8e4a4306c7
|
@ -170,7 +170,9 @@ void BASIC_GAL::DrawGlyph( const KIFONT::GLYPH& aGlyph, int aNth, int aTotal )
|
|||
{
|
||||
if( aGlyph.IsStroke() )
|
||||
{
|
||||
for( const std::vector<VECTOR2D>& pointList : aGlyph.GetPoints() )
|
||||
const auto& strokeGlyph = static_cast<const KIFONT::STROKE_GLYPH&>( aGlyph );
|
||||
|
||||
for( const std::vector<VECTOR2D>& pointList : strokeGlyph )
|
||||
DrawPolyline( pointList );
|
||||
}
|
||||
#if 0 // FONT TODO
|
||||
|
|
|
@ -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<std::unique_ptr<GLYPH>>& aGlyphs,
|
||||
const std::unique_ptr<MARKUP::NODE>& 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<std::unique_ptr<GLYPH>> 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>& glyph : glyphs )
|
||||
for( const std::unique_ptr<GLYPH>& 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<std::unique_ptr<GLYPH>> glyphs; // ignored
|
||||
VECTOR2D nextPosition = drawMarkup( aBoundingBox, glyphs, markupRoot, aPosition, aGlyphSize,
|
||||
aAngle, false, textStyle );
|
||||
|
||||
return nextPosition;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2021 Ola Rinta-Koski <gitlab@rinta-koski.net>
|
||||
* 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<VECTOR2D>& pointList : aGlyph.m_pointLists )
|
||||
m_pointLists.push_back( pointList );
|
||||
for( const std::vector<VECTOR2D>& 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<VECTOR2D> 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<VECTOR2D>& 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<GLYPH> STROKE_GLYPH::Resize( const VECTOR2D& aGlyphSize ) const
|
||||
{
|
||||
std::shared_ptr<STROKE_GLYPH> glyph = std::make_shared<STROKE_GLYPH>( *this );
|
||||
|
||||
glyph->clearBoundingBox();
|
||||
|
||||
bool first = true;
|
||||
|
||||
for( std::vector<VECTOR2D>& 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<GLYPH> STROKE_GLYPH::Translate( const VECTOR2D& aOffset ) const
|
||||
{
|
||||
auto glyph = std::make_shared<STROKE_GLYPH>( *this );
|
||||
|
||||
glyph->clearBoundingBox();
|
||||
|
||||
bool first = true;
|
||||
|
||||
for( std::vector<VECTOR2D>& 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<GLYPH> STROKE_GLYPH::Transform( const VECTOR2D& aGlyphSize, const VECTOR2D& aOffset,
|
||||
std::unique_ptr<GLYPH> STROKE_GLYPH::Transform( const VECTOR2D& aGlyphSize, const VECTOR2D& aOffset,
|
||||
double aTilt )
|
||||
{
|
||||
std::shared_ptr<STROKE_GLYPH> glyph = std::make_shared<STROKE_GLYPH>( *this );
|
||||
std::unique_ptr<STROKE_GLYPH> glyph = std::make_unique<STROKE_GLYPH>( *this );
|
||||
|
||||
glyph->clearBoundingBox();
|
||||
VECTOR2D end = glyph->m_boundingBox.GetEnd();
|
||||
|
||||
bool first = true;
|
||||
end.x *= aGlyphSize.x;
|
||||
end.y *= aGlyphSize.y;
|
||||
|
||||
for( std::vector<VECTOR2D>& pointList : glyph->m_pointLists )
|
||||
if( aTilt )
|
||||
end.x -= end.y * aTilt;
|
||||
|
||||
glyph->m_boundingBox.SetEnd( end );
|
||||
glyph->m_boundingBox.Offset( aOffset );
|
||||
|
||||
for( std::vector<VECTOR2D>& pointList : *glyph.get() )
|
||||
{
|
||||
for( VECTOR2D& point : pointList )
|
||||
{
|
||||
|
@ -170,16 +90,6 @@ std::shared_ptr<GLYPH> 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<GLYPH> STROKE_GLYPH::Transform( const VECTOR2D& aGlyphSize, cons
|
|||
}
|
||||
|
||||
|
||||
std::shared_ptr<GLYPH> 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<STROKE_GLYPH>( *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<VECTOR2D>& pointList : m_pointLists )
|
||||
m_boundingBox.SetOrigin( pos );
|
||||
m_boundingBox.SetEnd( end );
|
||||
|
||||
for( std::vector<VECTOR2D>& 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 );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
|
||||
* Copyright (C) 2013 CERN
|
||||
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||
* 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 <gal/graphics_abstraction_layer.h>
|
||||
#include <wx/string.h>
|
||||
#include <wx/filename.h>
|
||||
#include <wx/textfile.h>
|
||||
#include <newstroke_font.h>
|
||||
#include <font/glyph.h>
|
||||
|
@ -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<BOX2D>* g_defaultFontGlyphBoundingBoxes; ///< Bounding boxes of the glyphs
|
||||
bool g_defaultFontInitialized = false;
|
||||
std::vector<std::shared_ptr<GLYPH>> g_defaultFontGlyphs;
|
||||
std::vector<BOX2D>* g_defaultFontGlyphBoundingBoxes;
|
||||
|
||||
|
||||
STROKE_FONT::STROKE_FONT() :
|
||||
|
@ -83,6 +79,25 @@ STROKE_FONT* STROKE_FONT::LoadFont( const wxString& aFontName )
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void buildGlyphBoundingBox( std::shared_ptr<STROKE_GLYPH>& aGlyph, double aGlyphWidth )
|
||||
{
|
||||
VECTOR2D min( 0, 0 );
|
||||
VECTOR2D max( aGlyphWidth, 0 );
|
||||
|
||||
for( const std::vector<VECTOR2D>& 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<STROKE_GLYPH>();
|
||||
double glyphStartX = 0.0;
|
||||
double glyphEndX = 0.0;
|
||||
double glyphWidth = 0.0;
|
||||
|
||||
std::vector<VECTOR2D>* 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<std::unique_ptr<GLYPH>> 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<std::unique_ptr<GLYPH>>& 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<STROKE_GLYPH*>( m_glyphs->at( dd ).get() );
|
||||
STROKE_GLYPH* source = static_cast<STROKE_GLYPH*>( 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<STROKE_GLYPH> overbarGlyph = std::make_shared<STROKE_GLYPH>();
|
||||
std::unique_ptr<STROKE_GLYPH> 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 )
|
||||
|
|
|
@ -1765,7 +1765,9 @@ void CAIRO_GAL_BASE::DrawGlyph( const KIFONT::GLYPH& aGlyph, int aNth, int aTota
|
|||
{
|
||||
if( aGlyph.IsStroke() )
|
||||
{
|
||||
for( const std::vector<VECTOR2D>& pointList : aGlyph.GetPoints() )
|
||||
const auto& strokeGlyph = static_cast<const KIFONT::STROKE_GLYPH&>( aGlyph );
|
||||
|
||||
for( const std::vector<VECTOR2D>& pointList : strokeGlyph )
|
||||
drawPoly( pointList );
|
||||
}
|
||||
#if 0 // FONT TODO
|
||||
|
|
|
@ -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<KIFONT::GLYPH>& glyph : aGlyphs )
|
||||
{
|
||||
DrawGlyph( glyph, nth, total );
|
||||
nth++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Fallback for implementations that don't implement bitmap text: use stroke font
|
||||
*/
|
||||
|
|
|
@ -2415,7 +2415,9 @@ void OPENGL_GAL::DrawGlyph( const KIFONT::GLYPH& aGlyph, int aNth, int aTotal )
|
|||
{
|
||||
if( aGlyph.IsStroke() )
|
||||
{
|
||||
for( const std::vector<VECTOR2D>& pointList : aGlyph.GetPoints() )
|
||||
const auto& strokeGlyph = static_cast<const KIFONT::STROKE_GLYPH&>( aGlyph );
|
||||
|
||||
for( const std::vector<VECTOR2D>& pointList : strokeGlyph )
|
||||
DrawPolyline( pointList );
|
||||
}
|
||||
#if 0 // FONT TODO
|
||||
|
|
|
@ -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 <utf8.h>
|
||||
#include <font/glyph.h>
|
||||
#include <font/text_attributes.h>
|
||||
|
||||
|
||||
namespace MARKUP
|
||||
{
|
||||
struct NODE;
|
||||
}
|
||||
#include <markup_parser.h>
|
||||
|
||||
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<std::unique_ptr<GLYPH>>& 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<std::unique_ptr<GLYPH>>& aGlyphs,
|
||||
const std::unique_ptr<MARKUP::NODE>& 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();
|
||||
|
||||
|
|
|
@ -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<GLYPH> Resize( const VECTOR2D& aGlyphSize ) const = 0;
|
||||
|
||||
virtual std::shared_ptr<GLYPH> Translate( const VECTOR2D& aOffset ) const = 0;
|
||||
|
||||
virtual std::shared_ptr<GLYPH> 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<std::vector<VECTOR2D>>& GetPoints() const = 0;
|
||||
|
||||
virtual bool IsOutline() const { return false; }
|
||||
virtual bool IsStroke() const { return false; }
|
||||
};
|
||||
|
||||
typedef std::vector<std::shared_ptr<GLYPH>> 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<GLYPH> Resize( const VECTOR2D& aGlyphSize ) const override
|
||||
{
|
||||
wxFAIL_MSG( "unimplemented" );
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<GLYPH> Translate( const VECTOR2D& aOffset ) const override
|
||||
{
|
||||
wxFAIL_MSG( "unimplemented" );
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<GLYPH> 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<std::vector<VECTOR2D>>& GetPoints() const override
|
||||
{
|
||||
wxFAIL_MSG( "unimplemented" );
|
||||
return m_dummy;
|
||||
}
|
||||
|
||||
private:
|
||||
SHAPE_POLY_SET m_polySet;
|
||||
|
||||
// For unimplemented return values
|
||||
std::vector<std::vector<VECTOR2D>> m_dummy;
|
||||
};
|
||||
|
||||
|
||||
class STROKE_GLYPH : public GLYPH
|
||||
class STROKE_GLYPH : public GLYPH, public std::vector<std::vector<VECTOR2D>>
|
||||
{
|
||||
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<GLYPH> Resize( const VECTOR2D& aGlyphSize ) const override;
|
||||
|
||||
std::shared_ptr<GLYPH> Translate( const VECTOR2D& aOffset ) const override;
|
||||
|
||||
std::shared_ptr<GLYPH> Transform( const VECTOR2D& aGlyphSize, const VECTOR2D& aOffset,
|
||||
double aTilt );
|
||||
|
||||
std::shared_ptr<GLYPH> 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<std::vector<VECTOR2D>>& GetPoints() const override { return m_pointLists; }
|
||||
std::unique_ptr<GLYPH> 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<std::vector<VECTOR2D>> m_pointLists;
|
||||
BOX2D m_boundingBox;
|
||||
|
||||
// For unimplemented return values
|
||||
SHAPE_POLY_SET m_dummy;
|
||||
bool m_penIsDown = false;
|
||||
BOX2D m_boundingBox;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> 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 <maciej.suminski@cern.ch>
|
||||
*
|
||||
|
@ -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<std::unique_ptr<GLYPH>>& 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<std::shared_ptr<GLYPH>>* m_glyphs;
|
||||
const GLYPH_BOUNDING_BOX_LIST* m_glyphBoundingBoxes;
|
||||
double m_maxGlyphWidth;
|
||||
};
|
||||
|
||||
} //namespace KIFONT
|
||||
|
|
|
@ -176,13 +176,6 @@ public:
|
|||
*/
|
||||
virtual void DrawGlyph( const KIFONT::GLYPH& aGlyph, int aNth = 0, int aTotal = 1 ) {};
|
||||
|
||||
void DrawGlyph( const std::shared_ptr<KIFONT::GLYPH>& aGlyph, int aNth = 0, int aTotal = 1 )
|
||||
{
|
||||
DrawGlyph( *aGlyph, aNth, aTotal );
|
||||
}
|
||||
|
||||
void DrawGlyphs( const KIFONT::GLYPH_LIST& aGlyphs );
|
||||
|
||||
/**
|
||||
* Draw a polygon.
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue