Gerbview: fixed an issue with some gerber files. Added Image Justify support (partial support).
This commit is contained in:
parent
a911720adf
commit
de37bbad17
|
@ -151,6 +151,9 @@ void GERBER_IMAGE::ResetDefaultValues()
|
||||||
m_FileName.Empty();
|
m_FileName.Empty();
|
||||||
m_ImageName = wxT( "no name" ); // Image name from the IN command
|
m_ImageName = wxT( "no name" ); // Image name from the IN command
|
||||||
m_ImageNegative = false; // true = Negative image
|
m_ImageNegative = false; // true = Negative image
|
||||||
|
m_ImageJustifyOffset = wxPoint(0,0); // Image justify Offset
|
||||||
|
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_GerbMetric = false; // false = Inches (default), true = metric
|
||||||
m_Relative = false; // false = absolute Coord,
|
m_Relative = false; // false = absolute Coord,
|
||||||
// true = relative Coord
|
// true = relative Coord
|
||||||
|
@ -271,3 +274,45 @@ void GERBER_IMAGE::StepAndRepeatItem( const GERBER_DRAW_ITEM& aItem )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Function DisplayInfo
|
||||||
|
* has knowledge about the frame and how and where to put status information
|
||||||
|
* about this object into the frame's message panel.
|
||||||
|
* Display info about Image Parameters.
|
||||||
|
*/
|
||||||
|
void GERBER_IMAGE::DisplayImageInfo( void )
|
||||||
|
{
|
||||||
|
wxString msg;
|
||||||
|
|
||||||
|
m_Parent->ClearMsgPanel();
|
||||||
|
|
||||||
|
// Display Image name
|
||||||
|
m_Parent->AppendMsgPanel( _( "Image name" ), m_ImageName, BROWN );
|
||||||
|
|
||||||
|
// Display graphic layer number
|
||||||
|
msg.Printf( wxT( "%d" ), m_GraphicLayer + 1 );
|
||||||
|
m_Parent->AppendMsgPanel( _( "Graphic layer" ), msg, BROWN );
|
||||||
|
|
||||||
|
// This next info can be see as debug info, so it can be disabled
|
||||||
|
|
||||||
|
// Display rotation
|
||||||
|
msg.Printf( wxT( "%d" ), m_ImageRotation / 10 );
|
||||||
|
m_Parent->AppendMsgPanel( _( "Rotation" ), msg, CYAN );
|
||||||
|
|
||||||
|
// Display Image justification;
|
||||||
|
msg = m_ImageJustifyXCenter ? _("Center") : _("Normal");
|
||||||
|
m_Parent->AppendMsgPanel( _( "X Justify" ), msg, DARKRED );
|
||||||
|
|
||||||
|
msg = m_ImageJustifyYCenter ? _("Center") : _("Normal");
|
||||||
|
m_Parent->AppendMsgPanel( _( "Y Justify" ), msg, DARKRED );
|
||||||
|
|
||||||
|
if( g_UserUnit == INCHES )
|
||||||
|
msg.Printf( wxT( "X=%f Y=%f" ), (double) m_ImageJustifyOffset.x/10000,
|
||||||
|
(double) m_ImageJustifyOffset.y/10000 );
|
||||||
|
else
|
||||||
|
msg.Printf( wxT( "X=%f Y=%f" ), (double) m_ImageJustifyOffset.x*2.54/1000,
|
||||||
|
(double) m_ImageJustifyOffset.y*2.54/1000 );
|
||||||
|
m_Parent->AppendMsgPanel( _( "Image Justify Offset" ), msg, CYAN );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -86,6 +86,9 @@ public:
|
||||||
wxString m_ImageName; // Image name, from IN <name>* command
|
wxString m_ImageName; // Image name, from IN <name>* command
|
||||||
int m_GraphicLayer; // Graphic layer Number
|
int m_GraphicLayer; // Graphic layer Number
|
||||||
bool m_ImageNegative; // true = Negative image
|
bool m_ImageNegative; // true = Negative image
|
||||||
|
bool m_ImageJustifyXCenter; // Image Justify Center on X axis (default = false)
|
||||||
|
bool m_ImageJustifyYCenter; // Image Justify Center on Y axis (default = false)
|
||||||
|
wxPoint m_ImageJustifyOffset; // Image Justify Offset on XY axis (default = 0,0)
|
||||||
bool m_GerbMetric; // false = Inches, true = metric
|
bool m_GerbMetric; // false = Inches, true = metric
|
||||||
bool m_Relative; // false = absolute Coord, true = relative Coord
|
bool m_Relative; // false = absolute Coord, true = relative Coord
|
||||||
bool m_NoTrailingZeros; // true: remove tailing zeros.
|
bool m_NoTrailingZeros; // true: remove tailing zeros.
|
||||||
|
@ -236,6 +239,13 @@ public:
|
||||||
* @param aItem = the item to repeat
|
* @param aItem = the item to repeat
|
||||||
*/
|
*/
|
||||||
void StepAndRepeatItem( const GERBER_DRAW_ITEM& aItem );
|
void StepAndRepeatItem( const GERBER_DRAW_ITEM& aItem );
|
||||||
|
|
||||||
|
/** Function DisplayImageInfo
|
||||||
|
* has knowledge about the frame and how and where to put status information
|
||||||
|
* about this object into the frame's message panel.
|
||||||
|
* Display info about Image Parameters.
|
||||||
|
*/
|
||||||
|
void DisplayImageInfo( void );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -120,7 +120,7 @@ wxPoint GERBER_DRAW_ITEM::GetABPosition( const wxPoint& aXYPosition )
|
||||||
* For instance: Rotation must be made after or before mirroring ?
|
* For instance: Rotation must be made after or before mirroring ?
|
||||||
* Note: if something is changed here, GetYXPosition must reflect changes
|
* Note: if something is changed here, GetYXPosition must reflect changes
|
||||||
*/
|
*/
|
||||||
wxPoint abPos = aXYPosition;
|
wxPoint abPos = aXYPosition + m_imageParams->m_ImageJustifyOffset;
|
||||||
|
|
||||||
if( m_swapAxis )
|
if( m_swapAxis )
|
||||||
EXCHG( abPos.x, abPos.y );
|
EXCHG( abPos.x, abPos.y );
|
||||||
|
@ -165,7 +165,7 @@ wxPoint GERBER_DRAW_ITEM::GetXYPosition( const wxPoint& aABPosition )
|
||||||
xyPos -= m_layerOffset + m_imageParams->m_ImageOffset;
|
xyPos -= m_layerOffset + m_imageParams->m_ImageOffset;
|
||||||
if( m_swapAxis )
|
if( m_swapAxis )
|
||||||
EXCHG( xyPos.x, xyPos.y );
|
EXCHG( xyPos.x, xyPos.y );
|
||||||
return xyPos;
|
return xyPos - m_imageParams->m_ImageJustifyOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -458,7 +458,7 @@ void GERBER_DRAW_ITEM::DrawGbrPoly( EDA_Rect* aClipBox,
|
||||||
/** Function DisplayInfo
|
/** Function DisplayInfo
|
||||||
* has knowledge about the frame and how and where to put status information
|
* has knowledge about the frame and how and where to put status information
|
||||||
* about this object into the frame's message panel.
|
* about this object into the frame's message panel.
|
||||||
* Display info about the track segment only, and does not calculate the full track length
|
* Display info about this GERBER item
|
||||||
* @param frame A WinEDA_DrawFrame in which to print status information.
|
* @param frame A WinEDA_DrawFrame in which to print status information.
|
||||||
*/
|
*/
|
||||||
void GERBER_DRAW_ITEM::DisplayInfo( WinEDA_DrawFrame* frame )
|
void GERBER_DRAW_ITEM::DisplayInfo( WinEDA_DrawFrame* frame )
|
||||||
|
@ -473,13 +473,6 @@ void GERBER_DRAW_ITEM::DisplayInfo( WinEDA_DrawFrame* frame )
|
||||||
msg.Printf( wxT( "%d" ), m_DCode );
|
msg.Printf( wxT( "%d" ), m_DCode );
|
||||||
frame->AppendMsgPanel( _( "D Code" ), msg, RED );
|
frame->AppendMsgPanel( _( "D Code" ), msg, RED );
|
||||||
|
|
||||||
// Display Image name
|
|
||||||
if( m_imageParams )
|
|
||||||
{
|
|
||||||
msg = m_imageParams->m_ImageName;
|
|
||||||
frame->AppendMsgPanel( _( "Image name" ), msg, BROWN );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Display graphic layer number
|
// Display graphic layer number
|
||||||
msg.Printf( wxT( "%d" ), GetLayer() + 1 );
|
msg.Printf( wxT( "%d" ), GetLayer() + 1 );
|
||||||
frame->AppendMsgPanel( _( "Graphic layer" ), msg, BROWN );
|
frame->AppendMsgPanel( _( "Graphic layer" ), msg, BROWN );
|
||||||
|
|
|
@ -209,7 +209,7 @@ public:
|
||||||
* has knowledge about the frame and how and where to put status information
|
* has knowledge about the frame and how and where to put status information
|
||||||
* about this object into the frame's message panel.
|
* about this object into the frame's message panel.
|
||||||
* Is virtual from EDA_BaseStruct.
|
* Is virtual from EDA_BaseStruct.
|
||||||
* Display info about the track segment and the full track length
|
* Display info about this GERBER item
|
||||||
* @param frame A WinEDA_DrawFrame in which to print status information.
|
* @param frame A WinEDA_DrawFrame in which to print status information.
|
||||||
*/
|
*/
|
||||||
void DisplayInfo( WinEDA_DrawFrame* frame );
|
void DisplayInfo( WinEDA_DrawFrame* frame );
|
||||||
|
|
|
@ -37,6 +37,12 @@ void WinEDA_GerberFrame::OnLeftClick( wxDC* DC, const wxPoint& MousePos )
|
||||||
{
|
{
|
||||||
DrawStruct = GerberGeneralLocateAndDisplay();
|
DrawStruct = GerberGeneralLocateAndDisplay();
|
||||||
GetScreen()->SetCurItem( DrawStruct );
|
GetScreen()->SetCurItem( DrawStruct );
|
||||||
|
if( DrawStruct == NULL )
|
||||||
|
{
|
||||||
|
GERBER_IMAGE* gerber = g_GERBER_List[getActiveLayer() ];
|
||||||
|
if( gerber )
|
||||||
|
gerber->DisplayImageInfo( );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
G04 Test image justify 1*
|
||||||
|
G04 Crosshairs should be justified to the X axis *
|
||||||
|
G04 and 0.5 inches offset from Y axis *
|
||||||
|
G04 Handcoded by Julian Lamb *
|
||||||
|
%MOIN*%
|
||||||
|
%FSLAX23Y23*%
|
||||||
|
%IJB.5*%
|
||||||
|
%ADD10C,0.050*%
|
||||||
|
|
||||||
|
G04 Crosshairs *
|
||||||
|
X-1000Y0D02*
|
||||||
|
G54D10*
|
||||||
|
X1000Y0D01*
|
||||||
|
|
||||||
|
X0Y-1000D02*
|
||||||
|
G54D10*
|
||||||
|
X0Y1000D01*
|
||||||
|
|
||||||
|
M02*
|
|
@ -0,0 +1,18 @@
|
||||||
|
G04 Test image offset *
|
||||||
|
G04 Crosshairs should be centered on 0,0 in final rendering*
|
||||||
|
G04 Handcoded by Julian Lamb *
|
||||||
|
%MOIN*%
|
||||||
|
%FSLAX23Y23*%
|
||||||
|
%IOA-2.0B-1.0*%
|
||||||
|
%ADD10C,0.050*%
|
||||||
|
|
||||||
|
G04 Crosshairs to be on 0,0 *
|
||||||
|
X1000Y1000D02*
|
||||||
|
G54D10*
|
||||||
|
X3000Y1000D01*
|
||||||
|
|
||||||
|
X2000Y0D02*
|
||||||
|
G54D10*
|
||||||
|
X2000Y2000D01*
|
||||||
|
|
||||||
|
M02*
|
|
@ -11,6 +11,9 @@
|
||||||
|
|
||||||
#define CODE( x, y ) ( ( (x) << 8 ) + (y) )
|
#define CODE( x, y ) ( ( (x) << 8 ) + (y) )
|
||||||
|
|
||||||
|
// Helper function to read a primitive macro param (TODO: make it DCODE_PARAM function)
|
||||||
|
static bool ReadMacroParam( DCODE_PARAM& aParam, char*& aText );
|
||||||
|
|
||||||
// See rs274xrevd_e.pdf, table 1: RS-274X parameters order of entry
|
// See rs274xrevd_e.pdf, table 1: RS-274X parameters order of entry
|
||||||
// in gerber files, when a coordinate is given (like X78Y600 or I0J80):
|
// in gerber files, when a coordinate is given (like X78Y600 or I0J80):
|
||||||
// Y and Y are logical coordinates
|
// Y and Y are logical coordinates
|
||||||
|
@ -94,13 +97,15 @@ static int ReadXCommand( char*& text )
|
||||||
* int, then skip over that.
|
* int, then skip over that.
|
||||||
* @param text A reference to a character pointer from which bytes are read
|
* @param text A reference to a character pointer from which bytes are read
|
||||||
* and the pointer is advanced for each byte read.
|
* and the pointer is advanced for each byte read.
|
||||||
* @param int - The int read in.
|
* @param aSkipSeparator = true (default) to skip comma
|
||||||
|
* @return int - The int read in.
|
||||||
*/
|
*/
|
||||||
static int ReadInt( char*& text )
|
static 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 )
|
||||||
++text;
|
++text;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -113,13 +118,15 @@ static int ReadInt( char*& text )
|
||||||
* the double, then skip over that.
|
* the double, then skip over that.
|
||||||
* @param text A reference to a character pointer from which the ASCII double
|
* @param text A reference to a character pointer from which the ASCII double
|
||||||
* is read from and the pointer advanced for each character read.
|
* is read from and the pointer advanced for each character read.
|
||||||
|
* @param aSkipSeparator = true (default) to skip comma
|
||||||
* @return double
|
* @return double
|
||||||
*/
|
*/
|
||||||
static double ReadDouble( char*& text )
|
static 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 )
|
||||||
++text;
|
++text;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -427,11 +434,68 @@ bool GERBER_IMAGE::ExecuteRS274XCommand( int command,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IMAGE_JUSTIFY:
|
case IMAGE_JUSTIFY: // Command IJAnBn*
|
||||||
case PLOTTER_FILM:
|
m_ImageJustifyXCenter = false; // Image Justify Center on X axis (default = false)
|
||||||
|
m_ImageJustifyYCenter = false; // Image Justify Center on Y axis (default = false)
|
||||||
|
m_ImageJustifyOffset = wxPoint(0,0); // Image Justify Offset on XY axis (default = 0,0)
|
||||||
|
while( *text && *text != '*' )
|
||||||
|
{
|
||||||
|
// IJ command is (for A or B axis) AC or AL or A<coordinate>
|
||||||
|
switch( *text )
|
||||||
|
{
|
||||||
|
case 'A': // A axis justify
|
||||||
|
text++;
|
||||||
|
if( *text == 'C' )
|
||||||
|
{
|
||||||
|
m_ImageJustifyXCenter = true;
|
||||||
|
text++;
|
||||||
|
}
|
||||||
|
else if( *text == 'L' )
|
||||||
|
{
|
||||||
|
m_ImageJustifyXCenter = true;
|
||||||
|
text++;
|
||||||
|
}
|
||||||
|
else m_ImageJustifyOffset.x = wxRound( ReadDouble( text ) * conv_scale);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'B': // B axis justify
|
||||||
|
text++;
|
||||||
|
if( *text == 'C' )
|
||||||
|
{
|
||||||
|
m_ImageJustifyYCenter = true;
|
||||||
|
text++;
|
||||||
|
}
|
||||||
|
else if( *text == 'L' )
|
||||||
|
{
|
||||||
|
m_ImageJustifyYCenter = true;
|
||||||
|
text++;
|
||||||
|
}
|
||||||
|
else m_ImageJustifyOffset.y = wxRound( ReadDouble( text ) * conv_scale);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
text++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( m_ImageJustifyXCenter )
|
||||||
|
m_ImageJustifyOffset.x = 0;
|
||||||
|
if( m_ImageJustifyYCenter )
|
||||||
|
m_ImageJustifyOffset.y = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
case KNOCKOUT:
|
case KNOCKOUT:
|
||||||
msg.Printf( _( "RS274X: Command \"%c%c\" ignored by Gerbview" ),
|
msg = _( "RS274X: Command KNOCKOUT ignored by Gerbview" ) ;
|
||||||
(command >> 8) & 0xFF, command & 0xFF );
|
ReportMessage( msg );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PLOTTER_FILM: // Command PF <string>
|
||||||
|
// This is an info about film that must be used to plot this file
|
||||||
|
// Has no meaning here. We just display this string
|
||||||
|
msg = ( "Plotter Film info:<br>" );
|
||||||
|
while( *text != '*' )
|
||||||
|
{
|
||||||
|
msg.Append( *text++ );
|
||||||
|
}
|
||||||
ReportMessage( msg );
|
ReportMessage( msg );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -498,10 +562,10 @@ bool GERBER_IMAGE::ExecuteRS274XCommand( int command,
|
||||||
m_FilesPtr++;
|
m_FilesPtr++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AP_MACRO:
|
case AP_MACRO: // lines like %AMMYMACRO*
|
||||||
|
// 5,1,8,0,0,1.08239X$1,22.5*
|
||||||
|
// %
|
||||||
ok = ReadApertureMacro( buff, text, m_Current_File );
|
ok = ReadApertureMacro( buff, text, m_Current_File );
|
||||||
if( !ok )
|
|
||||||
break;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AP_DEFINITION:
|
case AP_DEFINITION:
|
||||||
|
@ -729,24 +793,39 @@ bool GetEndOfBlock( char buff[GERBER_BUFZ], char*& text, FILE* gerber_file )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** function GetNextLine
|
||||||
static bool CheckForLineEnd( char buff[GERBER_BUFZ], char*& text, FILE* fp )
|
* test for an end of line
|
||||||
|
* if an end of line is found:
|
||||||
|
* read a new line
|
||||||
|
* @param aBuff[GERBER_BUFZ] = buffer to fill with a new line
|
||||||
|
* @param aText = pointer to the last useful char in aBuff
|
||||||
|
* on return: points the beginning of the next line.
|
||||||
|
* @param aFile = the opened GERBER file to read
|
||||||
|
* @return a pointer to the beginning of the next line or NULL if end of file
|
||||||
|
*/
|
||||||
|
static char* GetNextLine( char aBuff[GERBER_BUFZ], char* aText, FILE* aFile )
|
||||||
{
|
{
|
||||||
while( *text == '\n' || *text == '\r' || !*text )
|
for( ; ; )
|
||||||
{
|
{
|
||||||
if( *text == '\n' || *text == '\r' )
|
switch (*aText )
|
||||||
++text;
|
|
||||||
|
|
||||||
if( !*text )
|
|
||||||
{
|
{
|
||||||
if( fgets( buff, GERBER_BUFZ, fp ) == NULL )
|
case ' ': // skip blanks
|
||||||
return false;
|
case '\n':
|
||||||
|
case '\r': // Skip line terminators
|
||||||
|
++aText;
|
||||||
|
break;
|
||||||
|
|
||||||
text = buff;
|
case 0: // End of text found in aBuff: Read a new string
|
||||||
|
if( fgets( aBuff, GERBER_BUFZ, aFile ) == NULL )
|
||||||
|
return NULL;
|
||||||
|
aText = aBuff;
|
||||||
|
return aText;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return aText;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return aText;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -769,24 +848,28 @@ bool GERBER_IMAGE::ReadApertureMacro( char buff[GERBER_BUFZ],
|
||||||
am.name.Append( *text++ );
|
am.name.Append( *text++ );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Read aperture macro parameters
|
||||||
for( ; ; )
|
for( ; ; )
|
||||||
{
|
{
|
||||||
AM_PRIMITIVE prim( m_GerbMetric );
|
|
||||||
|
|
||||||
if( *text == '*' )
|
if( *text == '*' )
|
||||||
++text;
|
++text;
|
||||||
|
|
||||||
if( !CheckForLineEnd( buff, text, gerber_file ) )
|
text = GetNextLine( buff, text, gerber_file ); // Get next line
|
||||||
|
if( text == NULL ) // End of File
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// text points the beginning of a new line.
|
||||||
|
|
||||||
|
// Test for the last line in aperture macro lis:
|
||||||
|
// last line is % or *% sometime found.
|
||||||
|
if( *text == '*' )
|
||||||
|
++text;
|
||||||
if( *text == '%' )
|
if( *text == '%' )
|
||||||
break; // exit with text still pointing at %
|
break; // exit with text still pointing at %
|
||||||
|
|
||||||
prim.primitive_id = (AM_PRIMITIVE_ID) ReadInt( text );
|
int paramCount = 0;
|
||||||
|
int primitive_type = ReadInt( text );
|
||||||
int paramCount;
|
switch( primitive_type )
|
||||||
|
|
||||||
switch( prim.primitive_id )
|
|
||||||
{
|
{
|
||||||
case AMP_CIRCLE:
|
case AMP_CIRCLE:
|
||||||
paramCount = 4;
|
paramCount = 4;
|
||||||
|
@ -823,30 +906,26 @@ bool GERBER_IMAGE::ReadApertureMacro( char buff[GERBER_BUFZ],
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
||||||
// @todo, there needs to be a way of reporting the line number
|
// @todo, there needs to be a way of reporting the line number
|
||||||
msg.Printf( wxT( "RS274X: Invalid primitive id code %d\n" ), prim.primitive_id );
|
msg.Printf( wxT( "RS274X: Aperture Macro \"%s\": Invalid primitive id code %d, line: \"%s\"" ),
|
||||||
|
GetChars(am.name), primitive_type, CONV_FROM_UTF8(buff) );
|
||||||
ReportMessage( msg );
|
ReportMessage( msg );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AM_PRIMITIVE prim( m_GerbMetric );
|
||||||
|
prim.primitive_id = (AM_PRIMITIVE_ID) primitive_type;
|
||||||
int i;
|
int i;
|
||||||
for( i = 0; i < paramCount && *text != '*'; ++i )
|
for( i = 0; i < paramCount && *text && *text != '*'; ++i )
|
||||||
{
|
{
|
||||||
prim.params.push_back( DCODE_PARAM() );
|
prim.params.push_back( DCODE_PARAM() );
|
||||||
|
|
||||||
DCODE_PARAM& param = prim.params.back();
|
DCODE_PARAM& param = prim.params.back();
|
||||||
|
|
||||||
if( !CheckForLineEnd( buff, text, gerber_file ) )
|
text = GetNextLine( buff, text, gerber_file );
|
||||||
|
if( text == NULL) // End of File
|
||||||
return false;
|
return false;
|
||||||
|
ReadMacroParam( param, text );
|
||||||
if( *text == '$' )
|
|
||||||
{
|
|
||||||
++text;
|
|
||||||
param.SetIndex( ReadInt( text ) );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
param.SetValue( ReadDouble( text ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( i < paramCount )
|
if( i < paramCount )
|
||||||
|
@ -856,6 +935,7 @@ bool GERBER_IMAGE::ReadApertureMacro( char buff[GERBER_BUFZ],
|
||||||
"RS274X: read macro descr type %d: read %d parameters, insufficient parameters\n" ),
|
"RS274X: read macro descr type %d: read %d parameters, insufficient parameters\n" ),
|
||||||
prim.primitive_id, i );
|
prim.primitive_id, i );
|
||||||
ReportMessage( msg );
|
ReportMessage( msg );
|
||||||
|
|
||||||
}
|
}
|
||||||
// there are more parameters to read if this is an AMP_OUTLINE
|
// there are more parameters to read if this is an AMP_OUTLINE
|
||||||
if( prim.primitive_id == AMP_OUTLINE )
|
if( prim.primitive_id == AMP_OUTLINE )
|
||||||
|
@ -875,16 +955,10 @@ bool GERBER_IMAGE::ReadApertureMacro( char buff[GERBER_BUFZ],
|
||||||
|
|
||||||
DCODE_PARAM& param = prim.params.back();
|
DCODE_PARAM& param = prim.params.back();
|
||||||
|
|
||||||
if( !CheckForLineEnd( buff, text, gerber_file ) )
|
text = GetNextLine( buff, text, gerber_file );
|
||||||
|
if( text == NULL ) // End of File
|
||||||
return false;
|
return false;
|
||||||
|
ReadMacroParam( param, text );
|
||||||
if( *text == '$' )
|
|
||||||
{
|
|
||||||
++text;
|
|
||||||
param.SetIndex( ReadInt( text ) );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
param.SetValue( ReadDouble( text ) );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -895,3 +969,37 @@ bool GERBER_IMAGE::ReadApertureMacro( char buff[GERBER_BUFZ],
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Function ReadMacroParam
|
||||||
|
* Read one aperture macro parameter
|
||||||
|
* a parameter can be:
|
||||||
|
* a number
|
||||||
|
* a reference to an aperture definition parameter value: $1 ot $3 ...
|
||||||
|
* a parameter definition can be complex and have operators between numbers and/or other parameter
|
||||||
|
* like $1+3 or $2x2..
|
||||||
|
* Parameters are separated by a comma ( of finish by *)
|
||||||
|
* Return if a param is read, or false
|
||||||
|
*/
|
||||||
|
static bool ReadMacroParam( DCODE_PARAM& aParam, char*& aText )
|
||||||
|
{
|
||||||
|
bool found = false;
|
||||||
|
if( *aText == '$' ) // value defined later, in aperture description
|
||||||
|
{
|
||||||
|
++aText;
|
||||||
|
aParam.SetIndex( ReadInt( aText, false ) );
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
aParam.SetValue( ReadDouble( aText, false ) );
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip extra characters and separator
|
||||||
|
while( *aText && (*aText != ',') && (*aText != '*') )
|
||||||
|
aText++;
|
||||||
|
if( *aText == ',' )
|
||||||
|
aText++;
|
||||||
|
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue