Support for overbar syntax in Altium importer.
Fixes https://gitlab.com/kicad/code/kicad/issues/7979
This commit is contained in:
parent
c23e39dbe7
commit
f8a34d98b3
|
@ -22,6 +22,7 @@
|
|||
*/
|
||||
|
||||
#include "altium_parser.h"
|
||||
#include "altium_parser_utils.h"
|
||||
|
||||
#include <compoundfilereader.h>
|
||||
#include <ki_exception.h>
|
||||
|
@ -31,13 +32,14 @@
|
|||
#include <wx/log.h>
|
||||
#include <wx/translation.h>
|
||||
|
||||
const CFB::COMPOUND_FILE_ENTRY* FindStream(
|
||||
const CFB::CompoundFileReader& aReader, const char* aStreamName )
|
||||
const CFB::COMPOUND_FILE_ENTRY* FindStream( const CFB::CompoundFileReader& aReader,
|
||||
const char* aStreamName )
|
||||
{
|
||||
const CFB::COMPOUND_FILE_ENTRY* ret = nullptr;
|
||||
aReader.EnumFiles( aReader.GetRootEntry(), -1,
|
||||
[&]( const CFB::COMPOUND_FILE_ENTRY* aEntry, const CFB::utf16string& aU16dir,
|
||||
int level ) -> void {
|
||||
int level ) -> void
|
||||
{
|
||||
if( aReader.IsStream( aEntry ) )
|
||||
{
|
||||
std::string name = UTF16ToUTF8( aEntry->name );
|
||||
|
@ -64,8 +66,8 @@ const CFB::COMPOUND_FILE_ENTRY* FindStream(
|
|||
}
|
||||
|
||||
|
||||
ALTIUM_PARSER::ALTIUM_PARSER(
|
||||
const CFB::CompoundFileReader& aReader, const CFB::COMPOUND_FILE_ENTRY* aEntry )
|
||||
ALTIUM_PARSER::ALTIUM_PARSER( const CFB::CompoundFileReader& aReader,
|
||||
const CFB::COMPOUND_FILE_ENTRY* aEntry )
|
||||
{
|
||||
m_subrecord_end = nullptr;
|
||||
m_size = static_cast<size_t>( aEntry->size );
|
||||
|
@ -93,6 +95,7 @@ std::map<wxString, wxString> ALTIUM_PARSER::ReadProperties()
|
|||
std::map<wxString, wxString> kv;
|
||||
|
||||
uint32_t length = Read<uint32_t>();
|
||||
|
||||
if( length > GetRemainingBytes() )
|
||||
{
|
||||
m_error = true;
|
||||
|
@ -107,6 +110,7 @@ std::map<wxString, wxString> ALTIUM_PARSER::ReadProperties()
|
|||
// There is one case by kliment where Board6 ends with "|NEARDISTANCE=1000mi".
|
||||
// Both the 'l' and the null-byte are missing, which looks like Altium swallowed two bytes.
|
||||
bool hasNullByte = m_pos[length - 1] == '\0';
|
||||
|
||||
if( !hasNullByte )
|
||||
{
|
||||
wxLogError( _( "For Altium import, we assumes a null byte at the end of a list of "
|
||||
|
@ -120,6 +124,7 @@ std::map<wxString, wxString> ALTIUM_PARSER::ReadProperties()
|
|||
m_pos += length;
|
||||
|
||||
std::size_t token_end = 0;
|
||||
|
||||
while( token_end < str.size() && token_end != std::string::npos )
|
||||
{
|
||||
std::size_t token_start = str.find( '|', token_end );
|
||||
|
@ -146,11 +151,14 @@ std::map<wxString, wxString> ALTIUM_PARSER::ReadProperties()
|
|||
wxString canonicalKey = key.Trim( false ).Trim( true ).MakeUpper();
|
||||
// If the key starts with '%UTF8%' we have to parse the value using UTF8
|
||||
wxString value;
|
||||
|
||||
if( canonicalKey.StartsWith( "%UTF8%" ) )
|
||||
value = wxString( valueS.c_str(), wxConvUTF8 );
|
||||
else
|
||||
value = wxString( valueS.c_str(), wxConvISO8859_1 );
|
||||
|
||||
value = AltiumPropertyToKiCadString( value.Trim() );
|
||||
|
||||
kv.insert( { canonicalKey, value.Trim() } );
|
||||
}
|
||||
|
||||
|
@ -164,8 +172,9 @@ int32_t ALTIUM_PARSER::ConvertToKicadUnit( const double aValue )
|
|||
|
||||
int32_t iu = KiROUND( Clamp<double>( -int_limit, aValue, int_limit ) * 2.54 );
|
||||
|
||||
// Altium stores metric units up to 0.001mm (1000nm) in accuracy. This code fixes rounding errors.
|
||||
// Because imperial units > 0.01mil are always even, this workaround should never trigger for them.
|
||||
// Altium stores metric units up to 0.001mm (1000nm) in accuracy. This code fixes rounding
|
||||
// errors. Because imperial units > 0.01mil are always even, this workaround should never
|
||||
// trigger for them.
|
||||
switch( iu % 1000 )
|
||||
{
|
||||
case 1:
|
||||
|
@ -180,16 +189,16 @@ int32_t ALTIUM_PARSER::ConvertToKicadUnit( const double aValue )
|
|||
}
|
||||
|
||||
|
||||
int ALTIUM_PARSER::PropertiesReadInt(
|
||||
const std::map<wxString, wxString>& aProperties, const wxString& aKey, int aDefault )
|
||||
int ALTIUM_PARSER::PropertiesReadInt( const std::map<wxString, wxString>& aProperties,
|
||||
const wxString& aKey, int aDefault )
|
||||
{
|
||||
const std::map<wxString, wxString>::const_iterator& value = aProperties.find( aKey );
|
||||
return value == aProperties.end() ? aDefault : wxAtoi( value->second );
|
||||
}
|
||||
|
||||
|
||||
double ALTIUM_PARSER::PropertiesReadDouble(
|
||||
const std::map<wxString, wxString>& aProperties, const wxString& aKey, double aDefault )
|
||||
double ALTIUM_PARSER::PropertiesReadDouble( const std::map<wxString, wxString>& aProperties,
|
||||
const wxString& aKey, double aDefault )
|
||||
{
|
||||
const std::map<wxString, wxString>::const_iterator& value = aProperties.find( aKey );
|
||||
if( value == aProperties.end() )
|
||||
|
@ -206,8 +215,9 @@ double ALTIUM_PARSER::PropertiesReadDouble(
|
|||
return doubleValue;
|
||||
}
|
||||
|
||||
bool ALTIUM_PARSER::PropertiesReadBool(
|
||||
const std::map<wxString, wxString>& aProperties, const wxString& aKey, bool aDefault )
|
||||
|
||||
bool ALTIUM_PARSER::PropertiesReadBool( const std::map<wxString, wxString>& aProperties,
|
||||
const wxString& aKey, bool aDefault )
|
||||
{
|
||||
const std::map<wxString, wxString>::const_iterator& value = aProperties.find( aKey );
|
||||
if( value == aProperties.end() )
|
||||
|
@ -216,8 +226,9 @@ bool ALTIUM_PARSER::PropertiesReadBool(
|
|||
return value->second == "T" || value->second == "TRUE";
|
||||
}
|
||||
|
||||
|
||||
int32_t ALTIUM_PARSER::PropertiesReadKicadUnit( const std::map<wxString, wxString>& aProperties,
|
||||
const wxString& aKey, const wxString& aDefault )
|
||||
const wxString& aKey, const wxString& aDefault )
|
||||
{
|
||||
const wxString& value = PropertiesReadString( aProperties, aKey, aDefault );
|
||||
|
||||
|
@ -240,14 +251,19 @@ int32_t ALTIUM_PARSER::PropertiesReadKicadUnit( const std::map<wxString, wxStrin
|
|||
return ConvertToKicadUnit( mils * 10000 );
|
||||
}
|
||||
|
||||
|
||||
wxString ALTIUM_PARSER::PropertiesReadString( const std::map<wxString, wxString>& aProperties,
|
||||
const wxString& aKey, const wxString& aDefault )
|
||||
const wxString& aKey, const wxString& aDefault )
|
||||
{
|
||||
const std::map<wxString, wxString>::const_iterator& utf8Value =
|
||||
aProperties.find( wxString( "%UTF8%" ) + aKey );
|
||||
const auto& utf8Value = aProperties.find( wxString( "%UTF8%" ) + aKey );
|
||||
|
||||
if( utf8Value != aProperties.end() )
|
||||
return utf8Value->second;
|
||||
|
||||
const std::map<wxString, wxString>::const_iterator& value = aProperties.find( aKey );
|
||||
return value == aProperties.end() ? aDefault : value->second;
|
||||
const auto& value = aProperties.find( aKey );
|
||||
|
||||
if( value != aProperties.end() )
|
||||
return value->second;
|
||||
|
||||
return aDefault;
|
||||
}
|
||||
|
|
|
@ -30,8 +30,7 @@
|
|||
|
||||
LIB_ID AltiumToKiCadLibID( wxString aLibName, wxString aLibReference )
|
||||
{
|
||||
ReplaceIllegalFileNameChars( aLibName, '_' );
|
||||
ReplaceIllegalFileNameChars( aLibReference, '_' );
|
||||
aLibReference = EscapeString( aLibReference, CTX_LIBID );
|
||||
|
||||
wxString key = !aLibName.empty() ? ( aLibName + ":" + aLibReference ) : aLibReference;
|
||||
|
||||
|
@ -41,6 +40,43 @@ LIB_ID AltiumToKiCadLibID( wxString aLibName, wxString aLibReference )
|
|||
return libId;
|
||||
}
|
||||
|
||||
|
||||
wxString AltiumPropertyToKiCadString( const wxString& aString )
|
||||
{
|
||||
wxString converted;
|
||||
bool inOverbar = false;
|
||||
|
||||
for( wxString::const_iterator chIt = aString.begin(); chIt != aString.end(); ++chIt )
|
||||
{
|
||||
wxString::const_iterator lookahead = chIt + 1;
|
||||
|
||||
if( lookahead != aString.end() && *lookahead == '\\' )
|
||||
{
|
||||
if( !inOverbar )
|
||||
{
|
||||
converted += "~{";
|
||||
inOverbar = true;
|
||||
}
|
||||
|
||||
converted += *chIt;
|
||||
chIt = lookahead;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( inOverbar )
|
||||
{
|
||||
converted += "}";
|
||||
inOverbar = false;
|
||||
}
|
||||
|
||||
converted += *chIt;
|
||||
}
|
||||
}
|
||||
|
||||
return converted;
|
||||
}
|
||||
|
||||
|
||||
// https://www.altium.com/documentation/altium-designer/sch-obj-textstringtext-string-ad#!special-strings
|
||||
wxString AltiumSpecialStringsToKiCadVariables( const wxString& aString,
|
||||
const altium_override_map_t& aOverride )
|
||||
|
@ -64,6 +100,7 @@ wxString AltiumSpecialStringsToKiCadVariables( const wxString& aStr
|
|||
{
|
||||
size_t text_start = escaping_start + 1;
|
||||
size_t escaping_end = aString.find( "'", text_start );
|
||||
|
||||
if( escaping_end == wxString::npos )
|
||||
{
|
||||
escaping_end = aString.size();
|
||||
|
@ -80,6 +117,7 @@ wxString AltiumSpecialStringsToKiCadVariables( const wxString& aStr
|
|||
if( !specialString.IsEmpty() )
|
||||
{
|
||||
auto variableOverride = aOverride.find( specialString );
|
||||
|
||||
if( variableOverride == aOverride.end() )
|
||||
{
|
||||
result += wxString::Format( wxT( "${%s}" ), specialString );
|
||||
|
|
|
@ -45,6 +45,8 @@ typedef std::map<wxString, wxString, CASE_INSENSITIVE_COMPARATOR> altium_overrid
|
|||
|
||||
LIB_ID AltiumToKiCadLibID( wxString aLibName, wxString aLibReference );
|
||||
|
||||
wxString AltiumPropertyToKiCadString( const wxString& aString );
|
||||
|
||||
wxString AltiumSpecialStringsToKiCadVariables( const wxString& aString,
|
||||
const altium_override_map_t& aOverride );
|
||||
|
||||
|
|
|
@ -2257,12 +2257,11 @@ void SCH_ALTIUM_PLUGIN::ParseParameter( const std::map<wxString, wxString>& aPro
|
|||
|
||||
switch( elem.orientation )
|
||||
{
|
||||
case ASCH_RECORD_ORIENTATION::RIGHTWARDS: field->SetTextAngle( 0 ); break;
|
||||
case ASCH_RECORD_ORIENTATION::UPWARDS: field->SetTextAngle( 90 ); break;
|
||||
case ASCH_RECORD_ORIENTATION::LEFTWARDS: field->SetTextAngle( 180 ); break;
|
||||
case ASCH_RECORD_ORIENTATION::DOWNWARDS: field->SetTextAngle( 270 ); break;
|
||||
default:
|
||||
break;
|
||||
case ASCH_RECORD_ORIENTATION::RIGHTWARDS: field->SetTextAngle( 0 ); break;
|
||||
case ASCH_RECORD_ORIENTATION::UPWARDS: field->SetTextAngle( 90 ); break;
|
||||
case ASCH_RECORD_ORIENTATION::LEFTWARDS: field->SetTextAngle( 180 ); break;
|
||||
case ASCH_RECORD_ORIENTATION::DOWNWARDS: field->SetTextAngle( 270 ); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue