From 7fbeb899abccb72350a7da35bf3abffb59297f2f Mon Sep 17 00:00:00 2001 From: Dick Hollenbeck Date: Tue, 11 May 2010 11:35:40 -0500 Subject: [PATCH] initial work on Bug 578577, partial fix --- gerbview/rs274d.cpp | 443 +++++++++++++++++++++++--------------------- gerbview/rs274x.cpp | 44 +++-- 2 files changed, 265 insertions(+), 222 deletions(-) diff --git a/gerbview/rs274d.cpp b/gerbview/rs274d.cpp index a7f5d1e713..73285eac6b 100644 --- a/gerbview/rs274d.cpp +++ b/gerbview/rs274d.cpp @@ -1180,225 +1180,246 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame, break; case APT_MACRO: - { - APERTURE_MACRO* macro = tool->GetMacro(); - wxASSERT( macro ); - - // split the macro primitives up into multiple normal TRACK - // elements - for( AM_PRIMITIVES::iterator p = macro->primitives.begin(); - p!=macro->primitives.end(); - ++p ) { - bool exposure; - wxPoint curPos = m_CurrentPos; + APERTURE_MACRO* macro = tool->GetMacro(); + wxASSERT( macro ); - switch( p->primitive_id ) + // split the macro primitives up into multiple normal TRACK + // elements + for( AM_PRIMITIVES::iterator p = macro->primitives.begin(); + p!=macro->primitives.end(); + ++p ) { - case AMP_CIRCLE: - { - exposure = mapExposure( p->GetExposure(), m_Exposure, - m_ImageNegative ); - curPos += mapPt( p->params[2].GetValue( tool ), - p->params[3].GetValue( tool ), - m_GerbMetric ); - int diameter = scale( p->params[1].GetValue( tool ), - m_GerbMetric ); + bool exposure; + wxPoint curPos = m_CurrentPos; - track = new TRACK( pcb ); - pcb->m_Track.Append( track ); - D( printf( "R:%p\n", track ); ) - fillRoundFlashTRACK( track, dcode, activeLayer, - m_CurrentPos, diameter, exposure ); - } - break; - - case AMP_LINE2: - case AMP_LINE20: - { - exposure = mapExposure( - p->GetExposure(), m_Exposure, m_ImageNegative ); - int width = scale( p->params[1].GetValue( tool ), - m_GerbMetric ); - wxPoint start = mapPt( p->params[2].GetValue( tool ), - p->params[3].GetValue( tool ), - m_GerbMetric ); - wxPoint end = mapPt( p->params[4].GetValue( tool ), - p->params[5].GetValue( tool ), - m_GerbMetric ); - - if( start.x == end.x ) + switch( p->primitive_id ) { - size.x = width; - size.y = ABS( end.y - start.y ) + 1; + case AMP_CIRCLE: + { + exposure = mapExposure( p->GetExposure(), m_Exposure, + m_ImageNegative ); + curPos += mapPt( p->params[2].GetValue( tool ), + p->params[3].GetValue( tool ), + m_GerbMetric ); + int diameter = scale( p->params[1].GetValue( tool ), + m_GerbMetric ); + + track = new TRACK( pcb ); + pcb->m_Track.Append( track ); + D( printf( "R:%p\n", track ); ) + fillRoundFlashTRACK( track, dcode, activeLayer, + m_CurrentPos, diameter, exposure ); + } + break; + + case AMP_LINE2: + case AMP_LINE20: + { + exposure = mapExposure( + p->GetExposure(), m_Exposure, m_ImageNegative ); + int width = scale( p->params[1].GetValue( tool ), + m_GerbMetric ); + wxPoint start = mapPt( p->params[2].GetValue( tool ), + p->params[3].GetValue( tool ), + m_GerbMetric ); + wxPoint end = mapPt( p->params[4].GetValue( tool ), + p->params[5].GetValue( tool ), + m_GerbMetric ); + + if( start.x == end.x ) + { + size.x = width; + size.y = ABS( end.y - start.y ) + 1; + } + else + { + size.x = ABS( end.x - start.x ) + 1; + size.y = width; + } + + wxPoint midPoint( ( start.x + end.x ) / 2, + ( start.y + end.y ) / 2 ); + curPos += midPoint; + track = new TRACK( pcb ); + pcb->m_Track.Append( track ); + D( printf( "R:%p\n", track ); ) + fillOvalOrRectFlashTRACK( track, dcode, activeLayer, + curPos, size, S_SPOT_RECT, + exposure ); + } + break; + + case AMP_LINE_CENTER: + { + exposure = mapExposure( p->GetExposure(), m_Exposure, + m_ImageNegative ); + wxPoint msize = mapPt( p->params[1].GetValue( tool ), + p->params[2].GetValue( tool ), + m_GerbMetric ); + size.x = msize.x; + size.y = msize.y; + curPos += mapPt( p->params[3].GetValue( tool ), + p->params[4].GetValue( tool ), + m_GerbMetric ); + track = new TRACK( pcb ); + pcb->m_Track.Append( track ); + D( printf( "R:%p\n", track ); ) + fillOvalOrRectFlashTRACK( track, dcode, activeLayer, + curPos, size, S_SPOT_RECT, + exposure ); + } + break; + + case AMP_LINE_LOWER_LEFT: + { + exposure = mapExposure( + p->GetExposure(), m_Exposure, m_ImageNegative ); + wxPoint msize = mapPt( p->params[1].GetValue( tool ), + p->params[2].GetValue( tool ), + m_GerbMetric ); + size.x = msize.x; + size.y = msize.y; + wxPoint lowerLeft = mapPt( p->params[3].GetValue( tool ), + p->params[4].GetValue( tool ), + m_GerbMetric ); + curPos += lowerLeft; + + // need the middle, so adjust from the lower left + curPos.y += size.y / 2; + curPos.x += size.x / 2; + track = new TRACK( pcb ); + pcb->m_Track.Append( track ); + D( printf( "R:%p\n", track ); ) + fillOvalOrRectFlashTRACK( track, dcode, activeLayer, + curPos, size, S_SPOT_RECT, + exposure ); + } + break; + + case AMP_THERMAL: + { + int outerDiam = scale( p->params[2].GetValue( tool ), + m_GerbMetric ); + int innerDiam = scale( p->params[3].GetValue( tool ), + m_GerbMetric ); + + curPos += mapPt( p->params[0].GetValue( tool ), + p->params[1].GetValue( tool ), + m_GerbMetric ); + + track = new TRACK( pcb ); + pcb->m_Track.Append( track ); + D( printf( "R:%p\n", track ); ) + fillRoundFlashTRACK( track, dcode, activeLayer, + curPos, outerDiam, + !( m_LayerNegative ^ m_ImageNegative ) ); + + track = new TRACK( pcb ); + pcb->m_Track.Append( track ); + D( printf( "R:%p\n", track ); ) + fillRoundFlashTRACK( track, dcode, activeLayer, curPos, + innerDiam, + ( m_LayerNegative ^ m_ImageNegative ) ); + + // @todo: draw the cross hairs, see page 23 of rs274 + // spec. this might be done with two lines, thickness + // from params[4], and drawing + // darkness "(m_LayerNegative ^ m_ImageNegative)" + } + break; + + case AMP_MOIRE: + { + curPos += mapPt( p->params[0].GetValue( tool ), + p->params[1].GetValue( tool ), + m_GerbMetric ); + + // e.g.: "6,0,0,0.125,.01,0.01,3,0.003,0.150,0" + int outerDiam = scale( p->params[2].GetValue( tool ), + m_GerbMetric ); + int penThickness = scale( p->params[3].GetValue( tool ), + m_GerbMetric ); + int gap = scale( p->params[4].GetValue( tool ), + m_GerbMetric ); + int numCircles = (int) p->params[5].GetValue( tool ); + int crossHairThickness = + scale( p->params[6].GetValue( tool ), m_GerbMetric ); + int crossHairLength = + scale( p->params[7].GetValue( tool ), m_GerbMetric ); + + // ignore rotation, not supported + // adjust outerDiam by this on each nested circle + int diamAdjust = 2 * (gap + penThickness); + for( int i = 0; + i < numCircles; + ++i, outerDiam -= diamAdjust ) + { + track = new TRACK( pcb ); + pcb->m_Track.Append( track ); + D( printf( "R:%p\n", track ); ) + fillCircularTRACK( track, dcode, activeLayer, + curPos, outerDiam, + penThickness, + !( m_LayerNegative ^ m_ImageNegative ) ); + } + + track = new TRACK( pcb ); + pcb->m_Track.Append( track ); + D( printf( "R:%p\n", track ); ) + fillOvalOrRectFlashTRACK( track, dcode, activeLayer, + curPos, + wxSize( crossHairThickness, + crossHairLength ), + S_SPOT_RECT, + !( m_LayerNegative ^ m_ImageNegative ) ); + + track = new TRACK( pcb ); + pcb->m_Track.Append( track ); + D( printf( "R:%p\n", track ); ) + + // swap x and y in wxSize() for this one + fillOvalOrRectFlashTRACK( track, dcode, activeLayer, + curPos, + wxSize( crossHairLength, + crossHairThickness ), + S_SPOT_RECT, + !( m_LayerNegative ^ m_ImageNegative ) ); + } + break; + + case AMP_OUTLINE: +#if defined(DEBUG) + { + int numPoints = (int) p->params[1].GetValue( tool ); + + printf( "AMP_OUTLINE:\n" ); + printf( " exposure: %g\n", p->params[0].GetValue( tool ) ); + printf( " # points: %d\n", numPoints ); + + // numPoints does not include the starting point, so add 1. + for( int i=0; iparams[i*2+2+0].GetValue( tool ), + p->params[i*2+2+1].GetValue( tool ) + ); + } + printf( " rotation: %g\n", p->params[numPoints*2+4].GetValue( tool ) ); + } +#endif + break; + + case AMP_POLYGON: + case AMP_EOF: + default: + + // not yet supported, waiting for you. + break; } - else - { - size.x = ABS( end.x - start.x ) + 1; - size.y = width; - } - - wxPoint midPoint( ( start.x + end.x ) / 2, - ( start.y + end.y ) / 2 ); - curPos += midPoint; - track = new TRACK( pcb ); - pcb->m_Track.Append( track ); - D( printf( "R:%p\n", track ); ) - fillOvalOrRectFlashTRACK( track, dcode, activeLayer, - curPos, size, S_SPOT_RECT, - exposure ); - } - break; - - case AMP_LINE_CENTER: - { - exposure = mapExposure( p->GetExposure(), m_Exposure, - m_ImageNegative ); - wxPoint msize = mapPt( p->params[1].GetValue( tool ), - p->params[2].GetValue( tool ), - m_GerbMetric ); - size.x = msize.x; - size.y = msize.y; - curPos += mapPt( p->params[3].GetValue( tool ), - p->params[4].GetValue( tool ), - m_GerbMetric ); - track = new TRACK( pcb ); - pcb->m_Track.Append( track ); - D( printf( "R:%p\n", track ); ) - fillOvalOrRectFlashTRACK( track, dcode, activeLayer, - curPos, size, S_SPOT_RECT, - exposure ); - } - break; - - case AMP_LINE_LOWER_LEFT: - { - exposure = mapExposure( - p->GetExposure(), m_Exposure, m_ImageNegative ); - wxPoint msize = mapPt( p->params[1].GetValue( tool ), - p->params[2].GetValue( tool ), - m_GerbMetric ); - size.x = msize.x; - size.y = msize.y; - wxPoint lowerLeft = mapPt( p->params[3].GetValue( tool ), - p->params[4].GetValue( tool ), - m_GerbMetric ); - curPos += lowerLeft; - - // need the middle, so adjust from the lower left - curPos.y += size.y / 2; - curPos.x += size.x / 2; - track = new TRACK( pcb ); - pcb->m_Track.Append( track ); - D( printf( "R:%p\n", track ); ) - fillOvalOrRectFlashTRACK( track, dcode, activeLayer, - curPos, size, S_SPOT_RECT, - exposure ); - } - break; - - case AMP_THERMAL: - { - int outerDiam = scale( p->params[2].GetValue( tool ), - m_GerbMetric ); - int innerDiam = scale( p->params[3].GetValue( tool ), - m_GerbMetric ); - - curPos += mapPt( p->params[0].GetValue( tool ), - p->params[1].GetValue( tool ), - m_GerbMetric ); - - track = new TRACK( pcb ); - pcb->m_Track.Append( track ); - D( printf( "R:%p\n", track ); ) - fillRoundFlashTRACK( track, dcode, activeLayer, - curPos, outerDiam, - !( m_LayerNegative ^ m_ImageNegative ) ); - - track = new TRACK( pcb ); - pcb->m_Track.Append( track ); - D( printf( "R:%p\n", track ); ) - fillRoundFlashTRACK( track, dcode, activeLayer, curPos, - innerDiam, - ( m_LayerNegative ^ m_ImageNegative ) ); - - // @todo: draw the cross hairs, see page 23 of rs274 - // spec. this might be done with two lines, thickness - // from params[4], and drawing - // darkness "(m_LayerNegative ^ m_ImageNegative)" - } - break; - - case AMP_MOIRE: - { - curPos += mapPt( p->params[0].GetValue( tool ), - p->params[1].GetValue( tool ), - m_GerbMetric ); - - // e.g.: "6,0,0,0.125,.01,0.01,3,0.003,0.150,0" - int outerDiam = scale( p->params[2].GetValue( tool ), - m_GerbMetric ); - int penThickness = scale( p->params[3].GetValue( tool ), - m_GerbMetric ); - int gap = scale( p->params[4].GetValue( tool ), - m_GerbMetric ); - int numCircles = (int) p->params[5].GetValue( tool ); - int crossHairThickness = - scale( p->params[6].GetValue( tool ), m_GerbMetric ); - int crossHairLength = - scale( p->params[7].GetValue( tool ), m_GerbMetric ); - - // ignore rotation, not supported - // adjust outerDiam by this on each nested circle - int diamAdjust = 2 * (gap + penThickness); - for( int i = 0; - i < numCircles; - ++i, outerDiam -= diamAdjust ) - { - track = new TRACK( pcb ); - pcb->m_Track.Append( track ); - D( printf( "R:%p\n", track ); ) - fillCircularTRACK( track, dcode, activeLayer, - curPos, outerDiam, - penThickness, - !( m_LayerNegative ^ m_ImageNegative ) ); - } - - track = new TRACK( pcb ); - pcb->m_Track.Append( track ); - D( printf( "R:%p\n", track ); ) - fillOvalOrRectFlashTRACK( track, dcode, activeLayer, - curPos, - wxSize( crossHairThickness, - crossHairLength ), - S_SPOT_RECT, - !( m_LayerNegative ^ m_ImageNegative ) ); - - track = new TRACK( pcb ); - pcb->m_Track.Append( track ); - D( printf( "R:%p\n", track ); ) - - // swap x and y in wxSize() for this one - fillOvalOrRectFlashTRACK( track, dcode, activeLayer, - curPos, - wxSize( crossHairLength, - crossHairThickness ), - S_SPOT_RECT, - !( m_LayerNegative ^ m_ImageNegative ) ); - } - break; - - case AMP_EOF: - case AMP_OUTLINE: - case AMP_POLYGON: - default: - - // not yet supported, waiting for you. - break; } } - } - break; + break; default: break; diff --git a/gerbview/rs274x.cpp b/gerbview/rs274x.cpp index ad43830eaf..72f97fb7ae 100644 --- a/gerbview/rs274x.cpp +++ b/gerbview/rs274x.cpp @@ -535,6 +535,26 @@ bool GetEndOfBlock( char buff[GERBER_BUFZ], char*& text, FILE* gerber_file ) } +static bool CheckForLineEnd( char buff[GERBER_BUFZ], char*& text, FILE* fp ) +{ + while( *text == '\n' || !*text ) + { + if( *text == '\n' ) + ++text; + + if( !*text ) + { + if( fgets( buff, GERBER_BUFZ, fp ) == NULL ) + return false; + + text = buff; + } + } + + return true; +} + + bool GERBER::ReadApertureMacro( char buff[GERBER_BUFZ], char*& text, FILE* gerber_file ) @@ -563,15 +583,8 @@ bool GERBER::ReadApertureMacro( char buff[GERBER_BUFZ], if( *text == '*' ) ++text; - if( *text == '\n' ) - ++text; - - if( !*text ) - { - text = buff; - if( fgets( buff, GERBER_BUFZ, gerber_file ) == NULL ) - return false; - } + if( !CheckForLineEnd( buff, text, gerber_file ) ) + return false; if( *text == '%' ) break; // exit with text still pointing at % @@ -625,12 +638,15 @@ bool GERBER::ReadApertureMacro( char buff[GERBER_BUFZ], } int i; - for( i = 0; i < paramCount && *text && *text != '*'; ++i ) + for( i = 0; i < paramCount && *text != '*'; ++i ) { prim.params.push_back( DCODE_PARAM() ); DCODE_PARAM& param = prim.params.back(); + if( !CheckForLineEnd( buff, text, gerber_file ) ) + return false; + if( *text == '$' ) { ++text; @@ -647,18 +663,24 @@ bool GERBER::ReadApertureMacro( char buff[GERBER_BUFZ], // there are more parameters to read if this is an AMP_OUTLINE if( prim.primitive_id == AMP_OUTLINE ) { + // so far we have read [0]:exposure, [1]:#points, [2]:X start, [3]: Y start + // Now read all the points, plus trailing rotation in degrees. + // params[1] is a count of polygon points, so it must be given // in advance, i.e. be immediate. wxASSERT( prim.params[1].IsImmediate() ); paramCount = (int) prim.params[1].GetValue( 0 ) * 2 + 1; - for( int i = 0; i < paramCount && *text && *text != '*'; ++i ) + for( int i = 0; i < paramCount && *text != '*'; ++i ) { prim.params.push_back( DCODE_PARAM() ); DCODE_PARAM& param = prim.params.back(); + if( !CheckForLineEnd( buff, text, gerber_file ) ) + return false; + if( *text == '$' ) { ++text;