diff --git a/common/gbr_metadata.cpp b/common/gbr_metadata.cpp index 5b98045460..45136c7d7a 100644 --- a/common/gbr_metadata.cpp +++ b/common/gbr_metadata.cpp @@ -32,6 +32,80 @@ #include +wxString GbrMakeProjectGUIDfromString( wxString& aText ) +{ + /* Gerber GUID format should be RFC4122 Version 1 or 4. + * See en.wikipedia.org/wiki/Universally_unique_identifier + * The format is: + * xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx + * with + * x = hexDigit lower/upper case + * and + * M = '1' or '4' (UUID version: 1 (basic) or 4 (random)) (we use 4: UUID random) + * and + * N = '8' or '9' or 'A|a' or 'B|b' : UUID variant 1: 2 MSB bits have meaning) (we use N = 9) + * N = 1000 or 1001 or 1010 or 1011 : 10xx means Variant 1 (Variant2: 110x and 111x are reserved) + */ + + wxString guid; + + // Build a 32 digits GUID from the board name: + // guid has 32 digits, so add chars in name to be sure we can build a 32 digits guid + // (i.e. from a 16 char string name) + // In fact only 30 digits are used, and 2 UID id + wxString bname = aText; + int cnt = 16 - bname.Len(); + + if( cnt > 0 ) + bname.Append( 'X', cnt ); + + int chr_idx = 0; + + // Output the 8 first hex digits: + for( unsigned ii = 0; ii < 4; ii++ ) + { + int cc = int( bname[chr_idx++] ) & 0xFF; + guid << wxString::Format( "%2.2x", cc ); + } + + // Output the 4 next hex digits: + guid << '-'; + + for( unsigned ii = 0; ii < 2; ii++ ) + { + int cc = int( bname[chr_idx++] ) & 0xFF; + guid << wxString::Format( "%2.2x", cc ); + } + + // Output the 4 next hex digits (UUID version and 3 digits): + guid << "-4"; // first digit: UUID version 4 (M = 4) + { + int cc = int( bname[chr_idx++] ) << 4 & 0xFF0; + cc += int( bname[chr_idx] ) >> 4 & 0x0F; + guid << wxString::Format( "%3.3x", cc ); + } + + // Output the 4 next hex digits (UUID variant and 3 digits): + guid << "-9"; // first digit: UUID variant 1 (N = 9) + { + int cc = (int( bname[chr_idx++] ) & 0x0F) << 8; + cc += int( bname[chr_idx++] ) & 0xFF; + guid << wxString::Format( "%3.3x", cc ); + } + + // Output the 12 last hex digits: + guid << '-'; + + for( unsigned ii = 0; ii < 6; ii++ ) + { + int cc = int( bname[chr_idx++] ) & 0xFF; + guid << wxString::Format( "%2.2x", cc ); + } + + return guid; +} + + std::string GBR_APERTURE_METADATA::FormatAttribute( GBR_APERTURE_ATTRIB aAttribute, bool aUseX1StructuredComment ) { diff --git a/include/gbr_metadata.h b/include/gbr_metadata.h index 115269a7c3..1e6dc5bb2b 100644 --- a/include/gbr_metadata.h +++ b/include/gbr_metadata.h @@ -35,6 +35,16 @@ #include +/** 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 + * and therefore the GUID generated has no meaning because it do not use any time and time stamp + * specific to the project, just a random pattern (random is here a pattern specific to a project). + * + * See en.wikipedia.org/wiki/Universally_unique_identifier + */ +wxString GbrMakeProjectGUIDfromString( wxString& aText ); + // this class handle info which can be added in a gerber file as attribute // of an aperture, by the %TA.AperFunction command diff --git a/pcbnew/exporters/gerber_jobfile_writer.cpp b/pcbnew/exporters/gerber_jobfile_writer.cpp index 862b656a36..79698a01d8 100644 --- a/pcbnew/exporters/gerber_jobfile_writer.cpp +++ b/pcbnew/exporters/gerber_jobfile_writer.cpp @@ -247,31 +247,15 @@ void GERBER_JOBFILE_WRITER::addJSONGeneralSpecs() // is the name of the project, restricted to basic ASCII symbols only, // and comma not accepted // All illegal chars will be replaced by underscore - // 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: accepts only ASCII 7 code (only basic ASCII codes are allowed in gerber files). + // + // 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 = m_pcb->GetFileName(); wxString 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 a , from the board name + wxString guid = GbrMakeProjectGUIDfromString( msg ); // build the string: this is the board short filename (without ext) // and all non ASCII chars are replaced by '_' diff --git a/pcbnew/pcbplot.cpp b/pcbnew/pcbplot.cpp index 63dddf13df..39b55989d2 100644 --- a/pcbnew/pcbplot.cpp +++ b/pcbnew/pcbplot.cpp @@ -42,6 +42,7 @@ #include #include #include +#include const wxString GetGerberProtelExtension( LAYER_NUM aLayer ) @@ -276,85 +277,6 @@ static wxString& makeStringCompatX1( wxString& aText, bool aUseX1CompatibilityMo } -/** 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 - * and therefore the GUID generated has no meaning because it do not use any time and time stamp - * specific to the project, just a random pattern (random is here a pattern specific to a project). - * - * See en.wikipedia.org/wiki/Universally_unique_identifier - */ -static wxString makeProjectGUIDfromString( wxString& aText ) -{ - // Gerber GUID format should be RFC4122 Version 1 or 4. The format is: - // xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx - // with - // x = hexDigit lower/upper case - // and - // M = '1' or '4' (UUID version: 1 (basic) or 4 (random)) (we use 4: UUID random) - // and - // N = '8' or '9' or 'A|a' or 'B|b' : UUID variant 1: 2 MSB bits have meaning) (we use N = 9) - // N = 1000 or 1001 or 1010 or 1011 : 10xx means Variant 1 (Variant2: 110x and 111x are reserved) - - wxString guid; - - // Build a 32 digits GUID from the board name: - // guid has 32 digits, so add chars in name to be sure we can build a 32 digits guid - // (i.e. from a 16 char string name) - // In fact only 30 digits are used, and 2 UID id - wxString bname = aText; - int cnt = 16 - bname.Len(); - - if( cnt > 0 ) - bname.Append( 'X', cnt ); - - int chr_idx = 0; - - // Output the 8 first hex digits: - for( unsigned ii = 0; ii < 4; ii++ ) - { - int cc = int( bname[chr_idx++] ) & 0xFF; - guid << wxString::Format( "%2.2x", cc ); - } - - // Output the 4 next hex digits: - guid << '-'; - - for( unsigned ii = 0; ii < 2; ii++ ) - { - int cc = int( bname[chr_idx++] ) & 0xFF; - guid << wxString::Format( "%2.2x", cc ); - } - - // Output the 4 next hex digits (UUID version and 3 digits): - guid << "-4"; // first digit: UUID version 4 (M = 4) - { - int cc = int( bname[chr_idx++] ) << 4 & 0xFF0; - cc += int( bname[chr_idx] ) >> 4 & 0x0F; - guid << wxString::Format( "%3.3x", cc ); - } - - // Output the 4 next hex digits (UUID variant and 3 digits): - guid << "-9"; // first digit: UUID variant 1 (N = 9) - { - int cc = (int( bname[chr_idx++] ) & 0x0F) << 8; - cc += int( bname[chr_idx++] ) & 0xFF; - guid << wxString::Format( "%3.3x", cc ); - } - - // Output the 12 last hex digits: - guid << '-'; - - for( unsigned ii = 0; ii < 6; ii++ ) - { - int cc = int( bname[chr_idx++] ) & 0xFF; - guid << wxString::Format( "%2.2x", cc ); - } - - return guid; -} - - void AddGerberX2Header( PLOTTER * aPlotter, const BOARD *aBoard, bool aUseX1CompatibilityMode ) { @@ -393,7 +315,7 @@ void AddGerberX2Header( PLOTTER * aPlotter, msg = fn.GetFullName(); // Build a , from the board name - wxString guid = makeProjectGUIDfromString( msg ); + wxString guid = GbrMakeProjectGUIDfromString( msg ); // build the string: this is the board short filename (without ext) // and all non ASCII chars and comma are replaced by '_'