Allow PCB reference image locking and UUID to be saved

Add some unit tests for reference image saving/loading.

Fixes: https://gitlab.com/kicad/code/kicad/-/issues/16334
This commit is contained in:
John Beard 2023-12-12 20:38:55 +00:00 committed by Jon Evans
parent f3f16a1e23
commit 481fa1f959
10 changed files with 905 additions and 16 deletions

View File

@ -3099,8 +3099,26 @@ PCB_REFERENCE_IMAGE* PCB_PARSER::parsePCB_REFERENCE_IMAGE( BOARD_ITEM* aParent )
break;
}
case T_locked:
{
// This has only ever been (locked yes) format
const bool locked = parseBool();
bitmap->SetLocked( locked );
NeedRIGHT();
break;
}
case T_uuid:
{
NextTok();
const_cast<KIID&>( bitmap->m_Uuid ) = CurStrToKIID();
NeedRIGHT();
break;
}
default:
Expecting( "at, layer, scale, data" );
Expecting( "at, layer, scale, data, locked or uuid" );
}
}

View File

@ -1041,9 +1041,10 @@ void PCB_PLUGIN::format( const PCB_REFERENCE_IMAGE* aBitmap, int aNestLevel ) co
formatLayer( aBitmap->GetLayer() );
if( aBitmap->GetImage()->GetScale() != 1.0 )
m_out->Print( 0, " (scale %g)", aBitmap->GetImage()->GetScale() );
m_out->Print( 0, "(scale %g)", aBitmap->GetImage()->GetScale() );
m_out->Print( 0, "\n" );
if( const bool locked = aBitmap->IsLocked() )
KICAD_FORMAT::FormatBool( m_out, 0, "locked", locked );
m_out->Print( aNestLevel + 1, "(data" );
@ -1064,6 +1065,9 @@ void PCB_PLUGIN::format( const PCB_REFERENCE_IMAGE* aBitmap, int aNestLevel ) co
m_out->Print( 0, "\n" );
m_out->Print( aNestLevel + 1, ")\n" ); // Closes data token.
KICAD_FORMAT::FormatUuid( m_out, aBitmap->m_Uuid, 0 );
m_out->Print( aNestLevel, ")\n" ); // Closes image token.
}

View File

