More work on Gerber pick and place files
In P&P files, user strings are now quoted, and use UTF8 encoding
This commit is contained in:
parent
4178cf7f36
commit
4a0bd46ed6
|
@ -30,6 +30,7 @@
|
||||||
|
|
||||||
#include <fctsys.h>
|
#include <fctsys.h>
|
||||||
#include <gbr_metadata.h>
|
#include <gbr_metadata.h>
|
||||||
|
#include <utf8.h>
|
||||||
|
|
||||||
wxString GbrMakeCreationDateAttributeString( GBR_NC_STRING_FORMAT aFormat )
|
wxString GbrMakeCreationDateAttributeString( GBR_NC_STRING_FORMAT aFormat )
|
||||||
{
|
{
|
||||||
|
@ -314,19 +315,53 @@ std::string GBR_APERTURE_METADATA::FormatAttribute( GBR_APERTURE_ATTRIB aAttribu
|
||||||
return full_attribute_string;
|
return full_attribute_string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Helper function to convert a ascii hex char to its integer value
|
||||||
|
// If the char is not a hexa char, return -1
|
||||||
|
int char2Hex( unsigned aCode )
|
||||||
|
{
|
||||||
|
if( aCode >= '0' && aCode <= '9' )
|
||||||
|
return aCode - '0';
|
||||||
|
|
||||||
|
if( aCode >= 'A' && aCode <= 'F' )
|
||||||
|
return aCode - 'A' + 10;
|
||||||
|
|
||||||
|
if( aCode >= 'a' && aCode <= 'f' )
|
||||||
|
return aCode - 'a' + 10;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
wxString FormatStringFromGerber( const wxString& aString )
|
wxString FormatStringFromGerber( const wxString& aString )
|
||||||
{
|
{
|
||||||
// make the inverse conversion of formatStringToGerber()
|
// make the inverse conversion of FormatStringToGerber()
|
||||||
// It converts a "normalized" gerber string and convert it to a 16 bits sequence unicode
|
// It converts a "normalized" gerber string and convert it to a 16 bits sequence unicode
|
||||||
// and return a wxString (unicode 16) from the gerber string
|
// and return a wxString (unicode 16) from the gerber string
|
||||||
wxString txt;
|
wxString txt; // The string converted from Gerber string
|
||||||
|
wxString uniString; // the unicode string from UTF8 Gerber string but without converted escape sequence
|
||||||
|
|
||||||
for( unsigned ii = 0; ii < aString.Length(); ++ii )
|
unsigned count = aString.Length();
|
||||||
|
|
||||||
|
for( unsigned ii = 0; ii < count; ++ii )
|
||||||
{
|
{
|
||||||
unsigned code = aString[ii];
|
unsigned code = aString[ii];
|
||||||
|
|
||||||
if( code == '\\' )
|
if( code == '\\' )
|
||||||
{
|
{
|
||||||
|
// If next char is not a hexadecimal char, just skip the '\'
|
||||||
|
// It is perhaps a escape sequence like \\ or \" or ...
|
||||||
|
if( ii < count-1 )
|
||||||
|
{
|
||||||
|
code = aString[ii+1];
|
||||||
|
|
||||||
|
if( char2Hex( code ) < 0 )
|
||||||
|
{
|
||||||
|
++ii;
|
||||||
|
txt.Append( aString[ii] );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
// Convert 4 hexadecimal digits to a 16 bit unicode
|
// Convert 4 hexadecimal digits to a 16 bit unicode
|
||||||
// (Gerber allows only 4 hexadecimal digits)
|
// (Gerber allows only 4 hexadecimal digits)
|
||||||
long value = 0;
|
long value = 0;
|
||||||
|
@ -335,8 +370,8 @@ wxString FormatStringFromGerber( const wxString& aString )
|
||||||
{
|
{
|
||||||
value <<= 4;
|
value <<= 4;
|
||||||
code = aString[++ii];
|
code = aString[++ii];
|
||||||
// Very basic conversion, but it expects a valid gerber file
|
// Basic conversion (with no control), but it expects a valid gerber file
|
||||||
int hexa = (code <= '9' ? code - '0' : code - 'A' + 10) & 0xF;
|
int hexa = char2Hex( code );
|
||||||
value += hexa;
|
value += hexa;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -350,19 +385,20 @@ wxString FormatStringFromGerber( const wxString& aString )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string formatStringToGerber( const wxString& aString )
|
wxString ConvertNotAllowedCharsInGerber( const wxString& aString, bool aAllowUtf8Chars, bool aQuoteString )
|
||||||
{
|
{
|
||||||
/* format string means convert any code > 0x7F and unautorized code to a hexadecimal
|
/* format string means convert any code > 0x7E and unautorized codes to a hexadecimal
|
||||||
* 16 bits sequence unicode
|
* 16 bits sequence unicode
|
||||||
* unautorized codes are ',' '*' '%' '\'
|
* unautorized codes are ',' '*' '%' '\' and are used as separators in Gerber files
|
||||||
*/
|
*/
|
||||||
std::string txt;
|
wxString txt;
|
||||||
|
|
||||||
txt.reserve( aString.Length() );
|
if( aQuoteString )
|
||||||
|
txt << "\"";
|
||||||
|
|
||||||
for( unsigned ii = 0; ii < aString.Length(); ++ii )
|
for( unsigned ii = 0; ii < aString.Length(); ++ii )
|
||||||
{
|
{
|
||||||
unsigned code = aString[ii];
|
wxChar code = aString[ii];
|
||||||
bool convert = false;
|
bool convert = false;
|
||||||
|
|
||||||
switch( code )
|
switch( code )
|
||||||
|
@ -378,7 +414,10 @@ std::string formatStringToGerber( const wxString& aString )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( convert || code > 0x7F )
|
if( !aAllowUtf8Chars && code > 0x7F )
|
||||||
|
convert = true;
|
||||||
|
|
||||||
|
if( convert )
|
||||||
{
|
{
|
||||||
txt += '\\';
|
txt += '\\';
|
||||||
|
|
||||||
|
@ -389,9 +428,35 @@ std::string formatStringToGerber( const wxString& aString )
|
||||||
txt += hexa;
|
txt += hexa;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
txt += char( code );
|
txt += code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( aQuoteString )
|
||||||
|
txt << "\"";
|
||||||
|
|
||||||
|
return txt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::string FormatStringToGerber( const wxString& aString )
|
||||||
|
{
|
||||||
|
wxString converted;
|
||||||
|
/* format string means convert any code > 0x7E and unautorized codes to a hexadecimal
|
||||||
|
* 16 bits sequence unicode
|
||||||
|
* unautorized codes are ',' '*' '%' '\'
|
||||||
|
* This conversion is not made for quoted strings, because if the string is
|
||||||
|
* quoted, the conversion is expected to be already made, and the returned string must use
|
||||||
|
* UTF8 encoding
|
||||||
|
*/
|
||||||
|
if( aString[0] != '\"' || aString[aString.Len()-1] != '\"' )
|
||||||
|
converted = ConvertNotAllowedCharsInGerber( aString, false, false );
|
||||||
|
else
|
||||||
|
converted = aString;
|
||||||
|
|
||||||
|
// Convert the char string to std::string. Be carefull when converting awxString to
|
||||||
|
// a std::string: using static_cast<const char*> is mandatory
|
||||||
|
std::string txt = static_cast<const char*>( converted.utf8_str() );
|
||||||
|
|
||||||
return txt;
|
return txt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -437,13 +502,13 @@ bool FormatNetAttribute( std::string& aPrintedText, std::string& aLastNetAttribu
|
||||||
// print info associated to a flashed pad (cmpref, pad name)
|
// print info associated to a flashed pad (cmpref, pad name)
|
||||||
// example: %TO.P,R5,3*%
|
// example: %TO.P,R5,3*%
|
||||||
pad_attribute_string = prepend_string + "TO.P,";
|
pad_attribute_string = prepend_string + "TO.P,";
|
||||||
pad_attribute_string += formatStringToGerber( aData->m_Cmpref ) + ",";
|
pad_attribute_string += FormatStringToGerber( aData->m_Cmpref ) + ",";
|
||||||
|
|
||||||
if( aData->m_Padname.IsEmpty() )
|
if( aData->m_Padname.IsEmpty() )
|
||||||
// Happens for "mechanical" or never connected pads
|
// Happens for "mechanical" or never connected pads
|
||||||
pad_attribute_string += formatStringToGerber( NO_PAD_NAME );
|
pad_attribute_string += FormatStringToGerber( NO_PAD_NAME );
|
||||||
else
|
else
|
||||||
pad_attribute_string += formatStringToGerber( aData->m_Padname );
|
pad_attribute_string += FormatStringToGerber( aData->m_Padname );
|
||||||
|
|
||||||
pad_attribute_string += eol_string;
|
pad_attribute_string += eol_string;
|
||||||
}
|
}
|
||||||
|
@ -466,11 +531,11 @@ bool FormatNetAttribute( std::string& aPrintedText, std::string& aLastNetAttribu
|
||||||
{
|
{
|
||||||
// Happens for not connected pads: use a normalized
|
// Happens for not connected pads: use a normalized
|
||||||
// dummy name
|
// dummy name
|
||||||
net_attribute_string += formatStringToGerber( NO_NET_NAME );
|
net_attribute_string += FormatStringToGerber( NO_NET_NAME );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
net_attribute_string += formatStringToGerber( aData->m_Netname );
|
net_attribute_string += FormatStringToGerber( aData->m_Netname );
|
||||||
|
|
||||||
net_attribute_string += eol_string;
|
net_attribute_string += eol_string;
|
||||||
}
|
}
|
||||||
|
@ -483,7 +548,7 @@ bool FormatNetAttribute( std::string& aPrintedText, std::string& aLastNetAttribu
|
||||||
// Because GBR_NETINFO_PAD option already contains this info, it is not
|
// Because GBR_NETINFO_PAD option already contains this info, it is not
|
||||||
// created here for a GBR_NETINFO_PAD attribute
|
// created here for a GBR_NETINFO_PAD attribute
|
||||||
cmp_attribute_string = prepend_string + "TO.C,";
|
cmp_attribute_string = prepend_string + "TO.C,";
|
||||||
cmp_attribute_string += formatStringToGerber( aData->m_Cmpref ) + eol_string;
|
cmp_attribute_string += FormatStringToGerber( aData->m_Cmpref ) + eol_string;
|
||||||
}
|
}
|
||||||
|
|
||||||
// the full list of requested attributes:
|
// the full list of requested attributes:
|
||||||
|
@ -590,7 +655,7 @@ void GBR_CMP_PNP_METADATA::ClearData()
|
||||||
/**
|
/**
|
||||||
* @return a string containing the formated metadata in X2 syntax.
|
* @return a string containing the formated metadata in X2 syntax.
|
||||||
* one line by non empty data
|
* one line by non empty data
|
||||||
* the orientation is always generated
|
* the orientation (.CRot) and mount type (.CMnt) are always generated
|
||||||
*/
|
*/
|
||||||
wxString GBR_CMP_PNP_METADATA::FormatCmpPnPMetadata()
|
wxString GBR_CMP_PNP_METADATA::FormatCmpPnPMetadata()
|
||||||
{
|
{
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
|
|
||||||
#include <wx/log.h>
|
#include <wx/log.h>
|
||||||
#include <X2_gerber_attributes.h>
|
#include <X2_gerber_attributes.h>
|
||||||
|
#include <macros.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* class X2_ATTRIBUTE
|
* class X2_ATTRIBUTE
|
||||||
|
@ -92,11 +93,11 @@ void X2_ATTRIBUTE::DbgListPrms()
|
||||||
bool X2_ATTRIBUTE::ParseAttribCmd( FILE* aFile, char *aBuffer, int aBuffSize, char* &aText,
|
bool X2_ATTRIBUTE::ParseAttribCmd( FILE* aFile, char *aBuffer, int aBuffSize, char* &aText,
|
||||||
int& aLineNum )
|
int& aLineNum )
|
||||||
{
|
{
|
||||||
// parse a TF command and fill m_Prms by the parameters found.
|
// parse a TF, TA, TO ... command and fill m_Prms by the parameters found.
|
||||||
// the "%TF" (start of command) is already read by the caller
|
// the "%TF" (start of command) is already read by the caller
|
||||||
|
|
||||||
bool ok = true;
|
bool ok = true;
|
||||||
wxString data;
|
std::string data;
|
||||||
|
|
||||||
for( ; ; )
|
for( ; ; )
|
||||||
{
|
{
|
||||||
|
@ -114,19 +115,19 @@ bool X2_ATTRIBUTE::ParseAttribCmd( FILE* aFile, char *aBuffer, int aBuffSize, ch
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '*': // End of block
|
case '*': // End of block
|
||||||
m_Prms.Add( data );
|
m_Prms.Add( FROM_UTF8( data.c_str() ) );
|
||||||
data.Empty();
|
data.clear();
|
||||||
aText++;
|
aText++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ',': // End of parameter (separator)
|
case ',': // End of parameter (separator)
|
||||||
aText++;
|
aText++;
|
||||||
m_Prms.Add( data );
|
m_Prms.Add( FROM_UTF8( data.c_str() ) );
|
||||||
data.Empty();
|
data.clear();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
data.Append( *aText );
|
data += *aText;
|
||||||
aText++;
|
aText++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#include <gerbview.h>
|
#include <gerbview.h>
|
||||||
#include <gerber_file_image.h>
|
#include <gerber_file_image.h>
|
||||||
#include <X2_gerber_attributes.h>
|
#include <X2_gerber_attributes.h>
|
||||||
|
#include <gbr_metadata.h>
|
||||||
|
|
||||||
extern int ReadInt( char*& text, bool aSkipSeparator = true );
|
extern int ReadInt( char*& text, bool aSkipSeparator = true );
|
||||||
extern double ReadDouble( char*& text, bool aSkipSeparator = true );
|
extern double ReadDouble( char*& text, bool aSkipSeparator = true );
|
||||||
|
@ -138,50 +139,6 @@ int GERBER_FILE_IMAGE::ReadXCommandID( char*& text )
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert a string read from a gerber file to an unicode string
|
|
||||||
* Usual chars (ASCII7 values) are the only values allowed in Gerber files,
|
|
||||||
* and are just copied.
|
|
||||||
* However Gerber format allows using non ASCII7 values by coding them in a
|
|
||||||
* sequence of 4 hexadecimal chars (16 bits hexadecimal value)
|
|
||||||
* Hexadecimal coded values ("\hhhh") are converted to
|
|
||||||
* the unicode char value
|
|
||||||
*/
|
|
||||||
static const wxString fromGerberString( const wxString& aGbrString )
|
|
||||||
{
|
|
||||||
wxString text;
|
|
||||||
|
|
||||||
for( unsigned ii = 0; ii < aGbrString.size(); ++ii )
|
|
||||||
{
|
|
||||||
if( aGbrString[ii] == '\\' )
|
|
||||||
{
|
|
||||||
unsigned value = 0;
|
|
||||||
|
|
||||||
for( int jj = 0; jj < 4; jj++ )
|
|
||||||
{ // Convert 4 hexa digits to binary value:
|
|
||||||
ii++;
|
|
||||||
value <<= 4;
|
|
||||||
int digit = aGbrString[ii];
|
|
||||||
|
|
||||||
if( digit >= '0' && digit <= '9' )
|
|
||||||
digit -= '0';
|
|
||||||
else if( digit >= 'A' && digit <= 'F' )
|
|
||||||
digit -= 'A' - 10;
|
|
||||||
else if( digit >= 'a' && digit <= 'f' )
|
|
||||||
digit -= 'a' - 10;
|
|
||||||
else digit = 0;
|
|
||||||
|
|
||||||
value += digit & 0xF;
|
|
||||||
}
|
|
||||||
|
|
||||||
text.Append( wxUniChar( value ) );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
text.Append( aGbrString[ii] );
|
|
||||||
}
|
|
||||||
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GERBER_FILE_IMAGE::ReadRS274XCommand( char *aBuff, unsigned int aBuffSize, char*& aText )
|
bool GERBER_FILE_IMAGE::ReadRS274XCommand( char *aBuff, unsigned int aBuffSize, char*& aText )
|
||||||
{
|
{
|
||||||
|
@ -451,18 +408,18 @@ bool GERBER_FILE_IMAGE::ExecuteRS274XCommand( int aCommand, char* aBuff,
|
||||||
if( dummy.GetAttribute() == ".N" )
|
if( dummy.GetAttribute() == ".N" )
|
||||||
{
|
{
|
||||||
m_NetAttributeDict.m_NetAttribType |= GBR_NETLIST_METADATA::GBR_NETINFO_NET;
|
m_NetAttributeDict.m_NetAttribType |= GBR_NETLIST_METADATA::GBR_NETINFO_NET;
|
||||||
m_NetAttributeDict.m_Netname = fromGerberString( dummy.GetPrm( 1 ) );
|
m_NetAttributeDict.m_Netname = FormatStringFromGerber( dummy.GetPrm( 1 ) );
|
||||||
}
|
}
|
||||||
else if( dummy.GetAttribute() == ".C" )
|
else if( dummy.GetAttribute() == ".C" )
|
||||||
{
|
{
|
||||||
m_NetAttributeDict.m_NetAttribType |= GBR_NETLIST_METADATA::GBR_NETINFO_CMP;
|
m_NetAttributeDict.m_NetAttribType |= GBR_NETLIST_METADATA::GBR_NETINFO_CMP;
|
||||||
m_NetAttributeDict.m_Cmpref = fromGerberString( dummy.GetPrm( 1 ) );
|
m_NetAttributeDict.m_Cmpref = FormatStringFromGerber( dummy.GetPrm( 1 ) );
|
||||||
}
|
}
|
||||||
else if( dummy.GetAttribute() == ".P" )
|
else if( dummy.GetAttribute() == ".P" )
|
||||||
{
|
{
|
||||||
m_NetAttributeDict.m_NetAttribType |= GBR_NETLIST_METADATA::GBR_NETINFO_PAD;
|
m_NetAttributeDict.m_NetAttribType |= GBR_NETLIST_METADATA::GBR_NETINFO_PAD;
|
||||||
m_NetAttributeDict.m_Cmpref = fromGerberString( dummy.GetPrm( 1 ) );
|
m_NetAttributeDict.m_Cmpref = FormatStringFromGerber( dummy.GetPrm( 1 ) );
|
||||||
m_NetAttributeDict.m_Padname = fromGerberString( dummy.GetPrm( 2 ) );
|
m_NetAttributeDict.m_Padname = FormatStringFromGerber( dummy.GetPrm( 2 ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -210,10 +210,24 @@ private:
|
||||||
* @param aString = the wxString to convert
|
* @param aString = the wxString to convert
|
||||||
* @return a std::string (ASCII7 coded) compliant with a gerber string
|
* @return a std::string (ASCII7 coded) compliant with a gerber string
|
||||||
*/
|
*/
|
||||||
std::string formatStringToGerber( const wxString& aString );
|
std::string FormatStringToGerber( const wxString& aString );
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This helper function make the inverse conversion of formatStringToGerber()
|
* Similar to FormatStringToGerber.
|
||||||
|
* "normalize" aString and convert it to a Gerber compatible wxString
|
||||||
|
* Normalisation means unautorized code to a hexadecimal 16 bits sequence unicode
|
||||||
|
* and, on request convert any code > 0x7F.
|
||||||
|
* unautorized codes are ',' '*' '%' '\'
|
||||||
|
* @param aString = the wxString to convert
|
||||||
|
* @param aAllowUtf8Chars = false to convert non ASCII7 values to unicode sequence
|
||||||
|
* @param aQuoteString = true to double quote the returned string
|
||||||
|
* @return a wxString without unautorized chars (and converted non ASCII7 chars on request)
|
||||||
|
*/
|
||||||
|
wxString ConvertNotAllowedCharsInGerber( const wxString& aString, bool aAllowUtf8Chars, bool aQuoteString );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This helper function make the inverse conversion of FormatStringToGerber()
|
||||||
* It converts a "normalized" gerber string and convert it to a 16 bits sequence unicode
|
* It converts a "normalized" gerber string and convert it to a 16 bits sequence unicode
|
||||||
* @param aString = the wxString compliant with a gerber string format
|
* @param aString = the wxString compliant with a gerber string format
|
||||||
* @return a wxString (unicode 16) from the gerber string
|
* @return a wxString (unicode 16) from the gerber string
|
||||||
|
|
|
@ -111,6 +111,7 @@ int PLACEFILE_GERBER_WRITER::CreatePlaceFile( wxString& aFullFilename,
|
||||||
plotter.StartPlot();
|
plotter.StartPlot();
|
||||||
|
|
||||||
int cmp_count = 0;
|
int cmp_count = 0;
|
||||||
|
bool allowUtf8 = true;
|
||||||
|
|
||||||
for( MODULE* footprint : fp_list )
|
for( MODULE* footprint : fp_list )
|
||||||
{
|
{
|
||||||
|
@ -119,7 +120,9 @@ int PLACEFILE_GERBER_WRITER::CreatePlaceFile( wxString& aFullFilename,
|
||||||
gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_CMP_POSITION );
|
gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_CMP_POSITION );
|
||||||
|
|
||||||
// Add object attribute: component reference to flash (mainly usefull for users)
|
// Add object attribute: component reference to flash (mainly usefull for users)
|
||||||
wxString ref = footprint->GetReference();
|
// using quoted UTF8 string
|
||||||
|
wxString ref = ConvertNotAllowedCharsInGerber( footprint->GetReference(),
|
||||||
|
allowUtf8, true );
|
||||||
|
|
||||||
gbr_metadata.SetCmpReference( ref );
|
gbr_metadata.SetCmpReference( ref );
|
||||||
gbr_metadata.SetNetAttribType( GBR_NETLIST_METADATA::GBR_NETINFO_CMP );
|
gbr_metadata.SetNetAttribType( GBR_NETLIST_METADATA::GBR_NETINFO_CMP );
|
||||||
|
@ -143,15 +146,15 @@ int PLACEFILE_GERBER_WRITER::CreatePlaceFile( wxString& aFullFilename,
|
||||||
: GBR_CMP_PNP_METADATA::MOUNT_TYPE_TH;
|
: GBR_CMP_PNP_METADATA::MOUNT_TYPE_TH;
|
||||||
|
|
||||||
// Add component value info:
|
// Add component value info:
|
||||||
pnpAttrib.m_Value = FormatStringFromGerber( footprint->GetValue() );
|
pnpAttrib.m_Value = ConvertNotAllowedCharsInGerber( footprint->GetValue(), allowUtf8, true );
|
||||||
|
|
||||||
// Add component footprint info:
|
// Add component footprint info:
|
||||||
wxString fp_info = FROM_UTF8( footprint->GetFPID().GetLibItemName().c_str() );
|
wxString fp_info = FROM_UTF8( footprint->GetFPID().GetLibItemName().c_str() );
|
||||||
pnpAttrib.m_Footprint = FormatStringFromGerber( fp_info );
|
pnpAttrib.m_Footprint = ConvertNotAllowedCharsInGerber( fp_info, allowUtf8, true );
|
||||||
|
|
||||||
// Add footprint lib name:
|
// Add footprint lib name:
|
||||||
fp_info = FROM_UTF8( footprint->GetFPID().GetLibNickname().c_str() );
|
fp_info = FROM_UTF8( footprint->GetFPID().GetLibNickname().c_str() );
|
||||||
pnpAttrib.m_LibraryName = FormatStringFromGerber( fp_info );
|
pnpAttrib.m_LibraryName = ConvertNotAllowedCharsInGerber( fp_info, allowUtf8, true );
|
||||||
|
|
||||||
gbr_metadata.m_NetlistMetadata.SetExtraData( pnpAttrib.FormatCmpPnPMetadata() );
|
gbr_metadata.m_NetlistMetadata.SetExtraData( pnpAttrib.FormatCmpPnPMetadata() );
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue