KiCad PCB EDA Suite
gbr_metadata.cpp File Reference

helper functions to handle the gerber metadata in files, related to the netlist info and aperture attribute. More...

#include <fctsys.h>
#include <gbr_metadata.h>

Go to the source code of this file.

Macros

#define NO_NET_NAME   wxT( "N/C" )
 
#define NO_PAD_NAME   wxT( "" )
 

Functions

wxString GbrMakeProjectGUIDfromString (wxString &aText)
 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). More...
 
wxString FormatStringFromGerber (const wxString &aString)
 This helper function make the inverse conversion of formatStringToGerber() It converts a "normalized" gerber string and convert it to a 16 bits sequence unicode. More...
 
std::string formatStringToGerber (const wxString &aString)
 This helper function "normalize" aString and convert it to a Gerber std::string Normalisation means convert any code > 0x7F and unautorized code to a hexadecimal 16 bits sequence unicode unautorized codes are ',' '*' '' '\'. More...
 
bool FormatNetAttribute (std::string &aPrintedText, std::string &aLastNetAttributes, GBR_NETLIST_METADATA *aData, bool &aClearPreviousAttributes, bool aUseX1StructuredComment)
 Generates the string to print to a gerber file, to set a net attribute for a graphic object. More...
 

Detailed Description

helper functions to handle the gerber metadata in files, related to the netlist info and aperture attribute.

Definition in file gbr_metadata.cpp.

Macro Definition Documentation

#define NO_NET_NAME   wxT( "N/C" )

Definition at line 302 of file gbr_metadata.cpp.

Referenced by FormatNetAttribute().

#define NO_PAD_NAME   wxT( "" )

Definition at line 303 of file gbr_metadata.cpp.

Referenced by FormatNetAttribute().

Function Documentation

bool FormatNetAttribute ( std::string &  aPrintedText,
std::string &  aLastNetAttributes,
GBR_NETLIST_METADATA aData,
bool &  aClearPreviousAttributes,
bool  aUseX1StructuredComment 
)

Generates the string to print to a gerber file, to set a net attribute for a graphic object.

Parameters
aPrintedTextis the string to print
aLastNetAttributesis the current full set of attributes.
aDatais the GBR_NETLIST_METADATA associated to the graphic object (can be NULL if no associated metadata, and aClearPreviousAttributes will be set to false)
aClearPreviousAttributesreturns true if the full set of attributes must be deleted from file before adding new attribute (happens when a previous attribute does not exist no more).
aUseX1StructuredComment= false in X2 mode, and true in X1 mode to add the net attribut in compatible X1 structured comment (i.e. prefixed by "G04 #@! ")
Returns
false if nothing can be done (GBR_NETLIST_METADATA has GBR_APERTURE_ATTRIB_NONE, and true if OK if the new attribute(s) is the same as current attribute(s), aPrintedText will be empty

Definition at line 305 of file gbr_metadata.cpp.

References formatStringToGerber(), GBR_NETLIST_METADATA::GBR_NETINFO_CMP, GBR_NETLIST_METADATA::GBR_NETINFO_NET, GBR_NETLIST_METADATA::GBR_NETINFO_PAD, GBR_NETLIST_METADATA::GBR_NETINFO_UNSPECIFIED, GBR_NETLIST_METADATA::m_Cmpref, GBR_NETLIST_METADATA::m_NetAttribType, GBR_NETLIST_METADATA::m_Netname, GBR_NETLIST_METADATA::m_NotInNet, GBR_NETLIST_METADATA::m_Padname, NO_NET_NAME, and NO_PAD_NAME.

Referenced by GERBER_PLOTTER::formatNetAttribute().

308 {
309  aClearPreviousAttributes = false;
310  wxString prepend_string;
311  wxString eol_string;
312 
313  if( aUseX1StructuredComment )
314  {
315  prepend_string = "G04 #@! ";
316  eol_string = "*\n";
317  }
318  else
319  {
320  prepend_string = "%";
321  eol_string = "*%\n";
322  }
323 
324  // print a Gerber net attribute record.
325  // it is added to the object attributes dictionnary
326  // On file, only modified or new attributes are printed.
327  if( aData == NULL )
328  return false;
329 
330  std::string pad_attribute_string;
331  std::string net_attribute_string;
332  std::string cmp_attribute_string;
333 
335  return false; // idle command: do nothing
336 
338  {
339  // print info associated to a flashed pad (cmpref, pad name)
340  // example: %TO.P,R5,3*%
341  pad_attribute_string = prepend_string + "TO.P,";
342  pad_attribute_string += formatStringToGerber( aData->m_Cmpref ) + ",";
343 
344  if( aData->m_Padname.IsEmpty() )
345  // Happens for "mechanical" or never connected pads
346  pad_attribute_string += formatStringToGerber( NO_PAD_NAME );
347  else
348  pad_attribute_string += formatStringToGerber( aData->m_Padname );
349 
350  pad_attribute_string += eol_string;
351  }
352 
354  {
355  // print info associated to a net
356  // example: %TO.N,Clk3*%
357  net_attribute_string = prepend_string + "TO.N,";
358 
359  if( aData->m_Netname.IsEmpty() )
360  {
361  if( aData->m_NotInNet )
362  {
363  // Happens for not connectable pads: mechanical pads
364  // and pads with no padname/num
365  // In this case the net name must be left empty
366  }
367  else
368  {
369  // Happens for not connected pads: use a normalized
370  // dummy name
371  net_attribute_string += formatStringToGerber( NO_NET_NAME );
372  }
373  }
374  else
375  net_attribute_string += formatStringToGerber( aData->m_Netname );
376 
377  net_attribute_string += eol_string;
378  }
379 
382  {
383  // print info associated to a footprint
384  // example: %TO.C,R2*%
385  // Because GBR_NETINFO_PAD option already contains this info, it is not
386  // created here for a GBR_NETINFO_PAD attribute
387  cmp_attribute_string = prepend_string + "TO.C,";
388  cmp_attribute_string += formatStringToGerber( aData->m_Cmpref ) + eol_string;
389  }
390 
391  // the full list of requested attributes:
392  std::string full_attribute_string = pad_attribute_string + net_attribute_string
393  + cmp_attribute_string;
394  // the short list of requested attributes
395  // (only modified or new attributes are stored here):
396  std::string short_attribute_string;
397 
398  if( aLastNetAttributes != full_attribute_string )
399  {
400  // first, remove no more existing attributes.
401  // Because in Kicad the full attribute list is evaluated for each object,
402  // the entire dictionnary is cleared
403  bool clearDict = false;
404 
405  if( aLastNetAttributes.find( "TO.P," ) != std::string::npos )
406  {
407  if( pad_attribute_string.empty() ) // No more this attribute
408  clearDict = true;
409  else if( aLastNetAttributes.find( pad_attribute_string )
410  == std::string::npos ) // This attribute has changed
411  short_attribute_string += pad_attribute_string;
412  }
413  else // New attribute
414  short_attribute_string += pad_attribute_string;
415 
416  if( aLastNetAttributes.find( "TO.N," ) != std::string::npos )
417  {
418  if( net_attribute_string.empty() ) // No more this attribute
419  clearDict = true;
420  else if( aLastNetAttributes.find( net_attribute_string )
421  == std::string::npos ) // This attribute has changed
422  short_attribute_string += net_attribute_string;
423  }
424  else // New attribute
425  short_attribute_string += net_attribute_string;
426 
427  if( aLastNetAttributes.find( "TO.C," ) != std::string::npos )
428  {
429  if( cmp_attribute_string.empty() ) // No more this attribute
430  clearDict = true;
431  else if( aLastNetAttributes.find( cmp_attribute_string )
432  == std::string::npos ) // This attribute has changed
433  short_attribute_string += cmp_attribute_string;
434  }
435  else // New attribute
436  short_attribute_string += cmp_attribute_string;
437 
438  aClearPreviousAttributes = clearDict;
439 
440  aLastNetAttributes = full_attribute_string;
441 
442  if( clearDict )
443  aPrintedText = full_attribute_string;
444  else
445  aPrintedText = short_attribute_string;
446  }
447 
448  return true;
449 }
#define NO_NET_NAME
print info associated to a component (TO.C attribute)
wxString m_Cmpref
the component reference parent of the data
std::string formatStringToGerber(const wxString &aString)
This helper function "normalize" aString and convert it to a Gerber std::string Normalisation means c...
wxString m_Padname
for a flashed pad: the pad name ((TO.P attribute)
#define NO_PAD_NAME
wxString m_Netname
for items associated to a net: the netname
print info associated to a flashed pad (TO.P attribute)
bool m_NotInNet
true if a pad of a footprint cannot be connected (for instance a mechanical NPTH, ot a not named pad)...
print info associated to a net (TO.N attribute)
int m_NetAttribType
the type of net info (used to define the gerber string to create)
wxString FormatStringFromGerber ( const wxString &  aString)

This helper function make the inverse conversion of formatStringToGerber() It converts a "normalized" gerber string and convert it to a 16 bits sequence unicode.

Parameters
aString= the wxString compliant with a gerber string format
Returns
a wxString (unicode 16) from the gerber string

Definition at line 219 of file gbr_metadata.cpp.

Referenced by GERBER_JOBFILE_READER::ReadGerberJobFile().

220 {
221  // make the inverse conversion of formatStringToGerber()
222  // It converts a "normalized" gerber string and convert it to a 16 bits sequence unicode
223  // and return a wxString (unicode 16) from the gerber string
224  wxString txt;
225 
226  for( unsigned ii = 0; ii < aString.Length(); ++ii )
227  {
228  unsigned code = aString[ii];
229 
230  if( code == '\\' )
231  {
232  // Convert 4 hexadecimal digits to a 16 bit unicode
233  // (Gerber allows only 4 hexadecimal digits)
234  long value = 0;
235 
236  for( int jj = 0; jj < 4; jj++ )
237  {
238  value <<= 4;
239  code = aString[++ii];
240  // Very basic conversion, but it expects a valid gerber file
241  int hexa = (code <= '9' ? code - '0' : code - 'A' + 10) & 0xF;
242  value += hexa;
243  }
244 
245  txt.Append( wxChar( value ) );
246  }
247  else
248  txt.Append( aString[ii] );
249  }
250 
251  return txt;
252 }
std::string formatStringToGerber ( const wxString &  aString)

This helper function "normalize" aString and convert it to a Gerber std::string Normalisation means convert any code > 0x7F and unautorized code to a hexadecimal 16 bits sequence unicode unautorized codes are ',' '*' '' '\'.

Parameters
aString= the wxString to convert
Returns
a std::string (ASCII7 coded) compliant with a gerber string

Definition at line 255 of file gbr_metadata.cpp.

Referenced by GERBER_JOBFILE_WRITER::addJSONFilesAttributes(), GERBER_JOBFILE_WRITER::addJSONMaterialStackup(), and FormatNetAttribute().

256 {
257  /* format string means convert any code > 0x7F and unautorized code to a hexadecimal
258  * 16 bits sequence unicode
259  * unautorized codes are ',' '*' '%' '\'
260  */
261  std::string txt;
262 
263  txt.reserve( aString.Length() );
264 
265  for( unsigned ii = 0; ii < aString.Length(); ++ii )
266  {
267  unsigned code = aString[ii];
268  bool convert = false;
269 
270  switch( code )
271  {
272  case '\\':
273  case '%':
274  case '*':
275  case ',':
276  convert = true;
277  break;
278 
279  default:
280  break;
281  }
282 
283  if( convert || code > 0x7F )
284  {
285  txt += '\\';
286 
287  // Convert code to 4 hexadecimal digit
288  // (Gerber allows only 4 hexadecimal digit)
289  char hexa[32];
290  sprintf( hexa,"%4.4X", code & 0xFFFF);
291  txt += hexa;
292  }
293  else
294  txt += char( code );
295  }
296 
297  return txt;
298 }
wxString GbrMakeProjectGUIDfromString ( wxString &  aText)

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

Definition at line 35 of file gbr_metadata.cpp.

References Format().

Referenced by AddGerberX2Header(), and GERBER_JOBFILE_WRITER::addJSONGeneralSpecs().

36 {
37  /* Gerber GUID format should be RFC4122 Version 1 or 4.
38  * See en.wikipedia.org/wiki/Universally_unique_identifier
39  * The format is:
40  * xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx
41  * with
42  * x = hexDigit lower/upper case
43  * and
44  * M = '1' or '4' (UUID version: 1 (basic) or 4 (random)) (we use 4: UUID random)
45  * and
46  * N = '8' or '9' or 'A|a' or 'B|b' : UUID variant 1: 2 MSB bits have meaning) (we use N = 9)
47  * N = 1000 or 1001 or 1010 or 1011 : 10xx means Variant 1 (Variant2: 110x and 111x are reserved)
48  */
49 
50  wxString guid;
51 
52  // Build a 32 digits GUID from the board name:
53  // guid has 32 digits, so add chars in name to be sure we can build a 32 digits guid
54  // (i.e. from a 16 char string name)
55  // In fact only 30 digits are used, and 2 UID id
56  wxString bname = aText;
57  int cnt = 16 - bname.Len();
58 
59  if( cnt > 0 )
60  bname.Append( 'X', cnt );
61 
62  int chr_idx = 0;
63 
64  // Output the 8 first hex digits:
65  for( unsigned ii = 0; ii < 4; ii++ )
66  {
67  int cc = int( bname[chr_idx++] ) & 0xFF;
68  guid << wxString::Format( "%2.2x", cc );
69  }
70 
71  // Output the 4 next hex digits:
72  guid << '-';
73 
74  for( unsigned ii = 0; ii < 2; ii++ )
75  {
76  int cc = int( bname[chr_idx++] ) & 0xFF;
77  guid << wxString::Format( "%2.2x", cc );
78  }
79 
80  // Output the 4 next hex digits (UUID version and 3 digits):
81  guid << "-4"; // first digit: UUID version 4 (M = 4)
82  {
83  int cc = int( bname[chr_idx++] ) << 4 & 0xFF0;
84  cc += int( bname[chr_idx] ) >> 4 & 0x0F;
85  guid << wxString::Format( "%3.3x", cc );
86  }
87 
88  // Output the 4 next hex digits (UUID variant and 3 digits):
89  guid << "-9"; // first digit: UUID variant 1 (N = 9)
90  {
91  int cc = (int( bname[chr_idx++] ) & 0x0F) << 8;
92  cc += int( bname[chr_idx++] ) & 0xFF;
93  guid << wxString::Format( "%3.3x", cc );
94  }
95 
96  // Output the 12 last hex digits:
97  guid << '-';
98 
99  for( unsigned ii = 0; ii < 6; ii++ )
100  {
101  int cc = int( bname[chr_idx++] ) & 0xFF;
102  guid << wxString::Format( "%2.2x", cc );
103  }
104 
105  return guid;
106 }
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205