37#include <wx/mstream.h>
49 "BOM_Manufacturer Part",
71static std::vector<std::vector<wxString>>
RegexMatchAll( wxRegEx& aRegex,
const wxString& aString )
73 std::vector<std::vector<wxString>> allMatches;
79 wxString str = aString;
81 while( aRegex.Matches( str ) )
83 std::vector<wxString> matches;
84 aRegex.GetMatch( &start, &len );
86 for(
size_t i = 0; i < aRegex.GetMatchCount(); i++ )
87 matches.emplace_back( aRegex.GetMatch( str, i ) );
89 allMatches.emplace_back( matches );
91 prevstart = start + len;
92 str = str.Mid( prevstart );
106static std::vector<std::pair<wxString, std::vector<double>>>
109 wxRegEx transformRegex(
"(rotate|translate|scale)\\(([\\w\\s,\\.\\-]*)\\)", wxRE_ICASE );
110 std::vector<std::vector<wxString>> allMatches =
RegexMatchAll( transformRegex, transformData );
112 std::vector<std::pair<wxString, std::vector<double>>> transformCmds;
114 for(
int cmdId = allMatches.size() - 1; cmdId >= 0; cmdId-- )
116 std::vector<wxString>& groups = allMatches[cmdId];
118 if( groups.size() != 3 )
121 const wxString& cmdName = groups[1].Strip( wxString::both ).Lower();
122 const wxString& cmdArgsStr = groups[2];
124 wxArrayString cmdParts = wxSplit( cmdArgsStr,
',',
'\0' );
125 std::vector<double> cmdArgs;
127 for(
const wxString& cmdPart : cmdParts )
130 wxASSERT( cmdPart.Strip( wxString::both ).ToCDouble( &arg ) );
132 cmdArgs.push_back( arg );
135 transformCmds.emplace_back( cmdName, cmdArgs );
138 return transformCmds;
146 wxString key = !aLibName.empty() ? ( aLibName +
':' + libReference ) : libReference;
149 libId.
Parse( key,
true );
157 if( aStyle == wxS(
"0" ) )
159 else if( aStyle == wxS(
"1" ) )
161 else if( aStyle == wxS(
"2" ) )
170 if( aType == wxS(
"0" ) )
172 else if( aType == wxS(
"1" ) )
174 else if( aType == wxS(
"2" ) )
176 else if( aType == wxS(
"3" ) )
178 else if( aType == wxS(
"4" ) )
370 aReporter->
Report(
_(
"Power Port with unknown style imported as 'Bar' type." ),
392 std::map<wxString, wxString> paramMap,
393 wxArrayString aShapes )
395 for( wxString shapeStr : aShapes )
397 wxArrayString arr = wxSplit( shapeStr,
'~',
'\0' );
399 wxString elType = arr[0];
400 if( elType == wxS(
"PL" ) || elType == wxS(
"PG" ) )
402 wxArrayString ptArr = wxSplit( arr[1],
' ',
'\0' );
403 wxString strokeColor = arr[2];
404 double lineWidth =
Convert( arr[3] );
406 wxString fillColor = arr[5].Lower();
411 for(
size_t i = 1; i < ptArr.size(); i += 2 )
419 if( elType == wxS(
"PG" ) )
420 chain.SetClosed(
true );
422 if(
chain.PointCount() < 2 )
425 for(
int i = 0; i <
chain.PointCount(); i++ )
426 line->AddPoint(
chain.CPoint( i ) );
428 if(
chain.IsClosed() )
429 line->AddPoint(
chain.CPoint( 0 ) );
434 if( fillColor != wxS(
"none" ) )
436 line->SetFilled(
true );
438 if( fillColor == strokeColor )
446 else if( elType == wxS(
"PT" ) )
448 wxString pointsData = arr[1];
449 wxString strokeColor = arr[2];
450 double lineWidth =
Convert( arr[3] );
452 wxString fillColor = arr[5].Lower();
455 std::vector<SHAPE_LINE_CHAIN> lineChains =
462 if( outline.IsClosed() )
463 outline.Append( outline.CPoint( 0 ),
true );
465 for(
const VECTOR2I& pt : outline.CPoints() )
466 shape->AddPoint( pt );
471 if( fillColor != wxS(
"none" ) )
473 shape->SetFilled(
true );
475 if( fillColor == strokeColor )
484 else if( elType == wxS(
"Pimage" ) )
489 wxString imageUrl = arr[10];
491 if( imageUrl.BeforeFirst(
':' ) == wxS(
"data" ) )
493 wxArrayString paramsArr =
494 wxSplit( imageUrl.AfterFirst(
':' ).BeforeFirst(
',' ),
';',
'\0' );
496 wxString data = imageUrl.AfterFirst(
',' );
498 if( paramsArr.size() > 0 )
500 wxString mimeType = paramsArr[0];
501 wxMemoryBuffer buf = wxBase64Decode( data );
503 if( mimeType == wxS(
"image/svg+xml" ) )
519 libsymImporter.
SetScale( pixelScale );
528 for( std::unique_ptr<EDA_ITEM>& item : libsymImporter.
GetItems() )
533 wxMemoryInputStream memis( buf.GetData(), buf.GetDataLen() );
535 wxImage::SetDefaultLoadFlags( wxImage::GetDefaultLoadFlags()
536 & ~wxImage::Load_Verbose );
538 if( img.LoadFile( memis, mimeType ) )
540 int dimMul = img.GetWidth() * img.GetHeight();
541 double maxPixels = 30000;
543 if( dimMul > maxPixels )
545 double scale = sqrt( maxPixels / dimMul );
546 img.Rescale( img.GetWidth() *
scale, img.GetHeight() *
scale );
559 else if( elType == wxS(
"A" ) )
561 wxString data = arr[1];
562 wxString strokeColor = arr[3];
563 double lineWidth =
Convert( arr[4] );
565 wxString fillColor = arr[6].Lower();
568 std::vector<SHAPE_LINE_CHAIN> chains =
571 auto transform = [](
VECTOR2I aVec )
578 for(
int i = 0; i <=
chain.PointCount() && i != -1; i =
chain.NextShape( i ) )
580 if(
chain.IsArcStart( i ) )
584 std::unique_ptr<SCH_SHAPE> shape =
587 shape->SetArcGeometry( transform( arc.
GetP0() ),
589 transform( arc.
GetP1() ) );
594 if( fillColor != wxS(
"none" ) )
596 shape->SetFilled(
true );
598 if( fillColor == strokeColor )
610 std::unique_ptr<SCH_SHAPE> shape =
613 shape->AddPoint( transform( seg.
A ) );
614 shape->AddPoint( transform( seg.
B ) );
624 else if( elType == wxS(
"R" ) )
629 cr.
x = !arr[3].empty() ?
Convert( arr[3] ) : 0,
630 cr.
y = !arr[4].empty() ?
Convert( arr[4] ) : 0;
633 wxString strokeColor = arr[7];
634 double lineWidth =
Convert( arr[8] );
636 wxString fillColor = arr[10].Lower();
644 rect->SetEnd(
RelPosSym( start + size ) );
649 if( fillColor != wxS(
"none" ) )
651 rect->SetFilled(
true );
653 if( fillColor == strokeColor )
663 else if( elType == wxS(
"E" ) )
669 wxString strokeColor = arr[5];
670 double lineWidth =
Convert( arr[6] );
672 wxString fillColor = arr[8].Lower();
681 if( fillColor != wxS(
"none" ) )
683 circle->SetFilled(
true );
685 if( fillColor == strokeColor )
693 else if( elType == wxS(
"P" ) )
695 wxString sepShapeStr = shapeStr;
696 sepShapeStr.Replace( wxS(
"^^" ), wxS(
"\n" ) );
698 wxArrayString segments = wxSplit( sepShapeStr,
'\n',
'\0' );
699 wxArrayString mainParts = wxSplit( segments[0],
'~',
'\0' );
700 wxArrayString pinDotParts = wxSplit( segments[1],
'~',
'\0' );
701 wxArrayString pinPathColorParts = wxSplit( segments[2],
'~',
'\0' );
702 wxArrayString pinNameParts = wxSplit( segments[3],
'~',
'\0' );
703 wxArrayString pinNumParts = wxSplit( segments[4],
'~',
'\0' );
707 wxString pinNumber = mainParts[3];
713 bool nameVisible = pinNameParts[0] != wxS(
"0" );
714 wxString pinName = pinNameParts[4];
716 bool numVisible = pinNumParts[0] != wxS(
"0" );
720 bool vertical =
false;
724 wxString lineData = pinPathColorParts[0];
725 wxRegEx regex( wxS(
"^M\\s*([-\\d.]+)[,\\s]([-\\d.]+)\\s*([h|v])\\s*([-\\d.]+)\\s*$" ) );
727 if( regex.Matches( lineData ) )
729 startPoint.
x =
Convert( regex.GetMatch( lineData, 1 ) );
730 startPoint.
y =
Convert( regex.GetMatch( lineData, 2 ) );
732 vertical = regex.GetMatch( lineData, 3 ).Contains( wxS(
"v" ) );
733 pinLen =
Convert( regex.GetMatch( lineData, 4 ) );
740 if( startPoint.
x == pinPos.
x && pinLen < 0 )
742 else if( startPoint.
x == pinPos.
x && pinLen > 0 )
744 else if( startPoint.
x != pinPos.
x && pinLen < 0 )
746 else if( startPoint.
x != pinPos.
x && pinLen > 0 )
751 if( startPoint.
y == pinPos.
y && pinLen < 0 )
753 else if( startPoint.
y == pinPos.
y && pinLen > 0 )
755 else if( startPoint.
y != pinPos.
y && pinLen < 0 )
757 else if( startPoint.
y != pinPos.
y && pinLen > 0 )
763 if( pinRotation == 0 )
765 else if( pinRotation == 90 )
767 else if( pinRotation == 180 )
769 else if( pinRotation == 270 )
775 if( segments.size() > 5 )
777 wxArrayString dotParts = wxSplit( segments[5],
'~',
'\0' );
778 wxArrayString clockParts = wxSplit( segments[6],
'~',
'\0' );
780 if( dotParts.size() == 3 && clockParts.size() == 2 )
782 if( dotParts[0] == wxS(
"1" ) )
790 pinPos + ( dotPos - pinPos ).Resize(
std::abs( pinLen ) ) ) );
797 if( clockParts[0] == wxS(
"1" ) )
799 std::vector<SHAPE_LINE_CHAIN> lineChains =
806 if( outline.IsClosed() )
807 outline.Append( outline.CPoint( 0 ),
true );
809 for(
const VECTOR2I& pt : outline.CPoints() )
810 shape->AddPoint( pt );
820 std::unique_ptr<SCH_PIN>
pin = std::make_unique<SCH_PIN>( aSymbol );
822 pin->SetName( pinName );
823 pin->SetNumber( pinNumber );
824 pin->SetOrientation( orient );
825 pin->SetType( elecType );
826 pin->SetLength( kPinLen );
828 pin->SetUnit( pinUnit );
830 if(
pin->GetNumberTextSize() *
int( pinNumber.size() ) > kPinLen )
831 pin->SetNumberTextSize( kPinLen / pinNumber.size() );
841 else if( elType == wxS(
"T" ) )
843 wxString textType = arr[1];
847 wxString fontname = arr[6];
848 wxString fontSize = arr[7];
849 wxString baselineAlign = arr[10];
850 wxString textStr = arr[12];
851 bool visible = arr[13] != wxS(
"0" );
853 textStr.Replace( wxS(
"\\n" ), wxS(
"\n" ) );
856 wxString halignStr = arr[14];
861 if( textType == wxS(
"P" ) )
867 else if( textType == wxS(
"N" ) )
882 if( halignStr == wxS(
"middle" ) )
884 else if( halignStr == wxS(
"end" ) )
894 if( !fontSize.IsEmpty() )
896 if( fontSize.EndsWith( wxS(
"pt" ) ) )
897 ptSize =
Convert( fontSize.BeforeFirst(
'p' ) );
898 else if( fontSize.IsNumber() )
904 if( textStr.Contains( wxS(
"\n" ) ) )
921 std::map<wxString, wxString> aParams,
922 wxArrayString aShapes )
924 std::unique_ptr<LIB_SYMBOL> ksymbol = std::make_unique<LIB_SYMBOL>( wxEmptyString );
928 std::optional<wxString> valOpt;
929 wxString symbolName = wxS(
"Unknown" );
931 if( ( valOpt =
get_opt( aParams, wxS(
"name" ) ) ) )
932 symbolName = *valOpt;
933 else if( ( valOpt =
get_opt( aParams, wxS(
"spiceSymbolName" ) ) ) )
934 symbolName = *valOpt;
936 wxString symbolPrefix;
938 if( ( valOpt =
get_opt( aParams, wxS(
"pre" ) ) ) )
939 symbolPrefix = *valOpt;
940 else if( ( valOpt =
get_opt( aParams, wxS(
"spicePre" ) ) ) )
941 symbolPrefix = *valOpt;
945 ksymbol->SetLibId( libId );
946 ksymbol->SetName( symbolName );
948 ksymbol->GetReferenceField().SetText( symbolPrefix );
949 ksymbol->GetValueField().SetText( symbolName );
953 wxString srcName = attrName;
955 if( srcName == wxS(
"Datasheet" ) )
956 srcName = wxS(
"link" );
958 if( ( valOpt =
get_opt( aParams, srcName ) ) )
960 if( valOpt->empty() )
963 SCH_FIELD* fd = ksymbol->FindFieldCaseInsensitive( attrName );
968 ksymbol->AddField( fd );
978 return ksymbol.release();
982 const wxString& aNetname )
984 std::unique_ptr<LIB_SYMBOL> ksymbol = std::make_unique<LIB_SYMBOL>( wxEmptyString );
990 ksymbol->SetGlobalPower();
991 ksymbol->SetLibId( libId );
992 ksymbol->SetName( aNetname );
993 ksymbol->GetReferenceField().SetText( wxS(
"#PWR" ) );
994 ksymbol->GetReferenceField().SetVisible(
false );
995 ksymbol->GetValueField().SetText( aNetname );
996 ksymbol->GetValueField().SetVisible(
true );
997 ksymbol->SetDescription( wxString::Format(
_(
"Power symbol creates a global "
998 "label with name '%s'" ),
1000 ksymbol->SetKeyWords( wxS(
"power-flag" ) );
1001 ksymbol->SetShowPinNames(
false );
1002 ksymbol->SetShowPinNumbers(
false );
1004 std::unique_ptr<SCH_PIN>
pin = std::make_unique<SCH_PIN>( ksymbol.get() );
1006 pin->SetName( aNetname );
1007 pin->SetNumber( wxS(
"1" ) );
1010 pin->SetLength( 0 );
1012 ksymbol->AddDrawItem(
pin.release() );
1018 if( aFlagTypename == wxS(
"part_netLabel_gnD" ) )
1022 else if( aFlagTypename == wxS(
"part_netLabel_GNd" ) )
1026 else if( aFlagTypename == wxS(
"part_netLabel_gNd" ) )
1030 else if( aFlagTypename == wxS(
"part_netLabel_GnD" ) )
1034 else if( aFlagTypename == wxS(
"part_netLabel_VCC" ) )
1039 else if( aFlagTypename == wxS(
"part_netLabel_+5V" ) )
1044 else if( aFlagTypename == wxS(
"part_netLabel_VEE" ) )
1048 else if( aFlagTypename == wxS(
"part_netLabel_-5V" ) )
1052 else if( aFlagTypename == wxS(
"part_netLabel_Bar" ) )
1059 ksymbol->GetValueField().SetPosition( valueFieldPos );
1061 return std::make_pair( ksymbol.release(), flip );
1065 const wxString& aFileName, wxArrayString aShapes )
1067 std::map<wxString, std::unique_ptr<LIB_SYMBOL>> loadedSymbols;
1068 std::map<wxString, int> namesCounter;
1069 std::vector<std::unique_ptr<SCH_ITEM>> createdItems;
1071 for( wxString shap : aShapes )
1073 shap.Replace( wxS(
"#@$" ), wxS(
"\n" ) );
1074 wxArrayString parts = wxSplit( shap,
'\n',
'\0' );
1076 if( parts.size() < 1 )
1079 wxArrayString arr = wxSplit( parts[0],
'~',
'\0' );
1081 if( arr.size() < 1 )
1084 wxString rootType = arr[0];
1086 if( rootType == wxS(
"LIB" ) )
1088 if( arr.size() < 4 )
1093 wxString symbolName = wxString::Format( wxS(
"Unknown_%s_%s" ), arr[1], arr[2] );
1095 wxArrayString paramParts = wxSplit( arr[3],
'`',
'\0' );
1097 std::map<wxString, wxString> paramMap;
1099 for(
size_t i = 1; i < paramParts.size(); i += 2 )
1101 wxString key = paramParts[i - 1];
1102 wxString value = paramParts[i];
1104 if( key == wxS(
"spiceSymbolName" ) && !value.IsEmpty() )
1107 paramMap[key] = value;
1110 int& serial = namesCounter[symbolName];
1113 symbolName << wxS(
"_" ) << serial;
1117 paramMap[wxS(
"spiceSymbolName" )] = symbolName;
1119 parts.RemoveAt( 0 );
1124 loadedSymbols.emplace( symbolName, sym );
1131 std::unique_ptr<SCH_SYMBOL> schSym =
1132 std::make_unique<SCH_SYMBOL>( *sym, libId, &aSchematic->
CurrentSheet(), 0 );
1134 schSym->SetPosition(
RelPos( origin ) );
1135 schSym->SetRef( &aSchematic->
CurrentSheet(), referenceStr );
1137 createdItems.push_back( std::move( schSym ) );
1139 else if( rootType == wxS(
"F" ) )
1141 wxString sepShapeStr = parts[0];
1142 sepShapeStr.Replace( wxS(
"^^" ), wxS(
"\n" ) );
1144 wxArrayString segments = wxSplit( sepShapeStr,
'\n',
'\0' );
1147 wxArrayString valueParts = wxSplit( segments[2],
'~',
'\0' );
1149 wxString flagTypename = arr[1];
1151 double angle =
Convert( arr[4] );
1153 wxString netnameValue = valueParts[0];
1155 double textAngle =
Convert( valueParts[4] );
1156 wxString halignStr = valueParts[5];
1157 wxString valueFontname = valueParts[7];
1158 wxString valueFontsize = valueParts[8];
1160 if( flagTypename == wxS(
"part_netLabel_netPort" ) )
1162 std::unique_ptr<SCH_GLOBALLABEL> label =
1163 std::make_unique<SCH_GLOBALLABEL>(
RelPos( pos ), netnameValue );
1167 for(
double i = angle; i > 0; i -= 90 )
1171 if( segments.size() > 3 )
1173 wxArrayString shapeParts = wxSplit( segments[3],
'~',
'\0' );
1174 if( shapeParts[0] == wxS(
"PL" ) )
1176 wxArrayString ptArr = wxSplit( shapeParts[1],
' ',
'\0' );
1180 for(
size_t i = 1; i < ptArr.size(); i += 2 )
1192 if( shapeCenter.
x >= 0 )
1199 if( shapeCenter.
y >= 0 )
1207 label->SetSpinStyle( spin );
1210 createdItems.push_back( std::move( label ) );
1216 bool flip = pair.second;
1220 std::unique_ptr<SCH_SYMBOL> schSym = std::make_unique<SCH_SYMBOL>(
1229 else if( angle == 90 )
1243 schSym->SetPosition(
RelPos( pos ) );
1255 if( halignStr == wxS(
"middle" ) )
1257 else if( halignStr == wxS(
"end" ) )
1262 if( flip && ( angle == 90 || angle == 270 ) )
1274 if( flagTypename == wxS(
"part_netLabel_Bar" ) )
1278 if( angle == 0 && flagTypename == wxS(
"part_netLabel_Bar" ) )
1285 if( valueFontsize.EndsWith( wxS(
"pt" ) ) )
1286 ptSize =
Convert( valueFontsize.BeforeFirst(
'p' ) );
1290 if( netnameValue.Contains( wxS(
"\n" ) ) )
1299 createdItems.push_back( std::move( schSym ) );
1302 else if( rootType == wxS(
"W" ) )
1304 wxArrayString ptArr = wxSplit( arr[1],
' ',
'\0' );
1313 for(
size_t i = 1; i < ptArr.size(); i += 2 )
1316 for(
int segId = 0; segId <
chain.SegmentCount(); segId++ )
1318 const SEG& seg =
chain.CSegment( segId );
1320 std::unique_ptr<SCH_LINE> line = std::make_unique<SCH_LINE>( seg.
A,
LAYER_WIRE );
1321 line->SetEndPoint( seg.
B );
1323 createdItems.push_back( std::move( line ) );
1326 else if( rootType == wxS(
"N" ) )
1329 double angle =
Convert( arr[3] );
1330 wxString netname = arr[5];
1331 wxString halignStr = arr[7];
1338 std::unique_ptr<SCH_LABEL> label =
1339 std::make_unique<SCH_LABEL>(
RelPos( pos ), netname );
1341 if( halignStr == wxS(
"middle" ) )
1343 else if( halignStr == wxS(
"end" ) )
1349 label->Rotate90(
false );
1351 createdItems.push_back( std::move( label ) );
1353 else if( rootType == wxS(
"O" ) )
1357 std::unique_ptr<SCH_NO_CONNECT> noConn =
1358 std::make_unique<SCH_NO_CONNECT>(
RelPos( pos ) );
1360 createdItems.push_back( std::move( noConn ) );
1362 else if( rootType == wxS(
"J" ) )
1367 std::unique_ptr<SCH_JUNCTION> junction =
1368 std::make_unique<SCH_JUNCTION>(
RelPos( pos ) );
1370 createdItems.push_back( std::move( junction ) );
1372 else if( rootType == wxS(
"T" ) )
1375 int angle =
Convert( arr[4] );
1377 wxString fontname = arr[6];
1378 wxString fontSize = arr[7];
1379 wxString baselineAlign = arr[10];
1380 wxString textStr = arr[12];
1382 textStr.Replace( wxS(
"\\n" ), wxS(
"\n" ) );
1385 wxString halignStr = arr[14];
1387 std::unique_ptr<SCH_TEXT> textItem =
1388 std::make_unique<SCH_TEXT>(
RelPos( pos ), textStr );
1390 textItem->SetTextAngleDegrees( ( 360 - angle ) % 360 );
1393 if( halignStr == wxS(
"middle" ) )
1395 else if( halignStr == wxS(
"end" ) )
1404 if( fontSize.EndsWith( wxS(
"pt" ) ) )
1405 ptSize =
Convert( fontSize.BeforeFirst(
'p' ) );
1409 if( textStr.Contains( wxS(
"\n" ) ) )
1414 textItem->SetTextSize(
VECTOR2I( ktextSize, ktextSize ) );
1418 createdItems.push_back( std::move( textItem ) );
1420 else if( rootType == wxS(
"R" ) )
1425 cr.
x = !arr[3].empty() ?
Convert( arr[3] ) : 0,
1426 cr.
y = !arr[4].empty() ?
Convert( arr[4] ) : 0;
1429 wxString strokeColor = arr[7];
1430 double lineWidth =
Convert( arr[8] );
1432 wxString fillColor = arr[10].Lower();
1439 rect->SetStart(
RelPos( start ) );
1440 rect->SetEnd(
RelPos( start + size ) );
1444 if( fillColor != wxS(
"none" ) )
1446 rect->SetFilled(
true );
1448 if( fillColor == strokeColor )
1454 createdItems.push_back( std::move( rect ) );
1460 else if( rootType == wxS(
"I" ) )
1465 wxString imageUrl = arr[6];
1466 wxString transformData = arr[9];
1471 std::vector<std::pair<wxString, std::vector<double>>> transformCmds =
1474 auto applyTransform = [&](
SCH_ITEM* aSchItem )
1476 for(
const auto& cmd : transformCmds )
1478 if( cmd.first == wxS(
"rotate" ) )
1480 if( cmd.second.size() != 3 )
1483 double cmdAngle = 360 - cmd.second[0];
1484 VECTOR2D cmdAround( cmd.second[1], cmd.second[2] );
1486 for(
double i = cmdAngle; i > 0; i -= 90 )
1492 aSchItem->Rotate(
RelPos( cmdAround ),
false );
1496 aSchItem->Rotate(
RelPos( cmdAround ),
false );
1501 aSchItem->Rotate(
RelPos( cmdAround ),
false );
1505 else if( cmd.first == wxS(
"translate" ) )
1507 if( cmd.second.size() != 2 )
1510 VECTOR2D cmdOffset( cmd.second[0], cmd.second[1] );
1511 aSchItem->Move(
ScalePos( cmdOffset ) );
1513 else if( cmd.first == wxS(
"scale" ) )
1515 if( cmd.second.size() != 2 )
1518 double cmdScaleX = cmd.second[0];
1519 double cmdScaleY = cmd.second[1];
1525 if( cmdScaleX < 0 && cmdScaleY > 0 )
1527 aSchItem->MirrorHorizontally( 0 );
1529 else if( cmdScaleX > 0 && cmdScaleY < 0 )
1531 aSchItem->MirrorVertically( 0 );
1533 else if( cmdScaleX < 0 && cmdScaleY < 0 )
1535 aSchItem->MirrorHorizontally( 0 );
1536 aSchItem->MirrorVertically( 0 );
1545 if( imageUrl.BeforeFirst(
':' ) == wxS(
"data" ) )
1547 wxArrayString paramsArr =
1548 wxSplit( imageUrl.AfterFirst(
':' ).BeforeFirst(
',' ),
';',
'\0' );
1550 wxString data = imageUrl.AfterFirst(
',' );
1552 if( paramsArr.size() > 0 )
1554 wxString mimeType = paramsArr[0];
1555 wxMemoryBuffer buf = wxBase64Decode( data );
1557 if( mimeType == wxS(
"image/svg+xml" ) )
1573 schImporter.
SetScale( pixelScale );
1580 svgImportPlugin.
Import();
1582 for( std::unique_ptr<EDA_ITEM>& item : schImporter.
GetItems() )
1586 applyTransform( schItem );
1588 createdItems.emplace_back( schItem );
1593 std::unique_ptr<SCH_BITMAP> bitmap = std::make_unique<SCH_BITMAP>();
1596 wxImage::SetDefaultLoadFlags( wxImage::GetDefaultLoadFlags()
1597 & ~wxImage::Load_Verbose );
1601 VECTOR2D kcenter = kstart + ksize / 2;
1605 bitmap->SetPosition( kcenter );
1607 applyTransform( bitmap.get() );
1609 createdItems.push_back( std::move( bitmap ) );
1619 for( std::unique_ptr<SCH_ITEM>& ptr : createdItems )
1629 offset.
x =
KiROUND( offset.
x / alignGrid ) * alignGrid;
1630 offset.
y =
KiROUND( offset.
y / alignGrid ) * alignGrid;
1637 for( std::unique_ptr<SCH_ITEM>& ptr : createdItems )
1639 ptr->Move( offset );
1640 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()
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()
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...
Spin style for labels of all kinds on schematics.
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.
@ FILLED_WITH_BG_BODYCOLOR
@ FILLED_SHAPE
Fill with object color.
#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.
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