void GERBER_PLOTTER::ThickRect( const wxPoint& p1, const wxPoint& p2, int width,
                            EDA_DRAW_MODE_T tracemode, void* aData )
{
    GBR_METADATA *gbr_metadata = static_cast<GBR_METADATA*>( aData );
    SetCurrentLineWidth( width, gbr_metadata );

    if( gbr_metadata )
        formatNetAttribute( &gbr_metadata->m_NetlistMetadata );

    if( tracemode == FILLED )
        Rect( p1, p2, NO_FILL, DO_NOT_SET_LINE_WIDTH );
    else
    {
        SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH );
        wxPoint offsetp1( p1.x - (width - currentPenWidth) / 2,
                          p1.y - (width - currentPenWidth) / 2 );
        wxPoint offsetp2( p2.x + (width - currentPenWidth) / 2,
			  p2.y + (width - currentPenWidth) / 2 );
        Rect( offsetp1, offsetp2, NO_FILL, -1 );
        offsetp1.x += (width - currentPenWidth);
        offsetp1.y += (width - currentPenWidth);
        offsetp2.x -= (width - currentPenWidth);
        offsetp2.y -= (width - currentPenWidth);
        Rect( offsetp1, offsetp2, NO_FILL, DO_NOT_SET_LINE_WIDTH );
    }
}
/**
 * Function PLOTTER::Text
 *  same as DrawGraphicText, but plot graphic text insteed of draw it
 *  @param aPos = text position (according to aH_justify, aV_justify)
 *  @param aColor (COLOR4D) = text color
 *  @param aText = text to draw
 *  @param aOrient = angle in 0.1 degree
 *  @param aSize = text size (size.x or size.y can be < 0 for mirrored texts)
 *  @param aH_justify = horizontal justification (Left, center, right)
 *  @param aV_justify = vertical justification (bottom, center, top)
 *  @param aWidth = line width (pen width) (default = 0)
 *      if width < 0 : draw segments in sketch mode, width = abs(width)
 *      Use a value min(aSize.x, aSize.y) / 5 for a bold text
 *  @param aItalic = true to simulate an italic font
 *  @param aBold = true to use a bold font Useful only with default width value (aWidth = 0)
 *  @param aMultilineAllowed = true to plot text as multiline, otherwise single line
 */
void PLOTTER::Text( const wxPoint&              aPos,
                    const COLOR4D               aColor,
                    const wxString&             aText,
                    double                      aOrient,
                    const wxSize&               aSize,
                    enum EDA_TEXT_HJUSTIFY_T    aH_justify,
                    enum EDA_TEXT_VJUSTIFY_T    aV_justify,
                    int                         aWidth,
                    bool                        aItalic,
                    bool                        aBold,
                    bool                        aMultilineAllowed,
                    void*                       aData )
{
    int textPensize = aWidth;

    if( textPensize == 0 && aBold ) // Use default values if aWidth == 0
        textPensize = GetPenSizeForBold( std::min( aSize.x, aSize.y ) );

    if( textPensize >= 0 )
        textPensize = Clamp_Text_PenSize( aWidth, aSize, aBold );
    else
        textPensize = -Clamp_Text_PenSize( -aWidth, aSize, aBold );

    SetCurrentLineWidth( textPensize, aData );

    SetColor( aColor );

    DrawGraphicText( NULL, NULL, aPos, aColor, aText,
                     aOrient, aSize,
                     aH_justify, aV_justify,
                     textPensize, aItalic, aBold, NULL, this );

    if( aWidth != textPensize )
        SetCurrentLineWidth( aWidth, aData );
}
void PSLIKE_PLOTTER::FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize,
                                     SHAPE_POLY_SET* aPolygons,
                                     EDA_DRAW_MODE_T aTraceMode, void* aData )
{
    wxSize size( aSize );

    if( aTraceMode == FILLED )
        SetCurrentLineWidth( 0 );
    else
    {
        SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH );
        size.x -= GetCurrentLineWidth();
        size.y -= GetCurrentLineWidth();
    }


    std::vector< wxPoint > cornerList;

    for( int cnt = 0; cnt < aPolygons->OutlineCount(); ++cnt )
    {
        SHAPE_LINE_CHAIN& poly = aPolygons->Outline( cnt );
        cornerList.clear();

        for( int ii = 0; ii < poly.PointCount(); ++ii )
            cornerList.push_back( wxPoint( poly.Point( ii ).x, poly.Point( ii ).y ) );

        // Close polygon
        cornerList.push_back( cornerList[0] );

        PlotPoly( cornerList, ( aTraceMode == FILLED ) ? FILLED_SHAPE : NO_FILL,
                  GetCurrentLineWidth() );
    }
}
void PLOTTER::ThickSegment( const wxPoint& start, const wxPoint& end, int width,
                            EDA_DRAW_MODE_T tracemode )
{
    if( tracemode == FILLED )
    {
        SetCurrentLineWidth( width );
        MoveTo( start );
        FinishTo( end );
    }
    else
    {
        SetCurrentLineWidth( -1 );
        segmentAsOval( start, end, width, tracemode );
    }
}
void PSLIKE_PLOTTER::FlashPadRect( const wxPoint& aPadPos, const wxSize& aSize,
                                   double aPadOrient, EDA_DRAW_MODE_T aTraceMode, void* aData )
{
    static std::vector< wxPoint > cornerList;
    wxSize size( aSize );
    cornerList.clear();

    if( aTraceMode == FILLED )
        SetCurrentLineWidth( 0 );
    else
        SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH );

    size.x -= GetCurrentLineWidth();
    size.y -= GetCurrentLineWidth();

    if( size.x < 1 )
        size.x = 1;

    if( size.y < 1 )
        size.y = 1;

    int dx = size.x / 2;
    int dy = size.y / 2;

    wxPoint corner;
    corner.x = aPadPos.x - dx;
    corner.y = aPadPos.y + dy;
    cornerList.push_back( corner );
    corner.x = aPadPos.x - dx;
    corner.y = aPadPos.y - dy;
    cornerList.push_back( corner );
    corner.x = aPadPos.x + dx;
    corner.y = aPadPos.y - dy;
    cornerList.push_back( corner );
    corner.x = aPadPos.x + dx;
    corner.y = aPadPos.y + dy,
    cornerList.push_back( corner );

    for( unsigned ii = 0; ii < cornerList.size(); ii++ )
    {
        RotatePoint( &cornerList[ii], aPadPos, aPadOrient );
    }

    cornerList.push_back( cornerList[0] );

    PlotPoly( cornerList, ( aTraceMode == FILLED ) ? FILLED_SHAPE : NO_FILL,
              GetCurrentLineWidth() );
}
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.
}
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" );
}
Esempio n. 8
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 );
}
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 );
    }
}
Esempio n. 10
0
void PLOTTER::Arc( const wxPoint& centre, double StAngle, double EndAngle, int radius,
                   FILL_T fill, int width )
{
    wxPoint   start, end;
    const int delta = 50;   // increment (in 0.1 degrees) to draw circles

    if( StAngle > EndAngle )
        std::swap( StAngle, EndAngle );

    SetCurrentLineWidth( width );
    /* Please NOTE the different sign due to Y-axis flip */
    start.x = centre.x + KiROUND( cosdecideg( radius, -StAngle ) );
    start.y = centre.y + KiROUND( sindecideg( radius, -StAngle ) );
    MoveTo( start );
    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 ) );
        LineTo( end );
    }

    end.x = centre.x + KiROUND( cosdecideg( radius, -EndAngle ) );
    end.y = centre.y + KiROUND( sindecideg( radius, -EndAngle ) );
    FinishTo( end );
}
Esempio n. 11
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;
    }
}
Esempio n. 12
0
void PSLIKE_PLOTTER::FlashPadCircle( const wxPoint& pos, int diametre,
                                     EDA_DRAW_MODE_T modetrace )
{
    int current_line_width;
    wxASSERT( outputFile );

    SetCurrentLineWidth( -1 );
    current_line_width = GetCurrentLineWidth();
    if( current_line_width > diametre )
        current_line_width = diametre;

    if( modetrace == FILLED )
        Circle( pos, diametre - currentPenWidth, FILLED_SHAPE, current_line_width );
    else
        Circle( pos, diametre - currentPenWidth, NO_FILL, current_line_width );

    SetCurrentLineWidth( -1 );
}
Esempio n. 13
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 );
}
Esempio n. 14
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 );
}
void PSLIKE_PLOTTER::FlashPadTrapez( const wxPoint& aPadPos, const wxPoint *aCorners,
                                     double aPadOrient, EDA_DRAW_MODE_T aTraceMode, void* aData )
{
    static std::vector< wxPoint > cornerList;
    cornerList.clear();

    for( int ii = 0; ii < 4; ii++ )
        cornerList.push_back( aCorners[ii] );

    if( aTraceMode == FILLED )
    {
        SetCurrentLineWidth( 0 );
    }
    else
    {
        SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH );
        int w = GetCurrentLineWidth();
        // offset polygon by w
        // 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. */
        cornerList[0].x += w;
        cornerList[0].y -= w;
        cornerList[1].x += w;
        cornerList[1].y += w;
        cornerList[2].x -= w;
        cornerList[2].y += w;
        cornerList[3].x -= w;
        cornerList[3].y -= w;
    }

    for( int ii = 0; ii < 4; ii++ )
    {
        RotatePoint( &cornerList[ii], aPadOrient );
        cornerList[ii] += aPadPos;
    }

    cornerList.push_back( cornerList[0] );
    PlotPoly( cornerList, ( aTraceMode == FILLED ) ? FILLED_SHAPE : NO_FILL,
              GetCurrentLineWidth() );
}
void PSLIKE_PLOTTER::FlashPadCircle( const wxPoint& aPadPos, int aDiameter,
                                     EDA_DRAW_MODE_T aTraceMode, void* aData )
{
    if( aTraceMode == FILLED )
        Circle( aPadPos, aDiameter, FILLED_SHAPE, 0 );
    else    // Plot a ring:
    {
        SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH );
        int linewidth = GetCurrentLineWidth();

        // avoid aDiameter <= 1 )
        if( linewidth > aDiameter-2 )
            linewidth = aDiameter-2;

        Circle( aPadPos, aDiameter - linewidth, NO_FILL, linewidth );
    }

    SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH );
}
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();
}
void GERBER_PLOTTER::FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize,
                                     SHAPE_POLY_SET* aPolygons,
                                     EDA_DRAW_MODE_T aTraceMode, void* aData )

{
    // A Pad custom is plotted as polygon.

    // A flashed circle @aPadPos is added (anchor pad)
    // However, because the anchor pad can be circle or rect, we use only
    // a circle not bigger than the rect.
    // the main purpose is to print a flashed DCode as pad anchor
    if( aTraceMode == FILLED )
        FlashPadCircle( aPadPos, std::min( aSize.x, aSize.y ), aTraceMode, aData );

    GBR_METADATA gbr_metadata;

    if( aData )
    {
        gbr_metadata = *static_cast<GBR_METADATA*>( aData );
        // If the pad is drawn on a copper layer,
        // set attribute to GBR_APERTURE_ATTRIB_CONDUCTOR
        if( gbr_metadata.IsCopper() )
            gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_CONDUCTOR );

        wxString attrname( ".P" );
        gbr_metadata.m_NetlistMetadata.ClearAttribute( &attrname );   // not allowed on inner layers
    }

    SHAPE_POLY_SET polyshape = *aPolygons;

    if( aTraceMode != FILLED )
    {
        SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH, &gbr_metadata );
        polyshape.Inflate( -GetCurrentLineWidth()/2, 16 );
    }

    std::vector< wxPoint > cornerList;

    for( int cnt = 0; cnt < polyshape.OutlineCount(); ++cnt )
    {
        SHAPE_LINE_CHAIN& poly = polyshape.Outline( cnt );

        cornerList.clear();

        for( int ii = 0; ii < poly.PointCount(); ++ii )
            cornerList.push_back( wxPoint( poly.Point( ii ).x, poly.Point( ii ).y ) );

        // Close polygon
        cornerList.push_back( cornerList[0] );

        PlotPoly( cornerList,
                  aTraceMode == FILLED ? FILLED_SHAPE : NO_FILL,
                  aTraceMode == FILLED ? 0 : GetCurrentLineWidth(), &gbr_metadata );
    }
}
/**
 * Function start_plot
 * Write GERBER header to file
 * initialize global variable g_Plot_PlotOutputFile
 */
