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