25#include <wx/filename.h> 
   27#include <wx/xml/xml.h> 
   43const std::map<CADSTAR_ARCHIVE_PARSER::TEXT_FIELD_NAME, wxString>
 
   45                {   { TEXT_FIELD_NAME::DESIGN_TITLE, wxT( 
"DESIGN_TITLE" ) },
 
   46                    { TEXT_FIELD_NAME::SHORT_JOBNAME, wxT( 
"SHORT_JOBNAME" ) },
 
   47                    { TEXT_FIELD_NAME::LONG_JOBNAME, wxT( 
"LONG_JOBNAME" ) },
 
   48                    { TEXT_FIELD_NAME::NUM_OF_SHEETS, wxT( 
"##" ) },
 
   49                    { TEXT_FIELD_NAME::SHEET_NUMBER, wxT( 
"#" ) },
 
   50                    { TEXT_FIELD_NAME::SHEET_NAME, wxT( 
"SHEETNAME" ) },
 
   51                    { TEXT_FIELD_NAME::VARIANT_NAME, wxT( 
"VARIANT_NAME" ) },
 
   52                    { TEXT_FIELD_NAME::VARIANT_DESCRIPTION, wxT( 
"VARIANT_DESCRIPTION" ) },
 
   53                    { TEXT_FIELD_NAME::REG_USER, wxT( 
"REG_USER" ) },
 
   54                    { TEXT_FIELD_NAME::COMPANY_NAME, wxT( 
"COMPANY_NAME" ) },
 
   55                    { TEXT_FIELD_NAME::CURRENT_USER, wxT( 
"CURRENT_USER" ) },
 
   56                    { TEXT_FIELD_NAME::DATE, wxT( 
"DATE" ) },
 
   57                    { TEXT_FIELD_NAME::TIME, wxT( 
"TIME" ) },
 
   58                    { TEXT_FIELD_NAME::MACHINE_NAME, wxT( 
"MACHINE_NAME" ) } };
 
   63    wxASSERT( aNode->GetName() == wxT( 
"FORMAT" ) );
 
 
   73    wxASSERT( aNode->GetName() == wxT( 
"TIMESTAMP" ) );
 
 
   87    wxASSERT( aNode->GetName() == wxT( 
"HEADER" ) );
 
   91    for( ; cNode; cNode = cNode->
GetNext() )
 
   93        wxString nodeName = cNode->GetName();
 
   95        if( nodeName == wxT( 
"FORMAT" ) )
 
   97            Format.Parse( cNode, aContext );
 
   99        else if( nodeName == wxT( 
"JOBFILE" ) )
 
  103        else if( nodeName == wxT( 
"JOBTITLE" ) )
 
  107        else if( nodeName == wxT( 
"GENERATOR" ) )
 
  111        else if( nodeName == wxT( 
"RESOLUTION" ) )
 
  115            if( ( subNode->GetName() == wxT( 
"METRIC" ) )
 
  130        else if( nodeName == wxT( 
"TIMESTAMP" ) )
 
 
  144    wxASSERT( aNode->GetName() == wxT( 
"VMASTER" ) || aNode->GetName() == wxT( 
"VARIANT" ) );
 
  148    if( aNode->GetName() == wxT( 
"VMASTER" ) )
 
 
  164    wxASSERT( aNode->GetName() == wxT( 
"VHIERARCHY" ) );
 
  168    for( ; cNode; cNode = cNode->
GetNext() )
 
  170        if( cNode->GetName() == wxT( 
"VMASTER" ) || cNode->GetName() == wxT( 
"VARIANT" ) )
 
  173            variant.
Parse( cNode, aContext );
 
  174            Variants.insert( std::make_pair( variant.
ID, variant ) );
 
 
  186    wxASSERT( aNode->GetName() == wxT( 
"LINECODE" ) );
 
  196    if( !cNode || cNode->GetName() != wxT( 
"STYLE" ) )
 
  201    if( styleStr == wxT( 
"SOLID" ) )
 
  205    else if( styleStr == wxT( 
"DASH" ) )
 
  209    else if( styleStr == wxT( 
"DASHDOT" ) )
 
  213    else if( styleStr == wxT( 
"DASHDOTDOT" ) )
 
  217    else if( styleStr == wxT( 
"DOT" ) )
 
  224                                          wxString::Format( 
"LINECODE -> %s", 
Name ) );
 
 
  231    wxASSERT( aNode->GetName() == wxT( 
"HATCH" ) );
 
  238    if( !cNode || cNode->GetName() != wxT( 
"ORIENT" ) )
 
 
  247    wxASSERT( aNode->GetName() == wxT( 
"HATCHCODE" ) );
 
  253    wxString 
location = wxString::Format( 
"HATCHCODE -> %s", 
Name );
 
  255    for( ; cNode; cNode = cNode->
GetNext() )
 
  257        if( cNode->GetName() != wxT( 
"HATCH" ) )
 
  261        hatch.
Parse( cNode, aContext );
 
 
  269    wxASSERT( aNode->GetName() == wxT( 
"FONT" ) );
 
  277    for( ; cNode; cNode = cNode->
GetNext() )
 
  279        wxString cNodeName = cNode->GetName();
 
  281        if( cNodeName == wxT( 
"ITALIC" ) )
 
  283        else if( cNodeName == wxT( 
"KERNING" ) )
 
 
  293    wxASSERT( aNode->GetName() == wxT( 
"TEXTCODE" ) );
 
  306        if( cNode->GetName() == wxT( 
"FONT" ) )
 
  307            Font.Parse( cNode, aContext );
 
 
  316    wxASSERT( aNode->GetName() == wxT( 
"ROUTEREASSIGN" ) );
 
  323    for( ; cNode; cNode = cNode->
GetNext() )
 
  325        wxString cNodeName = cNode->GetName();
 
  327        if( cNodeName == wxT( 
"NECKWIDTH" ) )
 
  329        else if( cNodeName == wxT( 
"SROUTEWIDTH" ) )
 
  331        else if( cNodeName == wxT( 
"MINWIDTH" ) )
 
  333        else if( cNodeName == wxT( 
"MAXWIDTH" ) )
 
 
  343    wxASSERT( aNode->GetName() == wxT( 
"ROUTECODE" ) );
 
  351    for( ; cNode; cNode = cNode->
GetNext() )
 
  353        wxString cNodeName = cNode->GetName();
 
  355        if( cNodeName == wxT( 
"NECKWIDTH" ) )
 
  359        else if( cNodeName == wxT( 
"SROUTEWIDTH" ) )
 
  363        else if( cNodeName == wxT( 
"MINWIDTH" ) )
 
  367        else if( cNodeName == wxT( 
"MAXWIDTH" ) )
 
  371        else if( cNodeName == wxT( 
"ROUTEREASSIGN" ) )
 
  374            routereassign.
Parse( cNode, aContext );
 
 
  393    wxASSERT( aNode->GetName() == wxT( 
"E" ) );
 
  399                                wxString::Format( 
"%s->%s", aNode->
GetParent()->GetName(),
 
 
  407    wxASSERT( aNode->GetName() == wxT( 
"PT" ) );
 
 
  416    wxASSERT( aNode->GetName() == wxT( 
"PT" ) );
 
 
  425    wxString aNodeName = aNode->GetName();
 
  427    if( aNodeName == wxT( 
"PT" ) || aNodeName == wxT( 
"ACWARC" ) || aNodeName == wxT( 
"CWARC" )
 
  428            || aNodeName == wxT( 
"CWSEMI" ) || aNodeName == wxT( 
"ACWSEMI" ) )
 
 
  443    wxString aNodeName = aNode->GetName();
 
  445    if( aNodeName == wxT( 
"PT" ) )
 
  450        End.Parse( aNode, aContext );
 
  452    else if( aNodeName == wxT( 
"ACWARC" ) || aNodeName == wxT( 
"CWARC" ) )
 
  454        if( aNodeName == wxT( 
"ACWARC" ) )
 
  464    else if( aNodeName == wxT( 
"ACWSEMI" ) || aNodeName == wxT( 
"CWSEMI" ) )
 
  466        if( aNodeName == wxT( 
"ACWSEMI" ) )
 
  480        wxASSERT_MSG( 
true, wxT( 
"Unknown VERTEX type" ) );
 
 
  486        const std::function<
VECTOR2I( 
const VECTOR2I& )> aCadstarToKicadPointCallback,
 
  487        int aAccuracy )
 const 
  491        aChainToAppendTo->
Append( aCadstarToKicadPointCallback( 
End ) );
 
  495    wxCHECK_MSG( aChainToAppendTo->
PointCount() > 0, ,
 
  496                 "Can't append an arc to vertex to an empty chain" );
 
  499                                        aCadstarToKicadPointCallback ),
 
 
  505        const std::function<