bool GERBER_PLOTTER::StartPlot()
{
    wxASSERT( outputFile );

    finalFile = outputFile;     // the actual gerber file will be created later

    // Create a temporary filename to store gerber file
    // note tmpfile() does not work under Vista and W7 in user mode
    m_workFilename = filename + wxT(".tmp");
    workFile   = wxFopen( m_workFilename, wxT( "wt" ));
    outputFile = workFile;
    wxASSERT( outputFile );

    if( outputFile == NULL )
        return false;

    if( ! m_attribFunction.IsEmpty() )
    {
        fprintf( outputFile, "%%TF.FileFunction,%s*%%\n",
                 TO_UTF8( m_attribFunction ) );
    }

    // Set coordinate format to 3.6 or 4.5 absolute, leading zero omitted
    // the number of digits for the integer part of coordintes is needed
    // in gerber format, but is not very important when omitting leading zeros
    // It is fixed here to 3 (inch) or 4 (mm), but is not actually used
    int leadingDigitCount = m_gerberUnitInch ? 3 : 4;

    fprintf( outputFile, "%%FSLAX%d%dY%d%d*%%\n",
             leadingDigitCount, m_gerberUnitFmt,
             leadingDigitCount, m_gerberUnitFmt );
    fprintf( outputFile,
             "G04 Gerber Fmt %d.%d, Leading zero omitted, Abs format (unit %s)*\n",
             leadingDigitCount, m_gerberUnitFmt,
             m_gerberUnitInch ? "inch" : "mm" );

    wxString Title = creator + wxT( " " ) + GetBuildVersion();
    fprintf( outputFile, "G04 Created by KiCad (%s) date %s*\n",
             TO_UTF8( Title ), TO_UTF8( DateAndTime() ) );

    /* Mass parameter: unit = INCHES/MM */
    if( m_gerberUnitInch )
        fputs( "%MOIN*%\n", outputFile );
    else
        fputs( "%MOMM*%\n", outputFile );

    /* Specify linear interpol (G01) */
    fputs( "G01*\n", outputFile );
    fputs( "G04 APERTURE LIST*\n", outputFile );
    /* Select the default aperture */
    SetCurrentLineWidth( -1 );

    return true;
}
void GERBER_PLOTTER::ThickSegment( const wxPoint& start, const wxPoint& end, int width,
                            EDA_DRAW_MODE_T tracemode, void* aData )
{
    if( tracemode == FILLED )
    {
        GBR_METADATA *gbr_metadata = static_cast<GBR_METADATA*>( aData );
        SetCurrentLineWidth( width, gbr_metadata );

        if( gbr_metadata )
            formatNetAttribute( &gbr_metadata->m_NetlistMetadata );

        MoveTo( start );
        FinishTo( end );
    }
    else
    {
        SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH );
        segmentAsOval( start, end, width, tracemode );
    }
}
void GERBER_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSize,
                                     int aCornerRadius, double aOrient,
                                     EDA_DRAW_MODE_T aTraceMode, void* aData )

