Commit f7a804e2 authored by charras's avatar charras
Browse files

Bugfix for plotting

parent 11d9edfe
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ set(COMMON_SRCS
    common_plotHPGL_functions.cpp
    common_plotPS_functions.cpp
    common_plotGERBER_functions.cpp
    common_plotDXF_functions.cpp
    confirm.cpp
    copy_to_clipboard.cpp
    dcsvg.cpp
+374 −0
Original line number Diff line number Diff line
/******************************************/
/* Kicad: Common plot DXF Routines */
/******************************************/

#include "fctsys.h"
#include "gr_basic.h"
#include "trigo.h"
#include "wxstruct.h"
#include "base_struct.h"
#include "plot_common.h"
#include "macros.h"
#include "kicad_string.h"

/***********************************************************************************/
void DXF_Plotter::set_viewport( wxPoint offset,
                                double aScale, int orient )
/***********************************************************************************/

/* Set the plot offset for the current plotting
 */
{
    wxASSERT( !output_file );
    plot_offset  = offset;
    plot_scale   = aScale;
    device_scale = 1;
    set_default_line_width( 0 );    /* No line width on DXF */
    plot_orient_options = 0;        /* No mirroring on DXF */
    current_color = BLACK;
}


/*****************************************************************/
void DXF_Plotter::start_plot( FILE* fout )
/*****************************************************************/
{
    wxASSERT( !output_file );
    output_file = fout;
    /* DXF HEADER - Boilerplate */
    fputs(
        "0\nSECTION\n2\nHEADER\n9\n$ANGBASE\n50\n0.0\n9\n$ANGDIR\n70\n0\n0\nENDSEC\n0\nSECTION\n2\nTABLES\n0\nTABLE\n2\nLTYPE\n70\n1\n0\nLTYPE\n2\nCONTINUOUS\n70\n0\n3\nSolid line\n72\n65\n73\n0\n40\n0.0\n0\nENDTAB\n",
        output_file );
    /* Layer table - one layer per color */
    fprintf( output_file, "0\nTABLE\n2\nLAYER\n70\n%d\n", NBCOLOR );
    for( int i = 0; i<NBCOLOR; i++ )
    {
        fprintf( output_file, "0\nLAYER\n2\n%s\n70\n0\n62\n%d\n6\nCONTINUOUS\n",
                 CONV_TO_UTF8( ColorRefs[i].m_Name ), i + 1 );
    }

    /* End of layer table, begin entities */
    fputs( "0\nENDTAB\n0\nENDSEC\n0\nSECTION\n2\nENTITIES\n", output_file );
}


/**********************************/
void DXF_Plotter::end_plot()
/**********************************/
{
    wxASSERT( output_file );
    /* DXF FOOTER */
    fputs( "0\nENDSEC\n0\nEOF\n", output_file );
    fclose( output_file );
    output_file = 0;
}


/******************************/
void DXF_Plotter::set_color( int color )
/******************************/

/*
 * color = color index in ColorRefs[]
 */
{
    wxASSERT( output_file );
    if( (color >= 0 && color_mode)
       || (color == BLACK)
       || (color == WHITE) )
    {
        current_color = color;
    }
}


/************************************************************/
void DXF_Plotter::rect( wxPoint p1, wxPoint p2, FILL_T fill, int width )
/************************************************************/
{
    wxASSERT( output_file );
    move_to( p1 );
    line_to( wxPoint( p1.x, p2.y ) );
    line_to( wxPoint( p2.x, p2.y ) );
    line_to( wxPoint( p2.x, p1.y ) );
    finish_to( wxPoint( p1.x, p1.y ) );
}


/************************************************************/
void DXF_Plotter::circle( wxPoint centre, int diameter, FILL_T fill, int width )
/************************************************************/
{
    wxASSERT( output_file );
    double rayon = user_to_device_size( diameter / 2 );
    user_to_device_coordinates( centre );
    if( rayon > 0 )
    {
        fprintf( output_file, "0\nCIRCLE\n8\n%s\n10\n%d.0\n20\n%d.0\n40\n%g\n",
                 CONV_TO_UTF8( ColorRefs[current_color].m_Name ),
                 centre.x, centre.y, rayon );
    }
}


/*****************************************************/
void DXF_Plotter::poly( int nb, int* coord, FILL_T fill, int width )
/*****************************************************/

/* Trace un polygone (ferme si rempli) en format DXF
 * coord = tableau des coord des sommets
 * nb = nombre de coord ( 1 coord = 2 elements: X et Y du tableau )
 * fill : si != 0 polygone rempli
 */
{
    wxASSERT( output_file );
    if( nb <= 1 )
        return;

    move_to( wxPoint( coord[0], coord[1] ) );
    for( int ii = 1; ii < nb; ii++ )
        line_to( wxPoint( coord[ii * 2], coord[(ii * 2) + 1] ) );

    /* Fermeture eventuelle du polygone */
    if( fill )
    {
        int ii = (nb - 1) * 2;
        if( (coord[ii] != coord[0] ) || (coord[ii + 1] != coord[1]) )
            line_to( wxPoint( coord[0], coord[1] ) );
    }
    pen_finish();
}


/**********************************************/
void DXF_Plotter::pen_to( wxPoint pos, char plume )
/**********************************************/

/*
 * deplace la plume levee (plume = 'U') ou baissee (plume = 'D')
 * en position x,y
 * Unites en Unites DESSIN
 * Si plume = 'Z' lever de plume sans deplacement
 */
{
    wxASSERT( output_file );
    if( plume == 'Z' )
    {
        return;
    }
    user_to_device_coordinates( pos );

    if( pen_lastpos != pos && plume == 'D' )
    {
        /* DXF LINE */
        fprintf( output_file, "0\nLINE\n8\n%s\n10\n%d.0\n20\n%d.0\n11\n%d.0\n21\n%d.0\n",
                 CONV_TO_UTF8( ColorRefs[current_color].m_Name ),
                 pen_lastpos.x, pen_lastpos.y, pos.x, pos.y );
    }
    pen_lastpos = pos;
}


void DXF_Plotter::set_dash( bool dashed )
{
    /* NOP for now */
    wxASSERT( output_file );
}


void DXF_Plotter::thick_segment( wxPoint start, wxPoint end, int width,
                                 GRTraceMode tracemode )

/** Function Plot a filled segment (track)
 * @param start = starting point
 * @param end = ending point
 * @param aWidth = segment width (thickness)
 * @param aPlotMode = FILLED, SKETCH ..
 */
{
    wxASSERT( output_file );

    if( tracemode == FILAIRE )  /* just a line is Ok */
    {
        move_to( start );
        finish_to( end );
    }
    else
        segment_as_oval( start, end, width, tracemode );
}


/********************************************************************/
void DXF_Plotter::arc( wxPoint centre, int StAngle, int EndAngle, int rayon,
                       FILL_T fill, int width )
/********************************************************************/

/* trace d'un arc de cercle:
 * centre = coord du centre
 * StAngle, EndAngle = angle de debut et fin
 * rayon = rayon de l'arc
 */
{
    wxASSERT( output_file );

    if( rayon <= 0 )
        return;

    user_to_device_coordinates( centre );
    rayon = user_to_device_size( rayon );

    /* DXF ARC */
    fprintf( output_file, "0\nARC\n8\n%s\n10\n%d.0\n20\n%d.0\n40\n%d.0\n50\n%d.0\n51\n%d.0\n",
             CONV_TO_UTF8( ColorRefs[current_color].m_Name ),
             centre.x, centre.y, rayon,
             StAngle / 10, EndAngle / 10 );
}


/***********************************************************************************/
void DXF_Plotter::flash_pad_oval( wxPoint pos, wxSize size, int orient,
                                  GRTraceMode trace_mode )
/************************************************************************************/
/* Trace 1 pastille PAD_OVAL en position pos_X,Y , de dim size.x, size.y */
{
    wxASSERT( output_file );

    /* la pastille est ramenee a une pastille ovale avec size.y > size.x
     *  ( ovale vertical en orientation 0 ) */
    if( size.x > size.y )
    {
        EXCHG( size.x, size.y ); orient += 900;
        if( orient >= 3600 )
            orient -= 3600;
    }
    sketch_oval( pos, size, orient, -1 );
}


/*******************************************************************************/
void DXF_Plotter::flash_pad_circle( wxPoint pos, int diametre,
                                    GRTraceMode trace_mode )
/*******************************************************************************/
/* Trace 1 pastille RONDE (via,pad rond) en position pos */
{
    wxASSERT( output_file );
    circle( pos, diametre, NO_FILL );
}


/**************************************************************************/
void DXF_Plotter::flash_pad_rect( wxPoint pos, wxSize padsize,
                                  int orient, GRTraceMode trace_mode )
/**************************************************************************/

/*
 *  Trace 1 pad rectangulaire vertical ou horizontal ( Pad rectangulaire )
 *  donne par son centre et ses dimensions X et Y
 *  Units are user units
 */
{
    wxASSERT( output_file );
    wxSize size;
    int    ox, oy, fx, fy;

    size.x = padsize.x / 2;  size.y = padsize.y / 2;

    if( size.x < 0 )
        size.x = 0;
    if( size.y < 0 )
        size.y = 0;

    /* Si une des dimensions est nulle, le trace se reduit a 1 trait */
    if( size.x == 0 )
    {
        ox = pos.x; oy = pos.y - size.y;
        RotatePoint( &ox, &oy, pos.x, pos.y, orient );
        fx = pos.x; fy = pos.y + size.y;
        RotatePoint( &fx, &fy, pos.x, pos.y, orient );
        move_to( wxPoint( ox, oy ) );
        finish_to( wxPoint( fx, fy ) );
        return;
    }
    if( size.y == 0 )
    {
        ox = pos.x - size.x; oy = pos.y;
        RotatePoint( &ox, &oy, pos.x, pos.y, orient );
        fx = pos.x + size.x; fy = pos.y;
        RotatePoint( &fx, &fy, pos.x, pos.y, orient );
        move_to( wxPoint( ox, oy ) );
        finish_to( wxPoint( fx, fy ) );
        return;
    }

    ox = pos.x - size.x; oy = pos.y - size.y;
    RotatePoint( &ox, &oy, pos.x, pos.y, orient );
    move_to( wxPoint( ox, oy ) );

    fx = pos.x - size.x; fy = pos.y + size.y;
    RotatePoint( &fx, &fy, pos.x, pos.y, orient );
    line_to( wxPoint( fx, fy ) );

    fx = pos.x + size.x; fy = pos.y + size.y;
    RotatePoint( &fx, &fy, pos.x, pos.y, orient );
    line_to( wxPoint( fx, fy ) );

    fx = pos.x + size.x; fy = pos.y - size.y;
    RotatePoint( &fx, &fy, pos.x, pos.y, orient );
    line_to( wxPoint( fx, fy ) );

    finish_to( wxPoint( ox, oy ) );
}


/*******************************************************************/
void DXF_Plotter::flash_pad_trapez( wxPoint pos, wxSize size, wxSize delta,
                                    int orient, GRTraceMode trace_mode )
/*******************************************************************/

/*
 *  Trace 1 pad trapezoidal donne par :
 *  son centre pos.x,pos.y
 *  ses dimensions dimX et dimY
 *  les variations deltaX et deltaY
 *  son orientation orient et 0.1 degres
 *  le mode de trace (FILLED, SKETCH, FILAIRE)
 *  Le trace n'est fait que pour un trapeze, c.a.d que deltaX ou deltaY
 *  = 0.
 *
 *  les notation des sommets sont ( vis a vis de la table tracante )
 *      0 ------------- 3
 *        .			   .
 *          .		  .
 *           .		 .
 *            1 --- 2
 */
{
    wxASSERT( output_file );
    wxPoint polygone[4];    /* coord des sommets / centre du pad */
    wxPoint coord[4];       /* coord reelles des sommets du trapeze a tracer */
    int     moveX, moveY; /* variation de position plume selon axe X et Y , lors
                           *  du remplissage du trapeze */
    moveX = moveY = 0;

    size.x  /= 2;  size.y /= 2;
    delta.x /= 2; delta.y /= 2;

    polygone[0].x = -size.x - delta.y; polygone[0].y = +size.y + delta.x;
    polygone[1].x = -size.x + delta.y; polygone[1].y = -size.y - delta.x;
    polygone[2].x = +size.x - delta.y; polygone[2].y = -size.y + delta.x;
    polygone[3].x = +size.x + delta.y; polygone[3].y = +size.y - delta.x;

    for( int ii = 0; ii < 4; ii++ )
    {
        coord[ii].x = polygone[ii].x + pos.x;
        coord[ii].y = polygone[ii].y + pos.y;
        RotatePoint( &coord[ii], pos, orient );
    }

    // Plot edge:
    move_to( coord[0] );
    line_to( coord[1] );
    line_to( coord[2] );
    line_to( coord[3] );
    finish_to( coord[0] );
}
+1 −0
Original line number Diff line number Diff line
@@ -95,6 +95,7 @@ set(EESCHEMA_SRCS
    plot.cpp
    plothpgl.cpp
    plotps.cpp
    plotdxf.cpp
    priorque.cpp
    read_from_file_schematic_items_descriptions.cpp
    savelib.cpp
+6 −0
Original line number Diff line number Diff line
@@ -91,6 +91,12 @@ void WinEDA_SchematicFrame::ReCreateMenuBar()
    item->SetBitmap( plot_xpm );
    choice_plot_fmt->Append( item );

    item = new wxMenuItem( choice_plot_fmt, ID_GEN_PLOT_DXF, _( "Plot DXF" ),
                           _( "Plot schematic sheet in DXF format" ) );
    item->SetBitmap( plot_xpm );
    choice_plot_fmt->Append( item );


#ifdef __WINDOWS__
    /* Under windows, one can draw to the clipboard */
    item = new wxMenuItem( choice_plot_fmt, ID_GEN_COPY_SHEET_TO_CLIPBOARD,
+19 −12
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@ static void PlotLibPart( Plotter* plotter, SCH_COMPONENT* DrawLibItem )
    Multi   = DrawLibItem->m_Multi;
    convert = DrawLibItem->m_Convert;

    plotter->set_current_line_width( g_DrawDefaultLineThickness );
    for( LibEDA_BaseStruct* DEntry = Entry->m_Drawings;
        DEntry != NULL; DEntry = DEntry->Next() )
    {
@@ -88,12 +89,12 @@ static void PlotLibPart( Plotter* plotter, SCH_COMPONENT* DrawLibItem )
            if( draw_bgfill && Arc->m_Fill == FILLED_WITH_BG_BODYCOLOR )
            {
                plotter->set_color( ReturnLayerColor( LAYER_DEVICE_BACKGROUND ) );
                plotter->arc( pos, t1, t2, Arc->m_Rayon, FILLED_SHAPE, 0 );
                plotter->arc( pos, -t1, -t2, Arc->m_Rayon, FILLED_SHAPE, 0 );
            }
            plotter->set_color( ReturnLayerColor( LAYER_DEVICE ) );
            plotter->arc( pos,
                          t1,
                          t2,
                          -t1,
                          -t2,
                          Arc->m_Rayon,
                          Arc->m_Fill,
                          Arc->m_Width );
@@ -713,19 +714,25 @@ void PlotDrawlist( Plotter* plotter, SCH_ITEM* drawlist )
        switch( drawlist->Type() )
        {
        case DRAW_BUSENTRY_STRUCT_TYPE:             /* Struct Raccord et Segment sont identiques */
        case DRAW_SEGMENT_STRUCT_TYPE:
            if( drawlist->Type() == DRAW_BUSENTRY_STRUCT_TYPE )
            {
            #undef STRUCT
            #define STRUCT ( (DrawBusEntryStruct*) drawlist )
                StartPos = STRUCT->m_Pos;
                EndPos   = STRUCT->m_End();
                layer    = STRUCT->GetLayer();

        case DRAW_SEGMENT_STRUCT_TYPE:
                plotter->set_color( ReturnLayerColor( layer ) );
            }
            else
            {
            #undef STRUCT
            #define STRUCT ( (EDA_DrawLineStruct*) drawlist )
                StartPos = STRUCT->m_Start;
                EndPos   = STRUCT->m_End;
                layer    = STRUCT->GetLayer();
                plotter->set_color( ReturnLayerColor( layer ) );
            }

            switch( layer )
            {
Loading