/* * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2020 Thomas Pointhuber * Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, you may find one here: * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html * or you may search the http://www.gnu.org website for the version 2 license, * or you may write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include #include #include #include #include #include "plugins/altium/altium_parser.h" #include "sch_plugins/altium/altium_parser_sch.h" ALTIUM_SCH_RECORD ReadRecord( const std::map& aProps ) { int recordId = ALTIUM_PARSER::ReadInt( aProps, wxT( "RECORD" ), 0 ); return static_cast( recordId ); } constexpr int Altium2KiCadUnit( const int val, const int frac ) { return Mils2iu( val ) * 10 + Mils2iu( frac ) / 10000; // TODO: correct, rounding issues? } int ReadKiCadUnitFrac( const std::map& aProps, const wxString& aKey ) { // a unit is stored using two fields, denoting the size in mils and a fraction size int key = ALTIUM_PARSER::ReadInt( aProps, aKey, 0 ); int keyFrac = ALTIUM_PARSER::ReadInt( aProps, aKey + wxT( "_FRAC" ), 0 ); return Altium2KiCadUnit( key, keyFrac ); } int ReadKiCadUnitFrac1( const std::map& aProps, const wxString& aKey ) { // a unit is stored using two fields, denoting the size in mils and a fraction size // Dunno why Altium invents different units for the same purpose int key = ALTIUM_PARSER::ReadInt( aProps, aKey, 0 ); int keyFrac = ALTIUM_PARSER::ReadInt( aProps, aKey + wxT( "_FRAC1" ), 0 ); return Altium2KiCadUnit( key * 10, keyFrac ); } int ReadOwnerIndex( const std::map& aProperties ) { return ALTIUM_PARSER::ReadInt( aProperties, wxT( "OWNERINDEX" ), ALTIUM_COMPONENT_NONE ); } int ReadOwnerPartId( const std::map& aProperties ) { return ALTIUM_PARSER::ReadInt( aProperties, wxT( "OWNERPARTID" ), ALTIUM_COMPONENT_NONE ); } template T ReadEnum( const std::map& aProps, const wxString& aKey, int aLower, int aUpper, T aDefault ) { int value = ALTIUM_PARSER::ReadInt( aProps, aKey, static_cast( aDefault )); if( value < aLower || value > aUpper ) return aDefault; else return static_cast( value ); } ASCH_STORAGE_FILE::ASCH_STORAGE_FILE( ALTIUM_PARSER& aReader ) { aReader.Skip( 5 ); filename = aReader.ReadWxString(); uint32_t dataSize = aReader.Read(); data = aReader.ReadVector( dataSize ); if( aReader.HasParsingError() ) THROW_IO_ERROR( wxT( "Storage stream was not parsed correctly" ) ); } ASCH_SYMBOL::ASCH_SYMBOL( const std::map& aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::COMPONENT ); currentpartid = ALTIUM_PARSER::ReadInt( aProps, wxT( "CURRENTPARTID" ), ALTIUM_COMPONENT_NONE ); libreference = ALTIUM_PARSER::ReadString( aProps, wxT( "LIBREFERENCE" ), wxEmptyString ); sourcelibraryname = ALTIUM_PARSER::ReadString( aProps, wxT( "SOURCELIBRARYNAME" ), wxEmptyString ); componentdescription = ALTIUM_PARSER::ReadString( aProps, wxT( "COMPONENTDESCRIPTION" ), wxEmptyString ); orientation = ALTIUM_PARSER::ReadInt( aProps, wxT( "ORIENTATION" ), 0 ); isMirrored = ALTIUM_PARSER::ReadBool( aProps, wxT( "ISMIRRORED" ), false ); location = wxPoint( ReadKiCadUnitFrac( aProps, wxT( "LOCATION.X" ) ), -ReadKiCadUnitFrac( aProps, wxT( "LOCATION.Y" ) ) ); partcount = ALTIUM_PARSER::ReadInt( aProps, wxT( "PARTCOUNT" ), 0 ); displaymodecount = ALTIUM_PARSER::ReadInt( aProps, wxT( "DISPLAYMODECOUNT" ), 0 ); displaymode = ALTIUM_PARSER::ReadInt( aProps, wxT( "DISPLAYMODE" ), 0 ); } ASCH_PIN::ASCH_PIN( const std::map& aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::PIN ); ownerindex = ReadOwnerIndex( aProps ); ownerpartid = ReadOwnerPartId( aProps ); ownerpartdisplaymode = ALTIUM_PARSER::ReadInt( aProps, wxT( "OWNERPARTDISPLAYMODE" ), 0 ); name = ALTIUM_PARSER::ReadString( aProps, wxT( "NAME" ), wxEmptyString ); text = ALTIUM_PARSER::ReadString( aProps, wxT( "TEXT" ), wxEmptyString ); designator = ALTIUM_PARSER::ReadString( aProps, wxT( "DESIGNATOR" ), wxEmptyString ); int symbolOuterInt = ALTIUM_PARSER::ReadInt( aProps, wxT( "SYMBOL_OUTER" ), 0 ); symbolOuter = static_cast( symbolOuterInt ); int symbolInnerInt = ALTIUM_PARSER::ReadInt( aProps, wxT( "SYMBOL_INNER" ), 0 ); symbolInner = static_cast( symbolInnerInt ); int symbolOuterEdgeInt = ALTIUM_PARSER::ReadInt( aProps, wxT( "SYMBOL_OUTEREDGE" ), 0 ); symbolOuterEdge = ( symbolOuterEdgeInt == 0 || symbolOuterEdgeInt == 1 || symbolOuterEdgeInt == 4 || symbolOuterEdgeInt == 17 ) ? static_cast( symbolOuterEdgeInt ) : ASCH_PIN_SYMBOL_OUTEREDGE::NO_SYMBOL; int symbolInnerEdgeInt = ALTIUM_PARSER::ReadInt( aProps, wxT( "SYMBOL_INNEREDGE" ), 0 ); symbolInnerEdge = ( symbolInnerEdgeInt == 0 || symbolInnerEdgeInt == 3 ) ? static_cast( symbolInnerEdgeInt ) : ASCH_PIN_SYMBOL_INNEREDGE::NO_SYMBOL; electrical = ReadEnum( aProps, wxT( "ELECTRICAL" ), 0, 7, ASCH_PIN_ELECTRICAL::INPUT ); int pinconglomerate = ALTIUM_PARSER::ReadInt( aProps, wxT( "PINCONGLOMERATE" ), 0 ); orientation = static_cast( pinconglomerate & 0x03 ); showPinName = ( pinconglomerate & 0x08 ) != 0; showDesignator = ( pinconglomerate & 0x10 ) != 0; int x = ALTIUM_PARSER::ReadInt( aProps, wxT( "LOCATION.X" ), 0 ); int xfrac = ALTIUM_PARSER::ReadInt( aProps, wxT( "LOCATION.X_FRAC" ), 0 ); int y = ALTIUM_PARSER::ReadInt( aProps, wxT( "LOCATION.Y" ), 0 ); int yfrac = ALTIUM_PARSER::ReadInt( aProps, wxT( "LOCATION.Y_FRAC" ), 0 ); location = wxPoint( Altium2KiCadUnit( x, xfrac ), -Altium2KiCadUnit( y, yfrac ) ); int p = ALTIUM_PARSER::ReadInt( aProps, wxT( "PINLENGTH" ), 0 ); int pfrac = ALTIUM_PARSER::ReadInt( aProps, wxT( "PINLENGTH_FRAC" ), 0 ); pinlength = Altium2KiCadUnit( p, pfrac ); // this code calculates the location as required by KiCad without rounding error attached int kicadX = x; int kicadXfrac = xfrac; int kicadY = y; int kicadYfrac = yfrac; switch( orientation ) { case ASCH_RECORD_ORIENTATION::RIGHTWARDS: kicadX += p; kicadXfrac += pfrac; break; case ASCH_RECORD_ORIENTATION::UPWARDS: kicadY += p; kicadYfrac += pfrac; break; case ASCH_RECORD_ORIENTATION::LEFTWARDS: kicadX -= p; kicadXfrac -= pfrac; break; case ASCH_RECORD_ORIENTATION::DOWNWARDS: kicadY -= p; kicadYfrac -= pfrac; break; default: wxLogWarning( wxT( "Pin has unexpected orientation" ) ); break; } kicadLocation = wxPoint( Altium2KiCadUnit( kicadX, kicadXfrac ), -Altium2KiCadUnit( kicadY, kicadYfrac ) ); } ASCH_LABEL::ASCH_LABEL( const std::map& aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::LABEL ); ownerindex = ReadOwnerIndex( aProps ); ownerpartid = ReadOwnerPartId( aProps ); location = wxPoint( ReadKiCadUnitFrac( aProps, wxT( "LOCATION.X" ) ), -ReadKiCadUnitFrac( aProps, wxT( "LOCATION.Y" ) ) ); text = ALTIUM_PARSER::ReadString( aProps, wxT( "TEXT" ), wxEmptyString ); fontId = ALTIUM_PARSER::ReadInt( aProps, wxT( "FONTID" ), 0 ); isMirrored = ALTIUM_PARSER::ReadBool( aProps, wxT( "ISMIRRORED" ), false ); justification = ReadEnum( aProps, wxT( "JUSTIFICATION" ), 0, 8, ASCH_LABEL_JUSTIFICATION::BOTTOM_LEFT ); orientation = ReadEnum( aProps, wxT( "ORIENTATION" ), 0, 3, ASCH_RECORD_ORIENTATION::RIGHTWARDS ); } ASCH_TEXT_FRAME::ASCH_TEXT_FRAME( const std::map& aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::NOTE || ReadRecord( aProps ) == ALTIUM_SCH_RECORD::TEXT_FRAME ); location = wxPoint( ReadKiCadUnitFrac( aProps, wxT( "LOCATION.X" ) ), -ReadKiCadUnitFrac( aProps, wxT( "LOCATION.Y" ) ) ); size = wxSize( ReadKiCadUnitFrac( aProps, wxT( "CORNER.X" ) ) - location.x, -ReadKiCadUnitFrac( aProps, wxT( "CORNER.Y" ) ) - location.y ); text = ALTIUM_PARSER::ReadString( aProps, wxT( "TEXT" ), wxEmptyString ); text.Replace( wxT( "~1" ), wxT( "\n" ), true ); fontId = ALTIUM_PARSER::ReadInt( aProps, wxT( "FONTID" ), 0 ); isWordWrapped = ALTIUM_PARSER::ReadBool( aProps, wxT( "WORDWRAP" ), false ); border = ALTIUM_PARSER::ReadBool( aProps, wxT( "SHOWBORDER" ), false ); textMargin = ReadKiCadUnitFrac( aProps, wxT( "TEXTMARGIN" ) ); areaColor = ALTIUM_PARSER::ReadInt( aProps, wxT( "AREACOLOR" ), 0 ); alignment = ReadEnum( aProps, wxT( "ALIGNMENT" ), 1, 3, ASCH_TEXT_FRAME_ALIGNMENT::LEFT ); } ASCH_NOTE::ASCH_NOTE( const std::map& aProperties ) : ASCH_TEXT_FRAME( aProperties ) { wxASSERT( ReadRecord( aProperties ) == ALTIUM_SCH_RECORD::NOTE ); author = ALTIUM_PARSER::ReadString( aProperties, wxT( "AUTHOR" ), wxEmptyString ); } ASCH_BEZIER::ASCH_BEZIER( const std::map& aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::BEZIER ); ownerindex = ReadOwnerIndex( aProps ); ownerpartid = ReadOwnerPartId( aProps ); ownerpartdisplaymode = ALTIUM_PARSER::ReadInt( aProps, wxT( "OWNERPARTDISPLAYMODE" ), 0 ); int locationCount = ALTIUM_PARSER::ReadInt( aProps, wxT( "LOCATIONCOUNT" ), 0 ); for( int i = 1; i <= locationCount; i++ ) { const wxString si = std::to_string( i ); points.emplace_back( ReadKiCadUnitFrac( aProps, wxT( "X" ) + si ), -ReadKiCadUnitFrac( aProps, wxT( "Y" ) + si ) ); } lineWidth = ReadKiCadUnitFrac( aProps, wxT( "LINEWIDTH" ) ); } ASCH_POLYLINE::ASCH_POLYLINE( const std::map& aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::POLYLINE ); ownerindex = ReadOwnerIndex( aProps ); ownerpartid = ReadOwnerPartId( aProps ); ownerpartdisplaymode = ALTIUM_PARSER::ReadInt( aProps, wxT( "OWNERPARTDISPLAYMODE" ), 0 ); int locationCount = ALTIUM_PARSER::ReadInt( aProps, wxT( "LOCATIONCOUNT" ), 0 ); for( int i = 1; i <= locationCount; i++ ) { const wxString si = std::to_string( i ); points.emplace_back( ReadKiCadUnitFrac( aProps, wxT( "X" ) + si ), -ReadKiCadUnitFrac( aProps, wxT( "Y" ) + si ) ); } lineWidth = ReadKiCadUnitFrac( aProps, wxT( "LINEWIDTH" ) ); int linestyleVar = ALTIUM_PARSER::ReadInt( aProps, wxT( "LINESTYLEEXT" ), 0 ); linestyleVar = ALTIUM_PARSER::ReadInt( aProps, wxT( "LINESTYLE" ), linestyleVar ); // overwrite if present linestyle = linestyleVar >= 0 && linestyleVar <= 3 ? static_cast( linestyleVar ) : ASCH_POLYLINE_LINESTYLE::SOLID; } ASCH_POLYGON::ASCH_POLYGON( const std::map& aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::POLYGON ); ownerindex = ReadOwnerIndex( aProps ); ownerpartid = ReadOwnerPartId( aProps ); ownerpartdisplaymode = ALTIUM_PARSER::ReadInt( aProps, wxT( "OWNERPARTDISPLAYMODE" ), 0 ); int locationCount = ALTIUM_PARSER::ReadInt( aProps, wxT( "LOCATIONCOUNT" ), 0 ); for( int i = 1; i <= locationCount; i++ ) { const wxString si = std::to_string( i ); points.emplace_back( ReadKiCadUnitFrac( aProps, wxT( "X" ) + si ), -ReadKiCadUnitFrac( aProps, wxT( "Y" ) + si ) ); } lineWidth = ReadKiCadUnitFrac( aProps, wxT( "LINEWIDTH" ) ); isSolid = ALTIUM_PARSER::ReadBool( aProps, wxT( "ISSOLID" ), false ); color = ALTIUM_PARSER::ReadInt( aProps, wxT( "COLOR" ), 0 ); areacolor = ALTIUM_PARSER::ReadInt( aProps, wxT( "AREACOLOR" ), 0 ); } ASCH_ROUND_RECTANGLE::ASCH_ROUND_RECTANGLE( const std::map& aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::ROUND_RECTANGLE ); ownerindex = ReadOwnerIndex( aProps ); ownerpartid = ReadOwnerPartId( aProps ); ownerpartdisplaymode = ALTIUM_PARSER::ReadInt( aProps, wxT( "OWNERPARTDISPLAYMODE" ), 0 ); bottomLeft = wxPoint( ReadKiCadUnitFrac( aProps, wxT( "LOCATION.X" ) ), -ReadKiCadUnitFrac( aProps, wxT( "LOCATION.Y" ) ) ); topRight = wxPoint( ReadKiCadUnitFrac( aProps, wxT( "CORNER.X" ) ), -ReadKiCadUnitFrac( aProps, wxT( "CORNER.Y" ) ) ); cornerradius = wxSize( ReadKiCadUnitFrac( aProps, wxT( "CORNERXRADIUS" ) ), -ReadKiCadUnitFrac( aProps, wxT( "CORNERYRADIUS" ) ) ); lineWidth = ReadKiCadUnitFrac( aProps, wxT( "LINEWIDTH" ) ); isSolid = ALTIUM_PARSER::ReadBool( aProps, wxT( "ISSOLID" ), false ); isTransparent = ALTIUM_PARSER::ReadBool( aProps, wxT( "TRANSPARENT" ), false ); color = ALTIUM_PARSER::ReadInt( aProps, wxT( "COLOR" ), 0 ); areacolor = ALTIUM_PARSER::ReadInt( aProps, wxT( "AREACOLOR" ), 0 ); } ASCH_ARC::ASCH_ARC( const std::map& aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::ARC ); ownerindex = ReadOwnerIndex( aProps ); ownerpartid = ReadOwnerPartId( aProps ); ownerpartdisplaymode = ALTIUM_PARSER::ReadInt( aProps, wxT( "OWNERPARTDISPLAYMODE" ), 0 ); center = wxPoint( ReadKiCadUnitFrac( aProps, wxT( "LOCATION.X" ) ), -ReadKiCadUnitFrac( aProps, wxT( "LOCATION.Y" ) ) ); radius = ReadKiCadUnitFrac( aProps, wxT( "RADIUS" ) ); startAngle = ALTIUM_PARSER::ReadDouble( aProps, wxT( "STARTANGLE" ), 0 ); endAngle = ALTIUM_PARSER::ReadDouble( aProps, wxT( "ENDANGLE" ), 0 ); lineWidth = ReadKiCadUnitFrac( aProps, wxT( "LINEWIDTH" ) ); } ASCH_LINE::ASCH_LINE( const std::map& aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::LINE ); ownerindex = ReadOwnerIndex( aProps ); ownerpartid = ReadOwnerPartId( aProps ); ownerpartdisplaymode = ALTIUM_PARSER::ReadInt( aProps, wxT( "OWNERPARTDISPLAYMODE" ), 0 ); point1 = wxPoint( ReadKiCadUnitFrac( aProps, wxT( "LOCATION.X" ) ), -ReadKiCadUnitFrac( aProps, wxT( "LOCATION.Y" ) ) ); point2 = wxPoint( ReadKiCadUnitFrac( aProps, wxT( "CORNER.X" ) ), -ReadKiCadUnitFrac( aProps, wxT( "CORNER.Y" ) ) ); lineWidth = ReadKiCadUnitFrac( aProps, wxT( "LINEWIDTH" ) ); } ASCH_RECTANGLE::ASCH_RECTANGLE( const std::map& aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::RECTANGLE ); ownerindex = ReadOwnerIndex( aProps ); ownerpartid = ReadOwnerPartId( aProps ); ownerpartdisplaymode = ALTIUM_PARSER::ReadInt( aProps, wxT( "OWNERPARTDISPLAYMODE" ), 0 ); bottomLeft = wxPoint( ReadKiCadUnitFrac( aProps, wxT( "LOCATION.X" ) ), -ReadKiCadUnitFrac( aProps, wxT( "LOCATION.Y" ) ) ); topRight = wxPoint( ReadKiCadUnitFrac( aProps, wxT( "CORNER.X" ) ), -ReadKiCadUnitFrac( aProps, wxT( "CORNER.Y" ) ) ); lineWidth = ReadKiCadUnitFrac( aProps, wxT( "LINEWIDTH" ) ); isSolid = ALTIUM_PARSER::ReadBool( aProps, wxT( "ISSOLID" ), false ); isTransparent = ALTIUM_PARSER::ReadBool( aProps, wxT( "TRANSPARENT" ), false ); color = ALTIUM_PARSER::ReadInt( aProps, wxT( "COLOR" ), 0 ); areacolor = ALTIUM_PARSER::ReadInt( aProps, wxT( "AREACOLOR" ), 0 ); } ASCH_SHEET_SYMBOL::ASCH_SHEET_SYMBOL( const std::map& aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::SHEET_SYMBOL ); location = wxPoint( ReadKiCadUnitFrac( aProps, wxT( "LOCATION.X" ) ), -ReadKiCadUnitFrac( aProps, wxT( "LOCATION.Y" ) ) ); size = wxSize( ReadKiCadUnitFrac( aProps, wxT( "XSIZE" ) ), ReadKiCadUnitFrac( aProps, wxT( "YSIZE" ) ) ); isSolid = ALTIUM_PARSER::ReadBool( aProps, wxT( "ISSOLID" ), false ); color = ALTIUM_PARSER::ReadInt( aProps, wxT( "COLOR" ), 0 ); areacolor = ALTIUM_PARSER::ReadInt( aProps, wxT( "AREACOLOR" ), 0 ); } ASCH_SHEET_ENTRY::ASCH_SHEET_ENTRY( const std::map& aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::SHEET_ENTRY ); ownerindex = ReadOwnerIndex( aProps ); ownerpartid = ReadOwnerPartId( aProps ); // some magic, because it stores those infos in a different unit?? distanceFromTop = ReadKiCadUnitFrac1( aProps, wxT( "DISTANCEFROMTOP" ) ); side = ReadEnum( aProps, wxT( "SIDE" ), 0, 3, ASCH_SHEET_ENTRY_SIDE::LEFT ); name = ALTIUM_PARSER::ReadString( aProps, wxT( "NAME" ), wxEmptyString ); iotype = ReadEnum( aProps, wxT( "IOTYPE" ), 0, 3, ASCH_PORT_IOTYPE::UNSPECIFIED ); style = ReadEnum( aProps, wxT( "STYLE" ), 0, 7, ASCH_PORT_STYLE::NONE_HORIZONTAL ); } ASCH_POWER_PORT::ASCH_POWER_PORT( const std::map& aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::POWER_PORT ); ownerpartid = ReadOwnerPartId( aProps ); location = wxPoint( ReadKiCadUnitFrac( aProps, wxT( "LOCATION.X" ) ), -ReadKiCadUnitFrac( aProps, wxT( "LOCATION.Y" ) ) ); orientation = ReadEnum( aProps, wxT( "ORIENTATION" ), 0, 3, ASCH_RECORD_ORIENTATION::RIGHTWARDS ); text = ALTIUM_PARSER::ReadString( aProps, wxT( "TEXT" ), wxEmptyString ); showNetName = ALTIUM_PARSER::ReadBool( aProps, wxT( "SHOWNETNAME" ), true ); style = ReadEnum( aProps, wxT( "STYLE" ), 0, 10, ASCH_POWER_PORT_STYLE::CIRCLE ); } ASCH_PORT::ASCH_PORT( const std::map& aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::PORT ); ownerpartid = ReadOwnerPartId( aProps ); location = wxPoint( ReadKiCadUnitFrac( aProps, wxT( "LOCATION.X" ) ), -ReadKiCadUnitFrac( aProps, wxT( "LOCATION.Y" ) ) ); name = ALTIUM_PARSER::ReadString( aProps, wxT( "NAME" ), wxEmptyString ); harnessType = ALTIUM_PARSER::ReadString( aProps, wxT( "HARNESSTYPE" ), wxEmptyString ); width = ReadKiCadUnitFrac( aProps, wxT( "WIDTH" ) ); height = ReadKiCadUnitFrac( aProps, wxT( "HEIGHT" ) ); iotype = ReadEnum( aProps, wxT( "IOTYPE" ), 0, 3, ASCH_PORT_IOTYPE::UNSPECIFIED ); style = ReadEnum( aProps, wxT( "STYLE" ), 0, 7, ASCH_PORT_STYLE::NONE_HORIZONTAL ); } ASCH_NO_ERC::ASCH_NO_ERC( const std::map& aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::NO_ERC ); location = wxPoint( ReadKiCadUnitFrac( aProps, wxT( "LOCATION.X" ) ), -ReadKiCadUnitFrac( aProps, wxT( "LOCATION.Y" ) ) ); isActive = ALTIUM_PARSER::ReadBool( aProps, wxT( "ISACTIVE" ), true ); supressAll = ALTIUM_PARSER::ReadInt( aProps, wxT( "SUPPRESSALL" ), true ); } ASCH_NET_LABEL::ASCH_NET_LABEL( const std::map& aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::NET_LABEL ); text = ALTIUM_PARSER::ReadString( aProps, wxT( "TEXT" ), wxEmptyString ); location = wxPoint( ReadKiCadUnitFrac( aProps, wxT( "LOCATION.X" ) ), -ReadKiCadUnitFrac( aProps, wxT( "LOCATION.Y" ) ) ); orientation = ReadEnum( aProps, wxT( "ORIENTATION" ), 0, 3, ASCH_RECORD_ORIENTATION::RIGHTWARDS ); } ASCH_BUS::ASCH_BUS( const std::map& aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::BUS ); indexinsheet = ALTIUM_PARSER::ReadInt( aProps, wxT( "INDEXINSHEET" ), 0 ); int locationcount = ALTIUM_PARSER::ReadInt( aProps, wxT( "LOCATIONCOUNT" ), 0 ); for( int i = 1; i <= locationcount; i++ ) { const wxString si = std::to_string( i ); points.emplace_back( ReadKiCadUnitFrac( aProps, wxT( "X" ) + si ), -ReadKiCadUnitFrac( aProps, wxT( "Y" ) + si ) ); } lineWidth = ReadKiCadUnitFrac( aProps, wxT( "LINEWIDTH" ) ); } ASCH_WIRE::ASCH_WIRE( const std::map& aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::WIRE ); indexinsheet = ALTIUM_PARSER::ReadInt( aProps, wxT( "INDEXINSHEET" ), 0 ); int locationcount = ALTIUM_PARSER::ReadInt( aProps, wxT( "LOCATIONCOUNT" ), 0 ); for( int i = 1; i <= locationcount; i++ ) { const wxString si = std::to_string( i ); points.emplace_back( ReadKiCadUnitFrac( aProps, wxT( "X" ) + si ), -ReadKiCadUnitFrac( aProps, wxT( "Y" ) + si ) ); } lineWidth = ReadKiCadUnitFrac( aProps, wxT( "LINEWIDTH" ) ); } ASCH_JUNCTION::ASCH_JUNCTION( const std::map& aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::JUNCTION ); ownerpartid = ReadOwnerPartId( aProps ); location = wxPoint( ReadKiCadUnitFrac( aProps, wxT( "LOCATION.X" ) ), -ReadKiCadUnitFrac( aProps, wxT( "LOCATION.Y" ) ) ); } ASCH_IMAGE::ASCH_IMAGE( const std::map& aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::IMAGE ); indexinsheet = ALTIUM_PARSER::ReadInt( aProps, wxT( "INDEXINSHEET" ), 0 ); ownerpartid = ReadOwnerPartId( aProps ); filename = ALTIUM_PARSER::ReadString( aProps, wxT( "FILENAME" ), wxEmptyString ); location = wxPoint( ReadKiCadUnitFrac( aProps, wxT( "LOCATION.X" ) ), -ReadKiCadUnitFrac( aProps, wxT( "LOCATION.Y" ) ) ); corner = wxPoint( ReadKiCadUnitFrac( aProps, wxT( "CORNER.X" ) ), -ReadKiCadUnitFrac( aProps, wxT( "CORNER.Y" ) ) ); embedimage = ALTIUM_PARSER::ReadBool( aProps, wxT( "EMBEDIMAGE" ), false ); keepaspect = ALTIUM_PARSER::ReadBool( aProps, wxT( "KEEPASPECT" ), false ); } ASCH_SHEET_FONT::ASCH_SHEET_FONT( const std::map& aProps, int aId ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::SHEET ); const wxString sid = std::to_string( aId ); fontname = ALTIUM_PARSER::ReadString( aProps, wxT( "FONTNAME" ) + sid, wxEmptyString ); size = ReadKiCadUnitFrac( aProps, wxT( "SIZE" ) + sid ); rotation = ALTIUM_PARSER::ReadInt( aProps, wxT( "ROTATION" ) + sid, 0 ); italic = ALTIUM_PARSER::ReadBool( aProps, wxT( "ITALIC" ) + sid, false ); bold = ALTIUM_PARSER::ReadBool( aProps, wxT( "BOLD" ) + sid, false ); underline = ALTIUM_PARSER::ReadBool( aProps, wxT( "UNDERLINE" ) + sid, false ); } wxPoint ASchSheetGetSize( ASCH_SHEET_SIZE aSheetSize ) { // From: https://github.com/vadmium/python-altium/blob/master/format.md#sheet switch( aSheetSize ) { default: case ASCH_SHEET_SIZE::A4: return { 1150, 760 }; case ASCH_SHEET_SIZE::A3: return { 1550, 1110 }; case ASCH_SHEET_SIZE::A2: return { 2230, 1570 }; case ASCH_SHEET_SIZE::A1: return { 3150, 2230 }; case ASCH_SHEET_SIZE::A0: return { 4460, 3150 }; case ASCH_SHEET_SIZE::A: return { 950, 750 }; case ASCH_SHEET_SIZE::B: return { 1500, 950 }; case ASCH_SHEET_SIZE::C: return { 2000, 1500 }; case ASCH_SHEET_SIZE::D: return { 3200, 2000 }; case ASCH_SHEET_SIZE::E: return { 4200, 3200 }; case ASCH_SHEET_SIZE::LETTER: return { 1100, 850 }; case ASCH_SHEET_SIZE::LEGAL: return { 1400, 850 }; case ASCH_SHEET_SIZE::TABLOID: return { 1700, 1100 }; case ASCH_SHEET_SIZE::ORCAD_A: return { 990, 790 }; case ASCH_SHEET_SIZE::ORCAD_B: return { 1540, 990 }; case ASCH_SHEET_SIZE::ORCAD_C: return { 2060, 1560 }; case ASCH_SHEET_SIZE::ORCAD_D: return { 3260, 2060 }; case ASCH_SHEET_SIZE::ORCAD_E: return { 4280, 3280 }; } } ASCH_SHEET::ASCH_SHEET( const std::map& aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::SHEET ); int fontidcount = ALTIUM_PARSER::ReadInt( aProps, wxT( "FONTIDCOUNT" ), 0 ); for( int i = 1; i <= fontidcount; i++ ) fonts.emplace_back( aProps, i ); sheetSize = ReadEnum( aProps, wxT( "SHEETSTYLE" ), 0, 17, ASCH_SHEET_SIZE::A4 ); sheetOrientation = ReadEnum( aProps, wxT( "WORKSPACEORIENTATION" ), 0, 1, ASCH_SHEET_WORKSPACEORIENTATION::LANDSCAPE ); } ASCH_SHEET_NAME::ASCH_SHEET_NAME( const std::map& aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::SHEET_NAME ); ownerindex = ReadOwnerIndex( aProps ); ownerpartid = ReadOwnerPartId( aProps ); text = ALTIUM_PARSER::ReadString( aProps, wxT( "TEXT" ), wxEmptyString ); orientation = ReadEnum( aProps, wxT( "ORIENTATION" ), 0, 3, ASCH_RECORD_ORIENTATION::RIGHTWARDS ); location = wxPoint( ReadKiCadUnitFrac( aProps, wxT( "LOCATION.X" ) ), -ReadKiCadUnitFrac( aProps, wxT( "LOCATION.Y" ) ) ); isHidden = ALTIUM_PARSER::ReadBool( aProps, wxT( "ISHIDDEN" ), false ); } ASCH_FILE_NAME::ASCH_FILE_NAME( const std::map& aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::FILE_NAME ); ownerindex = ReadOwnerIndex( aProps ); ownerpartid = ReadOwnerPartId( aProps ); text = ALTIUM_PARSER::ReadString( aProps, wxT( "TEXT" ), wxEmptyString ); orientation = ReadEnum( aProps, wxT( "ORIENTATION" ), 0, 3, ASCH_RECORD_ORIENTATION::RIGHTWARDS ); location = wxPoint( ReadKiCadUnitFrac( aProps, wxT( "LOCATION.X" ) ), -ReadKiCadUnitFrac( aProps, wxT( "LOCATION.Y" ) ) ); isHidden = ALTIUM_PARSER::ReadBool( aProps, wxT( "ISHIDDEN" ), false ); } ASCH_DESIGNATOR::ASCH_DESIGNATOR( const std::map& aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::DESIGNATOR ); ownerindex = ReadOwnerIndex( aProps ); ownerpartid = ReadOwnerPartId( aProps ); name = ALTIUM_PARSER::ReadString( aProps, wxT( "NAME" ), wxEmptyString ); text = ALTIUM_PARSER::ReadString( aProps, wxT( "TEXT" ), wxEmptyString ); justification = ReadEnum( aProps, wxT( "JUSTIFICATION" ), 0, 8, ASCH_LABEL_JUSTIFICATION::BOTTOM_LEFT ); orientation = ReadEnum( aProps, wxT( "ORIENTATION" ), 0, 3, ASCH_RECORD_ORIENTATION::RIGHTWARDS ); location = wxPoint( ReadKiCadUnitFrac( aProps, wxT( "LOCATION.X" ) ), -ReadKiCadUnitFrac( aProps, wxT( "LOCATION.Y" ) ) ); } ASCH_IMPLEMENTATION::ASCH_IMPLEMENTATION( const std::map& aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::IMPLEMENTATION ); ownerindex = ALTIUM_PARSER::ReadInt( aProps, wxT( "OWNERINDEX" ), ALTIUM_COMPONENT_NONE ); name = ALTIUM_PARSER::ReadString( aProps, wxT( "MODELNAME" ), wxEmptyString ); type = ALTIUM_PARSER::ReadString( aProps, wxT( "MODELTYPE" ), wxEmptyString ); libname = ALTIUM_PARSER::ReadString( aProps, wxT( "MODELDATAFILE0" ), wxEmptyString ); isCurrent = ALTIUM_PARSER::ReadBool( aProps, wxT( "ISCURRENT" ), false ); } ASCH_IMPLEMENTATION_LIST::ASCH_IMPLEMENTATION_LIST( const std::map& aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::IMPLEMENTATION_LIST ); ownerindex = ReadOwnerIndex( aProps ); } ASCH_BUS_ENTRY::ASCH_BUS_ENTRY( const std::map& aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::BUS_ENTRY ); location = wxPoint( ReadKiCadUnitFrac( aProps, wxT( "LOCATION.X" ) ), -ReadKiCadUnitFrac( aProps, wxT( "LOCATION.Y" ) ) ); corner = wxPoint( ReadKiCadUnitFrac( aProps, wxT( "CORNER.X" ) ), -ReadKiCadUnitFrac( aProps, wxT( "CORNER.Y" ) ) ); } ASCH_PARAMETER::ASCH_PARAMETER( const std::map& aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::PARAMETER ); ownerindex = ReadOwnerIndex( aProps ); ownerpartid = ReadOwnerPartId( aProps ); location = wxPoint( ReadKiCadUnitFrac( aProps, wxT( "LOCATION.X" ) ), -ReadKiCadUnitFrac( aProps, wxT( "LOCATION.Y" ) ) ); justification = ReadEnum( aProps, wxT( "JUSTIFICATION" ), 0, 8, ASCH_LABEL_JUSTIFICATION::BOTTOM_LEFT ); orientation = ReadEnum( aProps, wxT( "ORIENTATION" ), 0, 3, ASCH_RECORD_ORIENTATION::RIGHTWARDS ); name = ALTIUM_PARSER::ReadString( aProps, wxT( "NAME" ), wxEmptyString ); text = ALTIUM_PARSER::ReadString( aProps, wxT( "TEXT" ), wxEmptyString ); isHidden = ALTIUM_PARSER::ReadBool( aProps, wxT( "ISHIDDEN" ), false ); isMirrored = ALTIUM_PARSER::ReadBool( aProps, wxT( "ISMIRRORED" ), false ); isShowName = ALTIUM_PARSER::ReadBool( aProps, wxT( "SHOWNAME" ), false ); }