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