55#include <compoundfilereader.h>
62#include <wx/mstream.h>
63#include <wx/zstream.h>
64#include <wx/wfstream.h>
65#include <magic_enum.hpp>
70#define HARNESS_PORT_COLOR_DEFAULT_BACKGROUND COLOR4D( 0.92941176470588238, \
71 0.94901960784313721, \
72 0.98431372549019602, 1.0 )
74#define HARNESS_PORT_COLOR_DEFAULT_OUTLINE COLOR4D( 0.56078431372549020, \
75 0.61960784313725492, \
76 0.78823529411764703, 1.0 )
89 int green = (
color & 0x00FF00 ) >> 8;
90 int blue = (
color & 0xFF0000 ) >> 16;
154 if(
color == default_color ||
color == alt_default_color )
183 else if( elem.
AreaColor == aStrokeColor )
189 else if( bgcolor.
WithAlpha( 1.0 ) == default_bgcolor )
227 for(
auto& [
name, symbol] : lib )
314 wxCHECK( !aFileName.IsEmpty() && aSchematic,
nullptr );
316 wxFileName fileName( aFileName );
321 std::unique_ptr<SCH_SHEET> deleter( aAppendToMe ?
nullptr :
m_rootSheet );
325 wxCHECK_MSG( aSchematic->
IsValid(),
nullptr,
"Can't append to a schematic with no root!" );
352 wxCHECK_MSG( libTable,
nullptr,
"Could not load symbol lib table." );
354 m_pi.reset( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_KICAD ) );
362 wxString libTableUri =
"${KIPRJMOD}/" +
getLibFileName().GetFullName();
366 wxString(
"KiCad" ) ) );
375 libTable->
Format( &formatter, 0 );
386 wxCHECK( rootScreen,
nullptr );
406 int minWireWidth = std::numeric_limits<int>::max();
407 int minBusWidth = std::numeric_limits<int>::max();
411 std::vector<SCH_MARKER*> markers;
418 minWireWidth = std::min( minWireWidth, line->
GetLineWidth() );
421 minBusWidth = std::min( minBusWidth, line->
GetLineWidth() );
427 if( minWireWidth < std::numeric_limits<int>::max() )
428 netSettings->m_DefaultNetClass->SetWireWidth( minWireWidth );
430 if( minBusWidth < std::numeric_limits<int>::max() )
431 netSettings->m_DefaultNetClass->SetBusWidth( minBusWidth );
452 wxFileName parentFileName = aFileName;
466 catch(
const CFB::CFBException& exception )
470 catch(
const std::exception& exc )
472 wxLogDebug( wxT(
"Unhandled exception in Altium schematic parsers: %s." ), exc.what() );
482 wxCHECK( currentScreen, );
490 wxCHECK2( sheet,
continue );
494 wxFileName loadAltiumFileName( parentFileName.GetPath(), sheet->
GetFileName() );
496 if( !loadAltiumFileName.IsFileReadable() )
500 wxDir::GetAllFiles( parentFileName.GetPath(), &files, wxEmptyString,
501 wxDIR_FILES | wxDIR_HIDDEN );
503 for(
const wxString& candidate : files )
505 wxFileName candidateFname( candidate );
507 if( candidateFname.GetFullName().IsSameAs( sheet->
GetFileName(),
false ) )
509 loadAltiumFileName = candidateFname;
515 if( loadAltiumFileName.GetFullName().IsEmpty() || !loadAltiumFileName.IsFileReadable() )
519 msg.Printf(
_(
"The file name for sheet %s is undefined, this is probably an"
520 " Altium signal harness that got converted to a sheet." ),
539 if( sheet->
GetName().Trim().empty() )
540 sheet->
SetName( loadAltiumFileName.GetName() );
542 wxCHECK2( screen,
continue );
548 wxFileName projectFileName = loadAltiumFileName;
551 sheet->
SetFileName( projectFileName.GetFullName() );
552 screen->
SetFileName( projectFileName.GetFullPath() );
562 const CFB::COMPOUND_FILE_ENTRY* file = aAltiumSchFile.
FindStream( {
"Storage" } );
564 if( file ==
nullptr )
569 std::map<wxString, wxString> properties = reader.
ReadProperties();
576 for(
int i = 0; i < weight; i++ )
587 "(%d bytes remaining)." ),
596 wxString streamName = wxS(
"Additional" );
598 const CFB::COMPOUND_FILE_ENTRY* file =
599 aAltiumSchFile.
FindStream( { streamName.ToStdString() } );
601 if( file ==
nullptr )
612 std::map<wxString, wxString> properties = reader.
ReadProperties();
617 if( record != ALTIUM_SCH_RECORD::HEADER )
623 std::map<wxString, wxString> properties = reader.
ReadProperties();
644 wxString streamName = wxS(
"FileHeader" );
646 const CFB::COMPOUND_FILE_ENTRY* file =
647 aAltiumSchFile.
FindStream( { streamName.ToStdString() } );
649 if( file ==
nullptr )
660 std::map<wxString, wxString> properties = reader.
ReadProperties();
664 if( libtype.CmpNoCase(
"Protel for Windows - Schematic Capture Binary File Version 5.0" ) )
677 std::map<wxString, wxString> properties = reader.
ReadProperties();
689 for( std::pair<const int, SCH_SYMBOL*>& symbol :
m_symbols )
699 symbol.second->SetLibSymbol( libSymbolIt->second );
736 while( storageReader.
CanRead() )
738 std::map<wxString, wxString> properties = storageReader.
ReadProperties();
741 if( properties.find( wxS(
"BINARY" ) ) != properties.end() )
755 std::map<wxString, wxString> properties = reader.
ReadProperties();
759 if( libtype.CmpNoCase(
"Protel for Windows - Schematic Capture Ascii File Version 5.0" ) )
774 std::map<wxString, wxString> properties = reader.
ReadProperties();
777 if( properties.find( wxS(
"HEADER" ) ) != properties.end() )
783 if( properties.find( wxS(
"RECORD" ) ) != properties.end() )
796 for( std::pair<const int, SCH_SYMBOL*>& symbol :
m_symbols )
806 symbol.second->SetLibSymbol( libSymbolIt->second );
842 const wxString& aSectionName )
852 case ALTIUM_SCH_RECORD::HEADER:
855 case ALTIUM_SCH_RECORD::COMPONENT:
859 case ALTIUM_SCH_RECORD::PIN:
863 case ALTIUM_SCH_RECORD::IEEE_SYMBOL:
867 case ALTIUM_SCH_RECORD::LABEL:
871 case ALTIUM_SCH_RECORD::BEZIER:
875 case ALTIUM_SCH_RECORD::POLYLINE:
879 case ALTIUM_SCH_RECORD::POLYGON:
883 case ALTIUM_SCH_RECORD::ELLIPSE:
887 case ALTIUM_SCH_RECORD::PIECHART:
891 case ALTIUM_SCH_RECORD::ROUND_RECTANGLE:
895 case ALTIUM_SCH_RECORD::ELLIPTICAL_ARC:
896 case ALTIUM_SCH_RECORD::ARC:
900 case ALTIUM_SCH_RECORD::LINE:
904 case ALTIUM_SCH_RECORD::RECTANGLE:
908 case ALTIUM_SCH_RECORD::SHEET_SYMBOL:
912 case ALTIUM_SCH_RECORD::SHEET_ENTRY:
916 case ALTIUM_SCH_RECORD::POWER_PORT:
920 case ALTIUM_SCH_RECORD::PORT:
926 case ALTIUM_SCH_RECORD::NO_ERC:
930 case ALTIUM_SCH_RECORD::NET_LABEL:
934 case ALTIUM_SCH_RECORD::BUS:
938 case ALTIUM_SCH_RECORD::WIRE:
942 case ALTIUM_SCH_RECORD::TEXT_FRAME:
946 case ALTIUM_SCH_RECORD::JUNCTION:
950 case ALTIUM_SCH_RECORD::IMAGE:
954 case ALTIUM_SCH_RECORD::SHEET:
958 case ALTIUM_SCH_RECORD::SHEET_NAME:
962 case ALTIUM_SCH_RECORD::FILE_NAME:
966 case ALTIUM_SCH_RECORD::DESIGNATOR:
970 case ALTIUM_SCH_RECORD::BUS_ENTRY:
974 case ALTIUM_SCH_RECORD::TEMPLATE:
978 case ALTIUM_SCH_RECORD::PARAMETER:
982 case ALTIUM_SCH_RECORD::PARAMETER_SET:
986 case ALTIUM_SCH_RECORD::IMPLEMENTATION_LIST:
990 case ALTIUM_SCH_RECORD::IMPLEMENTATION:
994 case ALTIUM_SCH_RECORD::MAP_DEFINER_LIST:
997 case ALTIUM_SCH_RECORD::MAP_DEFINER:
1000 case ALTIUM_SCH_RECORD::IMPL_PARAMS:
1003 case ALTIUM_SCH_RECORD::NOTE:
1007 case ALTIUM_SCH_RECORD::COMPILE_MASK:
1011 case ALTIUM_SCH_RECORD::HYPERLINK:
1016 case ALTIUM_SCH_RECORD::HARNESS_CONNECTOR:
1020 case ALTIUM_SCH_RECORD::HARNESS_ENTRY:
1024 case ALTIUM_SCH_RECORD::HARNESS_TYPE:
1028 case ALTIUM_SCH_RECORD::SIGNAL_HARNESS:
1032 case ALTIUM_SCH_RECORD::BLANKET:
1038 wxString::Format(
_(
"Unknown or unexpected record id %d found in %s." ), recordId,
1069 if( file.filename.IsSameAs( aFilename ) )
1072 if( file.filename.EndsWith( aFilename ) )
1073 nonExactMatch = &file;
1076 return nonExactMatch;
1083 wxCHECK( currentSheet, );
1085 wxString sheetName = currentSheet->
GetName();
1087 if( sheetName.IsEmpty() )
1088 sheetName = wxT(
"root" );
1096 m_reporter->
Report( wxString::Format(
_(
"Symbol \"%s\" in sheet \"%s\" at index %d "
1097 "replaced with symbol \"%s\"." ),
1109 wxString
name = wxString::Format(
"%s_%d%s_%s",
1132 field.SetVisible(
false );
1143 screen->
Append( symbol );
1152 wxCHECK( currentSheet, );
1154 wxString sheetName = currentSheet->
GetName();
1156 if( sheetName.IsEmpty() )
1157 sheetName = wxT(
"root" );
1162 wxString baseName = altiumTemplate.
filename.AfterLast(
'\\' ).BeforeLast(
'.' );
1164 if( baseName.IsEmpty() )
1165 baseName = wxS(
"Template" );
1173 std::vector<LIB_SYMBOL*>& aSymbol )
1189 m_reporter->
Report( wxString::Format( wxT(
"Pin's owner (%d) not found." ),
1198 schSymbol =
m_symbols.at( libSymbolIt->first );
1199 symbol = libSymbolIt->second;
1218 pin->SetVisible(
false );
1221 pin->SetNumberTextSize( 0 );
1224 pin->SetNameTextSize( 0 );
1230 case ASCH_RECORD_ORIENTATION::RIGHTWARDS:
1231 pin->SetOrientation( PIN_ORIENTATION::PIN_LEFT );
1235 case ASCH_RECORD_ORIENTATION::UPWARDS:
1236 pin->SetOrientation( PIN_ORIENTATION::PIN_DOWN );
1240 case ASCH_RECORD_ORIENTATION::LEFTWARDS:
1241 pin->SetOrientation( PIN_ORIENTATION::PIN_RIGHT );
1245 case ASCH_RECORD_ORIENTATION::DOWNWARDS:
1246 pin->SetOrientation( PIN_ORIENTATION::PIN_UP );
1260 pin->SetPosition( pinLocation );
1264 case ASCH_PIN_ELECTRICAL::INPUT:
1265 pin->SetType( ELECTRICAL_PINTYPE::PT_INPUT );
1268 case ASCH_PIN_ELECTRICAL::BIDI:
1269 pin->SetType( ELECTRICAL_PINTYPE::PT_BIDI );
1272 case ASCH_PIN_ELECTRICAL::OUTPUT:
1273 pin->SetType( ELECTRICAL_PINTYPE::PT_OUTPUT );
1276 case ASCH_PIN_ELECTRICAL::OPEN_COLLECTOR:
1277 pin->SetType( ELECTRICAL_PINTYPE::PT_OPENCOLLECTOR );
1280 case ASCH_PIN_ELECTRICAL::PASSIVE:
1281 pin->SetType( ELECTRICAL_PINTYPE::PT_PASSIVE );
1284 case ASCH_PIN_ELECTRICAL::TRISTATE:
1285 pin->SetType( ELECTRICAL_PINTYPE::PT_TRISTATE );
1288 case ASCH_PIN_ELECTRICAL::OPEN_EMITTER:
1289 pin->SetType( ELECTRICAL_PINTYPE::PT_OPENEMITTER );
1292 case ASCH_PIN_ELECTRICAL::POWER:
1293 pin->SetType( ELECTRICAL_PINTYPE::PT_POWER_IN );
1296 case ASCH_PIN_ELECTRICAL::UNKNOWN:
1298 pin->SetType( ELECTRICAL_PINTYPE::PT_UNSPECIFIED );
1314 pin->SetShape( GRAPHIC_PINSHAPE::INVERTED_CLOCK );
1318 pin->SetShape( GRAPHIC_PINSHAPE::INVERTED );
1327 pin->SetShape( GRAPHIC_PINSHAPE::CLOCK_LOW );
1331 pin->SetShape( GRAPHIC_PINSHAPE::INPUT_LOW );
1337 pin->SetShape( GRAPHIC_PINSHAPE::OUTPUT_LOW );
1344 pin->SetShape( GRAPHIC_PINSHAPE::CLOCK );
1348 pin->SetShape( GRAPHIC_PINSHAPE::LINE );
1358 int vjustify, hjustify;
1361 switch( justification )
1384 switch( justification )
1407 switch( orientation )
1430 text->SetTextAngle( angle );
1449 std::vector<LIB_SYMBOL*>& aSymbol, std::vector<int>& aFontSizes )
1455 static const std::map<wxString, wxString> variableMap = {
1456 {
"APPLICATION_BUILDNUMBER",
"KICAD_VERSION" },
1457 {
"SHEETNUMBER",
"#" },
1458 {
"SHEETTOTAL",
"##" },
1459 {
"TITLE",
"TITLE" },
1460 {
"REVISION",
"REVISION" },
1461 {
"DATE",
"ISSUE_DATE" },
1462 {
"CURRENTDATE",
"CURRENT_DATE" },
1463 {
"COMPANYNAME",
"COMPANY" },
1464 {
"DOCUMENTNAME",
"FILENAME" },
1465 {
"DOCUMENTFULLPATHANDNAME",
"FILEPATH" },
1466 {
"PROJECTNAME",
"PROJECTNAME" },
1474 size_t fontId =
static_cast<int>( elem.
fontId );
1491 screen->
Append( textItem );
1507 m_reporter->
Report( wxString::Format( wxT(
"Label's owner (%d) not found." ),
1513 symbol = libSymbolIt->second;
1514 schsym =
m_symbols.at( libSymbolIt->first );
1529 size_t fontId = elem.
fontId;
1540 else if( fontId > 0 && fontId <= aFontSizes.size() )
1542 int size = aFontSizes[fontId - 1];
1550 std::vector<LIB_SYMBOL*>& aSymbol,
1551 std::vector<int>& aFontSizes )
1578 textBox->
SetStart( sheetTopRight );
1579 textBox->
SetEnd( sheetBottomLeft );
1586 textBox->
SetFillMode( FILL_T::FILLED_WITH_COLOR );
1600 case ASCH_TEXT_FRAME_ALIGNMENT::LEFT:
1603 case ASCH_TEXT_FRAME_ALIGNMENT::CENTER:
1606 case ASCH_TEXT_FRAME_ALIGNMENT::RIGHT:
1611 size_t fontId =
static_cast<int>( aElem->
FontID );
1629 screen->
Append( textBox );
1634 std::vector<int>& aFontSizes )
1649 wxString::Format( wxT(
"Label's owner (%d) not found." ), aElem->
ownerindex ),
1654 symbol = libSymbolIt->second;
1655 schsym =
m_symbols.at( libSymbolIt->first );
1680 textBox->
SetFillMode( FILL_T::FILLED_WITH_COLOR );
1693 case ASCH_TEXT_FRAME_ALIGNMENT::LEFT:
1696 case ASCH_TEXT_FRAME_ALIGNMENT::CENTER:
1699 case ASCH_TEXT_FRAME_ALIGNMENT::RIGHT:
1704 if( aElem->
FontID > 0 && aElem->
FontID <=
static_cast<int>( aFontSizes.size() ) )
1706 int size = aFontSizes[aElem->
FontID - 1];
1713 std::vector<LIB_SYMBOL*>& aSymbol )
1717 if( elem.
points.size() < 2 )
1719 m_reporter->
Report( wxString::Format(
_(
"Bezier has %d control points. At least 2 are "
1721 static_cast<int>( elem.
points.size() ) ),
1729 wxCHECK( currentScreen, );
1731 for(
size_t i = 0; i + 1 < elem.
points.size(); i += 3 )
1733 if( i + 2 == elem.
points.size() )
1737 SCH_LAYER_ID::LAYER_NOTES );
1744 currentScreen->
Append( line );
1749 std::vector<VECTOR2I> bezierPoints;
1750 std::vector<VECTOR2I> polyPoints;
1752 for(
size_t j = i; j < elem.
points.size() && j < i + 4; j++ )
1753 bezierPoints.push_back( elem.
points.at( j ) );
1756 converter.
GetPoly( polyPoints );
1758 for(
size_t k = 0; k + 1 < polyPoints.size(); k++ )
1761 SCH_LAYER_ID::LAYER_NOTES );
1767 currentScreen->
Append( line );
1786 m_reporter->
Report( wxString::Format( wxT(
"Bezier's owner (%d) not found." ),
1792 symbol = libSymbolIt->second;
1793 schsym =
m_symbols.at( libSymbolIt->first );
1799 for(
size_t i = 0; i + 1 < elem.
points.size(); i += 3 )
1801 if( i + 2 == elem.
points.size() )
1809 for(
size_t j = i; j < elem.
points.size() && j < i + 2; j++ )
1821 else if( i + 3 == elem.
points.size() )
1832 for(
size_t j = i; j < elem.
points.size() && j < i + 2; j++ )
1852 for(
size_t j = i; j < elem.
points.size() && j < i + 4; j++ )
1861 case 0: bezier->
SetStart( pos );
break;
1864 case 3: bezier->
SetEnd( pos );
break;
1877 std::vector<LIB_SYMBOL*>& aSymbol )
1881 if( elem.
Points.size() < 2 )
1889 for(
size_t i = 1; i < elem.
Points.size(); i++ )
1918 m_reporter->
Report( wxString::Format( wxT(
"Polyline's owner (%d) not found." ),
1924 symbol = libSymbolIt->second;
1925 schsym =
m_symbols.at( libSymbolIt->first );
1954 std::vector<LIB_SYMBOL*>& aSymbol )
1989 m_reporter->
Report( wxString::Format( wxT(
"Polygon's owner (%d) not found." ),
1995 symbol = libSymbolIt->second;
1996 schsym =
m_symbols.at( libSymbolIt->first );
2037 std::vector<LIB_SYMBOL*>& aSymbol )
2071 m_reporter->
Report( wxString::Format( wxT(
"Rounded rectangle's owner (%d) not "
2078 symbol = libSymbolIt->second;
2079 schsym =
m_symbols.at( libSymbolIt->first );
2097 int radius = std::min( width / 2, height / 2 );
2133 std::vector<LIB_SYMBOL*>& aSymbol )
2149 wxCHECK( currentScreen, );
2161 currentScreen->
Append( circle );
2174 currentScreen->
Append( arc );
2191 m_reporter->
Report( wxString::Format( wxT(
"Arc's owner (%d) not found." ),
2197 symbol = libSymbolIt->second;
2198 schsym =
m_symbols.at( libSymbolIt->first );
2230 arc->
SetStart( center + startOffset );
2231 arc->
SetEnd( center + endOffset );
2241 std::vector<LIB_SYMBOL*>& aSymbol )
2248 wxCHECK( currentScreen, );
2254 std::vector<BEZIER<int>> beziers;
2261 schbezier->
SetStart( bezier.Start );
2264 schbezier->
SetEnd( bezier.End );
2268 currentScreen->
Append( schbezier );
2285 m_reporter->
Report( wxString::Format( wxT(
"Elliptical Arc's owner (%d) not found." ),
2291 symbol = libSymbolIt->second;
2292 schsym =
m_symbols.at( libSymbolIt->first );
2302 std::vector<BEZIER<int>> beziers;
2322 schbezier->
SetStart( bezier.Start );
2325 schbezier->
SetEnd( bezier.End );
2328 SetLibShapeLine( elem, schbezier, ALTIUM_SCH_RECORD::ELLIPTICAL_ARC );
2336 std::vector<LIB_SYMBOL*>& aSymbol )
2385 m_reporter->
Report( wxString::Format( wxT(
"Piechart's owner (%d) not found." ),
2391 symbol = libSymbolIt->second;
2392 schsym =
m_symbols.at( libSymbolIt->first );
2405 line->
AddPoint( center + startOffset );
2407 line->
AddPoint( center + endOffset );
2422 std::vector<LIB_SYMBOL*>& aSymbol )
2442 FILL_T fillMode = elem.
IsSolid ? FILL_T::FILLED_WITH_COLOR : FILL_T::NO_FILL;
2447 std::vector<BEZIER<int>> beziers;
2448 std::vector<VECTOR2I> polyPoints;
2455 schbezier->
SetStart( bezier.Start );
2458 schbezier->
SetEnd( bezier.End );
2464 screen->
Append( schbezier );
2466 polyPoints.push_back( bezier.Start );
2469 if( fillMode != FILL_T::NO_FILL )
2476 for(
const VECTOR2I& point : polyPoints )
2479 schpoly->
AddPoint( polyPoints[0] );
2481 screen->
Append( schpoly );
2498 m_reporter->
Report( wxString::Format( wxT(
"Ellipse's owner (%d) not found." ),
2504 symbol = libSymbolIt->second;
2505 schsym =
m_symbols.at( libSymbolIt->first );
2511 std::vector<BEZIER<int>> beziers;
2512 std::vector<VECTOR2I> polyPoints;
2524 libbezier->
SetStart( bezier.Start );
2527 libbezier->
SetEnd( bezier.End );
2541 polyPoints.push_back( libbezier->
GetStart() );
2552 for(
const VECTOR2I& point : polyPoints )
2555 libline->
AddPoint( polyPoints[0] );
2565 std::vector<LIB_SYMBOL*>& aSymbol )
2587 screen->
Append( circle );
2603 m_reporter->
Report( wxString::Format( wxT(
"Ellipse's owner (%d) not found." ),
2609 symbol = libSymbolIt->second;
2610 schsym =
m_symbols.at( libSymbolIt->first );
2632 std::vector<LIB_SYMBOL*>& aSymbol )
2665 m_reporter->
Report( wxString::Format( wxT(
"Line's owner (%d) not found." ),
2671 symbol = libSymbolIt->second;
2672 schsym =
m_symbols.at( libSymbolIt->first );
2723 m_reporter->
Report( wxT(
"Signal harness, belonging to the part is not currently "
2730 wxString>& aProperties )
2737 wxCHECK( currentScreen, );
2746 currentScreen->
Append( sheet );
2759 m_reporter->
Report( wxT(
"Harness connector, belonging to the part is not currently "
2774 m_reporter->
Report( wxString::Format( wxT(
"Harness entry's parent (%d) not found." ),
2781 sheetIt->second->AddPin( sheetPin );
2784 sheetPin->
SetShape( LABEL_FLAG_SHAPE::L_UNSPECIFIED );
2786 VECTOR2I pos = sheetIt->second->GetPosition();
2787 VECTOR2I size = sheetIt->second->GetSize();
2792 case ASCH_SHEET_ENTRY_SIDE::LEFT:
2795 sheetPin->
SetSide( SHEET_SIDE::LEFT );
2797 case ASCH_SHEET_ENTRY_SIDE::RIGHT:
2800 sheetPin->
SetSide( SHEET_SIDE::RIGHT );
2802 case ASCH_SHEET_ENTRY_SIDE::TOP:
2805 sheetPin->
SetSide( SHEET_SIDE::TOP );
2807 case ASCH_SHEET_ENTRY_SIDE::BOTTOM:
2810 sheetPin->
SetSide( SHEET_SIDE::BOTTOM );
2824 m_reporter->
Report( wxString::Format( wxT(
"Harness type's parent (%d) not found." ),
2838 ASCH_RECORD_ORIENTATION::RIGHTWARDS );
2846 wxString fullPath = fn.GetFullPath();
2848 fullPath.Replace( wxT(
"\\" ), wxT(
"/" ) );
2850 SCH_SCREEN* screen = sheetIt->second->GetScreen();
2855 m_reporter->
Report( wxString::Format(
_(
"Altium's harness connector (%s) was imported as a "
2856 "hierarchical sheet. Please review the imported "
2864 std::vector<LIB_SYMBOL*>& aSymbol )
2879 rect->
SetEnd( sheetBottomLeft );
2900 m_reporter->
Report( wxString::Format( wxT(
"Rectangle's owner (%d) not found." ),
2906 symbol = libSymbolIt->second;
2907 schsym =
m_symbols.at( libSymbolIt->first );
2921 rect->
SetEnd( sheetBottomLeft );
2949 wxCHECK( currentScreen, );
2950 currentScreen->
Append( sheet );
2959 wxCHECK( rootScreen, );
2967 m_sheets.insert( { aIndex, sheet } );
2979 m_reporter->
Report( wxString::Format( wxT(
"Sheet entry's owner (%d) not found." ),
2986 sheetIt->second->AddPin( sheetPin );
2989 sheetPin->
SetShape( LABEL_FLAG_SHAPE::L_UNSPECIFIED );
2993 VECTOR2I pos = sheetIt->second->GetPosition();
2994 VECTOR2I size = sheetIt->second->GetSize();
2999 case ASCH_SHEET_ENTRY_SIDE::LEFT:
3002 sheetPin->
SetSide( SHEET_SIDE::LEFT );
3005 case ASCH_SHEET_ENTRY_SIDE::RIGHT:
3008 sheetPin->
SetSide( SHEET_SIDE::RIGHT );
3011 case ASCH_SHEET_ENTRY_SIDE::TOP:
3014 sheetPin->
SetSide( SHEET_SIDE::TOP );
3017 case ASCH_SHEET_ENTRY_SIDE::BOTTOM:
3020 sheetPin->
SetSide( SHEET_SIDE::BOTTOM );
3027 case ASCH_PORT_IOTYPE::UNSPECIFIED:
3028 sheetPin->
SetShape( LABEL_FLAG_SHAPE::L_UNSPECIFIED );
3031 case ASCH_PORT_IOTYPE::OUTPUT:
3032 sheetPin->
SetShape( LABEL_FLAG_SHAPE::L_OUTPUT );
3035 case ASCH_PORT_IOTYPE::INPUT:
3036 sheetPin->
SetShape( LABEL_FLAG_SHAPE::L_INPUT );
3039 case ASCH_PORT_IOTYPE::BIDI:
3040 sheetPin->
SetShape( LABEL_FLAG_SHAPE::L_BIDI );
3231 aReporter->
Report(
_(
"Power Port with unknown style imported as 'Bar' type." ),
3256 wxString symName( elem.
text );
3257 std::string styleName( magic_enum::enum_name<ASCH_POWER_PORT_STYLE>( elem.
style ) );
3259 if( !styleName.empty() )
3260 symName <<
'_' << styleName;
3269 libSymbol = powerSymbolIt->second;
3274 libSymbol = alreadyLoaded;
3285 libSymbol->
SetDescription( wxString::Format(
_(
"Power symbol creates a global "
3286 "label with name '%s'" ), elem.
text ) );
3295 pin->SetPosition( { 0, 0 } );
3296 pin->SetLength( 0 );
3297 pin->SetType( ELECTRICAL_PINTYPE::PT_POWER_IN );
3298 pin->SetVisible(
false );
3331 case ASCH_RECORD_ORIENTATION::RIGHTWARDS:
3337 case ASCH_RECORD_ORIENTATION::UPWARDS:
3343 case ASCH_RECORD_ORIENTATION::LEFTWARDS:
3349 case ASCH_RECORD_ORIENTATION::DOWNWARDS:
3360 screen->
Append( symbol );
3371 int height = aElem.
Height;
3381 textBox->
SetFillMode( FILL_T::FILLED_WITH_COLOR );
3389 case ASCH_TEXT_FRAME_ALIGNMENT::LEFT:
3393 case ASCH_TEXT_FRAME_ALIGNMENT::CENTER:
3397 case ASCH_TEXT_FRAME_ALIGNMENT::RIGHT:
3402 size_t fontId =
static_cast<int>( aElem.
FontID );
3420 screen->
Append( textBox );
3422 m_reporter->
Report( wxString::Format(
_(
"Altium's harness port (%s) was imported as "
3423 "a text box. Please review the imported "
3442 switch( aElem.
Style )
3445 case ASCH_PORT_STYLE::NONE_HORIZONTAL:
3446 case ASCH_PORT_STYLE::LEFT:
3447 case ASCH_PORT_STYLE::RIGHT:
3448 case ASCH_PORT_STYLE::LEFT_RIGHT:
3452 case ASCH_PORT_STYLE::NONE_VERTICAL:
3453 case ASCH_PORT_STYLE::TOP:
3454 case ASCH_PORT_STYLE::BOTTOM:
3455 case ASCH_PORT_STYLE::TOP_BOTTOM:
3472 bool connectionFound = startIsWireTerminal
3473 || startIsBusTerminal
3474 || endIsWireTerminal
3475 || endIsBusTerminal;
3477 if( !connectionFound )
3484 VECTOR2I position = ( startIsWireTerminal || startIsBusTerminal ) ? start : end;
3499 case ASCH_PORT_IOTYPE::UNSPECIFIED: label->
SetShape( LABEL_FLAG_SHAPE::L_UNSPECIFIED );
break;
3500 case ASCH_PORT_IOTYPE::OUTPUT: label->
SetShape( LABEL_FLAG_SHAPE::L_OUTPUT );
break;
3501 case ASCH_PORT_IOTYPE::INPUT: label->
SetShape( LABEL_FLAG_SHAPE::L_INPUT );
break;
3502 case ASCH_PORT_IOTYPE::BIDI: label->
SetShape( LABEL_FLAG_SHAPE::L_BIDI );
break;
3505 switch( aElem.
Style )
3508 case ASCH_PORT_STYLE::NONE_HORIZONTAL:
3509 case ASCH_PORT_STYLE::LEFT:
3510 case ASCH_PORT_STYLE::RIGHT:
3511 case ASCH_PORT_STYLE::LEFT_RIGHT:
3512 if( ( startIsWireTerminal || startIsBusTerminal ) )
3519 case ASCH_PORT_STYLE::NONE_VERTICAL:
3520 case ASCH_PORT_STYLE::TOP:
3521 case ASCH_PORT_STYLE::BOTTOM:
3522 case ASCH_PORT_STYLE::TOP_BOTTOM:
3523 if( ( startIsWireTerminal || startIsBusTerminal ) )
3535 label->
GetFields()[0].SetVisible(
false );
3542 if( ( startIsWireTerminal && endIsWireTerminal ) )
3550 else if( startIsBusTerminal && endIsBusTerminal )
3573 screen->
Append( noConnect );
3601 for(
size_t i = 0; i + 1 < elem.
points.size(); i++ )
3604 SCH_LAYER_ID::LAYER_BUS );
3621 for(
size_t i = 0; i + 1 < elem.
points.size(); i++ )
3624 SCH_LAYER_ID::LAYER_WIRE );
3644 screen->
Append( junction );
3656 && component->second.currentpartid != elem.
ownerpartid )
3660 std::unique_ptr<SCH_BITMAP> bitmap = std::make_unique<SCH_BITMAP>( center );
3671 wxString msg = wxString::Format(
_(
"Embedded file %s not found in storage." ),
3677 wxString storagePath = wxFileName::CreateTempFileName(
"kicad_import_" );
3680 wxMemoryInputStream fileStream( storageFile->
data.data(), storageFile->
data.size() );
3681 wxZlibInputStream zlibInputStream( fileStream );
3682 wxFFileOutputStream outputStream( storagePath );
3683 outputStream.Write( zlibInputStream );
3684 outputStream.Close();
3686 if( !bitmap->ReadImageFile( storagePath ) )
3688 m_reporter->
Report( wxString::Format(
_(
"Error reading image %s." ), storagePath ),
3694 wxRemoveFile( storagePath );
3698 if( !wxFileExists( elem.
filename ) )
3705 if( !bitmap->ReadImageFile( elem.
filename ) )
3714 VECTOR2I currentImageSize = bitmap->GetSize();
3716 double scaleX =
std::abs(
static_cast<double>( expectedImageSize.
x ) / currentImageSize.
x );
3717 double scaleY =
std::abs(
static_cast<double>( expectedImageSize.
y ) / currentImageSize.
y );
3718 bitmap->SetImageScale( std::min( scaleX, scaleY ) );
3720 bitmap->SetFlags(
IS_NEW );
3721 screen->
Append( bitmap.release() );
3727 m_altiumSheet = std::make_unique<ASCH_SHEET>( aProperties );
3734 bool isPortrait =
m_altiumSheet->sheetOrientation == ASCH_SHEET_WORKSPACEORIENTATION::PORTRAIT;
3747 case ASCH_SHEET_SIZE::A4: pageInfo.
SetType(
"A4", isPortrait );
break;
3748 case ASCH_SHEET_SIZE::A3: pageInfo.
SetType(
"A3", isPortrait );
break;
3749 case ASCH_SHEET_SIZE::A2: pageInfo.
SetType(
"A2", isPortrait );
break;
3750 case ASCH_SHEET_SIZE::A1: pageInfo.
SetType(
"A1", isPortrait );
break;
3751 case ASCH_SHEET_SIZE::A0: pageInfo.
SetType(
"A0", isPortrait );
break;
3752 case ASCH_SHEET_SIZE::A: pageInfo.
SetType(
"A", isPortrait );
break;
3753 case ASCH_SHEET_SIZE::B: pageInfo.
SetType(
"B", isPortrait );
break;
3754 case ASCH_SHEET_SIZE::C: pageInfo.
SetType(
"C", isPortrait );
break;
3755 case ASCH_SHEET_SIZE::D: pageInfo.
SetType(
"D", isPortrait );
break;
3756 case ASCH_SHEET_SIZE::E: pageInfo.
SetType(
"E", isPortrait );
break;
3757 case ASCH_SHEET_SIZE::LETTER: pageInfo.
SetType(
"USLetter", isPortrait );
break;
3758 case ASCH_SHEET_SIZE::LEGAL: pageInfo.
SetType(
"USLegal", isPortrait );
break;
3759 case ASCH_SHEET_SIZE::TABLOID: pageInfo.
SetType(
"A3", isPortrait );
break;
3760 case ASCH_SHEET_SIZE::ORCAD_A: pageInfo.
SetType(
"A", isPortrait );
break;
3761 case ASCH_SHEET_SIZE::ORCAD_B: pageInfo.
SetType(
"B", isPortrait );
break;
3762 case ASCH_SHEET_SIZE::ORCAD_C: pageInfo.
SetType(
"C", isPortrait );
break;
3763 case ASCH_SHEET_SIZE::ORCAD_D: pageInfo.
SetType(
"D", isPortrait );
break;
3764 case ASCH_SHEET_SIZE::ORCAD_E: pageInfo.
SetType(
"E", isPortrait );
break;
3782 m_reporter->
Report( wxString::Format( wxT(
"Sheetname's owner (%d) not found." ),
3805 m_reporter->
Report( wxString::Format( wxT(
"Filename's owner (%d) not found." ),
3831 m_reporter->
Report( wxString::Format( wxT(
"Designator's owner (%d) not found." ),
3845 bool emptyRef = elem.
text.IsEmpty();
3850 bool visible = !emptyRef;
3862 std::vector<LIB_SYMBOL*>& aSymbol,
3863 std::vector<int>& aFontSizes )
3870 bool emptyRef = elem.
text.IsEmpty();
3871 SCH_FIELD& refField = symbol->GetReferenceField();
3874 refField.
SetText( wxT(
"X" ) );
3880 if( elem.
fontId > 0 && elem.
fontId <=
static_cast<int>( aFontSizes.size() ) )
3882 int size = aFontSizes[elem.
fontId - 1];
3899 busWireEntry->
SetSize( { vector.
x, vector.
y } );
3902 screen->
Append( busWireEntry );
3911 static const std::map<wxString, wxString> variableMap = {
3912 {
"COMMENT",
"VALUE" },
3913 {
"VALUE",
"ALTIUM_VALUE" },
3919 if( elem.
text ==
"*" )
3922 wxString paramName = elem.
name.Upper();
3924 if( paramName ==
"SHEETNUMBER" )
3928 else if( paramName ==
"TITLE" )
3932 else if( paramName ==
"REVISION" )
3936 else if( paramName ==
"DATE" )
3940 else if( paramName ==
"COMPANYNAME" )
3961 wxString upperName = elem.
name.Upper();
3963 if( upperName ==
"COMMENT" )
3970 wxString fieldName = elem.
name.Upper();
3974 if( fieldName.IsEmpty() )
3976 int disambiguate = 1;
3980 fieldName = wxString::Format(
"ALTIUM_UNNAMED_%d", disambiguate++ );
3987 else if( fieldName ==
"VALUE" )
3989 fieldName =
"ALTIUM_VALUE";
4005 std::vector<LIB_SYMBOL*>& aSymbol,
4006 std::vector<int>& aFontSizes )
4027 std::map<wxString, wxString> variableMap = {
4028 {
"COMMENT",
"VALUE" },
4034 wxString upperName = elem.
name.Upper();
4036 if( upperName ==
"COMMENT" )
4038 field = &libSymbol->GetValueField();
4042 int fieldIdx = libSymbol->GetFieldCount();
4043 wxString fieldNameStem = elem.
name;
4044 wxString fieldName = fieldNameStem;
4045 int disambiguate = 1;
4047 if( fieldName.IsEmpty() )
4049 fieldNameStem =
"ALTIUM_UNNAMED";
4050 fieldName =
"ALTIUM_UNNAMED_1";
4053 else if( upperName ==
"VALUE" )
4055 fieldNameStem =
"ALTIUM_VALUE";
4056 fieldName =
"ALTIUM_VALUE";
4060 while( libSymbol->FindField( fieldName ) )
4061 fieldName = wxString::Format(
"%s_%d", fieldNameStem, disambiguate++ );
4064 libSymbol->AddField( new_field );
4075 if( elem.
fontId > 0 && elem.
fontId <=
static_cast<int>( aFontSizes.size() ) )
4077 int size = aFontSizes[elem.
fontId - 1];
4085 const std::map<wxString, wxString>& aProperties )
4094 std::vector<LIB_SYMBOL*>& aSymbol )
4098 if( elem.
type != wxS(
"PCBLIB" ) )
4102 if( aSymbol.size() == 0 && !elem.
isCurrent )
4108 wxArrayString fpFilters;
4109 fpFilters.Add( wxString::Format( wxS(
"*%s*" ), elem.
name ) );
4112 if( !aSymbol.empty() )
4118 symbol->SetFPFilters( fpFilters );
4119 SCH_FIELD& footprintField = symbol->GetFootprintField();
4130 m_reporter->
Report( wxString::Format( wxT(
"Implementation's owner (%d) not found." ),
4136 const auto& libSymbolIt =
m_libSymbols.find( implementationOwnerIt->second );
4140 m_reporter->
Report( wxString::Format( wxT(
"Footprint's owner (%d) not found." ),
4141 implementationOwnerIt->second ),
4148 libSymbolIt->second->SetFPFilters( fpFilters );
4158 wxString>& aProperties )
4162 std::vector<LIB_SYMBOL*> symbols;
4180 symbols.push_back( symbol );
4189 std::map<wxString,LIB_SYMBOL*> ret;
4190 std::vector<int> fontSizes;
4194 std::map<wxString, const CFB::COMPOUND_FILE_ENTRY*> syms = aAltiumLibFile.
GetLibSymbols(
nullptr );
4196 for(
auto& [
name, entry] : syms )
4199 std::vector<LIB_SYMBOL*> symbols;
4207 std::map<wxString, wxString> properties = reader.
ReadProperties();
4211 if( record != ALTIUM_SCH_RECORD::COMPONENT )
4212 THROW_IO_ERROR(
"LibSymbol does not start with COMPONENT record" );
4217 auto handleBinaryDataLambda =
4218 [](
const std::string& binaryData ) -> std::map<wxString, wxString>
4221 std::map<wxString, wxString> result;
4225 int32_t recordId = binreader.
ReadInt32();
4227 if( recordId !=
static_cast<int32_t
>( ALTIUM_SCH_RECORD::PIN ) )
4230 result[
"RECORD"] = wxString::Format(
"%d", recordId );
4232 result[
"OWNERPARTID"] = wxString::Format(
"%d", binreader.
ReadInt16() );
4233 result[
"OWNERPARTDISPLAYMODE"] = wxString::Format(
"%d", binreader.
ReadByte() );
4234 result[
"SYMBOL_INNEREDGE"] = wxString::Format(
"%d", binreader.
ReadByte() );
4235 result[
"SYMBOL_OUTEREDGE"] = wxString::Format(
"%d", binreader.
ReadByte() );
4236 result[
"SYMBOL_INNER"] = wxString::Format(
"%d", binreader.
ReadByte() );
4237 result[
"SYMBOL_OUTER"] = wxString::Format(
"%d", binreader.
ReadByte() );
4240 result[
"ELECTRICAL"] = wxString::Format(
"%d", binreader.
ReadByte() );
4241 result[
"PINCONGLOMERATE"] = wxString::Format(
"%d", binreader.
ReadByte() );
4242 result[
"PINLENGTH"] = wxString::Format(
"%d", binreader.
ReadInt16() );
4243 result[
"LOCATION.X"] = wxString::Format(
"%d", binreader.
ReadInt16() );
4244 result[
"LOCATION.Y"] = wxString::Format(
"%d", binreader.
ReadInt16() );
4245 result[
"COLOR"] = wxString::Format(
"%d", binreader.
ReadInt32() );
4252 std::vector<std::string> partSeqSplit =
split( partSeq,
"|" );
4254 if( partSeqSplit.size() == 3 )
4256 result[
"PART"] = partSeqSplit[0];
4257 result[
"SEQ"] = partSeqSplit[2];
4265 std::map<wxString, wxString> properties = reader.
ReadProperties( handleBinaryDataLambda );
4267 if( properties.empty() )
4275 case ALTIUM_SCH_RECORD::PIN:
ParsePin( properties, symbols );
break;
4277 case ALTIUM_SCH_RECORD::LABEL:
ParseLabel( properties, symbols, fontSizes );
break;
4279 case ALTIUM_SCH_RECORD::BEZIER:
ParseBezier( properties, symbols );
break;
4281 case ALTIUM_SCH_RECORD::POLYLINE:
ParsePolyline( properties, symbols );
break;
4283 case ALTIUM_SCH_RECORD::POLYGON:
ParsePolygon( properties, symbols );
break;
4285 case ALTIUM_SCH_RECORD::ELLIPSE:
ParseEllipse( properties, symbols );
break;
4287 case ALTIUM_SCH_RECORD::PIECHART:
ParsePieChart( properties, symbols );
break;
4289 case ALTIUM_SCH_RECORD::ROUND_RECTANGLE:
ParseRoundRectangle( properties, symbols );
break;
4291 case ALTIUM_SCH_RECORD::ELLIPTICAL_ARC:
ParseEllipticalArc( properties, symbols );
break;
4293 case ALTIUM_SCH_RECORD::ARC:
ParseArc( properties, symbols );
break;
4295 case ALTIUM_SCH_RECORD::LINE:
ParseLine( properties, symbols );
break;
4297 case ALTIUM_SCH_RECORD::RECTANGLE:
ParseRectangle( properties, symbols );
break;
4299 case ALTIUM_SCH_RECORD::DESIGNATOR:
ParseLibDesignator( properties, symbols, fontSizes );
break;
4301 case ALTIUM_SCH_RECORD::PARAMETER:
ParseLibParameter( properties, symbols, fontSizes );
break;
4303 case ALTIUM_SCH_RECORD::TEXT_FRAME:
ParseTextFrame( properties, symbols, fontSizes );
break;
4306 case ALTIUM_SCH_RECORD::IMPLEMENTATION_LIST:
break;
4308 case ALTIUM_SCH_RECORD::IMPLEMENTATION:
ParseImplementation( properties, symbols );
break;
4310 case ALTIUM_SCH_RECORD::IMPL_PARAMS:
break;
4312 case ALTIUM_SCH_RECORD::MAP_DEFINER_LIST:
break;
4313 case ALTIUM_SCH_RECORD::MAP_DEFINER:
break;
4316 case ALTIUM_SCH_RECORD::IEEE_SYMBOL:
break;
4319 case ALTIUM_SCH_RECORD::IMAGE:
break;
4322 m_reporter->
Report( wxString::Format(
_(
"Unknown or unexpected record id %d found "
4324 recordId, symbols[0]->
GetName() ),
4336 for(
size_t ii = 0; ii < symbols.size(); ii++ )
4343 if( valField.
GetText().IsEmpty() )
4346 if( symbols.size() == 1 )
4349 ret[wxString::Format(
"%s (Altium Display %zd)",
name, ii + 1 )] = symbol;
4359 wxFileName fn( aLibraryPath );
4361 if( fn.IsFileReadable() && fn.GetModificationTime().IsValid() )
4362 return fn.GetModificationTime().GetValue().GetValue();
4364 return wxDateTime( 0.0 ).GetValue().GetValue();
4379 std::vector<std::unique_ptr<ALTIUM_COMPOUND_FILE>> compoundFiles;
4381 wxFileName fileName( aLibraryPath );
4386 if( aLibraryPath.Lower().EndsWith( wxS(
".schlib" ) ) )
4390 compoundFiles.push_back( std::make_unique<ALTIUM_COMPOUND_FILE>( aLibraryPath ) );
4392 else if( aLibraryPath.Lower().EndsWith( wxS(
".intlib" ) ) )
4396 std::unique_ptr<ALTIUM_COMPOUND_FILE> intCom =
4397 std::make_unique<ALTIUM_COMPOUND_FILE>( aLibraryPath );
4399 std::map<wxString, const CFB::COMPOUND_FILE_ENTRY*> schLibFiles =
4400 intCom->EnumDir( L
"SchLib" );
4402 for(
const auto& [schLibName, cfe] : schLibFiles )
4403 compoundFiles.push_back( intCom->DecodeIntLibStream( *cfe ) );
4406 std::map<wxString, LIB_SYMBOL*>& cacheMapRef =
m_libCache[aLibraryPath];
4408 for(
auto& altiumSchFilePtr : compoundFiles )
4410 std::map<wxString, LIB_SYMBOL*> parsed =
ParseLibFile( *altiumSchFilePtr );
4411 cacheMapRef.insert( parsed.begin(), parsed.end() );
4416 catch(
const CFB::CFBException& exception )
4420 catch(
const std::exception& exc )
4422 wxFAIL_MSG( wxString::Format( wxT(
"Unhandled exception in Altium schematic parsers: %s." ),
4430 std::vector<int>& aFontSizes )
4432 const CFB::COMPOUND_FILE_ENTRY* file = aAltiumSchFile.
FindStream( {
"FileHeader" } );
4434 if( file ==
nullptr )
4444 std::map<wxString, wxString> properties = reader.
ReadProperties();
4448 if( libtype.CmpNoCase(
"Protel for Windows - Schematic Library Editor Binary File Version 5.0" ) )
4449 THROW_IO_ERROR(
_(
"Expected Altium Schematic Library file version 5.0" ) );
4451 for(
auto& [key, value] : properties )
4453 wxString upperKey = key.Upper();
4456 if( upperKey.StartsWith(
"SIZE", &remaining ) )
4458 if( !remaining.empty() )
4460 int ind = wxAtoi( remaining );
4462 if(
static_cast<int>( aFontSizes.size() ) < ind )
4463 aFontSizes.resize( ind );
4467 aFontSizes[ind - 1] = scaled;
4477 std::function<
void(
const wxString&,
LIB_SYMBOL*)> aInserter )
4481 bool powerSymbolsOnly = ( aProperties &&
4483 != aProperties->end() );
4489 for(
auto& [libnameStr, libSymbol] : it->second )
4491 if( powerSymbolsOnly && !libSymbol->IsPower() )
4494 aInserter( libnameStr, libSymbol );
4501 const wxString& aLibraryPath,
4507 aSymbolNameList.Add( aStr );
4513 const wxString& aLibraryPath,
4519 aSymbolList.emplace_back( aSymbol );
4525 const wxString& aAliasName,
4534 auto it2 = it->second.find( aAliasName );
4536 if( it2 != it->second.end() )
const int ALTIUM_COMPONENT_NONE
wxString AltiumSchSpecialStringsToKiCadVariables(const wxString &aString, const std::map< wxString, wxString > &aOverrides)
wxString AltiumPinNamesToKiCad(wxString &aString)
LIB_ID AltiumToKiCadLibID(const wxString &aLibName, const wxString &aLibReference)
constexpr EDA_IU_SCALE schIUScale
void TransformEllipseToBeziers(const ELLIPSE< T > &aEllipse, std::vector< BEZIER< T > > &aBeziers)
Transforms an ellipse or elliptical arc into a set of quadratic Bezier curves that approximate it.
std::map< wxString, wxString > ReadProperties()
size_t GetRemainingBytes() const
std::map< wxString, wxString > ReadProperties(std::function< std::map< wxString, wxString >(const std::string &)> handleBinaryData=[](const std::string &) { return std::map< wxString, wxString >();})
std::string ReadPascalString()
std::map< wxString, const CFB::COMPOUND_FILE_ENTRY * > GetLibSymbols(const CFB::COMPOUND_FILE_ENTRY *aStart) const
const CFB::COMPOUND_FILE_ENTRY * FindStream(const std::vector< std::string > &aStreamPath) const
static int ReadInt(const std::map< wxString, wxString > &aProps, const wxString &aKey, int aDefault)
static wxString ReadString(const std::map< wxString, wxString > &aProps, const wxString &aKey, const wxString &aDefault)
Bezier curves to polygon converter.
void GetPoly(std::vector< VECTOR2I > &aOutput, int aMinSegLen=0, int aMaxSegCount=32)
Convert a Bezier curve to a polygon.
Generic cubic Bezier representation.
void SetFlags(EDA_ITEM_FLAGS aMask)
void SetBezierC2(const VECTOR2I &aPt)
void SetCenter(const VECTOR2I &aCenter)
FILL_T GetFillMode() const
void RebuildBezierToSegmentsPointsList(int aMinSegLen)
Rebuild the m_bezierPoints vertex list that approximate the Bezier curve by a list of segments.
void SetLineStyle(const LINE_STYLE aStyle)
void SetFilled(bool aFlag)
void SetFillColor(const COLOR4D &aColor)
void SetStart(const VECTOR2I &aStart)
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
COLOR4D GetFillColor() const
void SetEnd(const VECTOR2I &aEnd)
void SetBezierC1(const VECTOR2I &aPt)
virtual int GetWidth() const
void SetWidth(int aWidth)
void SetFillMode(FILL_T aFill)
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
void SetTextColor(const COLOR4D &aColor)
void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
virtual const wxString & GetText() const
Return the string associated with the text object.
void SetTextPos(const VECTOR2I &aPoint)
virtual void SetVisible(bool aVisible)
virtual void SetText(const wxString &aText)
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
void SetItalic(bool aItalic)
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
EE_TYPE OfType(KICAD_T aType) const
This class was created to handle importing ellipses from other file formats that support them nativel...
const wxString & GetName() const
Return a brief hard coded name for this IO interface.
REPORTER * m_reporter
Reporter to log errors/warnings to, may be nullptr.
virtual bool CanReadLibrary(const wxString &aFileName) const
Checks if this IO object can read the specified library file/directory.
A color representation with 4 components: red, green, blue, alpha.
COLOR4D WithAlpha(double aAlpha) const
Return a color with the same color, but the given alpha.
static const COLOR4D UNSPECIFIED
For legacy support; used as a value to indicate color hasn't been set yet.
COLOR4D & FromCSSRGBA(int aRed, int aGreen, int aBlue, double aAlpha=1.0)
Initialize the color from a RGBA value with 0-255 red/green/blue and 0-1 alpha.
A logical library item identifier and consists of various portions much like a URI.
static UTF8 FixIllegalChars(const UTF8 &aLibItemName, bool aLib)
Replace illegal LIB_ID item name characters with underscores '_'.
Define a library symbol object.
void SetUnitCount(int aCount, bool aDuplicateDrawItems=true)
Set the units per symbol count.
SCH_FIELD & GetValueField() const
Return reference to the value field.
void FixupDrawItems()
This function finds the filled draw items that are covering up smaller draw items and replaces their ...
wxString GetName() const override
void SetDescription(const wxString &aDescription)
Gets the Description field text value */.
void SetKeyWords(const wxString &aKeyWords)
SCH_FIELD & GetReferenceField() const
Return reference to the reference designator field.
void SetLibId(const LIB_ID &aLibId)
void AddDrawItem(SCH_ITEM *aItem, bool aSort=true)
Add a new draw aItem to the draw object list and sort according to aSort.
virtual void SetName(const wxString &aName)
bool HasLibrary(const wxString &aNickname, bool aCheckEnabled=false) const
Test for the existence of aNickname in the library table.
bool InsertRow(LIB_TABLE_ROW *aRow, bool doReplace=false)
Adds aRow if it does not already exist or if doReplace is true.
Describe the page size and margins of a paper page on which to eventually print or plot.
int GetHeightIU(double aIUScale) const
Gets the page height in IU.
static void SetCustomWidthMils(double aWidthInMils)
Set the width of Custom page in mils for any custom page constructed or made via SetType() after maki...
static const wxChar Custom[]
"User" defined page type
static void SetCustomHeightMils(double aHeightInMils)
Set the height of Custom page in mils for any custom page constructed or made via SetType() after mak...
bool SetType(const wxString &aStandardPageDescriptionName, bool aIsPortrait=false)
Set the name of the page type and also the sizes and margins commonly associated with that type name.
std::shared_ptr< NET_SETTINGS > & NetSettings()
static SYMBOL_LIB_TABLE * SchSymbolLibTable(PROJECT *aProject)
Accessor for project symbol library table.
virtual const wxString GetProjectPath() const
Return the full path of the project.
virtual const wxString GetProjectName() const
Return the short name of the project.
virtual PROJECT_FILE & GetProjectFile() const
virtual void SetElem(ELEM_T aIndex, _ELEM *aElem)
virtual std::map< wxString, wxString > & GetTextVars() const
A pure virtual class used to derive REPORTER objects from.
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)=0
Report a string with a given severity.
Holds all the data relating to one schematic.
void SetRoot(SCH_SHEET *aRootSheet)
Initialize the schematic with a new root sheet.
bool IsValid() const
A simple test if the schematic is loaded, not a complete one.
PROJECT & Prj() const override
Return a reference to the project this schematic is part of.
void SetSize(const VECTOR2I &aSize)
Class for a wire to bus entry.
Instances are attached to a symbol or sheet and provide a place for the symbol's value,...
VECTOR2I GetPosition() const override
void SetPosition(const VECTOR2I &aPosition) override
void SetText(const wxString &aText) override
void SetSpinStyle(SPIN_STYLE aSpinStyle) override
void ParseFileHeader(const ALTIUM_COMPOUND_FILE &aAltiumSchFile)
void ParseSignalHarness(const std::map< wxString, wxString > &aProperties)
std::map< int, ASCH_TEMPLATE > m_altiumTemplates
std::map< int, ASCH_SYMBOL > m_altiumComponents
void ParsePort(const ASCH_PORT &aElem)
bool IsComponentPartVisible(const ASCH_OWNER_INTERFACE &aElem) const
void ParseNote(const std::map< wxString, wxString > &aProperties)
void ParseAltiumSch(const wxString &aFileName)
std::vector< ASCH_PORT > m_altiumPortsCurrentSheet
void ParseSheetName(const std::map< wxString, wxString > &aProperties)
void ParseBusEntry(const std::map< wxString, wxString > &aProperties)
SCH_SHEET * getCurrentSheet()
void ParseStorage(const ALTIUM_COMPOUND_FILE &aAltiumSchFile)
std::map< wxString, LIB_SYMBOL * > m_powerSymbols
void ParseBus(const std::map< wxString, wxString > &aProperties)
void ParseFileName(const std::map< wxString, wxString > &aProperties)
static bool isASCIIFile(const wxString &aFileName)
std::map< int, SCH_SHEET * > m_sheets
void ParseLibHeader(const ALTIUM_COMPOUND_FILE &aAltiumSchFile, std::vector< int > &aFontSizes)
void ParseHarnessPort(const ASCH_PORT &aElem)
void ParseRoundRectangle(const std::map< wxString, wxString > &aProperties, std::vector< LIB_SYMBOL * > &aSymbol=nullsym)
int GetModifyHash() const override
Return the modification hash from the library cache.
void ParseLibDesignator(const std::map< wxString, wxString > &aProperties, std::vector< LIB_SYMBOL * > &aSymbol=nullsym, std::vector< int > &aFontSize=nullint)
std::map< int, int > m_altiumImplementationList
void ParseTextFrame(const std::map< wxString, wxString > &aProperties, std::vector< LIB_SYMBOL * > &aSymbol=nullsym, std::vector< int > &aFontSize=nullint)
void ParsePolygon(const std::map< wxString, wxString > &aProperties, std::vector< LIB_SYMBOL * > &aSymbol=nullsym)
void EnumerateSymbolLib(wxArrayString &aSymbolNameList, const wxString &aLibraryPath, const STRING_UTF8_MAP *aProperties=nullptr) override
Populate a list of LIB_SYMBOL alias names contained within the library aLibraryPath.
void ParseRecord(int index, std::map< wxString, wxString > &properties, const wxString &aSectionName)
std::vector< ASCH_PORT > m_altiumHarnessPortsCurrentSheet
std::unique_ptr< STRING_UTF8_MAP > m_properties
void ParseDesignator(const std::map< wxString, wxString > &aProperties)
int m_harnessOwnerIndexOffset
std::map< wxString, LIB_SYMBOL * > ParseLibFile(const ALTIUM_COMPOUND_FILE &aAltiumSchFile)
static bool checkFileHeader(const wxString &aFileName)
long long getLibraryTimestamp(const wxString &aLibraryPath) const
std::map< wxString, std::map< wxString, LIB_SYMBOL * > > m_libCache
void ParseSheetEntry(const std::map< wxString, wxString > &aProperties)
IO_RELEASER< SCH_IO > m_pi
static bool isBinaryFile(const wxString &aFileName)
void ParseHarnessType(const std::map< wxString, wxString > &aProperties)
void ParseJunction(const std::map< wxString, wxString > &aProperties)
void ParseLibParameter(const std::map< wxString, wxString > &aProperties, std::vector< LIB_SYMBOL * > &aSymbol=nullsym, std::vector< int > &aFontSize=nullint)
void ParseASCIISchematic(const wxString &aFileName)
void ParsePolyline(const std::map< wxString, wxString > &aProperties, std::vector< LIB_SYMBOL * > &aSymbol=nullsym)
std::unique_ptr< ASCH_SHEET > m_altiumSheet
void ParseComponent(int aIndex, const std::map< wxString, wxString > &aProperties)
std::unique_ptr< TITLE_BLOCK > m_currentTitleBlock
void ParseImage(const std::map< wxString, wxString > &aProperties)
void ParseArc(const std::map< wxString, wxString > &aProperties, std::vector< LIB_SYMBOL * > &aSymbol=nullsym)
void ParseNetLabel(const std::map< wxString, wxString > &aProperties)
void ParseNoERC(const std::map< wxString, wxString > &aProperties)
void ParseImplementationList(int aIndex, const std::map< wxString, wxString > &aProperties)
std::vector< LIB_SYMBOL * > ParseLibComponent(const std::map< wxString, wxString > &aProperties)
void ParseSheet(const std::map< wxString, wxString > &aProperties)
LIB_SYMBOL * LoadSymbol(const wxString &aLibraryPath, const wxString &aAliasName, const STRING_UTF8_MAP *aProperties=nullptr) override
Load a LIB_SYMBOL object having aPartName from the aLibraryPath containing a library format that this...
void ParseParameter(const std::map< wxString, wxString > &aProperties)
bool ShouldPutItemOnSheet(int aOwnerindex)
void AddLibTextBox(const ASCH_TEXT_FRAME *aElem, std::vector< LIB_SYMBOL * > &aSymbol=nullsym, std::vector< int > &aFontSize=nullint)
bool CanReadSchematicFile(const wxString &aFileName) const override
Checks if this SCH_IO can read the specified schematic file.
void ParsePieChart(const std::map< wxString, wxString > &aProperties, std::vector< LIB_SYMBOL * > &aSymbol=nullsym)
SCH_SHEET * LoadSchematicFile(const wxString &aFileName, SCHEMATIC *aSchematic, SCH_SHEET *aAppendToMe=nullptr, const STRING_UTF8_MAP *aProperties=nullptr) override
Load information from some input file format that this SCH_IO implementation knows about,...
void ParseEllipticalArc(const std::map< wxString, wxString > &aProperties, std::vector< LIB_SYMBOL * > &aSymbol=nullsym)
void ParseEllipse(const std::map< wxString, wxString > &aProperties, std::vector< LIB_SYMBOL * > &aSymbol=nullsym)
void ParseWire(const std::map< wxString, wxString > &aProperties)
void doEnumerateSymbolLib(const wxString &aLibraryPath, const STRING_UTF8_MAP *aProperties, std::function< void(const wxString &, LIB_SYMBOL *)> aInserter)
void ParseHarnessEntry(const std::map< wxString, wxString > &aProperties)
void ParseImplementation(const std::map< wxString, wxString > &aProperties, std::vector< LIB_SYMBOL * > &aSymbol=nullsym)
void ParseTemplate(int aIndex, const std::map< wxString, wxString > &aProperties)
void ParseAdditional(const ALTIUM_COMPOUND_FILE &aAltiumSchFile)
void ensureLoadedLibrary(const wxString &aLibraryPath, const STRING_UTF8_MAP *aProperties)
void AddTextBox(const ASCH_TEXT_FRAME *aElem)
void ParsePowerPort(const std::map< wxString, wxString > &aProperties)
bool CanReadLibrary(const wxString &aFileName) const override
Checks if this IO object can read the specified library file/directory.
const ASCH_STORAGE_FILE * GetFileFromStorage(const wxString &aFilename) const
void ParseRectangle(const std::map< wxString, wxString > &aProperties, std::vector< LIB_SYMBOL * > &aSymbol=nullsym)
std::vector< ASCH_STORAGE_FILE > m_altiumStorage
SCH_SHEET_PATH m_sheetPath
void ParseLabel(const std::map< wxString, wxString > &aProperties, std::vector< LIB_SYMBOL * > &aSymbol=nullsym, std::vector< int > &aFontSize=nullint)
void ParseBezier(const std::map< wxString, wxString > &aProperties, std::vector< LIB_SYMBOL * > &aSymbol=nullsym)
void ParseLine(const std::map< wxString, wxString > &aProperties, std::vector< LIB_SYMBOL * > &aSymbol=nullsym)
void ParseCircle(const std::map< wxString, wxString > &aProperties, std::vector< LIB_SYMBOL * > &aSymbol=nullsym)
std::map< int, SCH_SYMBOL * > m_symbols
void ParseSheetSymbol(int aIndex, const std::map< wxString, wxString > &aProperties)
std::map< wxString, long long > m_timestamps
wxFileName getLibFileName()
SCH_SCREEN * getCurrentScreen()
void ParsePin(const std::map< wxString, wxString > &aProperties, std::vector< LIB_SYMBOL * > &aSymbol=nullsym)
std::map< int, LIB_SYMBOL * > m_libSymbols
void ParseHarnessConnector(int aIndex, const std::map< wxString, wxString > &aProperties)
Base class that schematic file and library loading and saving plugins should derive from.
virtual bool CanReadSchematicFile(const wxString &aFileName) const
Checks if this SCH_IO can read the specified schematic file.
Base class for any item which can be embedded within the SCHEMATIC container class,...
virtual void SetUnit(int aUnit)
void SetShape(LABEL_FLAG_SHAPE aShape)
void AutoplaceFields(SCH_SCREEN *aScreen, bool aManual) override
std::vector< SCH_FIELD > & GetFields()
virtual void SetSpinStyle(SPIN_STYLE aSpinStyle)
Segment description base class to describe items which have 2 end points (track, wire,...
void SetStartPoint(const VECTOR2I &aPosition)
bool IsWire() const
Return true if the line is a wire.
void SetLineWidth(const int aSize)
bool IsBus() const
Return true if the line is a bus.
virtual void SetStroke(const STROKE_PARAMS &aStroke) override
void SetEndPoint(const VECTOR2I &aPosition)
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
void UpdateSymbolLinks(REPORTER *aReporter=nullptr)
Initialize the LIB_SYMBOL reference for each SCH_SYMBOL found in the full schematic.
std::vector< SCH_SHEET_INSTANCE > m_sheetInstances
void SetTitleBlock(const TITLE_BLOCK &aTitleBlock)
void Append(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
void SetPageSettings(const PAGE_INFO &aPageSettings)
EE_RTREE & Items()
Gets the full RTree, usually for iterating.
const KIID & GetUuid() const
bool IsTerminalPoint(const VECTOR2I &aPosition, int aLayer) const
Test if aPosition is a connection point on aLayer.
void SetFileName(const wxString &aFileName)
Set the file name for this screen to aFileName.
void SetPosition(const VECTOR2I &aPos) override
void SetStroke(const STROKE_PARAMS &aStroke) override
void AddPoint(const VECTOR2I &aPosition)
STROKE_PARAMS GetStroke() const override
VECTOR2I GetPosition() const override
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
KIID_PATH Path() const
Get the sheet path as an KIID_PATH.
SCH_SCREEN * LastScreen()
void SetPageNumber(const wxString &aPageNumber)
Set the sheet instance user definable page number.
SCH_SHEET * Last() const
Return a pointer to the last SCH_SHEET of the list.
void push_back(SCH_SHEET *aSheet)
Forwarded method from std::vector.
void pop_back()
Forwarded method from std::vector.
Define a sheet pin (label) used in sheets to create hierarchical schematics.
void SetPosition(const VECTOR2I &aPosition) override
void SetSide(SHEET_SIDE aEdge)
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
void SetBorderColor(KIGFX::COLOR4D aColor)
void SetFileName(const wxString &aFilename)
wxString GetFileName() const
Return the filename corresponding to this sheet.
bool SearchHierarchy(const wxString &aFilename, SCH_SCREEN **aScreen)
Search the existing hierarchy for an instance of screen loaded from aFileName.
void SetBackgroundColor(KIGFX::COLOR4D aColor)
void SetName(const wxString &aName)
SCH_SCREEN * GetScreen() const
void SetScreen(SCH_SCREEN *aScreen)
Set the SCH_SCREEN associated with this sheet to aScreen.
void SetLibId(const LIB_ID &aName)
void SetPosition(const VECTOR2I &aPosition) override
int GetFieldCount() const
Return the number of fields in this symbol.
void SetValueFieldText(const wxString &aValue)
SCH_FIELD * FindField(const wxString &aFieldName, bool aIncludeDefaultFields=true, bool aCaseInsensitive=false)
Search for a SCH_FIELD with aFieldName.
SCH_FIELD * GetField(MANDATORY_FIELD_T aFieldType)
Return a mandatory field in this symbol.
void SetRef(const SCH_SHEET_PATH *aSheet, const wxString &aReference)
Set the reference for the given sheet path for this symbol.
void SetOrientation(int aOrientation)
Compute the new transform matrix based on aOrientation for the symbol which is applied to the current...
void SetFootprintFieldText(const wxString &aFootprint)
VECTOR2I GetPosition() const override
TRANSFORM & GetTransform()
SCH_FIELD * AddField(const SCH_FIELD &aField)
Add a field to the symbol.
void GetFields(std::vector< SCH_FIELD * > &aVector, bool aVisibleOnly)
Populate a std::vector with SCH_FIELDs.
void SetLibSymbol(LIB_SYMBOL *aLibSymbol)
Set this schematic symbol library symbol reference to aLibSymbol.
void SetPosition(const VECTOR2I &aPosition) override
A name/value tuple with unique names and optional values.
Simple container to manage line stroke parameters.
void SetLineStyle(LINE_STYLE aLineStyle)
void SetWidth(int aWidth)
KIGFX::COLOR4D GetColor() const
Hold a record identifying a symbol library accessed by the appropriate symbol library SCH_IO object i...
static const wxString & GetSymbolLibTableFileName()
static const char * PropPowerSymsOnly
virtual void Format(OUTPUTFORMATTER *aOutput, int aIndentLevel) const override
Generate the table in s-expression format to aOutput with an indentation level of aIndentLevel.
static REPORTER & GetInstance()
#define DEFAULT_PINNUM_SIZE
The default pin name size when creating pins(can be changed in preference menu)
#define DEFAULT_PINNAME_SIZE
The default selection highlight thickness (can be changed in preference menu)
static constexpr EDA_ANGLE ANGLE_0
static constexpr EDA_ANGLE ANGLE_VERTICAL
static constexpr EDA_ANGLE ANGLE_HORIZONTAL
#define IS_NEW
New item, just created.
@ FILLED_WITH_BG_BODYCOLOR
static const std::string KiCadSchematicFileExtension
static const std::string KiCadSymbolLibFileExtension
#define THROW_IO_ERROR(msg)
static const std::vector< uint8_t > COMPOUND_FILE_HEADER
bool fileStartsWithBinaryHeader(const wxString &aFilePath, const std::vector< uint8_t > &aHeader)
Check if a file starts with a defined binary header.
bool fileStartsWithPrefix(const wxString &aFilePath, const wxString &aPrefix, bool aIgnoreWhitespace)
Check if a file starts with a defined string.
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
static COLOR4D GetColorFromInt(int color)
#define HARNESS_PORT_COLOR_DEFAULT_OUTLINE
static void SetLibShapeFillAndColor(const ASCH_FILL_INTERFACE &elem, SCH_SHAPE *shape, ALTIUM_SCH_RECORD aType, int aStrokeColor)
VECTOR2I HelperGeneratePowerPortGraphics(LIB_SYMBOL *aKsymbol, ASCH_POWER_PORT_STYLE aStyle, REPORTER *aReporter)
static void SetSchShapeLine(const ASCH_BORDER_INTERFACE &elem, SCH_SHAPE *shape)
static const VECTOR2I GetRelativePosition(const VECTOR2I &aPosition, const SCH_SYMBOL *aSymbol)
static void SetLibShapeLine(const ASCH_BORDER_INTERFACE &elem, SCH_SHAPE *shape, ALTIUM_SCH_RECORD aType)
static LINE_STYLE GetPlotDashType(const ASCH_POLYLINE_LINESTYLE linestyle)
#define HARNESS_PORT_COLOR_DEFAULT_BACKGROUND
static void SetSchShapeFillAndColor(const ASCH_FILL_INTERFACE &elem, SCH_SHAPE *shape)
void SetTextPositioning(EDA_TEXT *text, ASCH_LABEL_JUSTIFICATION justification, ASCH_RECORD_ORIENTATION orientation)
static std::vector< std::string > split(const std::string &aStr, const std::string &aDelim)
Split the input string into a vector of output strings.
LINE_STYLE
Dashed line types.
std::vector< VECTOR2I > points
std::vector< VECTOR2I > points
ASCH_LABEL_JUSTIFICATION justification
ASCH_RECORD_ORIENTATION orientation
ASCH_RECORD_ORIENTATION orientation
ASCH_SHEET_ENTRY_SIDE Side
ASCH_RECORD_ORIENTATION orientation
ASCH_LABEL_JUSTIFICATION justification
ASCH_POLYLINE_LINESTYLE LineStyle
ASCH_LABEL_JUSTIFICATION justification
ASCH_RECORD_ORIENTATION orientation
ASCH_RECORD_ORIENTATION orientation
ASCH_LABEL_JUSTIFICATION justification
ASCH_PIN_SYMBOL::PTYPE symbolOuterEdge
ASCH_PIN_ELECTRICAL electrical
ASCH_PIN_SYMBOL::PTYPE symbolInnerEdge
ASCH_RECORD_ORIENTATION orientation
std::vector< VECTOR2I > points
ASCH_POLYLINE_LINESTYLE LineStyle
std::vector< VECTOR2I > Points
ASCH_TEXT_FRAME_ALIGNMENT Alignment
ASCH_POWER_PORT_STYLE style
ASCH_RECORD_ORIENTATION orientation
ASCH_SHEET_ENTRY_SIDE side
ASCH_RECORD_ORIENTATION orientation
std::vector< VECTOR2I > Points
wxString componentdescription
ASCH_TEXT_FRAME_ALIGNMENT Alignment
std::vector< VECTOR2I > points
constexpr int IUToMils(int iu) const
constexpr int MilsToIU(int mils) const
A simple container for sheet instance information.
@ VALUE_FIELD
Field Value of part, i.e. "3.3K".
@ REFERENCE_FIELD
Field Reference of part, i.e. "IC21".
@ DESCRIPTION_FIELD
Field Description of part, i.e. "1/4W 1% Metal Film Resistor".
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition of file extensions used in Kicad.