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 The 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
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
21#include <vector>
22#include <font/glyph.h>
23#include <font/glyph_types.h>
24#include <trigo.h>
25
26using namespace KIFONT;
27
28
30{
31 reserve( aGlyph.size() );
32
33 for( const std::vector<VECTOR2D>& pointList : aGlyph )
34 push_back( pointList );
35
37}
38
39
40void STROKE_GLYPH::AddPoint( const VECTOR2D& aPoint )
41{
42 if( !m_penIsDown )
43 {
44 emplace_back();
45 back().reserve( 16 ); // This handles all but 359 strokes (out of over 328,000)
46 m_penIsDown = true;
47 }
48
49 back().push_back( aPoint );
50}
51
52
54{
55#if 0
56 if( m_penIsDown )
57 back().shrink_to_fit();
58#endif
59
60 m_penIsDown = false;
61}
62
63
65{
66 // Shrinking the strokes saves a bit less than 512K of memory. It's not worth it for the
67 // performance hit of doing more than 328,000 reallocs.
68#if 0
69if( !empty() && !back().empty() )
70 back().shrink_to_fit();
71#endif
72}
73
74
75std::unique_ptr<GLYPH> STROKE_GLYPH::Transform( const VECTOR2D& aGlyphSize, const VECTOR2I& aOffset,
76 double aTilt, const EDA_ANGLE& aAngle, bool aMirror,
77 const VECTOR2I& aOrigin )
78{
79 std::unique_ptr<STROKE_GLYPH> glyph = std::make_unique<STROKE_GLYPH>( *this );
80
81 VECTOR2D end = glyph->m_boundingBox.GetEnd();
82
83 end.x *= aGlyphSize.x;
84 end.y *= aGlyphSize.y;
85
86 if( aTilt != 0.0 )
87 end.x -= end.y * aTilt;
88
89 glyph->m_boundingBox.SetEnd( end );
90 glyph->m_boundingBox.Offset( aOffset );
91
92 for( std::vector<VECTOR2D>& pointList : *glyph )
93 {
94 for( VECTOR2D& point : pointList )
95 {
96 point *= aGlyphSize;
97
98 if( aTilt != 0.0 )
99 point.x -= point.y * aTilt;
100
101 point += aOffset;
102
103 if( aMirror )
104 point.x = aOrigin.x - ( point.x - aOrigin.x );
105
106 if( !aAngle.IsZero() )
107 RotatePoint( point, aOrigin, aAngle );
108 }
109 }
110
111 return glyph;
112}
113
114
115void STROKE_GLYPH::Move( const VECTOR2I& aOffset )
116{
117 m_boundingBox.Offset( aOffset );
118
119 for( std::vector<VECTOR2D>& pointList : *this )
120 {
121 for( VECTOR2D& point : pointList )
122 point += aOffset;
123 }
124}
125
126
128{
129 BOX2I bbox = BBox();
130 return BOX2D( bbox.GetOrigin(), bbox.GetSize() );
131}
132
133
134void OUTLINE_GLYPH::Triangulate( std::function<void( const VECTOR2I& aPt1,
135 const VECTOR2I& aPt2,
136 const VECTOR2I& aPt3 )> aCallback ) const
137{
138 const_cast<OUTLINE_GLYPH*>( this )->CacheTriangulation();
139
140 for( unsigned int i = 0; i < TriangulatedPolyCount(); i++ )
141 {
143
144 for( size_t j = 0; j < polygon->GetTriangleCount(); j++ )
145 {
146 VECTOR2I a, b, c;
147 polygon->GetTriangle( j, a, b, c );
148 aCallback( a, b, c );
149 }
150 }
151}
152
153
154void OUTLINE_GLYPH::CacheTriangulation( bool aSimplify, const TASK_SUBMITTER& aSubmitter, bool aBuildIndexes )
155{
156 // Only call CacheTriangulation if it has never been done before. Otherwise we'll hash
157 // the triangulation to see if it has been edited, and glyphs are invariant after creation.
158
159 if( TriangulatedPolyCount() == 0 )
160 SHAPE_POLY_SET::CacheTriangulation( aSimplify, {}, aBuildIndexes );
161}
162
163
164std::vector<std::unique_ptr<SHAPE_POLY_SET::TRIANGULATED_POLYGON>>
166{
167 std::vector<std::unique_ptr<SHAPE_POLY_SET::TRIANGULATED_POLYGON>> data;
168
169 for( const std::unique_ptr<SHAPE_POLY_SET::TRIANGULATED_POLYGON>& poly : m_triangulatedPolys )
170 data.push_back( std::make_unique<SHAPE_POLY_SET::TRIANGULATED_POLYGON>( *poly ) );
171
172 return data;
173}
174
175
177 std::vector<std::unique_ptr<SHAPE_POLY_SET::TRIANGULATED_POLYGON>>& aHintData )
178{
179 cacheTriangulation( false, &aHintData );
180}
BOX2< VECTOR2I > BOX2I
Definition box2.h:914
BOX2< VECTOR2D > BOX2D
Definition box2.h:915
constexpr const Vec & GetOrigin() const
Definition box2.h:207
constexpr const SizeVec & GetSize() const
Definition box2.h:203
bool IsZero() const
Definition eda_angle.h:135
void CacheTriangulation(bool aSimplify=false, const TASK_SUBMITTER &aSubmitter={}, bool aBuildIndexes=false) override
Build a polygon triangulation, needed to draw a polygon on OpenGL and in some other calculations.
Definition glyph.cpp:154
BOX2D BoundingBox() override
Definition glyph.cpp:127
void Triangulate(std::function< void(const VECTOR2I &aPt1, const VECTOR2I &aPt2, const VECTOR2I &aPt3)> aCallback) const
Definition glyph.cpp:134
std::vector< std::unique_ptr< SHAPE_POLY_SET::TRIANGULATED_POLYGON > > GetTriangulationData() const
Definition glyph.cpp:165
void AddPoint(const VECTOR2D &aPoint)
Definition glyph.cpp:40
void Move(const VECTOR2I &aOffset)
Definition glyph.cpp:115
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:75
void GetTriangle(int index, VECTOR2I &a, VECTOR2I &b, VECTOR2I &c) const
void cacheTriangulation(bool aSimplify, std::vector< std::unique_ptr< TRIANGULATED_POLYGON > > *aHintData, const TASK_SUBMITTER &aSubmitter={}, bool aBuildIndexes=false)
virtual void CacheTriangulation(bool aSimplify=false, const TASK_SUBMITTER &aSubmitter={}, bool aBuildIndexes=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.
std::function< void(std::function< void()>)> TASK_SUBMITTER
Callback that submits a unit of work for asynchronous execution.
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)
VECTOR2I end
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:227
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:708
VECTOR2< double > VECTOR2D
Definition vector2d.h:707