KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_eda_text.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) 2023 Wayne Stambaugh <[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 <boost/test/unit_test.hpp>
22#include <algorithm>
23#include <base_units.h>
24#include <eda_text.h>
25#include <gr_text.h>
26#include <text_var_dependency.h>
27
28
29BOOST_AUTO_TEST_SUITE( EdaText )
30
31
32// Common starting point for the Bold/thickness decoupling tests (#12911); text size doesn't
33// affect their outcomes, so a fixed 200x200 keeps each case focused on what it's testing.
35{
37 t.SetTextSize( VECTOR2I( 200, 200 ), false );
38 return t;
39}
40
41
43{
44 std::hash<EDA_TEXT> hasher;
47
48 BOOST_CHECK_EQUAL( a, b );
49 BOOST_CHECK_EQUAL( hasher( a ), hasher( b ) );
50
51 a.SetText( wxS( "A" ) );
52 BOOST_CHECK_GT( a, b );
53 BOOST_CHECK_NE( hasher( a ), hasher( b ) );
54
55 b.SetText( wxS( "B" ) );
56 BOOST_CHECK_LT( a, b );
57 BOOST_CHECK_NE( hasher( a ), hasher( b ) );
58
59 a.SetText( wxS( "B" ) );
60 a.SetTextPos( VECTOR2I( 1, 0 ) );
61 BOOST_CHECK_GT( a, b );
62
63 a.SetTextPos( VECTOR2I( -1, 0 ) );
64 BOOST_CHECK_LT( a, b );
65
66 a.SetTextPos( VECTOR2I( 0, 0 ) );
67 b.SetTextPos( VECTOR2I( 0, 1 ) );
68 BOOST_CHECK_LT( a, b );
69
70 b.SetTextPos( VECTOR2I( 0, -1 ) );
71 BOOST_CHECK_GT( a, b );
72
73 // Text attributes are tested in the TEXT_ATTRIBUTES unit tests.
74}
75
76
77BOOST_AUTO_TEST_CASE( BoldFlagLeavesStoredThicknessAlone )
78{
79 // Neither SetBold nor SetBoldFlag may mutate the stored width (#12911).
81 t.SetTextThickness( 30 );
82
83 t.SetBoldFlag( true );
84 BOOST_CHECK( t.IsBold() );
86
87 t.SetBold( false );
88 BOOST_CHECK( !t.IsBold() );
90}
91
92
93BOOST_AUTO_TEST_CASE( EffectiveWidthAppliesBoldMultiplierForStroke )
94{
95 // Bold scales the explicit base width by 1.6; 10 and 16 stay under the clamp.
97 t.SetTextThickness( 10 );
98
100
101 t.SetBoldFlag( true );
103}
104
105
106BOOST_AUTO_TEST_CASE( EffectiveWidthAutoBoldMatchesLegacy )
107{
108 EDA_TEXT t = makeText200();
109 t.SetTextThickness( 0 );
110 t.SetBoldFlag( true );
111
113}
114
115
116BOOST_AUTO_TEST_CASE( MigrateLegacyBoldStrokeWidthRecoversBase )
117{
118 // Migration divides the baked bold width back to base; auto/non-bold untouched.
119 EDA_TEXT bold = makeText200();
120 bold.SetTextThickness( 32 );
121 bold.SetBoldFlag( true );
124 BOOST_CHECK_EQUAL( bold.GetEffectiveTextPenWidth(), 32 ); // rendered width preserved
125
127 normal.SetTextThickness( 32 );
128 normal.MigrateLegacyBoldStrokeWidth();
129 BOOST_CHECK_EQUAL( normal.GetTextThickness(), 32 );
130
131 EDA_TEXT autoWidth = makeText200();
132 autoWidth.SetTextThickness( 0 );
133 autoWidth.SetBoldFlag( true );
135 BOOST_CHECK_EQUAL( autoWidth.GetTextThickness(), 0 );
136
137 // A width dividing to <= 1 must not collapse into the auto/"near-zero" special case in
138 // GetEffectiveTextPenWidth(), so the floor holds it at 2. That floor means sub-3-IU legacy
139 // widths (a scale no real board or schematic uses) don't round-trip exactly; document the
140 // actual post-migration effective width rather than leaving it unchecked.
141 EDA_TEXT tiny = makeText200();
142 tiny.SetTextThickness( 2 );
143 tiny.SetBoldFlag( true );
147}
148
149
150BOOST_AUTO_TEST_CASE( AutoThicknessOffFreezesBaseNotEffective )
151{
152 // Unchecking auto freezes the base, not the rendered width, so Bold doesn't double it.
153 EDA_TEXT t = makeText200();
154 t.SetTextThickness( 0 );
155 t.SetBoldFlag( true );
156
157 int autoEffective = t.GetEffectiveTextPenWidth();
158
159 t.SetAutoThickness( false );
161 BOOST_CHECK_EQUAL( t.GetEffectiveTextPenWidth(), autoEffective );
162}
163
164
165BOOST_AUTO_TEST_CASE( TextVarReferences_EmptyWhenNoVars )
166{
167 EDA_TEXT t( unityScale );
168 t.SetText( wxS( "plain text" ) );
169 BOOST_CHECK( t.GetTextVarReferences().empty() );
170 BOOST_CHECK( !t.HasTextVars() );
171}
172
173
174BOOST_AUTO_TEST_CASE( TextVarReferences_CapturedAfterSetText )
175{
176 EDA_TEXT t( unityScale );
177 t.SetText( wxS( "${VALUE} - ${U1:MPN}" ) );
178
179 BOOST_CHECK( t.HasTextVars() );
180
181 const auto& refs = t.GetTextVarReferences();
182 BOOST_REQUIRE_EQUAL( refs.size(), 2u );
183
184 auto hasKey = [&]( TEXT_VAR_REF_KEY::KIND k, const wxString& p, const wxString& s )
185 {
186 return std::any_of( refs.begin(), refs.end(),
187 [&]( const TEXT_VAR_REF_KEY& ref )
188 { return ref.kind == k && ref.primary == p && ref.secondary == s; } );
189 };
190
191 BOOST_CHECK( hasKey( TEXT_VAR_REF_KEY::KIND::LOCAL, wxS( "VALUE" ), wxS( "" ) ) );
192 BOOST_CHECK( hasKey( TEXT_VAR_REF_KEY::KIND::CROSS_REF, wxS( "U1" ), wxS( "MPN" ) ) );
193}
194
195
196BOOST_AUTO_TEST_CASE( TextVarReferences_InvalidatedOnRetext )
197{
198 EDA_TEXT t( unityScale );
199 t.SetText( wxS( "${VALUE}" ) );
200 BOOST_REQUIRE_EQUAL( t.GetTextVarReferences().size(), 1u );
201
202 t.SetText( wxS( "${REFERENCE}" ) );
203 const auto& refs = t.GetTextVarReferences();
204 BOOST_REQUIRE_EQUAL( refs.size(), 1u );
205 BOOST_CHECK( refs[0].primary == wxS( "REFERENCE" ) );
206}
207
208
209BOOST_AUTO_TEST_CASE( TextVarReferences_StableReferenceBetweenReads )
210{
211 // Refs are populated eagerly in cacheShownText() and stored as a plain
212 // member; two successive const reads must return the same storage address
213 // so listeners can hold the reference without copying.
214 EDA_TEXT t( unityScale );
215 t.SetText( wxS( "${X} and ${Y}" ) );
216
217 const auto& first = t.GetTextVarReferences();
218 const auto& second = t.GetTextVarReferences();
219
220 BOOST_REQUIRE_EQUAL( first.size(), 2u );
221 BOOST_CHECK( &first == &second );
222}
223
224
225BOOST_AUTO_TEST_CASE( TextVarReferences_EscapedLiteralNotEdge )
226{
227 // Finding 6 from codex review: extraction must run on raw m_text, not
228 // m_shown_text (post-UnescapeString). A backslash-escaped `\${VAR}` is a
229 // user literal and must NOT produce a dependency edge.
230 EDA_TEXT t( unityScale );
231 t.SetText( wxS( "literal: \\${VAR}" ) );
232
233 BOOST_CHECK( t.GetTextVarReferences().empty() );
234}
235
236
constexpr EDA_IU_SCALE unityScale
Definition base_units.h:124
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition eda_text.h:94
const std::vector< TEXT_VAR_REF_KEY > & GetTextVarReferences() const
Return the set of ${...} references extracted from the source text.
Definition eda_text.cpp:613
virtual void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
Definition eda_text.cpp:495
virtual void SetTextPos(const VECTOR2I &aPoint)
Definition eda_text.cpp:539
virtual int GetTextWidth() const
Definition eda_text.h:304
void SetBoldFlag(bool aBold)
Set only the bold flag, without changing the font.
Definition eda_text.cpp:319
bool HasTextVars() const
Indicates the ShownText has text var references which need to be processed.
Definition eda_text.h:139
void MigrateLegacyBoldStrokeWidth()
Migrate a pre-v11 bold stroke text so its stored thickness holds the base (non-bold) width.
Definition eda_text.cpp:327
virtual void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
Definition eda_text.cpp:245
void SetBold(bool aBold)
Set the text to be bold - this will also update the font if needed.
Definition eda_text.cpp:305
void SetAutoThickness(bool aAuto)
Definition eda_text.cpp:253
int GetEffectiveTextPenWidth(int aDefaultPenWidth=0) const
The EffectiveTextPenWidth uses the text thickness if > 1 or aDefaultPenWidth.
Definition eda_text.cpp:422
bool IsBold() const
Definition eda_text.h:215
virtual int GetTextThickness() const
Definition eda_text.h:159
virtual void SetText(const wxString &aText)
Definition eda_text.cpp:231
int GetPenSizeForBold(int aTextSize)
Definition gr_text.cpp:33
int GetPenSizeForNormal(int aTextSize)
Definition gr_text.cpp:57
Identifies a single resolvable source that a text item's ${...} reference depends on.
KIND
Categorizes a reference by the source that will produce its value.
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
static EDA_TEXT makeText200()
BOOST_AUTO_TEST_CASE(Compare)
BOOST_AUTO_TEST_SUITE_END()
BOOST_CHECK_EQUAL(result, "25.4")
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683