Commit bc0d79d5 authored by jean-pierre charras's avatar jean-pierre charras

finished Draw functions for aperture macros. Now aperture macros are drawn correctly.

 Known bug: aperture macros having parameters are incorrect: parameters are not transmited correctly. Work still in progress.
parent e0617666
...@@ -4,6 +4,14 @@ KiCad ChangeLog 2010 ...@@ -4,6 +4,14 @@ KiCad ChangeLog 2010
Please add newer entries at the top, list the date and your name with Please add newer entries at the top, list the date and your name with
email address. email address.
2010-oct-03, UPDATE Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
================================================================================
++gerbview:
finished Draw functions for aperture macros.
Now aperture macros are draww correctly.
Known bug: aperture macros having parameters are incorrect: parameters are not transmited correctly.
Work still in progress.
2010-sept-28, UPDATE Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr> 2010-sept-28, UPDATE Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
================================================================================ ================================================================================
++gerbview: ++gerbview:
......
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
* @return wxPoint - The gerbview coordinate system vector. * @return wxPoint - The gerbview coordinate system vector.
*/ */
extern wxPoint mapPt( double x, double y, bool isMetric ); // defined it rs274d.cpp extern wxPoint mapPt( double x, double y, bool isMetric ); // defined it rs274d.cpp
/** /**
* Function scale * Function scale
* converts a distance given in floating point to our deci-mils * converts a distance given in floating point to our deci-mils
...@@ -47,13 +48,80 @@ extern wxPoint mapPt( double x, double y, bool isMetric ); // defined it rs274d ...@@ -47,13 +48,80 @@ extern wxPoint mapPt( double x, double y, bool isMetric ); // defined it rs274d
extern int scale( double aCoord, bool isMetric ); // defined it rs274d.cpp extern int scale( double aCoord, bool isMetric ); // defined it rs274d.cpp
/**
* Function mapExposure
* translates the first parameter from an aperture macro into a current
* exposure setting.
* @param aParent = a GERBER_DRAW_ITEM that handle:
* ** m_Exposure A dynamic setting which can change throughout the
* reading of the gerber file, and it indicates whether the current tool
* is lit or not.
* ** m_ImageNegative A dynamic setting which can change throughout the reading
* of the gerber file, and it indicates whether the current D codes are to
* be interpreted as erasures or not.
* @return true to draw with current color, false to draw with alt color (erase)
*/
bool AM_PRIMITIVE::mapExposure( GERBER_DRAW_ITEM* aParent )
{
bool exposure;
switch( primitive_id )
{
case AMP_CIRCLE:
case AMP_LINE2:
case AMP_LINE20:
case AMP_LINE_CENTER:
case AMP_LINE_LOWER_LEFT:
case AMP_OUTLINE:
case AMP_THERMAL:
case AMP_POLYGON:
// All have an exposure parameter and can return true or false
switch( GetExposure() )
{
case 0: // exposure always OFF
exposure = false;
break;
default:
case 1: // exposure always OON
exposure = true;
break;
case 2: // reverse exposure
exposure = !aParent->m_LayerNegative;
}
break;
case AMP_MOIRE:
case AMP_EOF:
case AMP_UNKNOWN:
default:
return true; // All have no exposure parameter and must return true (no change for exposure)
break;
}
return exposure ^ aParent->m_ImageNegative;
}
/**
* Function GetExposure
* returns the first parameter in integer form. Some but not all primitives
* use the first parameter as an exposure control.
*/
int AM_PRIMITIVE::GetExposure() const
{
// No D_CODE* for GetValue()
wxASSERT( params.size() && params[0].IsImmediate() );
return (int) params[0].GetValue( NULL );
}
/** function DrawBasicShape /** function DrawBasicShape
* Draw the primitive shape for flashed items. * Draw the primitive shape for flashed items.
*/ */
void AM_PRIMITIVE::DrawBasicShape( GERBER_DRAW_ITEM* aParent, void AM_PRIMITIVE::DrawBasicShape( GERBER_DRAW_ITEM* aParent,
EDA_Rect* aClipBox, EDA_Rect* aClipBox,
wxDC* aDC, wxDC* aDC,
int aColor, int aColor, int aAltColor,
wxPoint aShapePos, wxPoint aShapePos,
bool aFilledShape ) bool aFilledShape )
{ {
...@@ -63,6 +131,12 @@ void AM_PRIMITIVE::DrawBasicShape( GERBER_DRAW_ITEM* aParent, ...@@ -63,6 +131,12 @@ void AM_PRIMITIVE::DrawBasicShape( GERBER_DRAW_ITEM* aParent,
wxPoint curPos = aShapePos; wxPoint curPos = aShapePos;
D_CODE* tool = aParent->GetDcodeDescr(); D_CODE* tool = aParent->GetDcodeDescr();
bool gerberMetric = aParent->m_UnitsMetric; bool gerberMetric = aParent->m_UnitsMetric;
int rotation;
if( mapExposure( aParent ) == false )
{
EXCHG(aColor, aAltColor);
}
switch( primitive_id ) switch( primitive_id )
{ {
case AMP_CIRCLE: // Circle, given diameter and position case AMP_CIRCLE: // Circle, given diameter and position
...@@ -70,9 +144,8 @@ void AM_PRIMITIVE::DrawBasicShape( GERBER_DRAW_ITEM* aParent, ...@@ -70,9 +144,8 @@ void AM_PRIMITIVE::DrawBasicShape( GERBER_DRAW_ITEM* aParent,
/* Generated by an aperture macro declaration like: /* Generated by an aperture macro declaration like:
* "1,1,0.3,0.5, 1.0*" * "1,1,0.3,0.5, 1.0*"
* type (1), exposure, diameter, pos.x, pos.y * type (1), exposure, diameter, pos.x, pos.y
* type is not stored in parameters list, so the first parameter is pos.x * type is not stored in parameters list, so the first parameter is exposure
*/ */
int exposure = params[0].GetValue( tool );
curPos += mapPt( params[2].GetValue( tool ), params[3].GetValue( tool ), gerberMetric ); curPos += mapPt( params[2].GetValue( tool ), params[3].GetValue( tool ), gerberMetric );
int radius = scale( params[1].GetValue( tool ), gerberMetric ) / 2; int radius = scale( params[1].GetValue( tool ), gerberMetric ) / 2;
if( !aFilledShape ) if( !aFilledShape )
...@@ -88,22 +161,24 @@ void AM_PRIMITIVE::DrawBasicShape( GERBER_DRAW_ITEM* aParent, ...@@ -88,22 +161,24 @@ void AM_PRIMITIVE::DrawBasicShape( GERBER_DRAW_ITEM* aParent,
/* Generated by an aperture macro declaration like: /* Generated by an aperture macro declaration like:
* "2,1,0.3,0,0, 0.5, 1.0,-135*" * "2,1,0.3,0,0, 0.5, 1.0,-135*"
* type (2), exposure, width, start.x, start.y, end.x, end.y, rotation * type (2), exposure, width, start.x, start.y, end.x, end.y, rotation
* type is not stored in parameters list, so the first parameter is pos.x * type is not stored in parameters list, so the first parameter is exposure
*/ */
int exposure = params[0].GetValue( tool ); ConvertShapeToPolygon( aParent, polybuffer, gerberMetric );
ConvertShapeToPolygon(aParent, polybuffer, gerberMetric);
// shape rotation: // shape rotation:
int rotation = wxRound(params[6].GetValue( tool ) * 10.0); rotation = wxRound( params[6].GetValue( tool ) * 10.0 );
if (rotation) if( rotation )
{ {
for( unsigned ii = 0; ii < polybuffer.size(); ii++ ) for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
RotatePoint(&polybuffer[ii], rotation); RotatePoint( &polybuffer[ii], rotation );
} }
// Move to current position: // Move to current position:
for( unsigned ii = 0; ii < polybuffer.size(); ii++ ) for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
polybuffer[ii] += curPos; polybuffer[ii] += curPos;
GRClosedPoly( aClipBox, aDC, polybuffer.size(), &polybuffer[0], aFilledShape, aColor, aColor ); GRClosedPoly( aClipBox, aDC,
polybuffer.size(), &polybuffer[0], aFilledShape, aColor, aColor );
} }
break; break;
...@@ -112,21 +187,24 @@ void AM_PRIMITIVE::DrawBasicShape( GERBER_DRAW_ITEM* aParent, ...@@ -112,21 +187,24 @@ void AM_PRIMITIVE::DrawBasicShape( GERBER_DRAW_ITEM* aParent,
/* Generated by an aperture macro declaration like: /* Generated by an aperture macro declaration like:
* "21,1,0.3,0.03,0,0,-135*" * "21,1,0.3,0.03,0,0,-135*"
* type (21), exposure, ,width, height, center pos.x, center pos.y, rotation * type (21), exposure, ,width, height, center pos.x, center pos.y, rotation
* type is not stored in parameters list, so the first parameter is pos.x * type is not stored in parameters list, so the first parameter is exposure
*/ */
int exposure = params[0].GetValue( tool ); ConvertShapeToPolygon( aParent, polybuffer, gerberMetric );
ConvertShapeToPolygon(aParent, polybuffer, gerberMetric);
// shape rotation: // shape rotation:
int rotation = wxRound(params[5].GetValue( tool ) * 10.0); rotation = wxRound( params[5].GetValue( tool ) * 10.0 );
if (rotation) if( rotation )
{ {
for( unsigned ii = 0; ii < polybuffer.size(); ii++ ) for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
RotatePoint(&polybuffer[ii], rotation); RotatePoint( &polybuffer[ii], rotation );
} }
// Move to current position: // Move to current position:
for( unsigned ii = 0; ii < polybuffer.size(); ii++ ) for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
polybuffer[ii] += curPos; polybuffer[ii] += curPos;
GRClosedPoly( aClipBox, aDC, polybuffer.size(), &polybuffer[0], aFilledShape, aColor, aColor );
GRClosedPoly( aClipBox, aDC,
polybuffer.size(), &polybuffer[0], aFilledShape, aColor, aColor );
} }
break; break;
...@@ -135,44 +213,64 @@ void AM_PRIMITIVE::DrawBasicShape( GERBER_DRAW_ITEM* aParent, ...@@ -135,44 +213,64 @@ void AM_PRIMITIVE::DrawBasicShape( GERBER_DRAW_ITEM* aParent,
/* Generated by an aperture macro declaration like: /* Generated by an aperture macro declaration like:
* "22,1,0.3,0.03,0,0,-135*" * "22,1,0.3,0.03,0,0,-135*"
* type (22), exposure, ,width, height, corner pos.x, corner pos.y, rotation * type (22), exposure, ,width, height, corner pos.x, corner pos.y, rotation
* type is not stored in parameters list, so the first parameter is pos.x * type is not stored in parameters list, so the first parameter is exposure
*/ */
int exposure = params[0].GetValue( tool ); ConvertShapeToPolygon( aParent, polybuffer, gerberMetric );
ConvertShapeToPolygon(aParent, polybuffer, gerberMetric);
// shape rotation: // shape rotation:
int rotation = wxRound(params[5].GetValue( tool ) * 10.0); rotation = wxRound( params[5].GetValue( tool ) * 10.0 );
if (rotation) if( rotation )
{ {
for( unsigned ii = 0; ii < polybuffer.size(); ii++ ) for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
RotatePoint(&polybuffer[ii], rotation); RotatePoint( &polybuffer[ii], rotation );
} }
// Move to current position: // Move to current position:
for( unsigned ii = 0; ii < polybuffer.size(); ii++ ) for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
polybuffer[ii] += curPos; polybuffer[ii] += curPos;
GRClosedPoly( aClipBox, aDC, polybuffer.size(), &polybuffer[0], aFilledShape, aColor, aColor );
GRClosedPoly( aClipBox, aDC,
polybuffer.size(), &polybuffer[0], aFilledShape, aColor, aColor );
} }
break; break;
case AMP_THERMAL: case AMP_THERMAL:
{ {
/* Generated by an aperture macro declaration like: /* Generated by an aperture macro declaration like:
* "7,0,0,1.0,0.3,0.01,-13*" * "7, 0,0,1.0,0.3,0.01,-13*"
* type (7), center.x , center.y, outside diam, inside diam, crosshair thickness, rotation * type (7), center.x , center.y, outside diam, inside diam, crosshair thickness, rotation
* type is not stored in parameters list, so the first parameter is pos.x * type is not stored in parameters list, so the first parameter is center.x
*/ */
ConvertShapeToPolygon(aParent, polybuffer, gerberMetric); curPos += mapPt( params[0].GetValue( tool ), params[1].GetValue( tool ), gerberMetric );
/* int outerRadius = scale( params[2].GetValue( tool ), gerberMetric ) / 2;
if( !aFilledShape )
GRCircle( aClipBox, aDC, curPos.x, curPos.y, outerRadius, aColor );
else
GRFilledCircle( aClipBox, aDC, curPos, outerRadius, aColor );
*/
ConvertShapeToPolygon( aParent, polybuffer, gerberMetric );
// shape rotation: // shape rotation:
int rotation = wxRound(params[6].GetValue( tool ) * 10.0); rotation = wxRound( params[5].GetValue( tool ) * 10.0 );
if (rotation)
// Because a thermal shape has 4 identical sub-shapes, only one is created in polybuffer.
// We must draw 4 sub-shapes rotated by 90 deg
std::vector<wxPoint> subshape_poly;
for( int ii = 0; ii < 4; ii++ )
{ {
for( unsigned ii = 0; ii < polybuffer.size(); ii++ ) subshape_poly = polybuffer;
RotatePoint(&polybuffer[ii], rotation); int sub_rotation = rotation + 900 * ii;
} for( unsigned jj = 0; jj < subshape_poly.size(); jj++ )
RotatePoint( &subshape_poly[jj], sub_rotation );
// Move to current position: // Move to current position:
for( unsigned ii = 0; ii < polybuffer.size(); ii++ ) for( unsigned jj = 0; jj < subshape_poly.size(); jj++ )
polybuffer[ii] += curPos; subshape_poly[jj] += curPos;
GRClosedPoly( aClipBox, aDC, polybuffer.size(), &polybuffer[0], aFilledShape, aColor, aColor );
printf(" AMP_THERMAL %d\n",polybuffer.size()); GRClosedPoly( aClipBox, aDC,
subshape_poly.size(), &subshape_poly[0], true, aAltColor,
aAltColor );
}
} }
break; break;
...@@ -189,10 +287,10 @@ printf(" AMP_THERMAL %d\n",polybuffer.size()); ...@@ -189,10 +287,10 @@ printf(" AMP_THERMAL %d\n",polybuffer.size());
int outerDiam = scale( params[2].GetValue( tool ), gerberMetric ); int outerDiam = scale( params[2].GetValue( tool ), gerberMetric );
int penThickness = scale( params[3].GetValue( tool ), gerberMetric ); int penThickness = scale( params[3].GetValue( tool ), gerberMetric );
int gap = scale( params[4].GetValue( tool ), gerberMetric ); int gap = scale( params[4].GetValue( tool ), gerberMetric );
int numCircles = wxRound(params[5].GetValue( tool )); int numCircles = wxRound( params[5].GetValue( tool ) );
// adjust outerDiam by this on each nested circle // adjust outerDiam by this on each nested circle
int diamAdjust = (gap + penThickness);//*2; //Should we use * 2 ? int diamAdjust = (gap + penThickness); //*2; //Should we use * 2 ?
for( int i = 0; i < numCircles; ++i, outerDiam -= diamAdjust ) for( int i = 0; i < numCircles; ++i, outerDiam -= diamAdjust )
{ {
if( outerDiam <= 0 ) if( outerDiam <= 0 )
...@@ -200,62 +298,103 @@ printf(" AMP_THERMAL %d\n",polybuffer.size()); ...@@ -200,62 +298,103 @@ printf(" AMP_THERMAL %d\n",polybuffer.size());
if( !aFilledShape ) if( !aFilledShape )
{ {
// draw the border of the pen's path using two circles, each as narrow as possible // draw the border of the pen's path using two circles, each as narrow as possible
GRCircle( aClipBox, aDC, curPos.x, curPos.y, outerDiam/2, 0, aColor ); GRCircle( aClipBox, aDC, curPos.x, curPos.y, outerDiam / 2, 0, aColor );
GRCircle( aClipBox, aDC, curPos.x, curPos.y, outerDiam/2 - penThickness, 0, aColor ); GRCircle( aClipBox, aDC, curPos.x, curPos.y,
outerDiam / 2 - penThickness, 0, aColor );
} }
else // Filled mode else // Filled mode
{ {
GRCircle( aClipBox, aDC, curPos.x, curPos.y, (outerDiam-penThickness)/2, penThickness, aColor ); GRCircle( aClipBox, aDC, curPos.x, curPos.y,
(outerDiam - penThickness) / 2, penThickness, aColor );
} }
} }
// Draw the cross: // Draw the cross:
ConvertShapeToPolygon(aParent, polybuffer, gerberMetric); ConvertShapeToPolygon( aParent, polybuffer, gerberMetric );
// shape rotation: // shape rotation:
int rotation = wxRound(params[8].GetValue( tool ) * 10.0); rotation = wxRound( params[8].GetValue( tool ) * 10.0 );
if (rotation) if( rotation )
{ {
for( unsigned ii = 0; ii < polybuffer.size(); ii++ ) for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
RotatePoint(&polybuffer[ii], rotation); RotatePoint( &polybuffer[ii], rotation );
} }
// Move to current position: // Move to current position:
for( unsigned ii = 0; ii < polybuffer.size(); ii++ ) for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
polybuffer[ii] += curPos; polybuffer[ii] += curPos;
GRClosedPoly( aClipBox, aDC, polybuffer.size(), &polybuffer[0], aFilledShape, aColor, aColor );
GRClosedPoly( aClipBox, aDC,
polybuffer.size(), &polybuffer[0], aFilledShape, aColor, aColor );
} }
break; break;
case AMP_OUTLINE: case AMP_OUTLINE:
#if defined(DEBUG)
{ {
int exposure = params[0].GetValue( tool ); /* Generated by an aperture macro declaration like:
int numPoints = (int) this->params[1].GetValue( tool ); * "4,1,3,0.0,0.0,0.0,0.5,0.5,0.5,0.5,0.0,-25"
int rotation = wxRound(params[numPoints * 2 + 4].GetValue( tool ) * 10.0); * type(4), exposure, corners count, corner1.x, corner.1y, ..., rotation
* type is not stored in parameters list, so the first parameter is exposure
printf( "AMP_OUTLINE:\n" ); */
printf( " exposure: %g\n", exposure ); int numPoints = (int) params[1].GetValue( tool );
printf( " # points: %d\n", numPoints ); rotation = wxRound( params[numPoints * 2 + 4].GetValue( tool ) * 10.0 );
wxPoint pos;
// numPoints does not include the starting point, so add 1. // Read points. numPoints does not include the starting point, so add 1.
for( int i = 0; i<numPoints + 1; ++i ) for( int i = 0; i<numPoints + 1; ++i )
{ {
printf( " [%d]: X=%g Y=%g\n", i, int jj = i * 2 + 2;
this->params[i * 2 + 2 + 0].GetValue( tool ), pos.x = scale( params[jj].GetValue( tool ), gerberMetric );
this->params[i * 2 + 2 + 1].GetValue( tool ) pos.y = scale( params[jj + 1].GetValue( tool ), gerberMetric );
); polybuffer.push_back(pos);
}
// rotate polygon and move it to the actual position
// shape rotation:
for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
{
NEGATE(polybuffer[ii].y);
RotatePoint( &polybuffer[ii], rotation );
} }
printf( " rotation: %g\n", (float)rotation/10 ); // Move to current position:
for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
polybuffer[ii] += curPos;
GRClosedPoly( aClipBox, aDC,
polybuffer.size(), &polybuffer[0], aFilledShape, aColor, aColor );
} }
#endif
break; break;
case AMP_UNKNOWN: case AMP_POLYGON: // Is a regular polygon
case AMP_POLYGON: /* Generated by an aperture macro declaration like:
case AMP_EOF: * "5,1,0.6,0,0,0.5,25"
default: * type(5), exposure, vertices count, pox.x, pos.y, diameter, rotation
* type is not stored in parameters list, so the first parameter is exposure
*/
curPos += mapPt( params[2].GetValue( tool ), params[3].GetValue( tool ),
gerberMetric );
// Creates the shape:
ConvertShapeToPolygon( aParent, polybuffer, gerberMetric );
// rotate polygon and move it to the actual position
rotation = wxRound( params[5].GetValue( tool ) * 10.0 );
for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
{
NEGATE(polybuffer[ii].y);
RotatePoint( &polybuffer[ii], rotation );
polybuffer[ii] += curPos;
}
GRClosedPoly( aClipBox, aDC,
polybuffer.size(), &polybuffer[0], aFilledShape, aColor, aColor );
break;
case AMP_EOF:
// not yet supported, waiting for you. // not yet supported, waiting for you.
break; break;
case AMP_UNKNOWN:
default:
D( printf( "AM_PRIMITIVE::DrawBasicShape() err: unknown prim id %d\n",primitive_id) );
break;
} }
} }
...@@ -269,9 +408,12 @@ printf(" AMP_THERMAL %d\n",polybuffer.size()); ...@@ -269,9 +408,12 @@ printf(" AMP_THERMAL %d\n",polybuffer.size());
* because circles are very easy to draw (no rotation problem) so convert them in polygons, * because circles are very easy to draw (no rotation problem) so convert them in polygons,
* and draw them as polygons is not a good idea. * and draw them as polygons is not a good idea.
*/ */
void AM_PRIMITIVE::ConvertShapeToPolygon( GERBER_DRAW_ITEM* aParent, std::vector<wxPoint>& aBuffer, bool aUnitsMetric) void AM_PRIMITIVE::ConvertShapeToPolygon( GERBER_DRAW_ITEM* aParent,
std::vector<wxPoint>& aBuffer,
bool aUnitsMetric )
{ {
D_CODE* tool = aParent->GetDcodeDescr(); D_CODE* tool = aParent->GetDcodeDescr();
switch( primitive_id ) switch( primitive_id )
{ {
case AMP_CIRCLE: // Circle, currently convertion not needed case AMP_CIRCLE: // Circle, currently convertion not needed
...@@ -280,31 +422,33 @@ void AM_PRIMITIVE::ConvertShapeToPolygon( GERBER_DRAW_ITEM* aParent, std::vector ...@@ -280,31 +422,33 @@ void AM_PRIMITIVE::ConvertShapeToPolygon( GERBER_DRAW_ITEM* aParent, std::vector
case AMP_LINE2: case AMP_LINE2:
case AMP_LINE20: // Line with rectangle ends. (Width, start and end pos + rotation) case AMP_LINE20: // Line with rectangle ends. (Width, start and end pos + rotation)
{ {
int width = scale( this->params[1].GetValue( tool ), aUnitsMetric ); int width = scale( params[1].GetValue( tool ), aUnitsMetric );
wxPoint start = mapPt( this->params[2].GetValue( tool ), wxPoint start = mapPt( params[2].GetValue( tool ),
this->params[3].GetValue( tool ), aUnitsMetric ); params[3].GetValue( tool ), aUnitsMetric );
wxPoint end = mapPt( this->params[4].GetValue( tool ), wxPoint end = mapPt( params[4].GetValue( tool ),
this->params[5].GetValue( tool ), aUnitsMetric ); params[5].GetValue( tool ), aUnitsMetric );
wxPoint delta = end - start; wxPoint delta = end - start;
int len = wxRound(hypot(delta.x, delta.y)); int len = wxRound( hypot( delta.x, delta.y ) );
// To build the polygon, we must create a horizonta polygon starting to "start" // To build the polygon, we must create a horizonta polygon starting to "start"
// and rotate it to have it end point to "end" // and rotate it to have it end point to "end"
wxPoint currpt; wxPoint currpt;
currpt.y += width/2; // Upper left currpt.y += width / 2; // Upper left
aBuffer.push_back(currpt); aBuffer.push_back( currpt );
currpt.x = len; // Upper right currpt.x = len; // Upper right
aBuffer.push_back(currpt); aBuffer.push_back( currpt );
currpt.y -= width; // lower right currpt.y -= width; // lower right
aBuffer.push_back(currpt); aBuffer.push_back( currpt );
currpt.x = 0; // Upper left currpt.x = 0; // Upper left
aBuffer.push_back(currpt); aBuffer.push_back( currpt );
// Rotate rectangle and move it to the actual start point // Rotate rectangle and move it to the actual start point
int angle = wxRound( atan2(delta.y, delta.x) * 1800.0 / M_PI ); int angle = wxRound( atan2( delta.y, delta.x ) * 1800.0 / M_PI );
for( unsigned ii = 0; ii < 4; ii++ ) for( unsigned ii = 0; ii < 4; ii++ )
{ {
RotatePoint(&aBuffer[ii], -angle); RotatePoint( &aBuffer[ii], -angle );
aBuffer[ii] += start; aBuffer[ii] += start;
NEGATE(aBuffer[ii].y); NEGATE( aBuffer[ii].y );
} }
} }
break; break;
...@@ -313,76 +457,148 @@ void AM_PRIMITIVE::ConvertShapeToPolygon( GERBER_DRAW_ITEM* aParent, std::vector ...@@ -313,76 +457,148 @@ void AM_PRIMITIVE::ConvertShapeToPolygon( GERBER_DRAW_ITEM* aParent, std::vector
{ {
wxPoint size = mapPt( params[1].GetValue( tool ), params[2].GetValue( tool ), aUnitsMetric ); wxPoint size = mapPt( params[1].GetValue( tool ), params[2].GetValue( tool ), aUnitsMetric );
wxPoint pos = mapPt( params[3].GetValue( tool ), params[4].GetValue( tool ), aUnitsMetric ); wxPoint pos = mapPt( params[3].GetValue( tool ), params[4].GetValue( tool ), aUnitsMetric );
// Build poly: // Build poly:
pos.x -= size.x/2; pos.x -= size.x / 2;
pos.y -= size.y/2; // Lower left pos.y -= size.y / 2; // Lower left
aBuffer.push_back(pos); aBuffer.push_back( pos );
pos.y += size.y; // Upper left pos.y += size.y; // Upper left
aBuffer.push_back(pos); aBuffer.push_back( pos );
pos.x += size.x; // Upper right pos.x += size.x; // Upper right
aBuffer.push_back(pos); aBuffer.push_back( pos );
pos.y -= size.y; // lower right pos.y -= size.y; // lower right
aBuffer.push_back(pos); aBuffer.push_back( pos );
} }
break; break;
case AMP_LINE_LOWER_LEFT: case AMP_LINE_LOWER_LEFT:
{ {
wxPoint size = mapPt( params[1].GetValue( tool ), params[2].GetValue( tool ), aUnitsMetric ); wxPoint size = mapPt( params[1].GetValue( tool ), params[2].GetValue( tool ), aUnitsMetric );
wxPoint lowerLeft = mapPt( params[3].GetValue( tool ), params[4].GetValue( tool ), aUnitsMetric ); wxPoint lowerLeft = mapPt( params[3].GetValue( tool ), params[4].GetValue(
tool ), aUnitsMetric );
// Build poly: // Build poly:
NEGATE(lowerLeft.y); NEGATE( lowerLeft.y );
aBuffer.push_back(lowerLeft); aBuffer.push_back( lowerLeft );
lowerLeft.y += size.y; // Upper left lowerLeft.y += size.y; // Upper left
aBuffer.push_back(lowerLeft); aBuffer.push_back( lowerLeft );
lowerLeft.x += size.x; // Upper right lowerLeft.x += size.x; // Upper right
aBuffer.push_back(lowerLeft); aBuffer.push_back( lowerLeft );
lowerLeft.y -= size.y; // lower right lowerLeft.y -= size.y; // lower right
aBuffer.push_back(lowerLeft); aBuffer.push_back( lowerLeft );
// Negate y coordinates: // Negate y coordinates:
for( unsigned ii = 0; ii < aBuffer.size(); ii++ ) for( unsigned ii = 0; ii < aBuffer.size(); ii++ )
NEGATE(aBuffer[ii].y); NEGATE( aBuffer[ii].y );
} }
break; break;
case AMP_THERMAL: case AMP_THERMAL:
{ {
int outerDiam = scale( this->params[2].GetValue( tool ), aUnitsMetric ); // Only 1/4 of the full shape is built, because the other 3 shapes will be draw from this first
int innerDiam = scale( this->params[3].GetValue( tool ), aUnitsMetric ); // rotated by 90, 180 and 270 deg.
// params = center.x (unused here), center.y (unused here), outside diam, inside diam, crosshair thickness
int outerRadius = scale( params[2].GetValue( tool ), aUnitsMetric ) / 2;
int innerRadius = scale( params[3].GetValue( tool ), aUnitsMetric ) / 2;
int halfthickness = scale( params[4].GetValue( tool ), aUnitsMetric ) / 2;
int angle_start = wxRound( asin(
(double) halfthickness / innerRadius ) * 1800 / M_PI );
// Draw shape in the first cadrant (X and Y > 0)
wxPoint pos, startpos;
// Inner arc
startpos.x = innerRadius;
int angle_end = 900 - angle_start;
int angle;
for( angle = angle_start; angle < angle_end; angle += 100 )
{
pos = startpos;
RotatePoint( &pos, angle );
aBuffer.push_back( pos );
}
// Last point
pos = startpos;
RotatePoint( &pos, angle_end );
aBuffer.push_back( pos );
// outer arc
startpos.x = outerRadius;
startpos.y = 0;
angle_start = wxRound( asin( (double) halfthickness / outerRadius ) * 1800 / M_PI );
angle_end = 900 - angle_start;
// First point, near Y axis, outer arc
for( angle = angle_end; angle > angle_start; angle -= 100 )
{
pos = startpos;
RotatePoint( &pos, angle );
aBuffer.push_back( pos );
}
// last point
pos = startpos;
RotatePoint( &pos, angle_start );
aBuffer.push_back( pos );
aBuffer.push_back( aBuffer[0] ); // Close poly
} }
break; break;
case AMP_MOIRE: // A cross hair with n concentric circles. Only the cros is build as polygon case AMP_MOIRE: // A cross hair with n concentric circles. Only the cros is build as polygon
// because circles can be drawn easily // because circles can be drawn easily
{ {
int crossHairThickness = scale( this->params[6].GetValue( tool ), aUnitsMetric ); int crossHairThickness = scale( params[6].GetValue( tool ), aUnitsMetric );
int crossHairLength = scale( this->params[7].GetValue( tool ), aUnitsMetric ); int crossHairLength = scale( params[7].GetValue( tool ), aUnitsMetric );
// Create cross. First create 1/4 of the shape. // Create cross. First create 1/4 of the shape.
// Others point are the same, totated by 90, 180 and 270 deg // Others point are the same, totated by 90, 180 and 270 deg
wxPoint pos(crossHairThickness/2, crossHairLength/2); wxPoint pos( crossHairThickness / 2, crossHairLength / 2 );
aBuffer.push_back(pos); aBuffer.push_back( pos );
pos.y = crossHairThickness/2; pos.y = crossHairThickness / 2;
aBuffer.push_back(pos); aBuffer.push_back( pos );
pos.x = -crossHairLength/2; pos.x = -crossHairLength / 2;
aBuffer.push_back(pos); aBuffer.push_back( pos );
pos.y = -crossHairThickness/2; pos.y = -crossHairThickness / 2;
aBuffer.push_back(pos); aBuffer.push_back( pos );
// Copy these 4 points, rotated by 90, 180 and 270 deg
// Copy the 4 shape, rotated by 90, 180 and 270 deg
for( int jj = 900; jj <= 2700; jj += 900 ) for( int jj = 900; jj <= 2700; jj += 900 )
{ {
for( int ii = 0; ii < 4; ii++ ) for( int ii = 0; ii < 4; ii++ )
{ {
pos = aBuffer[ii]; pos = aBuffer[ii];
RotatePoint(&pos,jj); RotatePoint( &pos, jj );
aBuffer.push_back(pos); aBuffer.push_back( pos );
} }
} }
} }
break; break;
case AMP_UNKNOWN:
case AMP_OUTLINE: case AMP_OUTLINE:
case AMP_POLYGON: // already is a polygon. Do nothing
break;
case AMP_POLYGON: // Creates a regular polygon
{
int vertexcount = wxRound( params[1].GetValue( tool ) );
int radius = scale( params[4].GetValue( tool ), aUnitsMetric ) / 2;
// rs274x said: vertex count = 3 ... 10, and the first corner is on the X axis
if( vertexcount < 3 )
vertexcount = 3;
if( vertexcount > 10 )
vertexcount = 10;
for( int ii = 0; ii <= vertexcount; ii++ )
{
wxPoint pos( radius, 0);
RotatePoint( &pos, ii * 3600 / vertexcount );
aBuffer.push_back( pos );
}
}
break;
case AMP_UNKNOWN:
case AMP_EOF: case AMP_EOF:
break; break;
} }
...@@ -394,15 +610,16 @@ void AM_PRIMITIVE::ConvertShapeToPolygon( GERBER_DRAW_ITEM* aParent, std::vector ...@@ -394,15 +610,16 @@ void AM_PRIMITIVE::ConvertShapeToPolygon( GERBER_DRAW_ITEM* aParent, std::vector
* When an item is flashed, this is the shape of the item * When an item is flashed, this is the shape of the item
*/ */
void APERTURE_MACRO::DrawApertureMacroShape( GERBER_DRAW_ITEM* aParent, void APERTURE_MACRO::DrawApertureMacroShape( GERBER_DRAW_ITEM* aParent,
EDA_Rect* aClipBox, EDA_Rect* aClipBox, wxDC* aDC,
wxDC* aDC, int aColor, int aAltColor,
int aColor, wxPoint aShapePos, bool aFilledShape )
wxPoint aShapePos,
bool aFilledShape )
{ {
for( AM_PRIMITIVES::iterator prim_macro = primitives.begin(); for( AM_PRIMITIVES::iterator prim_macro = primitives.begin();
prim_macro != primitives.end(); ++prim_macro ) prim_macro != primitives.end(); ++prim_macro )
{ {
prim_macro->DrawBasicShape( aParent, aClipBox, aDC, aColor, aShapePos, aFilledShape ); prim_macro->DrawBasicShape( aParent, aClipBox, aDC,
aColor, aAltColor,
aShapePos,
aFilledShape );
} }
} }
...@@ -84,21 +84,37 @@ public: ...@@ -84,21 +84,37 @@ public:
* returns the first parameter in integer form. Some but not all primitives * returns the first parameter in integer form. Some but not all primitives
* use the first parameter as an exposure control. * use the first parameter as an exposure control.
*/ */
int GetExposure() const int GetExposure() const;
{
// No D_CODE* for GetValue()
wxASSERT( params.size() && params[0].IsImmediate() );
return (int) params[0].GetValue( NULL );
}
/**
* Function mapExposure
* translates the first parameter from an aperture macro into a current
* exposure setting.
* @param aParent = a GERBER_DRAW_ITEM that handle:
* ** m_Exposure A dynamic setting which can change throughout the
* reading of the gerber file, and it indicates whether the current tool
* is lit or not.
* ** m_ImageNegative A dynamic setting which can change throughout the reading
* of the gerber file, and it indicates whether the current D codes are to
* be interpreted as erasures or not.
* @return true to draw with current color, false to draw with alt color (erase)
*/
bool mapExposure( GERBER_DRAW_ITEM* aParent );
/* Draw functions: */ /* Draw functions: */
/** function DrawBasicShape /** function DrawBasicShape
* Draw the primitive shape for flashed items. * Draw the primitive shape for flashed items.
* @param aParent = the parent GERBER_DRAW_ITEM which is actually drawn
* @param aClipBox = DC clip box (NULL is no clip)
* @param aDC = device context
* @param aColor = the normal color to use
* @param aAltColor = the color used to draw with "reverse" exposure mode (used in aperture macros only)
* @param aShapePos = the actual shape position
* @param aFilledShape = true to draw in filled mode, false to draw in skecth mode
*/ */
void DrawBasicShape( GERBER_DRAW_ITEM* aParent, EDA_Rect* aClipBox, wxDC* aDC, void DrawBasicShape( GERBER_DRAW_ITEM* aParent, EDA_Rect* aClipBox, wxDC* aDC,
int aColor, wxPoint aShapePos, bool aFilledShape ); int aColor, int aAltColor, wxPoint aShapePos, bool aFilledShape );
private: private:
...@@ -126,9 +142,16 @@ struct APERTURE_MACRO ...@@ -126,9 +142,16 @@ struct APERTURE_MACRO
/** function DrawApertureMacroShape /** function DrawApertureMacroShape
* Draw the primitive shape for flashed items. * Draw the primitive shape for flashed items.
* When an item is flashed, this is the shape of the item * When an item is flashed, this is the shape of the item
* @param aParent = the parent GERBER_DRAW_ITEM which is actually drawn
* @param aClipBox = DC clip box (NULL is no clip)
* @param aDC = device context
* @param aColor = the normal color to use
* @param aAltColor = the color used to draw with "reverse" exposure mode (used in aperture macros only)
* @param aShapePos = the actual shape position
* @param aFilledShape = true to draw in filled mode, false to draw in skecth mode
*/ */
void DrawApertureMacroShape( GERBER_DRAW_ITEM* aParent, EDA_Rect* aClipBox, wxDC* aDC, void DrawApertureMacroShape( GERBER_DRAW_ITEM* aParent, EDA_Rect* aClipBox, wxDC* aDC,
int aColor, wxPoint aShapePos, bool aFilledShape ); int aColor, int aAltColor, wxPoint aShapePos, bool aFilledShape );
}; };
......
...@@ -50,6 +50,8 @@ GERBER_DRAW_ITEM::GERBER_DRAW_ITEM( BOARD_ITEM* aParent ) : ...@@ -50,6 +50,8 @@ GERBER_DRAW_ITEM::GERBER_DRAW_ITEM( BOARD_ITEM* aParent ) :
m_Flashed = false; m_Flashed = false;
m_DCode = 0; m_DCode = 0;
m_UnitsMetric = false; m_UnitsMetric = false;
m_ImageNegative = false;
m_LayerNegative = false;
} }
...@@ -72,6 +74,9 @@ GERBER_DRAW_ITEM::GERBER_DRAW_ITEM( const GERBER_DRAW_ITEM& aSource ) : ...@@ -72,6 +74,9 @@ GERBER_DRAW_ITEM::GERBER_DRAW_ITEM( const GERBER_DRAW_ITEM& aSource ) :
m_DCode = aSource.m_DCode; m_DCode = aSource.m_DCode;
m_PolyCorners = aSource.m_PolyCorners; m_PolyCorners = aSource.m_PolyCorners;
m_UnitsMetric = aSource.m_UnitsMetric; m_UnitsMetric = aSource.m_UnitsMetric;
m_ImageNegative = aSource.m_ImageNegative;
m_LayerNegative = aSource.m_LayerNegative;
} }
...@@ -183,7 +188,7 @@ void GERBER_DRAW_ITEM::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, int aDrawMode, ...@@ -183,7 +188,7 @@ void GERBER_DRAW_ITEM::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, int aDrawMode,
/*********************************************************************/ /*********************************************************************/
{ {
static D_CODE dummyD_CODE( 0 ); // used when a D_CODE is not found. default D_CODE to draw a flashed item static D_CODE dummyD_CODE( 0 ); // used when a D_CODE is not found. default D_CODE to draw a flashed item
int color; int color, alt_color;
bool isFilled; bool isFilled;
int radius; int radius;
int halfPenWidth; int halfPenWidth;
...@@ -194,12 +199,6 @@ void GERBER_DRAW_ITEM::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, int aDrawMode, ...@@ -194,12 +199,6 @@ void GERBER_DRAW_ITEM::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, int aDrawMode,
if( d_codeDescr == NULL ) if( d_codeDescr == NULL )
d_codeDescr = &dummyD_CODE; d_codeDescr = &dummyD_CODE;
if( m_Flags & DRAW_ERASED ) // draw in background color ("negative" color)
{
color = g_DrawBgColor;
}
else
{
if( brd->IsLayerVisible( GetLayer() ) == false ) if( brd->IsLayerVisible( GetLayer() ) == false )
return; return;
...@@ -214,6 +213,12 @@ void GERBER_DRAW_ITEM::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, int aDrawMode, ...@@ -214,6 +213,12 @@ void GERBER_DRAW_ITEM::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, int aDrawMode,
} }
if( color & HIGHT_LIGHT_FLAG ) if( color & HIGHT_LIGHT_FLAG )
color = ColorRefs[color & MASKCOLOR].m_LightColor; color = ColorRefs[color & MASKCOLOR].m_LightColor;
alt_color = g_DrawBgColor ;
if( m_Flags & DRAW_ERASED ) // draw in background color ("negative" color)
{
EXCHG(color, alt_color);
} }
GRSetDrawMode( aDC, aDrawMode ); GRSetDrawMode( aDC, aDrawMode );
...@@ -272,7 +277,7 @@ void GERBER_DRAW_ITEM::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, int aDrawMode, ...@@ -272,7 +277,7 @@ void GERBER_DRAW_ITEM::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, int aDrawMode,
case GBR_SPOT_POLY: case GBR_SPOT_POLY:
case GBR_SPOT_MACRO: case GBR_SPOT_MACRO:
isFilled = DisplayOpt.DisplayPadFill ? true : false; isFilled = DisplayOpt.DisplayPadFill ? true : false;
d_codeDescr->DrawFlashedShape( this, &aPanel->m_ClipBox, aDC, color, d_codeDescr->DrawFlashedShape( this, &aPanel->m_ClipBox, aDC, color, alt_color,
m_Start, isFilled ); m_Start, isFilled );
break; break;
......
...@@ -74,6 +74,8 @@ public: ...@@ -74,6 +74,8 @@ public:
// 0 for items that do not use DCodes (polygons) // 0 for items that do not use DCodes (polygons)
// or when unknown and normal values are 10 to 999 // or when unknown and normal values are 10 to 999
// values 0 to 9 can be used for special purposes // values 0 to 9 can be used for special purposes
bool m_ImageNegative; // true = item in negative image
bool m_LayerNegative; // TRUE = item in negative Layer
public: public:
GERBER_DRAW_ITEM( BOARD_ITEM* aParent ); GERBER_DRAW_ITEM( BOARD_ITEM* aParent );
......
...@@ -293,7 +293,7 @@ void WinEDA_GerberFrame::CopyDCodesSizeToItems() ...@@ -293,7 +293,7 @@ void WinEDA_GerberFrame::CopyDCodesSizeToItems()
* When an item is flashed, the DCode shape is the shape of the item * When an item is flashed, the DCode shape is the shape of the item
*/ */
void D_CODE::DrawFlashedShape( GERBER_DRAW_ITEM* aParent, void D_CODE::DrawFlashedShape( GERBER_DRAW_ITEM* aParent,
EDA_Rect* aClipBox, wxDC* aDC, int aColor, EDA_Rect* aClipBox, wxDC* aDC, int aColor, int aAltColor,
wxPoint aShapePos, bool aFilledShape ) wxPoint aShapePos, bool aFilledShape )
{ {
int radius; int radius;
...@@ -301,7 +301,8 @@ void D_CODE::DrawFlashedShape( GERBER_DRAW_ITEM* aParent, ...@@ -301,7 +301,8 @@ void D_CODE::DrawFlashedShape( GERBER_DRAW_ITEM* aParent,
switch( m_Shape ) switch( m_Shape )
{ {
case APT_MACRO: case APT_MACRO:
GetMacro()->DrawApertureMacroShape( aParent, aClipBox, aDC, aColor, aShapePos, aFilledShape); GetMacro()->DrawApertureMacroShape( aParent, aClipBox, aDC, aColor, aAltColor,
aShapePos, aFilledShape);
break; break;
case APT_CIRCLE: case APT_CIRCLE:
......
...@@ -193,9 +193,15 @@ public: ...@@ -193,9 +193,15 @@ public:
/** function DrawFlashedShape /** function DrawFlashedShape
* Draw the dcode shape for flashed items. * Draw the dcode shape for flashed items.
* When an item is flashed, the DCode shape is the shape of the item * When an item is flashed, the DCode shape is the shape of the item
* @param aClipBox = DC clip box (NULL is no clip)
* @param aDC = device context
* @param aColor = the normal color to use
* @param aAltColor = the color used to draw with "reverse" exposure mode (used in aperture macros only)
* @param aFilled = true to draw in filled mode, false to draw in skecth mode
* @param aPosition = the actual shape position
*/ */
void DrawFlashedShape( GERBER_DRAW_ITEM* aParent, void DrawFlashedShape( GERBER_DRAW_ITEM* aParent,
EDA_Rect* aClipBox, wxDC* aDC, int aColor, EDA_Rect* aClipBox, wxDC* aDC, int aColor, int aAltColor,
wxPoint aShapePos, bool aFilledShape ); wxPoint aShapePos, bool aFilledShape );
/** function DrawFlashedPolygon /** function DrawFlashedPolygon
...@@ -203,6 +209,11 @@ public: ...@@ -203,6 +209,11 @@ public:
* Draw some Apertures shapes when they are defined as filled polygons. * Draw some Apertures shapes when they are defined as filled polygons.
* APT_POLYGON is always a polygon, but some complex shapes are also converted to * APT_POLYGON is always a polygon, but some complex shapes are also converted to
* polygons (shapes with holes, some rotated shapes) * polygons (shapes with holes, some rotated shapes)
* @param aClipBox = DC clip box (NULL is no clip)
* @param aDC = device context
* @param aColor = the normal color to use
* @param aFilled = true to draw in filled mode, false to draw in skecth mode
* @param aPosition = the actual shape position
*/ */
void DrawFlashedPolygon( EDA_Rect* aClipBox, wxDC* aDC, int aColor, void DrawFlashedPolygon( EDA_Rect* aClipBox, wxDC* aDC, int aColor,
bool aFilled, const wxPoint& aPosition ); bool aFilled, const wxPoint& aPosition );
......
G04 Verification of all aperture macros *
G04 Handcoded by Stefan Petersen *
%MOIN*%
%FSLAX23Y23*%
%OFA0.0000B0.0000*%
G90*
%AMCIRCLE*
1,1,0.5,0,0*
%
%AMVECTOR*
2,1,0.3,0,0,1,1,-15*
%
%AMLINE*
21,1,0.3,0.05,0,0,-135*
%
%AMLINE2*
22,1,0.8,0.5,0,0,-45*
%
%AMOUTLINE*
4,1,3,0.0,0.0,0.0,0.5,0.5,0.5,0.5,0.0,-25*
%
%AMPOLYGON*
5,1,5,0,0,0.5,25*
%
%AMMOIRE*
6,0,0,1.0,0.1,0.4,2,0.01,1,20*
%
%AMTHERMAL*
7,0,0,1.0,0.3,0.04,-13*
%
%ADD10C,0.0650*%
%ADD11CIRCLE*%
%ADD12VECTOR*%
%ADD13LINE*%
%ADD14LINE2*%
%ADD15OUTLINE*%
%ADD16POLYGON*%
%ADD18MOIRE*%
%ADD19THERMAL*%
G04 Outline*
X0Y0D02*
G54D10*
X0Y0D01*
X10000D01*
Y10000D01*
X0D01*
Y0D01*
G04 Dots *
X2000Y5000D03*
X3000D03*
X4000D03*
X5000D03*
X6000D03*
X7000D03*
X8000D03*
X9000D03*
Y6200X9000D03*
G04 Draw circle*
G54D11*
X2000Y5000D03*
G04 Draw line vector *
G54D12*
X3000D03*
G04 Draw line center *
G54D13*
X4000D03*
G04 Draw line lower left *
G54D14*
X5000D03*
G04 Draw outline *
G54D15*
X6000D03*
G04 Draw polygon 1 *
G54D16*
X7000D03*
G04 Draw Moire *
G54D18*
X9000D03*
G04 Draw Thermal *
G54D19*
Y6200X9000D03*
M02*
...@@ -76,123 +76,68 @@ static wxPoint LastPosition; ...@@ -76,123 +76,68 @@ static wxPoint LastPosition;
/** /**
* Function fillCircularGBRITEM * Function fillFlashedGBRITEM
* initializes a given GBRITEM so that it can draw a circle which is not filled
* and
* has a given pen width (\a aPenWidth ).
*
* @param aGbrItem The GBRITEM to fill in.
* @param Dcode_index The DCODE value, like D14
* @param aLayer The layer index to set into the GBRITEM
* @param aPos The center point of the flash
* @param aDiameter The diameter of the round flash
* @param aPenWidth The width of the pen used to draw the circle's
* circumference.
* @param isDark True if flash is positive and should use a drawing
* color other than the background color, else use the background color
* when drawing so that an erasure happens.
*/
static void fillCircularGBRITEM( GERBER_DRAW_ITEM* aGbrItem,
int Dcode_index,
int aLayer,
const wxPoint& aPos,
int aDiameter,
int aPenWidth,
bool isDark )
{
aGbrItem->m_Shape = GBR_CIRCLE;
aGbrItem->m_Size.x = aGbrItem->m_Size.y = aPenWidth;
aGbrItem->SetLayer( aLayer );
aGbrItem->m_DCode = Dcode_index;
// When drawing a GBRITEM with shape GBR_CIRCLE, the hypotenuse (i.e. distance)
// between the Start and End points gives the radius of the circle.
aGbrItem->m_Start = aGbrItem->m_End = aPos;
aGbrItem->m_End.x += max( 0, (aDiameter + 1) / 2 );
NEGATE( aGbrItem->m_Start.y );
NEGATE( aGbrItem->m_End.y );
if( !isDark )
{
aGbrItem->m_Flags |= DRAW_ERASED;
}
}
/**
* Function fillRoundFlashGBRITEM
* initializes a given GBRITEM so that it can draw a circle which is filled and * initializes a given GBRITEM so that it can draw a circle which is filled and
* has no pen border. * has no pen border.
* *
* @param aGbrItem The GBRITEM to fill in. * @param aGbrItem The GBRITEM to fill in.
* @param aAperture the associated type of aperture
* @param Dcode_index The DCODE value, like D14 * @param Dcode_index The DCODE value, like D14
* @param aLayer The layer index to set into the GBRITEM * @param aLayer The layer index to set into the GBRITEM
* @param aPos The center point of the flash * @param aPos The center point of the flash
* @param aDiameter The diameter of the round flash * @param aSize The diameter of the round flash
* @param isDark True if flash is positive and should use a drawing * @param aLayerNegative = true if the current layer is negative
* color other than the background color, else use the background color * @param aImageNegative = true if the current image is negative
* when drawing so that an erasure happens.
*/ */
static void fillRoundFlashGBRITEM( GERBER_DRAW_ITEM* aGbrItem, static void fillFlashedGBRITEM( GERBER_DRAW_ITEM* aGbrItem,
APERTURE_T aAperture,
int Dcode_index, int Dcode_index,
int aLayer, int aLayer,
const wxPoint& aPos, const wxPoint& aPos,
int aDiameter, wxSize aSize,
bool isDark ) bool aLayerNegative,
bool aImageNegative )
{ {
aGbrItem->SetLayer( aLayer ); aGbrItem->SetLayer( aLayer );
aGbrItem->m_Size.x = aGbrItem->m_Size.y = aDiameter; aGbrItem->m_Size = aSize;
aGbrItem->m_Start = aPos; aGbrItem->m_Start = aPos;
NEGATE( aGbrItem->m_Start.y ); NEGATE( aGbrItem->m_Start.y );
aGbrItem->m_End = aGbrItem->m_Start; aGbrItem->m_End = aGbrItem->m_Start;
aGbrItem->m_DCode = Dcode_index; aGbrItem->m_DCode = Dcode_index;
aGbrItem->m_Shape = GBR_SPOT_CIRCLE; aGbrItem->m_LayerNegative = aLayerNegative;
aGbrItem->m_ImageNegative = aImageNegative;
aGbrItem->m_Flashed = true; aGbrItem->m_Flashed = true;
switch( aAperture )
if( !isDark )
{ {
aGbrItem->m_Flags |= DRAW_ERASED; case APT_POLYGON: // flashed regular polygon
} aGbrItem->m_Shape = GBR_SPOT_POLY;
} break;
case APT_LINE: // Should not be used.
case APT_CIRCLE:
aGbrItem->m_Shape = GBR_SPOT_CIRCLE;
aGbrItem->m_Size.y = aGbrItem->m_Size.x;
break;
/** case APT_OVAL:
* Function fillOvalOrRectFlashGBRITEM aGbrItem->m_Shape = GBR_SPOT_OVAL;
* initializes a given GBRITEM so that it can draw an oval or rectangular break;
* filled rectangle.
*
* @param aGbrItem The GERBER_DRAW_ITEM to fill in.
* @param Dcode_index The DCODE value, like D14
* @param aLayer The layer index to set into the GBRITEM
* @param aPos The center point of the rectangle
* @param aSize The size of the flash
* @param aShape What type of flash, GBR_SPOT_OVALE or GBR_SPOT_RECT
* @param isDark True if flash is positive and should use a drawing
* color other than the background color, else use the background color
* when drawing so that an erasure happens.
*/
static void fillOvalOrRectFlashGBRITEM( GERBER_DRAW_ITEM* aGbrItem,
int Dcode_index,
int aLayer,
const wxPoint& aPos,
const wxSize& aSize,
int aShape,
bool isDark )
{
aGbrItem->SetLayer( aLayer );
aGbrItem->m_Flashed = true;
aGbrItem->m_Size = aSize; case APT_RECT:
aGbrItem->m_Shape = GBR_SPOT_RECT;
break;
aGbrItem->m_Start = aPos; case APT_MACRO:
NEGATE( aGbrItem->m_Start.y ); aGbrItem->m_Shape = GBR_SPOT_MACRO;
aGbrItem->m_End = aGbrItem->m_Start; break;
}
aGbrItem->m_DCode = Dcode_index; bool isDark = !(aGbrItem->m_LayerNegative ^ aGbrItem->m_ImageNegative);
aGbrItem->m_Shape = aShape;
/* isDark is true if flash is positive and should use a drawing
* color other than the background color, else use the background color
* when drawing so that an erasure happens.
*/
if( !isDark ) if( !isDark )
{ {
aGbrItem->m_Flags |= DRAW_ERASED; aGbrItem->m_Flags |= DRAW_ERASED;
...@@ -209,9 +154,8 @@ static void fillOvalOrRectFlashGBRITEM( GERBER_DRAW_ITEM* aGbrItem, ...@@ -209,9 +154,8 @@ static void fillOvalOrRectFlashGBRITEM( GERBER_DRAW_ITEM* aGbrItem,
* @param aLayer The layer index to set into the GBRITEM * @param aLayer The layer index to set into the GBRITEM
* @param aPos The center point of the flash * @param aPos The center point of the flash
* @param aDiameter The diameter of the round flash * @param aDiameter The diameter of the round flash
* @param isDark True if flash is positive and should use a drawing * @param aLayerNegative = true if the current layer is negative
* color other than the background color, else use the background color * @param aImageNegative = true if the current image is negative
* when drawing so that an erasure happens.
*/ */
static void fillLineGBRITEM( GERBER_DRAW_ITEM* aGbrItem, static void fillLineGBRITEM( GERBER_DRAW_ITEM* aGbrItem,
int Dcode_index, int Dcode_index,
...@@ -219,7 +163,8 @@ static void fillLineGBRITEM( GERBER_DRAW_ITEM* aGbrItem, ...@@ -219,7 +163,8 @@ static void fillLineGBRITEM( GERBER_DRAW_ITEM* aGbrItem,
const wxPoint& aStart, const wxPoint& aStart,
const wxPoint& aEnd, const wxPoint& aEnd,
int aWidth, int aWidth,
bool isDark ) bool aLayerNegative,
bool aImageNegative )
{ {
aGbrItem->SetLayer( aLayer ); aGbrItem->SetLayer( aLayer );
aGbrItem->m_Flashed = false; aGbrItem->m_Flashed = false;
...@@ -233,7 +178,15 @@ static void fillLineGBRITEM( GERBER_DRAW_ITEM* aGbrItem, ...@@ -233,7 +178,15 @@ static void fillLineGBRITEM( GERBER_DRAW_ITEM* aGbrItem,
NEGATE( aGbrItem->m_End.y ); NEGATE( aGbrItem->m_End.y );
aGbrItem->m_DCode = Dcode_index; aGbrItem->m_DCode = Dcode_index;
aGbrItem->m_LayerNegative = aLayerNegative;
aGbrItem->m_ImageNegative = aImageNegative;
bool isDark = !(aGbrItem->m_LayerNegative ^ aGbrItem->m_ImageNegative);
/* isDark is true if flash is positive and should use a drawing
* color other than the background color, else use the background color
* when drawing so that an erasure happens.
*/
if( !isDark ) if( !isDark )
{ {
aGbrItem->m_Flags |= DRAW_ERASED; aGbrItem->m_Flags |= DRAW_ERASED;
...@@ -267,14 +220,15 @@ static void fillLineGBRITEM( GERBER_DRAW_ITEM* aGbrItem, ...@@ -267,14 +220,15 @@ static void fillLineGBRITEM( GERBER_DRAW_ITEM* aGbrItem,
* same quadrant. * same quadrant.
* @param aDiameter The diameter of the round flash * @param aDiameter The diameter of the round flash
* @param aWidth is the pen width. * @param aWidth is the pen width.
* @param isDark True if flash is positive and should use a drawing * @param aLayerNegative = true if the current layer is negative
* color other than the background color, else use the background color * @param aImageNegative = true if the current image is negative
* when drawing so that an erasure happens.
*/ */
static void fillArcGBRITEM( GERBER_DRAW_ITEM* aGbrItem, int Dcode_index, int aLayer, static void fillArcGBRITEM( GERBER_DRAW_ITEM* aGbrItem, int Dcode_index, int aLayer,
const wxPoint& aStart, const wxPoint& aEnd, const wxPoint& aStart, const wxPoint& aEnd,
const wxPoint& rel_center, int aWidth, const wxPoint& rel_center, int aWidth,
bool clockwise, bool multiquadrant, bool isDark ) bool clockwise, bool multiquadrant,
bool aLayerNegative,
bool aImageNegative )
{ {
wxPoint center, delta; wxPoint center, delta;
...@@ -347,6 +301,15 @@ static void fillArcGBRITEM( GERBER_DRAW_ITEM* aGbrItem, int Dcode_index, int aL ...@@ -347,6 +301,15 @@ static void fillArcGBRITEM( GERBER_DRAW_ITEM* aGbrItem, int Dcode_index, int aL
NEGATE( aGbrItem->m_End.y ); NEGATE( aGbrItem->m_End.y );
NEGATE( aGbrItem->m_ArcCentre.y ); NEGATE( aGbrItem->m_ArcCentre.y );
aGbrItem->m_LayerNegative = aLayerNegative;
aGbrItem->m_ImageNegative = aImageNegative;
bool isDark = !(aGbrItem->m_LayerNegative ^ aGbrItem->m_ImageNegative);
/* isDark is true if flash is positive and should use a drawing
* color other than the background color, else use the background color
* when drawing so that an erasure happens.
*/
if( !isDark ) if( !isDark )
{ {
aGbrItem->m_Flags |= DRAW_ERASED; aGbrItem->m_Flags |= DRAW_ERASED;
...@@ -379,23 +342,38 @@ static void fillArcGBRITEM( GERBER_DRAW_ITEM* aGbrItem, int Dcode_index, int aL ...@@ -379,23 +342,38 @@ static void fillArcGBRITEM( GERBER_DRAW_ITEM* aGbrItem, int Dcode_index, int aL
* same quadrant. * same quadrant.
* @param aDiameter The diameter of the round flash * @param aDiameter The diameter of the round flash
* @param aWidth is the pen width. * @param aWidth is the pen width.
* @param isDark True if flash is positive and should use a drawing * @param aLayerNegative = true if the current layer is negative
* color other than the background color, else use the background color * @param aImageNegative = true if the current image is negative
* when drawing so that an erasure happens.
*/ */
static void fillArcPOLY( BOARD* aPcb, GERBER_DRAW_ITEM* aGrbrItem, static void fillArcPOLY( BOARD* aPcb, GERBER_DRAW_ITEM* aGbrItem,
const wxPoint& aStart, const wxPoint& aEnd, const wxPoint& aStart, const wxPoint& aEnd,
const wxPoint& rel_center, const wxPoint& rel_center,
bool clockwise, bool multiquadrant, bool isDark ) bool clockwise, bool multiquadrant,
bool aLayerNegative,
bool aImageNegative )
{ {
/* in order to calculate arc parameters, we use fillArcGBRITEM /* in order to calculate arc parameters, we use fillArcGBRITEM
* so we muse create a dummy track and use its geometric parameters * so we muse create a dummy track and use its geometric parameters
*/ */
static GERBER_DRAW_ITEM dummyGbrItem( NULL ); static GERBER_DRAW_ITEM dummyGbrItem( NULL );
aGbrItem->m_LayerNegative = aLayerNegative;
aGbrItem->m_ImageNegative = aImageNegative;
bool isDark = !(aGbrItem->m_LayerNegative ^ aGbrItem->m_ImageNegative);
/* isDark is true if flash is positive and should use a drawing
* color other than the background color, else use the background color
* when drawing so that an erasure happens.
*/
if( !isDark )
{
aGbrItem->m_Flags |= DRAW_ERASED;
}
fillArcGBRITEM( &dummyGbrItem, 0, 0, fillArcGBRITEM( &dummyGbrItem, 0, 0,
aStart, aEnd, rel_center, 0, aStart, aEnd, rel_center, 0,
clockwise, multiquadrant, isDark ); clockwise, multiquadrant, aLayerNegative, aImageNegative );
// dummyTrack has right geometric parameters, and has its Y coordinates negated (to match the pcbnew Y axis). // dummyTrack has right geometric parameters, and has its Y coordinates negated (to match the pcbnew Y axis).
// Approximate arc by 36 segments per 360 degree // Approximate arc by 36 segments per 360 degree
...@@ -457,14 +435,10 @@ static void fillArcPOLY( BOARD* aPcb, GERBER_DRAW_ITEM* aGrbrItem, ...@@ -457,14 +435,10 @@ static void fillArcPOLY( BOARD* aPcb, GERBER_DRAW_ITEM* aGrbrItem,
// D( printf( " >> Add arc %d rot %d, edge poly item %d,%d to %d,%d\n", // D( printf( " >> Add arc %d rot %d, edge poly item %d,%d to %d,%d\n",
// ii, rot, start_arc.x, start_arc.y,end_arc.x, end_arc.y ); ) // ii, rot, start_arc.x, start_arc.y,end_arc.x, end_arc.y ); )
if( aGrbrItem->m_PolyCorners.size() == 0 ) if( aGbrItem->m_PolyCorners.size() == 0 )
aGrbrItem->m_PolyCorners.push_back( start_arc + center ); aGbrItem->m_PolyCorners.push_back( start_arc + center );
aGrbrItem->m_PolyCorners.push_back( end_arc + center ); aGbrItem->m_PolyCorners.push_back( end_arc + center );
if( !isDark )
{
aGrbrItem->m_Flags |= DRAW_ERASED;
}
start_arc = end_arc; start_arc = end_arc;
} }
} }
...@@ -537,9 +511,10 @@ wxPoint GERBER::ReadXYCoord( char*& Text ) ...@@ -537,9 +511,10 @@ wxPoint GERBER::ReadXYCoord( char*& Text )
if( fmt_scale < 0 || fmt_scale > 9 ) if( fmt_scale < 0 || fmt_scale > 9 )
fmt_scale = 4; fmt_scale = 4;
double scale_list[10] = double scale_list[10] =
{ 10000.0, 1000.0, 100.0, 10.0, {
10000.0, 1000.0, 100.0, 10.0,
1, 1,
0.1, 0.01, 0.001, 0.0001, 0.00001 0.1, 0.01, 0.001, 0.0001,0.00001
}; };
real_scale = scale_list[fmt_scale]; real_scale = scale_list[fmt_scale];
...@@ -635,9 +610,10 @@ wxPoint GERBER::ReadIJCoord( char*& Text ) ...@@ -635,9 +610,10 @@ wxPoint GERBER::ReadIJCoord( char*& Text )
fmt_scale = 4; // select scale 1.0 fmt_scale = 4; // select scale 1.0
double scale_list[10] = double scale_list[10] =
{ 10000.0, 1000.0, 100.0, 10.0, {
10000.0, 1000.0, 100.0, 10.0,
1, 1,
0.1, 0.01, 0.001, 0.0001, 0.00001 0.1, 0.01, 0.001, 0.0001,0.00001
}; };
real_scale = scale_list[fmt_scale]; real_scale = scale_list[fmt_scale];
...@@ -707,7 +683,7 @@ int GERBER::ReturnDCodeNumber( char*& Text ) ...@@ -707,7 +683,7 @@ int GERBER::ReturnDCodeNumber( char*& Text )
bool GERBER::Execute_G_Command( char*& text, int G_commande ) bool GERBER::Execute_G_Command( char*& text, int G_commande )
{ {
D( printf( "%22s: G_CODE<%d>\n", __func__, G_commande ); ) // D( printf( "%22s: G_CODE<%d>\n", __func__, G_commande ); )
switch( G_commande ) switch( G_commande )
{ {
...@@ -832,49 +808,12 @@ int scale( double aCoord, bool isMetric ) ...@@ -832,49 +808,12 @@ int scale( double aCoord, bool isMetric )
*/ */
wxPoint mapPt( double x, double y, bool isMetric ) wxPoint mapPt( double x, double y, bool isMetric )
{ {
wxPoint ret( scale( x, isMetric ), wxPoint ret( scale( x, isMetric ), scale( y, isMetric ) );
scale( y, isMetric ) );
return ret; return ret;
} }
/**
* Function mapExposure
* translates the first parameter from an aperture macro into a current
* exposure
* setting.
* @param curExposure A dynamic setting which can change throughout the
* reading of the gerber file, and it indicates whether the current tool
* is lit or not.
* @param isNegative A dynamic setting which can change throughout the reading
* of
* the gerber file, and it indicates whether the current D codes are to
* be interpreted as erasures or not.
*/
static bool mapExposure( int param1, bool curExposure, bool isNegative )
{
bool exposure;
switch( param1 )
{
case 0:
exposure = false;
break;
default:
case 1:
exposure = true;
break;
case 2:
exposure = !curExposure;
}
return exposure ^ isNegative;
}
bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame, char*& text, int D_commande ) bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame, char*& text, int D_commande )
{ {
wxSize size( 15, 15 ); wxSize size( 15, 15 );
...@@ -889,7 +828,7 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame, char*& text, int ...@@ -889,7 +828,7 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame, char*& text, int
D_CODE* tool = NULL; D_CODE* tool = NULL;
wxString msg; wxString msg;
D( printf( "%22s: D_CODE<%d>\n", __func__, D_commande ); ) // D( printf( "%22s: D_CODE<%d>\n", __func__, D_commande ); )
if( D_commande >= FIRST_DCODE ) // This is a "Set tool" command if( D_commande >= FIRST_DCODE ) // This is a "Set tool" command
{ {
...@@ -932,21 +871,20 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame, char*& text, int ...@@ -932,21 +871,20 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame, char*& text, int
case GERB_INTERPOL_ARC_NEG: case GERB_INTERPOL_ARC_NEG:
case GERB_INTERPOL_ARC_POS: case GERB_INTERPOL_ARC_POS:
gbritem = (GERBER_DRAW_ITEM*)( pcb->m_Drawings.GetLast() ); gbritem = (GERBER_DRAW_ITEM*)( pcb->m_Drawings.GetLast() );
D( printf( "Add arc poly %d,%d to %d,%d fill %d interpol %d 360_enb %d\n", // D( printf( "Add arc poly %d,%d to %d,%d fill %d interpol %d 360_enb %d\n",
m_PreviousPos.x, m_PreviousPos.y, m_CurrentPos.x, // m_PreviousPos.x, m_PreviousPos.y, m_CurrentPos.x,
m_CurrentPos.y, m_PolygonFillModeState, m_Iterpolation, m_360Arc_enbl ); ) // m_CurrentPos.y, m_PolygonFillModeState, m_Iterpolation, m_360Arc_enbl ); )
fillArcPOLY( pcb, gbritem, m_PreviousPos, fillArcPOLY( pcb, gbritem, m_PreviousPos,
m_CurrentPos, m_IJPos, m_CurrentPos, m_IJPos,
( m_Iterpolation == GERB_INTERPOL_ARC_NEG ) ? ( m_Iterpolation == GERB_INTERPOL_ARC_NEG ) ?
false : true, m_360Arc_enbl, false : true, m_360Arc_enbl, m_LayerNegative, m_ImageNegative );
!(m_LayerNegative ^ m_ImageNegative) );
break; break;
default: default:
gbritem = (GERBER_DRAW_ITEM*)( pcb->m_Drawings.GetLast() ); gbritem = (GERBER_DRAW_ITEM*)( pcb->m_Drawings.GetLast() );
D( printf( "Add poly edge %d,%d to %d,%d fill %d\n", // D( printf( "Add poly edge %d,%d to %d,%d fill %d\n",
m_PreviousPos.x, m_PreviousPos.y, // m_PreviousPos.x, m_PreviousPos.y,
m_CurrentPos.x, m_CurrentPos.y, m_Iterpolation ); ) // m_CurrentPos.x, m_CurrentPos.y, m_Iterpolation ); )
gbritem->m_Start = m_PreviousPos; // m_Start is used as temporary storage gbritem->m_Start = m_PreviousPos; // m_Start is used as temporary storage
NEGATE( gbritem->m_Start.y ); NEGATE( gbritem->m_Start.y );
...@@ -962,7 +900,6 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame, char*& text, int ...@@ -962,7 +900,6 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame, char*& text, int
{ {
if( m_LayerNegative ^ m_ImageNegative ) if( m_LayerNegative ^ m_ImageNegative )
gbritem->m_Flags |= DRAW_ERASED; gbritem->m_Flags |= DRAW_ERASED;
D( printf( "\nm_Flags=0x%08X\n", gbritem->m_Flags ); )
} }
break; break;
} }
...@@ -1002,10 +939,9 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame, char*& text, int ...@@ -1002,10 +939,9 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame, char*& text, int
gbritem = new GERBER_DRAW_ITEM( pcb ); gbritem = new GERBER_DRAW_ITEM( pcb );
gbritem->m_UnitsMetric = m_GerbMetric; gbritem->m_UnitsMetric = m_GerbMetric;
pcb->m_Drawings.Append( gbritem ); pcb->m_Drawings.Append( gbritem );
D( printf( "R:%p\n", gbritem ); ) // D( printf( "R:%p\n", gbritem ); )
fillLineGBRITEM( gbritem, dcode, activeLayer, m_PreviousPos, fillLineGBRITEM( gbritem, dcode, activeLayer, m_PreviousPos,
m_CurrentPos, size.x, m_CurrentPos, size.x, m_LayerNegative, m_ImageNegative );
!(m_LayerNegative ^ m_ImageNegative) );
break; break;
case GERB_INTERPOL_LINEAR_01X: case GERB_INTERPOL_LINEAR_01X:
...@@ -1019,12 +955,12 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame, char*& text, int ...@@ -1019,12 +955,12 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame, char*& text, int
gbritem = new GERBER_DRAW_ITEM( pcb ); gbritem = new GERBER_DRAW_ITEM( pcb );
gbritem->m_UnitsMetric = m_GerbMetric; gbritem->m_UnitsMetric = m_GerbMetric;
pcb->m_Drawings.Append( gbritem ); pcb->m_Drawings.Append( gbritem );
D( printf( "R:%p\n", gbritem ); ) // D( printf( "R:%p\n", gbritem ); )
fillArcGBRITEM( gbritem, dcode, activeLayer, m_PreviousPos, fillArcGBRITEM( gbritem, dcode, activeLayer, m_PreviousPos,
m_CurrentPos, m_IJPos, size.x, m_CurrentPos, m_IJPos, size.x,
( m_Iterpolation == GERB_INTERPOL_ARC_NEG ) ? ( m_Iterpolation == GERB_INTERPOL_ARC_NEG ) ?
false : true, m_360Arc_enbl, false : true, m_360Arc_enbl,
!(m_LayerNegative ^ m_ImageNegative) ); m_LayerNegative, m_ImageNegative );
break; break;
default: default:
...@@ -1051,288 +987,13 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame, char*& text, int ...@@ -1051,288 +987,13 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame, char*& text, int
aperture = tool->m_Shape; aperture = tool->m_Shape;
} }
switch( aperture )
{
case APT_POLYGON: // flashed regular polygon
case APT_CIRCLE:
gbritem = new GERBER_DRAW_ITEM( pcb );
gbritem->m_UnitsMetric = m_GerbMetric;
pcb->m_Drawings.Append( gbritem );
D( printf( "R:%p\n", gbritem ); )
fillRoundFlashGBRITEM( gbritem, dcode, activeLayer,
m_CurrentPos, size.x,
!(m_LayerNegative ^ m_ImageNegative) );
if( aperture == APT_POLYGON )
gbritem->m_Shape = GBR_SPOT_POLY;
break;
case APT_OVAL:
case APT_RECT:
gbritem = new GERBER_DRAW_ITEM( pcb );
gbritem->m_UnitsMetric = m_GerbMetric;
pcb->m_Drawings.Append( gbritem );
D( printf( "R:%p\n", gbritem ); )
fillOvalOrRectFlashGBRITEM( gbritem, dcode, activeLayer,
m_CurrentPos, size,
( aperture == APT_RECT ) ?
GBR_SPOT_RECT : GBR_SPOT_OVAL,
!(m_LayerNegative ^ m_ImageNegative) );
break;
case APT_MACRO:
{
APERTURE_MACRO* macro = tool->GetMacro();
wxASSERT( macro );
#if 1
gbritem = new GERBER_DRAW_ITEM( pcb ); gbritem = new GERBER_DRAW_ITEM( pcb );
gbritem->m_UnitsMetric = m_GerbMetric; gbritem->m_UnitsMetric = m_GerbMetric;
pcb->m_Drawings.Append( gbritem ); pcb->m_Drawings.Append( gbritem );
fillRoundFlashGBRITEM( gbritem, dcode, activeLayer, // D( printf( "R:%p dcode %d layer %d\n", gbritem, dcode, activeLayer ); )
m_CurrentPos, size.x, fillFlashedGBRITEM( gbritem, aperture,
!(m_LayerNegative ^ m_ImageNegative) ); dcode, activeLayer, m_CurrentPos,
gbritem->m_Shape = GBR_SPOT_MACRO; size, m_LayerNegative, m_ImageNegative );
#else
// split the macro primitives up into multiple normal GBRITEM
// elements
for( AM_PRIMITIVES::iterator p = macro->primitives.begin();
p!=macro->primitives.end();
++p )
{
bool exposure;
wxPoint curPos = m_CurrentPos;
switch( p->primitive_id )
{
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 );
gbritem = new GERBER_DRAW_ITEM( pcb );
pcb->m_Drawings.Append( gbritem );
D( printf( "R:%p\n", gbritem ); )
fillRoundFlashGBRITEM( gbritem, dcode, activeLayer,
curPos, 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;
gbritem = new GERBER_DRAW_ITEM( pcb );
pcb->m_Drawings.Append( gbritem );
D( printf( "R:%p\n", gbritem ); )
fillOvalOrRectFlashGBRITEM( gbritem, dcode, activeLayer,
curPos, size, GBR_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 );
gbritem = new GERBER_DRAW_ITEM( pcb );
pcb->m_Drawings.Append( gbritem );
D( printf( "R:%p\n", gbritem ); )
fillOvalOrRectFlashGBRITEM( gbritem, dcode, activeLayer,
curPos, size, GBR_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;
gbritem = new GERBER_DRAW_ITEM( pcb );
pcb->m_Drawings.Append( gbritem );
D( printf( "R:%p\n", gbritem ); )
fillOvalOrRectFlashGBRITEM( gbritem, dcode, activeLayer,
curPos, size, GBR_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 );
gbritem = new GERBER_DRAW_ITEM( pcb );
pcb->m_Drawings.Append( gbritem );
D( printf( "R:%p\n", gbritem ); )
fillRoundFlashGBRITEM( gbritem, dcode, activeLayer,
curPos, outerDiam,
!( m_LayerNegative ^ m_ImageNegative ) );
gbritem = new GERBER_DRAW_ITEM( pcb );
pcb->m_Drawings.Append( gbritem );
D( printf( "R:%p\n", gbritem ); )
fillRoundFlashGBRITEM( gbritem, 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 )
{
gbritem = new GERBER_DRAW_ITEM( pcb );
pcb->m_Drawings.Append( gbritem );
D( printf( "R:%p\n", gbritem ); )
fillCircularGBRITEM( gbritem, dcode, activeLayer,
curPos, outerDiam,
penThickness,
!( m_LayerNegative ^ m_ImageNegative ) );
}
gbritem = new GERBER_DRAW_ITEM( pcb );
pcb->m_Drawings.Append( gbritem );
D( printf( "R:%p\n", gbritem ); )
fillOvalOrRectFlashGBRITEM( gbritem, dcode, activeLayer,
curPos,
wxSize( crossHairThickness,
crossHairLength ),
GBR_SPOT_RECT,
!( m_LayerNegative ^ m_ImageNegative ) );
gbritem = new GERBER_DRAW_ITEM( pcb );
pcb->m_Drawings.Append( gbritem );
D( printf( "R:%p\n", gbritem ); )
// swap x and y in wxSize() for this one
fillOvalOrRectFlashGBRITEM( gbritem, dcode, activeLayer,
curPos,
wxSize( crossHairLength,
crossHairThickness ),
GBR_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; i<numPoints + 1; ++i )
{
printf( " [%d]: X=%g Y=%g\n", i,
p->params[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;
}
}
#endif
}
break;
default:
break;
}
m_PreviousPos = m_CurrentPos; m_PreviousPos = m_CurrentPos;
break; break;
......
...@@ -173,8 +173,7 @@ bool GERBER::ExecuteRS274XCommand( int command, ...@@ -173,8 +173,7 @@ bool GERBER::ExecuteRS274XCommand( int command,
double conv_scale = m_GerbMetric ? PCB_INTERNAL_UNIT / double conv_scale = m_GerbMetric ? PCB_INTERNAL_UNIT /
25.4 : PCB_INTERNAL_UNIT; 25.4 : PCB_INTERNAL_UNIT;
D( printf( "%22s: Command <%c%c>\n", __func__, (command >> 8) & 0xFF, // D( printf( "%22s: Command <%c%c>\n", __func__, (command >> 8) & 0xFF, command & 0xFF ); )
command & 0xFF ); )
switch( command ) switch( command )
{ {
...@@ -663,7 +662,7 @@ bool GERBER::ReadApertureMacro( char buff[GERBER_BUFZ], ...@@ -663,7 +662,7 @@ bool GERBER::ReadApertureMacro( char buff[GERBER_BUFZ],
break; break;
case AMP_POLYGON: case AMP_POLYGON:
paramCount = 4; paramCount = 6;
break; break;
case AMP_MOIRE: case AMP_MOIRE:
...@@ -703,7 +702,8 @@ bool GERBER::ReadApertureMacro( char buff[GERBER_BUFZ], ...@@ -703,7 +702,8 @@ bool GERBER::ReadApertureMacro( char buff[GERBER_BUFZ],
if( i < paramCount ) // maybe some day we can throw an exception and if( i < paramCount ) // maybe some day we can throw an exception and
// track a line number // track a line number
printf( "i=%d, insufficient parameters\n", i ); printf( "read macro descr type %d: read %d parameters, insufficient parameters\n",
prim.primitive_id, i );
// 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 )
......
/* Bits characterizing cell */ /* Bits characterizing cell */
#define HOLE (char)0x01 /* a conducting hole or obstacle */ #define HOLE 0x01 /* a conducting hole or obstacle */
#define CELL_is_MODULE (char)0x02 /* auto placement occupied by a module */ #define CELL_is_MODULE 0x02 /* auto placement occupied by a module */
#define CELL_is_EDGE (char)0x20 /* Area and auto-placement: limiting cell #define CELL_is_EDGE 0x20 /* Area and auto-placement: limiting cell
* contour (Board, Zone) */ * contour (Board, Zone) */
#define CELL_is_FRIEND (char)0x40 /* Area and auto-placement: cell part of the #define CELL_is_FRIEND 0x40 /* Area and auto-placement: cell part of the
* net */ * net */
#define CELL_is_ZONE (char)0x80 /* Area and auto-placement: cell available */ #define CELL_is_ZONE 0x80 /* Area and auto-placement: cell available */
/* Bit masks for presence of obstacles to autorouting */ /* Bit masks for presence of obstacles to autorouting */
#define OCCUPE 1 /* Autorouting: obstacle tracks and vias. */ #define OCCUPE 1 /* Autorouting: obstacle tracks and vias. */
......
...@@ -65,7 +65,7 @@ void WinEDA_BasePcbFrame::Plot_Serigraphie( PLOTTER* plotter, ...@@ -65,7 +65,7 @@ void WinEDA_BasePcbFrame::Plot_Serigraphie( PLOTTER* plotter,
Plot_Edges_Modules( plotter, m_Pcb, masque_layer, trace_mode ); Plot_Edges_Modules( plotter, m_Pcb, masque_layer, trace_mode );
/* Plot pads (creates pads outlines, for pads on silkscreen layers) */ /* Plot pads (creates pads outlines, for pads on silkscreen layers) */
bool layersmask_plotpads = masque_layer; int layersmask_plotpads = masque_layer;
// Calculate the mask layers of allowed layers for pads // Calculate the mask layers of allowed layers for pads
if( !g_pcb_plot_options.PlotPadsOnSilkLayer ) if( !g_pcb_plot_options.PlotPadsOnSilkLayer )
layersmask_plotpads &= ~(SILKSCREEN_LAYER_BACK || SILKSCREEN_LAYER_FRONT); layersmask_plotpads &= ~(SILKSCREEN_LAYER_BACK || SILKSCREEN_LAYER_FRONT);
......
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