Gerber files generation: fix a rounding issue when drawing circles. (explains bug Bug #1339086 ).

Gerbview: allows x.7 format (recently indroduced in Gerber format)
Also minor coding style fixes.
This commit is contained in:
jean-pierre charras 2014-07-14 09:36:37 +02:00 committed by Maciej Suminski
parent 14cfd173e6
commit 7d1c1f3085
4 changed files with 39 additions and 26 deletions

View File

@ -356,14 +356,17 @@ void GERBER_PLOTTER::Arc( const wxPoint& aCenter, double aStAngle, double aEndAn
DPOINT devEnd = userToDeviceCoordinates( end ); DPOINT devEnd = userToDeviceCoordinates( end );
DPOINT devCenter = userToDeviceCoordinates( aCenter ) DPOINT devCenter = userToDeviceCoordinates( aCenter )
- userToDeviceCoordinates( start ); - userToDeviceCoordinates( start );
fprintf( outputFile, "G75*\n" ); // Multiquadrant mode fprintf( outputFile, "G75*\n" ); // Multiquadrant mode
if( aStAngle < aEndAngle ) if( aStAngle < aEndAngle )
fprintf( outputFile, "G03" ); fprintf( outputFile, "G03" );
else else
fprintf( outputFile, "G02" ); fprintf( outputFile, "G02" );
fprintf( outputFile, "X%dY%dI%dJ%dD01*\n", int( devEnd.x ), int( devEnd.y ),
int( devCenter.x ), int( devCenter.y ) ); fprintf( outputFile, "X%dY%dI%dJ%dD01*\n",
KiROUND( devEnd.x ), KiROUND( devEnd.y ),
KiROUND( devCenter.x ), KiROUND( devCenter.y ) );
fprintf( outputFile, "G74*\nG01*\n" ); // Back to single quadrant and linear interp. fprintf( outputFile, "G74*\nG01*\n" ); // Back to single quadrant and linear interp.
} }

View File

@ -19,25 +19,24 @@
// depending on the gerber file format // depending on the gerber file format
// this scale list assumes gerber units are imperial. // this scale list assumes gerber units are imperial.
// for metric gerber units, the imperial to metric conversion is made in read functions // for metric gerber units, the imperial to metric conversion is made in read functions
static double scale_list[10] = #define SCALE_LIST_SIZE 10
static double scale_list[SCALE_LIST_SIZE] =
{ {
1000.0 * IU_PER_MILS, 1000.0 * IU_PER_MILS, // x.1 format (certainly useless)
100.0 * IU_PER_MILS, 100.0 * IU_PER_MILS, // x.2 format (certainly useless)
10.0 * IU_PER_MILS, 10.0 * IU_PER_MILS, // x.3 format
1.0 * IU_PER_MILS, 1.0 * IU_PER_MILS, // x.4 format
0.1 * IU_PER_MILS, 0.1 * IU_PER_MILS, // x.5 format
0.01 * IU_PER_MILS, 0.01 * IU_PER_MILS, // x.6 format
0.001 * IU_PER_MILS, 0.0001 * IU_PER_MILS, // x.7 format
0.0001 * IU_PER_MILS, 0.00001 * IU_PER_MILS, // provided, but not used
0.00001 * IU_PER_MILS,
0.000001 * IU_PER_MILS 0.000001 * IU_PER_MILS
}; };
/*
/**
* Function scale * Function scale
* converts a distance given in floating point to our internal units * converts a coordinate given in floating point to Gerbvies internal units
* (deci-mils or nano units) * (currently = 10 nanometers)
*/ */
int scaletoIU( double aCoord, bool isMetric ) int scaletoIU( double aCoord, bool isMetric )
{ {
@ -78,6 +77,7 @@ wxPoint GERBER_IMAGE::ReadXYCoord( char*& Text )
Text++; Text++;
text = line; text = line;
nbdigits = 0; nbdigits = 0;
while( IsNumber( *Text ) ) while( IsNumber( *Text ) )
{ {
if( *Text == '.' ) // Force decimat format if reading a floating point number if( *Text == '.' ) // Force decimat format if reading a floating point number
@ -90,6 +90,7 @@ wxPoint GERBER_IMAGE::ReadXYCoord( char*& Text )
} }
*text = 0; *text = 0;
if( is_float ) if( is_float )
{ {
// When X or Y values are float numbers, they are given in mm or inches // When X or Y values are float numbers, they are given in mm or inches
@ -101,6 +102,7 @@ wxPoint GERBER_IMAGE::ReadXYCoord( char*& Text )
else else
{ {
int fmt_scale = (type_coord == 'X') ? m_FmtScale.x : m_FmtScale.y; int fmt_scale = (type_coord == 'X') ? m_FmtScale.x : m_FmtScale.y;
if( m_NoTrailingZeros ) if( m_NoTrailingZeros )
{ {
int min_digit = int min_digit =
@ -113,6 +115,7 @@ wxPoint GERBER_IMAGE::ReadXYCoord( char*& Text )
*text = 0; *text = 0;
} }
current_coord = atoi( line ); current_coord = atoi( line );
double real_scale = scale_list[fmt_scale]; double real_scale = scale_list[fmt_scale];
@ -177,6 +180,7 @@ wxPoint GERBER_IMAGE::ReadIJCoord( char*& Text )
// count digits only (sign and decimal point are not counted) // count digits only (sign and decimal point are not counted)
if( (*Text >= '0') && (*Text <='9') ) if( (*Text >= '0') && (*Text <='9') )
nbdigits++; nbdigits++;
*(text++) = *(Text++); *(text++) = *(Text++);
} }
@ -193,6 +197,7 @@ wxPoint GERBER_IMAGE::ReadIJCoord( char*& Text )
{ {
int fmt_scale = int fmt_scale =
(type_coord == 'I') ? m_FmtScale.x : m_FmtScale.y; (type_coord == 'I') ? m_FmtScale.x : m_FmtScale.y;
if( m_NoTrailingZeros ) if( m_NoTrailingZeros )
{ {
int min_digit = int min_digit =
@ -205,20 +210,21 @@ wxPoint GERBER_IMAGE::ReadIJCoord( char*& Text )
*text = 0; *text = 0;
} }
current_coord = atoi( line ); current_coord = atoi( line );
if( fmt_scale < 0 || fmt_scale > 9 )
fmt_scale = 4; // select scale 1.0
double real_scale = scale_list[fmt_scale]; double real_scale = scale_list[fmt_scale];
if( m_GerbMetric ) if( m_GerbMetric )
real_scale = real_scale / 25.4; real_scale = real_scale / 25.4;
current_coord = KiROUND( current_coord * real_scale ); current_coord = KiROUND( current_coord * real_scale );
} }
if( type_coord == 'I' ) if( type_coord == 'I' )
pos.x = current_coord; pos.x = current_coord;
else if( type_coord == 'J' ) else if( type_coord == 'J' )
pos.y = current_coord; pos.y = current_coord;
continue; continue;
} }
else else
@ -246,8 +252,10 @@ int ReadInt( char*& text, bool aSkipSeparator = true )
int ret = (int) strtol( text, &text, 10 ); int ret = (int) strtol( text, &text, 10 );
if( *text == ',' || isspace( *text ) ) if( *text == ',' || isspace( *text ) )
{
if( aSkipSeparator ) if( aSkipSeparator )
++text; ++text;
}
return ret; return ret;
} }
@ -267,8 +275,10 @@ double ReadDouble( char*& text, bool aSkipSeparator = true )
double ret = strtod( text, &text ); double ret = strtod( text, &text );
if( *text == ',' || isspace( *text ) ) if( *text == ',' || isspace( *text ) )
{
if( aSkipSeparator ) if( aSkipSeparator )
++text; ++text;
}
return ret; return ret;
} }

