Gerbview: implement ;FILE_FORMAT parsing

Apparently Altium likes to output drill files with a specific header
setting the number format

Fixes https://gitlab.com/kicad/code/kicad/-/issues/7519
This commit is contained in:
Mike Williams 2021-07-31 14:39:41 -04:00 committed by jean-pierre charras
parent 5e23294bf5
commit f2241d25c6
4 changed files with 74 additions and 7 deletions

View File

@ -53,6 +53,8 @@ enum drill_M_code_t {
DRILL_RESET_CMD,
DRILL_AUTOMATIC_TOOL_CHANGE,
DRILL_FMT,
DRILL_FORMAT_ALTIUM,
DRILL_HEADER_SKIP,
DRILL_SKIP,
DRILL_TOOL_INFORMATION,
DRILL_M_END_LIST // not used: sentinel
@ -164,6 +166,14 @@ private:
bool Execute_EXCELLON_G_Command( char*& text );
bool Execute_Drill_Command( char*& text );
/**
* Read an Altium-specific FILE_FORMAT=X:X attribute that specifies the length
* and mantissa of the numbers in the gerber file
*
* @param aText Text containing format and mantissa
*/
void readFileFormat( char*& aText );
/**
* Read a tool definition like T1C0.02 or T1F00S00C0.02 or T1C0.02F00S00
* and enter params in TCODE list.

View File

@ -213,6 +213,9 @@ static EXCELLON_CMD excellonHeaderCmdList[] =
{ "DETECT", DRILL_DETECT_BROKEN, -1 },
{ "ICI", DRILL_INCREMENTALHEADER, 1 },
{ "FMAT", DRILL_FMT, 1 }, // Use Format command
{ ";FILE_FORMAT",
DRILL_FORMAT_ALTIUM, 1 }, // Use Format command
{ ";", DRILL_HEADER_SKIP, 0 }, // Other ; hints that we don't implement
{ "ATC", DRILL_AUTOMATIC_TOOL_CHANGE, 0 },
{ "TCST", DRILL_TOOL_CHANGE_STOP, 0 }, // Tool Change Stop
{ "AFS", DRILL_AUTOMATIC_SPEED, 0 }, // Automatic Feeds and Speeds
@ -345,7 +348,7 @@ bool EXCELLON_IMAGE::LoadFile( const wxString & aFullFileName )
char* line = excellonReader.Line();
char* text = StrPurge( line );
if( *text == ';' || *text == 0 ) // comment: skip line or empty malformed line
if( *text == 0 ) // Skip empty lines
continue;
if( m_State == EXCELLON_IMAGE::READ_HEADER_STATE )
@ -356,6 +359,7 @@ bool EXCELLON_IMAGE::LoadFile( const wxString & aFullFileName )
{
switch( *text )
{
case ';':
case 'M':
Execute_HEADER_And_M_Command( text );
break;
@ -474,6 +478,13 @@ bool EXCELLON_IMAGE::Execute_HEADER_And_M_Command( char*& text )
m_State = READ_PROGRAM_STATE;
break;
case DRILL_FORMAT_ALTIUM:
readFileFormat( text );
break;
case DRILL_HEADER_SKIP:
break;
case DRILL_M_METRIC:
SelectUnits( true );
break;
@ -568,6 +579,42 @@ bool EXCELLON_IMAGE::Execute_HEADER_And_M_Command( char*& text )
}
void EXCELLON_IMAGE::readFileFormat( char*& aText )
{
int mantissaDigits = 0;
int characteristicDigits = 0;
// Example String: ;FILE_FORMAT=4:4
// The ;FILE_FORMAT potion will already be stripped off.
// Parse the rest strictly as single_digit:single_digit like 4:4 or 2:4
// Don't allow anything clever like spaces or multiple digits
if( *aText != '=' )
return;
aText++;
if( !isdigit( *aText ) )
return;
characteristicDigits = *aText - '0';
aText++;
if( *aText != ':' )
return;
aText++;
if( !isdigit( *aText ) )
return;
mantissaDigits = *aText - '0';
m_hasFormat = true;
m_FmtLen.x = m_FmtLen.y = characteristicDigits + mantissaDigits;
m_FmtScale.x = m_FmtScale.y = mantissaDigits;
}
bool EXCELLON_IMAGE::readToolInformation( char*& aText )
{
// Read a tool definition like T1C0.02 or T1F00S00C0.02 or T1C0.02F00S00
@ -885,16 +932,24 @@ void EXCELLON_IMAGE::SelectUnits( bool aMetric )
if( aMetric )
{
m_GerbMetric = true;
// number of digits in mantissa
m_FmtScale.x = m_FmtScale.y = fmtMantissaMM;
// number of digits (mantissa+integer)
m_FmtLen.x = m_FmtLen.y = fmtIntegerMM+fmtMantissaMM;
if( !m_hasFormat )
{
// number of digits in mantissa
m_FmtScale.x = m_FmtScale.y = fmtMantissaMM;
// number of digits (mantissa+integer)
m_FmtLen.x = m_FmtLen.y = fmtIntegerMM + fmtMantissaMM;
}
}
else
{
m_GerbMetric = false;
m_FmtScale.x = m_FmtScale.y = fmtMantissaInch;
m_FmtLen.x = m_FmtLen.y = fmtIntegerInch+fmtMantissaInch;
if( !m_hasFormat )
{
m_FmtScale.x = m_FmtScale.y = fmtMantissaInch;
m_FmtLen.x = m_FmtLen.y = fmtIntegerInch + fmtMantissaInch;
}
}
}

View File

@ -183,6 +183,7 @@ void GERBER_FILE_IMAGE::ResetDefaultValues()
m_ImageJustifyXCenter = false; // Image Justify Center on X axis (default = false)
m_ImageJustifyYCenter = false; // Image Justify Center on Y axis (default = false)
m_GerbMetric = false; // false = Inches (default), true = metric
m_hasFormat = false;
m_Relative = false; // false = absolute Coord,
// true = relative Coord
m_NoTrailingZeros = false; // true: trailing zeros deleted

View File

@ -379,6 +379,7 @@ public:
///< Image Justify Offset on XY axis (default = 0,0).
wxPoint m_ImageJustifyOffset;
bool m_GerbMetric; // false = Inches, true = metric
bool m_hasFormat;
///< false = absolute Coord, true = relative Coord.
bool m_Relative;