Drill files generation: add 3 structured comments in NC (Excellon) drill files and remove duplicate code.
This commit is contained in:
parent
106eaaade6
commit
0b890b4d1d
|
@ -31,6 +31,47 @@
|
|||
#include <fctsys.h>
|
||||
#include <gbr_metadata.h>
|
||||
|
||||
wxString GbrMakeCreationDateAttributeString( GBR_NC_STRING_FORMAT aFormat )
|
||||
{
|
||||
// creates the CreationDate attribute:
|
||||
// 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 timezone_offset; // ISO 8601 offset from UTC in timezone
|
||||
timezone_offset = date.Format( "%z" ); // Extract the time zone offset
|
||||
// The time zone offset format is +mm or +hhmm (or -mm or -hhmm)
|
||||
// (mm = number of minutes, hh = number of hours. 1h00mn is returned as +0100)
|
||||
// we want +(or -) hh:mm
|
||||
if( timezone_offset.Len() > 3 ) // format +hhmm or -hhmm found
|
||||
// Add separator between hours and minutes
|
||||
timezone_offset.insert( 3, ":", 1 );
|
||||
|
||||
wxString msg;
|
||||
|
||||
switch( aFormat )
|
||||
{
|
||||
case GBR_NC_STRING_FORMAT_X2:
|
||||
msg.Printf( "%%TF.CreationDate,%s%s*%%", date.FormatISOCombined(), timezone_offset );
|
||||
break;
|
||||
|
||||
case GBR_NC_STRING_FORMAT_X1:
|
||||
msg.Printf( "G04 #@! TF.CreationDate,%s%s", date.FormatISOCombined(), timezone_offset );
|
||||
break;
|
||||
|
||||
case GBR_NC_STRING_FORMAT_GBRJOB:
|
||||
msg.Printf( "\"CreationDate\": \"%s%s\"", date.FormatISOCombined(), timezone_offset );
|
||||
break;
|
||||
|
||||
case GBR_NC_STRING_FORMAT_NCDRILL:
|
||||
msg.Printf( "; #@! TF.CreationDate,%s%s", date.FormatISOCombined(), timezone_offset );
|
||||
break;
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
|
||||
wxString GbrMakeProjectGUIDfromString( wxString& aText )
|
||||
{
|
||||
|
|
|
@ -35,6 +35,29 @@
|
|||
|
||||
#include <gbr_netlist_metadata.h>
|
||||
|
||||
/** creates the TF.CreationDate attribute:
|
||||
* 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 is effectively created,
|
||||
* not the time the project of PCB was started
|
||||
* @param aFormat = string compatibility: X1, X2, GBRJOB or NC drill synthax.
|
||||
* exemple of structured comment (compatible X1 gerber)
|
||||
* G04 #@! TF.CreationDate,2018-11-21T08:49:16+01:00* (exemple of X1 attribute)
|
||||
* exemple NC drill files
|
||||
* ; #@! TF.CreationDate,2018-11-21T08:49:16+01:00* (exemple of NC drill comment)
|
||||
* exemple of X2 attribute:
|
||||
* %TF.CreationDate,2018-11-06T08:25:24+01:00*%
|
||||
*/
|
||||
enum GBR_NC_STRING_FORMAT // Options for string format in some attribute strings
|
||||
{
|
||||
GBR_NC_STRING_FORMAT_X1,
|
||||
GBR_NC_STRING_FORMAT_X2,
|
||||
GBR_NC_STRING_FORMAT_GBRJOB,
|
||||
GBR_NC_STRING_FORMAT_NCDRILL
|
||||
};
|
||||
wxString GbrMakeCreationDateAttributeString( GBR_NC_STRING_FORMAT aFormat );
|
||||
|
||||
|
||||
/** A helper function to build a project GUID using format RFC4122 Version 1 or 4
|
||||
* from the project name, because a kicad project has no specific GUID
|
||||
* RFC4122 is used mainly for its syntax, because fields have no meaning for Gerber files
|
||||
|
|
|
@ -45,9 +45,11 @@
|
|||
|
||||
#include <pcbplot.h>
|
||||
#include <pcbnew.h>
|
||||
#include <class_board.h>
|
||||
#include <gendrill_Excellon_writer.h>
|
||||
#include <wildcards_and_files_ext.h>
|
||||
#include <reporter.h>
|
||||
#include <gbr_metadata.h>
|
||||
|
||||
// Comment/uncomment this to write or not a comment
|
||||
// in drill file when PTH and NPTH are merged to flag
|
||||
|
@ -126,7 +128,7 @@ void EXCELLON_WRITER::CreateDrillandMapFilesSet( const wxString& aPlotDirectory,
|
|||
}
|
||||
}
|
||||
|
||||
createDrillFile( file );
|
||||
createDrillFile( file, pair, doing_npth );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -136,7 +138,8 @@ void EXCELLON_WRITER::CreateDrillandMapFilesSet( const wxString& aPlotDirectory,
|
|||
}
|
||||
|
||||
|
||||
int EXCELLON_WRITER::createDrillFile( FILE* aFile )
|
||||
int EXCELLON_WRITER::createDrillFile( FILE* aFile, DRILL_LAYER_PAIR aLayerPair,
|
||||
bool aGenerateNPTH_list )
|
||||
{
|
||||
m_file = aFile;
|
||||
|
||||
|
@ -147,7 +150,7 @@ int EXCELLON_WRITER::createDrillFile( FILE* aFile )
|
|||
|
||||
LOCALE_IO dummy; // Use the standard notation for double numbers
|
||||
|
||||
writeEXCELLONHeader();
|
||||
writeEXCELLONHeader( aLayerPair, aGenerateNPTH_list );
|
||||
|
||||
holes_count = 0;
|
||||
|
||||
|
@ -440,18 +443,19 @@ void EXCELLON_WRITER::writeCoordinates( char* aLine, double aCoordX, double aCoo
|
|||
}
|
||||
|
||||
|
||||
void EXCELLON_WRITER::writeEXCELLONHeader()
|
||||
void EXCELLON_WRITER::writeEXCELLONHeader( DRILL_LAYER_PAIR aLayerPair,
|
||||
bool aGenerateNPTH_list)
|
||||
{
|
||||
fputs( "M48\n", m_file ); // The beginning of a header
|
||||
|
||||
if( !m_minimalHeader )
|
||||
{
|
||||
// The next 2 lines in EXCELLON files are comments:
|
||||
// The next lines in EXCELLON files are comments:
|
||||
wxString msg;
|
||||
msg << wxT("KiCad") << wxT( " " ) << GetBuildVersion();
|
||||
msg << "KiCad " << GetBuildVersion();
|
||||
|
||||
fprintf( m_file, ";DRILL file {%s} date %s\n", TO_UTF8( msg ), TO_UTF8( DateAndTime() ) );
|
||||
msg = wxT( ";FORMAT={" );
|
||||
fprintf( m_file, "; DRILL file {%s} date %s\n", TO_UTF8( msg ), TO_UTF8( DateAndTime() ) );
|
||||
msg = "; FORMAT={";
|
||||
|
||||
// Print precision:
|
||||
// Note in decimal format the precision is not used.
|
||||
|
@ -459,10 +463,10 @@ void EXCELLON_WRITER::writeEXCELLONHeader()
|
|||
if( m_zeroFormat != DECIMAL_FORMAT )
|
||||
msg << m_precision.GetPrecisionString();
|
||||
else
|
||||
msg << wxT( "-:-" ); // in decimal format the precision is irrelevant
|
||||
msg << "-:-"; // in decimal format the precision is irrelevant
|
||||
|
||||
msg << wxT( "/ absolute / " );
|
||||
msg << ( m_unitsMetric ? wxT( "metric" ) : wxT( "inch" ) );
|
||||
msg << "/ absolute / ";
|
||||
msg << ( m_unitsMetric ? "metric" : "inch" );
|
||||
|
||||
/* Adding numbers notation format.
|
||||
* this is same as m_Choice_Zeros_Format strings, but NOT translated
|
||||
|
@ -475,14 +479,34 @@ void EXCELLON_WRITER::writeEXCELLONHeader()
|
|||
|
||||
const wxString zero_fmt[4] =
|
||||
{
|
||||
wxT( "decimal" ),
|
||||
wxT( "suppress leading zeros" ),
|
||||
wxT( "suppress trailing zeros" ),
|
||||
wxT( "keep zeros" )
|
||||
"decimal",
|
||||
"suppress leading zeros",
|
||||
"suppress trailing zeros",
|
||||
"keep zeros"
|
||||
};
|
||||
|
||||
msg << zero_fmt[m_zeroFormat] << wxT( "}\n" );
|
||||
msg << zero_fmt[m_zeroFormat] << "}\n";
|
||||
fputs( TO_UTF8( msg ), m_file );
|
||||
|
||||
// add the structured comment TF.CreationDate:
|
||||
// The attribute value must conform to the full version of the ISO 8601
|
||||
msg = GbrMakeCreationDateAttributeString( GBR_NC_STRING_FORMAT_NCDRILL ) + "\n";
|
||||
fputs( TO_UTF8( msg ), m_file );
|
||||
|
||||
// Add the application name that created the drill file
|
||||
msg = "; #@! TF.GenerationSoftware,Kicad,Pcbnew,";
|
||||
msg << GetBuildVersion() << "\n";
|
||||
fputs( TO_UTF8( msg ), m_file );
|
||||
|
||||
if( !m_merge_PTH_NPTH )
|
||||
{
|
||||
// Add the standard X2 FileFunction for drill files
|
||||
// TF.FileFunction,Plated[NonPlated],layer1num,layer2num,PTH[NPTH]
|
||||
msg = BuildFileFunctionAttributeString( aLayerPair, aGenerateNPTH_list, true )
|
||||
+ "\n";
|
||||
fputs( TO_UTF8( msg ), m_file );
|
||||
}
|
||||
|
||||
fputs( "FMAT,2\n", m_file ); // Use Format 2 commands (version used since 1979)
|
||||
}
|
||||
|
||||
|
|
|
@ -114,17 +114,22 @@ private:
|
|||
* @param aFile = an opened file to write to will be closed by CreateDrillFile
|
||||
* @return hole count
|
||||
*/
|
||||
int createDrillFile( FILE * aFile );
|
||||
int createDrillFile( FILE * aFile, DRILL_LAYER_PAIR aLayerPair,
|
||||
bool aGenerateNPTH_list );
|
||||
|
||||
|
||||
/* Print the DRILL file header. The full header is:
|
||||
/* Print the DRILL file header. The full header is somethink like:
|
||||
* M48
|
||||
* ;DRILL file {PCBNEW (2007-11-29-b)} date 17/1/2008-21:02:35
|
||||
* ;FORMAT={ <precision> / absolute / <units> / <numbers format>}
|
||||
* ; #@! TF.FileFunction,Plated,1,4,PTH
|
||||
* ; #@! TF.CreationDate,2018-11-23T15:59:51+01:00
|
||||
* ; #@! TF.GenerationSoftware,Kicad,Pcbnew,2017.04
|
||||
* FMAT,2
|
||||
* INCH,TZ
|
||||
*/
|
||||
void writeEXCELLONHeader();
|
||||
void writeEXCELLONHeader( DRILL_LAYER_PAIR aLayerPair,
|
||||
bool aGenerateNPTH_list);
|
||||
|
||||
void writeEXCELLONEndOfFile();
|
||||
|
||||
|
|
|
@ -342,3 +342,88 @@ void GENDRILL_WRITER_BASE::CreateMapFilesSet( const wxString& aPlotDirectory,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const wxString GENDRILL_WRITER_BASE::BuildFileFunctionAttributeString(
|
||||
DRILL_LAYER_PAIR aLayerPair, bool aIsNpth, bool aCompatNCdrill ) const
|
||||
{
|
||||
// Build a wxString containing the .FileFunction attribute for drill files.
|
||||
// %TF.FileFunction,Plated[NonPlated],layer1num,layer2num,PTH[NPTH][Blind][Buried],Drill[Route][Mixed]*%
|
||||
wxString text;
|
||||
|
||||
if( aCompatNCdrill )
|
||||
text = "; #@! ";
|
||||
else
|
||||
text = "%";
|
||||
|
||||
text << "TF.FileFunction,";
|
||||
|
||||
if( aIsNpth )
|
||||
text << "NonPlated,";
|
||||
else
|
||||
text << "Plated,";
|
||||
|
||||
int layer1 = aLayerPair.first;
|
||||
int layer2 = aLayerPair.second;
|
||||
// In Gerber files, layers num are 1 to copper layer count instead of F_Cu to B_Cu
|
||||
// (0 to copper layer count-1)
|
||||
// Note also for a n copper layers board, gerber layers num are 1 ... n
|
||||
layer1 += 1;
|
||||
|
||||
if( layer2 == B_Cu )
|
||||
layer2 = m_pcb->GetCopperLayerCount();
|
||||
else
|
||||
layer2 += 1;
|
||||
|
||||
text << layer1 << ",";
|
||||
text << layer2 << ",";
|
||||
|
||||
// Now add PTH or NPTH or Blind or Buried attribute
|
||||
int toplayer = 1;
|
||||
int bottomlayer = m_pcb->GetCopperLayerCount();
|
||||
|
||||
if( aIsNpth )
|
||||
text << "NPTH";
|
||||
else if( layer1 == toplayer && layer2 == bottomlayer )
|
||||
text << "PTH";
|
||||
else if( layer1 == toplayer || layer2 == bottomlayer )
|
||||
text << "Blind";
|
||||
else
|
||||
text << "Buried";
|
||||
|
||||
// In NC drill file, these previous parameters should be enough:
|
||||
if( aCompatNCdrill )
|
||||
return text;
|
||||
|
||||
|
||||
// Now add Drill or Route or Mixed:
|
||||
// file containing only round holes have Drill attribute
|
||||
// file containing only oblong holes have Routed attribute
|
||||
// file containing both holes have Mixed attribute
|
||||
bool hasOblong = false;
|
||||
bool hasDrill = false;
|
||||
|
||||
for( unsigned ii = 0; ii < m_holeListBuffer.size(); ii++ )
|
||||
{
|
||||
const HOLE_INFO& hole_descr = m_holeListBuffer[ii];
|
||||
|
||||
if( hole_descr.m_Hole_Shape ) // m_Hole_Shape not 0 is an oblong hole)
|
||||
hasOblong = true;
|
||||
else
|
||||
hasDrill = true;
|
||||
}
|
||||
|
||||
if( hasOblong && hasDrill )
|
||||
text << ",Mixed";
|
||||
else if( hasDrill )
|
||||
text << ",Drill";
|
||||
else if( hasOblong )
|
||||
text << ",Route";
|
||||
|
||||
// else: empty file.
|
||||
|
||||
// End of .FileFunction attribute:
|
||||
text << "*%";
|
||||
|
||||
return text;
|
||||
}
|
||||
|
|
|
@ -340,6 +340,20 @@ protected:
|
|||
*/
|
||||
virtual const wxString getDrillFileName( DRILL_LAYER_PAIR aPair, bool aNPTH,
|
||||
bool aMerge_PTH_NPTH ) const;
|
||||
|
||||
|
||||
/**
|
||||
* @return a wxString containing the .FileFunction attribute.
|
||||
* the standard X2 FileFunction for drill files is
|
||||
* %TF.FileFunction,Plated[NonPlated],layer1num,layer2num,PTH[NPTH][Blind][Buried],Drill[Route][Mixed]*%
|
||||
* There is no X1 version, as the Gerber drill files uses only X2 format
|
||||
* There is a compatible NC drill version.
|
||||
* @param aLayerPair is the layer pair (Drill from rom first layer to second layer)
|
||||
* @param aIsNpth is true when generating NPTH drill file
|
||||
* @param aCompatNCdrill is true when generating NC (Excellon) compatible drill file
|
||||
*/
|
||||
const wxString BuildFileFunctionAttributeString( DRILL_LAYER_PAIR aLayerPair,
|
||||
bool aIsNpth, bool aCompatNCdrill = false ) const;
|
||||
};
|
||||
|
||||
#endif // #define GENDRILL_FILE_WRITER_BASE_H
|
||||
|
|
|
@ -95,13 +95,13 @@ void GERBER_WRITER::CreateDrillandMapFilesSet( const wxString& aPlotDirectory,
|
|||
{
|
||||
wxString fullFilename = fn.GetFullPath();
|
||||
|
||||
int result = createDrillFile( fullFilename, doing_npth, pair.first, pair.second );
|
||||
int result = createDrillFile( fullFilename, doing_npth, pair );
|
||||
|
||||
if( result < 0 )
|
||||
{
|
||||
if( aReporter )
|
||||
{
|
||||
msg.Printf( _( "** Unable to create %s **\n" ), GetChars( fullFilename ) );
|
||||
msg.Printf( _( "** Unable to create %s **\n" ), fullFilename );
|
||||
aReporter->Report( msg );
|
||||
}
|
||||
break;
|
||||
|
@ -110,7 +110,7 @@ void GERBER_WRITER::CreateDrillandMapFilesSet( const wxString& aPlotDirectory,
|
|||
{
|
||||
if( aReporter )
|
||||
{
|
||||
msg.Printf( _( "Create file %s\n" ), GetChars( fullFilename ) );
|
||||
msg.Printf( _( "Create file %s\n" ), fullFilename );
|
||||
aReporter->Report( msg );
|
||||
}
|
||||
}
|
||||
|
@ -127,7 +127,7 @@ void GERBER_WRITER::CreateDrillandMapFilesSet( const wxString& aPlotDirectory,
|
|||
static void convertOblong2Segment( wxSize aSize, double aOrient, wxPoint& aStart, wxPoint& aEnd );
|
||||
|
||||
int GERBER_WRITER::createDrillFile( wxString& aFullFilename, bool aIsNpth,
|
||||
int aLayer1, int aLayer2 )
|
||||
DRILL_LAYER_PAIR aLayerPair )
|
||||
{
|
||||
int holes_count;
|
||||
|
||||
|
@ -148,68 +148,7 @@ int GERBER_WRITER::createDrillFile( wxString& aFullFilename, bool aIsNpth,
|
|||
|
||||
// Add the standard X2 FileFunction for drill files
|
||||
// %TF.FileFunction,Plated[NonPlated],layer1num,layer2num,PTH[NPTH][Blind][Buried],Drill[Route][Mixed]*%
|
||||
wxString text( "%TF.FileFunction," );
|
||||
|
||||
if( aIsNpth )
|
||||
text << "NonPlated,";
|
||||
else
|
||||
text << "Plated,";
|
||||
|
||||
// In Gerber files, layers num are 1 to copper layer count instead of F_Cu to B_Cu
|
||||
// (0 to copper layer count-1)
|
||||
// Note also for a n copper layers board, gerber layers num are 1 ... n
|
||||
aLayer1 += 1;
|
||||
|
||||
if( aLayer2 == B_Cu )
|
||||
aLayer2 = m_pcb->GetCopperLayerCount();
|
||||
else
|
||||
aLayer2 += 1;
|
||||
|
||||
text << aLayer1 << ",";
|
||||
text << aLayer2 << ",";
|
||||
|
||||
// Now add PTH or NPTH or Blind or Buried attribute
|
||||
int toplayer = 1;
|
||||
int bottomlayer = m_pcb->GetCopperLayerCount();
|
||||
|
||||
if( aIsNpth )
|
||||
text << "NPTH";
|
||||
else if( aLayer1 == toplayer && aLayer2 == bottomlayer )
|
||||
text << "PTH";
|
||||
else if( aLayer1 == toplayer || aLayer2 == bottomlayer )
|
||||
text << "Blind";
|
||||
else
|
||||
text << "Buried";
|
||||
|
||||
// Now add Drill or Route or Mixed:
|
||||
// file containing only round holes have Drill attribute
|
||||
// file containing only oblong holes have Routed attribute
|
||||
// file containing both holes have Mixed attribute
|
||||
bool hasOblong = false;
|
||||
bool hasDrill = false;
|
||||
|
||||
for( unsigned ii = 0; ii < m_holeListBuffer.size(); ii++ )
|
||||
{
|
||||
HOLE_INFO& hole_descr = m_holeListBuffer[ii];
|
||||
|
||||
if( hole_descr.m_Hole_Shape ) // m_Hole_Shape not 0 is an oblong hole)
|
||||
hasOblong = true;
|
||||
else
|
||||
hasDrill = true;
|
||||
}
|
||||
|
||||
if( hasOblong && hasDrill )
|
||||
text << ",Mixed";
|
||||
else if( hasDrill )
|
||||
text << ",Drill";
|
||||
else if( hasOblong )
|
||||
text << ",Route";
|
||||
|
||||
// else: empty file.
|
||||
|
||||
// End of .FileFunction attribute:
|
||||
text << "*%";
|
||||
|
||||
wxString text = BuildFileFunctionAttributeString( aLayerPair, aIsNpth );
|
||||
plotter.AddLineToHeader( text );
|
||||
|
||||
// Add file polarity (positive)
|
||||
|
|
|
@ -84,12 +84,11 @@ private:
|
|||
* Creates an Excellon drill file
|
||||
* @param aFullFilename = the full filename
|
||||
* @param aIsNpth = true for a NPTH file, false for a PTH file
|
||||
* @param aLayer1 = the first board layer
|
||||
* @param aLayer2 = the last board layer
|
||||
* @param aLayerPair = first board layer and the last board layer for this drill file
|
||||
* for blind buried vias, they are not always top and bottom layers
|
||||
* @return hole count, or -1 if the file cannot be created
|
||||
*/
|
||||
int createDrillFile( wxString& aFullFilename, bool aIsNpth, int aLayer1, int aLayer2 );
|
||||
int createDrillFile( wxString& aFullFilename, bool aIsNpth, DRILL_LAYER_PAIR aLayerPair );
|
||||
|
||||
/**
|
||||
* @return a filename which identify the drill file function.
|
||||
|
|
|
@ -155,20 +155,10 @@ void GERBER_JOBFILE_WRITER::addJSONHeader()
|
|||
addJSONObject( text );
|
||||
closeBlockWithSep();
|
||||
|
||||
// creates the TF.CreationDate ext:
|
||||
// creates the CreationDate attribute:
|
||||
// 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( "\"CreationDate\": \"%s%s\"\n" ),date.FormatISOCombined(), msg );
|
||||
// date and time format, including time and time zone.
|
||||
text = GbrMakeCreationDateAttributeString( GBR_NC_STRING_FORMAT_GBRJOB ) + "\n";
|
||||
addJSONObject( text );
|
||||
|
||||
closeBlockWithSep();
|
||||
|
|
|
@ -287,20 +287,11 @@ void AddGerberX2Header( PLOTTER * aPlotter,
|
|||
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.CreationDate attribute:
|
||||
text = GbrMakeCreationDateAttributeString( aUseX1CompatibilityMode ?
|
||||
GBR_NC_STRING_FORMAT_X1 :
|
||||
GBR_NC_STRING_FORMAT_X2 );
|
||||
aPlotter->AddLineToHeader( text );
|
||||
|
||||
// Creates the TF,.ProjectId. Format is (from Gerber file format doc):
|
||||
// %TF.ProjectId,<project id>,<project GUID>,<revision id>*%
|
||||
|
@ -312,7 +303,7 @@ void AddGerberX2Header( PLOTTER * aPlotter,
|
|||
// <project GUID> is a string which is an unique id of a project.
|
||||
// However Kicad does not handle such a project GUID, so it is built from the board name
|
||||
wxFileName fn = aBoard->GetFileName();
|
||||
msg = fn.GetFullName();
|
||||
wxString msg = fn.GetFullName();
|
||||
|
||||
// Build a <project GUID>, from the board name
|
||||
wxString guid = GbrMakeProjectGUIDfromString( msg );
|
||||
|
|
Loading…
Reference in New Issue