@ -0,0 +1,283 @@
(kicad_pcb
(version 20231212)
(generator "pcbnew")
(generator_version "7.99")
(general
(thickness 1.6)
(legacy_teardrops no)
)
(paper "A4")
(layers
(0 "F.Cu" signal)
(31 "B.Cu" signal)
(32 "B.Adhes" user "B.Adhesive")
(33 "F.Adhes" user "F.Adhesive")
(34 "B.Paste" user)
(35 "F.Paste" user)
(36 "B.SilkS" user "B.Silkscreen")
(37 "F.SilkS" user "F.Silkscreen")
(38 "B.Mask" user)
(39 "F.Mask" user)
(40 "Dwgs.User" user "User.Drawings")
(41 "Cmts.User" user "User.Comments")
(42 "Eco1.User" user "User.Eco1")
(43 "Eco2.User" user "User.Eco2")
(44 "Edge.Cuts" user)
(45 "Margin" user)
(46 "B.CrtYd" user "B.Courtyard")
(47 "F.CrtYd" user "F.Courtyard")
(48 "B.Fab" user)
(49 "F.Fab" user)
(50 "User.1" user)
(51 "User.2" user)
(52 "User.3" user)
(53 "User.4" user)
(54 "User.5" user)
(55 "User.6" user)
(56 "User.7" user)
(57 "User.8" user)
(58 "User.9" user)
)
(setup
(pad_to_mask_clearance 0)
(allow_soldermask_bridges_in_footprints no)
(pcbplotparams
(layerselection 0x00010fc_ffffffff)
(plot_on_all_layers_selection 0x0000000_00000000)
(disableapertmacros no)
(usegerberextensions no)
(usegerberattributes yes)
(usegerberadvancedattributes yes)
(creategerberjobfile yes)
(dashed_line_dash_ratio 12.000000)
(dashed_line_gap_ratio 3.000000)
(svgprecision 4)
(plotframeref no)
(viasonmask no)
(mode 1)
(useauxorigin no)
(hpglpennumber 1)
(hpglpenspeed 20)
(hpglpendiameter 15.000000)
(pdf_front_fp_property_popups yes)
(pdf_back_fp_property_popups yes)
(dxfpolygonmode yes)
(dxfimperialunits yes)
(dxfusepcbnewfont yes)
(psnegative no)
(psa4output no)
(plotreference yes)
(plotvalue yes)
(plotfptext yes)
(plotinvisibletext no)
(sketchpadsonfab no)
(subtractmaskfromsilk no)
(outputformat 1)
(mirror no)
(drillshape 1)
(scaleselection 1)
(outputdirectory "")
)
)
(net 0 "")
(image
(at 100 46)
(layer "F.Cu")
(data "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"
"TkSuQmCC"
)
(uuid "7dde345e-020a-4fdd-af77-588b452be5e0")
)
(image
(at 100 65)
(layer "F.Cu")
(locked yes)
(data "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"
"TkSuQmCC"
)
(uuid "e4fd52dd-1d89-4c43-b621-aebfc9788d5c")
)
(image
(at 100 90)
(layer "B.Cu")
(scale 2)
(data "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"
"TkSuQmCC"
)
(uuid "d402397e-bce0-4cae-a398-b5aeef397e87")
)
(gr_text "Image at scale 1"
(at 97 38 0)
(layer "Cmts.User")
(uuid "11c5bcf4-add5-4b5a-8a6e-551d6cc455dc")
(effects
(font
(size 1.5 1.5)
(thickness 0.3)
(bold yes)
)
(justify left bottom)
)
)
(gr_text "Locked image"
(at 97 57 0)
(layer "Cmts.User")
(uuid "ad07820b-4490-4581-87a7-7709f90e4f7e")
(effects
(font
(size 1.5 1.5)
(thickness 0.3)
(bold yes)
)
(justify left bottom)
)
)
(gr_text "Image at scale 2 on B.Cu"
(at 97 76 0)
(layer "Cmts.User")
(uuid "c4b3cc49-cd2d-43d3-93e2-82f81e39ecf0")
(effects
(font
(size 1.5 1.5)
(thickness 0.3)
(bold yes)
)
(justify left bottom)
)
)
)

View File

