KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_plot_footprint_scaled_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 The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
21
22#include <board.h>
24#include <footprint.h>
25#include <pcb_field.h>
26#include <pcb_text.h>
27#include <pcbplot.h>
29#include <pcb_plot_params.h>
31
32#include <wx/filename.h>
33#include <wx/ffile.h>
34
35#include <limits>
36#include <regex>
37#include <string>
38
39
40// Plot F.SilkS to Gerber and return the bbox of all plotted coords. The box
41// scales with the drawn text size.
42static BOX2I plotSilkBBox( BOARD& aBoard )
43{
44 GERBER_PLOTTER plotter;
45 SIMPLE_RENDER_SETTINGS renderSettings;
46 plotter.SetRenderSettings( &renderSettings );
47
48 wxString gbrPath = wxFileName::CreateTempFileName( wxT( "kicad_gbr_scaletext" ) );
49 BOOST_REQUIRE( !gbrPath.IsEmpty() );
50 BOOST_REQUIRE( plotter.OpenFile( gbrPath ) );
51
52 plotter.SetViewport( VECTOR2I( 0, 0 ), pcbIUScale.IU_PER_MILS / 10, 1.0, false );
53 BOOST_REQUIRE( plotter.StartPlot( wxT( "1" ) ) );
54
55 PCB_PLOT_PARAMS plotOpts;
57
58 PlotStandardLayer( &aBoard, &plotter, LSET( { F_SilkS } ), plotOpts );
59
60 BOOST_REQUIRE( plotter.EndPlot() );
61
62 wxFFile file( gbrPath, wxT( "rb" ) );
63 BOOST_REQUIRE( file.IsOpened() );
64 wxFileOffset len = file.Length();
65
66 std::string buffer;
67 buffer.resize( static_cast<size_t>( len ) );
68 BOOST_REQUIRE_EQUAL( file.Read( buffer.data(), len ), static_cast<size_t>( len ) );
69 file.Close();
70 wxRemoveFile( gbrPath );
71
72 std::regex coordRe( R"(X(-?\d+)Y(-?\d+)D0[12]\*)" );
73 auto it = std::sregex_iterator( buffer.begin(), buffer.end(), coordRe );
74 auto end = std::sregex_iterator();
75
76 long long minX = std::numeric_limits<long long>::max();
77 long long maxX = std::numeric_limits<long long>::min();
78 long long minY = std::numeric_limits<long long>::max();
79 long long maxY = std::numeric_limits<long long>::min();
80
81 for( ; it != end; ++it )
82 {
83 long long x = std::stoll( ( *it )[1] );
84 long long y = std::stoll( ( *it )[2] );
85 minX = std::min( minX, x );
86 maxX = std::max( maxX, x );
87 minY = std::min( minY, y );
88 maxY = std::max( maxY, y );
89 }
90
91 if( minX > maxX )
92 return BOX2I();
93
94 return BOX2I( VECTOR2I( (int) minX, (int) minY ), VECTOR2I( (int) ( maxX - minX ), (int) ( maxY - minY ) ) );
95}
96
97
98BOOST_AUTO_TEST_SUITE( PlotFootprintScaledText )
99
100
101// A scaled footprint's reference (REF**) must plot at the scaled size, not lib size.
102BOOST_AUTO_TEST_CASE( ScaledFootprintReferencePlotsScaled )
103{
104 BOARD board;
105 auto footprint = std::make_unique<FOOTPRINT>( &board );
106 footprint->SetPosition( VECTOR2I( pcbIUScale.mmToIU( 50.0 ), pcbIUScale.mmToIU( 50.0 ) ) );
107
108 PCB_FIELD& ref = footprint->Reference();
109 ref.SetText( wxT( "U1" ) );
110 ref.SetLayer( F_SilkS );
111 ref.SetVisible( true );
112 ref.SetTextSize( VECTOR2I( pcbIUScale.mmToIU( 1.0 ), pcbIUScale.mmToIU( 1.0 ) ) );
113 ref.SetTextThickness( pcbIUScale.mmToIU( 0.15 ) );
114
115 footprint->Value().SetVisible( false );
116
117 FOOTPRINT* fp = footprint.get();
118 board.Add( footprint.release() );
119
120 const BOX2I bbox1 = plotSilkBBox( board );
121 BOOST_REQUIRE( bbox1.GetWidth() > 0 && bbox1.GetHeight() > 0 );
122
123 fp->SetTransformScale( 2.0, 2.0 );
124
125 const BOX2I bbox2 = plotSilkBBox( board );
126
127 // Plotted text doubles. Slack covers stroke width and glyph metric rounding.
128 BOOST_CHECK_CLOSE( (double) bbox2.GetWidth(), 2.0 * bbox1.GetWidth(), 12.0 );
129 BOOST_CHECK_CLOSE( (double) bbox2.GetHeight(), 2.0 * bbox1.GetHeight(), 12.0 );
130}
131
132
133// Same guarantee for a plain graphic text item on silk.
134BOOST_AUTO_TEST_CASE( ScaledFootprintGraphicTextPlotsScaled )
135{
136 BOARD board;
137 auto footprint = std::make_unique<FOOTPRINT>( &board );
138 footprint->SetPosition( VECTOR2I( pcbIUScale.mmToIU( 50.0 ), pcbIUScale.mmToIU( 50.0 ) ) );
139
140 footprint->Reference().SetVisible( false );
141 footprint->Value().SetVisible( false );
142
143 PCB_TEXT* text = new PCB_TEXT( footprint.get() );
144 text->SetText( wxT( "TEXT" ) );
145 text->SetLayer( F_SilkS );
146 text->SetTextSize( VECTOR2I( pcbIUScale.mmToIU( 1.0 ), pcbIUScale.mmToIU( 1.0 ) ) );
147 text->SetTextThickness( pcbIUScale.mmToIU( 0.15 ) );
148 footprint->Add( text );
149
150 FOOTPRINT* fp = footprint.get();
151 board.Add( footprint.release() );
152
153 const BOX2I bbox1 = plotSilkBBox( board );
154 BOOST_REQUIRE( bbox1.GetWidth() > 0 && bbox1.GetHeight() > 0 );
155
156 fp->SetTransformScale( 2.0, 2.0 );
157
158 const BOX2I bbox2 = plotSilkBBox( board );
159
160 BOOST_CHECK_CLOSE( (double) bbox2.GetWidth(), 2.0 * bbox1.GetWidth(), 12.0 );
161 BOOST_CHECK_CLOSE( (double) bbox2.GetHeight(), 2.0 * bbox1.GetHeight(), 12.0 );
162}
163
164
constexpr EDA_IU_SCALE pcbIUScale
Definition base_units.h:121
BOX2< VECTOR2I > BOX2I
Definition box2.h:918
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition board_item.h:313
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:372
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
Definition board.cpp:1295
constexpr size_type GetWidth() const
Definition box2.h:210
constexpr size_type GetHeight() const
Definition box2.h:211
virtual void SetVisible(bool aVisible)
Definition eda_text.cpp:381
virtual void SetText(const wxString &aText)
Definition eda_text.cpp:265
void SetTransformScale(double aScaleX, double aScaleY)
virtual void SetViewport(const VECTOR2I &aOffset, double aIusPerDecimil, double aScale, bool aMirror) override
Set the plot offset and scaling for the current plot.
virtual bool EndPlot() override
virtual bool StartPlot(const wxString &pageNumber) override
Write GERBER header to file initialize global variable g_Plot_PlotOutputFile.
LSET is a set of PCB_LAYER_IDs.
Definition lset.h:37
Parameters and options when plotting/printing a board.
void SetFormat(PLOT_FORMAT aFormat)
void SetTextThickness(int aWidth) override
The TextThickness is that set by the user.
Definition pcb_text.cpp:495
void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true) override
Definition pcb_text.cpp:467
virtual bool OpenFile(const wxString &aFullFilename)
Open or create the plot file aFullFilename.
Definition plotter.cpp:73
void SetRenderSettings(RENDER_SETTINGS *aSettings)
Definition plotter.h:163
Minimal concrete render settings suitable for plotters in tests.
@ F_SilkS
Definition layer_ids.h:96
void PlotStandardLayer(BOARD *aBoard, PLOTTER *aPlotter, const LSET &aLayerMask, const PCB_PLOT_PARAMS &aPlotOpt)
Plot copper or technical layers.
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_CASE(ScaledFootprintReferencePlotsScaled)
static BOX2I plotSilkBBox(BOARD &aBoard)
VECTOR2I end
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683