Commit 85bc2ae0 authored by jean-pierre charras's avatar jean-pierre charras

Rework on Gerber plot functions: add X2 attributes in J5 version. Minor code cleaning.

parent 0b7fd874
...@@ -117,9 +117,10 @@ bool GERBER_PLOTTER::StartPlot() ...@@ -117,9 +117,10 @@ bool GERBER_PLOTTER::StartPlot()
if( outputFile == NULL ) if( outputFile == NULL )
return false; return false;
if( ! m_attribFunction.IsEmpty() ) for( unsigned ii = 0; ii < m_headerExtraLines.GetCount(); ii++ )
{ {
fprintf( outputFile, "%s\n", TO_UTF8( m_attribFunction ) ); if( ! m_headerExtraLines[ii].IsEmpty() )
fprintf( outputFile, "%s\n", TO_UTF8( m_headerExtraLines[ii] ) );
} }
// Set coordinate format to 3.6 or 4.5 absolute, leading zero omitted // Set coordinate format to 3.6 or 4.5 absolute, leading zero omitted
......
...@@ -465,7 +465,7 @@ void WORKSHEET_DATAITEM_TEXT::IncrementLabel( int aIncr ) ...@@ -465,7 +465,7 @@ void WORKSHEET_DATAITEM_TEXT::IncrementLabel( int aIncr )
// Replace the '\''n' sequence by EOL // Replace the '\''n' sequence by EOL
// and the sequence '\''\' by only one '\' in m_FullText // and the sequence '\''\' by only one '\' in m_FullText
// if m_FullTextis a multiline text (i;e.contains '\n') return true // if m_FullText is a multiline text (i.e.contains '\n') return true
bool WORKSHEET_DATAITEM_TEXT::ReplaceAntiSlashSequence() bool WORKSHEET_DATAITEM_TEXT::ReplaceAntiSlashSequence()
{ {
bool multiline = false; bool multiline = false;
......
...@@ -142,9 +142,28 @@ public: ...@@ -142,9 +142,28 @@ public:
virtual void SetDash( bool dashed ) = 0; virtual void SetDash( bool dashed ) = 0;
virtual void SetCreator( const wxString& _creator ) virtual void SetCreator( const wxString& aCreator )
{ {
creator = _creator; creator = aCreator;
}
/**
* Function AddLineToHeader
* Add a line to the list of free lines to print at the beginning of the file
* @param aExtraString is the string to print
*/
void AddLineToHeader( const wxString& aExtraString )
{
m_headerExtraLines.Add( aExtraString );
}
/**
* Function ClearHeaderLinesList
* remove all lines from the list of free lines to print at the beginning of the file
*/
void ClearHeaderLinesList()
{
m_headerExtraLines.Clear();
} }
/** /**
...@@ -324,11 +343,6 @@ public: ...@@ -324,11 +343,6 @@ public:
// NOP for most plotters. // NOP for most plotters.
} }
virtual void SetLayerAttribFunction( const wxString& function )
{
// NOP for most plotters. Only for Gerber plotter
}
virtual void SetGerberCoordinatesFormat( int aResolution, bool aUseInches = false ) virtual void SetGerberCoordinatesFormat( int aResolution, bool aUseInches = false )
{ {
// NOP for most plotters. Only for Gerber plotter // NOP for most plotters. Only for Gerber plotter
...@@ -406,6 +420,7 @@ protected: ...@@ -406,6 +420,7 @@ protected:
double GetDashGapLenIU() const; double GetDashGapLenIU() const;
protected: // variables used in most of plotters:
/// Plot scale - chosen by the user (even implicitly with 'fit in a4') /// Plot scale - chosen by the user (even implicitly with 'fit in a4')
double plotScale; double plotScale;
...@@ -444,6 +459,8 @@ protected: ...@@ -444,6 +459,8 @@ protected:
PAGE_INFO pageInfo; PAGE_INFO pageInfo;
/// Paper size in IU - not in mils /// Paper size in IU - not in mils
wxSize paperSize; wxSize paperSize;
wxArrayString m_headerExtraLines; /// a set of string to print in header file
}; };
...@@ -943,11 +960,6 @@ public: ...@@ -943,11 +960,6 @@ public:
*/ */
virtual void SetLayerPolarity( bool aPositive ); virtual void SetLayerPolarity( bool aPositive );
virtual void SetLayerAttribFunction( const wxString& function )
{
m_attribFunction = function;
}
/** /**
* Function SetGerberCoordinatesFormat * Function SetGerberCoordinatesFormat
* selection of Gerber units and resolution (number of digits in mantissa) * selection of Gerber units and resolution (number of digits in mantissa)
...@@ -985,8 +997,6 @@ protected: ...@@ -985,8 +997,6 @@ protected:
std::vector<APERTURE> apertures; std::vector<APERTURE> apertures;
std::vector<APERTURE>::iterator currentAperture; std::vector<APERTURE>::iterator currentAperture;
wxString m_attribFunction; // the layer "function", in GERBER X2 extention
// it is linked with the layer id
bool m_gerberUnitInch; // true if the gerber units are inches, false for mm bool m_gerberUnitInch; // true if the gerber units are inches, false for mm
int m_gerberUnitFmt; // number of digits in mantissa. int m_gerberUnitFmt; // number of digits in mantissa.
// usually 6 in Inches and 5 or 6 in mm // usually 6 in Inches and 5 or 6 in mm
......
...@@ -143,14 +143,16 @@ static EDA_HOTKEY HkNewProject( _HKI( "New Project" ), HK_NEW_PRJ, 'N' + GR_KB_C ...@@ -143,14 +143,16 @@ static EDA_HOTKEY HkNewProject( _HKI( "New Project" ), HK_NEW_PRJ, 'N' + GR_KB_C
static EDA_HOTKEY HkNewPrjFromTemplate( _HKI( "New Prj From Template" ), static EDA_HOTKEY HkNewPrjFromTemplate( _HKI( "New Prj From Template" ),
HK_NEW_PRJ_TEMPLATE, 'T' + GR_KB_CTRL ); HK_NEW_PRJ_TEMPLATE, 'T' + GR_KB_CTRL );
static EDA_HOTKEY HkRunEeschema( _HKI( "Run Eeschema" ), HK_RUN_EESCHEMA, 'E', 0 ); static EDA_HOTKEY HkRunEeschema( _HKI( "Run Eeschema" ), HK_RUN_EESCHEMA, 'E' + GR_KB_CTRL, 0 );
static EDA_HOTKEY HkRunLibedit( _HKI( "Run LibEdit" ), HK_RUN_LIBEDIT, 'L', 0 ); static EDA_HOTKEY HkRunLibedit( _HKI( "Run LibEdit" ), HK_RUN_LIBEDIT, 'L' + GR_KB_CTRL, 0 );
static EDA_HOTKEY HkRunPcbnew( _HKI( "Run Pcbnew" ), HK_RUN_PCBNEW, 'P', 0 ); static EDA_HOTKEY HkRunPcbnew( _HKI( "Run Pcbnew" ), HK_RUN_PCBNEW, 'P' + GR_KB_CTRL, 0 );
static EDA_HOTKEY HkRunModedit( _HKI( "Run FpEditor" ), HK_RUN_FPEDITOR, 'F', 0 ); static EDA_HOTKEY HkRunModedit( _HKI( "Run FpEditor" ), HK_RUN_FPEDITOR, 'F' + GR_KB_CTRL, 0 );
static EDA_HOTKEY HkRunGerbview( _HKI( "Run Gerbview" ), HK_RUN_GERBVIEW, 'G', 0 ); static EDA_HOTKEY HkRunGerbview( _HKI( "Run Gerbview" ), HK_RUN_GERBVIEW, 'G' + GR_KB_CTRL, 0 );
static EDA_HOTKEY HkRunBm2Cmp( _HKI( "Run Bitmap2Component" ), HK_RUN_BM2COMPONENT, 'B', 0 ); static EDA_HOTKEY HkRunBm2Cmp( _HKI( "Run Bitmap2Component" ),
static EDA_HOTKEY HkRunPcbCalc( _HKI( "Run PcbCalculator" ), HK_RUN_PCBCALCULATOR, 'C', 0 ); HK_RUN_BM2COMPONENT, 'B' + GR_KB_CTRL, 0 );
static EDA_HOTKEY HkRunPleditor( _HKI( "Run PlEditor" ), HK_RUN_PLEDITOR, 'Y', 0 ); static EDA_HOTKEY HkRunPcbCalc( _HKI( "Run PcbCalculator" ),
HK_RUN_PCBCALCULATOR, 'C' + GR_KB_CTRL, 0 );
static EDA_HOTKEY HkRunPleditor( _HKI( "Run PlEditor" ), HK_RUN_PLEDITOR, 'Y' + GR_KB_CTRL, 0 );
// List of hotkey descriptors // List of hotkey descriptors
EDA_HOTKEY* common_Hotkey_List[] = EDA_HOTKEY* common_Hotkey_List[] =
......
/* /*
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com> * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
#include <wx/ffile.h> #include <wx/ffile.h>
#include <dialog_plot.h> #include <dialog_plot.h>
#include <macros.h> #include <macros.h>
#include <build_version.h>
const wxString GetGerberExtension( LAYER_NUM aLayer ) const wxString GetGerberExtension( LAYER_NUM aLayer )
...@@ -84,8 +85,8 @@ const wxString GetGerberExtension( LAYER_NUM aLayer ) ...@@ -84,8 +85,8 @@ const wxString GetGerberExtension( LAYER_NUM aLayer )
} }
wxString GetGerberFileFunction( const BOARD *aBoard, LAYER_NUM aLayer, wxString GetGerberFileFunctionAttribute( const BOARD *aBoard,
bool aUseX1CompatibilityMode ) LAYER_NUM aLayer, bool aUseX1CompatibilityMode )
{ {
wxString attrib; wxString attrib;
...@@ -146,6 +147,14 @@ wxString GetGerberFileFunction( const BOARD *aBoard, LAYER_NUM aLayer, ...@@ -146,6 +147,14 @@ wxString GetGerberFileFunction( const BOARD *aBoard, LAYER_NUM aLayer,
attrib = wxString( wxT( "Other,ECO2" ) ); attrib = wxString( wxT( "Other,ECO2" ) );
break; break;
case B_Fab:
attrib = wxString( wxT( "Other,Fab,Bot" ) );
break;
case F_Fab:
attrib = wxString( wxT( "Other,Fab,Top" ) );
break;
case B_Cu: case B_Cu:
attrib = wxString::Format( wxT( "Copper,L%d,Bot" ), aBoard->GetCopperLayerCount() ); attrib = wxString::Format( wxT( "Copper,L%d,Bot" ), aBoard->GetCopperLayerCount() );
break; break;
...@@ -156,9 +165,9 @@ wxString GetGerberFileFunction( const BOARD *aBoard, LAYER_NUM aLayer, ...@@ -156,9 +165,9 @@ wxString GetGerberFileFunction( const BOARD *aBoard, LAYER_NUM aLayer,
default: default:
if( IsCopperLayer( aLayer ) ) if( IsCopperLayer( aLayer ) )
{
attrib = wxString::Format( wxT( "Copper,L%d,Inr" ), aLayer+1 ); attrib = wxString::Format( wxT( "Copper,L%d,Inr" ), aLayer+1 );
} else
attrib = wxString::Format( wxT( "Other,User" ), aLayer+1 );
break; break;
} }
...@@ -193,6 +202,95 @@ wxString GetGerberFileFunction( const BOARD *aBoard, LAYER_NUM aLayer, ...@@ -193,6 +202,95 @@ wxString GetGerberFileFunction( const BOARD *aBoard, LAYER_NUM aLayer,
return fileFct; return fileFct;
} }
/* Add some X2 attributes to the file header, as defined in the
* Gerber file format specification J4 and J5
*/
#define USE_J5_ATTR
void AddGerberX2Attribute( PLOTTER * aPlotter,
const BOARD *aBoard, LAYER_NUM aLayer )
{
wxString text;
#ifdef USE_J5_ATTR
text = wxT("%TF.GerberVersion,J5*%");
#else
text = wxT("%TF.GerberVersion,J4*%");
#endif
aPlotter->AddLineToHeader( text );
#ifdef USE_J5_ATTR
// Creates the TF,.GenerationSoftware. Format is:
// %TF,.GenerationSoftware,<vendor>,<application name>[,<application version>]*%
text.Printf( wxT( "%TF.GenerationSoftware,KiCad,Pcbnew,%s*%%" ), GetBuildVersion() );
aPlotter->AddLineToHeader( text );
// 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( text );
// Creates the TF,.JobID. Format is (from Gerber file format doc):
// %TF.JobID,<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.JobID,%s,%s,%s*%%" ), msg.ToAscii(), GetChars( guid ), rev.ToAscii() );
aPlotter->AddLineToHeader( text );
#endif
// Add the TF.FileFunction
text = GetGerberFileFunctionAttribute( aBoard, aLayer, false );
aPlotter->AddLineToHeader( text );
}
void BuildPlotFileName( wxFileName* aFilename, void BuildPlotFileName( wxFileName* aFilename,
const wxString& aOutputDir, const wxString& aOutputDir,
......
/* /*
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
...@@ -252,9 +252,9 @@ void BuildPlotFileName( wxFileName* aFilename, ...@@ -252,9 +252,9 @@ void BuildPlotFileName( wxFileName* aFilename,
const wxString GetGerberExtension( LAYER_NUM aLayer ); const wxString GetGerberExtension( LAYER_NUM aLayer );
/** /**
* Function GetGerberFileFunction * Function GetGerberFileFunctionAttribute
* Returns the "file function" attribute for \a aLayer, as defined in the * Returns the "file function" attribute for \a aLayer, as defined in the
* Gerber file format specification J1 (chapter 5). The returned string excludes * Gerber file format specification J1 (chapter 5). The returned string includes
* the "%TF.FileFunction" attribute prefix and the "*%" suffix. * the "%TF.FileFunction" attribute prefix and the "*%" suffix.
* @param aBoard = the board, needed to get the total count of copper layers * @param aBoard = the board, needed to get the total count of copper layers
* @param aLayer = the layer number to create the attribute for * @param aLayer = the layer number to create the attribute for
...@@ -262,10 +262,18 @@ const wxString GetGerberExtension( LAYER_NUM aLayer ); ...@@ -262,10 +262,18 @@ const wxString GetGerberExtension( LAYER_NUM aLayer );
* , compatible with X1 (rx274) notation (G04#@!TF.FileFunction) * , compatible with X1 (rx274) notation (G04#@!TF.FileFunction)
* @return The attribute, as a text string * @return The attribute, as a text string
*/ */
extern wxString GetGerberFileFunction( const BOARD *aBoard, LAYER_NUM aLayer, extern wxString GetGerberFileFunctionAttribute( const BOARD *aBoard,
bool aUseX1CompatibilityMode ); LAYER_NUM aLayer, bool aUseX1CompatibilityMode );
// PLOTGERB.CPP /**
void SelectD_CODE_For_LineDraw( PLOTTER* plotter, int aSize ); * Function AddGerberX2Attribute
* Calculates some X2 attributes, as defined in the
* Gerber file format specification J4 (chapter 5) and add them
* the to the gerber file header
* @param aPlotter, the current plotter.
* @param aBoard = the board, needed to extract some info
* @param aLayer = the layer number to create the attribute for
*/
extern void AddGerberX2Attribute( PLOTTER * aPlotter, const BOARD *aBoard, LAYER_NUM aLayer );
#endif // PCBPLOT_H_ #endif // PCBPLOT_H_
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
/* /*
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
...@@ -142,7 +142,7 @@ void PlotSilkScreen( BOARD *aBoard, PLOTTER* aPlotter, LSET aLayerMask, ...@@ -142,7 +142,7 @@ void PlotSilkScreen( BOARD *aBoard, PLOTTER* aPlotter, LSET aLayerMask,
} }
void PlotOneBoardLayer( BOARD *aBoard, PLOTTER* aPlotter, LAYER_ID aLayer, void PlotOneBoardLayer( BOARD *aBoard, PLOTTER* aPlotter, LAYER_ID aLayer,
const PCB_PLOT_PARAMS& aPlotOpt ) const PCB_PLOT_PARAMS& aPlotOpt )
{ {
PCB_PLOT_PARAMS plotOpt = aPlotOpt; PCB_PLOT_PARAMS plotOpt = aPlotOpt;
int soldermask_min_thickness = aBoard->GetDesignSettings().m_SolderMaskMinWidth; int soldermask_min_thickness = aBoard->GetDesignSettings().m_SolderMaskMinWidth;
...@@ -1044,12 +1044,18 @@ PLOTTER* StartPlotBoard( BOARD *aBoard, PCB_PLOT_PARAMS *aPlotOpts, ...@@ -1044,12 +1044,18 @@ PLOTTER* StartPlotBoard( BOARD *aBoard, PCB_PLOT_PARAMS *aPlotOpts,
if( plotter->OpenFile( aFullFileName ) ) if( plotter->OpenFile( aFullFileName ) )
{ {
plotter->ClearHeaderLinesList();
// For the Gerber "file function" attribute, set the layer number // For the Gerber "file function" attribute, set the layer number
if( plotter->GetPlotterType() == PLOT_FORMAT_GERBER ) if( plotter->GetPlotterType() == PLOT_FORMAT_GERBER )
{ {
bool useX2mode = plotOpts.GetUseGerberAttributes(); bool useX2mode = plotOpts.GetUseGerberAttributes();
plotter->SetLayerAttribFunction( GetGerberFileFunction( aBoard, aLayer,
useX2mode ? false : true ) ); if( useX2mode )
AddGerberX2Attribute( plotter, aBoard, aLayer );
else
plotter->AddLineToHeader( GetGerberFileFunctionAttribute(
aBoard, aLayer, true ) );
} }
plotter->StartPlot(); plotter->StartPlot();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment