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