コード例 #1
0
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" );
}
コード例 #2
0
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.
}
コード例 #3
0
/* 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();
}
コード例 #4
0
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 );
}
コード例 #5
0
/**
 * 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' );
}
コード例 #6
0
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;
}
コード例 #7
0
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 );
}
コード例 #8
0
/**
 * 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");
        }
    }
}
コード例 #9
0
/* 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 );
}
コード例 #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();
}
コード例 #11
0
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 );
    }
}
コード例 #12
0
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;
}
コード例 #13
0
/**
 * 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 );
    }
}
コード例 #14
0
/**
 * 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();
}
コード例 #15
0
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;
    }
}
コード例 #16
0
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 );
}
コード例 #17
0
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 );
}
コード例 #18
0
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;
}
コード例 #19
0
/**
 * 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' );
}
コード例 #20
0
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 );
}
コード例 #21
0
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;
}
コード例 #22
0
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
             );
}
コード例 #23
0
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;
}
コード例 #24
0
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 );
        }
    }
}
コード例 #25
0
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 );
    }
}
コード例 #26
0
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;
}
コード例 #27
0
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;
}
コード例 #28
0
/**
 * 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' );
}
コード例 #29
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     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();
}
コード例 #30
0
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;
    }
}