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