KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_issue25074_odb_knockout_textbox.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 <filesystem>
21#include <fstream>
22#include <memory>
23
25#include <boost/test/unit_test.hpp>
26
27#include <base_units.h>
28#include <board.h>
29#include <kiid.h>
30#include <pcb_shape.h>
31#include <pcb_textbox.h>
34#include <core/utf8.h>
35
36namespace fs = std::filesystem;
37
38
39// A knockout reaches the feature file as filled polygons, so surface records prove it was emitted.
40static int countSurfaceRecords( const fs::path& aFeaturesFile )
41{
42 int count = 0;
43 std::ifstream stream( aFeaturesFile );
44 std::string line;
45
46 while( std::getline( stream, line ) )
47 {
48 if( line.rfind( "S ", 0 ) == 0 )
49 count++;
50 }
51
52 return count;
53}
54
55
56// A knockout text box was cast to PCB_TEXT before being turned into polygons. The two share no
57// base below EDA_TEXT, so the export read the wrong subobject and died.
58BOOST_AUTO_TEST_CASE( OdbKnockoutTextboxExport )
59{
60 SETTINGS_MANAGER settingsManager;
61 std::unique_ptr<BOARD> board = std::make_unique<BOARD>();
62
63 const int side = pcbIUScale.mmToIU( 20 );
64
65 auto addEdge = [&]( const VECTOR2I& aStart, const VECTOR2I& aEnd )
66 {
67 PCB_SHAPE* edge = new PCB_SHAPE( board.get(), SHAPE_T::SEGMENT );
68 edge->SetLayer( Edge_Cuts );
69 edge->SetStart( aStart );
70 edge->SetEnd( aEnd );
71 edge->SetWidth( pcbIUScale.mmToIU( 0.1 ) );
72 board->Add( edge );
73 };
74
75 addEdge( { 0, 0 }, { side, 0 } );
76 addEdge( { side, 0 }, { side, side } );
77 addEdge( { side, side }, { 0, side } );
78 addEdge( { 0, side }, { 0, 0 } );
79
80 PCB_TEXTBOX* textbox = new PCB_TEXTBOX( board.get() );
81 textbox->SetLayer( B_SilkS );
82 textbox->SetStart( { pcbIUScale.mmToIU( 5 ), pcbIUScale.mmToIU( 8 ) } );
83 textbox->SetEnd( { pcbIUScale.mmToIU( 15 ), pcbIUScale.mmToIU( 12 ) } );
84 textbox->SetText( wxT( "MCU" ) );
85 textbox->SetTextSize( { pcbIUScale.mmToIU( 1.26 ), pcbIUScale.mmToIU( 1.26 ) } );
86 textbox->SetTextThickness( pcbIUScale.mmToIU( 0.254 ) );
87 textbox->SetBold( true );
88 textbox->SetMirrored( true );
89 textbox->SetBorderEnabled( false );
90 textbox->SetIsKnockout( true );
91 board->Add( textbox );
92
93 const fs::path outDir =
94 fs::temp_directory_path() / ( "kicad_qa_odb_knockout_25074_" + KIID().AsString().ToStdString() );
95
96 BOOST_REQUIRE( fs::create_directory( outDir ) );
97
98 PCB_IO_ODBPP odbExporter;
99 std::map<std::string, UTF8> props;
100 props["units"] = "mm";
101 props["sigfig"] = "6";
102
103 BOOST_REQUIRE_NO_THROW( odbExporter.SaveBoard( outDir.string(), board.get(), &props ) );
104
105 const fs::path features = outDir / "steps" / "pcb" / "layers" / "b.silkscreen" / "features";
106
107 BOOST_REQUIRE_MESSAGE( fs::exists( features ), "ODB++ export produced no back silkscreen features file" );
108
109 BOOST_CHECK_MESSAGE( countSurfaceRecords( features ) > 0,
110 "Knockout text box produced no surface features on the back silkscreen" );
111
112 fs::remove_all( outDir );
113}
constexpr EDA_IU_SCALE pcbIUScale
Definition base_units.h:121
Definition kiid.h:46
wxString AsString() const
Definition kiid.cpp:264
void SaveBoard(const wxString &aFileName, BOARD *aBoard, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Write aBoard to a storage file in a format that this PCB_IO implementation knows about or it can be u...
void SetWidth(int aWidth) override
void SetEnd(const VECTOR2I &aEnd) override
void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
void SetStart(const VECTOR2I &aStart) override
@ SEGMENT
Definition eda_shape.h:46
@ Edge_Cuts
Definition layer_ids.h:108
@ B_SilkS
Definition layer_ids.h:97
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_AUTO_TEST_CASE(OdbKnockoutTextboxExport)
static int countSurfaceRecords(const fs::path &aFeaturesFile)
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683