23#include <boost/test/unit_test.hpp>
83 const std::string dest = ( tmp.
GetPath() /
"out.kicad_pcb" ).string();
88 std::ifstream file( dest );
89 std::string content( ( std::istreambuf_iterator<char>( file ) ), std::istreambuf_iterator<char>() );
91 const std::set<std::string> known =
97 if( !unsupported.empty() )
99 std::string msg =
"Downgraded board uses tokens " + aTarget.m_name.ToStdString() +
" cannot parse:";
101 for(
const std::string& token : unsupported )
129 fp->
SetUnitInfo( { { wxT(
"A" ), { wxT(
"1" ) } }, { wxT(
"B" ), { wxT(
"2" ) } } } );
138 pad->SetNumber( wxT(
"1" ) );
142 pad->SetPadToDieDelay( 1000 );
144 pad->Padstack().FrontPostMachining().size =
pcbIUScale.mmToIU( 1.2 );
145 pad->Padstack().FrontPostMachining().depth =
pcbIUScale.mmToIU( 0.2 );
148 PAD* customPad =
new PAD( fp );
157 fp->
Add( customPad );
171 aBoard.
Add( generator );
176 generator->AddItem(
via );
188 parent->Add( ended );
191 parent->Add( constraint );
203 parent->Add( ellipse );
211 parent->Add( rounded );
218 parent->Add( hatch );
225 parent->Add( copperHatch );
228 barcode->
SetText( wxT(
"TEST123" ) );
232 parent->Add( barcode );
235 textbox->
SetText( wxT(
"Knockout" ) );
240 parent->Add( textbox );
243 table->SetColCount( 1 );
248 cell->
SetText( wxT(
"Knockout cell" ) );
252 table->AddCell( cell );
253 parent->Add(
table );
265 group->SetName( wxT(
"transform group" ) );
266 group->SetDesignBlockLibId(
LIB_ID( wxT(
"Lib" ), wxT(
"Block" ) ) );
267 group->AddItem( hatch );
268 group->AddItem( barcode );
269 parent->Add(
group );
277 aBoard.
Add( skipVia );
284 aBoard.
Add( buriedVia );
297 image->GetReferenceImage().SetImageScale( 2.0 );
311 bool aDropInsteadOfApproximate )
317 { wxT(
"Geometric constraints" ), 20260624, DOWNGRADE_BUCKET::DROP },
318 { wxT(
"Local grids" ), 20260728, DOWNGRADE_BUCKET::DROP },
319 { wxT(
"Via stitching and guarding" ), 20260816, DOWNGRADE_BUCKET::DROP },
320 { wxT(
"Microvia stack generators" ), 20260830, DOWNGRADE_BUCKET::DROP },
321 { wxT(
"Graphic line endings" ), 20260818, DOWNGRADE_BUCKET::LOWER },
322 { wxT(
"Footprint simulation exclusions" ), 20260828, DOWNGRADE_BUCKET::DROP },
323 { wxT(
"Custom properties" ), 20260831, DOWNGRADE_BUCKET::DROP },
324 { wxT(
"Drill charts and maps" ), 20260901, DOWNGRADE_BUCKET::DROP },
325 { wxT(
"Drill symbol configuration" ), 20260901, DOWNGRADE_BUCKET::DROP },
326 { wxT(
"Net chains" ), 20260512, DOWNGRADE_BUCKET::DROP },
327 { wxT(
"Ellipse graphics" ), 20260508, DOWNGRADE_BUCKET::LOWER },
328 { wxT(
"Extruded 3D bodies" ), 20260410, DOWNGRADE_BUCKET::DROP },
329 { wxT(
"Pad simulation types" ), 20260521, DOWNGRADE_BUCKET::DROP },
330 { wxT(
"Footprint unit metadata" ), 20250909, DOWNGRADE_BUCKET::DROP },
331 { wxT(
"Barcodes" ), 20250914, DOWNGRADE_BUCKET::LOWER },
332 { wxT(
"PCB variants" ), 20260101, DOWNGRADE_BUCKET::DROP },
333 { wxT(
"Jumper pad groups" ), 20250324, DOWNGRADE_BUCKET::DROP },
334 { wxT(
"Counterbore / countersink" ), 20251101, DOWNGRADE_BUCKET::DROP },
335 { wxT(
"Press-fit pads" ), 20250811, DOWNGRADE_BUCKET::DROP },
336 { wxT(
"Skip vias" ), 20250801, DOWNGRADE_BUCKET::LOWER, true },
337 { wxT(
"Buried vias" ), 20250926, DOWNGRADE_BUCKET::LOWER, true },
338 { wxT(
"Zone layer defaults" ), 20250302, DOWNGRADE_BUCKET::DROP },
339 { wxT(
"Pad-to-die delays" ), 20250401, DOWNGRADE_BUCKET::DROP },
340 { wxT(
"Hatched shape fills" ), 20250222, DOWNGRADE_BUCKET::LOWER },
341 { wxT(
"Hatched copper fills" ), 20250222, DOWNGRADE_BUCKET::LOWER, true },
342 { wxT(
"PCB points" ), 20250901, DOWNGRADE_BUCKET::DROP },
343 { wxT(
"Via protection" ), 20250228, DOWNGRADE_BUCKET::DROP },
344 { wxT(
"Dielectric frequency models" ), 20260511, DOWNGRADE_BUCKET::DROP },
345 { wxT(
"Group design block links" ), 20250513, DOWNGRADE_BUCKET::DROP },
346 { wxT(
"Knockout text boxes" ), 20250210, DOWNGRADE_BUCKET::LOWER },
347 { wxT(
"Rounded rectangles" ), 20250829, DOWNGRADE_BUCKET::LOWER },
348 { wxT(
"Knockout table cells" ), 20260603, DOWNGRADE_BUCKET::LOWER },
349 { wxT(
"Per-zone layer properties" ), 20250302, DOWNGRADE_BUCKET::DROP },
351 aDropInsteadOfApproximate );
356 const std::string& aTokenFileName )
359 const std::set<std::string> known =
363 for(
bool drop : {
false,
true } )
368 const std::string src = ( tmp.
GetPath() /
"source.kicad_pcb" ).string();
369 const std::string dest = ( tmp.
GetPath() /
"out.kicad_pcb" ).string();
371 std::unique_ptr<BOARD> board(
389 for(
const std::string& token : unsupported )
390 BOOST_ERROR(
"Transformed board uses unknown token: " + token );
392 BOOST_CHECK( content.find(
"(version " + std::to_string( aTarget.
m_boardVersion ) +
")" )
393 != std::string::npos );
396 std::unique_ptr<BOARD> reloaded( io.
LoadBoard( dest,
nullptr ) );
399 BOOST_CHECK( !reloadReport.IsBlocked() );
403 if( aTarget.
m_id == wxT(
"9.0" ) )
406 size_t buriedCount = 0;
408 for(
PCB_TRACK* track : reloaded->Tracks() )
423 if(
via->IsBuriedVia() )
427 BOOST_CHECK(
via->TopLayer() ==
In1_Cu );
428 BOOST_CHECK(
via->BottomLayer() ==
In2_Cu );
434 for(
const COMPAT_ENTRY& entry : reloadReport.Entries() )
436 if( entry.m_feature == wxT(
"Via protection" ) )
439 BOOST_ERROR(
"Unexpected feature after reload: " + entry.m_feature.ToStdString() );
444 BOOST_CHECK( !reloadReport.IsLossy() );
466 const std::string& aBoard,
const std::string& aReference,
size_t aExpectedDrops,
467 size_t aExpectedLowerings,
bool aDropInsteadOfApproximate =
false )
472 const std::string dest = ( tmp.
GetPath() / ( aBoard +
".kicad_pcb" ) ).string();
477 nullptr, wxEmptyString, aDropInsteadOfApproximate ) );
481 const std::string difference =
483 BOOST_CHECK_MESSAGE( difference.empty(), difference );
527 const std::string& aReference,
bool aDropInsteadOfApproximate =
false )
531 const wxString dest = ( tmp.
GetPath() /
"metadata.kicad_mod" ).wstring();
532 const wxString src = wxString::FromUTF8( fixture +
"current/metadata.pretty/metadata.kicad_mod" );
538 fixture + aRelease +
"/" + aReference +
".pretty/metadata.kicad_mod", dest.ToStdString() );
539 BOOST_CHECK_MESSAGE( difference.empty(), difference );
550 const std::string dest = ( tmp.
GetPath() /
"out.kicad_pcb" ).string();
560 BOOST_CHECK_MESSAGE( out.find(
"gr_poly" ) != std::string::npos,
561 "the custom pad's primitive was dropped instead of approximated" );
564 bool inString =
false;
566 for(
size_t ii = 0; ii < out.size(); ++ii )
568 if( out[ii] ==
'"' && ( ii == 0 || out[ii - 1] !=
'\\' ) )
569 inString = !inString;
570 else if( !inString && out[ii] ==
'(' )
572 else if( !inString && out[ii] ==
')' )
576 BOOST_CHECK_MESSAGE( depth == 0,
"exported board is unbalanced by " + std::to_string( depth ) );
579 std::unique_ptr<BOARD> reloaded( io.
LoadBoard( dest,
nullptr ) );
581 BOOST_REQUIRE_EQUAL( reloaded->Footprints().size(), 1 );
582 BOOST_REQUIRE_EQUAL( reloaded->Footprints().front()->Pads().size(), 1 );
583 BOOST_CHECK_EQUAL( reloaded->Footprints().front()->Pads().front()->GetPrimitives(
F_Cu ).size(), 1 );
647 const std::string golden =
"(kicad_pcb (version 20241229) (generator_version \"9.0\") "
648 "(setup (pad_to_mask_clearance 0.05)) "
649 "(pad \"1\" (at 100 100 30) (size 2 1) (net 1 \"SIGNAL\")))";
652 for(
const auto& [from, to] : std::vector<std::pair<std::string, std::string>>{ {
"100 100",
"0 0" },
653 {
"(size 2 1)",
"(size 1 2)" },
656 {
"100 100 30",
"100 100 31" },
657 {
"20241229",
"20260206" } } )
659 std::string changed = golden;
660 changed.replace( changed.find( from ), from.size(), to );
665 auto metadataOnly = parser.
Parse(
"(kicad_pcb (version 20241229) (generator_version \"10.99\") "
666 "(setup (pad_to_mask_clearance 0.05)) "
667 "(pad \"1\" (at 100.000001 99.999999 30) (size 2 1) (net 1 \"SIGNAL\")))" );
670 const std::string plotGolden =
"(kicad_pcb (setup (pcbplotparams (hpglpennumber 1) (hpglpenspeed 20) "
671 "(hpglpendiameter 15) (plotinvisibletext no))))";
672 auto plotExpected = parser.
Parse( plotGolden );
673 auto modernPlot = parser.
Parse(
"(kicad_pcb (setup (pcbplotparams (pngdpi 300) (pngantialias yes))))" );
676 for(
const auto& [from, to] :
677 std::vector<std::pair<std::string, std::string>>{ {
"hpglpennumber 1",
"hpglpennumber 2" },
678 {
"hpglpenspeed 20",
"hpglpenspeed 30" },
679 {
"hpglpendiameter 15",
"hpglpendiameter 16" },
680 {
"plotinvisibletext no",
"plotinvisibletext yes" } } )
682 std::string changed = plotGolden;
683 changed.replace( changed.find( from ), from.size(), to );
684 auto nonDefault = parser.
Parse( changed );
697 const wxString
path = ( tmp.
GetPath() / ( target.m_id.ToStdString() +
".kicad_pcb" ) ).string();
699 std::ifstream file(
path.ToStdString() );
700 std::string
text( ( std::istreambuf_iterator<char>( file ) ), std::istreambuf_iterator<char>() );
701 BOOST_CHECK(
text.find(
"(pngdpi " ) == std::string::npos );
702 BOOST_CHECK(
text.find(
"(pngantialias " ) == std::string::npos );
704 if( target.m_id == wxT(
"9.0" ) )
706 BOOST_CHECK(
text.find(
"(hpglpennumber 1)" ) != std::string::npos );
707 BOOST_CHECK(
text.find(
"(hpglpenspeed 20)" ) != std::string::npos );
708 BOOST_CHECK(
text.find(
"(hpglpendiameter 15.000000)" ) != std::string::npos );
709 BOOST_CHECK(
text.find(
"(plotinvisibletext no)" ) != std::string::npos );
726 const wxString
path = ( tmp.
GetPath() / ( target.m_id.ToStdString() +
".kicad_pcb" ) ).string();
728 std::ifstream file(
path.ToStdString() );
729 std::string
text( ( std::istreambuf_iterator<char>( file ) ), std::istreambuf_iterator<char>() );
730 const std::string
expected = target.m_id == wxT(
"9.0" ) ?
"(paper \"User\" 123.457 100.123)"
731 :
"(paper \"User\" 123.456789 100.123456)";
732 BOOST_CHECK(
text.find(
expected ) != std::string::npos );
741 for(
bool drop : {
false,
true } )
775 text.SetFont(
nullptr );
777 text.SetTextThickness( 100000 );
778 text.SetLineSpacing( 1.25 );
779 text.SetItalic(
true );
783 text.SetMirrored(
true );
784 text.SetVisible(
false );
785 text.SetHyperlink( wxT(
"https://example.com/datasheet" ) );
787 const std::string prefix =
"(effects(font(size 2 1)(line_spacing 1.25)(thickness 0.1)"
788 "(italic yes)(color 51 102 153 0.75))(justify left bottom mirror)";
789 const std::string href =
"(href \"https://example.com/datasheet\"))";
794 for(
bool v9 : {
false,
true } )
797 BOOST_CHECK( omitted.find(
"(color " ) == std::string::npos );
798 BOOST_CHECK( omitted.find(
"(href " ) == std::string::npos );
799 BOOST_CHECK( omitted.find(
"(justify left bottom mirror)" ) != std::string::npos );
804 BOOST_CHECK( !
text.IsVisible() );
811 text.SetFont(
nullptr );
814 for(
bool v9 : {
false,
true } )
816 text.SetBold(
false );
817 text.SetTextThickness( 0 );
818 BOOST_CHECK(
text.GetAutoThickness() );
821 text.SetTextThickness( 1 );
822 BOOST_CHECK( !
text.GetAutoThickness() );
826 text.SetTextThickness( 100000 );
829 text.SetBold(
true );
833 text.SetTextThickness( 0 );
843 text.SetFont(
nullptr );
844 text.SetMultilineAllowed(
false );
846 text.SetAutoThickness(
true );
847 text.SetVisible(
false );
848 BOOST_CHECK(
text.GetAutoThickness() );
851 text.SetTextThickness( 1 );
852 BOOST_CHECK( !
text.GetAutoThickness() );
855 text.SetTextThickness( 0 );
856 BOOST_CHECK(
text.GetAutoThickness() );
859 text.SetBold(
true );
861 text.SetBold(
false );
862 text.SetMirrored(
true );
872 BOOST_CHECK(
empty.GetString().empty() );
874 title.
SetTitle( wxT(
"Production" ) );
875 title.
SetDate( wxT(
"2026-10-08" ) );
883 "(company \"KiCad\")(comment 1 \"First\")(comment 9 \"Last\"))" );
884 BOOST_CHECK( title.
GetComment( 8 ) == wxT(
"Last" ) );
886 for(
const auto& [style, token] :
909 auto file = std::make_shared<EMBEDDED_FILES::EMBEDDED_FILE>();
910 file->name = wxT(
"metadata.bin" );
912 file->data_hash =
"metadata-only";
921 "(embedded_files (file (name \"metadata.bin\")(type other)(checksum \"metadata-only\")))" );
923 for(
bool writeData : {
false,
true } )
931 BOOST_CHECK( file->compressedEncodedData.empty() );
939 auto file = std::make_shared<EMBEDDED_FILES::EMBEDDED_FILE>();
940 file->name = wxT(
"payload.bin" );
943 for(
int ii = 0; ii < 4096; ++ii )
944 file->decompressedData.push_back(
static_cast<char>( ( ii * 131 + ii / 251 ) % 256 ) );
947 BOOST_REQUIRE_GT( file->compressedEncodedData.size(), 76 );
950 const std::string hash = file->data_hash;
952 std::string
expected =
"(embedded_files (file (name \"payload.bin\")(type other)(data";
954 for(
size_t first = 0; first < encoded.size(); first += 76 )
956 const std::string chunk = encoded.substr( first, 76 );
961 if( first + chunk.size() == encoded.size() )
967 expected +=
")(checksum \"" + hash +
"\")))";
969 for(
bool v9 : {
false,
true } )
987 "(embedded_files (file (name \"payload.bin\")(type other)(checksum \"" + hash +
"\")))" );
1011 hash.
addDataV1(
reinterpret_cast<const uint8_t*
>( aPayload.data() ), aPayload.size() );
1018 std::vector<size_t> sizes = { 4095, 4096, 4097 };
1020 for(
size_t size = 0; size <= 32; ++size )
1021 sizes.push_back( size );
1023 for(
size_t size : sizes )
1026 auto file = std::make_shared<EMBEDDED_FILES::EMBEDDED_FILE>();
1027 file->name = wxT(
"payload.bin" );
1029 for(
size_t ii = 0; ii < size; ++ii )
1030 file->decompressedData.push_back(
static_cast<char>( ( ii * 131 + ii / 251 ) % 256 ) );
1034 const auto original = *file;
1037 if( size % 16 != 0 )
1038 BOOST_CHECK_NE( checksum, original.data_hash );
1040 for(
bool v9 : {
false,
true } )
1042 for(
bool writeData : {
false,
true } )
1047 BOOST_CHECK( output.find(
"(checksum \"" + checksum +
"\")" ) != std::string::npos );
1052 BOOST_CHECK_EQUAL( output,
"(embedded_files (file (name \"payload.bin\")(type other)"
1054 + checksum +
"\")))" );
1057 BOOST_CHECK( file->decompressedData == original.decompressedData );
1058 BOOST_CHECK_EQUAL( file->compressedEncodedData, original.compressedEncodedData );
1070 for(
size_t size : { 0u, 1u, 13u, 17u, 31u, 4097u } )
1073 auto file = std::make_shared<EMBEDDED_FILES::EMBEDDED_FILE>();
1074 file->name = wxT(
"encoded.bin" );
1075 file->decompressedData.assign( size,
'x' );
1078 file->decompressedData.clear();
1080 const auto original = *file;
1082 for(
bool v9 : {
false,
true } )
1084 for(
bool writeData : {
false,
true } )
1089 BOOST_CHECK( output.find(
"(checksum \"" + checksum +
"\")" ) != std::string::npos );
1091 BOOST_CHECK( file->decompressedData.empty() );
1092 BOOST_CHECK_EQUAL( file->compressedEncodedData, original.compressedEncodedData );
1104 for(
bool badChecksum : {
false,
true } )
1107 auto file = std::make_shared<EMBEDDED_FILES::EMBEDDED_FILE>();
1108 file->name = wxT(
"invalid.bin" );
1109 file->decompressedData.assign( 13,
'x' );
1111 file->decompressedData.clear();
1114 file->data_hash =
"invalid-checksum";
1116 file->compressedEncodedData =
"invalid-base64";
1119 const auto original = *file;
1121 for(
bool v9 : {
false,
true } )
1123 for(
bool writeData : {
false,
true } )
1126 BOOST_CHECK( file->decompressedData.empty() );
1127 BOOST_CHECK_EQUAL( file->compressedEncodedData, original.compressedEncodedData );
1146 const std::vector<std::pair<wxString, std::string>> checksums = {
1147 { wxT(
"SchematicTemplate.kicad_wks" ),
"6003EC72C5978E83C182073E67278FCF" },
1148 { wxT(
"SchematicTemplateEmpty.kicad_wks" ),
"0D054F65E3E0563620A9E16BBBB777DD" }
1151 for(
const auto& [
name, checksum] : checksums )
1153 const auto* file = board->GetEmbeddedFile(
name );
1156 BOOST_CHECK_NE( file->data_hash, checksum );
1158 const auto original = *file;
1160 for(
bool v9 : {
false,
true } )
1162 for(
bool writeData : {
false,
true } )
1165 BOOST_CHECK( output.find(
"(name \"" +
name.ToStdString() +
"\")" ) != std::string::npos );
1166 BOOST_CHECK( output.find(
"(checksum \"" + checksum +
"\")" ) != std::string::npos );
1167 BOOST_CHECK( output.find(
"(checksum \"" + original.data_hash +
"\")" ) == std::string::npos );
1169 BOOST_CHECK( file->decompressedData == original.decompressedData );
1170 BOOST_CHECK_EQUAL( file->compressedEncodedData, original.compressedEncodedData );
constexpr EDA_IU_SCALE pcbIUScale
COMPATIBILITY_REPORT ClassifyBoardForDowngrade(const BOARD *aBoard, const DOWNGRADE_TARGET &aTarget, bool aDropInsteadOfApproximate)
Report what a board would lose if exported to an older KiCad.
void SaveBoardForTarget(BOARD *aBoard, const wxString &aPath, const DOWNGRADE_TARGET &aTarget)
Save a board stamped for the target, using the writer for that version.
bool ExportBoardToOlderVersion(const wxString &aSrcFile, const wxString &aDestFile, const DOWNGRADE_TARGET &aTarget, COMPATIBILITY_REPORT &aReport, wxString *aUnsupportedToken, const wxString &aVariant, bool aDropInsteadOfApproximate)
Load a board, downgrade the copy, and write it stamped for the target.
DOWNGRADE_FILE_RESULT DowngradeFootprintFileToTemp(const wxString &aSrcFile, const wxString &aTmpFile, const DOWNGRADE_TARGET &aTarget, bool aDropInsteadOfApproximate)
Load one .kicad_mod, classify it against the rule table, and write the downgraded copy to aTmpFile.
void DowngradeBoardInPlace(BOARD *aBoard, const DOWNGRADE_TARGET &aTarget, bool aDropInsteadOfApproximate)
Approximate or remove, in place, what the target cannot represent.
General utilities for PCB file IO for QA programs.
@ BS_ITEM_TYPE_DIELECTRIC
int GetLegacyPPI() const
Recompute the PPI the way it was computed before the pixels/cm truncation fix.
std::map< PCB_LAYER_ID, ZONE_LAYER_PROPERTIES > m_ZoneLayerProperties
DRILL_SYMBOL_PROFILE & GetDrillSymbolProfile()
BOARD_STACKUP & GetStackupDescriptor()
Abstract interface for BOARD_ITEMs capable of storing other items inside.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
virtual void SetIsKnockout(bool aKnockout)
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Manage one layer needed to make a physical board.
const std::vector< BOARD_STACKUP_ITEM * > & GetList() const
Information pertinent to a Pcbnew printed circuit board.
void SetPlotOptions(const PCB_PLOT_PARAMS &aOptions)
void SetVariantNames(const std::vector< wxString > &aNames)
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
void SetPageSettings(const PAGE_INFO &aPageSettings)
const PCB_PLOT_PARAMS & GetPlotOptions() const
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
const DRAWINGS & Drawings() const
What an export to a given target will keep, approximate, drop, or block.
bool IsBlocked() const
True if some feature makes the target impossible. The user cannot export anyway.
int Count(DOWNGRADE_BUCKET aBucket) const
void SetName(const wxString &aName)
void SetCustomProperty(const wxString &aKey, const wxString &aValue)
void SetEndEndingStyle(LINE_ENDING_STYLE aStyle)
void SetFillMode(FILL_T aFill)
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
virtual void SetText(const wxString &aText)
EMBEDDED_FILE * GetEmbeddedFile(const wxString &aName) const
Returns the embedded file with the given name or nullptr if it does not exist.
EMBEDDED_FILE * AddFile(const wxFileName &aName, bool aOverwrite)
Load a file from disk and adds it to the collection.
static RETURN_CODE CompressAndEncode(EMBEDDED_FILE &aFile)
Take data from the decompressedData buffer and compresses it using ZSTD into the compressedEncodedDat...
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
A color representation with 4 components: red, green, blue, alpha.
A temporary directory deleted when it goes out of scope.
const std::filesystem::path & GetPath() const
A logical library item identifier and consists of various portions much like a URI.
A streaming C++ equivalent for MurmurHash3_x64_128.
FORCE_INLINE void addDataV1(const uint8_t *data, size_t length)
FORCE_INLINE HASH_128 digest()
Handle the data for a net.
void SetNetChain(const wxString &aNetChain)
A PADSTACK defines the characteristics of a single or multi-layer pad, in the IPC sense of the word.
MASK_LAYER_PROPS & FrontOuterLayers()
void SetUnconnectedLayerMode(UNCONNECTED_LAYER_MODE aMode)
MASK_LAYER_PROPS & BackOuterLayers()
static constexpr PCB_LAYER_ID ALL_LAYERS
! The layer identifier to use for the single defintion on normal padstacks
void SetShape(PCB_LAYER_ID aLayer, PAD_SHAPE aShape)
Set the new shape of this pad.
void SetNumber(const wxString &aNumber)
Set the pad number (note that it can be alphanumeric, such as the array reference "AA12").
void AddPrimitive(PCB_LAYER_ID aLayer, PCB_SHAPE *aPrimitive)
Add item to the custom shape primitives list.
Describe the page size and margins of a paper page on which to eventually print or plot.
void SetWidthMM(double aWidthInMM)
void SetHeightMM(double aHeightInMM)
void SetWidth(int aWidth)
void SetHeight(int aHeight)
void SetLayer(PCB_LAYER_ID aLayer) override
Set the drawing layer for the barcode and its text.
void SetText(const wxString &aText)
Set the barcode content text to encode.
A geometric constraint between board items (issue #2329).
void AddMember(const KIID &aItem, CONSTRAINT_ANCHOR aAnchor=CONSTRAINT_ANCHOR::WHOLE, int aIndex=-1)
A drill chart placed on the board, kept in step with the holes.
Turns on drill symbols at the holes, for one layer.
A set of BOARD_ITEMs (i.e., without duplicates).
A PCB_IO derivation for saving and loading Pcbnew s-expression formatted files.
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...
std::unique_ptr< BOARD > LoadBoard(const wxString &aFileName, const std::map< std::string, UTF8 > *aProperties=nullptr, PROJECT *aProject=nullptr)
Load information from some input file format that this PCB_IO implementation knows about into new BOA...
Parameters and options when plotting/printing a board.
PLOT_FORMAT GetFormat() const
void SetFormat(PLOT_FORMAT aFormat)
A PCB_POINT is a 0-dimensional point that is used to mark a position on a PCB, or more usually a foot...
Object to handle a bitmap image that can be inserted in a PCB.
void SetEllipseCenter(const VECTOR2I &aPt) override
void SetCornerRadius(int aCornerRadius) override
void SetWidth(int aWidth) override
void SetEllipseStartAngle(const EDA_ANGLE &aA) override
void SetEllipseEndAngle(const EDA_ANGLE &aA) override
void SetEnd(const VECTOR2I &aEnd) override
void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
void SetEllipseMinorRadius(int aR) override
void SetStart(const VECTOR2I &aStart) override
void SetEllipseMajorRadius(int aR) override
void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
A microvia stack: several single hop microvias, plus connecting traces for staggered stacks,...
const PADSTACK & Padstack() const
void SetDrill(int aDrill)
void SetLayerPair(PCB_LAYER_ID aTopLayer, PCB_LAYER_ID aBottomLayer)
For a via m_layer contains the top layer, the other layer is in m_bottomLayer/.
void SetViaType(VIATYPE aViaType)
void SetWidth(int aWidth) override
A REFERENCE_IMAGE is a wrapper around a BITMAP_IMAGE that is displayed in an editor as a reference fo...
const BITMAP_BASE & GetImage() const
Get the underlying image.
double GetImageScale() const
std::unique_ptr< SEXPR > Parse(const std::string &aString)
Simple container to manage line stroke parameters.
void SetColor(const KIGFX::COLOR4D &aColor)
Hold the information shown in the lower right corner of a plot, printout, or editing view.
void SetRevision(const wxString &aRevision)
void SetComment(int aIdx, const wxString &aComment)
void SetTitle(const wxString &aTitle)
const wxString & GetComment(int aIdx) const
void SetCompany(const wxString &aCompany)
void SetDate(const wxString &aDate)
Set the date field, and defaults to the current time and date.
Handle a list of polygons defining a copper zone.
bool AppendCorner(const VECTOR2I &aPosition, int aHoleIdx, bool aAllowDuplication=false)
Add a new corner to the zone outline (to the main outline or a hole)
ZONE_LAYER_PROPERTIES & LayerProperties(PCB_LAYER_ID aLayer)
virtual void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
@ LOWER
Approximated down to a simpler equivalent.
@ DROP
No equivalent, left out.
static bool empty(const wxTextEntryBase *aCtrl)
@ CONVERTED
The temp file holds the downgraded copy.
static constexpr EDA_ANGLE ANGLE_0
static constexpr EDA_ANGLE ANGLE_90
@ FILLED_SHAPE
Fill with object color.
@ RECTANGLE
Use RECTANGLE instead of RECT to avoid collision in a Windows header.
Test utilities for timestamps.
std::string GetPcbnewTestDataDir()
Utility which returns a path to the data directory where the test board files are stored.
std::set< std::string > LoadTokenSet(const std::string &aFileName)
Read a release keyword file from qa/data/downgrade, one token per line.
std::string GoldenFileDifference(const std::string &aExpected, const std::string &aActual)
std::string ReadGoldenText(const std::string &aPath)
void CheckTransformCoverage(const COMPATIBILITY_REPORT &aReport, int aTargetVersion, std::initializer_list< EXPECTED_DOWNGRADE_FEATURE > aFeatures, bool aDropInsteadOfApproximate)
const DOWNGRADE_TARGET & RequireDowngradeTarget(const wxString &aId)
std::string GoldenSexprDifference(const SEXPR::SEXPR &aExpected, const SEXPR::SEXPR &aActual, const std::string &aPath="", const std::string &aParent="", size_t aIndex=0)
wxMemoryBuffer MakePngWithFractionalPixelsPerCm()
A tiny PNG whose embedded resolution gives a fractional pixels/cm, so the legacy truncating PPI diffe...
double SerializedImageScale(const std::string &aContent, const std::string &aUuid)
std::vector< std::string > UnknownSexprHeads(const std::string &aContent, const std::set< std::string > &aKnown, const std::set< std::string > &aHarmless={})
Every node head in the serialized text that is not in the known or harmless sets.
@ PRESSFIT
a PTH with a hole diameter with tight tolerances for press fit pin
BARCODE class definition.
@ HORIZONTAL
A segment (or two points) is horizontal.
Class to handle a set of BOARD_ITEMs.
One line in the compatibility report.
An older KiCad release we can export a project back to.
int m_boardVersion
SEXPR_BOARD_FILE_VERSION for the target.
wxString m_id
Stable machine key for CLI and jobsets, e.g. "10.0".
std::string compressedEncodedData
std::string ToString() const
std::optional< bool > is_capped
True if the drill hole should be capped.
std::optional< bool > is_filled
True if the drill hole should be filled completely.
std::optional< bool > has_covering
True if the pad on this side should have covering.
std::optional< bool > has_plugging
True if the drill hole should be plugged on this side.
std::optional< VECTOR2I > hatching_offset
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
static void checkBoardTransformCoverage(const COMPATIBILITY_REPORT &aReport, const DOWNGRADE_TARGET &aTarget, bool aDropInsteadOfApproximate)
static void checkExportUsesOnlyKnownTokens(const DOWNGRADE_TARGET &aTarget, const std::string &aTokenFileName)
static void checkNativeFootprintGolden(const DOWNGRADE_TARGET &aTarget, const std::string &aRelease, const std::string &aReference, bool aDropInsteadOfApproximate=false)
static void checkNativeBoardGolden(const DOWNGRADE_TARGET &aTarget, const std::string &aRelease, const std::string &aBoard, const std::string &aReference, size_t aExpectedDrops, size_t aExpectedLowerings, bool aDropInsteadOfApproximate=false)
static void checkTransformedBoardUsesOnlyKnownTokens(const DOWNGRADE_TARGET &aTarget, const std::string &aTokenFileName)
static std::string releaseEmbeddedChecksum(const std::vector< char > &aPayload)
BOOST_AUTO_TEST_CASE(BoardToKicad9UsesOnlyKnownTokens)
static std::string historicalTextEffects(const EDA_TEXT &aText, bool aV9, int aControlBits=0)
static PCB_REFERENCE_IMAGE * addTransformFeatures(BOARD &aBoard)
static void checkCustomPadArcSurvives(const DOWNGRADE_TARGET &aTarget)
static std::string historicalEmbeddedFiles(const EMBEDDED_FILES &aFiles, bool aV9, bool aWriteData)
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_AUTO_TEST_SUITE_END()
VECTOR3I expected(15, 30, 45)
static const DOWNGRADE_TARGET & kicad10
static const DOWNGRADE_TARGET & kicad9
static void checkExportUsesOnlyKnownTokens(const DOWNGRADE_TARGET &aTarget, const std::string &aTokenFileName)
BOOST_TEST_CONTEXT("Test Clearance")
BOOST_CHECK_EQUAL(result, "25.4")
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
@ PCB_DRILL_CHART_T
class PCB_DRILL_CHART, a live drill chart derived from PCB_TABLE
VECTOR2< int32_t > VECTOR2I