VECTOR2I( 
const VECTOR2I& )> aCadstarToKicadPointCallback )
 const 
  508                 "Can't build an arc for a straight segment!" );
 
  511    VECTOR2I endPoint = aCadstarToKicadPointCallback( 
End );
 
  515        centerPoint = ( startPoint / 2 ) + ( endPoint / 2 );
 
  517        centerPoint = aCadstarToKicadPointCallback( 
Center );
 
  523    VECTOR2I transform = aCadstarToKicadPointCallback( { 500, 500 } )
 
  524                       - aCadstarToKicadPointCallback( { 0, 0 } );
 
  526    if( ( transform.
x > 0 && transform.
y < 0 ) || ( transform.
x < 0 && transform.
y > 0 ) )
 
  527        clockwise = !clockwise;
 
 
  537    wxASSERT( aNode->GetName() == wxT( 
"CUTOUT" ) );
 
 
  545    wxString aNodeName = aNode->GetName();
 
  547    if( aNodeName == wxT( 
"OPENSHAPE" ) || aNodeName == wxT( 
"OUTLINE" )
 
  548            || aNodeName == wxT( 
"SOLID" ) || aNodeName == wxT( 
"HATCHED" ) )
 
 
  563    wxString aNodeName = aNode->GetName();
 
  565    if( aNodeName == wxT( 
"OPENSHAPE" ) )
 
  572    else if( aNodeName == wxT( 
"OUTLINE" ) )
 
  579    else if( aNodeName == wxT( 
"SOLID" ) )
 
  586    else if( aNodeName == wxT( 
"HATCHED" ) )
 
  595        wxASSERT_MSG( 
true, wxT( 
"Unknown SHAPE type" ) );
 
 
  600        const std::function<
VECTOR2I( 
const VECTOR2I& )> aCadstarToKicadPointCallback,
 
  601        int aMaxError  )
 const 
  608    for( 
const auto& vertex : 
Vertices )
 
  609        vertex.AppendToChain( &outline, aCadstarToKicadPointCallback, aMaxError );
 
 
  624        const std::function<
VECTOR2I( 
const VECTOR2I& )> aCadstarToKicadPointCallback,
 
  625        int aMaxError )
 const 
  634    for( 
const auto& cutout : 
Cutouts )
 
  638        if( cutout.Vertices.size() == 0 )
 
  641        for( 
const auto& cutoutVertex : cutout.Vertices )
 
  642            cutoutVertex.AppendToChain( &hole, aCadstarToKicadPointCallback, aMaxError );
 
  647        cutout.Vertices.at( 0 ).AppendToChain( &hole, aCadstarToKicadPointCallback, aMaxError );
 
 
  658    wxASSERT( aNode->GetName() == wxT( 
"UNITS" ) );
 
  662    if( unit == wxT( 
"CENTIMETER" ) )
 
  664    else if( unit == wxT( 
"INCH" ) )
 
  666    else if( unit == wxT( 
"METER" ) )
 
  668    else if( unit == wxT( 
"MICROMETRE" ) )
 
  670    else if( unit == wxT( 
"MM" ) )
 
  672    else if( unit == wxT( 
"THOU" ) )
 
  674    else if( unit == wxT( 
"DESIGN" ) )
 
 
  685    wxASSERT( aNode->GetName() == wxT( 
"ANGUNITS" ) );
 
  689    if( angUnitStr == wxT( 
"DEGREES" ) )
 
  691    else if( angUnitStr == wxT( 
"RADIANS" ) )
 
 
  702    wxString aNodeName = aNode->GetName();
 
  704    if( aNodeName == wxT( 
"FRACTIONALGRID" ) || aNodeName == wxT( 
"STEPGRID" ) )
 
 
  713    wxASSERT( 
IsGrid( aNode ) );
 
  715    wxString aNodeName = aNode->GetName();
 
  717    if( aNodeName == wxT( 
"FRACTIONALGRID" ) )
 
  719    else if( aNodeName == wxT( 
"STEPGRID" ) )
 
  722        wxASSERT_MSG( 
true, wxT( 
"Unknown Grid Type" ) );
 
 
  732    wxASSERT( aNode->GetName() == wxT( 
"GRIDS" ) );
 
  736    for( ; cNode; cNode = cNode->
GetNext() )
 
  738        wxString cNodeName = cNode->GetName();
 
  740        if( cNodeName == wxT( 
"WORKINGGRID" ) )
 
  747                        workingGridNode->GetName(), wxT( 
"GRIDS -> WORKINGGRID" ) );
 
  754        else if( cNodeName == wxT( 
"SCREENGRID" ) )
 
  761                        screenGridNode->GetName(), wxT( 
"GRIDS -> SCREENGRID" ) );
 
  771            userGrid.
Parse( cNode, aContext );
 
 
  780    wxString cNodeName = aChildNode->GetName();
 
  782    if( cNodeName == wxT( 
"UNITS" ) )
 
  786    else if( cNodeName == wxT( 
"UNITSPRECISION" ) )
 
  790    else if( cNodeName == wxT( 
"INTERLINEGAP" ) )
 
  794    else if( cNodeName == wxT( 
"BARLINEGAP" ) )
 
  798    else if( cNodeName == wxT( 
"ALLOWBARTEXT" ) )
 
  802    else if( cNodeName == wxT( 
"ANGULARPRECISION" ) )
 
  806    else if( cNodeName == wxT( 
"DESIGNORIGIN" ) )
 
  810    else if( cNodeName == wxT( 
"DESIGNAREA" ) )
 
  813        DesignArea             = std::make_pair( pts[0], pts[1] );
 
  815    else if( cNodeName == wxT( 
"DESIGNREF" ) )
 
  819    else if( cNodeName == wxT( 
"DESIGNLIMIT" ) )
 
  823    else if( cNodeName == wxT( 
"PINNOOFFSET" ) )
 
  827    else if( cNodeName == wxT( 
"PINNOANGLE" ) )
 
 
  842    wxASSERT( aNode->GetName() == wxT( 
"SETTINGS" ) );
 
  846    for( ; cNode; cNode = cNode->
GetNext() )
 
  848        wxString cNodeName = cNode->GetName();
 
 
  861    static const std::map<TEXT_FIELD_NAME, wxString> txtTokens =
 
  885    wxString remainingStr = aTextString;
 
  888    while( remainingStr.size() > 0 )
 
  891        size_t startpos = remainingStr.Find( wxT( 
"<@" ) );
 
  893        if( 
static_cast<int>( startpos ) == wxNOT_FOUND )
 
  896            returnStr += remainingStr;
 
  901            returnStr += remainingStr.SubString( 0, startpos - 1 );
 
  903        if( ( startpos + 2 ) >= remainingStr.size() )
 
  906        remainingStr = remainingStr.Mid( startpos + 2 );
 
  911        for( std::pair<TEXT_FIELD_NAME, wxString> txtF : txtTokens )
 
  913            if( remainingStr.StartsWith( txtF.second ) )
 
  915                foundField = txtF.first;
 
  923            returnStr += wxT( 
"<@" );
 
  928        size_t endpos = remainingStr.Find( wxT( 
"@>" ) );
 
  930        if( 
static_cast<int>( endpos ) == wxNOT_FOUND )
 
  934            returnStr += wxT( 
"<@" ) + remainingStr;
 
  938        size_t   valueStart = txtTokens.at( foundField ).size();
 
  939        wxString fieldValue = remainingStr.SubString( valueStart, endpos - 1 );
 
  945            wxASSERT_MSG( fieldValue.at( 0 ) == 
'"', 
"Expected '\"' as the first character" );
 
  947            size_t splitPos = fieldValue.find_first_of( 
'"', 1 );
 
  948            address         = fieldValue.SubString( 1, splitPos - 1 );
 
  953                wxASSERT_MSG( remainingStr.EndsWith( wxT( 
"@>" ) ),
 
  954                              "Expected '@>' at the end of a hyperlink" );
 
  956                fieldValue = remainingStr.SubString( valueStart + splitPos + 1,
 
  957                                                     remainingStr.Length() - 3 );
 
  959                remainingStr = wxEmptyString;
 
  963                fieldValue = fieldValue.Mid( splitPos + 1 );
 
 1004            returnStr += fieldValue;
 
 1009            wxFileName fn( address );
 
 1010            wxString   fieldFmt = wxT( 
"FROM_FILE_%s_%s" );
 
 1011            wxString   fieldName = wxString::Format( fieldFmt, fn.GetName(), fn.GetExt() );
 
 1020                fieldName = wxString::Format( fieldFmt, fn.GetName(), fn.GetExt() )
 
 1021                            + wxString::Format( wxT( 
"_%d" ), version++ );
 
 1025            returnStr += wxT( 
"${" ) + fieldName + wxT( 
"}" );
 
 1037            wxFAIL_MSG( 
"We should have already covered this scenario above" );
 
 1042        if( ( endpos + 2 ) >= remainingStr.size() )
 
 1045        remainingStr = remainingStr.Mid( endpos + 2 );
 
 
 1054    wxASSERT( aNode->GetName() == wxT( 
"ALIGN" ) );
 
 1058    if( alignmentStr == wxT( 
"BOTTOMCENTER" ) )
 
 1060    else if( alignmentStr == wxT( 
"BOTTOMLEFT" ) )
 
 1062    else if( alignmentStr == wxT( 
"BOTTOMRIGHT" ) )
 
 1064    else if( alignmentStr == wxT( 
"CENTERCENTER" ) )
 
 1066    else if( alignmentStr == wxT( 
"CENTERLEFT" ) )
 
 1068    else if( alignmentStr == wxT( 
"CENTERRIGHT" ) )
 
 1070    else if( alignmentStr == wxT( 
"TOPCENTER" ) )
 
 1072    else if( alignmentStr == wxT( 
"TOPLEFT" ) )
 
 1074    else if( alignmentStr == wxT( 
"TOPRIGHT" ) )
 
 
 1086    wxASSERT( aNode->GetName() == wxT( 
"JUSTIFICATION" ) );
 
 1090    if( justificationStr == wxT( 
"LEFT" ) )
 
 1092    else if( justificationStr == wxT( 
"RIGHT" ) )
 
 1094    else if( justificationStr == wxT( 
"CENTER" ) )
 
 
 1105    wxASSERT( aNode->GetName() == wxT( 
"READABILITY" ) );
 
 1109    if( readabilityStr == wxT( 
"BOTTOM_TO_TOP" ) )
 
 1111    else if( readabilityStr == wxT( 
"TOP_TO_BOTTOM" ) )
 
 
 1131    wxString cNodeName = aChildNode->GetName();
 
 1133    if( cNodeName == wxT( 
"PT" ) )
 
 1134        Position.Parse( aChildNode, aContext );
 
 1135    else if( cNodeName == wxT( 
"ORIENT" ) )
 
 1137    else if( cNodeName == wxT( 
"MIRROR" ) )
 
 1139    else if( cNodeName == wxT( 
"FIX" ) )
 
 1141    else if( cNodeName == wxT( 
"ALIGN" ) )
 
 1143    else if( cNodeName == wxT( 
"JUSTIFICATION" ) )
 
 
 1154    wxASSERT( aNode->GetName() == wxT( 
"ATTRLOC" ) );
 
 1161    for( ; cNode; cNode = cNode->
GetNext() )
 
 
 1176    wxASSERT( aNode->GetName() == wxT( 
"COLUMNORDER" ) );
 
 
 1187    wxASSERT( aNode->GetName() == wxT( 
"COLUMNWIDTH" ) );
 
 
 1198    wxASSERT( aNode->GetName() == wxT( 
"ATTRNAME" ) );
 
 1204    wxString 
