Improvements to Altium PCB/footprint importer:
- Support unicode footprint names
- Set default footprint text size and thickness to match KLC
- Position Reference at the top, Value at the bottom of fp bounding box
(cherry picked from commit 24452f41ad
)
This commit is contained in:
parent
acc03e91f3
commit
4918ac6307
|
@ -2,6 +2,7 @@
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2019-2020 Thomas Pointhuber <thomas.pointhuber@gmx.at>
|
* Copyright (C) 2019-2020 Thomas Pointhuber <thomas.pointhuber@gmx.at>
|
||||||
|
* Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -88,26 +89,106 @@ ALTIUM_COMPOUND_FILE::ALTIUM_COMPOUND_FILE( const wxString& aFilePath )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static const CFB::COMPOUND_FILE_ENTRY*
|
std::map<wxString, wxString> ALTIUM_COMPOUND_FILE::ListLibFootprints() const
|
||||||
FindStreamSingleLevel( const CFB::CompoundFileReader& aReader,
|
|
||||||
const CFB::COMPOUND_FILE_ENTRY* aEntry, const std::string aName,
|
|
||||||
const bool aIsStream )
|
|
||||||
{
|
{
|
||||||
|
std::map<wxString, wxString> patternMap;
|
||||||
|
|
||||||
|
if( !m_reader )
|
||||||
|
return patternMap;
|
||||||
|
|
||||||
|
const CFB::COMPOUND_FILE_ENTRY* root = m_reader->GetRootEntry();
|
||||||
|
|
||||||
|
if( !root )
|
||||||
|
return patternMap;
|
||||||
|
|
||||||
|
m_reader->EnumFiles( root, 2,
|
||||||
|
[&]( const CFB::COMPOUND_FILE_ENTRY* entry, const CFB::utf16string& dir,
|
||||||
|
int level ) -> void
|
||||||
|
{
|
||||||
|
std::wstring dirName = UTF16ToWstring( dir.data(), dir.size() );
|
||||||
|
std::wstring fileName = UTF16ToWstring( entry->name, entry->nameLen );
|
||||||
|
|
||||||
|
if( m_reader->IsStream( entry ) && fileName == L"Parameters" )
|
||||||
|
{
|
||||||
|
ALTIUM_PARSER parametersReader( *this, entry );
|
||||||
|
std::map<wxString, wxString> parameterProperties =
|
||||||
|
parametersReader.ReadProperties();
|
||||||
|
|
||||||
|
wxString key = ALTIUM_PARSER::ReadString(
|
||||||
|
parameterProperties, wxT( "PATTERN" ), wxT( "" ) );
|
||||||
|
|
||||||
|
wxString fpName = ALTIUM_PARSER::ReadUnicodeString(
|
||||||
|
parameterProperties, wxT( "PATTERN" ), wxT( "" ) );
|
||||||
|
|
||||||
|
patternMap.emplace( key, fpName );
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
|
||||||
|
return patternMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
wxString ALTIUM_COMPOUND_FILE::FindLibFootprintDirName( const wxString& aFpUnicodeName ) const
|
||||||
|
{
|
||||||
|
if( !m_reader )
|
||||||
|
return wxEmptyString;
|
||||||
|
|
||||||
|
const CFB::COMPOUND_FILE_ENTRY* root = m_reader->GetRootEntry();
|
||||||
|
|
||||||
|
if( !root )
|
||||||
|
return wxEmptyString;
|
||||||
|
|
||||||
|
wxString ret;
|
||||||
|
|
||||||
|
m_reader->EnumFiles( root, 2,
|
||||||
|
[&]( const CFB::COMPOUND_FILE_ENTRY* entry, const CFB::utf16string& dir,
|
||||||
|
int level ) -> void
|
||||||
|
{
|
||||||
|
std::wstring dirName = UTF16ToWstring( dir.data(), dir.size() );
|
||||||
|
std::wstring fileName = UTF16ToWstring( entry->name, entry->nameLen );
|
||||||
|
|
||||||
|
if( m_reader->IsStream( entry ) && fileName == L"Parameters" )
|
||||||
|
{
|
||||||
|
ALTIUM_PARSER parametersReader( *this, entry );
|
||||||
|
std::map<wxString, wxString> parameterProperties =
|
||||||
|
parametersReader.ReadProperties();
|
||||||
|
|
||||||
|
wxString fpName = ALTIUM_PARSER::ReadUnicodeString(
|
||||||
|
parameterProperties, wxT( "PATTERN" ), wxT( "" ) );
|
||||||
|
|
||||||
|
if( fpName == aFpUnicodeName )
|
||||||
|
{
|
||||||
|
ret = dirName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const CFB::COMPOUND_FILE_ENTRY*
|
||||||
|
ALTIUM_COMPOUND_FILE::FindStreamSingleLevel( const CFB::COMPOUND_FILE_ENTRY* aEntry,
|
||||||
|
const std::string aName, const bool aIsStream ) const
|
||||||
|
{
|
||||||
|
if( !m_reader || !aEntry )
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
const CFB::COMPOUND_FILE_ENTRY* ret = nullptr;
|
const CFB::COMPOUND_FILE_ENTRY* ret = nullptr;
|
||||||
|
|
||||||
aReader.EnumFiles( aEntry, 1,
|
m_reader->EnumFiles( aEntry, 1,
|
||||||
[&]( const CFB::COMPOUND_FILE_ENTRY* entry, const CFB::utf16string& dir,
|
[&]( const CFB::COMPOUND_FILE_ENTRY* entry, const CFB::utf16string& dir,
|
||||||
int level ) -> void
|
int level ) -> void
|
||||||
{
|
{
|
||||||
if( aReader.IsStream( entry ) == aIsStream )
|
if( m_reader->IsStream( entry ) == aIsStream )
|
||||||
{
|
{
|
||||||
std::string name = UTF16ToUTF8( entry->name );
|
std::string name = UTF16ToUTF8( entry->name );
|
||||||
if( name == aName.c_str() )
|
if( name == aName.c_str() )
|
||||||
{
|
{
|
||||||
ret = entry;
|
ret = entry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,9 +197,7 @@ const CFB::COMPOUND_FILE_ENTRY*
|
||||||
ALTIUM_COMPOUND_FILE::FindStream( const std::vector<std::string>& aStreamPath ) const
|
ALTIUM_COMPOUND_FILE::FindStream( const std::vector<std::string>& aStreamPath ) const
|
||||||
{
|
{
|
||||||
if( !m_reader )
|
if( !m_reader )
|
||||||
{
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
|
||||||
|
|
||||||
const CFB::COMPOUND_FILE_ENTRY* currentDirEntry = m_reader->GetRootEntry();
|
const CFB::COMPOUND_FILE_ENTRY* currentDirEntry = m_reader->GetRootEntry();
|
||||||
|
|
||||||
|
@ -129,12 +208,11 @@ ALTIUM_COMPOUND_FILE::FindStream( const std::vector<std::string>& aStreamPath )
|
||||||
|
|
||||||
if( ++it == aStreamPath.cend() )
|
if( ++it == aStreamPath.cend() )
|
||||||
{
|
{
|
||||||
return FindStreamSingleLevel( *m_reader.get(), currentDirEntry, name, true );
|
return FindStreamSingleLevel( currentDirEntry, name, true );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
currentDirEntry =
|
currentDirEntry = FindStreamSingleLevel( currentDirEntry, name, false );
|
||||||
FindStreamSingleLevel( *m_reader.get(), currentDirEntry, name, false );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,9 +310,12 @@ std::map<wxString, wxString> ALTIUM_PARSER::ReadProperties()
|
||||||
else
|
else
|
||||||
value = wxString( valueS.c_str(), wxConvISO8859_1 );
|
value = wxString( valueS.c_str(), wxConvISO8859_1 );
|
||||||
|
|
||||||
// Breathless hack because I haven't a clue what the story is here (but this character
|
if( canonicalKey != wxS( "PATTERN" ) && canonicalKey != wxS( "SOURCEFOOTPRINTLIBRARY" ) )
|
||||||
// appears in a lot of radial dimensions and is rendered by Altium as a space).
|
{
|
||||||
value.Replace( wxT( "ÿ" ), wxT( " " ) );
|
// Breathless hack because I haven't a clue what the story is here (but this character
|
||||||
|
// appears in a lot of radial dimensions and is rendered by Altium as a space).
|
||||||
|
value.Replace( wxT( "ÿ" ), wxT( " " ) );
|
||||||
|
}
|
||||||
|
|
||||||
if( canonicalKey == wxT( "DESIGNATOR" )
|
if( canonicalKey == wxT( "DESIGNATOR" )
|
||||||
|| canonicalKey == wxT( "NAME" )
|
|| canonicalKey == wxT( "NAME" )
|
||||||
|
@ -341,3 +422,28 @@ wxString ALTIUM_PARSER::ReadString( const std::map<wxString, wxString>& aProps,
|
||||||
|
|
||||||
return aDefault;
|
return aDefault;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
wxString ALTIUM_PARSER::ReadUnicodeString( const std::map<wxString, wxString>& aProps,
|
||||||
|
const wxString& aKey, const wxString& aDefault )
|
||||||
|
{
|
||||||
|
const auto& unicodeFlag = aProps.find( wxS( "UNICODE" ) );
|
||||||
|
|
||||||
|
if( unicodeFlag != aProps.end() && unicodeFlag->second.Contains( wxS( "EXISTS" ) ) )
|
||||||
|
{
|
||||||
|
const auto& unicodeValue = aProps.find( wxString( "UNICODE__" ) + aKey );
|
||||||
|
|
||||||
|
if( unicodeValue != aProps.end() )
|
||||||
|
{
|
||||||
|
wxArrayString arr = wxSplit( unicodeValue->second, ',', '\0' );
|
||||||
|
wxString out;
|
||||||
|
|
||||||
|
for( wxString part : arr )
|
||||||
|
out += wxString( wchar_t( wxAtoi( part ) ) );
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ReadString( aProps, aKey, aDefault );
|
||||||
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2019-2020 Thomas Pointhuber <thomas.pointhuber@gmx.at>
|
* Copyright (C) 2019-2020 Thomas Pointhuber <thomas.pointhuber@gmx.at>
|
||||||
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
|
* Copyright (C) 2020-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -63,8 +63,16 @@ public:
|
||||||
|
|
||||||
const CFB::CompoundFileReader& GetCompoundFileReader() const { return *m_reader; }
|
const CFB::CompoundFileReader& GetCompoundFileReader() const { return *m_reader; }
|
||||||
|
|
||||||
|
std::map<wxString, wxString> ListLibFootprints() const;
|
||||||
|
|
||||||
|
wxString FindLibFootprintDirName( const wxString& aFpUnicodeName ) const;
|
||||||
|
|
||||||
const CFB::COMPOUND_FILE_ENTRY* FindStream( const std::vector<std::string>& aStreamPath ) const;
|
const CFB::COMPOUND_FILE_ENTRY* FindStream( const std::vector<std::string>& aStreamPath ) const;
|
||||||
|
|
||||||
|
const CFB::COMPOUND_FILE_ENTRY* FindStreamSingleLevel( const CFB::COMPOUND_FILE_ENTRY* aEntry,
|
||||||
|
const std::string aName,
|
||||||
|
const bool aIsStream ) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<CFB::CompoundFileReader> m_reader;
|
std::unique_ptr<CFB::CompoundFileReader> m_reader;
|
||||||
std::vector<char> m_buffer;
|
std::vector<char> m_buffer;
|
||||||
|
@ -107,24 +115,31 @@ public:
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString ReadWxString()
|
wxScopedCharBuffer ReadCharBuffer()
|
||||||
{
|
{
|
||||||
uint8_t len = Read<uint8_t>();
|
uint8_t len = Read<uint8_t>();
|
||||||
if( GetRemainingBytes() >= len )
|
if( GetRemainingBytes() >= len )
|
||||||
{
|
{
|
||||||
// TODO: Identify where the actual code page is stored. For now, this default code page
|
char* buf = new char[len];
|
||||||
// has limited impact, because recent Altium files come with a UTF16 string table
|
memcpy( buf, m_pos, len );
|
||||||
wxString val = wxString( m_pos, wxConvISO8859_1, len );
|
|
||||||
m_pos += len;
|
m_pos += len;
|
||||||
return val;
|
|
||||||
|
return wxScopedCharBuffer::CreateOwned( buf, len );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_error = true;
|
m_error = true;
|
||||||
return wxString( "" );
|
return wxScopedCharBuffer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxString ReadWxString()
|
||||||
|
{
|
||||||
|
// TODO: Identify where the actual code page is stored. For now, this default code page
|
||||||
|
// has limited impact, because recent Altium files come with a UTF16 string table
|
||||||
|
return wxString( ReadCharBuffer(), wxConvISO8859_1 );
|
||||||
|
}
|
||||||
|
|
||||||
std::map<uint32_t, wxString> ReadWideStringTable()
|
std::map<uint32_t, wxString> ReadWideStringTable()
|
||||||
{
|
{
|
||||||
std::map<uint32_t, wxString> table;
|
std::map<uint32_t, wxString> table;
|
||||||
|
@ -225,6 +240,9 @@ public:
|
||||||
static wxString ReadString( const std::map<wxString, wxString>& aProps,
|
static wxString ReadString( const std::map<wxString, wxString>& aProps,
|
||||||
const wxString& aKey, const wxString& aDefault );
|
const wxString& aKey, const wxString& aDefault );
|
||||||
|
|
||||||
|
static wxString ReadUnicodeString( const std::map<wxString, wxString>& aProps,
|
||||||
|
const wxString& aKey, const wxString& aDefault );
|
||||||
|
|
||||||
void Skip( size_t aLength )
|
void Skip( size_t aLength )
|
||||||
{
|
{
|
||||||
if( GetRemainingBytes() >= aLength )
|
if( GetRemainingBytes() >= aLength )
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2019 Thomas Pointhuber <thomas.pointhuber@gmx.at>
|
* Copyright (C) 2019 Thomas Pointhuber <thomas.pointhuber@gmx.at>
|
||||||
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
|
* Copyright (C) 2020-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -144,6 +144,9 @@ void ALTIUM_DESIGNER_PLUGIN::FootprintEnumerate( wxArrayString& aFootprintNames
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
// Map code-page-dependent names to unicode names
|
||||||
|
std::map<wxString, wxString> patternMap = altiumLibFile.ListLibFootprints();
|
||||||
|
|
||||||
const std::vector<std::string> streamName = { "Library", "Data" };
|
const std::vector<std::string> streamName = { "Library", "Data" };
|
||||||
const CFB::COMPOUND_FILE_ENTRY* libraryData = altiumLibFile.FindStream( streamName );
|
const CFB::COMPOUND_FILE_ENTRY* libraryData = altiumLibFile.FindStream( streamName );
|
||||||
if( libraryData == nullptr )
|
if( libraryData == nullptr )
|
||||||
|
@ -161,8 +164,20 @@ void ALTIUM_DESIGNER_PLUGIN::FootprintEnumerate( wxArrayString& aFootprintNames
|
||||||
for( size_t i = 0; i < numberOfFootprints; i++ )
|
for( size_t i = 0; i < numberOfFootprints; i++ )
|
||||||
{
|
{
|
||||||
parser.ReadAndSetSubrecordLength();
|
parser.ReadAndSetSubrecordLength();
|
||||||
wxString footprintName = parser.ReadWxString();
|
|
||||||
aFootprintNames.Add( footprintName );
|
wxScopedCharBuffer charBuffer = parser.ReadCharBuffer();
|
||||||
|
wxString fpPattern( charBuffer, wxConvISO8859_1 );
|
||||||
|
|
||||||
|
auto it = patternMap.find( fpPattern );
|
||||||
|
if( it != patternMap.end() )
|
||||||
|
{
|
||||||
|
aFootprintNames.Add( it->second ); // Proper unicode name
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
THROW_IO_ERROR( wxString::Format( "Component name not found: '%s'", fpPattern ) );
|
||||||
|
}
|
||||||
|
|
||||||
parser.SkipSubrecord();
|
parser.SkipSubrecord();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -331,8 +331,10 @@ ACOMPONENT6::ACOMPONENT6( ALTIUM_PARSER& aReader )
|
||||||
nameon = ALTIUM_PARSER::ReadBool( props, wxT( "NAMEON" ), true );
|
nameon = ALTIUM_PARSER::ReadBool( props, wxT( "NAMEON" ), true );
|
||||||
commenton = ALTIUM_PARSER::ReadBool( props, wxT( "COMMENTON" ), false );
|
commenton = ALTIUM_PARSER::ReadBool( props, wxT( "COMMENTON" ), false );
|
||||||
sourcedesignator = ALTIUM_PARSER::ReadString( props, wxT( "SOURCEDESIGNATOR" ), wxT( "" ) );
|
sourcedesignator = ALTIUM_PARSER::ReadString( props, wxT( "SOURCEDESIGNATOR" ), wxT( "" ) );
|
||||||
sourcefootprintlibrary = ALTIUM_PARSER::ReadString( props, wxT( "SOURCEFOOTPRINTLIBRARY" ), wxT( "" ) );
|
|
||||||
pattern = ALTIUM_PARSER::ReadString( props, wxT( "PATTERN" ), wxT( "" ) );
|
sourcefootprintlibrary =
|
||||||
|
ALTIUM_PARSER::ReadUnicodeString( props, wxT( "SOURCEFOOTPRINTLIBRARY" ), wxT( "" ) );
|
||||||
|
pattern = ALTIUM_PARSER::ReadUnicodeString( props, wxT( "PATTERN" ), wxT( "" ) );
|
||||||
|
|
||||||
sourcecomponentlibrary = ALTIUM_PARSER::ReadString( props, wxT( "SOURCECOMPONENTLIBRARY" ), wxT( "" ) );
|
sourcecomponentlibrary = ALTIUM_PARSER::ReadString( props, wxT( "SOURCECOMPONENTLIBRARY" ), wxT( "" ) );
|
||||||
sourcelibreference = ALTIUM_PARSER::ReadString( props, wxT( "SOURCELIBREFERENCE" ), wxT( "" ) );
|
sourcelibreference = ALTIUM_PARSER::ReadString( props, wxT( "SOURCELIBREFERENCE" ), wxT( "" ) );
|
||||||
|
|
|
@ -666,6 +666,7 @@ FOOTPRINT* ALTIUM_PCB::ParseFootprint( const ALTIUM_COMPOUND_FILE& altiumLibFile
|
||||||
|
|
||||||
m_unicodeStrings.clear();
|
m_unicodeStrings.clear();
|
||||||
m_extendedPrimitiveInformationMaps.clear();
|
m_extendedPrimitiveInformationMaps.clear();
|
||||||
|
|
||||||
// TODO: WideStrings are stored as parameterMap in the case of footprints, not as binary
|
// TODO: WideStrings are stored as parameterMap in the case of footprints, not as binary
|
||||||
// std::string unicodeStringsStreamName = aFootprintName.ToStdString() + "\\WideStrings";
|
// std::string unicodeStringsStreamName = aFootprintName.ToStdString() + "\\WideStrings";
|
||||||
// const CFB::COMPOUND_FILE_ENTRY* unicodeStringsData = altiumLibFile.FindStream( unicodeStringsStreamName );
|
// const CFB::COMPOUND_FILE_ENTRY* unicodeStringsData = altiumLibFile.FindStream( unicodeStringsStreamName );
|
||||||
|
@ -674,7 +675,15 @@ FOOTPRINT* ALTIUM_PCB::ParseFootprint( const ALTIUM_COMPOUND_FILE& altiumLibFile
|
||||||
// ParseWideStrings6Data( altiumLibFile, unicodeStringsData );
|
// ParseWideStrings6Data( altiumLibFile, unicodeStringsData );
|
||||||
// }
|
// }
|
||||||
|
|
||||||
const std::vector<std::string> streamName{ aFootprintName.ToStdString(), "Data" };
|
wxString fpDirName = altiumLibFile.FindLibFootprintDirName(aFootprintName);
|
||||||
|
|
||||||
|
if( fpDirName.IsEmpty() )
|
||||||
|
{
|
||||||
|
THROW_IO_ERROR(
|
||||||
|
wxString::Format( _( "Footprint directory not found: '%s'." ), aFootprintName ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<std::string> streamName{ fpDirName.ToStdString(), "Data" };
|
||||||
const CFB::COMPOUND_FILE_ENTRY* footprintData = altiumLibFile.FindStream( streamName );
|
const CFB::COMPOUND_FILE_ENTRY* footprintData = altiumLibFile.FindStream( streamName );
|
||||||
|
|
||||||
if( footprintData == nullptr )
|
if( footprintData == nullptr )
|
||||||
|
@ -686,13 +695,13 @@ FOOTPRINT* ALTIUM_PCB::ParseFootprint( const ALTIUM_COMPOUND_FILE& altiumLibFile
|
||||||
ALTIUM_PARSER parser( altiumLibFile, footprintData );
|
ALTIUM_PARSER parser( altiumLibFile, footprintData );
|
||||||
|
|
||||||
parser.ReadAndSetSubrecordLength();
|
parser.ReadAndSetSubrecordLength();
|
||||||
wxString footprintName = parser.ReadWxString();
|
//wxString footprintName = parser.ReadWxString(); // Not used (single-byte char set)
|
||||||
parser.SkipSubrecord();
|
parser.SkipSubrecord();
|
||||||
|
|
||||||
LIB_ID fpID = AltiumToKiCadLibID( "", footprintName ); // TODO: library name
|
LIB_ID fpID = AltiumToKiCadLibID( "", aFootprintName ); // TODO: library name
|
||||||
footprint->SetFPID( fpID );
|
footprint->SetFPID( fpID );
|
||||||
|
|
||||||
const std::vector<std::string> parametersStreamName{ aFootprintName.ToStdString(),
|
const std::vector<std::string> parametersStreamName{ fpDirName.ToStdString(),
|
||||||
"Parameters" };
|
"Parameters" };
|
||||||
const CFB::COMPOUND_FILE_ENTRY* parametersData =
|
const CFB::COMPOUND_FILE_ENTRY* parametersData =
|
||||||
altiumLibFile.FindStream( parametersStreamName );
|
altiumLibFile.FindStream( parametersStreamName );
|
||||||
|
@ -713,7 +722,7 @@ FOOTPRINT* ALTIUM_PCB::ParseFootprint( const ALTIUM_COMPOUND_FILE& altiumLibFile
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<std::string> extendedPrimitiveInformationStreamName{
|
const std::vector<std::string> extendedPrimitiveInformationStreamName{
|
||||||
aFootprintName.ToStdString(), "ExtendedPrimitiveInformation", "Data"
|
fpDirName.ToStdString(), "ExtendedPrimitiveInformation", "Data"
|
||||||
};
|
};
|
||||||
const CFB::COMPOUND_FILE_ENTRY* extendedPrimitiveInformationData =
|
const CFB::COMPOUND_FILE_ENTRY* extendedPrimitiveInformationData =
|
||||||
altiumLibFile.FindStream( extendedPrimitiveInformationStreamName );
|
altiumLibFile.FindStream( extendedPrimitiveInformationStreamName );
|
||||||
|
@ -722,10 +731,19 @@ FOOTPRINT* ALTIUM_PCB::ParseFootprint( const ALTIUM_COMPOUND_FILE& altiumLibFile
|
||||||
ParseExtendedPrimitiveInformationData( altiumLibFile, extendedPrimitiveInformationData );
|
ParseExtendedPrimitiveInformationData( altiumLibFile, extendedPrimitiveInformationData );
|
||||||
|
|
||||||
footprint->SetReference( wxT( "REF**" ) );
|
footprint->SetReference( wxT( "REF**" ) );
|
||||||
footprint->SetValue( footprintName );
|
footprint->SetValue( aFootprintName );
|
||||||
footprint->Reference().SetVisible( true ); // TODO: extract visibility information
|
footprint->Reference().SetVisible( true ); // TODO: extract visibility information
|
||||||
footprint->Value().SetVisible( true );
|
footprint->Value().SetVisible( true );
|
||||||
|
|
||||||
|
const VECTOR2I defaultTextSize( pcbIUScale.mmToIU( 1.0 ), pcbIUScale.mmToIU( 1.0 ) );
|
||||||
|
const int defaultTextThickness( pcbIUScale.mmToIU( 0.15 ) );
|
||||||
|
|
||||||
|
footprint->Reference().SetTextSize( defaultTextSize );
|
||||||
|
footprint->Reference().SetTextThickness( defaultTextThickness );
|
||||||
|
|
||||||
|
footprint->Value().SetTextSize( defaultTextSize );
|
||||||
|
footprint->Value().SetTextThickness( defaultTextThickness );
|
||||||
|
|
||||||
for( int primitiveIndex = 0; parser.GetRemainingBytes() >= 4; primitiveIndex++ )
|
for( int primitiveIndex = 0; parser.GetRemainingBytes() >= 4; primitiveIndex++ )
|
||||||
{
|
{
|
||||||
ALTIUM_RECORD recordtype = static_cast<ALTIUM_RECORD>( parser.Peek<uint8_t>() );
|
ALTIUM_RECORD recordtype = static_cast<ALTIUM_RECORD>( parser.Peek<uint8_t>() );
|
||||||
|
@ -785,6 +803,22 @@ FOOTPRINT* ALTIUM_PCB::ParseFootprint( const ALTIUM_COMPOUND_FILE& altiumLibFile
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Auto-position reference and value
|
||||||
|
BOX2I bbox = footprint.get()->GetBoundingBox( false, false );
|
||||||
|
bbox.Inflate( pcbIUScale.mmToIU( 0.2 ) ); // Gap between graphics and text
|
||||||
|
|
||||||
|
if( footprint->Reference().GetPosition() == VECTOR2I( 0, 0 ) )
|
||||||
|
{
|
||||||
|
footprint->Reference().SetX( bbox.GetCenter().x );
|
||||||
|
footprint->Reference().SetY( bbox.GetTop() - footprint->Reference().GetTextSize().y / 2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( footprint->Value().GetPosition() == VECTOR2I( 0, 0 ) )
|
||||||
|
{
|
||||||
|
footprint->Value().SetX( bbox.GetCenter().x );
|
||||||
|
footprint->Value().SetY( bbox.GetBottom() + footprint->Value().GetTextSize().y / 2 );
|
||||||
|
}
|
||||||
|
|
||||||
if( parser.HasParsingError() )
|
if( parser.HasParsingError() )
|
||||||
{
|
{
|
||||||
THROW_IO_ERROR( wxString::Format( wxT( "%s stream was not parsed correctly" ),
|
THROW_IO_ERROR( wxString::Format( wxT( "%s stream was not parsed correctly" ),
|
||||||
|
@ -2158,7 +2192,7 @@ void ALTIUM_PCB::ConvertShapeBasedRegions6ToFootprintItemOnLayer( FOOTPRINT*
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PCB_SHAPE* shape = new PCB_SHAPE( aFootprint, SHAPE_T::POLY );
|
FP_SHAPE* shape = new FP_SHAPE( aFootprint, SHAPE_T::POLY );
|
||||||
|
|
||||||
shape->SetPolyShape( polySet );
|
shape->SetPolyShape( polySet );
|
||||||
shape->SetFilled( true );
|
shape->SetFilled( true );
|
||||||
|
|
Loading…
Reference in New Issue