40#include <wx/mstream.h> 
   52                                                             "BOM_Manufacturer Part",
 
 
   74static std::vector<std::vector<wxString>> 
RegexMatchAll( wxRegEx& aRegex, 
const wxString& aString )
 
   76    std::vector<std::vector<wxString>> allMatches;
 
   82    wxString str = aString;
 
   84    while( aRegex.Matches( str ) )
 
   86        std::vector<wxString> matches;
 
   87        aRegex.GetMatch( &start, &len );
 
   89        for( 
size_t i = 0; i < aRegex.GetMatchCount(); i++ )
 
   90            matches.emplace_back( aRegex.GetMatch( str, i ) );
 
   92        allMatches.emplace_back( matches );
 
   94        prevstart = start + len;
 
   95        str = str.Mid( prevstart );
 
 
  109static std::vector<std::pair<wxString, std::vector<double>>>
 
  112    wxRegEx transformRegex( 
"(rotate|translate|scale)\\(([\\w\\s,\\.\\-]*)\\)", wxRE_ICASE );
 
  113    std::vector<std::vector<wxString>> allMatches = 
RegexMatchAll( transformRegex, transformData );
 
  115    std::vector<std::pair<wxString, std::vector<double>>> transformCmds;
 
  117    for( 
int cmdId = allMatches.size() - 1; cmdId >= 0; cmdId-- )
 
  119        std::vector<wxString>& groups = allMatches[cmdId];
 
  121        if( groups.size() != 3 )
 
  124        const wxString& cmdName = groups[1].Strip( wxString::both ).Lower();
 
  125        const wxString& cmdArgsStr = groups[2];
 
  127        wxArrayString       cmdParts = wxSplit( cmdArgsStr, 
',', 
'\0' );
 
  128        std::vector<double> cmdArgs;
 
  130        for( 
const wxString& cmdPart : cmdParts )
 
  133            wxASSERT( cmdPart.Strip( wxString::both ).ToCDouble( &arg ) );
 
  135            cmdArgs.push_back( arg );
 
  138        transformCmds.emplace_back( cmdName, cmdArgs );
 
  141    return transformCmds;
 
 
  149    wxString key = !aLibName.empty() ? ( aLibName + 
':' + libReference ) : libReference;
 
  152    libId.
Parse( key, 
true );
 
 
  160    if( aStyle == wxS( 
"0" ) )
 
  162    else if( aStyle == wxS( 
"1" ) )
 
  164    else if( aStyle == wxS( 
"2" ) )
 
 
  173    if( aType == wxS( 
"0" ) )
 
  175    else if( aType == wxS( 
"1" ) )
 
  177    else if( aType == wxS( 
"2" ) )
 
  179    else if( aType == wxS( 
"3" ) )
 
  181    else if( aType == wxS( 
"4" ) )
 
 
  373            aReporter->
Report( 
_( 
"Power Port with unknown style imported as 'Bar' type." ),
 
 
  395                                            std::map<wxString, wxString> paramMap,
 
  396                                            wxArrayString                aShapes )
 
  398    for( wxString shapeStr : aShapes )
 
  400        wxArrayString arr = wxSplit( shapeStr, 
'~', 
'\0' );
 
  402        wxString elType = arr[0];
 
  403        if( elType == wxS( 
"PL" ) || elType == wxS( 
"PG" ) )
 
  405            wxArrayString  ptArr = wxSplit( arr[1], 
' ', 
'\0' );
 
  406            wxString       strokeColor = arr[2];
 
  407            double         lineWidth = 
Convert( arr[3] );
 
  409            wxString       fillColor = arr[5].Lower();
 
  414            for( 
size_t i = 1; i < ptArr.size(); i += 2 )
 
  422            if( elType == wxS( 
"PG" ) )
 
  423                chain.SetClosed( 
true );
 
  425            if( 
chain.PointCount() < 2 )
 
  428            for( 
int i = 0; i < 
chain.PointCount(); i++ )
 
  429                line->AddPoint( 
chain.CPoint( i ) );
 
  431            if( 
chain.IsClosed() )
 
  432                line->AddPoint( 
chain.CPoint( 0 ) );
 
  437            if( fillColor != wxS( 
"none" ) )
 
  439                line->SetFilled( 
true );
 
  441                if( fillColor == strokeColor )
 
  449        else if( elType == wxS( 
"PT" ) ) 
 
  451            wxString   pointsData = arr[1];
 
  452            wxString   strokeColor = arr[2];
 
  453            double     lineWidth = 
