KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_line_ending.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 The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 * or you may search the http://www.gnu.org website for the version 2 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
24#include <base_units.h>
25#include <line_ending.h>
27#include <richio.h>
28
29#include <string>
30#include <vector>
31
32
33BOOST_AUTO_TEST_SUITE( LineEnding )
34
35
36static std::string formatLineEnding( LINE_ENDING_STYLE aStyle, int aLength = 0,
37 int aWidth = 0 )
38{
39 LINE_ENDING ending( aStyle, aLength, aWidth );
40
41 STRING_FORMATTER formatter;
42 ending.Format( &formatter, pcbIUScale, "start_shape" );
43
44 return formatter.GetString();
45}
46
47
48static void checkDoesNotWriteFill( const std::string& aFormatted )
49{
50 BOOST_CHECK_EQUAL( aFormatted.find( "(fill" ), std::string::npos );
51}
52
53
54static void checkVectorEqual( const VECTOR2I& aActual, const VECTOR2I& aExpected )
55{
56 BOOST_CHECK_EQUAL( aActual.x, aExpected.x );
57 BOOST_CHECK_EQUAL( aActual.y, aExpected.y );
58}
59
60
61static void checkEffectiveSize( int aLength, int aWidth, const VECTOR2I& aExpected )
62{
63 const int lineWidth = 100;
64
65 LINE_ENDING ending( LINE_ENDING_STYLE::ARROW, aLength, aWidth );
66
67 checkVectorEqual( ending.GetEffectiveSize( lineWidth ), aExpected );
68}
69
70
71static void checkShortenDepth( LINE_ENDING_STYLE aStyle, int aLength, int aWidth,
72 int aStrokeWidth, int aExpected )
73{
74 const int lineWidth = 100;
75
76 LINE_ENDING ending( aStyle, aLength, aWidth, aStrokeWidth );
77
78 BOOST_CHECK_EQUAL( ending.GetShortenDepth( lineWidth ), aExpected );
79}
80
81
82static void checkCurveOrientationDepth( LINE_ENDING_STYLE aStyle, int aLength, int aWidth,
83 int aStrokeWidth, int aExpected )
84{
85 const int lineWidth = 100;
86
87 LINE_ENDING ending( aStyle, aLength, aWidth, aStrokeWidth );
88
89 BOOST_CHECK_EQUAL( ending.GetCurveOrientationDepth( lineWidth ), aExpected );
90}
91
92
93BOOST_AUTO_TEST_CASE( FormatDoesNotWriteFill )
94{
95 const std::string closedArrow = formatLineEnding( LINE_ENDING_STYLE::ARROW );
96 const std::string openArrow = formatLineEnding( LINE_ENDING_STYLE::ARROW_OPEN );
99
100 BOOST_CHECK_EQUAL( closedArrow, "(start_shape arrow)" );
101 BOOST_CHECK_EQUAL( openArrow, "(start_shape arrow_open)" );
102 BOOST_CHECK_EQUAL( circle, "(start_shape circle)" );
103 BOOST_CHECK_EQUAL( square, "(start_shape square)" );
104
105 checkDoesNotWriteFill( closedArrow );
106 checkDoesNotWriteFill( openArrow );
109}
110
111
112BOOST_AUTO_TEST_CASE( FormatPreservesExplicitEqualLengthWidth )
113{
114 const std::string explicitSquare = formatLineEnding( LINE_ENDING_STYLE::SQUARE,
115 pcbIUScale.mmToIU( 2.0 ),
116 pcbIUScale.mmToIU( 2.0 ) );
117
118 BOOST_CHECK_NE( explicitSquare.find( "(length " ), std::string::npos );
119 BOOST_CHECK_NE( explicitSquare.find( "(width " ), std::string::npos );
120
121 const std::string autoWidthArrow = formatLineEnding( LINE_ENDING_STYLE::ARROW,
122 pcbIUScale.mmToIU( 2.0 ), 0 );
123
124 BOOST_CHECK_NE( autoWidthArrow.find( "(length " ), std::string::npos );
125 BOOST_CHECK_EQUAL( autoWidthArrow.find( "(width " ), std::string::npos );
126}
127
128
129BOOST_AUTO_TEST_CASE( GetEffectiveSizeUsesConfiguredAndAutoAxes )
130{
131 checkEffectiveSize( 700, 300, { 700, 300 } );
132 checkEffectiveSize( 700, 0, { 700, 700 } );
133 checkEffectiveSize( 0, 300, { 300, 300 } );
134 checkEffectiveSize( 0, 0, { 500, 500 } );
135}
136
137
138BOOST_AUTO_TEST_CASE( GetShapesProducesStyleGeometry )
139{
140 const VECTOR2I endpoint( 1000, 2000 );
141 const EDA_ANGLE tangent( 0.0, DEGREES_T );
142 std::vector<VECTOR2I> polygon;
143
144 LINE_ENDING none( LINE_ENDING_STYLE::NONE, 300, 200 );
145 none.GetShapes( endpoint, tangent, 100, polygon );
146 BOOST_CHECK( polygon.empty() );
147
148 LINE_ENDING arrow( LINE_ENDING_STYLE::ARROW, 300, 200 );
149 arrow.GetShapes( endpoint, tangent, 100, polygon );
150 BOOST_REQUIRE_EQUAL( polygon.size(), 4 );
151 checkVectorEqual( polygon[0], { 1000, 2000 } );
152 checkVectorEqual( polygon[1], { 700, 2100 } );
153 checkVectorEqual( polygon[2], { 700, 1900 } );
154 checkVectorEqual( polygon[3], { 1000, 2000 } );
155
156 LINE_ENDING openArrow( LINE_ENDING_STYLE::ARROW_OPEN, 300, 200 );
157 openArrow.GetShapes( endpoint, tangent, 100, polygon );
158 BOOST_REQUIRE_EQUAL( polygon.size(), 3 );
159 checkVectorEqual( polygon[0], { 700, 1900 } );
160 checkVectorEqual( polygon[1], { 1000, 2000 } );
161 checkVectorEqual( polygon[2], { 700, 2100 } );
162
164 square.GetShapes( endpoint, tangent, 100, polygon );
165 BOOST_REQUIRE_EQUAL( polygon.size(), 5 );
166 checkVectorEqual( polygon[0], { 1200, 2100 } );
167 checkVectorEqual( polygon[1], { 1200, 1900 } );
168 checkVectorEqual( polygon[2], { 800, 1900 } );
169 checkVectorEqual( polygon[3], { 800, 2100 } );
170 checkVectorEqual( polygon[4], { 1200, 2100 } );
171
173 circle.GetShapes( endpoint, tangent, 100, polygon );
174 BOOST_REQUIRE_EQUAL( polygon.size(), 33 );
175 checkVectorEqual( polygon.front(), { 1200, 2000 } );
176 checkVectorEqual( polygon.back(), { 1200, 2000 } );
177}
178
179
192
193
194BOOST_AUTO_TEST_CASE( GetShortenDepthUsesEndpointPolicy )
195{
197
198 // Configured sizes: arrow tip consumes the full length, centered shapes consume half.
199 checkShortenDepth( LINE_ENDING_STYLE::ARROW, 800, 300, 0, 800 );
201 checkShortenDepth( LINE_ENDING_STYLE::CIRCLE, 800, 300, 0, 400 );
202 checkShortenDepth( LINE_ENDING_STYLE::SQUARE, 800, 300, 0, 400 );
203
204 // Auto sizes use DEFAULT_RATIO_LENGTH against the parent line width.
208
209 // Stroked outlines reduce the line-body shortening by half the outline width.
210 checkShortenDepth( LINE_ENDING_STYLE::ARROW, 800, 300, 100, 750 );
211 checkShortenDepth( LINE_ENDING_STYLE::CIRCLE, 800, 300, 100, 350 );
212 checkShortenDepth( LINE_ENDING_STYLE::SQUARE, 100, 300, 300, 0 );
213}
214
215
constexpr EDA_IU_SCALE pcbIUScale
Definition base_units.h:121
double square(double x)
Decorative shape (arrowhead, circle, square) at the start or end of a graphic line,...
Definition line_ending.h:62
int GetShortenDepth(int aLineWidth) const
Return how far the line should be shortened at this ending.
int GetCurveOrientationDepth(int aLineWidth) const
Return how far along a curved body to look when orienting this ending.
VECTOR2I GetEffectiveSize(int aLineWidth) const
Return the rendered size per axis, applying auto-sizing when length or width is 0.
void GetShapes(const VECTOR2I &aPoint, const EDA_ANGLE &aTangent, int aLineWidth, std::vector< VECTOR2I > &aPolygon) const
Generate ending geometry as polygon vertices at the given point and direction.
void Format(OUTPUTFORMATTER *aOut, const EDA_IU_SCALE &aIuScale, const char *aToken) const
Implement an OUTPUTFORMATTER to a memory buffer.
Definition richio.h:430
const std::string & GetString()
Definition richio.h:453
@ DEGREES_T
Definition eda_angle.h:31
LINE_ENDING_STYLE
Line ending styles for graphic lines, arcs, and beziers.
Definition line_ending.h:44
STL namespace.
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_CASE(FormatDoesNotWriteFill)
static void checkDoesNotWriteFill(const std::string &aFormatted)
static void checkShortenDepth(LINE_ENDING_STYLE aStyle, int aLength, int aWidth, int aStrokeWidth, int aExpected)
static void checkEffectiveSize(int aLength, int aWidth, const VECTOR2I &aExpected)
static void checkVectorEqual(const VECTOR2I &aActual, const VECTOR2I &aExpected)
static std::string formatLineEnding(LINE_ENDING_STYLE aStyle, int aLength=0, int aWidth=0)
static void checkCurveOrientationDepth(LINE_ENDING_STYLE aStyle, int aLength, int aWidth, int aStrokeWidth, int aExpected)
SHAPE_CIRCLE circle(c.m_circle_center, c.m_circle_radius)
BOOST_CHECK_EQUAL(result, "25.4")
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683