55#include <compoundfilereader.h>
60#include <wx/mstream.h>
62#include <wx/zstream.h>
63#include <wx/wfstream.h>
64#include <magic_enum.hpp>
69#define HARNESS_PORT_COLOR_DEFAULT_BACKGROUND COLOR4D( 0.92941176470588238, \
70 0.94901960784313721, \
71 0.98431372549019602, 1.0 )
73#define HARNESS_PORT_COLOR_DEFAULT_OUTLINE COLOR4D( 0.56078431372549020, \
74 0.61960784313725492, \
75 0.78823529411764703, 1.0 )
94 int green = (
color & 0x00FF00 ) >> 8;
95 int blue = (
color & 0xFF0000 ) >> 16;
159 if(
color == default_color ||
color == alt_default_color )
188 else if( elem.
AreaColor == aStrokeColor )
194 else if( bgcolor.
WithAlpha( 1.0 ) == default_bgcolor )
232 for(
auto& [
name, symbol] : lib )
319 wxCHECK( !aFileName.IsEmpty() && aSchematic,
nullptr );
321 wxFileName fileName( aFileName );
326 std::unique_ptr<SCH_SHEET> deleter( aAppendToMe ?
nullptr :
m_rootSheet );
330 wxCHECK_MSG( aSchematic->
IsValid(),
nullptr,
"Can't append to a schematic with no root!" );
357 wxCHECK_MSG( libTable,
nullptr,
"Could not load symbol lib table." );
359 m_pi.reset( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_KICAD ) );
367 wxString libTableUri =
"${KIPRJMOD}/" +
getLibFileName().GetFullName();
371 wxString(
"KiCad" ) ) );
380 libTable->
Format( &formatter, 0 );
391 wxCHECK( rootScreen,
nullptr );
411 int minWireWidth = std::numeric_limits<int>::max();
412 int minBusWidth = std::numeric_limits<int>::max();
416 std::vector<SCH_MARKER*> markers;
423 minWireWidth = std::min( minWireWidth, line->
GetLineWidth() );
426 minBusWidth = std::min( minBusWidth, line->
GetLineWidth() );
432 if( minWireWidth < std::numeric_limits<int>::max() )
433 netSettings->m_DefaultNetClass->SetWireWidth( minWireWidth );
435 if( minBusWidth < std::numeric_limits<int>::max() )
436 netSettings->m_DefaultNetClass->SetBusWidth( minBusWidth );
457 wxFileName parentFileName = aFileName;
471 catch(
const CFB::CFBException& exception )
475 catch(
const std::exception& exc )
477 wxLogDebug( wxT(
"Unhandled exception in Altium schematic parsers: %s." ), exc.what() );
487 wxCHECK( currentScreen, );
495 wxCHECK2( sheet,
continue );
499 wxFileName loadAltiumFileName( parentFileName.GetPath(), sheet->
GetFileName() );
501 if( !loadAltiumFileName.IsFileReadable() )
505 wxDir::GetAllFiles( parentFileName.GetPath(), &files, wxEmptyString,
506 wxDIR_FILES | wxDIR_HIDDEN );
508 for(
const wxString& candidate : files )
510 wxFileName candidateFname( candidate );
512 if( candidateFname.GetFullName().IsSameAs( sheet->
GetFileName(),
false ) )
514 loadAltiumFileName = candidateFname;
520 if( loadAltiumFileName.GetFullName().IsEmpty() || !loadAltiumFileName.IsFileReadable() )
524 msg.Printf(
_(
"The file name for sheet %s is undefined, this is probably an"
525 " Altium signal harness that got converted to a sheet." ),
544 if( sheet->
GetName().Trim().empty() )
545 sheet->
SetName( loadAltiumFileName.GetName() );
547 wxCHECK2( screen,
continue );
553 wxFileName projectFileName = loadAltiumFileName;
556 sheet->
SetFileName( projectFileName.GetFullName() );
557 screen->
SetFileName( projectFileName.GetFullPath() );
567 const CFB::COMPOUND_FILE_ENTRY* file = aAltiumSchFile.
FindStream( {
"Storage" } );
569 if( file ==
nullptr )
574 std::map<wxString, wxString> properties = reader.
ReadProperties();
581 for(
int i = 0; i < weight; i++ )
592 "(%d bytes remaining)." ),
601 wxString streamName = wxS(
"Additional" );
603 const CFB::COMPOUND_FILE_ENTRY* file =
604 aAltiumSchFile.
FindStream( { streamName.ToStdString() } );
606 if( file ==
nullptr )
617 std::map<wxString, wxString> properties = reader.
ReadProperties();
622 if( record != ALTIUM_SCH_RECORD::HEADER )
628 std::map<wxString, wxString> properties = reader.
ReadProperties();
649 wxString streamName = wxS(
"FileHeader" );
651 const CFB::COMPOUND_FILE_ENTRY* file =
652 aAltiumSchFile.
FindStream( { streamName.ToStdString() } );
654 if( file ==
nullptr )
665 std::map<wxString, wxString> properties = reader.
ReadProperties();
669 if( libtype.CmpNoCase(
"Protel for Windows - Schematic Capture Binary File Version 5.0" ) )
682 std::map<wxString, wxString> properties = reader.
ReadProperties();
694 for( std::pair<const int, SCH_SYMBOL*>& symbol :
m_symbols )
704 symbol.second->SetLibSymbol( libSymbolIt->second );
741 while( storageReader.
CanRead() )
743 std::map<wxString, wxString> properties = storageReader.
ReadProperties();
746 if( properties.find( wxS(
"BINARY" ) ) != properties.end() )
760 std::map<wxString, wxString> properties = reader.
ReadProperties();
764 if( libtype.CmpNoCase(
"Protel for Windows - Schematic Capture Ascii File Version 5.0" ) )
779 std::map<wxString, wxString> properties = reader.
ReadProperties();
782 if( properties.find( wxS(
"HEADER" ) ) != properties.end() )
788 if( properties.find( wxS(
"RECORD" ) ) != properties.end() )
801 for( std::pair<const int, SCH_SYMBOL*>& symbol :
m_symbols )
811 symbol.second->SetLibSymbol( libSymbolIt->second );
847 const wxString& aSectionName )
857 case ALTIUM_SCH_RECORD::HEADER:
860 case ALTIUM_SCH_RECORD::COMPONENT:
864 case ALTIUM_SCH_RECORD::PIN:
868 case ALTIUM_SCH_RECORD::IEEE_SYMBOL:
872 case ALTIUM_SCH_RECORD::LABEL:
876 case ALTIUM_SCH_RECORD::BEZIER:
880 case ALTIUM_SCH_RECORD::POLYLINE:
884 case ALTIUM_SCH_RECORD::POLYGON:
888 case ALTIUM_SCH_RECORD::ELLIPSE:
892 case ALTIUM_SCH_RECORD::PIECHART:
896 case ALTIUM_SCH_RECORD::ROUND_RECTANGLE:
900 case ALTIUM_SCH_RECORD::ELLIPTICAL_ARC:
901 case ALTIUM_SCH_RECORD::ARC:
905 case ALTIUM_SCH_RECORD::LINE:
909 case ALTIUM_SCH_RECORD::RECTANGLE:
913 case ALTIUM_SCH_RECORD::SHEET_SYMBOL:
917 case ALTIUM_SCH_RECORD::SHEET_ENTRY:
921 case ALTIUM_SCH_RECORD::POWER_PORT:
925 case ALTIUM_SCH_RECORD::PORT:
931 case ALTIUM_SCH_RECORD::NO_ERC:
935 case ALTIUM_SCH_RECORD::NET_LABEL:
939 case ALTIUM_SCH_RECORD::BUS:
943 case ALTIUM_SCH_RECORD::WIRE:
947 case ALTIUM_SCH_RECORD::TEXT_FRAME:
951 case ALTIUM_SCH_RECORD::JUNCTION:
955 case ALTIUM_SCH_RECORD::IMAGE:
959 case ALTIUM_SCH_RECORD::SHEET:
963 case ALTIUM_SCH_RECORD::SHEET_NAME:
967 case ALTIUM_SCH_RECORD::FILE_NAME:
971 case ALTIUM_SCH_RECORD::DESIGNATOR:
975 case ALTIUM_SCH_RECORD::BUS_ENTRY:
979 case ALTIUM_SCH_RECORD::TEMPLATE:
983 case ALTIUM_SCH_RECORD::PARAMETER:
987 case ALTIUM_SCH_RECORD::PARAMETER_SET:
991 case ALTIUM_SCH_RECORD::IMPLEMENTATION_LIST:
995 case ALTIUM_SCH_RECORD::IMPLEMENTATION:
999 case ALTIUM_SCH_RECORD::MAP_DEFINER_LIST:
1002 case ALTIUM_SCH_RECORD::MAP_DEFINER:
1005 case ALTIUM_SCH_RECORD::IMPL_PARAMS:
1008 case ALTIUM_SCH_RECORD::NOTE:
1012 case ALTIUM_SCH_RECORD::COMPILE_MASK:
1016 case ALTIUM_SCH_RECORD::HYPERLINK:
1021 case ALTIUM_SCH_RECORD::HARNESS_CONNECTOR:
1025 case ALTIUM_SCH_RECORD::HARNESS_ENTRY:
1029 case ALTIUM_SCH_RECORD::HARNESS_TYPE:
1033 case ALTIUM_SCH_RECORD::SIGNAL_HARNESS:
1037 case ALTIUM_SCH_RECORD::BLANKET:
1043 wxString::Format(
_(
"Unknown or unexpected record id %d found in %s." ), recordId,
1074 if( file.filename.IsSameAs( aFilename ) )
1077 if( file.filename.EndsWith( aFilename ) )
1078 nonExactMatch = &file;
1081 return nonExactMatch;
1088 wxCHECK( currentSheet, );
1090 wxString sheetName = currentSheet->
GetName();
1092 if( sheetName.IsEmpty() )
1093 sheetName = wxT(
"root" );
1101 m_reporter->
Report( wxString::Format(
_(
"Symbol \"%s\" in sheet \"%s\" at index %d "
1102 "replaced with symbol \"%s\"." ),
1114 wxString
name = wxString::Format(
"%s_%d%s_%s",
1145 screen->
Append( symbol );
1154 wxCHECK( currentSheet, );
1156 wxString sheetName = currentSheet->
GetName();
1158 if( sheetName.IsEmpty() )
1159 sheetName = wxT(
"root" );
1164 wxString baseName = altiumTemplate.
filename.AfterLast(
'\\' ).BeforeLast(
'.' );
1166 if( baseName.IsEmpty() )
1167 baseName = wxS(
"Template" );
1175 std::vector<LIB_SYMBOL*>& aSymbol )
1191 m_reporter->
Report( wxString::Format( wxT(
"Pin's owner (%d) not found." ),
1200 schSymbol =
m_symbols.at( libSymbolIt->first );
1201 symbol = libSymbolIt->second;
1220 pin->SetVisible(
false );
1223 pin->SetNumberTextSize( 0 );
1226 pin->SetNameTextSize( 0 );
1232 case ASCH_RECORD_ORIENTATION::RIGHTWARDS:
1233 pin->SetOrientation( PIN_ORIENTATION::PIN_LEFT );
1237 case ASCH_RECORD_ORIENTATION::UPWARDS:
1238 pin->SetOrientation( PIN_ORIENTATION::PIN_DOWN );
1242 case ASCH_RECORD_ORIENTATION::LEFTWARDS:
1243 pin->SetOrientation( PIN_ORIENTATION::PIN_RIGHT );
1247 case ASCH_RECORD_ORIENTATION::DOWNWARDS:
1248 pin->SetOrientation( PIN_ORIENTATION::PIN_UP );
1261 pin->SetPosition(
VECTOR2I( pinLocation.
x, -pinLocation.
y ) );
1265 case ASCH_PIN_ELECTRICAL::INPUT:
1266 pin->SetType( ELECTRICAL_PINTYPE::PT_INPUT );
1269 case ASCH_PIN_ELECTRICAL::BIDI:
1270 pin->SetType( ELECTRICAL_PINTYPE::PT_BIDI );
1273 case ASCH_PIN_ELECTRICAL::OUTPUT:
1274 pin->SetType( ELECTRICAL_PINTYPE::PT_OUTPUT );
1277 case ASCH_PIN_ELECTRICAL::OPEN_COLLECTOR:
1278 pin->SetType( ELECTRICAL_PINTYPE::PT_OPENCOLLECTOR );
1281 case ASCH_PIN_ELECTRICAL::PASSIVE:
1282 pin->SetType( ELECTRICAL_PINTYPE::PT_PASSIVE );
1285 case ASCH_PIN_ELECTRICAL::TRISTATE:
1286 pin->SetType( ELECTRICAL_PINTYPE::PT_TRISTATE );
1289 case ASCH_PIN_ELECTRICAL::OPEN_EMITTER:
1290 pin->SetType( ELECTRICAL_PINTYPE::PT_OPENEMITTER );
1293 case ASCH_PIN_ELECTRICAL::POWER:
1294 pin->SetType( ELECTRICAL_PINTYPE::PT_POWER_IN );
1297 case ASCH_PIN_ELECTRICAL::UNKNOWN:
1299 pin->SetType( ELECTRICAL_PINTYPE::PT_UNSPECIFIED );
1315 pin->SetShape( GRAPHIC_PINSHAPE::INVERTED_CLOCK );
1319 pin->SetShape( GRAPHIC_PINSHAPE::INVERTED );
1328 pin->SetShape( GRAPHIC_PINSHAPE::CLOCK_LOW );
1332 pin->SetShape( GRAPHIC_PINSHAPE::INPUT_LOW );
1338 pin->SetShape( GRAPHIC_PINSHAPE::OUTPUT_LOW );
1345 pin->SetShape( GRAPHIC_PINSHAPE::CLOCK );
1349 pin->SetShape( GRAPHIC_PINSHAPE::LINE );
1359 int vjustify, hjustify;
1362 switch( justification )
1385 switch( justification )
1408 switch( orientation )
1433 text->SetTextAngle( angle );
1452 std::vector<LIB_SYMBOL*>& aSymbol, std::vector<int>& aFontSizes )
1458 static const std::map<wxString, wxString> variableMap = {
1459 {
"APPLICATION_BUILDNUMBER",
"KICAD_VERSION" },
1460 {
"SHEETNUMBER",
"#" },
1461 {
"SHEETTOTAL",
"##" },
1462 {
"TITLE",
"TITLE" },
1463 {
"REVISION",
"REVISION" },
1464 {
"DATE",
"ISSUE_DATE" },
1465 {
"CURRENTDATE",
"CURRENT_DATE" },
1466 {
"COMPANYNAME",
"COMPANY" },
1467 {
"DOCUMENTNAME",
"FILENAME" },
1468 {
"DOCUMENTFULLPATHANDNAME",
1470 {
"PROJECTNAME",
"PROJECTNAME" },
1478 size_t fontId =
static_cast<int>( elem.
fontId );
1495 screen->
Append( textItem );
1511 m_reporter->
Report( wxString::Format( wxT(
"Label's owner (%d) not found." ),
1517 symbol = libSymbolIt->second;
1518 schsym =
m_symbols.at( libSymbolIt->first );
1533 size_t fontId = elem.
fontId;
1544 else if( fontId > 0 && fontId <= aFontSizes.size() )
1546 int size = aFontSizes[fontId - 1];
1554 std::vector<LIB_SYMBOL*>& aSymbol,
1555 std::vector<int>& aFontSizes )
1582 textBox->
SetStart( sheetTopRight );
1583 textBox->
SetEnd( sheetBottomLeft );
1590 textBox->
SetFillMode( FILL_T::FILLED_WITH_COLOR );
1604 case ASCH_TEXT_FRAME_ALIGNMENT::LEFT:
1607 case ASCH_TEXT_FRAME_ALIGNMENT::CENTER:
1610 case ASCH_TEXT_FRAME_ALIGNMENT::RIGHT:
1615 size_t fontId =
static_cast<int>( aElem->
FontID );
1633 screen->
Append( textBox );
1638 std::vector<int>& aFontSizes )
1653 wxString::Format( wxT(
"Label's owner (%d) not found." ), aElem->
ownerindex ),
1658 symbol = libSymbolIt->second;
1659 schsym =
m_symbols.at( libSymbolIt->first );
1684 textBox->
SetFillMode( FILL_T::FILLED_WITH_COLOR );
1697 case ASCH_TEXT_FRAME_ALIGNMENT::LEFT:
1700 case ASCH_TEXT_FRAME_ALIGNMENT::CENTER:
1703 case ASCH_TEXT_FRAME_ALIGNMENT::RIGHT:
1708 if( aElem->
FontID > 0 && aElem->
FontID <=
static_cast<int>( aFontSizes.size() ) )
1710 int size = aFontSizes[aElem->
FontID - 1];
1717 std::vector<LIB_SYMBOL*>& aSymbol )
1721 if( elem.
points.size() < 2 )
1723 m_reporter->
Report( wxString::Format(
_(
"Bezier has %d control points. At least 2 are "
1725 static_cast<int>( elem.
points.size() ) ),
1733 wxCHECK( currentScreen, );
1735 for(
size_t i = 0; i + 1 < elem.
points.size(); i += 3 )
1737 if( i + 2 == elem.
points.size() )
1741 SCH_LAYER_ID::LAYER_NOTES );
1748 currentScreen->
Append( line );
1753 std::vector<VECTOR2I> bezierPoints;
1754 std::vector<VECTOR2I> polyPoints;
1756 for(
size_t j = i; j < elem.
points.size() && j < i + 4; j++ )
1757 bezierPoints.push_back( elem.
points.at( j ) );
1760 converter.
GetPoly( polyPoints );
1762 for(
size_t k = 0; k + 1 < polyPoints.size(); k++ )
1765 SCH_LAYER_ID::LAYER_NOTES );
1771 currentScreen->
Append( line );
1790 m_reporter->
Report( wxString::Format( wxT(
"Bezier's owner (%d) not found." ),
1796 symbol = libSymbolIt->second;
1797 schsym =
m_symbols.at( libSymbolIt->first );
1803 for(
size_t i = 0; i + 1 < elem.
points.size(); i += 3 )
1805 if( i + 2 == elem.
points.size() )
1813 for(
size_t j = i; j < elem.
points.size() && j < i + 2; j++ )
1824 else if( i + 3 == elem.
points.size() )
1835 for(
size_t j = i; j < elem.
points.size() && j < i + 2; j++ )
1854 for(
size_t j = i; j < elem.
points.size() && j < i + 4; j++ )
1865 case 0: bezier->
SetStart( pos );
break;
1868 case 3: bezier->
SetEnd( pos );
break;
1881 std::vector<LIB_SYMBOL*>& aSymbol )
1885 if( elem.
Points.size() < 2 )
1893 for(
size_t i = 1; i < elem.
Points.size(); i++ )
1922 m_reporter->
Report( wxString::Format( wxT(
"Polyline's owner (%d) not found." ),
1928 symbol = libSymbolIt->second;
1929 schsym =
m_symbols.at( libSymbolIt->first );
1958 std::vector<LIB_SYMBOL*>& aSymbol )
1993 m_reporter->
Report( wxString::Format( wxT(
"Polygon's owner (%d) not found." ),
1999 symbol = libSymbolIt->second;
2000 schsym =
m_symbols.at( libSymbolIt->first );
2039 std::vector<LIB_SYMBOL*>& aSymbol )
2073 m_reporter->
Report( wxString::Format( wxT(
"Rounded rectangle's owner (%d) not "
2080 symbol = libSymbolIt->second;
2081 schsym =
m_symbols.at( libSymbolIt->first );
2099 int radius = std::min( width / 2, height / 2 );
2136 std::vector<LIB_SYMBOL*>& aSymbol )
2147 wxCHECK( currentScreen, );
2157 currentScreen->
Append( circle );
2173 currentScreen->
Append( arc );
2190 m_reporter->
Report( wxString::Format( wxT(
"Arc's owner (%d) not found." ),
2196 symbol = libSymbolIt->second;
2197 schsym =
m_symbols.at( libSymbolIt->first );
2250 std::vector<LIB_SYMBOL*>& aSymbol )
2257 wxCHECK( currentScreen, );
2263 std::vector<BEZIER<int>> beziers;
2270 schbezier->
SetStart( bezier.Start );
2273 schbezier->
SetEnd( bezier.End );
2277 currentScreen->
Append( schbezier );
2294 m_reporter->
Report( wxString::Format( wxT(
"Elliptical Arc's owner (%d) not found." ),
2300 symbol = libSymbolIt->second;
2301 schsym =
m_symbols.at( libSymbolIt->first );
2311 std::vector<BEZIER<int>> beziers;
2337 SetLibShapeLine( elem, schbezier, ALTIUM_SCH_RECORD::ELLIPTICAL_ARC );
2345 std::vector<LIB_SYMBOL*>& aSymbol )
2365 FILL_T fillMode = elem.
IsSolid ? FILL_T::FILLED_WITH_COLOR : FILL_T::NO_FILL;
2370 std::vector<BEZIER<int>> beziers;
2371 std::vector<VECTOR2I> polyPoints;
2378 schbezier->
SetStart( bezier.Start );
2381 schbezier->
SetEnd( bezier.End );
2387 screen->
Append( schbezier );
2389 polyPoints.push_back( bezier.Start );
2392 if( fillMode != FILL_T::NO_FILL )
2399 for(
const VECTOR2I& point : polyPoints )
2402 schpoly->
AddPoint( polyPoints[0] );
2404 screen->
Append( schpoly );
2421 m_reporter->
Report( wxString::Format( wxT(
"Ellipse's owner (%d) not found." ),
2427 symbol = libSymbolIt->second;
2428 schsym =
m_symbols.at( libSymbolIt->first );
2434 std::vector<BEZIER<int>> beziers;
2435 std::vector<VECTOR2I> polyPoints;
2464 polyPoints.push_back( libbezier->
GetStart() );
2475 for(
const VECTOR2I& point : polyPoints )
2478 libline->
AddPoint( polyPoints[0] );
2488 std::vector<LIB_SYMBOL*>& aSymbol )
2510 screen->
Append( circle );
2526 m_reporter->
Report( wxString::Format( wxT(
"Ellipse's owner (%d) not found." ),
2532 symbol = libSymbolIt->second;
2533 schsym =
m_symbols.at( libSymbolIt->first );
2555 std::vector<LIB_SYMBOL*>& aSymbol )
2588 m_reporter->
Report( wxString::Format( wxT(
"Line's owner (%d) not found." ),
2594 symbol = libSymbolIt->second;
2595 schsym =
m_symbols.at( libSymbolIt->first );
2646 m_reporter->
Report( wxT(
"Signal harness, belonging to the part is not currently "
2653 wxString>& aProperties )
2660 wxCHECK( currentScreen, );
2669 currentScreen->
Append( sheet );
2682 m_reporter->
Report( wxT(
"Harness connector, belonging to the part is not currently "
2697 m_reporter->
Report( wxString::Format( wxT(
"Harness entry's parent (%d) not found." ),
2704 sheetIt->second->AddPin( sheetPin );
2707 sheetPin->
SetShape( LABEL_FLAG_SHAPE::L_UNSPECIFIED );
2709 VECTOR2I pos = sheetIt->second->GetPosition();
2710 VECTOR2I size = sheetIt->second->GetSize();
2715 case ASCH_SHEET_ENTRY_SIDE::LEFT:
2718 sheetPin->
SetSide( SHEET_SIDE::LEFT );
2720 case ASCH_SHEET_ENTRY_SIDE::RIGHT:
2723 sheetPin->
SetSide( SHEET_SIDE::RIGHT );
2725 case ASCH_SHEET_ENTRY_SIDE::TOP:
2728 sheetPin->
SetSide( SHEET_SIDE::TOP );
2730 case ASCH_SHEET_ENTRY_SIDE::BOTTOM:
2733 sheetPin->
SetSide( SHEET_SIDE::BOTTOM );
2747 m_reporter->
Report( wxString::Format( wxT(
"Harness type's parent (%d) not found." ),
2761 ASCH_RECORD_ORIENTATION::RIGHTWARDS );
2769 wxString fullPath = fn.GetFullPath();
2771 fullPath.Replace( wxT(
"\\" ), wxT(
"/" ) );
2773 SCH_SCREEN* screen = sheetIt->second->GetScreen();
2778 m_reporter->
Report( wxString::Format(
_(
"Altium's harness connector (%s) was imported as a "
2779 "hierarchical sheet. Please review the imported "
2787 std::vector<LIB_SYMBOL*>& aSymbol )
2802 rect->
SetEnd( sheetBottomLeft );
2823 m_reporter->
Report( wxString::Format( wxT(
"Rectangle's owner (%d) not found." ),
2829 symbol = libSymbolIt->second;
2830 schsym =
m_symbols.at( libSymbolIt->first );
2859 const std::map<wxString, wxString>& aProperties )
2874 wxCHECK( currentScreen, );
2875 currentScreen->
Append( sheet );
2884 wxCHECK( rootScreen, );
2892 m_sheets.insert( { aIndex, sheet } );
2904 m_reporter->
Report( wxString::Format( wxT(
"Sheet entry's owner (%d) not found." ),
2911 sheetIt->second->AddPin( sheetPin );
2914 sheetPin->
SetShape( LABEL_FLAG_SHAPE::L_UNSPECIFIED );
2918 VECTOR2I pos = sheetIt->second->GetPosition();
2919 VECTOR2I size = sheetIt->second->GetSize();
2924 case ASCH_SHEET_ENTRY_SIDE::LEFT:
2927 sheetPin->
SetSide( SHEET_SIDE::LEFT );
2930 case ASCH_SHEET_ENTRY_SIDE::RIGHT:
2933 sheetPin->
SetSide( SHEET_SIDE::RIGHT );
2936 case ASCH_SHEET_ENTRY_SIDE::TOP:
2939 sheetPin->
SetSide( SHEET_SIDE::TOP );
2942 case ASCH_SHEET_ENTRY_SIDE::BOTTOM:
2945 sheetPin->
SetSide( SHEET_SIDE::BOTTOM );
2952 case ASCH_PORT_IOTYPE::UNSPECIFIED:
2953 sheetPin->
SetShape( LABEL_FLAG_SHAPE::L_UNSPECIFIED );
2956 case ASCH_PORT_IOTYPE::OUTPUT:
2957 sheetPin->
SetShape( LABEL_FLAG_SHAPE::L_OUTPUT );
2960 case ASCH_PORT_IOTYPE::INPUT:
2961 sheetPin->
SetShape( LABEL_FLAG_SHAPE::L_INPUT );
2964 case ASCH_PORT_IOTYPE::BIDI:
2965 sheetPin->
SetShape( LABEL_FLAG_SHAPE::L_BIDI );
3156 aReporter->
Report(
_(
"Power Port with unknown style imported as 'Bar' type." ),
3181 wxString symName( elem.
text );
3182 std::string styleName( magic_enum::enum_name<ASCH_POWER_PORT_STYLE>( elem.
style ) );
3184 if( !styleName.empty() )
3185 symName <<
'_' << styleName;
3194 libSymbol = powerSymbolIt->second;
3199 libSymbol = alreadyLoaded;
3209 libSymbol->
SetDescription( wxString::Format(
_(
"Power symbol creates a global "
3210 "label with name '%s'" ), elem.
text ) );
3219 pin->SetPosition( { 0, 0 } );
3220 pin->SetLength( 0 );
3221 pin->SetType( ELECTRICAL_PINTYPE::PT_POWER_IN );
3222 pin->SetVisible(
false );
3254 case ASCH_RECORD_ORIENTATION::RIGHTWARDS:
3260 case ASCH_RECORD_ORIENTATION::UPWARDS:
3266 case ASCH_RECORD_ORIENTATION::LEFTWARDS:
3272 case ASCH_RECORD_ORIENTATION::DOWNWARDS:
3283 screen->
Append( symbol );
3294 int height = aElem.
Height;
3304 textBox->
SetFillMode( FILL_T::FILLED_WITH_COLOR );
3312 case ASCH_TEXT_FRAME_ALIGNMENT::LEFT:
3316 case ASCH_TEXT_FRAME_ALIGNMENT::CENTER:
3320 case ASCH_TEXT_FRAME_ALIGNMENT::RIGHT:
3325 size_t fontId =
static_cast<int>( aElem.
FontID );
3343 screen->
Append( textBox );
3345 m_reporter->
Report( wxString::Format(
_(
"Altium's harness port (%s) was imported as "
3346 "a text box. Please review the imported "
3365 switch( aElem.
Style )
3368 case ASCH_PORT_STYLE::NONE_HORIZONTAL:
3369 case ASCH_PORT_STYLE::LEFT:
3370 case ASCH_PORT_STYLE::RIGHT:
3371 case ASCH_PORT_STYLE::LEFT_RIGHT:
3375 case ASCH_PORT_STYLE::NONE_VERTICAL:
3376 case ASCH_PORT_STYLE::TOP:
3377 case ASCH_PORT_STYLE::BOTTOM:
3378 case ASCH_PORT_STYLE::TOP_BOTTOM:
3395 bool connectionFound = startIsWireTerminal
3396 || startIsBusTerminal
3397 || endIsWireTerminal
3398 || endIsBusTerminal;
3400 if( !connectionFound )
3407 VECTOR2I position = ( startIsWireTerminal || startIsBusTerminal ) ? start : end;
3422 case ASCH_PORT_IOTYPE::UNSPECIFIED: label->
SetShape( LABEL_FLAG_SHAPE::L_UNSPECIFIED );
break;
3423 case ASCH_PORT_IOTYPE::OUTPUT: label->
SetShape( LABEL_FLAG_SHAPE::L_OUTPUT );
break;
3424 case ASCH_PORT_IOTYPE::INPUT: label->
SetShape( LABEL_FLAG_SHAPE::L_INPUT );
break;
3425 case ASCH_PORT_IOTYPE::BIDI: label->
SetShape( LABEL_FLAG_SHAPE::L_BIDI );
break;
3428 switch( aElem.
Style )
3431 case ASCH_PORT_STYLE::NONE_HORIZONTAL:
3432 case ASCH_PORT_STYLE::LEFT:
3433 case ASCH_PORT_STYLE::RIGHT:
3434 case ASCH_PORT_STYLE::LEFT_RIGHT:
3435 if( ( startIsWireTerminal || startIsBusTerminal ) )
3442 case ASCH_PORT_STYLE::NONE_VERTICAL:
3443 case ASCH_PORT_STYLE::TOP:
3444 case ASCH_PORT_STYLE::BOTTOM:
3445 case ASCH_PORT_STYLE::TOP_BOTTOM:
3446 if( ( startIsWireTerminal || startIsBusTerminal ) )
3458 label->
GetFields()[0].SetVisible(
false );
3465 if( ( startIsWireTerminal && endIsWireTerminal ) )
3473 else if( startIsBusTerminal && endIsBusTerminal )
3496 screen->
Append( noConnect );
3524 for(
size_t i = 0; i + 1 < elem.
points.size(); i++ )
3527 SCH_LAYER_ID::LAYER_BUS );
3544 for(
size_t i = 0; i + 1 < elem.
points.size(); i++ )
3547 SCH_LAYER_ID::LAYER_WIRE );
3567 screen->
Append( junction );
3579 && component->second.currentpartid != elem.
ownerpartid )
3583 std::unique_ptr<SCH_BITMAP> bitmap = std::make_unique<SCH_BITMAP>( center );
3594 wxString msg = wxString::Format(
_(
"Embedded file %s not found in storage." ),
3600 wxString storagePath = wxFileName::CreateTempFileName(
"kicad_import_" );
3603 wxMemoryInputStream fileStream( storageFile->
data.data(), storageFile->
data.size() );
3604 wxZlibInputStream zlibInputStream( fileStream );
3605 wxFFileOutputStream outputStream( storagePath );
3606 outputStream.Write( zlibInputStream );
3607 outputStream.Close();
3609 if( !bitmap->ReadImageFile( storagePath ) )
3611 m_reporter->
Report( wxString::Format(
_(
"Error reading image %s." ), storagePath ),
3617 wxRemoveFile( storagePath );
3621 if( !wxFileExists( elem.
filename ) )
3628 if( !bitmap->ReadImageFile( elem.
filename ) )
3637 VECTOR2I currentImageSize = bitmap->GetSize();
3639 double scaleX =
std::abs(
static_cast<double>( expectedImageSize.
x ) / currentImageSize.
x );
3640 double scaleY =
std::abs(
static_cast<double>( expectedImageSize.
y ) / currentImageSize.
y );
3641 bitmap->SetImageScale( std::min( scaleX, scaleY ) );
3643 bitmap->SetFlags(
IS_NEW );
3644 screen->
Append( bitmap.release() );
3650 m_altiumSheet = std::make_unique<ASCH_SHEET>( aProperties );
3657 bool isPortrait =
m_altiumSheet->sheetOrientation == ASCH_SHEET_WORKSPACEORIENTATION::PORTRAIT;
3670 case ASCH_SHEET_SIZE::A4: pageInfo.
SetType(
"A4", isPortrait );
break;
3671 case ASCH_SHEET_SIZE::A3: pageInfo.
SetType(
"A3", isPortrait );
break;
3672 case ASCH_SHEET_SIZE::A2: pageInfo.
SetType(
"A2", isPortrait );
break;
3673 case ASCH_SHEET_SIZE::A1: pageInfo.
SetType(
"A1", isPortrait );
break;
3674 case ASCH_SHEET_SIZE::A0: pageInfo.
SetType(
"A0", isPortrait );
break;
3675 case ASCH_SHEET_SIZE::A: pageInfo.
SetType(
"A", isPortrait );
break;
3676 case ASCH_SHEET_SIZE::B: pageInfo.
SetType(
"B", isPortrait );
break;
3677 case ASCH_SHEET_SIZE::C: pageInfo.
SetType(
"C", isPortrait );
break;
3678 case ASCH_SHEET_SIZE::D: pageInfo.
SetType(
"D", isPortrait );
break;
3679 case ASCH_SHEET_SIZE::E: pageInfo.
SetType(
"E", isPortrait );
break;
3680 case ASCH_SHEET_SIZE::LETTER: pageInfo.
SetType(
"USLetter", isPortrait );
break;
3681 case ASCH_SHEET_SIZE::LEGAL: pageInfo.
SetType(
"USLegal", isPortrait );
break;
3682 case ASCH_SHEET_SIZE::TABLOID: pageInfo.
SetType(
"A3", isPortrait );
break;
3683 case ASCH_SHEET_SIZE::ORCAD_A: pageInfo.
SetType(
"A", isPortrait );
break;
3684 case ASCH_SHEET_SIZE::ORCAD_B: pageInfo.
SetType(
"B", isPortrait );
break;
3685 case ASCH_SHEET_SIZE::ORCAD_C: pageInfo.
SetType(
"C", isPortrait );
break;
3686 case ASCH_SHEET_SIZE::ORCAD_D: pageInfo.
SetType(
"D", isPortrait );
break;
3687 case ASCH_SHEET_SIZE::ORCAD_E: pageInfo.
SetType(
"E", isPortrait );
break;
3705 m_reporter->
Report( wxString::Format( wxT(
"Sheetname's owner (%d) not found." ),
3728 m_reporter->
Report( wxString::Format( wxT(
"Filename's owner (%d) not found." ),
3754 m_reporter->
Report( wxString::Format( wxT(
"Designator's owner (%d) not found." ),
3768 bool emptyRef = elem.
text.IsEmpty();
3773 bool visible = !emptyRef;
3785 std::vector<LIB_SYMBOL*>& aSymbol,
3786 std::vector<int>& aFontSizes )
3793 bool emptyRef = elem.
text.IsEmpty();
3794 SCH_FIELD& refField = symbol->GetReferenceField();
3797 refField.
SetText( wxT(
"X" ) );
3803 if( elem.
fontId > 0 && elem.
fontId <=
static_cast<int>( aFontSizes.size() ) )
3805 int size = aFontSizes[elem.
fontId - 1];
3822 busWireEntry->
SetSize( { vector.
x, vector.
y } );
3825 screen->
Append( busWireEntry );
3834 static const std::map<wxString, wxString> variableMap = {
3835 {
"COMMENT",
"VALUE" },
3836 {
"VALUE",
"ALTIUM_VALUE" },
3842 if( elem.
text ==
"*" )
3845 wxString paramName = elem.
name.Upper();
3847 if( paramName ==
"SHEETNUMBER" )
3851 else if( paramName ==
"TITLE" )
3855 else if( paramName ==
"REVISION" )
3859 else if( paramName ==
"DATE" )
3863 else if( paramName ==
"COMPANYNAME" )
3884 wxString upperName = elem.
name.Upper();
3886 if( upperName ==
"COMMENT" )
3893 wxString fieldName = elem.
name.Upper();
3897 if( fieldName.IsEmpty() )
3899 int disambiguate = 1;
3903 fieldName = wxString::Format(
"ALTIUM_UNNAMED_%d", disambiguate++ );
3910 else if( fieldName ==
"VALUE" )
3912 fieldName =
"ALTIUM_VALUE";
3928 std::vector<LIB_SYMBOL*>& aSymbol,
3929 std::vector<int>& aFontSizes )
3950 std::map<wxString, wxString> variableMap = {
3951 {
"COMMENT",
"VALUE" },
3957 wxString upperName = elem.
name.Upper();
3959 if( upperName ==
"COMMENT" )
3961 field = &libSymbol->GetValueField();
3965 int fieldIdx = libSymbol->GetFieldCount();
3966 wxString fieldNameStem = elem.
name;
3967 wxString fieldName = fieldNameStem;
3968 int disambiguate = 1;
3970 if( fieldName.IsEmpty() )
3972 fieldNameStem =
"ALTIUM_UNNAMED";
3973 fieldName =
"ALTIUM_UNNAMED_1";
3976 else if( upperName ==
"VALUE" )
3978 fieldNameStem =
"ALTIUM_VALUE";
3979 fieldName =
"ALTIUM_VALUE";
3983 while( libSymbol->FindField( fieldName ) )
3984 fieldName = wxString::Format(
"%s_%d", fieldNameStem, disambiguate++ );
3987 libSymbol->AddField( new_field );
4000 if( elem.
fontId > 0 && elem.
fontId <=
static_cast<int>( aFontSizes.size() ) )
4002 int size = aFontSizes[elem.
fontId - 1];
4010 const std::map<wxString, wxString>& aProperties )
4019 std::vector<LIB_SYMBOL*>& aSymbol )
4023 if( elem.
type != wxS(
"PCBLIB" ) )
4027 if( aSymbol.size() == 0 && !elem.
isCurrent )
4033 wxArrayString fpFilters;
4034 fpFilters.Add( wxString::Format( wxS(
"*%s*" ), elem.
name ) );
4037 if( !aSymbol.empty() )
4043 symbol->SetFPFilters( fpFilters );
4044 SCH_FIELD& footprintField = symbol->GetFootprintField();
4055 m_reporter->
Report( wxString::Format( wxT(
"Implementation's owner (%d) not found." ),
4061 const auto& libSymbolIt =
m_libSymbols.find( implementationOwnerIt->second );
4065 m_reporter->
Report( wxString::Format( wxT(
"Footprint's owner (%d) not found." ),
4066 implementationOwnerIt->second ),
4073 libSymbolIt->second->SetFPFilters( fpFilters );
4083 wxString>& aProperties )
4087 std::vector<LIB_SYMBOL*> symbols;
4105 symbols.push_back( symbol );
4114 std::map<wxString,LIB_SYMBOL*> ret;
4115 std::vector<int> fontSizes;
4119 std::map<wxString, const CFB::COMPOUND_FILE_ENTRY*> syms = aAltiumLibFile.
GetLibSymbols(
nullptr );
4121 for(
auto& [
name, entry] : syms )
4124 std::vector<LIB_SYMBOL*> symbols;
4132 std::map<wxString, wxString> properties = reader.
ReadProperties();
4136 if( record != ALTIUM_SCH_RECORD::COMPONENT )
4137 THROW_IO_ERROR(
"LibSymbol does not start with COMPONENT record" );
4142 auto handleBinaryDataLambda =
4143 [](
const std::string& binaryData ) -> std::map<wxString, wxString>
4146 std::map<wxString, wxString> result;
4150 int32_t recordId = binreader.
ReadInt32();
4152 if( recordId !=
static_cast<int32_t
>( ALTIUM_SCH_RECORD::PIN ) )
4155 result[
"RECORD"] = wxString::Format(
"%d", recordId );
4157 result[
"OWNERPARTID"] = wxString::Format(
"%d", binreader.
ReadInt16() );
4158 result[
"OWNERPARTDISPLAYMODE"] = wxString::Format(
"%d", binreader.
ReadByte() );
4159 result[
"SYMBOL_INNEREDGE"] = wxString::Format(
"%d", binreader.
ReadByte() );
4160 result[
"SYMBOL_OUTEREDGE"] = wxString::Format(
"%d", binreader.
ReadByte() );
4161 result[
"SYMBOL_INNER"] = wxString::Format(
"%d", binreader.
ReadByte() );
4162 result[
"SYMBOL_OUTER"] = wxString::Format(
"%d", binreader.
ReadByte() );
4165 result[
"ELECTRICAL"] = wxString::Format(
"%d", binreader.
ReadByte() );
4166 result[
"PINCONGLOMERATE"] = wxString::Format(
"%d", binreader.
ReadByte() );
4167 result[
"PINLENGTH"] = wxString::Format(
"%d", binreader.
ReadInt16() );
4168 result[
"LOCATION.X"] = wxString::Format(
"%d", binreader.
ReadInt16() );
4169 result[
"LOCATION.Y"] = wxString::Format(
"%d", binreader.
ReadInt16() );
4170 result[
"COLOR"] = wxString::Format(
"%d", binreader.
ReadInt32() );
4177 std::vector<std::string> partSeqSplit =
split( partSeq,
"|" );
4179 if( partSeqSplit.size() == 3 )
4181 result[
"PART"] = partSeqSplit[0];
4182 result[
"SEQ"] = partSeqSplit[2];
4187 result[
"ISKICADLIBPIN"] = wxString(
"T" );
4193 std::map<wxString, wxString> properties = reader.
ReadProperties( handleBinaryDataLambda );
4195 if( properties.empty() )
4203 case ALTIUM_SCH_RECORD::PIN:
ParsePin( properties, symbols );
break;
4205 case ALTIUM_SCH_RECORD::LABEL:
ParseLabel( properties, symbols, fontSizes );
break;
4207 case ALTIUM_SCH_RECORD::BEZIER:
ParseBezier( properties, symbols );
break;
4209 case ALTIUM_SCH_RECORD::POLYLINE:
ParsePolyline( properties, symbols );
break;
4211 case ALTIUM_SCH_RECORD::POLYGON:
ParsePolygon( properties, symbols );
break;
4213 case ALTIUM_SCH_RECORD::ELLIPSE:
ParseEllipse( properties, symbols );
break;
4215 case ALTIUM_SCH_RECORD::ROUND_RECTANGLE:
ParseRoundRectangle( properties, symbols );
break;
4217 case ALTIUM_SCH_RECORD::ELLIPTICAL_ARC:
ParseEllipticalArc( properties, symbols );
break;
4219 case ALTIUM_SCH_RECORD::ARC:
ParseArc( properties, symbols );
break;
4221 case ALTIUM_SCH_RECORD::LINE:
ParseLine( properties, symbols );
break;
4223 case ALTIUM_SCH_RECORD::RECTANGLE:
ParseRectangle( properties, symbols );
break;
4225 case ALTIUM_SCH_RECORD::DESIGNATOR:
ParseLibDesignator( properties, symbols, fontSizes );
break;
4227 case ALTIUM_SCH_RECORD::PARAMETER:
ParseLibParameter( properties, symbols, fontSizes );
break;
4229 case ALTIUM_SCH_RECORD::TEXT_FRAME:
ParseTextFrame( properties, symbols, fontSizes );
break;
4232 case ALTIUM_SCH_RECORD::IMPLEMENTATION_LIST:
break;
4234 case ALTIUM_SCH_RECORD::IMPLEMENTATION:
ParseImplementation( properties, symbols );
break;
4236 case ALTIUM_SCH_RECORD::IMPL_PARAMS:
break;
4238 case ALTIUM_SCH_RECORD::MAP_DEFINER_LIST:
break;
4239 case ALTIUM_SCH_RECORD::MAP_DEFINER:
break;
4242 case ALTIUM_SCH_RECORD::IEEE_SYMBOL:
break;
4245 case ALTIUM_SCH_RECORD::IMAGE:
break;
4248 m_reporter->
Report( wxString::Format(
_(
"Unknown or unexpected record id %d found "
4250 recordId, symbols[0]->
GetName() ),
4262 for(
size_t ii = 0; ii < symbols.size(); ii++ )
4269 if( valField.
GetText().IsEmpty() )
4272 if( symbols.size() == 1 )
4275 ret[wxString::Format(
"%s (Altium Display %zd)",
name, ii + 1 )] = symbol;
4285 wxFileName fn( aLibraryPath );
4287 if( fn.IsFileReadable() && fn.GetModificationTime().IsValid() )
4288 return fn.GetModificationTime().GetValue().GetValue();
4290 return wxDateTime( 0.0 ).GetValue().GetValue();
4305 std::vector<std::unique_ptr<ALTIUM_COMPOUND_FILE>> compoundFiles;
4307 wxFileName fileName( aLibraryPath );
4312 if( aLibraryPath.Lower().EndsWith( wxS(
".schlib" ) ) )
4316 compoundFiles.push_back( std::make_unique<ALTIUM_COMPOUND_FILE>( aLibraryPath ) );
4318 else if( aLibraryPath.Lower().EndsWith( wxS(
".intlib" ) ) )
4322 std::unique_ptr<ALTIUM_COMPOUND_FILE> intCom =
4323 std::make_unique<ALTIUM_COMPOUND_FILE>( aLibraryPath );
4325 std::map<wxString, const CFB::COMPOUND_FILE_ENTRY*> schLibFiles =
4326 intCom->EnumDir( L
"SchLib" );
4328 for(
const auto& [schLibName, cfe] : schLibFiles )
4329 compoundFiles.push_back( intCom->DecodeIntLibStream( *cfe ) );
4332 std::map<wxString, LIB_SYMBOL*>& cacheMapRef =
m_libCache[aLibraryPath];
4334 for(
auto& altiumSchFilePtr : compoundFiles )
4336 std::map<wxString, LIB_SYMBOL*> parsed =
ParseLibFile( *altiumSchFilePtr );
4337 cacheMapRef.insert( parsed.begin(), parsed.end() );
4342 catch(
const CFB::CFBException& exception )
4346 catch(
const std::exception& exc )
4348 wxFAIL_MSG( wxString::Format( wxT(
"Unhandled exception in Altium schematic parsers: %s." ),
4356 std::vector<int>& aFontSizes )
4358 const CFB::COMPOUND_FILE_ENTRY* file = aAltiumSchFile.
FindStream( {
"FileHeader" } );
4360 if( file ==
nullptr )
4370 std::map<wxString, wxString> properties = reader.
ReadProperties();
4374 if( libtype.CmpNoCase(
"Protel for Windows - Schematic Library Editor Binary File Version 5.0" ) )
4375 THROW_IO_ERROR(
_(
"Expected Altium Schematic Library file version 5.0" ) );
4377 for(
auto& [key, value] : properties )
4379 wxString upperKey = key.Upper();
4382 if( upperKey.StartsWith(
"SIZE", &remaining ) )
4384 if( !remaining.empty() )
4386 int ind = wxAtoi( remaining );
4388 if(
static_cast<int>( aFontSizes.size() ) < ind )
4389 aFontSizes.resize( ind );
4393 aFontSizes[ind - 1] = scaled;
4402 const wxString& aLibraryPath,
4411 for(
auto& [libnameStr, libSymbol] : it->second )
4412 aSymbolNameList.Add( libnameStr );
4419 const wxString& aLibraryPath,
4428 for(
auto& [libnameStr, libSymbol] : it->second )
4429 aSymbolList.push_back( libSymbol );
4434 const wxString& aAliasName,
4443 auto it2 = it->second.find( aAliasName );
4445 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)
void SetArcAngleAndEnd(const EDA_ANGLE &aAngle, bool aCheckNegativeAngle=false)
Set the end point from the angle center and start.
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.
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 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 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()
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)
static const VECTOR2I GetLibEditPosition(const VECTOR2I &aPosition)
#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.