Convert( arr[3] );
 
  455            wxString   fillColor = arr[5].Lower();
 
  458            std::vector<SHAPE_LINE_CHAIN> lineChains =
 
  465                if( outline.IsClosed() )
 
  466                    outline.Append( outline.CPoint( 0 ), 
true );
 
  468                for( 
const VECTOR2I& pt : outline.CPoints() )
 
  469                    shape->AddPoint( pt );
 
  474                if( fillColor != wxS( 
"none" ) )
 
  476                    shape->SetFilled( 
true );
 
  478                    if( fillColor == strokeColor )
 
  487        else if( elType == wxS( 
"Pimage" ) )
 
  492            wxString imageUrl = arr[10];
 
  494            if( imageUrl.BeforeFirst( 
':' ) == wxS( 
"data" ) )
 
  496                wxArrayString paramsArr =
 
  497                        wxSplit( imageUrl.AfterFirst( 
':' ).BeforeFirst( 
',' ), 
';', 
'\0' );
 
  499                wxString data = imageUrl.AfterFirst( 
',' );
 
  501                if( paramsArr.size() > 0 )
 
  503                    wxString       mimeType = paramsArr[0];
 
  504                    wxMemoryBuffer buf = wxBase64Decode( data );
 
  506                    if( mimeType == wxS( 
"image/svg+xml" ) )
 
  522                        libsymImporter.
SetScale( pixelScale );
 
  531                        for( std::unique_ptr<EDA_ITEM>& item : libsymImporter.
GetItems() )
 
  536                        wxMemoryInputStream memis( buf.GetData(), buf.GetDataLen() );
 
  538                        wxImage::SetDefaultLoadFlags( wxImage::GetDefaultLoadFlags()
 
  539                                                      & ~wxImage::Load_Verbose );
 
  541                        if( img.LoadFile( memis, mimeType ) )
 
  543                            int    dimMul = img.GetWidth() * img.GetHeight();
 
  544                            double maxPixels = 30000;
 
  546                            if( dimMul > maxPixels )
 
  548                                double scale = sqrt( maxPixels / dimMul );
 
  549                                img.Rescale( img.GetWidth() * 
scale, img.GetHeight() * 
scale );
 
  562        else if( elType == wxS( 
"A" ) )
 
  564            wxString   data = arr[1];
 
  565            wxString   strokeColor = arr[3];
 
  566            double     lineWidth = 
Convert( arr[4] );
 
  568            wxString   fillColor = arr[6].Lower();
 
  571            std::vector<SHAPE_LINE_CHAIN> chains =
 
  574            auto transform = []( 
VECTOR2I aVec )
 
  581                for( 
int i = 0; i <= 
chain.PointCount() && i != -1; i = 
chain.NextShape( i ) )
 
  583                    if( 
chain.IsArcStart( i ) )
 
  587                        std::unique_ptr<SCH_SHAPE> shape =
 
  590                        shape->SetArcGeometry( transform( arc.
GetP0() ),
 
  592                                               transform( arc.
GetP1() ) );
 
  597                        if( fillColor != wxS( 
"none" ) )
 
  599                            shape->SetFilled( 
true );
 
  601                            if( fillColor == strokeColor )
 
  613                        std::unique_ptr<SCH_SHAPE> shape =
 
  616                        shape->AddPoint( transform( seg.
A ) );
 
  617                        shape->AddPoint( transform( seg.
B ) );
 
  627        else if( elType == wxS( 
"R" ) )
 
  632            cr.
x = !arr[3].empty() ? 
Convert( arr[3] ) : 0,
 
  633            cr.
y = !arr[4].empty() ? 
Convert( arr[4] ) : 0; 
 
  636            wxString   strokeColor = arr[7];
 
  637            double     lineWidth = 
Convert( arr[8] );
 
  639            wxString   fillColor = arr[10].Lower();
 
  647                rect->SetEnd( 
RelPosSym( start + size ) );
 
  652                if( fillColor != wxS( 
"none" ) )
 
  654                    rect->SetFilled( 
true );
 
  656                    if( fillColor == strokeColor )
 
  666        else if( elType == wxS( 
"E" ) )
 
  672            wxString   strokeColor = arr[5];
 
  673            double     lineWidth = 
Convert( arr[6] );
 
  675            wxString   fillColor = arr[8].Lower();
 
  684            if( fillColor != wxS( 
"none" ) )
 
  686                circle->SetFilled( 
true );
 
  688                if( fillColor == strokeColor )
 
  696        else if( elType == wxS( 
"P" ) )
 
  698            wxString sepShapeStr = shapeStr;
 
  699            sepShapeStr.Replace( wxS( 
"^^" ), wxS( 
"\n" ) );
 
  701            wxArrayString segments = wxSplit( sepShapeStr, 
'\n', 
'\0' );
 
  702            wxArrayString mainParts = wxSplit( segments[0], 
'~', 
'\0' );
 
  703            wxArrayString pinDotParts = wxSplit( segments[1], 
'~', 
'\0' );
 
  704            wxArrayString pinPathColorParts = wxSplit( segments[2], 
'~', 
'\0' );
 
  705            wxArrayString pinNameParts = wxSplit( segments[3], 
'~', 
'\0' );
 
  706            wxArrayString pinNumParts = wxSplit( segments[4], 
'~', 
'\0' );
 
  710            wxString           pinNumber = mainParts[3];
 
  716            bool     nameVisible = pinNameParts[0] != wxS( 
"0" );
 
  717            wxString pinName = pinNameParts[4];
 
  719            bool     numVisible = pinNumParts[0] != wxS( 
"0" );
 
  723            bool     vertical = 
false;
 
  727            wxString lineData = pinPathColorParts[0];
 
  728            wxRegEx  regex( wxS( 
"^M\\s*([-\\d.]+)[,\\s]([-\\d.]+)\\s*([h|v])\\s*([-\\d.]+)\\s*$" ) );
 
  730            if( regex.Matches( lineData ) )
 
  732                startPoint.
x = 
Convert( regex.GetMatch( lineData, 1 ) );
 
  733                startPoint.
y = 
Convert( regex.GetMatch( lineData, 2 ) );
 
  735                vertical = regex.GetMatch( lineData, 3 ).Contains( wxS( 
"v" ) );
 
  736                pinLen = 
Convert( regex.GetMatch( lineData, 4 ) );
 
  743                if( startPoint.
x == pinPos.
x && pinLen < 0 )
 
  745                else if( startPoint.
x == pinPos.
x && pinLen > 0 )
 
  747                else if( startPoint.
x != pinPos.
x && pinLen < 0 )
 
  749                else if( startPoint.
x != pinPos.
x && pinLen > 0 )
 
  754                if( startPoint.
y == pinPos.
y && pinLen < 0 )
 
  756                else if( startPoint.
y == pinPos.
y && pinLen > 0 )
 
  758                else if( startPoint.
y != pinPos.
y && pinLen < 0 )
 
  760                else if( startPoint.
y != pinPos.
y && pinLen > 0 )
 
  766            if( pinRotation == 0 )
 
  768            else if( pinRotation == 90 )
 
  770            else if( pinRotation == 180 )
 
  772            else if( pinRotation == 270 )
 
  778            if( segments.size() > 5 )
 
  780                wxArrayString dotParts = wxSplit( segments[5], 
'~', 
'\0' );
 
  781                wxArrayString clockParts = wxSplit( segments[6], 
'~', 
'\0' );
 
  783                if( dotParts.size() == 3 && clockParts.size() == 2 )
 
  785                    if( dotParts[0] == wxS( 
"1" ) )
 
  793                                pinPos + ( dotPos - pinPos ).Resize( 
std::abs( pinLen ) ) ) );
 
  800                    if( clockParts[0] == wxS( 
"1" ) )
 
  802                        std::vector<SHAPE_LINE_CHAIN> lineChains =
 
  809                            if( outline.IsClosed() )
 
  810                                outline.Append( outline.CPoint( 0 ), 
true );
 
  812                            for( 
const VECTOR2I& pt : outline.CPoints() )
 
  813                                shape->AddPoint( pt );
 
  823            std::unique_ptr<SCH_PIN> 
pin = std::make_unique<SCH_PIN>( aSymbol );
 
  825            pin->SetName( pinName );
 
  826            pin->SetNumber( pinNumber );
 
  827            pin->SetOrientation( orient );
 
  828            pin->SetType( elecType );
 
  829            pin->SetLength( kPinLen );
 
  831            pin->SetUnit( pinUnit );
 
  833            if( 
pin->GetNumberTextSize() * 
int( pinNumber.size() ) > kPinLen )
 
  834                pin->SetNumberTextSize( kPinLen / pinNumber.size() );
 
  844        else if( elType == wxS( 
"T" ) )
 
  846            wxString textType = arr[1];
 
  850            wxString fontname = arr[6];
 
  851            wxString fontSize = arr[7];
 
  852            wxString baselineAlign = arr[10];
 
  853            wxString textStr = arr[12];
 
  854            bool     visible = arr[13] != wxS( 
"0" );
 
  856            textStr.Replace( wxS( 
"\\n" ), wxS( 
"\n" ) );
 
  859            wxString halignStr = arr[14]; 
 
  864            if( textType == wxS( 
"P" ) )
 
  870            else if( textType == wxS( 
"N" ) )
 
  885            if( halignStr == wxS( 
"middle" ) )
 
  887            else if( halignStr == wxS( 
"end" ) )
 
  897            if( !fontSize.IsEmpty() )
 
  899                if( fontSize.EndsWith( wxS( 
"pt" ) ) )
 
  900                    ptSize = 
Convert( fontSize.BeforeFirst( 
'p' ) );
 
  901                else if( fontSize.IsNumber() )
 
  907            if( textStr.Contains( wxS( 
"\n" ) ) )
 
 
  924                                             std::map<wxString, wxString> aParams,
 
  925                                             wxArrayString                aShapes )
 
  927    std::unique_ptr<LIB_SYMBOL> ksymbol = std::make_unique<LIB_SYMBOL>( wxEmptyString );
 
  931    std::optional<wxString> valOpt;
 
  932    wxString                symbolName = wxS( 
"Unknown" );
 
  934    if( ( valOpt = 
get_opt( aParams, wxS( 
"name" ) ) ) )
 
  935        symbolName = *valOpt;
 
  936    else if( ( valOpt = 
get_opt( aParams, wxS( 
"spiceSymbolName" ) ) ) )
 
  937        symbolName = *valOpt;
 
  939    wxString symbolPrefix;
 
  941    if( ( valOpt = 
get_opt( aParams, wxS( 
"pre" ) ) ) )
 
  942        symbolPrefix = *valOpt;
 
  943    else if( ( valOpt = 
get_opt( aParams, wxS( 
"spicePre" ) ) ) )
 
  944        symbolPrefix = *valOpt;
 
  948    ksymbol->SetLibId( libId );
 
  949    ksymbol->SetName( symbolName );
 
  951    ksymbol->GetReferenceField().SetText( symbolPrefix );
 
  952    ksymbol->GetValueField().SetText( symbolName );
 
  956        wxString srcName = attrName;
 
  958        if( srcName == wxS( 
"Datasheet" ) )
 
  959            srcName = wxS( 
"link" );
 
  961        if( ( valOpt = 
get_opt( aParams, srcName ) ) )
 
  963            if( valOpt->empty() )
 
  966            SCH_FIELD* fd = ksymbol->FindFieldCaseInsensitive( attrName );
 
  971                ksymbol->AddField( fd );
 
  981    return ksymbol.release();
 
 
  985                                                                  const wxString& aNetname )
 
  987    std::unique_ptr<LIB_SYMBOL> ksymbol = std::make_unique<LIB_SYMBOL>( wxEmptyString );
 
  993    ksymbol->SetGlobalPower();
 
  994    ksymbol->SetLibId( libId );
 
  995    ksymbol->SetName( aNetname );
 
  996    ksymbol->GetReferenceField().SetText( wxS( 
"#PWR" ) );
 
  997    ksymbol->GetReferenceField().SetVisible( 
false );
 
  998    ksymbol->GetValueField().SetText( aNetname );
 
  999    ksymbol->GetValueField().SetVisible( 
true );
 
 1000    ksymbol->SetDescription( wxString::Format( 
_( 
"Power symbol creates a global " 
 1001                                                  "label with name '%s'" ),
 
 1003    ksymbol->SetKeyWords( wxS( 
"power-flag" ) );
 
 1004    ksymbol->SetShowPinNames( 
false );
 
 1005    ksymbol->SetShowPinNumbers( 
false );
 
 1007    std::unique_ptr<SCH_PIN> 
pin = std::make_unique<SCH_PIN>( ksymbol.get() );
 
 1009    pin->SetName( aNetname );
 
 1010    pin->SetNumber( wxS( 
"1" ) );
 
 1013    pin->SetLength( 0 );
 
 1015    ksymbol->AddDrawItem( 
pin.release() );
 
 1021    if( aFlagTypename == wxS( 
"part_netLabel_gnD" ) )
 
 1025    else if( aFlagTypename == wxS( 
"part_netLabel_GNd" ) )
 
 1029    else if( aFlagTypename == wxS( 
"part_netLabel_gNd" ) )
 
 1033    else if( aFlagTypename == wxS( 
"part_netLabel_GnD" ) )
 
 1037    else if( aFlagTypename == wxS( 
"part_netLabel_VCC" ) )
 
 1042    else if( aFlagTypename == wxS( 
"part_netLabel_+5V" ) )
 
 1047    else if( aFlagTypename == wxS( 
"part_netLabel_VEE" ) )
 
 1051    else if( aFlagTypename == wxS( 
"part_netLabel_-5V" ) )
 
 1055    else if( aFlagTypename == wxS( 
"part_netLabel_Bar" ) )
 
 1062    ksymbol->GetValueField().SetPosition( valueFieldPos );
 
 1064    return std::make_pair( ksymbol.release(), flip );
 
 
 1068                                         const wxString& aFileName, wxArrayString aShapes )
 
 1070    std::map<wxString, std::unique_ptr<LIB_SYMBOL>> loadedSymbols;
 
 1071    std::map<wxString, int>                         namesCounter;
 
 1072    std::vector<std::unique_ptr<SCH_ITEM>>          createdItems;
 
 1074    for( wxString shap : aShapes )
 
 1076        shap.Replace( wxS( 
"#@$" ), wxS( 
"\n" ) );
 
 1077        wxArrayString parts = wxSplit( shap, 
'\n', 
'\0' );
 
 1079        if( parts.size() < 1 )
 
 1082        wxArrayString arr = wxSplit( parts[0], 
'~', 
'\0' );
 
 1084        if( arr.size() < 1 )
 
 1087        wxString rootType = arr[0];
 
 1089        if( rootType == wxS( 
"LIB" ) )
 
 1091            if( arr.size() < 4 )
 
 1096            wxString symbolName = wxString::Format( wxS( 
"Unknown_%s_%s" ), arr[1], arr[2] );
 
 1098            wxArrayString paramParts = wxSplit( arr[3], 
'`', 
'\0' );
 
 1100            std::map<wxString, wxString> paramMap;
 
 1102            for( 
size_t i = 1; i < paramParts.size(); i += 2 )
 
 1104                wxString key = paramParts[i - 1];
 
 1105                wxString value = paramParts[i];
 
 1107                if( key == wxS( 
"spiceSymbolName" ) && !value.IsEmpty() )
 
 1110                paramMap[key] = value;
 
 1113            int& serial = namesCounter[symbolName];
 
 1116                symbolName << wxS( 
"_" ) << serial;
 
 1120            paramMap[wxS( 
"spiceSymbolName" )] = symbolName;
 
 1122            parts.RemoveAt( 0 );
 
 1127            loadedSymbols.emplace( symbolName, sym );
 
 1134            std::unique_ptr<SCH_SYMBOL> schSym =
 
 1135                    std::make_unique<SCH_SYMBOL>( *sym, libId, &aSchematic->
CurrentSheet(), 0 );
 
 1137            schSym->SetPosition( 
RelPos( origin ) );
 
 1138            schSym->SetRef( &aSchematic->
CurrentSheet(), referenceStr );
 
 1140            createdItems.push_back( std::move( schSym ) );
 
 1142        else if( rootType == wxS( 
"F" ) )
 
 1144            wxString sepShapeStr = parts[0];
 
 1145            sepShapeStr.Replace( wxS( 
"^^" ), wxS( 
"\n" ) );
 
 1147            wxArrayString segments = wxSplit( sepShapeStr, 
'\n', 
'\0' );
 
 1150            wxArrayString valueParts = wxSplit( segments[2], 
'~', 
'\0' );
 
 1152            wxString flagTypename = arr[1];
 
 1154            double   angle = 
Convert( arr[4] );
 
 1156            wxString netnameValue = valueParts[0];
 
 1158            double   textAngle = 
Convert( valueParts[4] );
 
 1159            wxString halignStr = valueParts[5];
 
 1160            wxString valueFontname = valueParts[7];
 
 1161            wxString valueFontsize = valueParts[8];
 
 1163            if( flagTypename == wxS( 
"part_netLabel_netPort" ) )
 
 1165                std::unique_ptr<SCH_GLOBALLABEL> label =
 
 1166                        std::make_unique<SCH_GLOBALLABEL>( 
RelPos( pos ), netnameValue );
 
 1170                for( 
double i = angle; i > 0; i -= 90 )
 
 1174                if( segments.size() > 3 )
 
 1176                    wxArrayString shapeParts = wxSplit( segments[3], 
'~', 
'\0' );
 
 1177                    if( shapeParts[0] == wxS( 
"PL" ) )
 
 1179                        wxArrayString ptArr = wxSplit( shapeParts[1], 
' ', 
'\0' );
 
 1183                        for( 
size_t i = 1; i < ptArr.size(); i += 2 )
 
 1195                            if( shapeCenter.
x >= 0 )
 
 1202                            if( shapeCenter.
y >= 0 )
 
 1210                label->SetSpinStyle( spin );
 
 1213                createdItems.push_back( std::move( label ) );
 
 1219                bool        flip = pair.second;
 
 1223                std::unique_ptr<SCH_SYMBOL> schSym = std::make_unique<SCH_SYMBOL>(
 
 1232                else if( angle == 90 )
 
 1246                schSym->SetPosition( 
RelPos( pos ) );
 
 1258                if( halignStr == wxS( 
"middle" ) )
 
 1260                else if( halignStr == wxS( 
"end" ) )
 
 1265                if( flip && ( angle == 90 || angle == 270 ) )
 
 1277                    if( flagTypename == wxS( 
"part_netLabel_Bar" ) ) 
 
 1281                if( angle == 0 && flagTypename == wxS( 
"part_netLabel_Bar" ) ) 
 
 1288                if( valueFontsize.EndsWith( wxS( 
"pt" ) ) )
 
 1289                    ptSize = 
Convert( valueFontsize.BeforeFirst( 
'p' ) );
 
 1293                if( netnameValue.Contains( wxS( 
"\n" ) ) )
 
 1302                createdItems.push_back( std::move( schSym ) );
 
 1305        else if( rootType == wxS( 
"W" ) )
 
 1307            wxArrayString ptArr = wxSplit( arr[1], 
' ', 
'\0' );
 
 1316            for( 
size_t i = 1; i < ptArr.size(); i += 2 )
 
 1319            for( 
int segId = 0; segId < 
chain.SegmentCount(); segId++ )
 
 1321                const SEG& seg = 
chain.CSegment( segId );
 
 1323                std::unique_ptr<SCH_LINE> line = std::make_unique<SCH_LINE>( seg.
A, 
LAYER_WIRE );
 
 1324                line->SetEndPoint( seg.
B );
 
 1326                createdItems.push_back( std::move( line ) );
 
 1329        else if( rootType == wxS( 
"N" ) )
 
 1332            double   angle = 
Convert( arr[3] );
 
 1333            wxString netname = arr[5];
 
 1334            wxString halignStr = arr[7];
 
 1341            std::unique_ptr<SCH_LABEL> label =
 
 1342                    std::make_unique<SCH_LABEL>( 
RelPos( pos ), netname );
 
 1344            if( halignStr == wxS( 
"middle" ) )
 
 1346            else if( halignStr == wxS( 
"end" ) )
 
 1352                label->Rotate90( 
false );
 
 1354            createdItems.push_back( std::move( label ) );
 
 1356        else if( rootType == wxS( 
"O" ) )
 
 1360            std::unique_ptr<SCH_NO_CONNECT> noConn =
 
 1361                    std::make_unique<SCH_NO_CONNECT>( 
RelPos( pos ) );
 
 1363            createdItems.push_back( std::move( noConn ) );
 
 1365        else if( rootType == wxS( 
"J" ) )
 
 1370            std::unique_ptr<SCH_JUNCTION> junction =
 
 1371                    std::make_unique<SCH_JUNCTION>( 
RelPos( pos )  );
 
 1373            createdItems.push_back( std::move( junction ) );
 
 1375        else if( rootType == wxS( 
"T" ) )
 
 1378            int      angle = 
Convert( arr[4] );
 
 1380            wxString fontname = arr[6];
 
 1381            wxString fontSize = arr[7];
 
 1382            wxString baselineAlign = arr[10];
 
 1383            wxString textStr = arr[12];
 
 1385            textStr.Replace( wxS( 
"\\n" ), wxS( 
"\n" ) );
 
 1388            wxString halignStr = arr[14]; 
 
 1390            std::unique_ptr<SCH_TEXT> textItem =
 
 1391                    std::make_unique<SCH_TEXT>( 
RelPos( pos ), textStr );
 
 1393            textItem->SetTextAngleDegrees( ( 360 - angle ) % 360 );
 
 1396            if( halignStr == wxS( 
"middle" ) )
 
 1398            else if( halignStr == wxS( 
"end" ) )
 
 1407            if( fontSize.EndsWith( wxS( 
"pt" ) ) )
 
 1408                ptSize = 
Convert( fontSize.BeforeFirst( 
'p' ) );
 
 1412            if( textStr.Contains( wxS( 
"\n" ) ) )
 
 1417            textItem->SetTextSize( 
VECTOR2I( ktextSize, ktextSize ) );
 
 1421            createdItems.push_back( std::move( textItem ) );
 
 1423        else if( rootType == wxS( 
"R" ) )
 
 1428            cr.
x = !arr[3].empty() ? 
Convert( arr[3] ) : 0,
 
 1429            cr.
y = !arr[4].empty() ? 
Convert( arr[4] ) : 0; 
 
 1432            wxString   strokeColor = arr[7];
 
 1433            double     lineWidth = 
Convert( arr[8] );
 
 1435            wxString   fillColor = arr[10].Lower();
 
 1442                rect->SetStart( 
RelPos( start ) );
 
 1443                rect->SetEnd( 
RelPos( start + size ) );
 
 1447                if( fillColor != wxS( 
"none" ) )
 
 1449                    rect->SetFilled( 
true );
 
 1451                    if( fillColor == strokeColor )
 
 1457                createdItems.push_back( std::move( rect ) );
 
 1463        else if( rootType == wxS( 
"I" ) )
 
 1468            wxString imageUrl = arr[6];
 
 1469            wxString transformData = arr[9];
 
 1474            std::vector<std::pair<wxString, std::vector<double>>> transformCmds =
 
 1477            auto applyTransform = [&]( 
SCH_ITEM* aSchItem )
 
 1479                for( 
const auto& cmd : transformCmds )
 
 1481                    if( cmd.first == wxS( 
"rotate" ) )
 
 1483                        if( cmd.second.size() != 3 )
 
 1486                        double   cmdAngle = 360 - cmd.second[0];
 
 1487                        VECTOR2D cmdAround( cmd.second[1], cmd.second[2] );
 
 1489                        for( 
double i = cmdAngle; i > 0; i -= 90 )
 
 1495                                aSchItem->Rotate( 
RelPos( cmdAround ), 
false );
 
 1499                                aSchItem->Rotate( 
RelPos( cmdAround ), 
false );
 
 1504                                aSchItem->Rotate( 
RelPos( cmdAround ), 
false );
 
 1508                    else if( cmd.first == wxS( 
"translate" ) )
 
 1510                        if( cmd.second.size() != 2 )
 
 1513                        VECTOR2D cmdOffset( cmd.second[0], cmd.second[1] );
 
 1514                        aSchItem->Move( 
ScalePos( cmdOffset ) );
 
 1516                    else if( cmd.first == wxS( 
"scale" ) )
 
 1518                        if( cmd.second.size() != 2 )
 
 1521                        double cmdScaleX = cmd.second[0];
 
 1522                        double cmdScaleY = cmd.second[1];
 
 1528                        if( cmdScaleX < 0 && cmdScaleY > 0 )
 
 1530                            aSchItem->MirrorHorizontally( 0 );
 
 1532                        else if( cmdScaleX > 0 && cmdScaleY < 0 )
 
 1534                            aSchItem->MirrorVertically( 0 );
 
 1536                        else if( cmdScaleX < 0 && cmdScaleY < 0 )
 
 1538                            aSchItem->MirrorHorizontally( 0 );
 
 1539                            aSchItem->MirrorVertically( 0 );
 
 1548            if( imageUrl.BeforeFirst( 
':' ) == wxS( 
"data" ) )
 
 1550                wxArrayString paramsArr =
 
 1551                        wxSplit( imageUrl.AfterFirst( 
':' ).BeforeFirst( 
',' ), 
';', 
'\0' );
 
 1553                wxString data = imageUrl.AfterFirst( 
',' );
 
 1555                if( paramsArr.size() > 0 )
 
 1557                    wxString       mimeType = paramsArr[0];
 
 1558                    wxMemoryBuffer buf = wxBase64Decode( data );
 
 1560                    if( mimeType == wxS( 
"image/svg+xml" ) )
 
 1576                        schImporter.
SetScale( pixelScale );
 
 1583                        svgImportPlugin.
Import();
 
 1585                        for( std::unique_ptr<EDA_ITEM>& item : schImporter.
GetItems() )
 
 1589                            applyTransform( schItem );
 
 1591                            createdItems.emplace_back( schItem );
 
 1596                        std::unique_ptr<SCH_BITMAP> bitmap = std::make_unique<SCH_BITMAP>();
 
 1599                        wxImage::SetDefaultLoadFlags( wxImage::GetDefaultLoadFlags()
 
 1600                                                      & ~wxImage::Load_Verbose );
 
 1604                            VECTOR2D kcenter = kstart + ksize / 2;
 
 1608                            bitmap->SetPosition( kcenter );
 
 1610                            applyTransform( bitmap.get() );
 
 1612                            createdItems.push_back( std::move( bitmap ) );
 
 1622    for( std::unique_ptr<SCH_ITEM>& ptr : createdItems )
 
 1632    offset.
x = 
KiROUND( offset.
x / alignGrid ) * alignGrid;
 
 1633    offset.
y = 
KiROUND( offset.
y / alignGrid ) * alignGrid;
 
 1640    for( std::unique_ptr<SCH_ITEM>& ptr : createdItems )
 
 1642        ptr->Move( offset );
 
 1643        screen->
Append( ptr.release() );
 
 
constexpr EDA_IU_SCALE schIUScale
 
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
 
constexpr size_type GetWidth() const
 
constexpr BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
 
constexpr size_type GetHeight() const
 
constexpr coord_type GetLeft() const
 
constexpr coord_type GetTop() const
 
static double Convert(const wxString &aValue)
 
double RelPosX(double aValue)
 
double RelPosY(double aValue)
 
VECTOR2< T > RelPos(const VECTOR2< T > &aVec)
 
VECTOR2< T > ScalePos(const VECTOR2< T > &aValue)
 
void TransformTextToBaseline(EDA_TEXT *textItem, const wxString &baselineAlign)
 
std::vector< SHAPE_LINE_CHAIN > ParseLineChains(const wxString &aData, int aMaxError, bool aForceClosed)
 
void SetBezierC2(const VECTOR2I &aPt)
 
void SetStart(const VECTOR2I &aStart)
 
void SetEnd(const VECTOR2I &aEnd)
 
void SetBezierC1(const VECTOR2I &aPt)
 
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
 
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)
 
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
 
GR_TEXT_H_ALIGN_T GetHorizJustify() const
 
virtual void SetVisible(bool aVisible)
 
void SetTextAngleDegrees(double aOrientation)
 
GR_TEXT_V_ALIGN_T GetVertJustify() const
 
virtual void SetText(const wxString &aText)
 
void SetFont(KIFONT::FONT *aFont)
 
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
 
void SetImportOffsetMM(const VECTOR2D &aOffset)
Set the offset in millimeters to add to coordinates when importing graphic items.
 
void SetScale(const VECTOR2D &aScale)
Set the scale factor affecting the imported shapes.
 
std::list< std::unique_ptr< EDA_ITEM > > & GetItems()
Return the list of objects representing the imported shapes.
 
virtual void SetImporter(GRAPHICS_IMPORTER *aImporter)
Set the receiver of the imported shapes.
 
static FONT * GetFont(const wxString &aFontName=wxEmptyString, bool aBold=false, bool aItalic=false, const std::vector< wxString > *aEmbeddedFiles=nullptr, bool aForDrawingSheet=false)
 
A logical library item identifier and consists of various portions much like a URI.
 
int Parse(const UTF8 &aId, bool aFix=false)
Parse LIB_ID with the information from aId.
 
Define a library symbol object.
 
SCH_FIELD & GetValueField()
Return reference to the value field.
 
void AddDrawItem(SCH_ITEM *aItem, bool aSort=true)
Add a new draw aItem to the draw object list and sort according to aSort.
 
SCH_FIELD & GetReferenceField()
Return reference to the reference designator field.
 
Describe the page size and margins of a paper page on which to eventually print or plot.
 
void SetHeightMils(double aHeightInMils)
 
void SetWidthMils(double aWidthInMils)
 
A progress reporter interface for use in multi-threaded environments.
 
A REFERENCE_IMAGE is a wrapper around a BITMAP_IMAGE that is displayed in an editor as a reference fo...
 
bool ReadImageFile(const wxString &aFullFilename)
Read and store an image file.
 
void SetImageScale(double aScale)
Set the image "zoom" value.
 
A pure virtual class used to derive REPORTER objects from.
 
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Report a string with a given severity.
 
Holds all the data relating to one schematic.
 
SCH_SHEET_PATH & CurrentSheet() const
 
void ParseSymbolShapes(LIB_SYMBOL *aContainer, std::map< wxString, wxString > paramMap, wxArrayString aShapes)
 
std::pair< LIB_SYMBOL *, bool > MakePowerSymbol(const wxString &aFlagTypename, const wxString &aNetname)
 
double ScaleSize(double aValue) override
 
void ParseSchematic(SCHEMATIC *aSchematic, SCH_SHEET *aRootSheet, const wxString &aFileName, wxArrayString aShapes)
 
VECTOR2< T > RelPosSym(const VECTOR2< T > &aVec)
 
LIB_SYMBOL * ParseSymbol(const VECTOR2D &aOrigin, std::map< wxString, wxString > aParams, wxArrayString aShapes)
 
SCH_EASYEDA_PARSER(SCHEMATIC *aSchematic, PROGRESS_REPORTER *aProgressReporter)
 
void SetPosition(const VECTOR2I &aPosition) override
 
void SetText(const wxString &aText) override
 
Base class for any item which can be embedded within the SCHEMATIC container class,...
 
const PAGE_INFO & GetPageSettings() const
 
void Append(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
 
void SetPageSettings(const PAGE_INFO &aPageSettings)
 
void SetStroke(const STROKE_PARAMS &aStroke) override
 
void AddPoint(const VECTOR2I &aPosition)
 
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
 
SCH_SCREEN * GetScreen() const
 
BOX2I GetBodyBoundingBox() const override
Return a bounding box for the symbol body but not the pins or fields.
 
const VECTOR2I & GetArcMid() const
 
const VECTOR2I & GetP1() const
 
const VECTOR2I & GetP0() const
 
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
 
Simple container to manage line stroke parameters.
 
bool Import() override
Actually imports the file.
 
virtual double GetImageWidth() const override
Return image width from original imported file.
 
bool LoadFromMemory(const wxMemoryBuffer &aMemBuffer) override
Set memory buffer with content for import.
 
virtual double GetImageHeight() const override
Return image height from original imported file.
 
#define ENDPOINT
ends. (Used to support dragging.)
 
#define STARTPOINT
When a line is selected, these flags indicate which.
 
@ RECTANGLE
Use RECTANGLE instead of RECT to avoid collision in a Windows header.
 
@ FILLED_WITH_BG_BODYCOLOR
 
@ FILLED_SHAPE
Fill with object color.
 
void ConvertImageToLibShapes(LIB_SYMBOL *aSymbol, int unit, wxImage img, VECTOR2D pixelScale, VECTOR2D offset)
 
std::optional< V > get_opt(const std::map< wxString, V > &aMap, const wxString &aKey)
 
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
 
ELECTRICAL_PINTYPE
The symbol library pin object electrical types used in ERC tests.
 
@ PT_INPUT
usual pin input: must be connected
 
@ PT_BIDI
input or output (like port for a microprocessor)
 
@ PT_POWER_IN
power input (GND, VCC for ICs). Must be connected to a power output.
 
@ PT_UNSPECIFIED
unknown electrical properties: creates always a warning when connected
 
@ PT_PASSIVE
pin for passive symbols: must be connected, and can be connected to any pin.
 
PIN_ORIENTATION
The symbol library pin object orientations.
 
@ PIN_UP
The pin extends upwards from the connection point: Probably on the bottom side of the symbol.
 
@ PIN_RIGHT
The pin extends rightwards from the connection point.
 
@ PIN_LEFT
The pin extends leftwards from the connection point: Probably on the right side of the symbol.
 
@ PIN_DOWN
The pin extends downwards from the connection: Probably on the top side of the symbol.
 
static std::vector< std::vector< wxString > > RegexMatchAll(wxRegEx &aRegex, const wxString &aString)
 
static const std::vector< wxString > c_attributesWhitelist
 
static ELECTRICAL_PINTYPE ConvertElecType(const wxString &aType)
 
VECTOR2I HelperGeneratePowerPortGraphics(LIB_SYMBOL *aKsymbol, EASYEDA::POWER_FLAG_STYLE aStyle, REPORTER *aReporter)
 
static LIB_ID EasyEdaToKiCadLibID(const wxString &aLibName, const wxString &aLibReference)
 
static std::vector< std::pair< wxString, std::vector< double > > > ParseImageTransform(const wxString &transformData)
EasyEDA image transformations are in the form of:
 
static LINE_STYLE ConvertStrokeStyle(const wxString &aStyle)
 
VECTOR2I HelperGeneratePowerPortGraphics(LIB_SYMBOL *aKsymbol, ASCH_POWER_PORT_STYLE aStyle, REPORTER *aReporter)
 
wxString EscapeString(const wxString &aSource, ESCAPE_CONTEXT aContext)
The Escape/Unescape routines use HTML-entity-reference-style encoding to handle characters which are:...
 
wxString UnescapeHTML(const wxString &aString)
Return a new wxString unescaped from HTML format.
 
LINE_STYLE
Dashed line types.
 
@ SYM_ROTATE_COUNTERCLOCKWISE
 
@ USER
The field ID hasn't been set yet; field is invalid.
 
@ VALUE
Field Value of part, i.e. "3.3K".
 
const SHAPE_LINE_CHAIN chain
 
SHAPE_CIRCLE circle(c.m_circle_center, c.m_circle_radius)
 
VECTOR2< int32_t > VECTOR2I
 
VECTOR2< double > VECTOR2D