KiCad PCB EDA Suite
Loading...
Searching...
No Matches
glyph.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2021 Ola Rinta-Koski <[email protected]>
5 * Copyright (C) 2021-2024 KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software: you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include <vector>
22#include <font/glyph.h>
23#include <trigo.h>
24
25using namespace KIFONT;
26
27
29{
30 reserve( aGlyph.size() );
31
32 for( const std::vector<VECTOR2D>& pointList : aGlyph )
33 push_back( pointList );
34
36}
37
38
39void STROKE_GLYPH::AddPoint( const VECTOR2D& aPoint )
40{
41 if( !m_penIsDown )
42 {
43 emplace_back();
44 back().reserve( 16 ); // This handles all but 359 strokes (out of over 328,000)
45 m_penIsDown = true;
46 }
47
48 back().push_back( aPoint );
49}
50
51
53{
54#if 0
55 if( m_penIsDown )
56 back().shrink_to_fit();
57#endif
58
59 m_penIsDown = false;
60}
61
62
64{
65 // Shrinking the strokes saves a bit less than 512K of memory. It's not worth it for the
66 // performance hit of doing more than 328,000 reallocs.
67#if 0
68if( !empty() && !back().empty() )
69 back().shrink_to_fit();
70#endif
71}
72
73
74std::unique_ptr<GLYPH> STROKE_GLYPH::Transform( const VECTOR2D& aGlyphSize, const VECTOR2I& aOffset,
75 double aTilt, const EDA_ANGLE& aAngle, bool aMirror,
76 const VECTOR2I& aOrigin )
77{
78 std::unique_ptr<STROKE_GLYPH> glyph = std::make_unique<STROKE_GLYPH>( *this );
79
80 VECTOR2D end = glyph->m_boundingBox.GetEnd();
81
82 end.x *= aGlyphSize.x;
83 end.y *= aGlyphSize.y;
84
85 if( aTilt )
86 end.x -= end.y * aTilt;
87
88 glyph->m_boundingBox.SetEnd( end );
89 glyph->m_boundingBox.Offset( aOffset );
90
91 for( std::vector<VECTOR2D>& pointList : *glyph.get() )
92 {
93 for( VECTOR2D& point : pointList )
94 {
95 point *= aGlyphSize;
96
97 if( aTilt )
98 point.x -= point.y * aTilt;
99
100 point += aOffset;
101
102 if( aMirror )
103 point.x = aOrigin.x - ( point.x - aOrigin.x );
104
105 if( !aAngle.IsZero() )
106 RotatePoint( point, aOrigin, aAngle );
107 }
108 }
109
110 return glyph;
111}
112
113
115{
116 BOX2I bbox = BBox();
117 return BOX2D( bbox.GetOrigin(), bbox.GetSize() );
118}
119
120
121void OUTLINE_GLYPH::Triangulate( std::function<void( const VECTOR2I& aPt1,
122 const VECTOR2I& aPt2,
123 const VECTOR2I& aPt3 )> aCallback ) const
124{
125 const_cast<OUTLINE_GLYPH*>( this )->CacheTriangulation( false );
126
127 for( unsigned int i = 0; i < TriangulatedPolyCount(); i++ )
128 {
130
131 for( size_t j = 0; j < polygon->GetTriangleCount(); j++ )
132 {
133 VECTOR2I a, b, c;
134 polygon->GetTriangle( j, a, b, c );
135 aCallback( a, b, c );
136 }
137 }
138}
139
140
141void OUTLINE_GLYPH::CacheTriangulation( bool aPartition, bool aSimplify )
142{
143 // Only call CacheTriangulation if it has never been done before. Otherwise we'll hash
144 // the triangulation to see if it has been edited, and glyphs are invariant after creation.
145 //
146 // Also forces "partition" to false as we never want to partition a glyph.
147
148 if( TriangulatedPolyCount() == 0 )
149 SHAPE_POLY_SET::CacheTriangulation( false, aSimplify );
150}
151
152
153std::vector<std::unique_ptr<SHAPE_POLY_SET::TRIANGULATED_POLYGON>> OUTLINE_GLYPH::GetTriangulationData() const
154{
155 std::vector<std::unique_ptr<SHAPE_POLY_SET::TRIANGULATED_POLYGON>> data;
156
157 for( const std::unique_ptr<SHAPE_POLY_SET::TRIANGULATED_POLYGON>& poly : m_triangulatedPolys )
158 data.push_back( std::make_unique<SHAPE_POLY_SET::TRIANGULATED_POLYGON>( *poly ) );
159
160 return data;
161}
162
163
164void OUTLINE_GLYPH::CacheTriangulation( std::vector<std::unique_ptr<SHAPE_POLY_SET::TRIANGULATED_POLYGON>>& aHintData )
165{
166 cacheTriangulation( false, false, &aHintData );
167}
BOX2< VECTOR2D > BOX2D
Definition: box2.h:854
const Vec & GetOrigin() const
Definition: box2.h:184
const Vec & GetSize() const
Definition: box2.h:180
bool IsZero() const
Definition: eda_angle.h:175
void CacheTriangulation(bool aPartition=true, bool aSimplify=false) override
Build a polygon triangulation, needed to draw a polygon on OpenGL and in some other calculations.
Definition: glyph.cpp:141
BOX2D BoundingBox() override
Definition: glyph.cpp:114
void Triangulate(std::function< void(const VECTOR2I &aPt1, const VECTOR2I &aPt2, const VECTOR2I &aPt3)> aCallback) const
Definition: glyph.cpp:121
std::vector< std::unique_ptr< SHAPE_POLY_SET::TRIANGULATED_POLYGON > > GetTriangulationData() const
Definition: glyph.cpp:153
void AddPoint(const VECTOR2D &aPoint)
Definition: glyph.cpp:39
BOX2D m_boundingBox
Definition: glyph.h:125
std::unique_ptr< GLYPH > Transform(const VECTOR2D &aGlyphSize, const VECTOR2I &aOffset, double aTilt, const EDA_ANGLE &aAngle, bool aMirror, const VECTOR2I &aOrigin)
Definition: glyph.cpp:74
void GetTriangle(int index, VECTOR2I &a, VECTOR2I &b, VECTOR2I &c) const
virtual void CacheTriangulation(bool aPartition=true, bool aSimplify=false)
Build a polygon triangulation, needed to draw a polygon on OpenGL and in some other calculations.
std::vector< std::unique_ptr< TRIANGULATED_POLYGON > > m_triangulatedPolys
const TRIANGULATED_POLYGON * TriangulatedPolygon(int aIndex) const
unsigned int TriangulatedPolyCount() const
Return the number of triangulated polygons.
void cacheTriangulation(bool aPartition, bool aSimplify, std::vector< std::unique_ptr< TRIANGULATED_POLYGON > > *aHintData)
const BOX2I BBox(int aClearance=0) const override
Compute a bounding box of the shape, with a margin of aClearance a collision.
static bool empty(const wxTextEntryBase *aCtrl)
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
Definition: trigo.cpp:228