KiCad PCB EDA Suite
gbr_metadata.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2019 Jean-Pierre Charras, jp.charras at wanadoo.fr
5  * Copyright (C) 2019 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, you may find one here:
19  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20  * or you may search the http://www.gnu.org website for the version 2 license,
21  * or you may write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23  */
24 
31 #include <fctsys.h>
32 #include <gbr_metadata.h>
33 #include <utf8.h>
34 
36 {
37  // creates the CreationDate attribute:
38  // The attribute value must conform to the full version of the ISO 8601
39  // date and time format, including time and time zone. Note that this is
40  // the date the Gerber file was effectively created,
41  // not the time the project of PCB was started
42  wxDateTime date( wxDateTime::GetTimeNow() );
43  // Date format: see http://www.cplusplus.com/reference/ctime/strftime
44  wxString timezone_offset; // ISO 8601 offset from UTC in timezone
45  timezone_offset = date.Format( "%z" ); // Extract the time zone offset
46  // The time zone offset format is +mm or +hhmm (or -mm or -hhmm)
47  // (mm = number of minutes, hh = number of hours. 1h00mn is returned as +0100)
48  // we want +(or -) hh:mm
49  if( timezone_offset.Len() > 3 ) // format +hhmm or -hhmm found
50  // Add separator between hours and minutes
51  timezone_offset.insert( 3, ":", 1 );
52 
53  wxString msg;
54 
55  switch( aFormat )
56  {
58  msg.Printf( "%%TF.CreationDate,%s%s*%%", date.FormatISOCombined(), timezone_offset );
59  break;
60 
62  msg.Printf( "G04 #@! TF.CreationDate,%s%s*", date.FormatISOCombined(), timezone_offset );
63  break;
64 
66  msg.Printf( "%s%s", date.FormatISOCombined(), timezone_offset );
67  break;
68 
70  msg.Printf( "; #@! TF.CreationDate,%s%s", date.FormatISOCombined(), timezone_offset );
71  break;
72  }
73  return msg;
74 }
75 
76 
77 wxString GbrMakeProjectGUIDfromString( wxString& aText )
78 {
79  /* Gerber GUID format should be RFC4122 Version 1 or 4.
80  * See en.wikipedia.org/wiki/Universally_unique_identifier
81  * The format is:
82  * xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx
83  * with
84  * x = hexDigit lower/upper case
85  * and
86  * M = '1' or '4' (UUID version: 1 (basic) or 4 (random)) (we use 4: UUID random)
87  * and
88  * N = '8' or '9' or 'A|a' or 'B|b' : UUID variant 1: 2 MSB bits have meaning) (we use N = 9)
89  * N = 1000 or 1001 or 1010 or 1011 : 10xx means Variant 1 (Variant2: 110x and 111x are reserved)
90  */
91 
92  wxString guid;
93 
94  // Build a 32 digits GUID from the board name:
95  // guid has 32 digits, so add chars in name to be sure we can build a 32 digits guid
96  // (i.e. from a 16 char string name)
97  // In fact only 30 digits are used, and 2 UID id
98  wxString bname = aText;
99  int cnt = 16 - bname.Len();
100 
101  if( cnt > 0 )
102  bname.Append( 'X', cnt );
103 
104  int chr_idx = 0;
105 
106  // Output the 8 first hex digits:
107  for( unsigned ii = 0; ii < 4; ii++ )
108  {
109  int cc = int( bname[chr_idx++] ) & 0xFF;
110  guid << wxString::Format( "%2.2x", cc );
111  }
112 
113  // Output the 4 next hex digits:
114  guid << '-';
115 
116  for( unsigned ii = 0; ii < 2; ii++ )
117  {
118  int cc = int( bname[chr_idx++] ) & 0xFF;
119  guid << wxString::Format( "%2.2x", cc );
120  }
121 
122  // Output the 4 next hex digits (UUID version and 3 digits):
123  guid << "-4"; // first digit: UUID version 4 (M = 4)
124  {
125  int cc = int( bname[chr_idx++] ) << 4 & 0xFF0;
126  cc += int( bname[chr_idx] ) >> 4 & 0x0F;
127  guid << wxString::Format( "%3.3x", cc );
128  }
129 
130  // Output the 4 next hex digits (UUID variant and 3 digits):
131  guid << "-9"; // first digit: UUID variant 1 (N = 9)
132  {
133  int cc = (int( bname[chr_idx++] ) & 0x0F) << 8;
134  cc += int( bname[chr_idx++] ) & 0xFF;
135  guid << wxString::Format( "%3.3x", cc );
136  }
137 
138  // Output the 12 last hex digits:
139  guid << '-';
140 
141  for( unsigned ii = 0; ii < 6; ii++ )
142  {
143  int cc = int( bname[chr_idx++] ) & 0xFF;
144  guid << wxString::Format( "%2.2x", cc );
145  }
146 
147  return guid;
148 }
149 
150 
152  bool aUseX1StructuredComment )
153 {
154  std::string attribute_string; // the specific aperture attribute (TA.xxx)
155  std::string comment_string; // a optional G04 comment line to write before the TA. line
156 
157  // generate a string to print a Gerber Aperture attribute
158  switch( aAttribute )
159  {
160  case GBR_APERTURE_ATTRIB_END: // Dummy value (aAttribute must be < GBR_APERTURE_ATTRIB_END)
161  case GBR_APERTURE_ATTRIB_NONE: // idle command: do nothing
162  break;
163 
164  case GBR_APERTURE_ATTRIB_ETCHEDCMP: // print info associated to an item
165  // which connects 2 different nets
166  // (Net tees, microwave component)
167  attribute_string = "TA.AperFunction,EtchedComponent";
168  break;
169 
170  case GBR_APERTURE_ATTRIB_CONDUCTOR: // print info associated to a track
171  attribute_string = "TA.AperFunction,Conductor";
172  break;
173 
174  case GBR_APERTURE_ATTRIB_EDGECUT: // print info associated to a board outline
175  attribute_string = "TA.AperFunction,Profile";
176  break;
177 
178  case GBR_APERTURE_ATTRIB_VIAPAD: // print info associated to a flashed via
179  attribute_string = "TA.AperFunction,ViaPad";
180  break;
181 
182  case GBR_APERTURE_ATTRIB_NONCONDUCTOR: // print info associated to a item on a copper layer
183  // which is not a track (for instance a text)
184  attribute_string = "TA.AperFunction,NonConductor";
185  break;
186 
187  case GBR_APERTURE_ATTRIB_COMPONENTPAD: // print info associated to a flashed
188  // through hole component on outer layer
189  attribute_string = "TA.AperFunction,ComponentPad";
190  break;
191 
192  case GBR_APERTURE_ATTRIB_SMDPAD_SMDEF: // print info associated to a flashed for SMD pad.
193  // with solder mask defined from the copper shape
194  // Excluded BGA pads which have their own type
195  attribute_string = "TA.AperFunction,SMDPad,SMDef";
196  break;
197 
198  case GBR_APERTURE_ATTRIB_SMDPAD_CUDEF: // print info associated to a flashed SMD pad with
199  // a solder mask defined by the solder mask
200  attribute_string = "TA.AperFunction,SMDPad,CuDef";
201  break;
202 
203  case GBR_APERTURE_ATTRIB_BGAPAD_SMDEF: // print info associated to flashed BGA pads with
204  // a solder mask defined by the copper shape
205  attribute_string = "TA.AperFunction,BGAPad,SMDef";
206  break;
207 
208  case GBR_APERTURE_ATTRIB_BGAPAD_CUDEF: // print info associated to a flashed BGA pad with
209  // a solder mask defined by the solder mask
210  attribute_string = "TA.AperFunction,BGAPad,CuDef";
211  break;
212 
213  case GBR_APERTURE_ATTRIB_CONNECTORPAD: // print info associated to a flashed edge connector pad (outer layers)
214  attribute_string = "TA.AperFunction,ConnectorPad";
215  break;
216 
217  case GBR_APERTURE_ATTRIB_WASHERPAD: // print info associated to flashed mechanical pads (NPTH)
218  attribute_string = "TA.AperFunction,WasherPad";
219  break;
220 
221  case GBR_APERTURE_ATTRIB_HEATSINKPAD: // print info associated to a flashed heat sink pad
222  // (typically for SMDs)
223  attribute_string = "TA.AperFunction,HeatsinkPad";
224  break;
225 
226  case GBR_APERTURE_ATTRIB_TESTPOINT: // print info associated to a flashed test point pad
227  // (typically for SMDs)
228  attribute_string = "TA.AperFunction,TestPad";
229  break;
230 
231  case GBR_APERTURE_ATTRIB_FIDUCIAL_GLBL: // print info associated to a flashed fiducial pad
232  // (typically for SMDs)
233  attribute_string = "TA.AperFunction,FiducialPad,Global";
234  break;
235 
236  case GBR_APERTURE_ATTRIB_FIDUCIAL_LOCAL: // print info associated to a flashed fiducial pad
237  // (typically for SMDs)
238  attribute_string = "TA.AperFunction,FiducialPad,Local";
239  break;
240 
241  case GBR_APERTURE_ATTRIB_CASTELLATEDPAD: // print info associated to a flashed castellated pad
242  // (typically for SMDs)
243  attribute_string = "TA.AperFunction,CastellatedPad";
244  break;
245 
246  case GBR_APERTURE_ATTRIB_CASTELLATEDDRILL: // print info associated to a flashed castellated pad
247  // in drill files
248  attribute_string = "TA.AperFunction,CastellatedDrill";
249  break;
250 
251  case GBR_APERTURE_ATTRIB_VIADRILL: // print info associated to a via hole in drill files
252  attribute_string = "TA.AperFunction,ViaDrill";
253  break;
254 
255  case GBR_APERTURE_ATTRIB_CMP_DRILL: // print info associated to a component
256  // round pad hole in drill files
257  attribute_string = "TA.AperFunction,ComponentDrill";
258  break;
259 
260  // print info associated to a component oblong pad hole in drill files
261  // Same as a round pad hole, but is a specific aperture in drill file and
262  // a G04 comment is added to the aperture function
264  comment_string = "aperture for slot hole";
265  attribute_string = "TA.AperFunction,ComponentDrill";
266  break;
267 
268  case GBR_APERTURE_ATTRIB_CMP_POSITION: // print info associated to a component
269  // flashed shape at the component position
270  // in placement files
271  attribute_string = "TA.AperFunction,ComponentMain";
272  break;
273 
274  case GBR_APERTURE_ATTRIB_PAD1_POSITION: // print info associated to a component
275  // flashed shape at pad 1 position
276  // (pad 1 is also pad A1 or pad AA1)
277  // in placement files
278  attribute_string = "TA.AperFunction,ComponentPin";
279  break;
280 
281  case GBR_APERTURE_ATTRIB_PADOTHER_POSITION: // print info associated to a component
282  // flashed shape at pads position (all but pad 1)
283  // in placement files
284  // Currently: (could be changed later) same as
285  // GBR_APERTURE_ATTRIB_PADOTHER_POSITION
286  attribute_string = "TA.AperFunction,ComponentPin";
287  break;
288 
289  case GBR_APERTURE_ATTRIB_CMP_BODY: // print info associated to a component
290  // print the component physical body
291  // polygon in placement files
292  attribute_string = "TA.AperFunction,ComponentOutline,Body";
293  break;
294 
295  case GBR_APERTURE_ATTRIB_CMP_LEAD2LEAD: // print info associated to a component
296  // print the component physical lead to lead
297  // polygon in placement files
298  attribute_string = "TA.AperFunction,ComponentOutline,Lead2Lead";
299  break;
300 
301  case GBR_APERTURE_ATTRIB_CMP_FOOTPRINT: // print info associated to a component
302  // print the component footprint bounding box
303  // polygon in placement files
304  attribute_string = "TA.AperFunction,ComponentOutline,Footprint";
305  break;
306 
307  case GBR_APERTURE_ATTRIB_CMP_COURTYARD: // print info associated to a component
308  // print the component courtyard
309  // polygon in placement files
310  attribute_string = "TA.AperFunction,ComponentOutline,Courtyard";
311  break;
312 
313  break;
314  }
315 
316  std::string full_attribute_string;
317  wxString eol_string;
318 
319  if( !attribute_string.empty() )
320  {
321  if( !comment_string.empty() )
322  {
323  full_attribute_string = "G04 " + comment_string + "*\n";
324  }
325 
326  if( aUseX1StructuredComment )
327  {
328  full_attribute_string += "G04 #@! ";
329  eol_string = "*\n";
330  }
331  else
332  {
333  full_attribute_string += "%";
334  eol_string = "*%\n";
335  }
336  }
337 
338  full_attribute_string += attribute_string + eol_string;
339 
340  return full_attribute_string;
341 }
342 
343 
344 // Helper function to convert a ascii hex char to its integer value
345 // If the char is not a hexa char, return -1
346 int char2Hex( unsigned aCode )
347 {
348  if( aCode >= '0' && aCode <= '9' )
349  return aCode - '0';
350 
351  if( aCode >= 'A' && aCode <= 'F' )
352  return aCode - 'A' + 10;
353 
354  if( aCode >= 'a' && aCode <= 'f' )
355  return aCode - 'a' + 10;
356 
357  return -1;
358 }
359 
360 
361 wxString FormatStringFromGerber( const wxString& aString )
362 {
363  // make the inverse conversion of FormatStringToGerber()
364  // It converts a "normalized" gerber string containing escape sequences
365  // and convert it to a 16 bits unicode char
366  // and return a wxString (unicode 16) from the gerber string
367  // Note the initial gerber string can already contain unicode chars.
368  wxString txt; // The string converted from Gerber string
369 
370  unsigned count = aString.Length();
371 
372  for( unsigned ii = 0; ii < count; ++ii )
373  {
374  unsigned code = aString[ii];
375 
376  if( code == '\\' && ii < count-5 && aString[ii+1] == 'u' )
377  {
378  // Note the latest Gerber X2 spec (2019 06) uses \uXXXX to encode
379  // the unicode XXXX hexadecimal value
380  // If 4 chars next to 'u' are hexadecimal chars,
381  // Convert these 4 hexadecimal digits to a 16 bit unicode
382  // (Gerber allows only 4 hexadecimal digits)
383  // If an error occurs, the escape sequence is not translated,
384  // and used "as this"
385  long value = 0;
386  bool error = false;
387 
388  for( int jj = 0; jj < 4; jj++ )
389  {
390  value <<= 4;
391  code = aString[ii+jj+2];
392 
393  int hexa = char2Hex( code );
394 
395  if( hexa >= 0 )
396  value += hexa;
397  else
398  {
399  error = true;
400  break;
401  }
402  }
403 
404  if( !error )
405  {
406  if( value >= ' ' ) // Is a valid wxChar ?
407  txt.Append( wxChar( value ) );
408 
409  ii += 5;
410  }
411  else
412  {
413  txt.Append( aString[ii] );
414  continue;
415  }
416  }
417  else
418  txt.Append( aString[ii] );
419  }
420 
421  return txt;
422 }
423 
424 
425 wxString ConvertNotAllowedCharsInGerber( const wxString& aString, bool aAllowUtf8Chars, bool aQuoteString )
426 {
427  /* format string means convert any code > 0x7E and unautorized codes to a hexadecimal
428  * 16 bits sequence unicode
429  * However if aAllowUtf8Chars is true only unautorized codes will be escaped, because some
430  * Gerber files accept UTF8 chars.
431  * unautorized codes are ',' '*' '%' '\' '"' and are used as separators in Gerber files
432  */
433  wxString txt;
434 
435  if( aQuoteString )
436  txt << "\"";
437 
438  for( unsigned ii = 0; ii < aString.Length(); ++ii )
439  {
440  wxChar code = aString[ii];
441  bool convert = false;
442 
443  switch( code )
444  {
445  case '\\':
446  case '%':
447  case '*':
448  case ',':
449  convert = true;
450  break;
451 
452  case '"':
453  if( aQuoteString )
454  convert = true;
455  break;
456 
457  default:
458  break;
459  }
460 
461  if( !aAllowUtf8Chars && code > 0x7F )
462  convert = true;
463 
464  if( convert )
465  {
466  // Convert code to 4 hexadecimal digit
467  // (Gerber allows only 4 hexadecimal digit) in escape seq:
468  // "\uXXXX", XXXX is the unicode 16 bits hexa value
469  char hexa[32];
470  sprintf( hexa,"\\u%4.4X", code & 0xFFFF);
471  txt += hexa;
472  }
473  else
474  txt += code;
475  }
476 
477  if( aQuoteString )
478  txt << "\"";
479 
480  return txt;
481 }
482 
483 
485 {
486  wxString converted;
487 
488  if( !m_field.IsEmpty() )
490 
491  // Convert the char string to std::string. Be carefull when converting awxString to
492  // a std::string: using static_cast<const char*> is mandatory
493  std::string txt = static_cast<const char*>( converted.utf8_str() );
494 
495  return txt;
496 }
497 
498 
499 std::string FormatStringToGerber( const wxString& aString )
500 {
501  wxString converted;
502  /* format string means convert any code > 0x7E and unautorized codes to a hexadecimal
503  * 16 bits sequence unicode
504  * unautorized codes are ',' '*' '%' '\'
505  * This conversion is not made for quoted strings, because if the string is
506  * quoted, the conversion is expected to be already made, and the returned string must use
507  * UTF8 encoding
508  */
509  if( !aString.IsEmpty() && ( aString[0] != '\"' || aString[aString.Len()-1] != '\"' ) )
510  converted = ConvertNotAllowedCharsInGerber( aString, false, false );
511  else
512  converted = aString;
513 
514  // Convert the char string to std::string. Be carefull when converting awxString to
515  // a std::string: using static_cast<const char*> is mandatory
516  std::string txt = static_cast<const char*>( converted.utf8_str() );
517 
518  return txt;
519 }
520 
521 // Netname and Pan num fields cannot be empty in Gerber files
522 // Normalized names must be used, if any
523 #define NO_NET_NAME wxT( "N/C" ) // net name of not connected pads (one pad net) (normalized)
524 #define NO_PAD_NAME wxT( "" ) // pad name of pads without pad name/number (not normalized)
525 
526 bool FormatNetAttribute( std::string& aPrintedText, std::string& aLastNetAttributes,
527  GBR_NETLIST_METADATA* aData, bool& aClearPreviousAttributes,
528  bool aUseX1StructuredComment )
529 {
530  aClearPreviousAttributes = false;
531  wxString prepend_string;
532  wxString eol_string;
533 
534  if( aUseX1StructuredComment )
535  {
536  prepend_string = "G04 #@! ";
537  eol_string = "*\n";
538  }
539  else
540  {
541  prepend_string = "%";
542  eol_string = "*%\n";
543  }
544 
545  // print a Gerber net attribute record.
546  // it is added to the object attributes dictionary
547  // On file, only modified or new attributes are printed.
548  if( aData == NULL )
549  return false;
550 
551  std::string pad_attribute_string;
552  std::string net_attribute_string;
553  std::string cmp_attribute_string;
554 
556  return false; // idle command: do nothing
557 
559  {
560  // print info associated to a flashed pad (cmpref, pad name, and optionally pin function)
561  // example1: %TO.P,R5,3*%
562  // example2: %TO.P,R5,3,reset*%
563  pad_attribute_string = prepend_string + "TO.P,";
564  pad_attribute_string += FormatStringToGerber( aData->m_Cmpref ) + ",";
565 
566  if( aData->m_Padname.IsEmpty() )
567  // Happens for "mechanical" or never connected pads
568  pad_attribute_string += FormatStringToGerber( NO_PAD_NAME );
569  else
570  {
571  pad_attribute_string += aData->m_Padname.GetGerberString();
572 
573  // In Pcbnew, the pin function comes from the schematic.
574  // so it exists only for named pads
575  if( !aData->m_PadPinFunction.IsEmpty() )
576  {
577  pad_attribute_string += ',';
578  pad_attribute_string += aData->m_PadPinFunction.GetGerberString();
579  }
580  }
581 
582  pad_attribute_string += eol_string;
583  }
584 
586  {
587  // print info associated to a net
588  // example: %TO.N,Clk3*%
589  net_attribute_string = prepend_string + "TO.N,";
590 
591  if( aData->m_Netname.IsEmpty() )
592  {
593  if( aData->m_NotInNet )
594  {
595  // Happens for not connectable pads: mechanical pads
596  // and pads with no padname/num
597  // In this case the net name must be left empty
598  }
599  else
600  {
601  // Happens for not connected pads: use a normalized
602  // dummy name
603  net_attribute_string += FormatStringToGerber( NO_NET_NAME );
604  }
605  }
606  else
607  net_attribute_string += FormatStringToGerber( aData->m_Netname );
608 
609  net_attribute_string += eol_string;
610  }
611 
614  {
615  // print info associated to a footprint
616  // example: %TO.C,R2*%
617  // Because GBR_NETINFO_PAD option already contains this info, it is not
618  // created here for a GBR_NETINFO_PAD attribute
619  cmp_attribute_string = prepend_string + "TO.C,";
620  cmp_attribute_string += FormatStringToGerber( aData->m_Cmpref ) + eol_string;
621  }
622 
623  // the full list of requested attributes:
624  std::string full_attribute_string = pad_attribute_string + net_attribute_string
625  + cmp_attribute_string;
626  // the short list of requested attributes
627  // (only modified or new attributes are stored here):
628  std::string short_attribute_string;
629 
630  // Attributes have changed: update attribute string, and see if the previous attribute
631  // list (dictionary in Gerber language) must be cleared
632  if( aLastNetAttributes != full_attribute_string )
633  {
634  // first, remove no longer existing attributes.
635  // Because in Kicad the full attribute list is evaluated for each object,
636  // the entire dictionary is cleared
637  // If m_TryKeepPreviousAttributes is true, only the no longer existing attribute
638  // is cleared.
639  // Note: to avoid interaction beteween clear attributes and set attributes
640  // the clear attribute is inserted first.
641  bool clearDict = false;
642 
643  if( aLastNetAttributes.find( "TO.P," ) != std::string::npos )
644  {
645  if( pad_attribute_string.empty() ) // No more this attribute
646  {
647  if( aData->m_TryKeepPreviousAttributes ) // Clear only this attribute
648  short_attribute_string.insert( 0, prepend_string + "TO.P" + eol_string );
649  else
650  clearDict = true;
651  }
652  else if( aLastNetAttributes.find( pad_attribute_string )
653  == std::string::npos ) // This attribute has changed
654  short_attribute_string += pad_attribute_string;
655  }
656  else // New attribute
657  short_attribute_string += pad_attribute_string;
658 
659  if( aLastNetAttributes.find( "TO.N," ) != std::string::npos )
660  {
661  if( net_attribute_string.empty() ) // No more this attribute
662  {
663  if( aData->m_TryKeepPreviousAttributes ) // Clear only this attribute
664  short_attribute_string.insert( 0, prepend_string + "TO.N" + eol_string );
665  else
666  clearDict = true;
667  }
668  else if( aLastNetAttributes.find( net_attribute_string )
669  == std::string::npos ) // This attribute has changed
670  short_attribute_string += net_attribute_string;
671  }
672  else // New attribute
673  short_attribute_string += net_attribute_string;
674 
675  if( aLastNetAttributes.find( "TO.C," ) != std::string::npos )
676  {
677  if( cmp_attribute_string.empty() ) // No more this attribute
678  {
679  if( aData->m_TryKeepPreviousAttributes ) // Clear only this attribute
680  {
681  // Refinement:
682  // the attribute will be cleared only if there is no pad attribute.
683  // If a pad attribute exists, the component name exists so the old
684  // TO.C value will be updated, therefore no need to clear it before updating
685  if( pad_attribute_string.empty() )
686  short_attribute_string.insert( 0, prepend_string + "TO.C" + eol_string );
687  }
688  else
689  clearDict = true;
690  }
691  else if( aLastNetAttributes.find( cmp_attribute_string )
692  == std::string::npos ) // This attribute has changed
693  short_attribute_string += cmp_attribute_string;
694  }
695  else // New attribute
696  short_attribute_string += cmp_attribute_string;
697 
698  aClearPreviousAttributes = clearDict;
699 
700  aLastNetAttributes = full_attribute_string;
701 
702  if( clearDict )
703  aPrintedText = full_attribute_string;
704  else
705  aPrintedText = short_attribute_string;
706  }
707 
708  return true;
709 }
710 
711 
712 /************ class GBR_CMP_PNP_METADATA *************/
713 
715 {
716  // Clear all strings
717  m_Orientation = 0.0;
718  m_Manufacturer.Clear();
719  m_MPN.Clear();
720  m_Package.Clear();
721  m_Value.Clear();
723 }
730 {
731  wxString text;
732  wxString start_of_line( "%TO.");
733  wxString end_of_line( "*%\n" );
734 
735  wxString mounType[] =
736  {
737  "Other", "SMD", "TH"
738  };
739 
740  if( !m_Manufacturer.IsEmpty() )
741  text << start_of_line << "CMfr," << m_Manufacturer << end_of_line;
742 
743  if( !m_MPN.IsEmpty() )
744  text << start_of_line << "CMPN," << m_MPN << end_of_line;
745 
746  if( !m_Package.IsEmpty() )
747  text << start_of_line << "Cpkg," << m_Package << end_of_line;
748 
749  if( !m_Footprint.IsEmpty() )
750  text << start_of_line << "CFtp," << m_Footprint << end_of_line;
751 
752  if( !m_Value.IsEmpty() )
753  text << start_of_line << "CVal," << m_Value << end_of_line;
754 
755  if( !m_LibraryName.IsEmpty() )
756  text << start_of_line << "CLbN," << m_LibraryName << end_of_line;
757 
758  if( !m_LibraryDescr.IsEmpty() )
759  text << start_of_line << "CLbD," << m_LibraryDescr << end_of_line;
760 
761  text << start_of_line << "CMnt," << mounType[m_MountType] << end_of_line;
762  text << start_of_line << "CRot," << m_Orientation << end_of_line;
763 
764  return text;
765 }
std::string FormatStringToGerber(const wxString &aString)
This helper function "normalize" aString and convert it to a Gerber std::string Normalisation means c...
a class to handle special data (items attributes) during plot.
aperture used for etched components
Definition: gbr_metadata.h:83
aperture used to draw component footprint bounding box in placement files
Definition: gbr_metadata.h:113
#define NO_NET_NAME
aperture used for edge connector pad (outer layers)
Definition: gbr_metadata.h:94
aperture used for flashed pin 1 (or A1 or AA1) position in placement files
Definition: gbr_metadata.h:107
aperture used for pads oblong holes in drill files
Definition: gbr_metadata.h:105
aperture used for heat sink pad (typically for SMDs)
Definition: gbr_metadata.h:99
bool m_useUTF8
true to use UTF8, false to escape non ascii7 chars
aperture used for flashed pads position in placement files
Definition: gbr_metadata.h:108
print info associated to a component (TO.C attribute)
int char2Hex(unsigned aCode)
wxString m_Cmpref
the component reference parent of the data
aperture used for through hole component on outer layer
Definition: gbr_metadata.h:89
wxString m_field
the unicade text to print in Gbr file (after escape and quoting)
aperture used for via holes in drill files
Definition: gbr_metadata.h:103
aperture used for castellated pads in drill files
Definition: gbr_metadata.h:101
wxString GbrMakeCreationDateAttributeString(GBR_NC_STRING_FORMAT aFormat)
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.
aperture used for castellated pads in copper layer files
Definition: gbr_metadata.h:100
this class handle info which can be added in a gerber file as attribute of an object the GBR_INFO_TYP...
aperture used for SMD pad. Excluded BGA pads which have their own type
Definition: gbr_metadata.h:90
GBR_DATA_FIELD m_PadPinFunction
for a pad: the pin function (defined in schematic)
aperture used for BGA pad with a solder mask defined by the solder mask
Definition: gbr_metadata.h:93
aperture used for fiducial pad (outer layers), at board level
Definition: gbr_metadata.h:97
#define NULL
wxString GbrMakeProjectGUIDfromString(wxString &aText)
A helper function to build a project GUID using format RFC4122 Version 1 or 4 from the project name,...
#define NO_PAD_NAME
aperture used for pad holes in drill files
Definition: gbr_metadata.h:104
GBR_DATA_FIELD m_Padname
for a flashed pad: the pad name ((TO.P attribute)
bool m_escapeString
true to quote the field in gbr file
wxString m_Netname
for items associated to a net: the netname
aperture used for mechanical pads (NPTH)
Definition: gbr_metadata.h:95
aperture used to draw component outline courtyard in placement files
Definition: gbr_metadata.h:115
aperture used for BGA pads with a solder mask defined by the copper shape
Definition: gbr_metadata.h:92
aperture used for connected items like tracks (not vias)
Definition: gbr_metadata.h:84
aperture used to draw component physical body outline (without pins) in placement files
Definition: gbr_metadata.h:109
aperture used for test point pad (outer layers)
Definition: gbr_metadata.h:96
static std::string FormatAttribute(GBR_APERTURE_ATTRIB aAttribute, bool aUseX1StructuredComment)
aperture used for flashed cmp position in placement files
Definition: gbr_metadata.h: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
wxString FormatCmpPnPMetadata()
std::string GetGerberString()
aperture used for fiducial pad (outer layers), at footprint level
Definition: gbr_metadata.h:98
aperture used for SMD pad with a solder mask defined by the solder mask
Definition: gbr_metadata.h:91
bool m_TryKeepPreviousAttributes
If true, do not clear all attributes when a atribute has changed Usefull when some attributes need to...
wxString ConvertNotAllowedCharsInGerber(const wxString &aString, bool aAllowUtf8Chars, bool aQuoteString)
Similar to FormatStringToGerber.
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)...
wxString FormatStringFromGerber(const wxString &aString)
This helper function make the inverse conversion of FormatStringToGerber() It converts a "normalized"...
aperture used for not connected items (texts, outlines on copper)
Definition: gbr_metadata.h:86
print info associated to a net (TO.N attribute)
GBR_NC_STRING_FORMAT
creates the TF.CreationDate attribute: The attribute value must conform to the full version of the IS...
Definition: gbr_metadata.h:51
aperture used to draw component physical body outline (with pins) in placement files
Definition: gbr_metadata.h:111
int m_NetAttribType
the type of net info (used to define the gerber string to create)