@ -0,0 +1,271 @@
{
"board": {
"3dviewports": [],
"design_settings": {
"defaults": {
"apply_defaults_to_fp_fields": false,
"apply_defaults_to_fp_shapes": false,
"apply_defaults_to_fp_text": false,
"board_outline_line_width": 0.049999999999999996,
"copper_line_width": 0.19999999999999998,
"copper_text_italic": false,
"copper_text_size_h": 1.5,
"copper_text_size_v": 1.5,
"copper_text_thickness": 0.3,
"copper_text_upright": false,
"courtyard_line_width": 0.049999999999999996,
"dimension_precision": 4,
"dimension_units": 3,
"dimensions": {
"arrow_length": 1270000,
"extension_offset": 500000,
"keep_text_aligned": true,
"suppress_zeroes": false,
"text_position": 0,
"units_format": 1
},
"fab_line_width": 0.09999999999999999,
"fab_text_italic": false,
"fab_text_size_h": 1.0,
"fab_text_size_v": 1.0,
"fab_text_thickness": 0.15,
"fab_text_upright": false,
"other_line_width": 0.09999999999999999,
"other_text_italic": false,
"other_text_size_h": 1.0,
"other_text_size_v": 1.0,
"other_text_thickness": 0.15,
"other_text_upright": false,
"pads": {
"drill": 0.762,
"height": 1.524,
"width": 1.524
},
"silk_line_width": 0.09999999999999999,
"silk_text_italic": false,
"silk_text_size_h": 1.0,
"silk_text_size_v": 1.0,
"silk_text_thickness": 0.09999999999999999,
"silk_text_upright": false,
"zones": {
"min_clearance": 0.5
}
},
"diff_pair_dimensions": [],
"drc_exclusions": [],
"meta": {
"version": 2
},
"rule_severities": {
"annular_width": "error",
"clearance": "error",
"connection_width": "warning",
"copper_edge_clearance": "error",
"copper_sliver": "warning",
"courtyards_overlap": "error",
"diff_pair_gap_out_of_range": "error",
"diff_pair_uncoupled_length_too_long": "error",
"drill_out_of_range": "error",
"duplicate_footprints": "warning",
"extra_footprint": "warning",
"footprint": "error",
"footprint_type_mismatch": "ignore",
"hole_clearance": "error",
"hole_near_hole": "error",
"invalid_outline": "error",
"isolated_copper": "warning",
"item_on_disabled_layer": "error",
"items_not_allowed": "error",
"length_out_of_range": "error",
"lib_footprint_issues": "warning",
"lib_footprint_mismatch": "warning",
"malformed_courtyard": "error",
"microvia_drill_out_of_range": "error",
"missing_courtyard": "ignore",
"missing_footprint": "warning",
"net_conflict": "warning",
"npth_inside_courtyard": "ignore",
"padstack": "warning",
"pth_inside_courtyard": "ignore",
"shorting_items": "error",
"silk_edge_clearance": "warning",
"silk_over_copper": "warning",
"silk_overlap": "warning",
"skew_out_of_range": "error",
"solder_mask_bridge": "error",
"starved_thermal": "error",
"text_height": "warning",
"text_thickness": "warning",
"through_hole_pad_without_hole": "error",
"too_many_vias": "error",
"track_dangling": "warning",
"track_width": "error",
"tracks_crossing": "error",
"unconnected_items": "error",
"unresolved_variable": "error",
"via_dangling": "warning",
"zones_intersect": "error"
},
"rules": {
"max_error": 0.005,
"min_clearance": 0.0,
"min_connection": 0.0,
"min_copper_edge_clearance": 0.5,
"min_hole_clearance": 0.25,
"min_hole_to_hole": 0.25,
"min_microvia_diameter": 0.19999999999999998,
"min_microvia_drill": 0.09999999999999999,
"min_resolved_spokes": 2,
"min_silk_clearance": 0.0,
"min_text_height": 0.7999999999999999,
"min_text_thickness": 0.08,
"min_through_hole_diameter": 0.3,
"min_track_width": 0.0,
"min_via_annular_width": 0.09999999999999999,
"min_via_diameter": 0.5,
"solder_mask_to_copper_clearance": 0.0,
"use_height_for_length_calcs": true
},
"teardrop_options": [
{
"td_onpadsmd": true,
"td_onroundshapesonly": false,
"td_ontrackend": false,
"td_onviapad": true
}
],
"teardrop_parameters": [
{
"td_allow_use_two_tracks": true,
"td_curve_segcount": 0,
"td_height_ratio": 1.0,
"td_length_ratio": 0.5,
"td_maxheight": 2.0,
"td_maxlen": 1.0,
"td_on_pad_in_zone": false,
"td_target_name": "td_round_shape",
"td_width_to_size_filter_ratio": 0.9
},
{
"td_allow_use_two_tracks": true,
"td_curve_segcount": 0,
"td_height_ratio": 1.0,
"td_length_ratio": 0.5,
"td_maxheight": 2.0,
"td_maxlen": 1.0,
"td_on_pad_in_zone": false,
"td_target_name": "td_rect_shape",
"td_width_to_size_filter_ratio": 0.9
},
{
"td_allow_use_two_tracks": true,
"td_curve_segcount": 0,
"td_height_ratio": 1.0,
"td_length_ratio": 0.5,
"td_maxheight": 2.0,
"td_maxlen": 1.0,
"td_on_pad_in_zone": false,
"td_target_name": "td_track_end",
"td_width_to_size_filter_ratio": 0.9
}
],
"track_widths": [],
"tuning_pattern_settings": {
"diff_pair_defaults": {
"corner_radius_percentage": 100,
"corner_style": 1,
"max_amplitude": 1.0,
"min_amplitude": 0.1,
"single_sided": false,
"spacing": 0.6
},
"diff_pair_skew_defaults": {
"corner_radius_percentage": 100,
"corner_style": 1,
"max_amplitude": 1.0,
"min_amplitude": 0.1,
"single_sided": false,
"spacing": 0.6
},
"single_track_defaults": {
"corner_radius_percentage": 100,
"corner_style": 1,
"max_amplitude": 1.0,
"min_amplitude": 0.1,
"single_sided": false,
"spacing": 0.6
}
},
"via_dimensions": [],
"zones_allow_external_fillets": false
},
"ipc2581": {
"dist": "",
"distpn": "",
"internal_id": "",
"mfg": "",
"mpn": ""
},
"layer_presets": [],
"viewports": []
},
"boards": [],
"cvpcb": {
"equivalence_files": []
},
"libraries": {
"pinned_footprint_libs": [],
"pinned_symbol_libs": []
},
"meta": {
"filename": "pcb_reference_images.kicad_pro",
"version": 1
},
"net_settings": {
"classes": [
{
"bus_width": 12,
"clearance": 0.2,
"diff_pair_gap": 0.25,
"diff_pair_via_gap": 0.25,
"diff_pair_width": 0.2,
"line_style": 0,
"microvia_diameter": 0.3,
"microvia_drill": 0.1,
"name": "Default",
"pcb_color": "rgba(0, 0, 0, 0.000)",
"schematic_color": "rgba(0, 0, 0, 0.000)",
"track_width": 0.2,
"via_diameter": 0.6,
"via_drill": 0.3,
"wire_width": 6
}
],
"meta": {
"version": 3
},
"net_colors": null,
"netclass_assignments": null,
"netclass_patterns": []
},
"pcbnew": {
"last_paths": {
"gencad": "",
"idf": "",
"netlist": "",
"plot": "",
"pos_files": "",
"specctra_dsn": "",
"step": "",
"svg": "",
"vrml": ""
},
"page_layout_descr_file": ""
},
"schematic": {
"legacy_lib_dir": "",
"legacy_lib_list": []
},
"sheets": [],
"text_variables": {}
}