{
    GBR_METADATA gbr_metadata;

    if( aData )
    {
        gbr_metadata = *static_cast<GBR_METADATA*>( aData );
        // If the pad is drawn on a copper layer,
        // set attribute to GBR_APERTURE_ATTRIB_CONDUCTOR
        if( gbr_metadata.IsCopper() )
            gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_CONDUCTOR );

        wxString attrname( ".P" );
        gbr_metadata.m_NetlistMetadata.ClearAttribute( &attrname );   // not allowed on inner layers
    }

    if( aTraceMode != FILLED )
        SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH, &gbr_metadata );

    // Currently, a Pad RoundRect is plotted as polygon.
    // TODO: use Aperture macro and flash it
    SHAPE_POLY_SET outline;
    const int segmentToCircleCount = 64;
    TransformRoundRectToPolygon( outline, aPadPos, aSize, aOrient,
                                 aCornerRadius, segmentToCircleCount );

    if( aTraceMode != FILLED )
        outline.Inflate( -GetCurrentLineWidth()/2, 16 );

    std::vector< wxPoint > cornerList;
    // TransformRoundRectToPolygon creates only one convex polygon
    SHAPE_LINE_CHAIN& poly = outline.Outline( 0 );
    cornerList.reserve( poly.PointCount() + 1 );

    for( int ii = 0; ii < poly.PointCount(); ++ii )
        cornerList.push_back( wxPoint( poly.Point( ii ).x, poly.Point( ii ).y ) );

    // Close polygon
    cornerList.push_back( cornerList[0] );

    PlotPoly( cornerList, aTraceMode == FILLED ? FILLED_SHAPE : NO_FILL,
              aTraceMode == FILLED ? 0 : GetCurrentLineWidth(), &gbr_metadata );

    // Now, flash a pad anchor, if a netlist attribute is set
    // (remove me when a Aperture macro will be used)
    if( aData && aTraceMode == FILLED )
    {
        int diameter = std::min( aSize.x, aSize.y );
        FlashPadCircle( aPadPos, diameter, aTraceMode , aData );
    }
}
void GERBER_PLOTTER::ThickCircle( const wxPoint& pos, int diametre, int width,
                              EDA_DRAW_MODE_T tracemode, void* aData )
{
    GBR_METADATA *gbr_metadata = static_cast<GBR_METADATA*>( aData );
    SetCurrentLineWidth( width, gbr_metadata );

    if( gbr_metadata )
        formatNetAttribute( &gbr_metadata->m_NetlistMetadata );

    if( tracemode == FILLED )
        Circle( pos, diametre, NO_FILL, DO_NOT_SET_LINE_WIDTH );
    else
    {
        SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH, gbr_metadata );
        Circle( pos, diametre - (width - currentPenWidth),
                    NO_FILL, DO_NOT_SET_LINE_WIDTH );
        Circle( pos, diametre + (width - currentPenWidth),
                    NO_FILL, DO_NOT_SET_LINE_WIDTH );
    }
}
Esempio n. 23
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' );
}
Esempio n. 24
0
void PLOTTER::ThickCircle( const wxPoint& pos, int diametre, int width, EDA_DRAW_MODE_T tracemode )
{
    if( tracemode == FILLED )
        Circle( pos, diametre, NO_FILL, width );
    else
    {
        SetCurrentLineWidth( -1 );
        Circle( pos, diametre - width + currentPenWidth, NO_FILL, -1 );
        Circle( pos, diametre + width - currentPenWidth, NO_FILL, -1 );
    }
}
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 GERBER_PLOTTER::ThickArc( const wxPoint& centre, double StAngle, double EndAngle,
                           int radius, int width, EDA_DRAW_MODE_T tracemode, void* aData )
{
    GBR_METADATA *gbr_metadata = static_cast<GBR_METADATA*>( aData );
    SetCurrentLineWidth( width, gbr_metadata );

    if( gbr_metadata )
        formatNetAttribute( &gbr_metadata->m_NetlistMetadata );

    if( tracemode == FILLED )
        Arc( centre, StAngle, EndAngle, radius, NO_FILL, DO_NOT_SET_LINE_WIDTH );
    else
    {
        SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH );
        Arc( centre, StAngle, EndAngle,
             radius - ( width - currentPenWidth ) / 2,
             NO_FILL, DO_NOT_SET_LINE_WIDTH );
        Arc( centre, StAngle, EndAngle,
             radius + ( width - currentPenWidth ) / 2, NO_FILL,
             DO_NOT_SET_LINE_WIDTH );
    }
}
Esempio n. 27
0
void PLOTTER::ThickArc( const wxPoint& centre, double StAngle, double EndAngle,
                        int radius, int width, EDA_DRAW_MODE_T tracemode )
{
    if( tracemode == FILLED )
        Arc( centre, StAngle, EndAngle, radius, NO_FILL, width );
    else
    {
        SetCurrentLineWidth( -1 );
        Arc( centre, StAngle, EndAngle,
             radius - ( width - currentPenWidth ) / 2, NO_FILL, -1 );
        Arc( centre, StAngle, EndAngle,
             radius + ( width - currentPenWidth ) / 2, NO_FILL, -1 );
    }
}
void PSLIKE_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSize,
                                        int aCornerRadius, double aOrient,
                                        EDA_DRAW_MODE_T aTraceMode, void* aData )
{
    wxSize size( aSize );

    if( aTraceMode == FILLED )
        SetCurrentLineWidth( 0 );
    else
    {
        SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH );
        size.x -= GetCurrentLineWidth();
        size.y -= GetCurrentLineWidth();
        aCornerRadius -= GetCurrentLineWidth()/2;
    }


    SHAPE_POLY_SET outline;
    const int segmentToCircleCount = 64;
    TransformRoundRectToPolygon( outline, aPadPos, size, aOrient,
                                 aCornerRadius, segmentToCircleCount );

    std::vector< wxPoint > cornerList;
    cornerList.reserve( segmentToCircleCount + 5 );
    // TransformRoundRectToPolygon creates only one convex polygon
    SHAPE_LINE_CHAIN& poly = outline.Outline( 0 );

    for( int ii = 0; ii < poly.PointCount(); ++ii )
        cornerList.push_back( wxPoint( poly.Point( ii ).x, poly.Point( ii ).y ) );

    // Close polygon
    cornerList.push_back( cornerList[0] );

    PlotPoly( cornerList, ( aTraceMode == FILLED ) ? FILLED_SHAPE : NO_FILL,
              GetCurrentLineWidth() );
}
Esempio n. 29
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 );
    }
}
Esempio n. 30
0
void PLOTTER::sketchOval( const wxPoint& pos, const wxSize& aSize, double orient, int width )
{
    SetCurrentLineWidth( width );
    width = currentPenWidth;
    int radius, deltaxy, cx, cy;
    wxSize size( aSize );

    if( size.x > size.y )
    {
        std::swap( size.x, size.y );
        orient = AddAngles( orient, 900 );
    }

    deltaxy = size.y - size.x;       /* distance between centers of the oval */
    radius   = ( size.x - width ) / 2;
    cx = -radius;
    cy = -deltaxy / 2;
    RotatePoint( &cx, &cy, orient );
    MoveTo( wxPoint( cx + pos.x, cy + pos.y ) );
    cx = -radius;
    cy = deltaxy / 2;
    RotatePoint( &cx, &cy, orient );
    FinishTo( wxPoint( cx + pos.x, cy + pos.y ) );

    cx = radius;
    cy = -deltaxy / 2;
    RotatePoint( &cx, &cy, orient );
    MoveTo( wxPoint( cx + pos.x, cy + pos.y ) );
    cx = radius;
    cy = deltaxy / 2;
    RotatePoint( &cx, &cy, orient );
    FinishTo( wxPoint( cx + pos.x, cy + pos.y ) );

    cx = 0;
    cy = deltaxy / 2;
    RotatePoint( &cx, &cy, orient );
    Arc( wxPoint( cx + pos.x, cy + pos.y ),
         orient + 1800, orient + 3600,
         radius, NO_FILL );
    cx = 0;
    cy = -deltaxy / 2;
    RotatePoint( &cx, &cy, orient );
    Arc( wxPoint( cx + pos.x, cy + pos.y ),
         orient, orient + 1800,
         radius, NO_FILL );
}