Beispiel #1
0
void AddGerberX2Attribute( PLOTTER * aPlotter,
            const BOARD *aBoard, LAYER_NUM aLayer, bool aUseX1CompatibilityMode )
{
    AddGerberX2Header( aPlotter, aBoard, aUseX1CompatibilityMode );

    wxString text;

    // Add the TF.FileFunction
    text = GetGerberFileFunctionAttribute( aBoard, aLayer );
    aPlotter->AddLineToHeader( makeStringCompatX1( text, aUseX1CompatibilityMode ) );

    // Add the TF.FilePolarity (for layers which support that)
    text = GetGerberFilePolarityAttribute( aLayer );

    if( !text.IsEmpty() )
        aPlotter->AddLineToHeader( makeStringCompatX1( text, aUseX1CompatibilityMode ) );
}
void AddGerberX2Attribute( PLOTTER * aPlotter,
            const BOARD *aBoard, LAYER_NUM aLayer, bool aUseX1CompatibilityMode )
{
    wxString text;

    // Creates the TF,.GenerationSoftware. Format is:
    // %TF,.GenerationSoftware,<vendor>,<application name>[,<application version>]*%
    text.Printf( wxT( "%%TF.GenerationSoftware,KiCad,Pcbnew,%s*%%" ), GetBuildVersion() );
    aPlotter->AddLineToHeader( makeStringCompatX1( text, aUseX1CompatibilityMode ) );

    // creates the TF.CreationDate ext:
    // The attribute value must conform to the full version of the ISO 8601
    // date and time format, including time and time zone. Note that this is
    // the date the Gerber file was effectively created,
    // not the time the project of PCB was started
    wxDateTime date( wxDateTime::GetTimeNow() );
    // Date format: see http://www.cplusplus.com/reference/ctime/strftime
    wxString msg = date.Format( wxT( "%z" ) );  // Extract the time zone offset
    // The time zone offset format is + (or -) mm or hhmm  (mm = number of minutes, hh = number of hours)
    // we want +(or -) hh:mm
    if( msg.Len() > 3 )
        msg.insert( 3, ":", 1 ),
    text.Printf( wxT( "%%TF.CreationDate,%s%s*%%" ), GetChars( date.FormatISOCombined() ), GetChars( msg ) );
    aPlotter->AddLineToHeader( makeStringCompatX1( text, aUseX1CompatibilityMode ) );

    // Creates the TF,.ProjectId. Format is (from Gerber file format doc):
    // %TF.ProjectId,<project id>,<project GUID>,<revision id>*%
    // <project id> is the name of the project, restricted to basic ASCII symbols only,
    // and comma not accepted
    // All illegal chars will be replaced by underscore
    // <project GUID> is a 32 hexadecimal digits string which is an unique id of a project.
    // This is a random 128-bit number expressed in 32 hexadecimal digits.
    // See en.wikipedia.org/wiki/GUID for more information
    // However Kicad does not handle such a project GUID, so it is built from the board name
    // Rem: <project id> accepts only ASCII 7 code (only basic ASCII codes are allowed in gerber files).
    wxFileName fn = aBoard->GetFileName();
    msg = fn.GetFullName();
    wxString guid;

    // Build a 32 digits GUID from the board name:
    for( unsigned ii = 0; ii < msg.Len(); ii++ )
    {
        int cc1 = int( msg[ii] ) & 0x0F;
        int cc2 = ( int( msg[ii] ) >> 4) & 0x0F;
        guid << wxString::Format( wxT( "%X%X" ), cc2, cc1 );

        if( guid.Len() >= 32 )
            break;
    }

    // guid has 32 digits, so add missing digits
    int cnt = 32 - guid.Len();

    if( cnt > 0 )
        guid.Append( '0', cnt );

    // build the <project id> string: this is the board short filename (without ext)
    // and all non ASCII chars and comma are replaced by '_'
    msg = fn.GetName();
    msg.Replace( wxT( "," ), wxT( "_" ) );

    // build the <rec> string. All non ASCII chars and comma are replaced by '_'
    wxString rev = ((BOARD*)aBoard)->GetTitleBlock().GetRevision();
    rev.Replace( wxT( "," ), wxT( "_" ) );

    if( rev.IsEmpty() )
        rev = wxT( "rev?" );

    text.Printf( wxT( "%%TF.ProjectId,%s,%s,%s*%%" ), msg.ToAscii(), GetChars( guid ), rev.ToAscii() );
    aPlotter->AddLineToHeader( makeStringCompatX1( text, aUseX1CompatibilityMode ) );

    // Add the TF.FileFunction
    text = GetGerberFileFunctionAttribute( aBoard, aLayer );
    aPlotter->AddLineToHeader( makeStringCompatX1( text, aUseX1CompatibilityMode ) );

    // Add the TF.FilePolarity (for layers which support that)
    text = GetGerberFilePolarityAttribute( aLayer );

    if( !text.IsEmpty() )
        aPlotter->AddLineToHeader( makeStringCompatX1( text, aUseX1CompatibilityMode ) );
}
/** Open a new plotfile using the options (and especially the format)
 * specified in the options and prepare the page for plotting.
 * Return the plotter object if OK, NULL if the file is not created
 * (or has a problem)
 */