View File

@ -26,19 +26,21 @@
#include <filesystem>
#include <wx/filename.h>
#include <board.h>
#include <board_design_settings.h>
#include <footprint.h>
#include <pcb_shape.h>
#include <zone.h>
#include <pad.h>
#include <settings/settings_manager.h>
#include <pcbnew_utils/board_file_utils.h>
#include <tool/tool_manager.h>
#include <zone_filler.h>
#include <boost/test/unit_test.hpp>
#include <board.h>
#include <board_commit.h>
#include <board_design_settings.h>
#include <footprint.h>
#include <kiid.h>
#include <pad.h>
#include <pcb_shape.h>
#include <zone.h>
#include <zone_filler.h>
#include <pcbnew_utils/board_file_utils.h>
#include <settings/settings_manager.h>
#include <tool/tool_manager.h>
#define CHECK_ENUM_CLASS_EQUAL( L, R ) \
BOOST_CHECK_EQUAL( static_cast<int>( L ), static_cast<int>( R ) )
@ -114,6 +116,49 @@ void LoadBoard( SETTINGS_MANAGER& aSettingsManager, const wxString& aRelPath,
}
BOARD_ITEM& RequireBoardItemWithTypeAndId( const BOARD& aBoard, KICAD_T aItemType, const KIID& aID )
{
BOARD_ITEM* item = aBoard.GetItem( aID );
BOOST_REQUIRE( item );
BOOST_REQUIRE( item->Type() == aItemType );
return *item;
}
void LoadAndTestBoardFile( const wxString aRelativePath, bool aRoundtrip,
std::function<void( BOARD& )> aBoardTestFunction )
{
const std::string absBoardPath =
KI_TEST::GetPcbnewTestDataDir() + aRelativePath.ToStdString() + ".kicad_pcb";
BOOST_TEST_MESSAGE( "Loading board to test: " << absBoardPath );
std::unique_ptr<BOARD> board1 = KI_TEST::ReadBoardFromFileOrStream( absBoardPath );
// Should load - if it doesn't we're done for
BOOST_REQUIRE( board1 );
BOOST_TEST_MESSAGE( "Testing loaded board" );
aBoardTestFunction( *board1 );
if( aRoundtrip )
{
const auto savePath = std::filesystem::temp_directory_path()
/ ( aRelativePath.ToStdString() + ".kicad_pcb" );
KI_TEST::DumpBoardToFile( *board1, savePath.string() );
std::unique_ptr<BOARD> board2 = KI_TEST::ReadBoardFromFileOrStream( savePath.string() );
// Should load again
BOOST_REQUIRE( board2 );
BOOST_TEST_MESSAGE( "Testing roundtripped (saved/reloaded) file" );
aBoardTestFunction( *board2 );
}
}
void FillZones( BOARD* m_board )
{
TOOL_MANAGER toolMgr;

View File

@ -27,15 +27,19 @@
#include <memory>
#include <string>
#include <wx/string.h>
#include <mutex>
#include <map>
#include <wx/string.h>
#include <reporter.h>
#include <core/typeinfo.h>
#include <tool/tool_manager.h>
class BOARD;
class BOARD_ITEM;
class FOOTPRINT;
class KIID;
class PCB_TEXT;
class PCB_SHAPE;
class ZONE;
@ -43,7 +47,6 @@ class PAD;
class SHAPE_POLY_SET;
class SETTINGS_MANAGER;
namespace KI_TEST
{
class DUMMY_TOOL : public TOOL_BASE
@ -173,6 +176,32 @@ private:
void LoadBoard( SETTINGS_MANAGER& aSettingsManager, const wxString& aRelPath,
std::unique_ptr<BOARD>& aBoard );
/**
* @brief Get an item from the given board with a certain type and UUID.
*
* If this doesn't exist, it's a BOOST_REQUIRE failure.
*
* @param aBoard the board to look in
* @param aItemType the required item type
* @param aID the required
* @return BOARD_ITEM& the required board item
*/
BOARD_ITEM& RequireBoardItemWithTypeAndId( const BOARD& aBoard, KICAD_T aItemType,
const KIID& aID );
/**
* @brief Perform "some test" on a board file loaded from the path,
* then optionally save and reload and run the test again.
*
* The roundtrip is useful to test stability of serialisation/reload.
*
* @param aRelativePath relative path of file to load
* @param aRoundtrip true to save, reload and re-test
* @param aBoardTestFunction the function that runs tests on the board
*/
void LoadAndTestBoardFile( const wxString aRelativePath, bool aRoundtrip,
std::function<void( BOARD& )> aBoardTestFunction );
void FillZones( BOARD* m_board );

View File

@ -40,6 +40,7 @@ set( QA_PCBNEW_SRCS
test_pad_numbering.cpp
test_prettifier.cpp
test_libeval_compiler.cpp
test_reference_image_load.cpp
test_save_load.cpp
test_tracks_cleaner.cpp
test_zone_filler.cpp

View File

@ -0,0 +1,102 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <filesystem>
#include <board.h>
#include <kiid.h>
#include <footprint.h>
#include <pcbnew_utils/board_file_utils.h>
#include <pcbnew_utils/board_test_utils.h>
#include <qa_utils/wx_utils/unit_test_utils.h>
#include <settings/settings_manager.h>
namespace
{
struct FOOTPRINT_LOAD_TEST_FIXTURE
{
FOOTPRINT_LOAD_TEST_FIXTURE() {}
};
struct FOOTPRINT_LOAD_TEST_CASE
{
// Which footprint this is
KIID m_footprintUuid;
bool m_expectedLocked;
VECTOR2I m_expectedPos;
};
struct FOOTPRINT_LOAD_BOARD_TEST_CASE
{
// The board to load
wxString m_boardFileRelativePath;
// List of images to check
std::vector<FOOTPRINT_LOAD_TEST_CASE> m_imageCases;
};
} // namespace
BOOST_FIXTURE_TEST_CASE( FootprintLoadSave, FOOTPRINT_LOAD_TEST_FIXTURE )
{
const std::vector<FOOTPRINT_LOAD_BOARD_TEST_CASE> testCases{
{
"footprints_load_save",
{
// From top to bottom in the board file
{
"898cf321-03c7-40bb-8d78-4bc5e52986c2",
false,
{ 100, 80 },
},
{
"0775cd70-2e84-4592-a160-456c37a8f4f6",
true,
{ 100, 100 },
},
},
},
};
for( const FOOTPRINT_LOAD_BOARD_TEST_CASE& testCase : testCases )
{
const auto doBoardTest = [&]( const BOARD& aBoard )
{
for( const FOOTPRINT_LOAD_TEST_CASE& fooprintTestCase : testCase.m_imageCases )
{
BOOST_TEST_MESSAGE( "Checking for footprint with UUID: "
<< fooprintTestCase.m_footprintUuid.AsString() );
const auto& image = static_cast<FOOTPRINT&>( KI_TEST::RequireBoardItemWithTypeAndId(
aBoard, PCB_FOOTPRINT_T, fooprintTestCase.m_footprintUuid ) );
BOOST_CHECK_EQUAL( image.IsLocked(), fooprintTestCase.m_expectedLocked );
BOOST_CHECK_EQUAL( image.GetPosition(), fooprintTestCase.m_expectedPos * 1000000 );
}
};
KI_TEST::LoadAndTestBoardFile( testCase.m_boardFileRelativePath, true, doBoardTest );
}
}

View File

@ -27,6 +27,7 @@
#include <boost/test/unit_test.hpp>
#include <kiplatform/app.h>
#include <wx/image.h>
#include <wx/init.h>
@ -34,7 +35,16 @@ bool init_unit_test()
{
KIPLATFORM::APP::Init();
boost::unit_test::framework::master_test_suite().p_name.value = "Pcbnew module tests";
return wxInitialize();
bool ok = wxInitialize();
if( ok )
{
// need these for library image functions
wxInitAllImageHandlers();
}
return ok;
}

View File

@ -0,0 +1,126 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <filesystem>
#include <board.h>
#include <kiid.h>
#include <pcb_reference_image.h>
#include <pcbnew_utils/board_file_utils.h>
#include <pcbnew_utils/board_test_utils.h>
#include <qa_utils/wx_utils/unit_test_utils.h>
#include <settings/settings_manager.h>
namespace
{
struct REFERENCE_IMAGE_LOAD_TEST_FIXTURE
{
REFERENCE_IMAGE_LOAD_TEST_FIXTURE() {}
};
struct REFERENCE_IMAGE_LOAD_TEST_CASE
{
// Which
KIID m_imageUuid;
bool m_expectedLocked;
VECTOR2I m_expectedPos;
double m_expectedScale;
// This should also check correct image decoding, as it won't work otherwise
VECTOR2I m_expectedPixelSize;
};
struct REFERENCE_IMAGE_LOAD_BOARD_TEST_CASE
{
// The board to load
wxString m_boardFileRelativePath;
// List of images to check
std::vector<REFERENCE_IMAGE_LOAD_TEST_CASE> m_imageCases;
};
} // namespace
BOOST_FIXTURE_TEST_CASE( ReferenceImageLoading, REFERENCE_IMAGE_LOAD_TEST_FIXTURE )
{
const std::vector<REFERENCE_IMAGE_LOAD_BOARD_TEST_CASE> testCases{
{
"reference_images_load_save",
{
// From top to bottom in the board file
{
"7dde345e-020a-4fdd-af77-588b452be5e0",
false,
{ 100, 46 },
1.0,
{ 64, 64 },
},
{
"e4fd52dd-1d89-4c43-b621-aebfc9788d5c",
true,
{ 100, 65 },
1.0,
{ 64, 64 },
},
{
"d402397e-bce0-4cae-a398-b5aeef397e87",
false,
{ 100, 90 },
2.0,
{ 64, 64 }, // It's the same size, but scaled
},
},
},
};
for( const REFERENCE_IMAGE_LOAD_BOARD_TEST_CASE& testCase : testCases )
{
const auto doBoardTest = [&]( const BOARD& aBoard )
{
for( const REFERENCE_IMAGE_LOAD_TEST_CASE& imageTestCase : testCase.m_imageCases )
{
BOOST_TEST_MESSAGE(
"Checking for image with UUID: " << imageTestCase.m_imageUuid.AsString() );
const auto& image =
static_cast<PCB_REFERENCE_IMAGE&>( KI_TEST::RequireBoardItemWithTypeAndId(
aBoard, PCB_REFERENCE_IMAGE_T, imageTestCase.m_imageUuid ) );
BOOST_CHECK_EQUAL( image.IsLocked(), imageTestCase.m_expectedLocked );
BOOST_CHECK_EQUAL( image.GetPosition(), imageTestCase.m_expectedPos * 1000000 );
BOOST_CHECK_CLOSE( image.GetImageScale(), imageTestCase.m_expectedScale, 1e-6 );
const BITMAP_BASE* bitmap = image.GetImage();
BOOST_REQUIRE( bitmap );
BOOST_TEST_MESSAGE( "Got underlying image" );
BOOST_CHECK_EQUAL( bitmap->GetSizePixels(), imageTestCase.m_expectedPixelSize );
}
};
KI_TEST::LoadAndTestBoardFile( testCase.m_boardFileRelativePath, true, doBoardTest );
}
}