Review ReadXY/ReadIJ to avoid static char arrays
Tighten up the code a bit, removing extra calls and loops. Removes
unchecked use of stack char array
Fixes https://gitlab.com/kicad/code/kicad/issues/10719
(cherry picked from commit 927afe313d
)
This commit is contained in:
parent
08ee2671cc
commit
7ed569058c
|
@ -39,15 +39,15 @@
|
||||||
#define SCALE_LIST_SIZE 9
|
#define SCALE_LIST_SIZE 9
|
||||||
static double scale_list[SCALE_LIST_SIZE] =
|
static double scale_list[SCALE_LIST_SIZE] =
|
||||||
{
|
{
|
||||||
1000.0 * IU_PER_MILS, // x.1 format (certainly useless)
|
1000.0 * GERB_IU_PER_MM * 0.0254, // x.1 format (certainly useless)
|
||||||
100.0 * IU_PER_MILS, // x.2 format (certainly useless)
|
100.0 * GERB_IU_PER_MM * 0.0254, // x.2 format (certainly useless)
|
||||||
10.0 * IU_PER_MILS, // x.3 format
|
10.0 * GERB_IU_PER_MM * 0.0254, // x.3 format
|
||||||
1.0 * IU_PER_MILS, // x.4 format
|
1.0 * GERB_IU_PER_MM * 0.0254, // x.4 format
|
||||||
0.1 * IU_PER_MILS, // x.5 format
|
0.1 * GERB_IU_PER_MM * 0.0254, // x.5 format
|
||||||
0.01 * IU_PER_MILS, // x.6 format
|
0.01 * GERB_IU_PER_MM * 0.0254, // x.6 format
|
||||||
0.001 * IU_PER_MILS, // x.7 format (currently the max allowed precision)
|
0.001 * GERB_IU_PER_MM * 0.0254, // x.7 format (currently the max allowed precision)
|
||||||
0.0001 * IU_PER_MILS, // provided, but not used
|
0.0001 * GERB_IU_PER_MM * 0.0254, // provided, but not used
|
||||||
0.00001 * IU_PER_MILS, // provided, but not used
|
0.00001 * GERB_IU_PER_MM * 0.0254, // provided, but not used
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -60,129 +60,99 @@ int scaletoIU( double aCoord, bool isMetric )
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if( isMetric ) // gerber are units in mm
|
if( isMetric ) // gerber are units in mm
|
||||||
ret = KiROUND( aCoord * IU_PER_MM );
|
ret = KiROUND( aCoord * GERB_IU_PER_MM );
|
||||||
else // gerber are units in inches
|
else // gerber are units in inches
|
||||||
ret = KiROUND( aCoord * IU_PER_MILS * 1000.0 );
|
ret = KiROUND( aCoord * GERB_IU_PER_MM * 0.0254 );
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VECTOR2I GERBER_FILE_IMAGE::ReadXYCoord( char*& Text, bool aExcellonMode )
|
VECTOR2I GERBER_FILE_IMAGE::ReadXYCoord( char*& aText, bool aExcellonMode )
|
||||||
{
|
{
|
||||||
VECTOR2I pos;
|
VECTOR2I pos( 0, 0 );
|
||||||
int type_coord = 0, current_coord, nbdigits;
|
bool is_float = false;
|
||||||
bool is_float = false;
|
|
||||||
char* text;
|
|
||||||
char line[256];
|
|
||||||
|
|
||||||
|
std::string line;
|
||||||
|
|
||||||
|
// Reserve the anticipated length plus an optional sign and decimal
|
||||||
|
line.reserve( std::max( m_FmtLen.x, m_FmtLen.y ) + 3 );
|
||||||
|
|
||||||
if( m_Relative )
|
if( m_Relative )
|
||||||
pos.x = pos.y = 0;
|
|
||||||
else
|
|
||||||
pos = m_CurrentPos;
|
pos = m_CurrentPos;
|
||||||
|
|
||||||
if( Text == nullptr )
|
if( aText == nullptr )
|
||||||
return pos;
|
return pos;
|
||||||
|
|
||||||
text = line;
|
while( *aText && ( ( *aText == 'X' ) || ( *aText == 'Y' ) || ( *aText == 'A' ) ) )
|
||||||
|
|
||||||
while( *Text )
|
|
||||||
{
|
{
|
||||||
if( ( *Text == 'X' ) || ( *Text == 'Y' ) || ( *Text == 'A' ) )
|
double decimal_scale = 1.0;
|
||||||
|
int nbdigits = 0;
|
||||||
|
int current_coord = 0;
|
||||||
|
char type_coord = *aText++;
|
||||||
|
|
||||||
|
line.clear();
|
||||||
|
|
||||||
|
while( IsNumber( *aText ) )
|
||||||
{
|
{
|
||||||
type_coord = *Text;
|
if( *aText == '.' ) // Force decimal format if reading a floating point number
|
||||||
Text++;
|
is_float = true;
|
||||||
text = line;
|
|
||||||
nbdigits = 0;
|
|
||||||
|
|
||||||
while( IsNumber( *Text ) )
|
// count digits only (sign and decimal point are not counted)
|
||||||
{
|
if( (*aText >= '0') && (*aText <='9') )
|
||||||
if( *Text == '.' ) // Force decimal format if reading a floating point number
|
nbdigits++;
|
||||||
is_float = true;
|
|
||||||
|
|
||||||
// count digits only (sign and decimal point are not counted)
|
line.push_back( *( aText++ ) );
|
||||||
if( (*Text >= '0') && (*Text <='9') )
|
}
|
||||||
nbdigits++;
|
|
||||||
|
|
||||||
*(text++) = *(Text++);
|
double val = strtod( line.data(), nullptr );
|
||||||
}
|
|
||||||
|
|
||||||
*text = 0;
|
if( is_float )
|
||||||
|
{
|
||||||
if( is_float )
|
// When X or Y (or A) values are float numbers, they are given in mm or inches
|
||||||
{
|
if( m_GerbMetric ) // units are mm
|
||||||
// When X or Y (or A) values are float numbers, they are given in mm or inches
|
current_coord = KiROUND( val * GERB_IU_PER_MM );
|
||||||
if( m_GerbMetric ) // units are mm
|
else // units are inches
|
||||||
current_coord = KiROUND( atof( line ) * IU_PER_MILS / 0.0254 );
|
current_coord = KiROUND( val * GERB_IU_PER_MM * 0.0254 );
|
||||||
else // units are inches
|
|
||||||
current_coord = KiROUND( atof( line ) * IU_PER_MILS * 1000 );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int fmt_scale = (type_coord == 'X') ? m_FmtScale.x : m_FmtScale.y;
|
|
||||||
|
|
||||||
if( m_NoTrailingZeros )
|
|
||||||
{
|
|
||||||
// no trailing zero format, we need to add missing zeros.
|
|
||||||
int digit_count = (type_coord == 'X') ? m_FmtLen.x : m_FmtLen.y;
|
|
||||||
|
|
||||||
while( nbdigits < digit_count )
|
|
||||||
{
|
|
||||||
*(text++) = '0';
|
|
||||||
nbdigits++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( aExcellonMode )
|
|
||||||
{
|
|
||||||
// Truncate the extra digits if the len is more than expected
|
|
||||||
// because the conversion to internal units expect exactly
|
|
||||||
// digit_count digits
|
|
||||||
while( nbdigits > digit_count )
|
|
||||||
{
|
|
||||||
*(text--) = 0;
|
|
||||||
nbdigits--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*text = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
current_coord = atoi( line );
|
|
||||||
double real_scale = scale_list[fmt_scale];
|
|
||||||
|
|
||||||
if( m_GerbMetric )
|
|
||||||
real_scale = real_scale / 25.4;
|
|
||||||
|
|
||||||
current_coord = KiROUND( current_coord * real_scale );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( type_coord == 'X' )
|
|
||||||
{
|
|
||||||
pos.x = current_coord;
|
|
||||||
}
|
|
||||||
else if( type_coord == 'Y' )
|
|
||||||
{
|
|
||||||
pos.y = current_coord;
|
|
||||||
}
|
|
||||||
else if( type_coord == 'A' )
|
|
||||||
{
|
|
||||||
m_ArcRadius = current_coord;
|
|
||||||
m_LastArcDataType = ARC_INFO_TYPE_RADIUS;
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
break;
|
int fmt_scale = (type_coord == 'X') ? m_FmtScale.x : m_FmtScale.y;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( m_Relative )
|
if( m_NoTrailingZeros )
|
||||||
{
|
{
|
||||||
pos.x += m_CurrentPos.x;
|
// no trailing zero format, we need to add missing zeros.
|
||||||
pos.y += m_CurrentPos.y;
|
int digit_count = (type_coord == 'X') ? m_FmtLen.x : m_FmtLen.y;
|
||||||
|
|
||||||
|
// Truncate the extra digits if the len is more than expected
|
||||||
|
// because the conversion to internal units expect exactly
|
||||||
|
// digit_count digits. Alternatively, add some additional digits
|
||||||
|
// to pad out to the missing zeros
|
||||||
|
if( nbdigits < digit_count || ( aExcellonMode && ( nbdigits > digit_count ) ) )
|
||||||
|
decimal_scale = std::pow<double>( 10, digit_count - nbdigits );
|
||||||
|
}
|
||||||
|
|
||||||
|
double real_scale = scale_list[fmt_scale];
|
||||||
|
|
||||||
|
if( m_GerbMetric )
|
||||||
|
real_scale = real_scale / 25.4;
|
||||||
|
|
||||||
|
current_coord = KiROUND( val * real_scale * decimal_scale );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( type_coord == 'X' )
|
||||||
|
{
|
||||||
|
pos.x += current_coord;
|
||||||
|
}
|
||||||
|
else if( type_coord == 'Y' )
|
||||||
|
{
|
||||||
|
pos.y += current_coord;
|
||||||
|
}
|
||||||
|
else if( type_coord == 'A' )
|
||||||
|
{
|
||||||
|
m_ArcRadius = current_coord;
|
||||||
|
m_LastArcDataType = ARC_INFO_TYPE_RADIUS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_CurrentPos = pos;
|
m_CurrentPos = pos;
|
||||||
|
@ -190,88 +160,82 @@ VECTOR2I GERBER_FILE_IMAGE::ReadXYCoord( char*& Text, bool aExcellonMode )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VECTOR2I GERBER_FILE_IMAGE::ReadIJCoord( char*& Text )
|
VECTOR2I GERBER_FILE_IMAGE::ReadIJCoord( char*& aText )
|
||||||
{
|
{
|
||||||
VECTOR2I pos( 0, 0 );
|
VECTOR2I pos( 0, 0 );
|
||||||
|
|
||||||
int type_coord = 0, current_coord, nbdigits;
|
|
||||||
bool is_float = false;
|
bool is_float = false;
|
||||||
char* text;
|
|
||||||
char line[256];
|
|
||||||
|
|
||||||
if( Text == nullptr )
|
std::string line;
|
||||||
|
|
||||||
|
// Reserve the anticipated length plus an optional sign and decimal
|
||||||
|
line.reserve( std::max( m_FmtLen.x, m_FmtLen.y ) + 3 );
|
||||||
|
|
||||||
|
if( aText == nullptr )
|
||||||
return pos;
|
return pos;
|
||||||
|
|
||||||
text = line;
|
while( *aText && ( ( *aText == 'I' ) || ( *aText == 'J' ) ) )
|
||||||
|
|
||||||
while( *Text )
|
|
||||||
{
|
{
|
||||||
if( ( *Text == 'I' ) || ( *Text == 'J' ) )
|
double decimal_scale = 1.0;
|
||||||
|
int nbdigits = 0;
|
||||||
|
int current_coord = 0;
|
||||||
|
char type_coord = *aText++;
|
||||||
|
|
||||||
|
line.clear();
|
||||||
|
|
||||||
|
while( IsNumber( *aText ) )
|
||||||
{
|
{
|
||||||
type_coord = *Text;
|
if( *aText == '.' ) // Force decimal format if reading a floating point number
|
||||||
Text++;
|
is_float = true;
|
||||||
text = line;
|
|
||||||
nbdigits = 0;
|
|
||||||
|
|
||||||
while( IsNumber( *Text ) )
|
// count digits only (sign and decimal point are not counted)
|
||||||
{
|
if( (*aText >= '0') && (*aText <='9') )
|
||||||
if( *Text == '.' )
|
nbdigits++;
|
||||||
is_float = true;
|
|
||||||
|
|
||||||
// count digits only (sign and decimal point are not counted)
|
line.push_back( *( aText++ ) );
|
||||||
if( ( *Text >= '0' ) && ( *Text <= '9' ) )
|
}
|
||||||
nbdigits++;
|
|
||||||
|
|
||||||
*(text++) = *(Text++);
|
double val = strtod( line.data(), nullptr );
|
||||||
}
|
|
||||||
|
|
||||||
*text = 0;
|
if( is_float )
|
||||||
|
{
|
||||||
if( is_float )
|
// When X or Y (or A) values are float numbers, they are given in mm or inches
|
||||||
{
|
if( m_GerbMetric ) // units are mm
|
||||||
// When X or Y values are float numbers, they are given in mm or inches
|
current_coord = KiROUND( val * GERB_IU_PER_MM );
|
||||||
if( m_GerbMetric ) // units are mm
|
else // units are inches
|
||||||
current_coord = KiROUND( atof( line ) * IU_PER_MILS / 0.0254 );
|
current_coord = KiROUND( val * GERB_IU_PER_MM * 0.0254 );
|
||||||
else // units are inches
|
|
||||||
current_coord = KiROUND( atof( line ) * IU_PER_MILS * 1000 );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int fmt_scale = ( type_coord == 'I' ) ? m_FmtScale.x : m_FmtScale.y;
|
|
||||||
|
|
||||||
if( m_NoTrailingZeros )
|
|
||||||
{
|
|
||||||
int min_digit = ( type_coord == 'I' ) ? m_FmtLen.x : m_FmtLen.y;
|
|
||||||
|
|
||||||
while( nbdigits < min_digit )
|
|
||||||
{
|
|
||||||
*(text++) = '0';
|
|
||||||
nbdigits++;
|
|
||||||
}
|
|
||||||
|
|
||||||
*text = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
current_coord = atoi( line );
|
|
||||||
|
|
||||||
double real_scale = scale_list[fmt_scale];
|
|
||||||
|
|
||||||
if( m_GerbMetric )
|
|
||||||
real_scale = real_scale / 25.4;
|
|
||||||
|
|
||||||
current_coord = KiROUND( current_coord * real_scale );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( type_coord == 'I' )
|
|
||||||
pos.x = current_coord;
|
|
||||||
else if( type_coord == 'J' )
|
|
||||||
pos.y = current_coord;
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
break;
|
int fmt_scale = ( type_coord == 'I' ) ? m_FmtScale.x : m_FmtScale.y;
|
||||||
|
|
||||||
|
if( m_NoTrailingZeros )
|
||||||
|
{
|
||||||
|
// no trailing zero format, we need to add missing zeros.
|
||||||
|
int digit_count = ( type_coord == 'I' ) ? m_FmtLen.x : m_FmtLen.y;
|
||||||
|
|
||||||
|
// Truncate the extra digits if the len is more than expected
|
||||||
|
// because the conversion to internal units expect exactly
|
||||||
|
// digit_count digits. Alternatively, add some additional digits
|
||||||
|
// to pad out to the missing zeros
|
||||||
|
if( nbdigits < digit_count )
|
||||||
|
decimal_scale = std::pow<double>( 10, digit_count - nbdigits );
|
||||||
|
}
|
||||||
|
|
||||||
|
double real_scale = scale_list[fmt_scale];
|
||||||
|
|
||||||
|
if( m_GerbMetric )
|
||||||
|
real_scale = real_scale / 25.4;
|
||||||
|
|
||||||
|
current_coord = KiROUND( val * real_scale * decimal_scale );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( type_coord == 'I' )
|
||||||
|
{
|
||||||
|
pos.x = current_coord;
|
||||||
|
}
|
||||||
|
else if( type_coord == 'J' )
|
||||||
|
{
|
||||||
|
pos.y = current_coord;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue