/* Plot round pad or via. */ void HPGL_PLOTTER::FlashPadCircle( const wxPoint& pos, int diametre, EDA_DRAW_MODE_T trace_mode ) { wxASSERT( outputFile ); DPOINT pos_dev = userToDeviceCoordinates( pos ); int delta = KiROUND( penDiameter - penOverlap ); int radius = ( diametre - KiROUND( penDiameter ) ) / 2; if( radius < 0 ) radius = 0; double rsize = userToDeviceSize( radius ); fprintf( outputFile, "PA %.0f,%.0f;CI %.0f;\n", pos_dev.x, pos_dev.y, rsize ); if( trace_mode == FILLED ) // Plot in filled mode. { if( delta > 0 ) { while( (radius -= delta ) >= 0 ) { rsize = userToDeviceSize( radius ); fprintf( outputFile, "PA %.0f,%.0f;CI %.0f;\n", pos_dev.x, pos_dev.y, rsize ); } } } PenFinish(); }
/* Plot an arc: * Center = center coord * Stangl, endAngle = angle of beginning and end * Radius = radius of the arc * Command * PU PY x, y; PD start_arc_X AA, start_arc_Y, angle, NbSegm; PU; * Or PU PY x, y; PD start_arc_X AA, start_arc_Y, angle, PU; */ void HPGL_PLOTTER::Arc( const wxPoint& centre, double StAngle, double EndAngle, int radius, FILL_T fill, int width ) { wxASSERT( outputFile ); double angle; if( radius <= 0 ) return; DPOINT centre_dev = userToDeviceCoordinates( centre ); if( m_plotMirror ) angle = StAngle - EndAngle; else angle = EndAngle - StAngle; NORMALIZE_ANGLE_180( angle ); angle /= 10; // Calculate arc start point: wxPoint cmap; cmap.x = centre.x + KiROUND( cosdecideg( radius, StAngle ) ); cmap.y = centre.y - KiROUND( sindecideg( radius, StAngle ) ); DPOINT cmap_dev = userToDeviceCoordinates( cmap ); fprintf( outputFile, "PU;PA %.0f,%.0f;PD;AA %.0f,%.0f,", cmap_dev.x, cmap_dev.y, centre_dev.x, centre_dev.y ); fprintf( outputFile, "%.0f", angle ); fprintf( outputFile, ";PU;\n" ); PenFinish(); }
/** * HPGL rectangle: fill not supported */ void HPGL_PLOTTER::Rect( const wxPoint& p1, const wxPoint& p2, FILL_T fill, int width ) { wxASSERT( outputFile ); DPOINT p2dev = userToDeviceCoordinates( p2 ); MoveTo( p1 ); fprintf( outputFile, "EA %.0f,%.0f;\n", p2dev.x, p2dev.y ); PenFinish(); }
/** * HPGL circle: fill not supported */ void HPGL_PLOTTER::Circle( const wxPoint& centre, int diameter, FILL_T fill, int width ) { wxASSERT( outputFile ); double radius = userToDeviceSize( diameter / 2 ); if( radius > 0 ) { MoveTo( centre ); fprintf( outputFile, "CI %g;\n", radius ); PenFinish(); } }
// HPGL circle void HPGL_PLOTTER::Circle( const wxPoint& centre, int diameter, FILL_T fill, int width ) { wxASSERT( outputFile ); double radius = userToDeviceSize( diameter / 2 ); SetCurrentLineWidth( width ); if( fill == FILLED_SHAPE ) { // Draw the filled area MoveTo( centre ); fprintf( outputFile, "PM 0; CI %g;\n", radius ); fprintf( outputFile, hpgl_end_polygon_cmd ); // Close, fill polygon and draw outlines PenFinish(); } if( radius > 0 ) { MoveTo( centre ); fprintf( outputFile, "CI %g;\n", radius ); PenFinish(); } }
void GERBER_PLOTTER:: PlotPoly( const std::vector< wxPoint >& aCornerList, FILL_T aFill, int aWidth, void * aData ) { if( aCornerList.size() <= 1 ) return; // Gerber format does not know filled polygons with thick outline // Therefore, to plot a filled polygon with outline having a thickness, // one should plot outline as thick segments GBR_METADATA* gbr_metadata = static_cast<GBR_METADATA*>( aData ); SetCurrentLineWidth( aWidth, gbr_metadata ); if( gbr_metadata ) formatNetAttribute( &gbr_metadata->m_NetlistMetadata ); if( aFill ) { fputs( "G36*\n", outputFile ); MoveTo( aCornerList[0] ); for( unsigned ii = 1; ii < aCornerList.size(); ii++ ) LineTo( aCornerList[ii] ); FinishTo( aCornerList[0] ); fputs( "G37*\n", outputFile ); } if( aWidth > 0 ) { MoveTo( aCornerList[0] ); for( unsigned ii = 1; ii < aCornerList.size(); ii++ ) LineTo( aCornerList[ii] ); // Ensure the thick outline is closed for filled polygons // (if not filled, could be only a polyline) if( aFill && ( aCornerList[aCornerList.size()-1] != aCornerList[0] ) ) LineTo( aCornerList[0] ); PenFinish(); } }
void HPGL_PLOTTER::PlotPoly( const std::vector<wxPoint>& aCornerList, FILL_T aFill, int aWidth ) { if( aCornerList.size() <= 1 ) return; SetCurrentLineWidth( aWidth ); MoveTo( aCornerList[0] ); if( aFill == FILLED_SHAPE ) { // Draw the filled area SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH ); fprintf( outputFile, "PM 0;\n" ); // Start polygon for( unsigned ii = 1; ii < aCornerList.size(); ++ii ) LineTo( aCornerList[ii] ); int ii = aCornerList.size() - 1; if( aCornerList[ii] != aCornerList[0] ) LineTo( aCornerList[0] ); fprintf( outputFile, hpgl_end_polygon_cmd ); // Close, fill polygon and draw outlines } else { // Plot only the polygon outline. for( unsigned ii = 1; ii < aCornerList.size(); ii++ ) LineTo( aCornerList[ii] ); // Always close polygon if filled. if( aFill ) { int ii = aCornerList.size() - 1; if( aCornerList[ii] != aCornerList[0] ) LineTo( aCornerList[0] ); } } PenFinish(); }
/** * HPGL polygon: fill not supported (but closed, at least) */ void HPGL_PLOTTER::PlotPoly( const std::vector<wxPoint>& aCornerList, FILL_T aFill, int aWidth ) { if( aCornerList.size() <= 1 ) return; MoveTo( aCornerList[0] ); for( unsigned ii = 1; ii < aCornerList.size(); ii++ ) LineTo( aCornerList[ii] ); // Close polygon if filled. if( aFill ) { int ii = aCornerList.size() - 1; if( aCornerList[ii] != aCornerList[0] ) LineTo( aCornerList[0] ); } PenFinish(); }
/* Plot round pad or via. */ void HPGL_PLOTTER::FlashPadCircle( const wxPoint& pos, int diametre, EDA_DRAW_MODE_T trace_mode ) { wxASSERT( outputFile ); DPOINT pos_dev = userToDeviceCoordinates( pos ); int radius = diametre / 2; if( trace_mode == FILLED ) { // if filled mode, the pen diameter is removed from diameter // to keep the pad size radius -= KiROUND( penDiameter ) / 2; } if( radius < 0 ) radius = 0; double rsize = userToDeviceSize( radius ); if( trace_mode == FILLED ) // Plot in filled mode. { // A filled polygon uses always the current point to start the polygon. // Gives a correct current starting point for the circle MoveTo( wxPoint( pos.x+radius, pos.y ) ); // Plot filled area and its outline fprintf( outputFile, "PM 0; PA %.0f,%.0f;CI %.0f;%s", pos_dev.x, pos_dev.y, rsize, hpgl_end_polygon_cmd ); } else { // Draw outline only: fprintf( outputFile, "PA %.0f,%.0f;CI %.0f;\n", pos_dev.x, pos_dev.y, rsize ); } PenFinish(); }
/** * DXF polygon: doesn't fill it but at least it close the filled ones * DXF does not know thick outline. * It does not know thhick segments, therefore filled polygons with thick outline * are converted to inflated polygon by aWidth/2 */ void DXF_PLOTTER::PlotPoly( const std::vector<wxPoint>& aCornerList, FILL_T aFill, int aWidth) { if( aCornerList.size() <= 1 ) return; unsigned last = aCornerList.size() - 1; // Plot outlines with lines (thickness = 0) to define the polygon if( aWidth <= 0 ) { MoveTo( aCornerList[0] ); for( unsigned ii = 1; ii < aCornerList.size(); ii++ ) LineTo( aCornerList[ii] ); // Close polygon if 'fill' requested if( aFill ) { if( aCornerList[last] != aCornerList[0] ) LineTo( aCornerList[0] ); } PenFinish(); return; } // if the polygon outline has thickness, and is not filled // (i.e. is a polyline) plot outlines with thick segments if( aWidth > 0 && !aFill ) { MoveTo( aCornerList[0] ); for( unsigned ii = 1; ii < aCornerList.size(); ii++ ) ThickSegment( aCornerList[ii-1], aCornerList[ii], aWidth, FILLED ); return; } // The polygon outline has thickness, and is filled // Build and plot the polygon which contains the initial // polygon and its thick outline SHAPE_POLY_SET bufferOutline; SHAPE_POLY_SET bufferPolybase; const int circleToSegmentsCount = 16; bufferPolybase.NewOutline(); // enter outline as polygon: for( unsigned ii = 1; ii < aCornerList.size(); ii++ ) { TransformRoundedEndsSegmentToPolygon( bufferOutline, aCornerList[ii-1], aCornerList[ii], circleToSegmentsCount, aWidth ); } // enter the initial polygon: for( unsigned ii = 0; ii < aCornerList.size(); ii++ ) { bufferPolybase.Append( aCornerList[ii] ); } // Merge polygons to build the polygon which contains the initial // polygon and its thick outline bufferPolybase.BooleanAdd( bufferOutline ); // create the outline which contains thick outline bufferPolybase.Fracture(); if( bufferPolybase.OutlineCount() < 1 ) // should not happen return; const SHAPE_LINE_CHAIN& path = bufferPolybase.COutline( 0 ); if( path.PointCount() < 2 ) // should not happen return; // Now, output the final polygon to DXF file: last = path.PointCount() - 1; VECTOR2I point = path.CPoint( 0 ); wxPoint startPoint( point.x, point.y ); MoveTo( startPoint ); for( int ii = 1; ii < path.PointCount(); ii++ ) { point = path.CPoint( ii ); LineTo( wxPoint( point.x, point.y ) ); } // Close polygon, if needed point = path.CPoint( last ); wxPoint endPoint( point.x, point.y ); if( endPoint != startPoint ) LineTo( startPoint ); PenFinish(); }