location = wxString::Format( 
"ATTRNAME -> %s", 
Name );
 
 1206    for( ; cNode; cNode = cNode->
GetNext() )
 
 1208        wxString cNodeName = cNode->GetName();
 
 1210        if( cNodeName == wxT( 
"ATTROWNER" ) )
 
 1214            if( attOwnerVal == wxT( 
"ALL_ITEMS" ) )
 
 1216            else if( attOwnerVal == wxT( 
"AREA" ) )
 
 1218            else if( attOwnerVal == wxT( 
"BOARD" ) )
 
 1220            else if( attOwnerVal == wxT( 
"COMPONENT" ) )
 
 1222            else if( attOwnerVal == wxT( 
"CONNECTION" ) )
 
 1224            else if( attOwnerVal == wxT( 
"COPPER" ) )
 
 1226            else if( attOwnerVal == wxT( 
"DOCSYMBOL" ) )
 
 1228            else if( attOwnerVal == wxT( 
"FIGURE" ) )
 
 1230            else if( attOwnerVal == wxT( 
"NET" ) )
 
 1232            else if( attOwnerVal == wxT( 
"NETCLASS" ) )
 
 1234            else if( attOwnerVal == wxT( 
"PART" ) )
 
 1236            else if( attOwnerVal == wxT( 
"PART_DEFINITION" ) )
 
 1238            else if( attOwnerVal == wxT( 
"PIN" ) )
 
 1240            else if( attOwnerVal == wxT( 
"SIGNALREF" ) )
 
 1242            else if( attOwnerVal == wxT( 
"SYMBOL" ) )
 
 1244            else if( attOwnerVal == wxT( 
"SYMDEF" ) )
 
 1246            else if( attOwnerVal == wxT( 
"TEMPLATE" ) )
 
 1248            else if( attOwnerVal == wxT( 
"TESTPOINT" ) )
 
 1253        else if( cNodeName == wxT( 
"ATTRUSAGE" ) )
 
 1257            if( attUsageVal == wxT( 
"BOTH" ) )
 
 1259            else if( attUsageVal == wxT( 
"COMPONENT" ) )
 
 1261            else if( attUsageVal == wxT( 
"PART_DEFINITION" ) )
 
 1263            else if( attUsageVal == wxT( 
"PART_LIBRARY" ) )
 
 1265            else if( attUsageVal == wxT( 
"SYMBOL" ) )
 
 1270        else if( cNodeName == wxT( 
"NOTRANSFER" ) )
 
 1274        else if( cNodeName == wxT( 
"COLUMNORDER" ) )
 
 1277            cOrder.
Parse( cNode, aContext );
 
 1280        else if( cNodeName == wxT( 
"COLUMNWIDTH" ) )
 
 1283            cWidth.
Parse( cNode, aContext );
 
 1286        else if( cNodeName == wxT( 
"COLUMNINVISIBLE" ) )
 
 
 1300    wxASSERT( aNode->GetName() == wxT( 
"ATTR" ) );
 
 1307    for( ; cNode; cNode = cNode->
GetNext() )
 
 1309        if( cNode->GetName() == wxT( 
"READONLY" ) )
 
 1313        else if( cNode->GetName() == wxT( 
"ATTRLOC" ) )
 
 
 1328    wxASSERT( aNode->GetName() == wxT( 
"TEXTLOC" ) );
 
 1331    bool     attributeIDisSet = 
false;
 
 1333    if( attributeStr == wxT( 
"PART_NAME" ) )
 
 1336        attributeIDisSet = 
true;
 
 1338    else if( attributeStr == wxT( 
"COMP_NAME" ) )
 
 1341        attributeIDisSet = 
true;
 
 1343    else if( attributeStr == wxT( 
"COMP_NAME2" ) )
 
 1346        attributeIDisSet = 
true;
 
 1348    else if( attributeStr == wxT( 
"SYMBOL_NAME" ) )
 
 1351        attributeIDisSet = 
true;
 
 1353    else if( attributeStr == wxT( 
"LINK_ORIGIN" ) )
 
 1356        attributeIDisSet = 
true;
 
 1358    else if( attributeStr == wxT( 
"SIGNALNAME_ORIGIN" ) )
 
 1361        attributeIDisSet = 
true;
 
 1363    else if( attributeStr == wxT( 
"ATTRREF" ) )
 
 1366        attributeIDisSet = 
false;
 
 1379    for( ; cNode; cNode = cNode->
GetNext() )
 
 1381        wxString cNodeName = cNode->GetName();
 
 1387        else if( !attributeIDisSet && cNodeName == wxT( 
"ATTRREF" ) )
 
 1390            attributeIDisSet = 
true;
 
 1392        else if( cNodeName == wxT( 
"ORIENT" ) )
 
 1396        else if( cNodeName == wxT( 
"MIRROR" ) )
 
 1400        else if( cNodeName == wxT( 
"FIX" ) )
 
 1404        else if( cNodeName == wxT( 
"ALIGN" ) )
 
 1408        else if( cNodeName == wxT( 
"JUSTIFICATION" ) )
 
 
 1425    wxASSERT( aNode->GetName() == wxT( 
"NETCLASS" ) );
 
 1431    wxString 
location = wxString::Format( 
"NETCLASS -> %s", 
Name );
 
 1433    for( ; cNode; cNode = cNode->
GetNext() )
 
 1435        wxString cNodeName = cNode->GetName();
 
 1437        if( cNodeName == wxT( 
"ATTR" ) )
 
 1440            attribute_val.
Parse( cNode, aContext );
 
 
 1453    wxASSERT( aNode->GetName() == wxT( 
"SPCCLASSNAME" ) );
 
 
 1462    wxString nodeName = aChildNode->GetName();
 
 1464    if( nodeName == wxT( 
"LINECODE" ) )
 
 1467        linecode.
Parse( aChildNode, aContext );
 
 1468        LineCodes.insert( std::make_pair( linecode.
ID, linecode ) );
 
 1470    else if( nodeName == wxT( 
"HATCHCODE" ) )
 
 1473        hatchcode.
Parse( aChildNode, aContext );
 
 1474        HatchCodes.insert( std::make_pair( hatchcode.
ID, hatchcode ) );
 
 1476    else if( nodeName == wxT( 
"TEXTCODE" ) )
 
 1479        textcode.
Parse( aChildNode, aContext );
 
 1480        TextCodes.insert( std::make_pair( textcode.
ID, textcode ) );
 
 1482    else if( nodeName == wxT( 
"ROUTECODE" ) )
 
 1485        routecode.
Parse( aChildNode, aContext );
 
 1486        RouteCodes.insert( std::make_pair( routecode.
ID, routecode ) );
 
 1488    else if( nodeName == wxT( 
"ATTRNAME" ) )
 
 1491        attrname.