PLOTTER* StartPlotBoard( BOARD *aBoard, PCB_PLOT_PARAMS *aPlotOpts,
                         int aLayer,
                         const wxString& aFullFileName,
                         const wxString& aSheetDesc )
{
    // Create the plotter driver and set the few plotter specific
    // options
    PLOTTER*    plotter = NULL;

    switch( aPlotOpts->GetFormat() )
    {
    case PLOT_FORMAT_DXF:
        plotter = new DXF_PLOTTER();
        break;

    case PLOT_FORMAT_POST:
        PS_PLOTTER* PS_plotter;
        PS_plotter = new PS_PLOTTER();
        PS_plotter->SetScaleAdjust( aPlotOpts->GetFineScaleAdjustX(),
                                    aPlotOpts->GetFineScaleAdjustY() );
        plotter = PS_plotter;
        break;

    case PLOT_FORMAT_PDF:
        plotter = new PDF_PLOTTER();
        break;

    case PLOT_FORMAT_HPGL:
        HPGL_PLOTTER* HPGL_plotter;
        HPGL_plotter = new HPGL_PLOTTER();

        /* HPGL options are a little more convoluted to compute, so
           they're split in an other function */
        ConfigureHPGLPenSizes( HPGL_plotter, aPlotOpts );
        plotter = HPGL_plotter;
        break;

    case PLOT_FORMAT_GERBER:
        plotter = new GERBER_PLOTTER();
        break;

    case PLOT_FORMAT_SVG:
        plotter = new SVG_PLOTTER();
        break;

    default:
        wxASSERT( false );
        return NULL;
    }

    // Compute the viewport and set the other options

    // page layout is not mirrored, so temporary change mirror option
    // just to plot the page layout
    PCB_PLOT_PARAMS plotOpts = *aPlotOpts;

    if( plotOpts.GetPlotFrameRef() && plotOpts.GetMirror() )
        plotOpts.SetMirror( false );

    initializePlotter( plotter, aBoard, &plotOpts );

    if( plotter->OpenFile( aFullFileName ) )
    {
        plotter->ClearHeaderLinesList();

        // For the Gerber "file function" attribute, set the layer number
        if( plotter->GetPlotterType() == PLOT_FORMAT_GERBER )
        {
            bool useX2mode = plotOpts.GetUseGerberAttributes();

            if( useX2mode )
                AddGerberX2Attribute( plotter, aBoard, aLayer );
            else
                plotter->AddLineToHeader( GetGerberFileFunctionAttribute(
                                              aBoard, aLayer, true ) );
        }

        plotter->StartPlot();

        // Plot the frame reference if requested
        if( aPlotOpts->GetPlotFrameRef() )
        {
            PlotWorkSheet( plotter, aBoard->GetTitleBlock(),
                           aBoard->GetPageSettings(),
                           1, 1, // Only one page
                           aSheetDesc, aBoard->GetFileName() );

            if( aPlotOpts->GetMirror() )
                initializePlotter( plotter, aBoard, aPlotOpts );
        }

        /* When plotting a negative board: draw a black rectangle
         * (background for plot board in white) and switch the current
         * color to WHITE; note the color inversion is actually done
         * in the driver (if supported) */
        if( aPlotOpts->GetNegative() )
        {
            EDA_RECT bbox = aBoard->ComputeBoundingBox();
            FillNegativeKnockout( plotter, bbox );
        }

        return plotter;
    }

    delete plotter;
    return NULL;
}