KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_coordinates.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, see <https://www.gnu.org/licenses/>.
18 */
19
20#include <algorithm>
21
22#include <boost/test/unit_test.hpp>
23
24#include <base_units.h>
25#include <gerber_draw_item.h>
26#include <gerber_file_image.h>
28
29
30BOOST_AUTO_TEST_SUITE( GerbviewCoordinates )
31
32
33BOOST_AUTO_TEST_CASE( DecimalModeDoesNotLeakBetweenAxes )
34{
35 wxString path = KI_TEST::GetTestDataRootDir() + "gerbview/mixed_coordinates.gbr";
37
38 BOOST_REQUIRE( image.LoadGerberFile( path ) );
39 BOOST_CHECK_EQUAL( image.GetMessages().GetCount(), 0u );
40
41 const GERBER_DRAW_ITEMS& items = image.GetItems();
42 BOOST_REQUIRE_EQUAL( items.size(), 10u );
43
44 // Both squares have 1 mm sides. The second starts at X=3 mm and uses decimal X
45 // with fixed-format Y. A leaked decimal flag stretches its height to 10 mm.
46 const int unit = gerbIUScale.mmToIU( 1.0 );
47 const VECTOR2I corners[] = { { 0, 0 }, { unit, 0 }, { unit, unit }, { 0, unit } };
48
49 for( int square = 0; square < 2; ++square )
50 {
51 VECTOR2I offset( square * 3 * unit, 0 );
52
53 for( int edge = 0; edge < 4; ++edge )
54 {
55 BOOST_TEST_CONTEXT( "square " << square << ", edge " << edge )
56 {
57 const GERBER_DRAW_ITEM* item = items[square * 4 + edge];
58 VECTOR2I start = corners[edge] + offset;
59 VECTOR2I end = corners[( edge + 1 ) % 4] + offset;
60
61 BOOST_CHECK_EQUAL( item->m_Start.x, start.x );
62 BOOST_CHECK_EQUAL( item->m_Start.y, start.y );
63 BOOST_CHECK_EQUAL( item->m_End.x, end.x );
64 BOOST_CHECK_EQUAL( item->m_End.y, end.y );
65 }
66 }
67 }
68
69 // Both centers are offset (1, 1) mm from the Gerber start point. The second
70 // arc uses decimal I with fixed-format J, which must still mean 1 mm.
71 for( int arc = 0; arc < 2; ++arc )
72 {
73 BOOST_TEST_CONTEXT( "arc " << arc )
74 {
75 const GERBER_DRAW_ITEM* item = items[8 + arc];
76 const int offsetX = arc * 4 * unit;
77
79 BOOST_CHECK_EQUAL( item->m_ArcCentre.x, offsetX + unit );
80 BOOST_CHECK_EQUAL( item->m_ArcCentre.y, 4 * unit );
81 BOOST_CHECK_EQUAL( std::min( item->m_Start.x, item->m_End.x ), offsetX );
82 BOOST_CHECK_EQUAL( std::max( item->m_Start.x, item->m_End.x ), offsetX + 2 * unit );
83 BOOST_CHECK_EQUAL( item->m_Start.y, 3 * unit );
84 BOOST_CHECK_EQUAL( item->m_End.y, 3 * unit );
85 BOOST_CHECK_EQUAL( item->m_Start.x - offsetX, items[8]->m_Start.x );
86 BOOST_CHECK_EQUAL( item->m_End.x - offsetX, items[8]->m_End.x );
87 }
88 }
89}
90
91
92BOOST_AUTO_TEST_CASE( FractionalScaleFactorsRoundTrip )
93{
94 wxString path = KI_TEST::GetTestDataRootDir() + "gerbview/fractional_scale.gbr";
96
97 BOOST_REQUIRE( image.LoadGerberFile( path ) );
98 BOOST_CHECK_EQUAL( image.GetMessages().GetCount(), 0u );
99
100 const GERBER_DRAW_ITEMS& items = image.GetItems();
101 BOOST_REQUIRE_EQUAL( items.size(), 2u );
102
103 const int unit = gerbIUScale.mmToIU( 1.0 );
104 const VECTOR2I expected[] = { { unit, -3 * unit }, { 3 * unit, -unit } };
105
106 // Swap the fractional scales between flashes to exercise both axes and ensure
107 // each item keeps its own scale. Display coordinates invert the Gerber Y axis.
108 for( size_t i = 0; i < items.size(); ++i )
109 {
110 BOOST_TEST_CONTEXT( "flash " << i )
111 {
112 const GERBER_DRAW_ITEM* item = items[i];
113 VECTOR2I position = item->GetABPosition( item->m_Start );
114
115 // Require correct forward scaling before trying the inverse: truncating
116 // 0.5 to zero used to cause integer division by zero in GetXYPosition().
117 BOOST_REQUIRE_EQUAL( position.x, expected[i].x );
118 BOOST_REQUIRE_EQUAL( position.y, expected[i].y );
119
120 VECTOR2I original = item->GetXYPosition( position );
121
122 BOOST_CHECK_EQUAL( original.x, 2 * unit );
123 BOOST_CHECK_EQUAL( original.y, 2 * unit );
124 }
125 }
126}
127
128
constexpr EDA_IU_SCALE gerbIUScale
Definition base_units.h:127
double square(double x)
VECTOR2I GetABPosition(const VECTOR2I &aXYPosition) const
Return the image position of aPosition for this object.
VECTOR2I GetXYPosition(const VECTOR2I &aABPosition) const
Return the image position of aPosition for this object.
GBR_BASIC_SHAPE_TYPE m_ShapeType
Hold the image data and parameters for one gerber file and layer parameters.
@ GBR_ARC
std::vector< GERBER_DRAW_ITEM * > GERBER_DRAW_ITEMS
std::string GetTestDataRootDir()
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_AUTO_TEST_CASE(DecimalModeDoesNotLeakBetweenAxes)
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_AUTO_TEST_SUITE_END()
std::string path
VECTOR3I expected(15, 30, 45)
VECTOR2I end
BOOST_TEST_CONTEXT("Test Clearance")
BOOST_CHECK_EQUAL(result, "25.4")
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:708