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 )
420 auto line = std::make_unique<SCH_SHAPE>( SHAPE_T::POLY,
LAYER_DEVICE );
422 if( elType == wxS(
"PG" ) )
429 line->AddPoint( chain.
CPoint( i ) );
432 line->AddPoint( chain.
CPoint( 0 ) );
437 if( fillColor != wxS(
"none" ) )
439 line->SetFilled(
true );
441 if( fillColor == strokeColor )
442 line->SetFillMode( FILL_T::FILLED_SHAPE );
444 line->SetFillMode( FILL_T::FILLED_WITH_BG_BODYCOLOR );
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 =
463 auto shape = std::make_unique<SCH_SHAPE>( SHAPE_T::POLY,
LAYER_DEVICE );
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 )
479 shape->SetFillMode( FILL_T::FILLED_SHAPE );
481 shape->SetFillMode( FILL_T::FILLED_WITH_BG_BODYCOLOR );
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 ) )
585 SHAPE_ARC arc = chain.Arc( chain.ArcIndex( i ) );
587 std::unique_ptr<SCH_SHAPE> shape =
588 std::make_unique<SCH_SHAPE>( SHAPE_T::ARC,
LAYER_DEVICE );
590 shape->SetArcGeometry( transform( arc.
GetP0() ),
592 transform( arc.
GetP1() ) );
597 if( fillColor != wxS(
"none" ) )
599 shape->SetFilled(
true );
601 if( fillColor == strokeColor )
602 shape->SetFillMode( FILL_T::FILLED_SHAPE );
604 shape->SetFillMode( FILL_T::FILLED_WITH_BG_BODYCOLOR );
611 SEG seg = chain.CSegment( i );
613 std::unique_ptr<SCH_SHAPE> shape =
614 std::make_unique<SCH_SHAPE>( SHAPE_T::POLY,
LAYER_DEVICE );
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();
644 auto rect = std::make_unique<SCH_SHAPE>( SHAPE_T::RECTANGLE,
LAYER_DEVICE );
647 rect->SetEnd(
RelPosSym( start + size ) );
652 if( fillColor != wxS(
"none" ) )
654 rect->SetFilled(
true );
656 if( fillColor == strokeColor )
657 rect->SetFillMode( FILL_T::FILLED_SHAPE );
659 rect->SetFillMode( FILL_T::FILLED_WITH_BG_BODYCOLOR );
666 else if( elType == wxS(
"E" ) )
668 auto circle = std::make_unique<SCH_SHAPE>( SHAPE_T::CIRCLE,
LAYER_DEVICE );
672 wxString strokeColor = arr[5];
673 double lineWidth =
Convert( arr[6] );
675 wxString fillColor = arr[8].Lower();
678 circle->SetCenter(
RelPosSym( center ) );
681 circle->SetUnit( 0 );
684 if( fillColor != wxS(
"none" ) )
686 circle->SetFilled(
true );
688 if( fillColor == strokeColor )
689 circle->SetFillMode( FILL_T::FILLED_SHAPE );
691 circle->SetFillMode( FILL_T::FILLED_WITH_BG_BODYCOLOR );
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" );
720 wxString ptSize = pinNumParts[4];
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 )
767 orient = PIN_ORIENTATION::PIN_RIGHT;
768 else if( pinRotation == 90 )
769 orient = PIN_ORIENTATION::PIN_UP;
770 else if( pinRotation == 180 )
771 orient = PIN_ORIENTATION::PIN_LEFT;
772 else if( pinRotation == 270 )
773 orient = PIN_ORIENTATION::PIN_DOWN;
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" ) )
789 auto circle = std::make_unique<SCH_SHAPE>( SHAPE_T::CIRCLE,
LAYER_DEVICE );
791 circle->SetCenter(
RelPosSym( dotPos ) );
793 pinPos + ( dotPos - pinPos ).Resize(
std::abs( pinLen ) ) ) );
795 circle->SetUnit( 0 );
800 if( clockParts[0] == wxS(
"1" ) )
802 std::vector<SHAPE_LINE_CHAIN> lineChains =
807 auto shape = std::make_unique<SCH_SHAPE>( SHAPE_T::POLY,
LAYER_DEVICE );
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];
849 wxString
color = arr[5];
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->FindField( attrName,
true );
970 fd =
new SCH_FIELD( ksymbol.get(), ksymbol->GetNextAvailableFieldId(), 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 );
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" ) );
1011 pin->SetOrientation( PIN_ORIENTATION::PIN_DOWN );
1012 pin->SetType( ELECTRICAL_PINTYPE::PT_POWER_IN );
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' );
1148 wxArrayString mainParts = wxSplit( segments[0],
'~',
'\0' );
1149 wxArrayString uselessParts = wxSplit( segments[1],
'~',
'\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 );
1211 label->SetShape( LABEL_FLAG_SHAPE::L_INPUT );
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' );
1308 wxString strokeColor = arr[2];
1311 wxString fillColor = arr[5].Lower();
1316 for(
size_t i = 1; i < ptArr.size(); i += 2 )
1319 for(
int segId = 0; segId < chain.
SegmentCount(); 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];
1338 wxString fontname = arr[10];
1339 wxString fontSize = arr[11];
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] );
1379 wxString
color = arr[5];
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();
1440 std::unique_ptr<SCH_SHAPE> rect = std::make_unique<SCH_SHAPE>( SHAPE_T::RECTANGLE );
1442 rect->SetStart(
RelPos( start ) );
1443 rect->SetEnd(
RelPos( start + size ) );
1447 if( fillColor != wxS(
"none" ) )
1449 rect->SetFilled(
true );
1451 if( fillColor == strokeColor )
1452 rect->SetFillMode( FILL_T::FILLED_SHAPE );
1454 rect->SetFillMode( FILL_T::FILLED_WITH_BG_BODYCOLOR );
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
std::vector< SHAPE_LINE_CHAIN > ParseLineChains(const wxString &aData, int aArcMinSegLen, bool aForceClosed)
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)
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() const
Return reference to the value field.
SCH_FIELD & GetReferenceField() const
Return reference to the reference designator field.
void AddDrawItem(SCH_ITEM *aItem, bool aSort=true)
Add a new draw aItem to the draw object list and sort according to aSort.
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)=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
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 SetPosition(const VECTOR2I &aPos) override
void SetStroke(const STROKE_PARAMS &aStroke) override
void AddPoint(const VECTOR2I &aPosition)
VECTOR2I GetPosition() const override
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.
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...
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)
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_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.
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)
@ 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".
VECTOR2< int32_t > VECTOR2I
VECTOR2< double > VECTOR2D