View File

@ -222,7 +222,6 @@ static void fillArcGBRITEM( GERBER_DRAW_ITEM* aGbrItem, int Dcode_index, int aL
aGbrItem->m_Size = aPenSize; aGbrItem->m_Size = aPenSize;
aGbrItem->m_Flashed = false; aGbrItem->m_Flashed = false;
if( aMultiquadrant ) if( aMultiquadrant )
center = aStart + aRelCenter; center = aStart + aRelCenter;
else else

View File

@ -235,15 +235,16 @@ bool GERBER_IMAGE::ExecuteRS274XCommand( int command,
if( code == 'X' ) if( code == 'X' )
{ {
x_fmt_known = true; x_fmt_known = true;
// number of digits after the decimal point (0 to 6 allowed) // number of digits after the decimal point (0 to 7 allowed)
m_FmtScale.x = *text - '0'; m_FmtScale.x = *text - '0';
m_FmtLen.x = ctmp + m_FmtScale.x; m_FmtLen.x = ctmp + m_FmtScale.x;
// m_FmtScale is 0 to 6 // m_FmtScale is 0 to 7
// (Old Gerber specification was 0 to 6)
if( m_FmtScale.x < 0 ) if( m_FmtScale.x < 0 )
m_FmtScale.x = 0; m_FmtScale.x = 0;
if( m_FmtScale.x > 6 ) if( m_FmtScale.x > 7 )
m_FmtScale.x = 6; m_FmtScale.x = 7;
} }
else else
{ {
@ -252,8 +253,8 @@ bool GERBER_IMAGE::ExecuteRS274XCommand( int command,
m_FmtLen.y = ctmp + m_FmtScale.y; m_FmtLen.y = ctmp + m_FmtScale.y;
if( m_FmtScale.y < 0 ) if( m_FmtScale.y < 0 )
m_FmtScale.y = 0; m_FmtScale.y = 0;
if( m_FmtScale.y > 6 ) if( m_FmtScale.y > 7 )
m_FmtScale.y = 6; m_FmtScale.y = 7;
} }
text++; text++;
} }