Parse( aChildNode, aContext );
 
 1494    else if( nodeName == wxT( 
"NETCLASS" ) )
 
 1497        netclass.
Parse( aChildNode, aContext );
 
 1498        NetClasses.insert( std::make_pair( netclass.
ID, netclass ) );
 
 1500    else if( nodeName == wxT( 
"SPCCLASSNAME" ) )
 
 1503        spcclassname.
Parse( aChildNode, aContext );
 
 
 1517    wxASSERT( aNode->GetName() == wxT( 
"SWAPRULE" ) );
 
 1522    if( swapRuleStr == wxT( 
"NO_SWAP" ) )
 
 1524    else if( swapRuleStr == wxT( 
"USE_SWAP_LAYER" ) )
 
 
 1535    wxASSERT( aNode->GetName() == wxT( 
"REUSEBLOCK" ) );
 
 1543    for( ; cNode; cNode = cNode->
GetNext() )
 
 1545        wxString cNodeName = cNode->GetName();
 
 1547        if( cNodeName == wxT( 
"MIRROR" ) )
 
 1549        else if( cNodeName == wxT( 
"ORIENT" ) )
 
 
 1565    wxASSERT( aNode->GetName() == wxT( 
"REUSEBLOCKREF" ) );
 
 
 1576    wxASSERT( aNode->GetName() == wxT( 
"GROUP" ) );
 
 1583    for( ; cNode; cNode = cNode->
GetNext() )
 
 1585        wxString cNodeName = cNode->GetName();
 
 1587        if( cNodeName == wxT( 
"FIX" ) )
 
 1589        else if( cNodeName == wxT( 
"TRANSFER" ) )
 
 1591        else if( cNodeName == wxT( 
"GROUPREF" ) )
 
 1593        else if( cNodeName == wxT( 
"REUSEBLOCKREF" ) )
 
 
 1603    wxASSERT( aNode->GetName() == wxT( 
"FIGURE" ) );
 
 1610    bool     shapeIsInitialised = 
false; 
 
 1611    wxString 
location           = wxString::Format( 
"Figure %s", 
ID );
 
 1616    for( ; cNode; cNode = cNode->
GetNext() )
 
 1618        wxString cNodeName = cNode->GetName();
 
 1620        if( !shapeIsInitialised && 
Shape.IsShape( cNode ) )
 
 1622            Shape.Parse( cNode, aContext );
 
 1623            shapeIsInitialised = 
true;
 
 1625        else if( cNodeName == wxT( 
"SWAPRULE" ) )
 
 1629        else if( cNodeName == wxT( 
"FIX" ) )
 
 1633        else if( cNodeName == wxT( 
"GROUPREF" ) )
 
 1638        else if( cNodeName == wxT( 
"REUSEBLOCKREF" ) )
 
 1642        else if( cNodeName == wxT( 
"ATTR" ) )
 
 1645            attr.
Parse( cNode, aContext );
 
 
 1658    Parse( aNode, aContext, 
true );
 
 
 1665    wxASSERT( aNode->GetName() == wxT( 
"TEXT" ) );
 
 1681    for( ; cNode; cNode = cNode->
GetNext() )
 
 1683        wxString cNodeName = cNode->GetName();
 
 1685        if( cNodeName == wxT( 
"PT" ) )
 
 1687        else if( cNodeName == wxT( 
"ORIENT" ) )
 
 1689        else if( cNodeName == wxT( 
"MIRROR" ) )
 
 1691        else if( cNodeName == wxT( 
"FIX" ) )
 
 1693        else if( cNodeName == wxT( 
"SWAPRULE" ) )
 
 1695        else if( cNodeName == wxT( 
"ALIGN" ) )
 
 1697        else if( cNodeName == wxT( 
"JUSTIFICATION" ) )
 
 1699        else if( cNodeName == wxT( 
"GROUPREF" ) )
 
 1701        else if( cNodeName == wxT( 
"REUSEBLOCKREF" ) )
 
 
 1717    wxASSERT( aNode->GetName() == wxT( 
"SYMDEF" ) );
 
 
 1727    wxString cNodeName = aChildNode->GetName();
 
 1729    if( cNodeName == wxT( 
"PT" ) )
 
 1731        Origin.Parse( aChildNode, aContext );
 
 1733    else if( cNodeName == wxT( 
"STUB" ) )
 
 1737    else if( cNodeName == wxT( 
"VERSION" ) )
 
 1741    else if( cNodeName == wxT( 
"FIGURE" ) )
 
 1744        figure.
Parse( aChildNode, aContext );
 
 1745        Figures.insert( std::make_pair( figure.
ID, figure ) );
 
 1747    else if( cNodeName == wxT( 
"TEXT" ) )
 
 1750        txt.
Parse( aChildNode, aContext );
 
 1751        Texts.insert( std::make_pair( txt.
ID, txt ) );
 
 1753    else if( cNodeName == wxT( 
"TEXTLOC" ) )
 
 1756        textloc.
Parse( aChildNode, aContext );
 
 1759    else if( cNodeName == wxT( 
"ATTR" ) )
 
 1762        attrVal.
Parse( aChildNode, aContext );
 
 
 1776    wxASSERT( aNode->GetName() == wxT( 
"GATEDEFINITION" ) );
 
 
 1789    wxASSERT( aNode->GetName() == wxT( 
"PINTYPE" ) );
 
 1793    std::map<wxString, CADSTAR_PIN_TYPE> pinTypeMap = {
 
 1804    if( pinTypeMap.find( pinTypeStr ) == pinTypeMap.end() )
 
 1807    return pinTypeMap[pinTypeStr];
 
 
 1813    wxASSERT( aNode->GetName() == wxT( 
"PARTDEFINITIONPIN" ) );
 
 1819    for( ; cNode; cNode = cNode->
GetNext() )
 
 1821        wxString cNodeName = cNode->GetName();
 
 1823        if( cNodeName == wxT( 
"PINNAME" ) )
 
 1827        else if( cNodeName == wxT( 
"PINLABEL" ) )
 
 1831        else if( cNodeName == wxT( 
"PINSIGNAL" ) )
 
 1835        else if( cNodeName == wxT( 
"PINTERM" ) )
 
 1840        else if( cNodeName == wxT( 
"PINTYPE" ) )
 
 1844        else if( cNodeName == wxT( 
"PINLOAD" ) )
 
 1848        else if( cNodeName == wxT( 
"PINPOSITION" ) )
 
 1852        else if( cNodeName == wxT( 
"PINIDENTIFIER" ) )
 
 
 1866    wxASSERT( aNode->GetName() == wxT( 
"PARTPIN" ) );
 
 1872    for( ; cNode; cNode = cNode->
GetNext() )
 
 1874        wxString cNodeName = cNode->GetName();
 
 1876        if( cNodeName == wxT( 
"PINNAME" ) )
 
 1878        else if( cNodeName == wxT( 
"PINTYPE" ) )
 
 1880        else if( cNodeName == wxT( 
"PINIDENTIFIER" ) )
 
 
 1891    wxASSERT( aNode->GetName() == wxT( 
"PINEQUIVALENCE" ) );
 
 1893    wxXmlAttribute* xmlAttribute = aNode->GetAttributes();
 
 1895    for( ; xmlAttribute; xmlAttribute = xmlAttribute->GetNext() )
 
 1902        if( !xmlAttribute->GetValue().ToLong( &pinId ) )
 
 
 1915    wxASSERT( aNode->GetName() == wxT( 
"SWAPGATE" ) );
 
 1917    wxXmlAttribute* xmlAttribute = aNode->GetAttributes();
 
 1919    for( ; xmlAttribute; xmlAttribute = xmlAttribute->GetNext() )
 
 1926        if( !xmlAttribute->GetValue().ToLong( &pinId ) )
 
 
 1939    wxASSERT( aNode->GetName() == wxT( 
"SWAPGROUP" ) );
 
 1945    for( ; cNode; cNode = cNode->
GetNext() )
 
 1947        wxString cNodeName = cNode->GetName();
 
 1949        if( cNodeName == wxT( 
"EXTERNAL" ) )
 
 1953        else if( cNodeName == wxT( 
"SWAPGATE" ) )
 
 1956            swapGate.
Parse( cNode, aContext );
 
 
 1969    wxASSERT( aNode->GetName() == wxT( 
"PARTDEFINITION" ) );
 
 1975    for( ; cNode; cNode = cNode->
GetNext() )
 
 1977        wxString cNodeName = cNode->GetName();
 
 1979        if( cNodeName == wxT( 
"HIDEPINNAMES" ) )
 
 1983        else if( cNodeName == wxT( 
"MAXPIN" ) )
 
 1987        else if( cNodeName == wxT( 
"GATEDEFINITION" ) )
 
 1990            gate.
Parse( cNode, aContext );
 
 1993        else if( cNodeName == wxT( 
"PARTDEFINITIONPIN" ) )
 
 1996            pin.Parse( cNode, aContext );
 
 1997            Pins.insert( std::make_pair( 
pin.ID, 
pin ) );
 
 1999        else if( cNodeName == wxT( 
"ATTR" ) )
 
 2002            attr.
Parse( cNode, aContext );
 
 2005        else if( cNodeName == wxT( 
"PINEQUIVALENCE" ) )
 
 2008            pinEq.
Parse( cNode, aContext );
 
 2011        else if( cNodeName == wxT( 
"SWAPGROUP" ) )
 
 2014            swapGroup.
Parse( cNode, aContext );
 
 
 2027    wxASSERT( aNode->GetName() == wxT( 
"PART" ) );
 
 2034    for( ; cNode; cNode = cNode->
GetNext() )
 
 2036        wxString cNodeName = cNode->GetName();
 
 2038        if( cNodeName == wxT( 
"VERSION" ) )
 
 2042        else if( cNodeName == wxT( 
"HIDEPINNAMES" ) )
 
 2046        else if( cNodeName == wxT( 
"PARTDEFINITION" ) )
 
 2050        else if( cNodeName == wxT( 
"PARTPIN" ) )
 
 2053            pin.Parse( cNode, aContext );
 
 2056        else if( cNodeName == wxT( 
"ATTR" ) )
 
 2059            attr.
Parse( cNode, aContext );
 
 
 2072    wxASSERT( aNode->GetName() == wxT( 
"PARTS" ) );
 
 2076    for( ; cNode; cNode = cNode->
GetNext() )
 
 2078        wxString cNodeName = cNode->GetName();
 
 2080        if( cNodeName == wxT( 
"PART" ) )
 
 2083            part.
Parse( cNode, aContext );
 
 
 2099    wxASSERT( aNode->GetName() == wxT( 
"JPT" ) );
 
 
 2109    wxString cNodeName = aChildNode->GetName();
 
 2111    if( cNodeName == wxT( 
"PT" ) )
 
 2112        Location.Parse( aChildNode, aContext );
 
 2113    else if( cNodeName == wxT( 
"FIX" ) )
 
 2115    else if( cNodeName == wxT( 
"GROUPREF" ) )
 
 2117    else if( cNodeName == wxT( 
"REUSEBLOCKREF" ) )
 
 
 2131    for( ; cNode; cNode = cNode->
GetNext() )
 
 
 2144    wxASSERT( aNode->GetName() == wxT( 
"CONN" ) );
 
 
 2155    wxString cNodeName = aChildNode->GetName();
 
 2157    if( cNodeName == wxT( 
"FIX" ) )
 
 2161    else if( cNodeName == wxT( 
"HIDDEN" ) )
 
 2165    else if( cNodeName == wxT( 
"GROUPREF" ) )
 
 2169    else if( cNodeName == wxT( 
"REUSEBLOCKREF" ) )
 
 2173    else if( cNodeName == wxT( 
"ATTR" ) )
 
 2176        attrVal.
Parse( aChildNode, aContext );
 
 
 2190    wxASSERT( aNode->GetName() == wxT( 
"NET" ) );
 
 
 2198    wxString cNodeName = aChildNode->GetName();
 
 2200    if( cNodeName == wxT( 
"NETCODE" ) )
 
 2204    else if( cNodeName == wxT( 
"SIGNAME" ) )
 
 2208    else if( cNodeName == wxT( 
"SIGNUM" ) )
 
 2212    else if( cNodeName == wxT( 
"HIGHLIT" ) )
 
 2216    else if( cNodeName == wxT( 
"JPT" ) )
 
 2219        jpt.
Parse( aChildNode, aContext );
 
 2220        Junctions.insert( std::make_pair( jpt.
ID, jpt ) );
 
 2222    else if( cNodeName == wxT( 
"NETCLASSREF" ) )
 
 2226    else if( cNodeName == wxT( 
"SPACINGCLASS" ) )
 
 2230    else if( cNodeName == wxT( 
"ATTR" ) )
 
 2233        attrVal.
Parse( aChildNode, aContext );
 
 
 2247    wxASSERT( aNode->GetName() == wxT( 
"DOCSYMBOL" ) );
 
 2254    bool   originParsed = 
false;
 
 2256    for( ; cNode; cNode = cNode->
GetNext() )
 
 2258        wxString cNodeName = cNode->GetName();
 
 2260        if( !originParsed && cNodeName == wxT( 
"PT" ) )
 
 2262            Origin.Parse( cNode, aContext );
 
 2263            originParsed = 
true;
 
 2265        else if( cNodeName == wxT( 
"GROUPREF" ) )
 
 2269        else if( cNodeName == wxT( 
"REUSEBLOCKREF" ) )
 
 2273        else if( cNodeName == wxT( 
"FIX" ) )
 
 2277        else if( cNodeName == wxT( 
"MIRROR" ) )
 
 2281        else if( cNodeName == wxT( 
"READABILITY" ) )
 
 2285        else if( cNodeName == wxT( 
"ORIENT" ) )
 
 2289        else if( cNodeName == wxT( 
"ATTR" ) )
 
 2292            attr.
Parse( cNode, aContext );
 
 2295        else if( cNodeName == wxT( 
"SCALE" ) )
 
 
 2313    wxASSERT( aNode->GetName() == wxT( 
"DFLTSETTINGS" ) );
 
 2319    for( ; cNode; cNode = cNode->
GetNext() )
 
 2321        wxString cNodeName = cNode->GetName();
 
 2323        if( cNodeName == wxT( 
"INVISIBLE" ) )
 
 
 2337    wxASSERT( aNode->GetName() == wxT( 
"ATTRCOL" ) );
 
 2344    for( ; cNode; cNode = cNode->
GetNext() )
 
 2346        wxString cNodeName = cNode->GetName();
 
 2348        if( cNodeName == wxT( 
"INVISIBLE" ) )
 
 2352        else if( cNodeName == wxT( 
"NOTPICKABLE" ) )
 
 
 2366    wxASSERT( aNode->GetName() == wxT( 
"ATTRCOLORS" ) );
 
 2370    for( ; cNode; cNode = cNode->
GetNext() )
 
 2372        wxString cNodeName = cNode->GetName();
 
 2374        if( cNodeName == wxT( 
"DFLTSETTINGS" ) )
 
 2378        else if( cNodeName == wxT( 
"ATTRCOL" ) )
 
 2381            attrcol.
Parse( cNode, aContext );
 
 2384        else if( cNodeName == wxT( 
"INVISIBLE" ) )
 
 
 2398    wxASSERT( aNode->GetName() == wxT( 
"PARTNAMECOL" ) );
 
 2404    for( ; cNode; cNode = cNode->
GetNext() )
 
 2406        wxString cNodeName = cNode->GetName();
 
 2408        if( cNodeName == wxT( 
"INVISIBLE" ) )
 
 2412        else if( cNodeName == wxT( 
"NOTPICKABLE" ) )
 
 
 2426    static const wxString c_numAttributes = wxT( 
"numAttributes" );
 
 2429    long     numAttributes = 0;
 
 2431    if( aNode->GetAttribute( c_numAttributes, &
result ) )
 
 2433        numAttributes = wxAtol( 
result );
 
 2434        aNode->DeleteAttribute( c_numAttributes );
 
 2438#if wxUSE_UNICODE_WCHAR 
 2439    std::wstring numAttrStr = std::to_wstring( numAttributes );
 
 2441    std::string numAttrStr = std::to_string( numAttributes );
 
 2446    wxString paramName = wxT( 
"attr" );
 
 2447    paramName << numAttrStr;
 
 
 2454                                                const wxString& aFileTypeIdentifier,
 
 2457    KEYWORD   emptyKeywords[1] = {};
 
 2458    XNODE*    rootNode = 
nullptr;
 
 2459    XNODE*    cNode = 
nullptr;
 
 2460    XNODE*    iNode = 
nullptr;
 
 2462    bool      cadstarFileCheckDone = 
false;
 
 2464    wxCSConv  win1252( wxT( 
"windows-1252" ) );
 
 2465    wxMBConv* conv = &win1252; 
 
 2469    FILE* fp = wxFopen( aFileName, wxT( 
"rt" ) );
 
 2472        THROW_IO_ERROR( wxString::Format( 
_( 
"Cannot open file '%s'" ), aFileName ) );
 
 2474    fseek( fp, 0
L, SEEK_END );
 
 2475    long fileSize = ftell( fp );
 
 2478    DSNLEXER lexer( emptyKeywords, 0, 
nullptr,  fp, aFileName );
 
 2480    auto currentProgress =  [&]() -> 
double 
 2482                                return static_cast<double>( ftell( fp ) ) / fileSize;
 
 2485    double previousReportedProgress = -1.0;
 
 2489        if( aProgressReporter && ( currentProgress() - previousReportedProgress ) > 0.01 )
 
 2499            previousReportedProgress = currentProgress();
 
 2513                THROW_IO_ERROR( 
_( 
"The selected file is not valid or might be corrupt!" ) );
 
 2519            str   = wxString( lexer.
CurText(), *conv );
 
 2520            cNode = 
new XNODE( wxXML_ELEMENT_NODE, str );
 
 2529                iNode->AddChild( cNode );
 
 2531            else if( !cadstarFileCheckDone )
 
 2533                if( cNode->GetName() != aFileTypeIdentifier )
 
 2536                    THROW_IO_ERROR( 
_( 
"The selected file is not valid or might be corrupt!" ) );
 
 2539                cadstarFileCheckDone = 
true;
 
 2546            str = wxString( lexer.
CurText(), *conv );
 
 2554            THROW_IO_ERROR( 
_( 
"The selected file is not valid or might be corrupt!" ) );
 
 2559    if( iNode != 
nullptr )
 
 2562        THROW_IO_ERROR( 
_( 
"The selected file is not valid or might be corrupt!" ) );
 
 2573        THROW_IO_ERROR( 
_( 
"The selected file is not valid or might be corrupt!" ) );
 
 
 2582    return aAttribute->GetName() != wxT( 
"numAttributes" );
 
 
 2589#if wxUSE_UNICODE_WCHAR 
 2590    std::wstring idStr = std::to_wstring( aID );
 
 2592    std::string idStr = std::to_string( aID );
 
 2595    wxString attrName = wxS( 
"attr" );
 
 2600    if( !aNode->GetAttribute( attrName, &retVal ) )
 
 2605            return wxEmptyString;
 
 
 2639    if( aNode && aNode->
GetNext() )
 
 
 2647    if( aNode->
GetChildren()->GetName() == wxT( 
"E" ) )
 
 
 2657    std::vector<POINT> retVal;
 
 2661    for( ; cNode; cNode = cNode->
GetNext() )
 
 2663        if( cNode->GetName() == wxT( 
"PT" ) )
 
 2667            pt.
Parse( cNode, aContext );
 
 2668            retVal.push_back( pt );
 
 2670        else if( aTestAllChildNodes )
 
 2677            && retVal.size() != 
static_cast<size_t>( aExpectedNumPoints ) )
 
 2680                _( 
"Unexpected number of points in '%s'. Found %d but expected %d." ),
 
 2681                aNode->GetName(), retVal.size(), aExpectedNumPoints ) );
 
 
 2691    std::vector<VERTEX> retVal;
 
 2695    for( ; cNode; cNode = cNode->
GetNext() )
 
 2701            vertex.
Parse( cNode, aContext );
 
 2702            retVal.push_back( vertex );
 
 2704        else if( aTestAllChildNodes )
 
 
 2717    std::vector<CUTOUT> retVal;
 
 2721    for( ; cNode; cNode = cNode->
GetNext() )
 
 2723        if( cNode->GetName() == wxT( 
"CUTOUT" ) )
 
 2727            cutout.
Parse( cNode, aContext );
 
 2728            retVal.push_back( cutout );
 
 2730        else if( aTestAllChildNodes )
 
 
 2745    for( ; childNodes; childNodes = childNodes->
GetNext() )
 
 
 2753        XNODE* aRootNode, std::vector<wxString> aSubNodeChildrenToCount )
 
 2758    for( ; level1Node; level1Node = level1Node->
GetNext() )
 
 2760        for( wxString childNodeName : aSubNodeChildrenToCount )
 
 2762            if( level1Node->GetName() == childNodeName )
 
 
 2775    wxString escapedText = aCadstarString;
 
 2777    escapedText.Replace( wxT( 
"'" ), wxT( 
"~" ) );
 
 
 2785    if( !aKiCadTextItem->
GetText().IsEmpty() )
 
 2792        int      numExtraLines = 
text.Replace( 
"\n", 
"\n" );
 
 2793        numExtraLines -= 
text.at( 
text.size() - 1 ) == 
'\n'; 
 
 2794        positionOffset.
x *= numExtraLines;
 
 2795        positionOffset.
y *= numExtraLines;
 
 2797        aKiCadTextItem->
Offset( positionOffset );
 
 
 2803                                                  const wxString& aAlternateName )
 
 2805    if( aAlternateName.IsEmpty() )
 
 
CADSTAR_PIN_POSITION
Positioning of pin names can be in one of four quadrants.
 
CADSTAR_PIN_TYPE
file: cadstar_archive_objects.h Contains common object definitions
 
@ OUTPUT_NOT_OR
Output pin not OR tieable.
 
@ TRISTATE_DRIVER
Tristate output pin.
 
@ OUTPUT_OR
Output pin OR tieable.
 
@ TRISTATE_INPUT
Tristate input pin.
 
@ TRISTATE_BIDIR
Tristate bi-directional driver pin.
 
@ OUTPUT_NOT_NORM_OR
Output pin not normally OR tieable.
 
Helper functions and common defines between schematic and PCB Archive files.
 
#define SYMBOL_NAME_ATTRID
Symbol Name attribute ID - used for placement of designators on the schematic.
 
#define SIGNALNAME_ORIGIN_ATTRID
 
#define THROW_MISSING_NODE_IO_ERROR(nodename, location)
 
#define THROW_UNKNOWN_NODE_IO_ERROR(nodename, location)
 
#define LINK_ORIGIN_ATTRID
 
#define COMPONENT_NAME_2_ATTRID
Component Name 2 Attribute ID - typically used for indicating the placement of designators in placeme...
 
#define THROW_UNKNOWN_PARAMETER_IO_ERROR(param, location)
 
#define COMPONENT_NAME_ATTRID
Component Name Attribute ID - typically used for placement of designators on silk screen.
 
#define THROW_MISSING_PARAMETER_IO_ERROR(param, location)
 
#define THROW_PARSING_IO_ERROR(param, location)
 
READABILITY
Sets the readability direction of text.
 
@ BOTTOM_TO_TOP
When text is vertical, show it rotated 90 degrees anticlockwise.
 
@ TOP_TO_BOTTOM
When text is vertical, show it rotated 90 degrees clockwise.
 
@ ANTICLOCKWISE_SEMICIRCLE
 
@ STEPGRID
Param1 = X Step, Param2 = Y Step. A standard x,y grid.
 
@ FRACTIONALGRID
Param1 = Units, Param2 = Divisor.
 
SWAP_RULE
Corresponds to "Display when" Item property.
 
@ USE_SWAP_LAYER
Display when Mirrored.
 
@ NO_SWAP
Display when Unmirrored.
 
static UNITS ParseUnits(XNODE *aNode)
 
static ALIGNMENT ParseAlignment(XNODE *aNode)
 
static const std::map< TEXT_FIELD_NAME, wxString > CADSTAR_TO_KICAD_FIELDS
Map between CADSTAR fields and KiCad text variables.
 
TEXT_FIELD_NAME
These are special fields in text objects enclosed between the tokens '<@' and '>' such as <@[FIELD_NA...
 
@ NONE
Synthetic for flagging.
 
static SWAP_RULE ParseSwapRule(XNODE *aNode)
 
ALIGNMENT
From CADSTAR Help: "Text Alignment enables you to define the position of an alignment origin for all ...
 
@ NO_ALIGNMENT
NO_ALIGNMENT has different meaning depending on the object type.
 
static const long UNDEFINED_VALUE
 
static wxString generateLibName(const wxString &aRefName, const wxString &aAlternateName)
 
static void CheckNoNextNodes(XNODE *aNode)
 
static std::vector< CUTOUT > ParseAllChildCutouts(XNODE *aNode, PARSER_CONTEXT *aContext, bool aTestAllChildNodes=false)
If no children are present, it just returns an empty vector (without throwing an exception).
 
static XNODE * LoadArchiveFile(const wxString &aFileName, const wxString &aFileTypeIdentifier, PROGRESS_REPORTER *aProgressReporter=nullptr)
Reads a CADSTAR Archive file (S-parameter format).
 
static JUSTIFICATION ParseJustification(XNODE *aNode)
 
static wxString ParseTextFields(const wxString &aTextString, PARSER_CONTEXT *aParserContext)
Replaces CADSTAR fields for the equivalent in KiCad and stores the field values in aParserContext.
 
@ PART_DEFINITION
From CADSTAR Help: Assigned to Parts library Definitions and displayed by the Library searcher.
 
@ BOTH
From CADSTAR Help: Assigned to both Schematic symbols and PCB components, and displayed on Schematic ...
 
@ COMPONENT
From CADSTAR Help: Assigned to PCB components and displayed on PCB designs.
 
@ SYMBOL
From CADSTAR Help: Assigned to Schematic Symbols and displayed on Schematic Designs.
 
@ PART_LIBRARY
From CADSTAR Help: Only used by non-Cadstar applications.
 
static std::vector< VERTEX > ParseAllChildVertices(XNODE *aNode, PARSER_CONTEXT *aContext, bool aTestAllChildNodes=false)
If no children are present, it just returns an empty vector (without throwing an exception).
 
static void FixTextPositionNoAlignment(EDA_TEXT *aKiCadTextItem)
Correct the position of a text element that had NO_ALIGNMENT in CADSTAR.
 
static ANGUNITS ParseAngunits(XNODE *aNode)
 
long PART_DEFINITION_PIN_ID
Pin identifier in the part definition.
 
@ OUTLINE
Unfilled closed shape.
 
@ OPENSHAPE
Unfilled open shape. Cannot have cutouts.
 
@ SOLID
Filled closed shape (solid fill).
 
@ HATCHED
Filled closed shape (hatch fill).
 
static const double TXT_HEIGHT_RATIO
CADSTAR fonts are drawn on a 24x24 integer matrix, where the each axis goes from 0 to 24.
 
static wxString GetXmlAttributeIDString(XNODE *aNode, unsigned int aID, bool aIsRequired=true)
 
void checkPoint()
Updates m_progressReporter or throws if user canceled.
 
static bool IsValidAttribute(wxXmlAttribute *aAttribute)
 
static READABILITY ParseReadability(XNODE *aNode)
 
static std::vector< POINT > ParseAllChildPoints(XNODE *aNode, PARSER_CONTEXT *aContext, bool aTestAllChildNodes=false, int aExpectedNumPoints=UNDEFINED_VALUE)
If no children are present, it just returns an empty vector (without throwing an exception).
 
@ DESIGN
Inherits from design units (assumed Assignments->Technology->Units)
 
static wxString HandleTextOverbar(wxString aCadstarString)
Convert a string with CADSTAR overbar characters to equivalent in KiCad.
 
static void CheckNoChildNodes(XNODE *aNode)
 
static long GetXmlAttributeIDLong(XNODE *aNode, unsigned int aID, bool aIsRequired=true)
 
JUSTIFICATION
From CADSTAR Help: "Multi Line Text can also be justified as Left, Centre or Right.
 
static void ParseChildEValue(XNODE *aNode, PARSER_CONTEXT *aContext, EVALUE &aValueToParse)
 
static long GetNumberOfStepsForReporting(XNODE *aRootNode, std::vector< wxString > aSubNodeChildrenToCount)
 
PROGRESS_REPORTER * m_progressReporter
 
static long GetNumberOfChildNodes(XNODE *aNode)
 
static void InsertAttributeAtEnd(XNODE *aNode, wxString aValue)
 
@ PART_DEFINITION
Only library Attributes.
 
@ PART
Only library Attributes.
 
Implement a lexical analyzer for the SPECCTRA DSN file format.
 
const char * CurText() const
Return a pointer to the current token's text.
 
int NextTok()
Return the next token found in the input file or DSN_EOF when reaching the end of file.
 
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
 
const EDA_ANGLE & GetTextAngle() const
 
virtual const wxString & GetText() const
Return the string associated with the text object.
 
void Offset(const VECTOR2I &aOffset)
 
int GetInterline(const RENDER_SETTINGS *aSettings) const
Return the distance between two lines of text.
 
A progress reporter interface for use in multi-threaded environments.
 
virtual bool KeepRefreshing(bool aWait=false)=0
Update the UI (if any).
 
virtual void SetCurrentProgress(double aProgress)=0
Set the progress value to aProgress (0..1).
 
SHAPE_ARC & ConstructFromStartEndCenter(const VECTOR2I &aStart, const VECTOR2I &aEnd, const VECTOR2I &aCenter, bool aClockwise=false, double aWidth=0)
Constructs this arc from the given start, end and center.
 
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
 
virtual const VECTOR2I GetPoint(int aIndex) 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.
 
Represent a set of closed polygons.
 
int AddOutline(const SHAPE_LINE_CHAIN &aOutline)
Adds a new outline to the set and returns its index.
 
int AddHole(const SHAPE_LINE_CHAIN &aHole, int aOutline=-1)
Adds a new hole to the given outline (default: last) and returns its index.
 
An extension of wxXmlNode that can format its contents as KiCad-style s-expressions.
 
XNODE * GetParent() const
 
XNODE * GetChildren() const
 
void AddAttribute(const wxString &aName, const wxString &aValue) override
 
#define THROW_IO_ERROR(msg)
macro which captures the "call site" values of FILE_, __FUNCTION & LINE
 
This file contains miscellaneous commonly used macros and functions.
 
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
 
wxString ConvertToNewOverbarNotation(const wxString &aOldStr)
Convert the old ~...~ overbar notation to the new ~{...} one.
 
wxString EscapeString(const wxString &aSource, ESCAPE_CONTEXT aContext)
The Escape/Unescape routines use HTML-entity-reference-style encoding to handle characters which are:...
 
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
 
DFLTSETTINGS DefaultSettings
 
std::map< ATTRIBUTE_ID, ATTRCOL > AttributeColors
 
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
 
void ParseIdentifiers(XNODE *aNode, PARSER_CONTEXT *aContext)
 
virtual void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
 
JUSTIFICATION Justification
Note: Justification has no effect on single lines of text.
 
ALIGNMENT Alignment
In CADSTAR The default alignment for a TEXT object (when "(No Alignment()" is selected) Bottom Left o...
 
bool ParseSubNode(XNODE *aChildNode, PARSER_CONTEXT *aContext)
 
ATTRIBUTE_LOCATION AttributeLocation
 
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
 
bool HasLocation
Flag to know if this ATTRIBUTE_VALUE has a location i.e.
 
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
 
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
 
NOTE from CADSTAR help: To convert a Part Definition Attribute into a hyperlink, prefix the attribute...
 
std::vector< COLUMNWIDTH > ColumnWidths
 
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
 
bool NoTransfer
True="All Design Types", False="Current Design Type" "All Design Types" Description from CADSTAR Help...
 
std::vector< COLUMNORDER > ColumnOrders
 
wxString Name
Parenthesis aren't permitted in user attributes in CADSTAR.
 
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
 
std::vector< ATTRIBUTE_VALUE > Attributes
 
std::map< SPACING_CLASS_ID, SPCCLASSNAME > SpacingClassNames
 
std::map< LINECODE_ID, LINECODE > LineCodes
 
std::map< NETCLASS_ID, CADSTAR_NETCLASS > NetClasses
 
bool ParseSubNode(XNODE *aChildNode, PARSER_CONTEXT *aContext)
 
std::map< HATCHCODE_ID, HATCHCODE > HatchCodes
 
std::map< ATTRIBUTE_ID, ATTRNAME > AttributeNames
 
std::map< ROUTECODE_ID, ROUTECODE > RouteCodes
 
std::map< TEXTCODE_ID, TEXTCODE > TextCodes
 
Represent a cutout in a closed shape (e.g.
 
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
 
std::vector< VERTEX > Vertices
 
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
 
long ScaleRatioNumerator
Documentation symbols can be arbitrarily scaled when added to a design.
 
std::map< ATTRIBUTE_ID, ATTRIBUTE_VALUE > AttributeValues
 
long ScaleRatioDenominator
Documentation symbols can be arbitrarily scaled when added to a design.
 
POINT Origin
Origin of the component (this is used as the reference point when placing the component in the design...
 
REUSEBLOCKREF ReuseBlockRef
 
GROUP_ID GroupID
If not empty, this component is part of a group.
 
LAYER_ID LayerID
Move all objects in the Symdef to this layer.
 
DOCUMENTATION_SYMBOL_ID ID
 
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
 
SYMDEF_ID SymdefID
Normally documentation symbols only have TEXT, FIGURE and TEXT_LOCATION objects which are all drawn o...
 
Represent a floating value in E notation.
 
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
 
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
 
long Modifier2
It seems this is always 0 regardless of settings.
 
bool KerningPairs
From CADSTAR Help: "Kerning Pairs is for causing the       system to automatically reduce the spacing...
 
long Modifier1
It seems this is related to weight. 400=Normal, 700=Bold.
 
GRID ScreenGrid
From CADSTAR Help: "There is one Screen Grid, which is visible as dots on the screen.
 
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
 
std::vector< GRID > UserGrids
List of predefined grids created by the user.
 
static bool IsGrid(XNODE *aNode)
 
long Param1
Either Units or X step, depending on Type (see GRID_TYPE for more details)
 
long Param2
Either Divisor or Y step, depending on Type (see GRID_TYPE for more details)
 
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
 
GROUP_ID GroupID
If not empty, this GROUP is part of another GROUP.
 
bool Transfer
If true, the group is transferred to PCB.
 
REUSEBLOCKREF ReuseBlockRef
 
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
 
std::vector< HATCH > Hatches
 
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
 
long OrientAngle
1/1000 of a Degree
 
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
 
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
 
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
 
std::map< ATTRIBUTE_ID, ATTRIBUTE_VALUE > AttributeValues
It is possible to add attributes solely to a particular connection.
 
REUSEBLOCKREF ReuseBlockRef
 
void ParseIdentifiers(XNODE *aNode, PARSER_CONTEXT *aContext)
 
GROUP_ID GroupID
If not empty, this connection is part of a group.
 
bool ParseSubNode(XNODE *aChildNode, PARSER_CONTEXT *aContext)
 
GROUP_ID GroupID
If not empty, this JUNCTION is part of a group.
 
bool ParseSubNode(XNODE *aChildNode, PARSER_CONTEXT *aContext)
 
virtual void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
 
void ParseIdentifiers(XNODE *aNode, PARSER_CONTEXT *aContext)
 
NETELEMENT_ID ID
First character is "J".
 
REUSEBLOCKREF ReuseBlockRef
 
ROUTECODE_ID RouteCodeID
"NETCODE" subnode
 
bool ParseSubNode(XNODE *aChildNode, PARSER_CONTEXT *aContext)
 
wxString Name
This is undefined (wxEmptyString) if the net is unnamed.
 
std::map< NETELEMENT_ID, JUNCTION > Junctions
 
void ParseIdentifiers(XNODE *aNode, PARSER_CONTEXT *aContext)
 
NETCLASS_ID NetClassID
The net might not have a net class, in which case it will be wxEmptyString ("NETCLASSREF" subnode)
 
SPACING_CLASS_ID SpacingClassID
The net might not have a spacing class, in which case it will be wxEmptyString ("SPACINGCLASS" subnod...
 
std::map< ATTRIBUTE_ID, ATTRIBUTE_VALUE > AttributeValues
 
long SignalNum
This is undefined if the net has been given a name.
 
std::map< TEXT_FIELD_NAME, wxString > TextFieldToValuesMap
Values for the text field elements used in the CADSTAR design extracted from the text element instanc...
 
std::map< wxString, wxString > FilenamesToTextMap
CADSTAR doesn't have user defined text fields but does allow loading text from a file.
 
std::map< wxString, wxString > TextToHyperlinksMap
KiCad doesn't support hyperlinks but we use this map to display warning messages after import.
 
std::set< TEXT_FIELD_NAME > InconsistentTextFields
Text fields need to be updated in CADSTAR and it is possible that they are not consistent across text...
 
std::function< void()> CheckPointCallback
Callback function to report progress.
 
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
 
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
 
std::map< PART_ID, PART > PartDefinitions
 
< "GATEDEFINITION" node name
 
long PinCount
Number of pins (terminals) in the symbol.
 
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
 
GATE_ID ID
Usually "A", "B", "C", etc.
 
wxString Alternate
Symbol alternate name in the symbol library.
 
wxString Name
Symbol name in the symbol library.
 
< "PINEQUIVALENCE" Node name
 
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
 
std::vector< PART_DEFINITION_PIN_ID > PinIDs
All the pins in this vector are equivalent and can be swapped with each other.
 
< "PARTDEFINITIONPIN" node name
 
wxString Label
This Can be empty (subnode= "PINLABEL") From CADSTAR Help: "Pin Labels are an optional replacement fo...
 
wxString Name
Can be empty.
 
long Load
The electrical current expected on the pin (It is unclear what the units are, but only accepted value...
 
CADSTAR_PIN_POSITION Position
The pin names will use these positions when the symbol is added to a design subnode="PINPOSITION".
 
TERMINAL_ID TerminalPin
(subnode="PINTERM", param1)
 
wxString Identifier
This should match a pad identifier in the component footprint subnode="PINIDENTIFIER".
 
GATE_ID TerminalGate
(subnode="PINTERM", param0)
 
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
 
wxString Signal
Usually for Power/Ground pins, (subnode="PINSIGNAL")
 
PART_DEFINITION_PIN_ID ID
 
CADSTAR_PIN_TYPE Type
subnode="PINTYPE"
 
< "SWAPGATE" Node name (represents an "Element")
 
std::vector< PART_DEFINITION_PIN_ID > PinIDs
The pins in this vector describe a "gate".
 
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
 
wxString GateName
Optional.
 
std::vector< SWAP_GATE > SwapGates
Each of the elements in this vector can be swapped with each other - i.e.
 
bool External
Determines if this swap group is external (and internal) or internal only.
 
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
 
bool HidePinNames
Specifies whether to display the pin names/identifier in the schematic symbol or not.
 
std::map< GATE_ID, GATE > GateSymbols
 
std::vector< PIN_EQUIVALENCE > PinEquivalences
 
wxString Name
This name can be different to the PART name.
 
long MaxPinCount
Optional parameter which is used for specifying the number of electrical pins on the PCB component sy...
 
std::map< ATTRIBUTE_ID, ATTRIBUTE_VALUE > AttributeValues
Some attributes are defined within the part definition, whilst others are defined in the part.
 
std::map< PART_DEFINITION_PIN_ID, PIN > Pins
 
std::vector< SWAP_GROUP > SwapGroups
 
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
 
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
 
static CADSTAR_PIN_TYPE GetPinType(XNODE *aNode)
 
std::map< PART_PIN_ID, PART_PIN > PartPins
It is unclear why there are two "Pin" structures in CPA files... PART_PIN seems to be a reduced versi...
 
std::map< ATTRIBUTE_ID, ATTRIBUTE_VALUE > AttributeValues
Some attributes are defined within the part definition, whilst others are defined in the part itself.
 
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
 
bool HidePinNames
This seems to be a duplicate of DEFINITION::HidePinNames Possibly only used in older file formats?
 
Represent a point in x,y coordinates.
 
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
 
REUSEBLOCK_ID ReuseBlockID
 
wxString ItemReference
For Components, this references the designator in the reuse file.
 
bool IsEmpty()
Determines if this is empty (i.e. no design reuse associated)
 
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
 
wxString FileName
Filename of the reuse block (usually a .pcb). Used for reloading.
 
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
 
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
 
std::vector< ROUTEREASSIGN > RouteReassigns
 
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
 
UNITS Units
Units to display for linear dimensions.
 
long PinNoAngle
The angle at which the Pin ID is positioned relative to a terminal.
 
long InterlineGap
For CADSTAR font only, distance between lines of text, expressed as a percentage of the text height (...
 
long BarlineGap
For CADSTAR font only, distance between top bar and character, expressed as a percentage of the text ...
 
virtual void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
 
bool AllowBarredText
Specifies if barring is allowed in the design.
 
std::pair< POINT, POINT > DesignArea
 
long AngularPrecision
Number of decimal points to display for angular dimensions.
 
long UnitDisplPrecision
Number of decimal points to display for linear dimensions.
 
bool ParseSubNode(XNODE *aChildNode, PARSER_CONTEXT *aContext)
 
long PinNoOffset
The distance, of a Pin Name/Identifier from its parent terminal.
 
SHAPE_POLY_SET ConvertToPolySet(const std::function< VECTOR2I(const VECTOR2I &)> aCadstarToKicadPointCallback, int aAccuracy) const
 
std::vector< VERTEX > Vertices
 
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
 
wxString HatchCodeID
Only Applicable for HATCHED Type.
 
static bool IsShape(XNODE *aNode)
 
std::vector< CUTOUT > Cutouts
Not Applicable to OPENSHAPE Type.
 
SHAPE_LINE_CHAIN OutlineAsChain(const std::function< VECTOR2I(const VECTOR2I &)> aCadstarToKicadPointCallback, int aAccuracy) const
 
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
 
std::map< FIGURE_ID, FIGURE > Figures
 
std::map< ATTRIBUTE_ID, TEXT_LOCATION > TextLocations
This contains location of any attributes, including designator position.
 
POINT Origin
Origin of the component (this is used as the reference point when placing the component in the design...
 
wxString Alternate
This is in addition to ReferenceName.
 
bool ParseSubNode(XNODE *aChildNode, PARSER_CONTEXT *aContext)
 
std::map< TEXT_ID, TEXT > Texts
 
bool Stub
When the CADSTAR Archive file is exported without the component library, if components on the board a...
 
wxString ReferenceName
This is the name which identifies the symbol in the library Multiple components may exist with the sa...
 
void ParseIdentifiers(XNODE *aNode, PARSER_CONTEXT *aContext)
 
std::map< ATTRIBUTE_ID, ATTRIBUTE_VALUE > AttributeValues
These attributes might also have a location.
 
wxString BuildLibName() const
 
long Version
Version is a sequential integer number to identify discrepancies between the library and the design.
 
long Width
Defaults to 0 if using system fonts or, if using CADSTAR font, default to equal height (1:1 aspect ra...
 
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
 
Corresponds to CADSTAR "origin".
 
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
 
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
 
REUSEBLOCKREF ReuseBlockRef
 
ALIGNMENT Alignment
In CADSTAR The default alignment for a TEXT object (when "(No Alignment()" is selected) Bottom Left o...
 
JUSTIFICATION Justification
Note: Justification has no effect on single lines of text.
 
GROUP_ID GroupID
If not empty, this FIGURE is part of a group.
 
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
 
std::map< VARIANT_ID, VARIANT > Variants
 
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
 
< Nodename = "VARIANT" or "VMASTER" (master variant
 
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
 
VARIANT_ID ParentID
if empty, then this one is the master
 
Represents a vertex in a shape.
 
static bool IsVertex(XNODE *aNode)
 
SHAPE_ARC BuildArc(const VECTOR2I &aPrevPoint, const std::function< VECTOR2I(const VECTOR2I &)> aCadstarToKicadPointCallback) const
 
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
 
void AppendToChain(SHAPE_LINE_CHAIN *aChainToAppendTo, const std::function< VECTOR2I(const VECTOR2I &)> aCadstarToKicadPointCallback, int aAccuracy) const
 
Hold a keyword string and its unique integer token.
 
wxString result
Test unit parsing edge cases and error handling.
 
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.
 
VECTOR2< int32_t > VECTOR2I