36#include <wx/mstream.h>
48 "BOM_Manufacturer Part",
70static std::vector<std::vector<wxString>>
RegexMatchAll( wxRegEx& aRegex,
const wxString& aString )
72 std::vector<std::vector<wxString>> allMatches;
78 wxString str = aString;
80 while( aRegex.Matches( str ) )
82 std::vector<wxString> matches;
83 aRegex.GetMatch( &start, &len );
85 for(
size_t i = 0; i < aRegex.GetMatchCount(); i++ )
86 matches.emplace_back( aRegex.GetMatch( str, i ) );
88 allMatches.emplace_back( matches );
90 prevstart = start + len;
91 str = str.Mid( prevstart );
105static std::vector<std::pair<wxString, std::vector<double>>>
108 wxRegEx transformRegex(
"(rotate|translate|scale)\\(([\\w\\s,\\.\\-]*)\\)", wxRE_ICASE );
109 std::vector<std::vector<wxString>> allMatches =
RegexMatchAll( transformRegex, transformData );
111 std::vector<std::pair<wxString, std::vector<double>>> transformCmds;
113 for(
int cmdId = allMatches.size() - 1; cmdId >= 0; cmdId-- )
115 std::vector<wxString>& groups = allMatches[cmdId];
117 if( groups.size() != 3 )
120 const wxString& cmdName = groups[1].Strip( wxString::both ).Lower();
121 const wxString& cmdArgsStr = groups[2];
123 wxArrayString cmdParts = wxSplit( cmdArgsStr,
',',
'\0' );
124 std::vector<double> cmdArgs;
126 for(
const wxString& cmdPart : cmdParts )
129 wxASSERT( cmdPart.Strip( wxString::both ).ToCDouble( &arg ) );
131 cmdArgs.push_back( arg );
134 transformCmds.emplace_back( cmdName, cmdArgs );
137 return transformCmds;
145 wxString key = !aLibName.empty() ? ( aLibName +
':' + libReference ) : libReference;
148 libId.
Parse( key,
true );
156 if( aStyle == wxS(
"0" ) )
158 else if( aStyle == wxS(
"1" ) )
160 else if( aStyle == wxS(
"2" ) )
169 if( aType == wxS(
"0" ) )
171 else if( aType == wxS(
"1" ) )
173 else if( aType == wxS(
"2" ) )
175 else if( aType == wxS(
"3" ) )
177 else if( aType == wxS(
"4" ) )
369 aReporter->
Report(
_(
"Power Port with unknown style imported as 'Bar' type." ),
391 std::map<wxString, wxString> paramMap,
392 wxArrayString aShapes )
394 for( wxString shapeStr : aShapes )
396 wxArrayString arr = wxSplit( shapeStr,
'~',
'\0' );
398 wxString elType = arr[0];
399 if( elType == wxS(
"PL" ) || elType == wxS(
"PG" ) )
401 wxArrayString ptArr = wxSplit( arr[1],
' ',
'\0' );
402 wxString strokeColor = arr[2];
403 double lineWidth =
Convert( arr[3] );
405 wxString fillColor = arr[5].Lower();
410 for(
size_t i = 1; i < ptArr.size(); i += 2 )
418 if( elType == wxS(
"PG" ) )
419 chain.SetClosed(
true );
421 if(
chain.PointCount() < 2 )
424 for(
int i = 0; i <
chain.PointCount(); i++ )
425 line->AddPoint(
chain.CPoint( i ) );
427 if(
chain.IsClosed() )
428 line->AddPoint(
chain.CPoint( 0 ) );
433 if( fillColor != wxS(
"none" ) )
435 line->SetFilled(
true );
437 if( fillColor == strokeColor )
445 else if( elType == wxS(
"PT" ) )
447 wxString pointsData = arr[1];
448 wxString strokeColor = arr[2];
449 double lineWidth =
Convert( arr[3] );
451 wxString fillColor = arr[5].Lower();
454 std::vector<SHAPE_LINE_CHAIN> lineChains =
461 if( outline.IsClosed() )
462 outline.Append( outline.CPoint( 0 ),
true );
464 for(
const VECTOR2I& pt : outline.CPoints() )
465 shape->AddPoint( pt );
470 if( fillColor != wxS(
"none" ) )
472 shape->SetFilled(
true );
474 if( fillColor == strokeColor )
483 else if( elType == wxS(
"Pimage" ) )
488 wxString imageUrl = arr[10];
490 if( imageUrl.BeforeFirst(
':' ) == wxS(
"data" ) )
492 wxArrayString paramsArr =
493 wxSplit( imageUrl.AfterFirst(
':' ).BeforeFirst(
',' ),
';',
'\0' );
495 wxString data = imageUrl.AfterFirst(
',' );
497 if( paramsArr.size() > 0 )
499 wxString mimeType = paramsArr[0];
500 wxMemoryBuffer buf = wxBase64Decode( data );
502 if( mimeType == wxS(
"image/svg+xml" ) )
518 libsymImporter.
SetScale( pixelScale );
527 for( std::unique_ptr<EDA_ITEM>& item : libsymImporter.
GetItems() )
532 wxMemoryInputStream memis( buf.GetData(), buf.GetDataLen() );
534 wxImage::SetDefaultLoadFlags( wxImage::GetDefaultLoadFlags()
535 & ~wxImage::Load_Verbose );
537 if( img.LoadFile( memis, mimeType ) )
539 int dimMul = img.GetWidth() * img.GetHeight();
540 double maxPixels = 30000;
542 if( dimMul > maxPixels )
544 double scale = sqrt( maxPixels / dimMul );
545 img.Rescale( img.GetWidth() *
scale, img.GetHeight() *
scale );
558 else if( elType == wxS(
"A" ) )
560 wxString data = arr[1];
561 wxString strokeColor = arr[3];
562 double lineWidth =
Convert( arr[4] );
564 wxString fillColor = arr[6].Lower();
567 std::vector<SHAPE_LINE_CHAIN> chains =
570 auto transform = [](
VECTOR2I aVec )
577 for(
int i = 0; i <=
chain.PointCount() && i != -1; i =
chain.NextShape( i ) )
579 if(
chain.IsArcStart( i ) )
583 std::unique_ptr<SCH_SHAPE> shape =
586 shape->SetArcGeometry( transform( arc.
GetP0() ),
588 transform( arc.
GetP1() ) );
593 if( fillColor != wxS(
"none" ) )
595 shape->SetFilled(
true );
597 if( fillColor == strokeColor )
609 std::unique_ptr<SCH_SHAPE> shape =
612 shape->AddPoint( transform( seg.
A ) );
613 shape->AddPoint( transform( seg.
B ) );
623 else if( elType == wxS(
"R" ) )
628 cr.
x = !arr[3].empty() ?
Convert( arr[3] ) : 0,
629 cr.
y = !arr[4].empty() ?
Convert( arr[4] ) : 0;
632 wxString strokeColor = arr[7];
633 double lineWidth =
Convert( arr[8] );
635 wxString fillColor = arr[10].Lower();
643 rect->SetEnd(
RelPosSym( start + size ) );
648 if( fillColor != wxS(
"none" ) )
650 rect->SetFilled(
true );
652 if( fillColor == strokeColor )
662 else if( elType == wxS(
"E" ) )
668 wxString strokeColor = arr[5];
669 double lineWidth =
Convert( arr[6] );
671 wxString fillColor = arr[8].Lower();
680 if( fillColor != wxS(
"none" ) )
682 circle->SetFilled(
true );
684 if( fillColor == strokeColor )
692 else if( elType == wxS(
"P" ) )
694 wxString sepShapeStr = shapeStr;
695 sepShapeStr.Replace( wxS(
"^^" ), wxS(
"\n" ) );
697 wxArrayString segments = wxSplit( sepShapeStr,
'\n',
'\0' );
698 wxArrayString mainParts = wxSplit( segments[0],
'~',
'\0' );
699 wxArrayString pinDotParts = wxSplit( segments[1],
'~',
'\0' );
700 wxArrayString pinPathColorParts = wxSplit( segments[2],
'~',
'\0' );
701 wxArrayString pinNameParts = wxSplit( segments[3],
'~',
'\0' );
702 wxArrayString pinNumParts = wxSplit( segments[4],
'~',
'\0' );
706 wxString pinNumber = mainParts[3];
712 bool nameVisible = pinNameParts[0] != wxS(
"0" );
713 wxString pinName = pinNameParts[4];
715 bool numVisible = pinNumParts[0] != wxS(
"0" );
719 bool vertical =
false;
723 wxString lineData = pinPathColorParts[0];
724 wxRegEx regex( wxS(
"^M\\s*([-\\d.]+)[,\\s]([-\\d.]+)\\s*([h|v])\\s*([-\\d.]+)\\s*$" ) );
726 if( regex.Matches( lineData ) )
728 startPoint.
x =
Convert( regex.GetMatch( lineData, 1 ) );
729 startPoint.
y =
Convert( regex.GetMatch( lineData, 2 ) );
731 vertical = regex.GetMatch( lineData, 3 ).Contains( wxS(
"v" ) );
732 pinLen =
Convert( regex.GetMatch( lineData, 4 ) );
739 if( startPoint.
x == pinPos.
x && pinLen < 0 )
741 else if( startPoint.
x == pinPos.
x && pinLen > 0 )
743 else if( startPoint.
x != pinPos.
x && pinLen < 0 )
745 else if( startPoint.
x != pinPos.
x && pinLen > 0 )
750 if( startPoint.
y == pinPos.
y && pinLen < 0 )
752 else if( startPoint.
y == pinPos.
y && pinLen > 0 )
754 else if( startPoint.
y != pinPos.
y && pinLen < 0 )
756 else if( startPoint.
y != pinPos.
y && pinLen > 0 )
762 if( pinRotation == 0 )
764 else if( pinRotation == 90 )
766 else if( pinRotation == 180 )
768 else if( pinRotation == 270 )
774 if( segments.size() > 5 )
776 wxArrayString dotParts = wxSplit( segments[5],
'~',
'\0' );
777 wxArrayString clockParts = wxSplit( segments[6],
'~',
'\0' );
779 if( dotParts.size() == 3 && clockParts.size() == 2 )
781 if( dotParts[0] == wxS(
"1" ) )
789 pinPos + ( dotPos - pinPos ).Resize(
std::abs( pinLen ) ) ) );
796 if( clockParts[0] == wxS(
"1" ) )
798 std::vector<SHAPE_LINE_CHAIN> lineChains =
805 if( outline.IsClosed() )
806 outline.Append( outline.CPoint( 0 ),
true );
808 for(
const VECTOR2I& pt : outline.CPoints() )
809 shape->AddPoint( pt );
819 std::unique_ptr<SCH_PIN>
pin = std::make_unique<SCH_PIN>( aSymbol );
821 pin->SetName( pinName );
822 pin->SetNumber( pinNumber );
823 pin->SetOrientation( orient );
824 pin->SetType( elecType );
825 pin->SetLength( kPinLen );
827 pin->SetUnit( pinUnit );
829 if(
pin->GetNumberTextSize() *
int( pinNumber.size() ) > kPinLen )
830 pin->SetNumberTextSize( kPinLen / pinNumber.size() );
840 else if( elType == wxS(
"T" ) )
842 wxString textType = arr[1];
846 wxString fontname = arr[6];
847 wxString fontSize = arr[7];
848 wxString baselineAlign = arr[10];
849 wxString textStr = arr[12];
850 bool visible = arr[13] != wxS(
"0" );
852 textStr.Replace( wxS(
"\\n" ), wxS(
"\n" ) );
855 wxString halignStr = arr[14];
860 if( textType == wxS(
"P" ) )
866 else if( textType == wxS(
"N" ) )
881 if( halignStr == wxS(
"middle" ) )
883 else if( halignStr == wxS(
"end" ) )
893 if( !fontSize.IsEmpty() )
895 if( fontSize.EndsWith( wxS(
"pt" ) ) )
896 ptSize =
Convert( fontSize.BeforeFirst(
'p' ) );
897 else if( fontSize.IsNumber() )
903 if( textStr.Contains( wxS(
"\n" ) ) )
920 std::map<wxString, wxString> aParams,
921 wxArrayString aShapes )
923 std::unique_ptr<LIB_SYMBOL> ksymbol = std::make_unique<LIB_SYMBOL>( wxEmptyString );
927 std::optional<wxString> valOpt;
928 wxString symbolName = wxS(
"Unknown" );
930 if( ( valOpt =
get_opt( aParams, wxS(
"name" ) ) ) )
931 symbolName = *valOpt;
932 else if( ( valOpt =
get_opt( aParams, wxS(
"spiceSymbolName" ) ) ) )
933 symbolName = *valOpt;
935 wxString symbolPrefix;
937 if( ( valOpt =
get_opt( aParams, wxS(
"pre" ) ) ) )
938 symbolPrefix = *valOpt;
939 else if( ( valOpt =
get_opt( aParams, wxS(
"spicePre" ) ) ) )
940 symbolPrefix = *valOpt;
944 ksymbol->SetLibId( libId );
945 ksymbol->SetName( symbolName );
947 ksymbol->GetReferenceField().SetText( symbolPrefix );
948 ksymbol->GetValueField().SetText( symbolName );
952 wxString srcName = attrName;
954 if( srcName == wxS(
"Datasheet" ) )
955 srcName = wxS(
"link" );
957 if( ( valOpt =
get_opt( aParams, srcName ) ) )
959 if( valOpt->empty() )
962 SCH_FIELD* fd = ksymbol->FindFieldCaseInsensitive( attrName );
967 ksymbol->AddField( fd );
977 return ksymbol.release();
981 const wxString& aNetname )
983 std::unique_ptr<LIB_SYMBOL> ksymbol = std::make_unique<LIB_SYMBOL>( wxEmptyString );
989 ksymbol->SetGlobalPower();
990 ksymbol->SetLibId( libId );
991 ksymbol->SetName( aNetname );
992 ksymbol->GetReferenceField().SetText( wxS(
"#PWR" ) );
993 ksymbol->GetReferenceField().SetVisible(
false );
994 ksymbol->GetValueField().SetText( aNetname );
995 ksymbol->GetValueField().SetVisible(
true );
996 ksymbol->SetDescription( wxString::Format(
_(
"Power symbol creates a global "
997 "label with name '%s'" ),
999 ksymbol->SetKeyWords( wxS(
"power-flag" ) );
1000 ksymbol->SetShowPinNames(
false );
1001 ksymbol->SetShowPinNumbers(
false );
1003 std::unique_ptr<SCH_PIN>
pin = std::make_unique<SCH_PIN>( ksymbol.get() );
1005 pin->SetName( aNetname );
1006 pin->SetNumber( wxS(
"1" ) );
1009 pin->SetLength( 0 );
1011 ksymbol->AddDrawItem(
pin.release() );
1017 if( aFlagTypename == wxS(
"part_netLabel_gnD" ) )
1021 else 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_VCC" ) )
1038 else if( aFlagTypename == wxS(
"part_netLabel_+5V" ) )
1043 else if( aFlagTypename == wxS(
"part_netLabel_VEE" ) )
1047 else if( aFlagTypename == wxS(
"part_netLabel_-5V" ) )
1051 else if( aFlagTypename == wxS(
"part_netLabel_Bar" ) )
1058 ksymbol->GetValueField().SetPosition( valueFieldPos );
1060 return std::make_pair( ksymbol.release(), flip );
1064 const wxString& aFileName, wxArrayString aShapes )
1066 std::map<wxString, std::unique_ptr<LIB_SYMBOL>> loadedSymbols;
1067 std::map<wxString, int> namesCounter;
1068 std::vector<std::unique_ptr<SCH_ITEM>> createdItems;
1070 for( wxString shap : aShapes )
1072 shap.Replace( wxS(
"#@$" ), wxS(
"\n" ) );
1073 wxArrayString parts = wxSplit( shap,
'\n',
'\0' );
1075 if( parts.size() < 1 )
1078 wxArrayString arr = wxSplit( parts[0],
'~',
'\0' );
1080 if( arr.size() < 1 )
1083 wxString rootType = arr[0];
1085 if( rootType == wxS(
"LIB" ) )
1087 if( arr.size() < 4 )
1092 wxString symbolName = wxString::Format( wxS(
"Unknown_%s_%s" ), arr[1], arr[2] );
1094 wxArrayString paramParts = wxSplit( arr[3],
'`',
'\0' );
1096 std::map<wxString, wxString> paramMap;
1098 for(
size_t i = 1; i < paramParts.size(); i += 2 )
1100 wxString key = paramParts[i - 1];
1101 wxString value = paramParts[i];
1103 if( key == wxS(
"spiceSymbolName" ) && !value.IsEmpty() )
1106 paramMap[key] = value;
1109 int& serial = namesCounter[symbolName];
1112 symbolName << wxS(
"_" ) << serial;
1116 paramMap[wxS(
"spiceSymbolName" )] = symbolName;
1118 parts.RemoveAt( 0 );
1123 loadedSymbols.emplace( symbolName, sym );
1130 std::unique_ptr<SCH_SYMBOL> schSym =
1131 std::make_unique<SCH_SYMBOL>( *sym, libId, &aSchematic->
CurrentSheet(), 0 );
1133 schSym->SetPosition(
RelPos( origin ) );
1134 schSym->SetRef( &aSchematic->
CurrentSheet(), referenceStr );
1136 createdItems.push_back( std::move( schSym ) );
1138 else if( rootType == wxS(
"F" ) )
1140 wxString sepShapeStr = parts[0];
1141 sepShapeStr.Replace( wxS(
"^^" ), wxS(
"\n" ) );
1143 wxArrayString segments = wxSplit( sepShapeStr,
'\n',
'\0' );
1146 wxArrayString valueParts = wxSplit( segments[2],
'~',
'\0' );
1148 wxString flagTypename = arr[1];
1150 double angle =
Convert( arr[4] );
1152 wxString netnameValue = valueParts[0];
1154 double textAngle =
Convert( valueParts[4] );
1155 wxString halignStr = valueParts[5];
1156 wxString valueFontname = valueParts[7];
1157 wxString valueFontsize = valueParts[8];
1159 if( flagTypename == wxS(
"part_netLabel_netPort" ) )
1161 std::unique_ptr<SCH_GLOBALLABEL> label =
1162 std::make_unique<SCH_GLOBALLABEL>(
RelPos( pos ), netnameValue );
1166 for(
double i = angle; i > 0; i -= 90 )
1170 if( segments.size() > 3 )
1172 wxArrayString shapeParts = wxSplit( segments[3],
'~',
'\0' );
1173 if( shapeParts[0] == wxS(
"PL" ) )
1175 wxArrayString ptArr = wxSplit( shapeParts[1],
' ',
'\0' );
1179 for(
size_t i = 1; i < ptArr.size(); i += 2 )
1191 if( shapeCenter.
x >= 0 )
1198 if( shapeCenter.
y >= 0 )
1206 label->SetSpinStyle( spin );
1209 createdItems.push_back( std::move( label ) );
1215 bool flip = pair.second;
1219 std::unique_ptr<SCH_SYMBOL> schSym = std::make_unique<SCH_SYMBOL>(
1228 else if( angle == 90 )
1242 schSym->SetPosition(
RelPos( pos ) );
1254 if( halignStr == wxS(
"middle" ) )
1256 else if( halignStr == wxS(
"end" ) )
1261 if( flip && ( angle == 90 || angle == 270 ) )
1273 if( flagTypename == wxS(
"part_netLabel_Bar" ) )
1277 if( angle == 0 && flagTypename == wxS(
"part_netLabel_Bar" ) )
1284 if( valueFontsize.EndsWith( wxS(
"pt" ) ) )
1285 ptSize =
Convert( valueFontsize.BeforeFirst(
'p' ) );
1289 if( netnameValue.Contains( wxS(
"\n" ) ) )
1298 createdItems.push_back( std::move( schSym ) );
1301 else if( rootType == wxS(
"W" ) )
1303 wxArrayString ptArr = wxSplit( arr[1],
' ',
'\0' );
1312 for(
size_t i = 1; i < ptArr.size(); i += 2 )
1315 for(
int segId = 0; segId <
chain.SegmentCount(); segId++ )
1317 const SEG& seg =
chain.CSegment( segId );
1319 std::unique_ptr<SCH_LINE> line = std::make_unique<SCH_LINE>( seg.
A,
LAYER_WIRE );
1320 line->SetEndPoint( seg.
B );
1322 createdItems.push_back( std::move( line ) );
1325 else if( rootType == wxS(
"N" ) )
1328 double angle =
Convert( arr[3] );
1329 wxString netname = arr[5];
1330 wxString halignStr = arr[7];
1337 std::unique_ptr<SCH_LABEL> label =
1338 std::make_unique<SCH_LABEL>(
RelPos( pos ), netname );
1340 if( halignStr == wxS(
"middle" ) )
1342 else if( halignStr == wxS(
"end" ) )
1348 label->Rotate90(
false );
1350 createdItems.push_back( std::move( label ) );
1352 else if( rootType == wxS(
"O" ) )
1356 std::unique_ptr<SCH_NO_CONNECT> noConn =
1357 std::make_unique<SCH_NO_CONNECT>(
RelPos( pos ) );
1359 createdItems.push_back( std::move( noConn ) );
1361 else if( rootType == wxS(
"J" ) )
1366 std::unique_ptr<SCH_JUNCTION> junction =
1367 std::make_unique<SCH_JUNCTION>(
RelPos( pos ) );
1369 createdItems.push_back( std::move( junction ) );
1371 else if( rootType == wxS(
"T" ) )
1374 int angle =
Convert( arr[4] );
1376 wxString fontname = arr[6];
1377 wxString fontSize = arr[7];
1378 wxString baselineAlign = arr[10];
1379 wxString textStr = arr[12];
1381 textStr.Replace( wxS(
"\\n" ), wxS(
"\n" ) );
1384 wxString halignStr = arr[14];
1386 std::unique_ptr<SCH_TEXT> textItem =
1387 std::make_unique<SCH_TEXT>(
RelPos( pos ), textStr );
1389 textItem->SetTextAngleDegrees( ( 360 - angle ) % 360 );
1392 if( halignStr == wxS(
"middle" ) )
1394 else if( halignStr == wxS(
"end" ) )
1403 if( fontSize.EndsWith( wxS(
"pt" ) ) )
1404 ptSize =
Convert( fontSize.BeforeFirst(
'p' ) );
1408 if( textStr.Contains( wxS(
"\n" ) ) )
1413 textItem->SetTextSize(
VECTOR2I( ktextSize, ktextSize ) );
1417 createdItems.push_back( std::move( textItem ) );
1419 else if( rootType == wxS(
"R" ) )
1424 cr.
x = !arr[3].empty() ?
Convert( arr[3] ) : 0,
1425 cr.
y = !arr[4].empty() ?
Convert( arr[4] ) : 0;
1428 wxString strokeColor = arr[7];
1429 double lineWidth =
Convert( arr[8] );
1431 wxString fillColor = arr[10].Lower();
1438 rect->SetStart(
RelPos( start ) );
1439 rect->SetEnd(
RelPos( start + size ) );
1443 if( fillColor != wxS(
"none" ) )
1445 rect->SetFilled(
true );
1447 if( fillColor == strokeColor )
1453 createdItems.push_back( std::move( rect ) );
1459 else if( rootType == wxS(
"I" ) )
1464 wxString imageUrl = arr[6];
1465 wxString transformData = arr[9];
1470 std::vector<std::pair<wxString, std::vector<double>>> transformCmds =
1473 auto applyTransform = [&](
SCH_ITEM* aSchItem )
1475 for(
const auto& cmd : transformCmds )
1477 if( cmd.first == wxS(
"rotate" ) )
1479 if( cmd.second.size() != 3 )
1482 double cmdAngle = 360 - cmd.second[0];
1483 VECTOR2D cmdAround( cmd.second[1], cmd.second[2] );
1485 for(
double i = cmdAngle; i > 0; i -= 90 )
1491 aSchItem->Rotate(
RelPos( cmdAround ),
false );
1495 aSchItem->Rotate(
RelPos( cmdAround ),
false );
1500 aSchItem->Rotate(
RelPos( cmdAround ),
false );
1504 else if( cmd.first == wxS(
"translate" ) )
1506 if( cmd.second.size() != 2 )
1509 VECTOR2D cmdOffset( cmd.second[0], cmd.second[1] );
1510 aSchItem->Move(
ScalePos( cmdOffset ) );
1512 else if( cmd.first == wxS(
"scale" ) )
1514 if( cmd.second.size() != 2 )
1517 double cmdScaleX = cmd.second[0];
1518 double cmdScaleY = cmd.second[1];
1524 if( cmdScaleX < 0 && cmdScaleY > 0 )
1526 aSchItem->MirrorHorizontally( 0 );
1528 else if( cmdScaleX > 0 && cmdScaleY < 0 )
1530 aSchItem->MirrorVertically( 0 );
1532 else if( cmdScaleX < 0 && cmdScaleY < 0 )
1534 aSchItem->MirrorHorizontally( 0 );
1535 aSchItem->MirrorVertically( 0 );
1544 if( imageUrl.BeforeFirst(
':' ) == wxS(
"data" ) )
1546 wxArrayString paramsArr =
1547 wxSplit( imageUrl.AfterFirst(
':' ).BeforeFirst(
',' ),
';',
'\0' );
1549 wxString data = imageUrl.AfterFirst(
',' );
1551 if( paramsArr.size() > 0 )
1553 wxString mimeType = paramsArr[0];
1554 wxMemoryBuffer buf = wxBase64Decode( data );
1556 if( mimeType == wxS(
"image/svg+xml" ) )
1572 schImporter.
SetScale( pixelScale );
1579 svgImportPlugin.
Import();
1581 for( std::unique_ptr<EDA_ITEM>& item : schImporter.
GetItems() )
1585 applyTransform( schItem );
1587 createdItems.emplace_back( schItem );
1592 std::unique_ptr<SCH_BITMAP> bitmap = std::make_unique<SCH_BITMAP>();
1595 wxImage::SetDefaultLoadFlags( wxImage::GetDefaultLoadFlags()
1596 & ~wxImage::Load_Verbose );
1600 VECTOR2D kcenter = kstart + ksize / 2;
1604 bitmap->SetPosition( kcenter );
1606 applyTransform( bitmap.get() );
1608 createdItems.push_back( std::move( bitmap ) );
1618 for( std::unique_ptr<SCH_ITEM>& ptr : createdItems )
1628 offset.
x =
KiROUND( offset.
x / alignGrid ) * alignGrid;
1629 offset.
y =
KiROUND( offset.
y / alignGrid ) * alignGrid;
1636 for( std::unique_ptr<SCH_ITEM>& ptr : createdItems )
1638 ptr->Move( offset );
1639 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)
virtual void SetEnd(const VECTOR2I &aEnd)
virtual void SetBezierC2(const VECTOR2I &aPt)
virtual void SetBezierC1(const VECTOR2I &aPt)
virtual void SetStart(const VECTOR2I &aStart)
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
virtual void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
virtual 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)
virtual const wxString & GetText() const override
Return the string associated with the text object.
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