void SVG_PLOTTER::PlotPoly( const std::vector<wxPoint>& aCornerList, FILL_T aFill, int aWidth ) { if( aCornerList.size() <= 1 ) return; setFillMode( aFill ); SetCurrentLineWidth( aWidth ); switch( aFill ) { case NO_FILL: fprintf( outputFile, "<polyline fill=\"none;\"\n" ); break; case FILLED_WITH_BG_BODYCOLOR: case FILLED_SHAPE: fprintf( outputFile, "<polyline style=\"fill-rule:evenodd;\"\n" ); break; } DPOINT pos = userToDeviceCoordinates( aCornerList[0] ); fprintf( outputFile, "points=\"%d,%d\n", (int) pos.x, (int) pos.y ); for( unsigned ii = 1; ii < aCornerList.size(); ii++ ) { pos = userToDeviceCoordinates( aCornerList[ii] ); fprintf( outputFile, "%d,%d\n", (int) pos.x, (int) pos.y ); } // Close/(fill) the path fprintf( outputFile, "\" /> \n" ); }
void GERBER_PLOTTER::Arc( const wxPoint& aCenter, double aStAngle, double aEndAngle, int aRadius, FILL_T aFill, int aWidth ) { SetCurrentLineWidth( aWidth ); wxPoint start, end; start.x = aCenter.x + KiROUND( cosdecideg( aRadius, aStAngle ) ); start.y = aCenter.y - KiROUND( sindecideg( aRadius, aStAngle ) ); MoveTo( start ); end.x = aCenter.x + KiROUND( cosdecideg( aRadius, aEndAngle ) ); end.y = aCenter.y - KiROUND( sindecideg( aRadius, aEndAngle ) ); DPOINT devEnd = userToDeviceCoordinates( end ); DPOINT devCenter = userToDeviceCoordinates( aCenter ) - userToDeviceCoordinates( start ); fprintf( outputFile, "G75*\n" ); // Multiquadrant mode if( aStAngle < aEndAngle ) fprintf( outputFile, "G03" ); else fprintf( outputFile, "G02" ); fprintf( outputFile, "X%dY%dI%dJ%dD01*\n", KiROUND( devEnd.x ), KiROUND( devEnd.y ), KiROUND( devCenter.x ), KiROUND( devCenter.y ) ); fprintf( outputFile, "G01*\n" ); // Back to linear interp. }
/* 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(); }
void PS_PLOTTER::Rect( const wxPoint& p1, const wxPoint& p2, FILL_T fill, int width ) { DPOINT p1_dev = userToDeviceCoordinates( p1 ); DPOINT p2_dev = userToDeviceCoordinates( p2 ); SetCurrentLineWidth( width ); fprintf( outputFile, "%g %g %g %g rect%d\n", p1_dev.x, p1_dev.y, p2_dev.x - p1_dev.x, p2_dev.y - p1_dev.y, fill ); }
/** * Rectangles in PDF. Supported by the native operator */ void PDF_PLOTTER::Rect( const wxPoint& p1, const wxPoint& p2, FILL_T fill, int width ) { wxASSERT( workFile ); DPOINT p1_dev = userToDeviceCoordinates( p1 ); DPOINT p2_dev = userToDeviceCoordinates( p2 ); SetCurrentLineWidth( width ); fprintf( workFile, "%g %g %g %g re %c\n", p1_dev.x, p1_dev.y, p2_dev.x - p1_dev.x, p2_dev.y - p1_dev.y, fill == NO_FILL ? 'S' : 'B' ); }
void PS_PLOTTER::PenTo( const wxPoint& pos, char plume ) { wxASSERT( outputFile ); if( plume == 'Z' ) { if( penState != 'Z' ) { fputs( "stroke\n", outputFile ); penState = 'Z'; penLastpos.x = -1; penLastpos.y = -1; } return; } if( penState == 'Z' ) { fputs( "newpath\n", outputFile ); } if( penState != plume || pos != penLastpos ) { DPOINT pos_dev = userToDeviceCoordinates( pos ); fprintf( outputFile, "%g %g %sto\n", pos_dev.x, pos_dev.y, ( plume=='D' ) ? "line" : "move" ); } penState = plume; penLastpos = pos; }
void PS_PLOTTER::Arc( const wxPoint& centre, double StAngle, double EndAngle, int radius, FILL_T fill, int width ) { wxASSERT( outputFile ); if( radius <= 0 ) return; if( StAngle > EndAngle ) EXCHG( StAngle, EndAngle ); SetCurrentLineWidth( width ); // Calculate start point. DPOINT centre_dev = userToDeviceCoordinates( centre ); double radius_dev = userToDeviceSize( radius ); if( m_plotMirror ) { if( m_mirrorIsHorizontal ) { StAngle = 1800.0 -StAngle; EndAngle = 1800.0 -EndAngle; EXCHG( StAngle, EndAngle ); } else { StAngle = -StAngle; EndAngle = -EndAngle; } } fprintf( outputFile, "%g %g %g %g %g arc%d\n", centre_dev.x, centre_dev.y, radius_dev, StAngle / 10.0, EndAngle / 10.0, fill ); }
/** * DXF circle: full functionality; it even does 'fills' drawing a * circle with a dual-arc polyline wide as the radius. * * I could use this trick to do other filled primitives */ void DXF_PLOTTER::Circle( const wxPoint& centre, int diameter, FILL_T fill, int width ) { wxASSERT( outputFile ); double radius = userToDeviceSize( diameter / 2 ); DPOINT centre_dev = userToDeviceCoordinates( centre ); if( radius > 0 ) { wxString cname( ColorGetName( m_currentColor ) ); if (!fill) { fprintf( outputFile, "0\nCIRCLE\n8\n%s\n10\n%g\n20\n%g\n40\n%g\n", TO_UTF8( cname ), centre_dev.x, centre_dev.y, radius ); } if (fill == FILLED_SHAPE) { double r = radius*0.5; fprintf( outputFile, "0\nPOLYLINE\n"); fprintf( outputFile, "8\n%s\n66\n1\n70\n1\n", TO_UTF8( cname )); fprintf( outputFile, "40\n%g\n41\n%g\n", radius, radius); fprintf( outputFile, "0\nVERTEX\n8\n%s\n", TO_UTF8( cname )); fprintf( outputFile, "10\n%g\n 20\n%g\n42\n1.0\n", centre_dev.x-r, centre_dev.y ); fprintf( outputFile, "0\nVERTEX\n8\n%s\n", TO_UTF8( cname )); fprintf( outputFile, "10\n%g\n 20\n%g\n42\n1.0\n", centre_dev.x+r, centre_dev.y ); fprintf( outputFile, "0\nSEQEND\n"); } } }
/* Plot an arc in DXF format * Filling is not supported */ void DXF_PLOTTER::Arc( const wxPoint& centre, double StAngle, double EndAngle, int radius, FILL_T fill, int width ) { wxASSERT( outputFile ); if( radius <= 0 ) return; // In DXF, arcs are drawn CCW. // In Kicad, arcs are CW or CCW // If StAngle > EndAngle, it is CW. So transform it to CCW if( StAngle > EndAngle ) { std::swap( StAngle, EndAngle ); } DPOINT centre_dev = userToDeviceCoordinates( centre ); double radius_dev = userToDeviceSize( radius ); // Emit a DXF ARC entity wxString cname( ColorGetName( m_currentColor ) ); fprintf( outputFile, "0\nARC\n8\n%s\n10\n%g\n20\n%g\n40\n%g\n50\n%g\n51\n%g\n", TO_UTF8( cname ), centre_dev.x, centre_dev.y, radius_dev, StAngle / 10.0, EndAngle / 10.0 ); }
/* 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(); }
void GERBER_PLOTTER::FlashPadCircle( const wxPoint& pos, int diametre, EDA_DRAW_MODE_T trace_mode, void* aData ) { wxSize size( diametre, diametre ); GBR_METADATA* gbr_metadata = static_cast<GBR_METADATA*>( aData ); if( trace_mode == SKETCH ) { SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH, gbr_metadata ); if( gbr_metadata ) formatNetAttribute( &gbr_metadata->m_NetlistMetadata ); Circle( pos, diametre - currentPenWidth, NO_FILL, DO_NOT_SET_LINE_WIDTH ); } else { DPOINT pos_dev = userToDeviceCoordinates( pos ); int aperture_attrib = gbr_metadata ? gbr_metadata->GetApertureAttrib() : 0; selectAperture( size, APERTURE::Circle, aperture_attrib ); if( gbr_metadata ) formatNetAttribute( &gbr_metadata->m_NetlistMetadata ); emitDcode( pos_dev, 3 ); } }
void PDF_PLOTTER::PenTo( const wxPoint& pos, char plume ) { wxASSERT( workFile ); if( plume == 'Z' ) { if( penState != 'Z' ) { fputs( "S\n", workFile ); penState = 'Z'; penLastpos.x = -1; penLastpos.y = -1; } return; } if( penState != plume || pos != penLastpos ) { DPOINT pos_dev = userToDeviceCoordinates( pos ); fprintf( workFile, "%g %g %c\n", pos_dev.x, pos_dev.y, ( plume=='D' ) ? 'l' : 'm' ); } penState = plume; penLastpos = pos; }
/** * The PDF engine can't directly plot arcs, it uses the base emulation. * So no filled arcs (not a great loss... ) */ void PDF_PLOTTER::Arc( const wxPoint& centre, double StAngle, double EndAngle, int radius, FILL_T fill, int width ) { wxASSERT( workFile ); if( radius <= 0 ) return; /* Arcs are not so easily approximated by beziers (in the general case), so we approximate them in the old way */ wxPoint start, end; const int delta = 50; // increment (in 0.1 degrees) to draw circles if( StAngle > EndAngle ) EXCHG( StAngle, EndAngle ); SetCurrentLineWidth( width ); // Usual trig arc plotting routine... start.x = centre.x + KiROUND( cosdecideg( radius, -StAngle ) ); start.y = centre.y + KiROUND( sindecideg( radius, -StAngle ) ); DPOINT pos_dev = userToDeviceCoordinates( start ); fprintf( workFile, "%g %g m ", pos_dev.x, pos_dev.y ); for( int ii = StAngle + delta; ii < EndAngle; ii += delta ) { end.x = centre.x + KiROUND( cosdecideg( radius, -ii ) ); end.y = centre.y + KiROUND( sindecideg( radius, -ii ) ); pos_dev = userToDeviceCoordinates( end ); fprintf( workFile, "%g %g l ", pos_dev.x, pos_dev.y ); } end.x = centre.x + KiROUND( cosdecideg( radius, -EndAngle ) ); end.y = centre.y + KiROUND( sindecideg( radius, -EndAngle ) ); pos_dev = userToDeviceCoordinates( end ); fprintf( workFile, "%g %g l ", pos_dev.x, pos_dev.y ); // The arc is drawn... if not filled we stroke it, otherwise we finish // closing the pie at the center if( fill == NO_FILL ) { fputs( "S\n", workFile ); } else { pos_dev = userToDeviceCoordinates( centre ); fprintf( workFile, "%g %g l b\n", pos_dev.x, pos_dev.y ); } }
/** * 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(); }
void GERBER_PLOTTER::FlashPadRect( const wxPoint& pos, const wxSize& aSize, double orient, EDA_DRAW_MODE_T trace_mode ) { wxASSERT( outputFile ); wxSize size( aSize ); // Plot as an aperture flash switch( int( orient ) ) { case 900: case 2700: // rotation of 90 degrees or 270 swaps sizes EXCHG( size.x, size.y ); // Pass through case 0: case 1800: if( trace_mode == SKETCH ) { SetCurrentLineWidth( -1 ); Rect( wxPoint( pos.x - (size.x - currentPenWidth) / 2, pos.y - (size.y - currentPenWidth) / 2 ), wxPoint( pos.x + (size.x - currentPenWidth) / 2, pos.y + (size.y - currentPenWidth) / 2 ), NO_FILL ); } else { DPOINT pos_dev = userToDeviceCoordinates( pos ); selectAperture( size, APERTURE::Rect ); emitDcode( pos_dev, 3 ); } break; default: // plot pad shape as polygon { // XXX to do: use an aperture macro to declare the rotated pad wxPoint coord[4]; // coord[0] is assumed the lower left // coord[1] is assumed the upper left // coord[2] is assumed the upper right // coord[3] is assumed the lower right /* Trace the outline. */ coord[0].x = -size.x/2; // lower left coord[0].y = size.y/2; coord[1].x = -size.x/2; // upper left coord[1].y = -size.y/2; coord[2].x = size.x/2; // upper right coord[2].y = -size.y/2; coord[3].x = size.x/2; // lower right coord[3].y = size.y/2; FlashPadTrapez( pos, coord, orient, trace_mode ); } break; } }
void PS_PLOTTER::Circle( const wxPoint& pos, int diametre, FILL_T fill, int width ) { wxASSERT( outputFile ); DPOINT pos_dev = userToDeviceCoordinates( pos ); double radius = userToDeviceSize( diametre / 2.0 ); SetCurrentLineWidth( width ); fprintf( outputFile, "%g %g %g cir%d\n", pos_dev.x, pos_dev.y, radius, fill ); }
void PS_PLOTTER::PlotPoly( const std::vector< wxPoint >& aCornerList, FILL_T aFill, int aWidth ) { if( aCornerList.size() <= 1 ) return; SetCurrentLineWidth( aWidth ); DPOINT pos = userToDeviceCoordinates( aCornerList[0] ); fprintf( outputFile, "newpath\n%g %g moveto\n", pos.x, pos.y ); for( unsigned ii = 1; ii < aCornerList.size(); ii++ ) { pos = userToDeviceCoordinates( aCornerList[ii] ); fprintf( outputFile, "%g %g lineto\n", pos.x, pos.y ); } // Close/(fill) the path fprintf( outputFile, "poly%d\n", aFill ); }
void DXF_PLOTTER::PenTo( const wxPoint& pos, char plume ) { wxASSERT( outputFile ); if( plume == 'Z' ) { return; } DPOINT pos_dev = userToDeviceCoordinates( pos ); DPOINT pen_lastpos_dev = userToDeviceCoordinates( penLastpos ); if( penLastpos != pos && plume == 'D' ) { // DXF LINE wxString cname( ColorGetName( m_currentColor ) ); fprintf( outputFile, "0\nLINE\n8\n%s\n10\n%g\n20\n%g\n11\n%g\n21\n%g\n", TO_UTF8( cname ), pen_lastpos_dev.x, pen_lastpos_dev.y, pos_dev.x, pos_dev.y ); } penLastpos = pos; }
/** * Polygon plotting for PDF. Everything is supported */ void PDF_PLOTTER::PlotPoly( const std::vector< wxPoint >& aCornerList, FILL_T aFill, int aWidth ) { wxASSERT( workFile ); if( aCornerList.size() <= 1 ) return; SetCurrentLineWidth( aWidth ); DPOINT pos = userToDeviceCoordinates( aCornerList[0] ); fprintf( workFile, "%g %g m\n", pos.x, pos.y ); for( unsigned ii = 1; ii < aCornerList.size(); ii++ ) { pos = userToDeviceCoordinates( aCornerList[ii] ); fprintf( workFile, "%g %g l\n", pos.x, pos.y ); } // Close path and stroke(/fill) fprintf( workFile, "%c\n", aFill == NO_FILL ? 'S' : 'b' ); }
void SVG_PLOTTER::Circle( const wxPoint& pos, int diametre, FILL_T fill, int width ) { DPOINT pos_dev = userToDeviceCoordinates( pos ); double radius = userToDeviceSize( diametre / 2.0 ); setFillMode( fill ); SetCurrentLineWidth( width ); fprintf( outputFile, "<circle cx=\"%g\" cy=\"%g\" r=\"%g\" /> \n", pos_dev.x, pos_dev.y, radius ); }
void SVG_PLOTTER::PenTo( const wxPoint& pos, char plume ) { if( plume == 'Z' ) { if( penState != 'Z' ) { fputs( "\" />\n", outputFile ); penState = 'Z'; penLastpos.x = -1; penLastpos.y = -1; } return; } if( penState == 'Z' ) // here plume = 'D' or 'U' { DPOINT pos_dev = userToDeviceCoordinates( pos ); // Ensure we do not use a fill mode when moving tne pen, // in SVG mode (i;e. we are plotting only basic lines, not a filled area if( m_fillMode != NO_FILL ) { setFillMode( NO_FILL ); setSVGPlotStyle(); } fprintf( outputFile, "<path d=\"M%d %d\n", (int) pos_dev.x, (int) pos_dev.y ); } else if( penState != plume || pos != penLastpos ) { DPOINT pos_dev = userToDeviceCoordinates( pos ); fprintf( outputFile, "L%d %d\n", (int) pos_dev.x, (int) pos_dev.y ); } penState = plume; penLastpos = pos; }
void SVG_PLOTTER::Rect( const wxPoint& p1, const wxPoint& p2, FILL_T fill, int width ) { EDA_RECT rect( p1, wxSize( p2.x -p1.x, p2.y -p1.y ) ); rect.Normalize(); DPOINT org_dev = userToDeviceCoordinates( rect.GetOrigin() ); DPOINT end_dev = userToDeviceCoordinates( rect.GetEnd() ); DSIZE size_dev = end_dev - org_dev; // Ensure size of rect in device coordinates is > 0 // Inkscape has problems with negative values for width and/or height DBOX rect_dev( org_dev, size_dev); rect_dev.Normalize(); setFillMode( fill ); SetCurrentLineWidth( width ); fprintf( outputFile, "<rect x=\"%g\" y=\"%g\" width=\"%g\" height=\"%g\" rx=\"%g\" />\n", rect_dev.GetPosition().x, rect_dev.GetPosition().y, rect_dev.GetSize().x, rect_dev.GetSize().y, 0.0 // radius of rounded corners ); }
void DXF_PLOTTER::PenTo( const wxPoint& pos, char plume ) { wxASSERT( outputFile ); if( plume == 'Z' ) { return; } DPOINT pos_dev = userToDeviceCoordinates( pos ); DPOINT pen_lastpos_dev = userToDeviceCoordinates( penLastpos ); if( penLastpos != pos && plume == 'D' ) { wxASSERT( m_currentLineType >= 0 && m_currentLineType < 4 ); // DXF LINE wxString cname = getDXFColorName( m_currentColor ); const char *lname = getDXFLineType( (PlotDashType) m_currentLineType ); fprintf( outputFile, "0\nLINE\n8\n%s\n6\n%s\n10\n%g\n20\n%g\n11\n%g\n21\n%g\n", TO_UTF8( cname ), lname, pen_lastpos_dev.x, pen_lastpos_dev.y, pos_dev.x, pos_dev.y ); } penLastpos = pos; }
void GERBER_PLOTTER::FlashPadOval( const wxPoint& pos, const wxSize& aSize, double orient, EDA_DRAW_MODE_T trace_mode ) { wxASSERT( outputFile ); int x0, y0, x1, y1, delta; wxSize size( aSize ); /* Plot a flashed shape. */ if( ( orient == 0 || orient == 900 || orient == 1800 || orient == 2700 ) && trace_mode == FILLED ) { if( orient == 900 || orient == 2700 ) /* orientation turned 90 deg. */ EXCHG( size.x, size.y ); DPOINT pos_dev = userToDeviceCoordinates( pos ); selectAperture( size, APERTURE::Oval ); emitDcode( pos_dev, 3 ); } else /* Plot pad as a segment. */ { if( size.x > size.y ) { EXCHG( size.x, size.y ); if( orient < 2700 ) orient += 900; else orient -= 2700; } if( trace_mode == FILLED ) { /* XXX to do: use an aperture macro to declare the rotated pad */ /* The pad is reduced to an oval with dy > dx */ delta = size.y - size.x; x0 = 0; y0 = -delta / 2; x1 = 0; y1 = delta / 2; RotatePoint( &x0, &y0, orient ); RotatePoint( &x1, &y1, orient ); ThickSegment( wxPoint( pos.x + x0, pos.y + y0 ), wxPoint( pos.x + x1, pos.y + y1 ), size.x, trace_mode ); } else { sketchOval( pos, size, orient, -1 ); } } }
void GERBER_PLOTTER::FlashPadCircle( const wxPoint& pos, int diametre, EDA_DRAW_MODE_T trace_mode ) { wxASSERT( outputFile ); wxSize size( diametre, diametre ); if( trace_mode == SKETCH ) { SetCurrentLineWidth( -1 ); Circle( pos, diametre - currentPenWidth, NO_FILL ); } else { DPOINT pos_dev = userToDeviceCoordinates( pos ); selectAperture( size, APERTURE::Circle ); emitDcode( pos_dev, 3 ); } }
void HPGL_PLOTTER::PenTo( const wxPoint& pos, char plume ) { wxASSERT( outputFile ); if( plume == 'Z' ) { penControl( 'Z' ); return; } penControl( plume ); DPOINT pos_dev = userToDeviceCoordinates( pos ); if( penLastpos != pos ) fprintf( outputFile, "PA %.0f,%.0f;\n", pos_dev.x, pos_dev.y ); penLastpos = pos; }
void GERBER_PLOTTER::PenTo( const wxPoint& aPos, char plume ) { wxASSERT( outputFile ); DPOINT pos_dev = userToDeviceCoordinates( aPos ); switch( plume ) { case 'Z': break; case 'U': emitDcode( pos_dev, 2 ); break; case 'D': emitDcode( pos_dev, 1 ); } penState = plume; }
/** * Circle drawing for PDF. They're approximated by curves, but fill is supported */ void PDF_PLOTTER::Circle( const wxPoint& pos, int diametre, FILL_T aFill, int width ) { wxASSERT( workFile ); DPOINT pos_dev = userToDeviceCoordinates( pos ); double radius = userToDeviceSize( diametre / 2.0 ); /* OK. Here's a trick. PDF doesn't support circles or circular angles, that's a fact. You'll have to do with cubic beziers. These *can't* represent circular arcs (NURBS can, beziers don't). But there is a widely known approximation which is really good */ SetCurrentLineWidth( width ); double magic = radius * 0.551784; // You don't want to know where this come from // This is the convex hull for the bezier approximated circle fprintf( workFile, "%g %g m " "%g %g %g %g %g %g c " "%g %g %g %g %g %g c " "%g %g %g %g %g %g c " "%g %g %g %g %g %g c %c\n", pos_dev.x - radius, pos_dev.y, pos_dev.x - radius, pos_dev.y + magic, pos_dev.x - magic, pos_dev.y + radius, pos_dev.x, pos_dev.y + radius, pos_dev.x + magic, pos_dev.y + radius, pos_dev.x + radius, pos_dev.y + magic, pos_dev.x + radius, pos_dev.y, pos_dev.x + radius, pos_dev.y - magic, pos_dev.x + magic, pos_dev.y - radius, pos_dev.x, pos_dev.y - radius, pos_dev.x - magic, pos_dev.y - radius, pos_dev.x - radius, pos_dev.y - magic, pos_dev.x - radius, pos_dev.y, aFill == NO_FILL ? 's' : 'b' ); }
/* 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(); }
void GERBER_PLOTTER::FlashPadRect( const wxPoint& pos, const wxSize& aSize, double orient, EDA_DRAW_MODE_T trace_mode, void* aData ) { wxASSERT( outputFile ); wxSize size( aSize ); GBR_METADATA* gbr_metadata = static_cast<GBR_METADATA*>( aData ); // Plot as an aperture flash switch( int( orient ) ) { case 900: case 2700: // rotation of 90 degrees or 270 swaps sizes std::swap( size.x, size.y ); // Pass through case 0: case 1800: if( trace_mode == SKETCH ) { SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH, gbr_metadata ); if( gbr_metadata ) formatNetAttribute( &gbr_metadata->m_NetlistMetadata ); Rect( wxPoint( pos.x - (size.x - currentPenWidth) / 2, pos.y - (size.y - currentPenWidth) / 2 ), wxPoint( pos.x + (size.x - currentPenWidth) / 2, pos.y + (size.y - currentPenWidth) / 2 ), NO_FILL, GetCurrentLineWidth() ); } else { DPOINT pos_dev = userToDeviceCoordinates( pos ); int aperture_attrib = gbr_metadata ? gbr_metadata->GetApertureAttrib() : 0; selectAperture( size, APERTURE::Rect, aperture_attrib ); if( gbr_metadata ) formatNetAttribute( &gbr_metadata->m_NetlistMetadata ); emitDcode( pos_dev, 3 ); } break; default: // plot pad shape as polygon { // XXX to do: use an aperture macro to declare the rotated pad wxPoint coord[4]; // coord[0] is assumed the lower left // coord[1] is assumed the upper left // coord[2] is assumed the upper right // coord[3] is assumed the lower right /* Trace the outline. */ coord[0].x = -size.x/2; // lower left coord[0].y = size.y/2; coord[1].x = -size.x/2; // upper left coord[1].y = -size.y/2; coord[2].x = size.x/2; // upper right coord[2].y = -size.y/2; coord[3].x = size.x/2; // lower right coord[3].y = size.y/2; FlashPadTrapez( pos, coord, orient, trace_mode, aData ); } break; } }