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) 2018 Jean-Pierre Charras, jp.charras at wanadoo.fr
5  * Copyright (C) 2018 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 
34 
36  bool aUseX1StructuredComment )
37 {
38  std::string attribute_string;
39 
40  // generate a string to print a Gerber Aperture attribute
41  switch( aAttribute )
42  {
43  case GBR_APERTURE_ATTRIB_END: // Dummy value (aAttribute must be < GBR_APERTURE_ATTRIB_END)
44  case GBR_APERTURE_ATTRIB_NONE: // idle command: do nothing
45  break;
46 
47  case GBR_APERTURE_ATTRIB_ETCHEDCMP: // print info associated to an item
48  // which connects 2 different nets
49  // (Net tees, microwave component)
50  attribute_string = "TA.AperFunction,EtchedComponent";
51  break;
52 
53  case GBR_APERTURE_ATTRIB_CONDUCTOR: // print info associated to a track
54  attribute_string = "TA.AperFunction,Conductor";
55  break;
56 
57  case GBR_APERTURE_ATTRIB_CUTOUT: // print info associated to a outline
58  attribute_string = "TA.AperFunction,CutOut";
59  break;
60 
61  case GBR_APERTURE_ATTRIB_VIAPAD: // print info associated to a flashed via
62  attribute_string = "TA.AperFunction,ViaPad";
63  break;
64 
65  case GBR_APERTURE_ATTRIB_NONCONDUCTOR: // print info associated to a item on a copper layer
66  // which is not a track (for instance a text)
67  attribute_string = "TA.AperFunction,NonConductor";
68  break;
69 
70  case GBR_APERTURE_ATTRIB_COMPONENTPAD: // print info associated to a flashed
71  // through hole component on outer layer
72  attribute_string = "TA.AperFunction,ComponentPad";
73  break;
74 
75  case GBR_APERTURE_ATTRIB_SMDPAD_SMDEF: // print info associated to a flashed for SMD pad.
76  // with solder mask defined from the copper shape
77  // Excluded BGA pads which have their own type
78  attribute_string = "TA.AperFunction,SMDPad,SMDef";
79  break;
80 
81  case GBR_APERTURE_ATTRIB_SMDPAD_CUDEF: // print info associated to a flashed SMD pad with
82  // a solder mask defined by the solder mask
83  attribute_string = "TA.AperFunction,SMDPad,CuDef";
84  break;
85 
86  case GBR_APERTURE_ATTRIB_BGAPAD_SMDEF: // print info associated to flashed BGA pads with
87  // a solder mask defined by the copper shape
88  attribute_string = "TA.AperFunction,BGAPad,SMDef";
89  break;
90 
91  case GBR_APERTURE_ATTRIB_BGAPAD_CUDEF: // print info associated to a flashed BGA pad with
92  // a solder mask defined by the solder mask
93  attribute_string = "TA.AperFunction,BGAPad,CuDef";
94  break;
95 
96  case GBR_APERTURE_ATTRIB_CONNECTORPAD: // print info associated to a flashed edge connector pad (outer layers)
97  attribute_string = "TA.AperFunction,ConnectorPad";
98  break;
99 
100  case GBR_APERTURE_ATTRIB_WASHERPAD: // print info associated to flashed mechanical pads (NPTH)
101  attribute_string = "TA.AperFunction,WasherPad";
102  break;
103 
104  case GBR_APERTURE_ATTRIB_HEATSINKPAD: // print info associated to a flashed heat sink pad
105  // (typically for SMDs)
106  attribute_string = "TA.AperFunction,HeatsinkPad";
107  break;
108 
109  case GBR_APERTURE_ATTRIB_VIADRILL: // print info associated to a via hole in drill files
110  attribute_string = "TA.AperFunction,ViaDrill";
111  break;
112 
113  case GBR_APERTURE_ATTRIB_COMPONENTDRILL: // print info associated to a component
114  // round hole in drill files
115  attribute_string = "TA.AperFunction,ComponentDrill";
116  break;
117 
118  case GBR_APERTURE_ATTRIB_SLOTDRILL: // print info associated to a oblong hole in drill files
119  attribute_string = "TA.AperFunction,Slot";
120  break;
121  }
122 
123  std::string full_attribute_string;
124  wxString eol_string;
125 
126  if( !attribute_string.empty() )
127  {
128  if( aUseX1StructuredComment )
129  {
130  full_attribute_string = "G04 #@! ";
131  eol_string = "*\n";
132  }
133  else
134  {
135  full_attribute_string = "%";
136  eol_string = "*%\n";
137  }
138  }
139 
140  full_attribute_string += attribute_string + eol_string;
141 
142  return full_attribute_string;
143 }
144 
145 wxString FormatStringFromGerber( const wxString& aString )
146 {
147  // make the inverse conversion of formatStringToGerber()
148  // It converts a "normalized" gerber string and convert it to a 16 bits sequence unicode
149  // and return a wxString (unicode 16) from the gerber string
150  wxString txt;
151 
152  for( unsigned ii = 0; ii < aString.Length(); ++ii )
153  {
154  unsigned code = aString[ii];
155 
156  if( code == '\\' )
157  {
158  // Convert 4 hexadecimal digits to a 16 bit unicode
159  // (Gerber allows only 4 hexadecimal digits)
160  long value = 0;
161 
162  for( int jj = 0; jj < 4; jj++ )
163  {
164  value <<= 4;
165  code = aString[++ii];
166  // Very basic conversion, but it expects a valid gerber file
167  int hexa = (code <= '9' ? code - '0' : code - 'A' + 10) & 0xF;
168  value += hexa;
169  }
170 
171  txt.Append( wxChar( value ) );
172  }
173  else
174  txt.Append( aString[ii] );
175  }
176 
177  return txt;
178 }
179 
180 
181 std::string formatStringToGerber( const wxString& aString )
182 {
183  /* format string means convert any code > 0x7F and unautorized code to a hexadecimal
184  * 16 bits sequence unicode
185  * unautorized codes are ',' '*' '%' '\'
186  */
187  std::string txt;
188 
189  txt.reserve( aString.Length() );
190 
191  for( unsigned ii = 0; ii < aString.Length(); ++ii )
192  {
193  unsigned code = aString[ii];
194  bool convert = false;
195 
196  switch( code )
197  {
198  case '\\':
199  case '%':
200  case '*':
201  case ',':
202  convert = true;
203  break;
204 
205  default:
206  break;
207  }
208 
209  if( convert || code > 0x7F )
210  {
211  txt += '\\';
212 
213  // Convert code to 4 hexadecimal digit
214  // (Gerber allows only 4 hexadecimal digit)
215  char hexa[32];
216  sprintf( hexa,"%4.4X", code & 0xFFFF);
217  txt += hexa;
218  }
219  else
220  txt += char( code );
221  }
222 
223  return txt;
224 }
225 
226 // Netname and Pan num fields cannot be empty in Gerber files
227 // Normalized names must be used, if any
228 #define NO_NET_NAME wxT( "N/C" ) // net name of not connected pads (one pad net) (normalized)
229 #define NO_PAD_NAME wxT( "" ) // pad name of pads without pad name/number (not normalized)
230 
231 bool FormatNetAttribute( std::string& aPrintedText, std::string& aLastNetAttributes,
232  GBR_NETLIST_METADATA* aData, bool& aClearPreviousAttributes,
233  bool aUseX1StructuredComment )
234 {
235  aClearPreviousAttributes = false;
236  wxString prepend_string;
237  wxString eol_string;
238 
239  if( aUseX1StructuredComment )
240  {
241  prepend_string = "G04 #@! ";
242  eol_string = "*\n";
243  }
244  else
245  {
246  prepend_string = "%";
247  eol_string = "*%\n";
248  }
249 
250  // print a Gerber net attribute record.
251  // it is added to the object attributes dictionnary
252  // On file, only modified or new attributes are printed.
253  if( aData == NULL )
254  return false;
255 
256  std::string pad_attribute_string;
257  std::string net_attribute_string;
258  std::string cmp_attribute_string;
259 
261  return false; // idle command: do nothing
262 
264  {
265  // print info associated to a flashed pad (cmpref, pad name)
266  // example: %TO.P,R5,3*%
267  pad_attribute_string = prepend_string + "TO.P,";
268  pad_attribute_string += formatStringToGerber( aData->m_Cmpref ) + ",";
269 
270  if( aData->m_Padname.IsEmpty() )
271  // Happens for "mechanical" or never connected pads
272  pad_attribute_string += formatStringToGerber( NO_PAD_NAME );
273  else
274  pad_attribute_string += formatStringToGerber( aData->m_Padname );
275 
276  pad_attribute_string += eol_string;
277  }
278 
280  {
281  // print info associated to a net
282  // example: %TO.N,Clk3*%
283  net_attribute_string = prepend_string + "TO.N,";
284 
285  if( aData->m_Netname.IsEmpty() )
286  {
287  if( aData->m_NotInNet )
288  {
289  // Happens for not connectable pads: mechanical pads
290  // and pads with no padname/num
291  // In this case the net name must be left empty
292  }
293  else
294  {
295  // Happens for not connected pads: use a normalized
296  // dummy name
297  net_attribute_string += formatStringToGerber( NO_NET_NAME );
298  }
299  }
300  else
301  net_attribute_string += formatStringToGerber( aData->m_Netname );
302 
303  net_attribute_string += eol_string;
304  }
305 
308  {
309  // print info associated to a footprint
310  // example: %TO.C,R2*%
311  // Because GBR_NETINFO_PAD option already contains this info, it is not
312  // created here for a GBR_NETINFO_PAD attribute
313  cmp_attribute_string = prepend_string + "TO.C,";
314  cmp_attribute_string += formatStringToGerber( aData->m_Cmpref ) + eol_string;
315  }
316 
317  // the full list of requested attributes:
318  std::string full_attribute_string = pad_attribute_string + net_attribute_string
319  + cmp_attribute_string;
320  // the short list of requested attributes
321  // (only modified or new attributes are stored here):
322  std::string short_attribute_string;
323 
324  if( aLastNetAttributes != full_attribute_string )
325  {
326  // first, remove no more existing attributes.
327  // Because in Kicad the full attribute list is evaluated for each object,
328  // the entire dictionnary is cleared
329  bool clearDict = false;
330 
331  if( aLastNetAttributes.find( "TO.P," ) != std::string::npos )
332  {
333  if( pad_attribute_string.empty() ) // No more this attribute
334  clearDict = true;
335  else if( aLastNetAttributes.find( pad_attribute_string )
336  == std::string::npos ) // This attribute has changed
337  short_attribute_string += pad_attribute_string;
338  }
339  else // New attribute
340  short_attribute_string += pad_attribute_string;
341 
342  if( aLastNetAttributes.find( "TO.N," ) != std::string::npos )
343  {
344  if( net_attribute_string.empty() ) // No more this attribute
345  clearDict = true;
346  else if( aLastNetAttributes.find( net_attribute_string )
347  == std::string::npos ) // This attribute has changed
348  short_attribute_string += net_attribute_string;
349  }
350  else // New attribute
351  short_attribute_string += net_attribute_string;
352 
353  if( aLastNetAttributes.find( "TO.C," ) != std::string::npos )
354  {
355  if( cmp_attribute_string.empty() ) // No more this attribute
356  clearDict = true;
357  else if( aLastNetAttributes.find( cmp_attribute_string )
358  == std::string::npos ) // This attribute has changed
359  short_attribute_string += cmp_attribute_string;
360  }
361  else // New attribute
362  short_attribute_string += cmp_attribute_string;
363 
364  aClearPreviousAttributes = clearDict;
365 
366  aLastNetAttributes = full_attribute_string;
367 
368  if( clearDict )
369  aPrintedText = full_attribute_string;
370  else
371  aPrintedText = short_attribute_string;
372  }
373 
374  return true;
375 }
a class to handle special data (items attributes) during plot.
aperture used for etched components
Definition: gbr_metadata.h:50
#define NO_NET_NAME
aperture used for edge connecto pad (outer layers)
Definition: gbr_metadata.h:60
aperture used for heat sink pad (typically for SMDs)
Definition: gbr_metadata.h:62
print info associated to a component (TO.C attribute)
wxString m_Cmpref
the component reference parent of the data
aperture used for through hole component on outer layer
Definition: gbr_metadata.h:55
aperture used for via holes in drill files
Definition: gbr_metadata.h:63
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...
this class handle info which can be added in a gerber file as attribute of an obtect the GBR_INFO_TYP...
std::string formatStringToGerber(const wxString &aString)
This helper function "normalize" aString and convert it to a Gerber std::string Normalisation means c...
aperture used for SMD pad. Excluded BGA pads which have their own type
Definition: gbr_metadata.h:56
aperture used for BGA pad with a solder mask defined by the solder mask
Definition: gbr_metadata.h:59
wxString m_Padname
for a flashed pad: the pad name ((TO.P attribute)
#define NO_PAD_NAME
aperture used for pad holes in drill files
Definition: gbr_metadata.h:64
wxString m_Netname
for items associated to a net: the netname
aperture used for mechanical pads (NPTH)
Definition: gbr_metadata.h:61
aperture used for BGA pads with a solder mask defined by the copper shape
Definition: gbr_metadata.h:58
aperture used for connected items like tracks (not vias)
Definition: gbr_metadata.h:51
static std::string FormatAttribute(GBR_APERTURE_ATTRIB aAttribute, bool aUseX1StructuredComment)
aperture used for SMD pad with a solder mask defined by the solder mask
Definition: gbr_metadata.h:57
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:53
print info associated to a net (TO.N attribute)
aperture used for oblong holes in drill files
Definition: gbr_metadata.h:65
int m_NetAttribType
the type of net info (used to define the gerber string to create)