Commit 49884da3 authored by jean-pierre charras's avatar jean-pierre charras

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.
parent 853abdac
......@@ -356,14 +356,17 @@ void GERBER_PLOTTER::Arc( const wxPoint& aCenter, double aStAngle, double aEndAn
DPOINT devEnd = userToDeviceCoordinates( end );
DPOINT devCenter = userToDeviceCoordinates( aCenter )
- userToDeviceCoordinates( start );
fprintf( outputFile, "G75*\n" ); // Multiquadrant mode
if( aStAngle < aEndAngle )
fprintf( outputFile, "G03" );
else
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.
}
......
......@@ -19,25 +19,24 @@
// depending on the gerber file format
// this scale list assumes gerber units are imperial.
// 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,
100.0 * IU_PER_MILS,
10.0 * IU_PER_MILS,
1.0 * IU_PER_MILS,
0.1 * IU_PER_MILS,
0.01 * IU_PER_MILS,
0.001 * IU_PER_MILS,
0.0001 * IU_PER_MILS,
0.00001 * IU_PER_MILS,
1000.0 * IU_PER_MILS, // x.1 format (certainly useless)
100.0 * IU_PER_MILS, // x.2 format (certainly useless)
10.0 * IU_PER_MILS, // x.3 format
1.0 * IU_PER_MILS, // x.4 format
0.1 * IU_PER_MILS, // x.5 format
0.01 * IU_PER_MILS, // x.6 format
0.0001 * IU_PER_MILS, // x.7 format
0.00001 * IU_PER_MILS, // provided, but not used
0.000001 * IU_PER_MILS
};
/**
/*
* Function scale
* converts a distance given in floating point to our internal units
* (deci-mils or nano units)
* converts a coordinate given in floating point to Gerbvies internal units
* (currently = 10 nanometers)
*/
int scaletoIU( double aCoord, bool isMetric )
{
......@@ -78,6 +77,7 @@ wxPoint GERBER_IMAGE::ReadXYCoord( char*& Text )
Text++;
text = line;
nbdigits = 0;
while( IsNumber( *Text ) )
{
if( *Text == '.' ) // Force decimat format if reading a floating point number
......@@ -90,6 +90,7 @@ wxPoint GERBER_IMAGE::ReadXYCoord( char*& Text )
}
*text = 0;
if( is_float )
{
// 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
{
int fmt_scale = (type_coord == 'X') ? m_FmtScale.x : m_FmtScale.y;
if( m_NoTrailingZeros )
{
int min_digit =
......@@ -113,6 +115,7 @@ wxPoint GERBER_IMAGE::ReadXYCoord( char*& Text )
*text = 0;
}
current_coord = atoi( line );
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)
if( (*Text >= '0') && (*Text <='9') )
nbdigits++;
*(text++) = *(Text++);
}
......@@ -193,6 +197,7 @@ wxPoint GERBER_IMAGE::ReadIJCoord( char*& Text )
{
int fmt_scale =
(type_coord == 'I') ? m_FmtScale.x : m_FmtScale.y;
if( m_NoTrailingZeros )
{
int min_digit =
......@@ -205,20 +210,21 @@ wxPoint GERBER_IMAGE::ReadIJCoord( char*& Text )
*text = 0;
}
current_coord = atoi( line );
if( fmt_scale < 0 || fmt_scale > 9 )
fmt_scale = 4; // select scale 1.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
......@@ -246,8 +252,10 @@ int ReadInt( char*& text, bool aSkipSeparator = true )
int ret = (int) strtol( text, &text, 10 );
if( *text == ',' || isspace( *text ) )
{
if( aSkipSeparator )
++text;
}
return ret;
}
......@@ -267,8 +275,10 @@ double ReadDouble( char*& text, bool aSkipSeparator = true )
double ret = strtod( text, &text );
if( *text == ',' || isspace( *text ) )
{
if( aSkipSeparator )
++text;
}
return ret;
}
......
......@@ -222,7 +222,6 @@ static void fillArcGBRITEM( GERBER_DRAW_ITEM* aGbrItem, int Dcode_index, int aL
aGbrItem->m_Size = aPenSize;
aGbrItem->m_Flashed = false;
if( aMultiquadrant )
center = aStart + aRelCenter;
else
......
......@@ -235,15 +235,16 @@ bool GERBER_IMAGE::ExecuteRS274XCommand( int command,
if( code == 'X' )
{
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_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 )
m_FmtScale.x = 0;
if( m_FmtScale.x > 6 )
m_FmtScale.x = 6;
if( m_FmtScale.x > 7 )
m_FmtScale.x = 7;
}
else
{
......@@ -252,8 +253,8 @@ bool GERBER_IMAGE::ExecuteRS274XCommand( int command,
m_FmtLen.y = ctmp + m_FmtScale.y;
if( m_FmtScale.y < 0 )
m_FmtScale.y = 0;
if( m_FmtScale.y > 6 )
m_FmtScale.y = 6;
if( m_FmtScale.y > 7 )
m_FmtScale.y = 7;
}
text++;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment