45#include <wx/mstream.h>
64static std::vector<std::vector<wxString>>
RegexMatchAll( wxRegEx& aRegex,
const wxString& aString )
66 std::vector<std::vector<wxString>> allMatches;
72 wxString str = aString;
74 while( aRegex.Matches( str ) )
76 std::vector<wxString> matches;
77 aRegex.GetMatch( &start, &len );
79 for(
size_t i = 0; i < aRegex.GetMatchCount(); i++ )
80 matches.emplace_back( aRegex.GetMatch( str, i ) );
82 allMatches.emplace_back( matches );
84 prevstart = start + len;
85 str = str.Mid( prevstart );
99static std::vector<std::pair<wxString, std::vector<double>>>
102 wxRegEx transformRegex(
"(rotate|translate|scale)\\(([\\w\\s,\\.\\-]*)\\)", wxRE_ICASE );
103 std::vector<std::vector<wxString>> allMatches =
RegexMatchAll( transformRegex, transformData );
105 std::vector<std::pair<wxString, std::vector<double>>> transformCmds;
107 for(
int cmdId = allMatches.size() - 1; cmdId >= 0; cmdId-- )
109 std::vector<wxString>& groups = allMatches[cmdId];
111 if( groups.size() != 3 )
114 const wxString& cmdName = groups[1].Strip( wxString::both ).Lower();
115 const wxString& cmdArgsStr = groups[2];
117 wxArrayString cmdParts = wxSplit( cmdArgsStr,
',',
'\0' );
118 std::vector<double> cmdArgs;
120 for(
const wxString& cmdPart : cmdParts )
123 wxASSERT( cmdPart.Strip( wxString::both ).ToCDouble( &arg ) );
125 cmdArgs.push_back( arg );
128 transformCmds.emplace_back( cmdName, cmdArgs );
131 return transformCmds;
139 wxString key = !aLibName.empty() ? ( aLibName +
':' + libReference ) : libReference;
142 libId.
Parse( key,
true );
150 if( aStyle == wxS(
"0" ) )
152 else if( aStyle == wxS(
"1" ) )
154 else if( aStyle == wxS(
"2" ) )
163 if( aType == wxS(
"0" ) )
165 else if( aType == wxS(
"1" ) )
167 else if( aType == wxS(
"2" ) )
169 else if( aType == wxS(
"3" ) )
171 else if( aType == wxS(
"4" ) )
182 if( baselineAlign == wxS(
"" ) || baselineAlign == wxS(
"auto" )
183 || baselineAlign == wxS(
"use-script" ) || baselineAlign == wxS(
"no-change" )
184 || baselineAlign == wxS(
"reset-size" ) || baselineAlign == wxS(
"alphabetic" )
185 || baselineAlign == wxS(
"inherit" ) )
189 else if( baselineAlign == wxS(
"ideographic" ) || baselineAlign == wxS(
"text-after-edge" ) )
193 else if( baselineAlign == wxS(
"central" ) )
197 else if( baselineAlign == wxS(
"middle" ) )
201 else if( baselineAlign == wxS(
"mathematical" ) )
205 else if( baselineAlign == wxS(
"hanging" ) || baselineAlign == wxS(
"text-before-edge" ) )
214 offset.
y = -offset.
y;
405 aReporter->
Report(
_(
"Power Port with unknown style imported as 'Bar' type." ),
427 std::map<wxString, wxString> paramMap,
428 wxArrayString aShapes )
430 for( wxString shapeStr : aShapes )
432 wxArrayString arr = wxSplit( shapeStr,
'~',
'\0' );
434 wxString elType = arr[0];
435 if( elType == wxS(
"PL" ) || elType == wxS(
"PG" ) )
437 wxArrayString ptArr = wxSplit( arr[1],
' ',
'\0' );
438 wxString strokeColor = arr[2];
439 double lineWidth =
Convert( arr[3] );
441 wxString fillColor = arr[5].Lower();
446 for(
size_t i = 1; i < ptArr.size(); i += 2 )
452 std::unique_ptr<LIB_SHAPE> line = std::make_unique<LIB_SHAPE>( aSymbol, SHAPE_T::POLY );
454 if( elType == wxS(
"PG" ) )
461 line->AddPoint( chain.
CPoint( i ) );
464 line->AddPoint( chain.
CPoint( 0 ) );
469 if( fillColor != wxS(
"none" ) )
471 line->SetFilled(
true );
473 if( fillColor == strokeColor )
474 line->SetFillMode( FILL_T::FILLED_SHAPE );
476 line->SetFillMode( FILL_T::FILLED_WITH_BG_BODYCOLOR );
481 else if( elType == wxS(
"PT" ) )
483 wxString pointsData = arr[1];
484 wxString strokeColor = arr[2];
485 double lineWidth =
Convert( arr[3] );
487 wxString fillColor = arr[5].Lower();
490 std::vector<SHAPE_LINE_CHAIN> lineChains =
495 std::unique_ptr<LIB_SHAPE> shape =
496 std::make_unique<LIB_SHAPE>( aSymbol, SHAPE_T::POLY );
498 outline.Mirror(
false,
true );
500 if( outline.IsClosed() )
501 outline.Append( outline.CPoint( 0 ),
true );
503 for(
const VECTOR2I& pt : outline.CPoints() )
504 shape->AddPoint( pt );
509 if( fillColor != wxS(
"none" ) )
511 shape->SetFilled(
true );
513 if( fillColor == strokeColor )
514 shape->SetFillMode( FILL_T::FILLED_SHAPE );
516 shape->SetFillMode( FILL_T::FILLED_WITH_BG_BODYCOLOR );
522 else if( elType == wxS(
"Pimage" ) )
527 wxString imageUrl = arr[10];
529 if( imageUrl.BeforeFirst(
':' ) == wxS(
"data" ) )
531 wxArrayString paramsArr =
532 wxSplit( imageUrl.AfterFirst(
':' ).BeforeFirst(
',' ),
';',
'\0' );
534 wxString data = imageUrl.AfterFirst(
',' );
536 if( paramsArr.size() > 0 )
538 wxString mimeType = paramsArr[0];
539 wxMemoryBuffer buf = wxBase64Decode( data );
541 if( mimeType == wxS(
"image/svg+xml" ) )
557 libsymImporter.
SetScale( pixelScale );
566 for( std::unique_ptr<EDA_ITEM>& item : libsymImporter.
GetItems() )
571 wxMemoryInputStream memis( buf.GetData(), buf.GetDataLen() );
573 wxImage::SetDefaultLoadFlags( wxImage::GetDefaultLoadFlags()
574 & ~wxImage::Load_Verbose );
576 if( img.LoadFile( memis, mimeType ) )
578 int dimMul = img.GetWidth() * img.GetHeight();
579 double maxPixels = 30000;
581 if( dimMul > maxPixels )
583 double scale = sqrt( maxPixels / dimMul );
584 img.Rescale( img.GetWidth() *
scale, img.GetHeight() *
scale );
597 else if( elType == wxS(
"A" ) )
599 wxString data = arr[1];
600 wxString strokeColor = arr[3];
601 double lineWidth =
Convert( arr[4] );
603 wxString fillColor = arr[6].Lower();
612 auto readNumber = [&]( wxString& aOut )
614 wxUniChar ch = data[pos];
616 while( ch ==
' ' || ch ==
',' )
619 while( isdigit( ch ) || ch ==
'.' || ch ==
'-' )
624 if( pos == data.size() )
633 wxUniChar sym = data[pos++];
643 else if( sym ==
'A' )
645 wxString radX, radY,
unknown, farFlag, cwFlag, endX, endY;
649 readNumber( farFlag );
650 readNumber( cwFlag );
654 isFar = farFlag == wxS(
"1" );
655 cw = cwFlag == wxS(
"1" );
659 }
while( pos < data.size() );
663 double d =
delta.EuclideanNorm();
664 double h = sqrt( rad.
x * rad.
x - d * d / 4 );
675 start +
delta / 2 +
delta.Perpendicular().Resize( ( isFar ^ cw ) ? h : -h );
678 std::swap( start, end );
680 std::unique_ptr<LIB_SHAPE> shape = std::make_unique<LIB_SHAPE>( aSymbol, SHAPE_T::ARC );
684 shape->SetCenter(
RelPosSym( arcCenter ) );
689 if( fillColor != wxS(
"none" ) )
691 shape->SetFilled(
true );
693 if( fillColor == strokeColor )
694 shape->SetFillMode( FILL_T::FILLED_SHAPE );
696 shape->SetFillMode( FILL_T::FILLED_WITH_BG_BODYCOLOR );
701 else if( elType == wxS(
"R" ) )
706 cr.
x = !arr[3].empty() ?
Convert( arr[3] ) : 0,
707 cr.
y = !arr[4].empty() ?
Convert( arr[4] ) : 0;
710 wxString strokeColor = arr[7];
711 double lineWidth =
Convert( arr[8] );
713 wxString fillColor = arr[10].Lower();
718 std::unique_ptr<LIB_SHAPE> rect =
719 std::make_unique<LIB_SHAPE>( aSymbol, SHAPE_T::RECTANGLE );
722 rect->SetEnd(
RelPosSym( start + size ) );
727 if( fillColor != wxS(
"none" ) )
729 rect->SetFilled(
true );
731 if( fillColor == strokeColor )
732 rect->SetFillMode( FILL_T::FILLED_SHAPE );
734 rect->SetFillMode( FILL_T::FILLED_WITH_BG_BODYCOLOR );
741 else if( elType == wxS(
"E" ) )
743 std::unique_ptr<LIB_SHAPE> circle =
744 std::make_unique<LIB_SHAPE>( aSymbol, SHAPE_T::CIRCLE );
748 wxString strokeColor = arr[5];
749 double lineWidth =
Convert( arr[6] );
751 wxString fillColor = arr[8].Lower();
754 circle->SetCenter(
RelPosSym( center ) );
757 circle->SetUnit( 0 );
760 if( fillColor != wxS(
"none" ) )
762 circle->SetFilled(
true );
764 if( fillColor == strokeColor )
765 circle->SetFillMode( FILL_T::FILLED_SHAPE );
767 circle->SetFillMode( FILL_T::FILLED_WITH_BG_BODYCOLOR );
772 else if( elType == wxS(
"P" ) )
774 wxString sepShapeStr = shapeStr;
775 sepShapeStr.Replace( wxS(
"^^" ), wxS(
"\n" ) );
777 wxArrayString segments = wxSplit( sepShapeStr,
'\n',
'\0' );
778 wxArrayString mainParts = wxSplit( segments[0],
'~',
'\0' );
779 wxArrayString pinDotParts = wxSplit( segments[1],
'~',
'\0' );
780 wxArrayString pinPathColorParts = wxSplit( segments[2],
'~',
'\0' );
781 wxArrayString pinNameParts = wxSplit( segments[3],
'~',
'\0' );
782 wxArrayString pinNumParts = wxSplit( segments[4],
'~',
'\0' );
786 wxString pinNumber = mainParts[3];
792 bool nameVisible = pinNameParts[0] != wxS(
"0" );
793 wxString pinName = pinNameParts[4];
795 bool numVisible = pinNumParts[0] != wxS(
"0" );
796 wxString ptSize = pinNumParts[4];
799 bool vertical =
false;
803 wxString lineData = pinPathColorParts[0];
805 wxS(
"^M\\s*([-\\d.]+)[,\\s]([-\\d.]+)\\s*([h|v])\\s*([-\\d.]+)\\s*$" ) );
806 if( regex.Matches( lineData ) )
808 startPoint.
x =
Convert( regex.GetMatch( lineData, 1 ) );
809 startPoint.
y =
Convert( regex.GetMatch( lineData, 2 ) );
811 vertical = regex.GetMatch( lineData, 3 ).Contains( wxS(
"v" ) );
812 pinLen =
Convert( regex.GetMatch( lineData, 4 ) );
819 if( startPoint.
x == pinPos.
x && pinLen < 0 )
821 else if( startPoint.
x == pinPos.
x && pinLen > 0 )
823 else if( startPoint.
x != pinPos.
x && pinLen < 0 )
825 else if( startPoint.
x != pinPos.
x && pinLen > 0 )
830 if( startPoint.
y == pinPos.
y && pinLen < 0 )
832 else if( startPoint.
y == pinPos.
y && pinLen > 0 )
834 else if( startPoint.
y != pinPos.
y && pinLen < 0 )
836 else if( startPoint.
y != pinPos.
y && pinLen > 0 )
842 if( pinRotation == 0 )
843 orient = PIN_ORIENTATION::PIN_RIGHT;
844 else if( pinRotation == 90 )
845 orient = PIN_ORIENTATION::PIN_UP;
846 else if( pinRotation == 180 )
847 orient = PIN_ORIENTATION::PIN_LEFT;
848 else if( pinRotation == 270 )
849 orient = PIN_ORIENTATION::PIN_DOWN;
854 std::unique_ptr<LIB_PIN>
pin = std::make_unique<LIB_PIN>( aSymbol );
856 pin->SetName( pinName );
857 pin->SetNumber( pinNumber );
858 pin->SetOrientation( orient );
859 pin->SetType( elecType );
860 pin->SetLength( kPinLen );
862 pin->SetUnit( pinUnit );
864 if(
pin->GetNumberTextSize() *
int( pinNumber.size() ) > kPinLen )
865 pin->SetNumberTextSize( kPinLen / pinNumber.size() );
875 else if( elType == wxS(
"T" ) )
877 wxString textType = arr[1];
880 wxString
color = arr[5];
881 wxString fontname = arr[6];
882 wxString fontSize = arr[7];
883 wxString baselineAlign = arr[10];
884 wxString textStr = arr[12];
886 textStr.Replace( wxS(
"\\n" ), wxS(
"\n" ) );
889 wxString halignStr = arr[14];
894 if( textType == wxS(
"P" ) )
898 else if( textType == wxS(
"N" ) )
914 if( halignStr == wxS(
"middle" ) )
916 else if( halignStr == wxS(
"end" ) )
925 if( !fontSize.IsEmpty() )
927 if( fontSize.EndsWith( wxS(
"pt" ) ) )
928 ptSize =
Convert( fontSize.BeforeFirst(
'p' ) );
929 else if( fontSize.IsNumber() )
935 if( textStr.Contains( wxS(
"\n" ) ) )
952 std::map<wxString, wxString> aParams,
953 wxArrayString aShapes )
955 std::unique_ptr<LIB_SYMBOL> ksymbol = std::make_unique<LIB_SYMBOL>( wxEmptyString );
959 wxString symbolName = wxS(
"Unknown" );
961 if( aParams.find( wxS(
"name" ) ) != aParams.end() )
962 symbolName = aParams.at( wxS(
"name" ) );
963 else if( aParams.find( wxS(
"spiceSymbolName" ) ) != aParams.end() )
964 symbolName = aParams.at( wxS(
"spiceSymbolName" ) );
966 wxString symbolPrefix;
968 if( aParams.find( wxS(
"pre" ) ) != aParams.end() )
969 symbolPrefix = aParams.at( wxS(
"pre" ) );
970 else if( aParams.find( wxS(
"spicePre" ) ) != aParams.end() )
971 symbolPrefix = aParams.at( wxS(
"spicePre" ) );
973 if( !symbolPrefix.EndsWith( wxS(
"?" ) ) )
974 symbolPrefix += wxS(
"?" );
978 ksymbol->SetLibId( libId );
979 ksymbol->SetName( symbolName );
981 ksymbol->GetReferenceField().SetText( symbolPrefix );
982 ksymbol->GetValueField().SetText( symbolName );
986 return ksymbol.release();
990 const wxString& aNetname )
992 std::unique_ptr<LIB_SYMBOL> ksymbol = std::make_unique<LIB_SYMBOL>( wxEmptyString );
999 ksymbol->SetLibId( libId );
1000 ksymbol->SetName( aNetname );
1001 ksymbol->GetReferenceField().SetText( wxS(
"#PWR" ) );
1002 ksymbol->GetReferenceField().SetVisible(
false );
1003 ksymbol->GetValueField().SetText( aNetname );
1004 ksymbol->GetValueField().SetVisible(
true );
1005 ksymbol->SetDescription( wxString::Format(
_(
"Power symbol creates a global "
1006 "label with name '%s'" ),
1008 ksymbol->SetKeyWords( wxS(
"power-flag" ) );
1009 ksymbol->SetShowPinNames(
false );
1010 ksymbol->SetShowPinNumbers(
false );
1012 std::unique_ptr<LIB_PIN>
pin = std::make_unique<LIB_PIN>( ksymbol.get() );
1014 pin->SetName( aNetname );
1015 pin->SetNumber( wxS(
"1" ) );
1016 pin->SetOrientation( PIN_ORIENTATION::PIN_DOWN );
1017 pin->SetType( ELECTRICAL_PINTYPE::PT_POWER_IN );
1018 pin->SetLength( 0 );
1020 ksymbol->AddDrawItem(
pin.release() );
1026 if( aFlagTypename == wxS(
"part_netLabel_gnD" ) )
1030 else if( aFlagTypename == wxS(
"part_netLabel_GNd" ) )
1034 else if( aFlagTypename == wxS(
"part_netLabel_gNd" ) )
1038 else if( aFlagTypename == wxS(
"part_netLabel_GnD" ) )
1042 else if( aFlagTypename == wxS(
"part_netLabel_VCC" ) )
1047 else if( aFlagTypename == wxS(
"part_netLabel_+5V" ) )
1052 else if( aFlagTypename == wxS(
"part_netLabel_VEE" ) )
1056 else if( aFlagTypename == wxS(
"part_netLabel_-5V" ) )
1060 else if( aFlagTypename == wxS(
"part_netLabel_Bar" ) )
1067 ksymbol->GetValueField().SetPosition( valueFieldPos );
1069 return std::make_pair( ksymbol.release(), flip );
1073 const wxString& aFileName, wxArrayString aShapes )
1075 std::map<wxString, std::unique_ptr<LIB_SYMBOL>> loadedSymbols;
1076 std::map<wxString, int> namesCounter;
1077 std::vector<std::unique_ptr<SCH_ITEM>> createdItems;
1079 for( wxString shap : aShapes )
1081 shap.Replace( wxS(
"#@$" ), wxS(
"\n" ) );
1082 wxArrayString parts = wxSplit( shap,
'\n',
'\0' );
1084 if( parts.size() < 1 )
1087 wxArrayString arr = wxSplit( parts[0],
'~',
'\0' );
1089 if( arr.size() < 1 )
1092 wxString rootType = arr[0];
1094 if( rootType == wxS(
"LIB" ) )
1096 if( arr.size() < 4 )
1101 wxString symbolName = wxString::Format( wxS(
"Unknown_%s_%s" ), arr[1], arr[2] );
1103 wxArrayString paramParts = wxSplit( arr[3],
'`',
'\0' );
1105 std::map<wxString, wxString> paramMap;
1107 for(
size_t i = 1; i < paramParts.size(); i += 2 )
1109 wxString key = paramParts[i - 1];
1110 wxString value = paramParts[i];
1112 if( key == wxS(
"spiceSymbolName" ) && !value.IsEmpty() )
1115 paramMap[key] = value;
1118 int& serial = namesCounter[symbolName];
1121 symbolName << wxS(
"_" ) << serial;
1125 paramMap[wxS(
"spiceSymbolName" )] = symbolName;
1127 parts.RemoveAt( 0 );
1132 loadedSymbols.emplace( symbolName, sym );
1139 std::unique_ptr<SCH_SYMBOL> schSym =
1140 std::make_unique<SCH_SYMBOL>( *sym, libId, &aSchematic->
CurrentSheet(), 0 );
1142 schSym->SetPosition(
RelPos( origin ) );
1143 schSym->SetRef( &aSchematic->
CurrentSheet(), referenceStr );
1145 createdItems.push_back( std::move( schSym ) );
1147 else if( rootType == wxS(
"F" ) )
1149 wxString sepShapeStr = parts[0];
1150 sepShapeStr.Replace( wxS(
"^^" ), wxS(
"\n" ) );
1152 wxArrayString segments = wxSplit( sepShapeStr,
'\n',
'\0' );
1153 wxArrayString mainParts = wxSplit( segments[0],
'~',
'\0' );
1154 wxArrayString uselessParts = wxSplit( segments[1],
'~',
'\0' );
1155 wxArrayString valueParts = wxSplit( segments[2],
'~',
'\0' );
1157 wxString flagTypename = arr[1];
1159 double angle =
Convert( arr[4] );
1161 wxString netnameValue = valueParts[0];
1163 double textAngle =
Convert( valueParts[4] );
1164 wxString halignStr = valueParts[5];
1165 wxString valueFontname = valueParts[7];
1166 wxString valueFontsize = valueParts[8];
1168 if( flagTypename == wxS(
"part_netLabel_netPort" ) )
1170 std::unique_ptr<SCH_GLOBALLABEL> label =
1171 std::make_unique<SCH_GLOBALLABEL>(
RelPos( pos ), netnameValue );
1175 for(
double i = angle; i > 0; i -= 90 )
1179 if( segments.size() > 3 )
1181 wxArrayString shapeParts = wxSplit( segments[3],
'~',
'\0' );
1182 if( shapeParts[0] == wxS(
"PL" ) )
1184 wxArrayString ptArr = wxSplit( shapeParts[1],
' ',
'\0' );
1188 for(
size_t i = 1; i < ptArr.size(); i += 2 )
1200 if( shapeCenter.
x >= 0 )
1207 if( shapeCenter.
y >= 0 )
1215 label->SetSpinStyle( spin );
1216 label->SetShape( LABEL_FLAG_SHAPE::L_INPUT );
1218 createdItems.push_back( std::move( label ) );
1224 bool flip = pair.second;
1228 std::unique_ptr<SCH_SYMBOL> schSym = std::make_unique<SCH_SYMBOL>(
1237 else if( angle == 90 )
1251 schSym->SetPosition(
RelPos( pos ) );
1263 if( halignStr == wxS(
"middle" ) )
1265 else if( halignStr == wxS(
"end" ) )
1270 if( flip && ( angle == 90 || angle == 270 ) )
1282 if( flagTypename == wxS(
"part_netLabel_Bar" ) )
1286 if( angle == 0 && flagTypename == wxS(
"part_netLabel_Bar" ) )
1293 if( valueFontsize.EndsWith( wxS(
"pt" ) ) )
1294 ptSize =
Convert( valueFontsize.BeforeFirst(
'p' ) );
1298 if( netnameValue.Contains( wxS(
"\n" ) ) )
1307 createdItems.push_back( std::move( schSym ) );
1310 else if( rootType == wxS(
"W" ) )
1312 wxArrayString ptArr = wxSplit( arr[1],
' ',
'\0' );
1313 wxString strokeColor = arr[2];
1316 wxString fillColor = arr[5].Lower();
1321 for(
size_t i = 1; i < ptArr.size(); i += 2 )
1324 for(
int segId = 0; segId < chain.
SegmentCount(); segId++ )
1328 std::unique_ptr<SCH_LINE> line = std::make_unique<SCH_LINE>( seg.
A,
LAYER_WIRE );
1329 line->SetEndPoint( seg.
B );
1331 createdItems.push_back( std::move( line ) );
1334 else if( rootType == wxS(
"N" ) )
1337 double angle =
Convert( arr[3] );
1338 wxString netname = arr[5];
1339 wxString halignStr = arr[7];
1343 wxString fontname = arr[10];
1344 wxString fontSize = arr[11];
1346 std::unique_ptr<SCH_LABEL> label =
1347 std::make_unique<SCH_LABEL>(
RelPos( pos ), netname );
1349 if( halignStr == wxS(
"middle" ) )
1351 else if( halignStr == wxS(
"end" ) )
1357 label->Rotate90(
false );
1359 createdItems.push_back( std::move( label ) );
1361 else if( rootType == wxS(
"O" ) )
1365 std::unique_ptr<SCH_NO_CONNECT> noConn =
1366 std::make_unique<SCH_NO_CONNECT>(
RelPos( pos ) );
1368 createdItems.push_back( std::move( noConn ) );
1370 else if( rootType == wxS(
"J" ) )
1375 std::unique_ptr<SCH_JUNCTION> junction =
1376 std::make_unique<SCH_JUNCTION>(
RelPos( pos ) );
1378 createdItems.push_back( std::move( junction ) );
1380 else if( rootType == wxS(
"T" ) )
1383 int angle =
Convert( arr[4] );
1384 wxString
color = arr[5];
1385 wxString fontname = arr[6];
1386 wxString fontSize = arr[7];
1387 wxString baselineAlign = arr[10];
1388 wxString textStr = arr[12];
1390 textStr.Replace( wxS(
"\\n" ), wxS(
"\n" ) );
1393 wxString halignStr = arr[14];
1395 std::unique_ptr<SCH_TEXT> textItem =
1396 std::make_unique<SCH_TEXT>(
RelPos( pos ), textStr );
1398 textItem->SetTextAngleDegrees( ( 360 - angle ) % 360 );
1401 if( halignStr == wxS(
"middle" ) )
1403 else if( halignStr == wxS(
"end" ) )
1412 if( fontSize.EndsWith( wxS(
"pt" ) ) )
1413 ptSize =
Convert( fontSize.BeforeFirst(
'p' ) );
1417 if( textStr.Contains( wxS(
"\n" ) ) )
1422 textItem->SetTextSize(
VECTOR2I( ktextSize, ktextSize ) );
1426 createdItems.push_back( std::move( textItem ) );
1428 else if( rootType == wxS(
"R" ) )
1433 cr.
x = !arr[3].empty() ?
Convert( arr[3] ) : 0,
1434 cr.
y = !arr[4].empty() ?
Convert( arr[4] ) : 0;
1437 wxString strokeColor = arr[7];
1438 double lineWidth =
Convert( arr[8] );
1440 wxString fillColor = arr[10].Lower();
1445 std::unique_ptr<SCH_SHAPE> rect = std::make_unique<SCH_SHAPE>( SHAPE_T::RECTANGLE );
1447 rect->SetStart(
RelPos( start ) );
1448 rect->SetEnd(
RelPos( start + size ) );
1452 if( fillColor != wxS(
"none" ) )
1454 rect->SetFilled(
true );
1456 if( fillColor == strokeColor )
1457 rect->SetFillMode( FILL_T::FILLED_SHAPE );
1459 rect->SetFillMode( FILL_T::FILLED_WITH_BG_BODYCOLOR );
1462 createdItems.push_back( std::move( rect ) );
1468 else if( rootType == wxS(
"I" ) )
1473 wxString imageUrl = arr[6];
1474 wxString transformData = arr[9];
1479 std::vector<std::pair<wxString, std::vector<double>>> transformCmds =
1482 auto applyTransform = [&](
SCH_ITEM* aSchItem )
1484 for(
const auto& cmd : transformCmds )
1486 if( cmd.first == wxS(
"rotate" ) )
1488 if( cmd.second.size() != 3 )
1491 double cmdAngle = 360 - cmd.second[0];
1492 VECTOR2D cmdAround( cmd.second[1], cmd.second[2] );
1494 for(
double i = cmdAngle; i > 0; i -= 90 )
1500 aSchItem->Rotate(
RelPos( cmdAround ) );
1504 aSchItem->Rotate(
RelPos( cmdAround ) );
1509 aSchItem->Rotate(
RelPos( cmdAround ) );
1513 else if( cmd.first == wxS(
"translate" ) )
1515 if( cmd.second.size() != 2 )
1518 VECTOR2D cmdOffset( cmd.second[0], cmd.second[1] );
1519 aSchItem->Move(
ScalePos( cmdOffset ) );
1521 else if( cmd.first == wxS(
"scale" ) )
1523 if( cmd.second.size() != 2 )
1526 double cmdScaleX = cmd.second[0];
1527 double cmdScaleY = cmd.second[1];
1533 if( cmdScaleX < 0 && cmdScaleY > 0 )
1535 aSchItem->MirrorHorizontally( 0 );
1537 else if( cmdScaleX > 0 && cmdScaleY < 0 )
1539 aSchItem->MirrorVertically( 0 );
1541 else if( cmdScaleX < 0 && cmdScaleY < 0 )
1543 aSchItem->MirrorHorizontally( 0 );
1544 aSchItem->MirrorVertically( 0 );
1553 if( imageUrl.BeforeFirst(
':' ) == wxS(
"data" ) )
1555 wxArrayString paramsArr =
1556 wxSplit( imageUrl.AfterFirst(
':' ).BeforeFirst(
',' ),
';',
'\0' );
1558 wxString data = imageUrl.AfterFirst(
',' );
1560 if( paramsArr.size() > 0 )
1562 wxString mimeType = paramsArr[0];
1563 wxMemoryBuffer buf = wxBase64Decode( data );
1565 if( mimeType == wxS(
"image/svg+xml" ) )
1581 schImporter.
SetScale( pixelScale );
1588 svgImportPlugin.
Import();
1590 for( std::unique_ptr<EDA_ITEM>& item : schImporter.
GetItems() )
1594 applyTransform( schItem );
1596 createdItems.emplace_back( schItem );
1601 std::unique_ptr<SCH_BITMAP> bitmap = std::make_unique<SCH_BITMAP>();
1603 wxImage::SetDefaultLoadFlags( wxImage::GetDefaultLoadFlags()
1604 & ~wxImage::Load_Verbose );
1606 if( bitmap->ReadImageFile( buf ) )
1608 VECTOR2D kcenter = kstart + ksize / 2;
1610 double scaleFactor =
ScaleSize( size.
x ) / bitmap->GetSize().x;
1611 bitmap->SetImageScale( scaleFactor );
1612 bitmap->SetPosition( kcenter );
1614 applyTransform( bitmap.get() );
1616 createdItems.push_back( std::move( bitmap ) );
1626 for( std::unique_ptr<SCH_ITEM>& ptr : createdItems )
1636 offset.
x =
KiROUND( offset.
x / alignGrid ) * alignGrid;
1637 offset.
y =
KiROUND( offset.
y / alignGrid ) * alignGrid;
1644 for( std::unique_ptr<SCH_ITEM>& ptr : createdItems )
1646 ptr->Move( offset );
1647 screen->
Append( ptr.release() );
constexpr EDA_IU_SCALE schIUScale
coord_type GetTop() const
coord_type GetHeight() const
coord_type GetWidth() const
coord_type GetLeft() const
BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
std::vector< SHAPE_LINE_CHAIN > ParseLineChains(const wxString &aData, int aArcMinSegLen)
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 SetEnd(const VECTOR2I &aEnd)
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
const VECTOR2I & GetTextPos() const
void SetTextSize(VECTOR2I aNewSize)
const EDA_ANGLE & GetTextAngle() const
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
void SetTextAngleDegrees(double aOrientation)
GR_TEXT_V_ALIGN_T GetVertJustify() const
virtual void SetText(const wxString &aText)
void SetFont(KIFONT::FONT *aFont)
VECTOR2I GetTextSize() const
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)
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.
The base class for drawable items used by schematic library symbols.
void SetStroke(const STROKE_PARAMS &aStroke)
void AddPoint(const VECTOR2I &aPosition)
void SetPosition(const VECTOR2I &aPosition) override
VECTOR2I GetPosition() const override
Define a library symbol object.
LIB_FIELD & GetReferenceField()
Return reference to the reference designator field.
void AddDrawItem(LIB_ITEM *aItem, bool aSort=true)
Add a new draw aItem to the draw object list and sort according to aSort.
LIB_FIELD & GetValueField()
Return reference to the value field.
Define a symbol library graphical text item.
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 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.
SCH_SHEET_PATH & CurrentSheet() const override
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)
Instances are attached to a symbol or sheet and provide a place for the symbol's value,...
void SetPosition(const VECTOR2I &aPosition) 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)
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
SCH_SCREEN * GetScreen() const
BOX2I GetBodyBoundingBox() const
Return a bounding box for the symbol body but not the pins or fields.
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
void Move(const VECTOR2I &aVector) override
bool IsClosed() const override
void SetClosed(bool aClosed)
Mark the line chain as closed (i.e.
int PointCount() const
Return the number of points (vertices) in this line chain.
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
int SegmentCount() const
Return the number of segments in this line chain.
const SEG CSegment(int aIndex) const
Return a constant copy of the aIndex segment in the line chain.
virtual VECTOR2I Centre() const
Compute a center-of-mass of the shape.
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.
void ConvertImageToLibShapes(LIB_SYMBOL *aSymbol, int unit, wxImage img, VECTOR2D pixelScale, VECTOR2D offset)
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_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.
VECTOR2I HelperGeneratePowerPortGraphics(LIB_SYMBOL *aKsymbol, ASCH_POWER_PORT_STYLE aStyle, REPORTER *aReporter)
static std::vector< std::vector< wxString > > RegexMatchAll(wxRegEx &aRegex, const wxString &aString)
static ELECTRICAL_PINTYPE ConvertElecType(const wxString &aType)
static void TransformToBaseline(EDA_TEXT *textItem, const wxString &baselineAlign, bool invertY)
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)
@ SYM_ROTATE_COUNTERCLOCKWISE
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.
constexpr double IUTomm(int iu) const
constexpr int IUToMils(int iu) const
constexpr int MilsToIU(int mils) const
@ VALUE_FIELD
Field Value of part, i.e. "3.3K".
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
VECTOR2< double > VECTOR2D