KiCad PCB EDA Suite
X2_gerber_attributes.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) 2010-2014 Jean-Pierre Charras jp.charras at wanadoo.fr
5  * Copyright (C) 1992-2014 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 
29 /*
30  * Manage the gerber extensions (attributes) in the new X2 version
31  * only few extensions are handled
32  * See http://www.ucamco.com/files/downloads/file/81/the_gerber_file_format_specification.pdf
33  *
34  * gerber attributes in the new X2 version look like:
35  * %TF.FileFunction,Copper,L1,Top*%
36  *
37  * Currently:
38  * .FileFunction .FileFunction Identifies the file's function in the PCB.
39  * Other Standard Attributes, not yet used in Gerbview:
40  * .Part Identifies the part the file represents, e.g. a single PCB
41  * .MD5 Sets the MD5 file signature or checksum.
42  */
43 
44 #include <wx/log.h>
45 #include <X2_gerber_attributes.h>
46 #include <macros.h>
47 
48 /*
49  * class X2_ATTRIBUTE
50  * The attribute value consists of a number of substrings separated by a comma
51  */
52 
54 {
55 }
56 
58 {
59 }
60 
61 /* return the attribute name (for instance .FileFunction)
62  * which is given by TF command.
63  */
64 const wxString& X2_ATTRIBUTE::GetAttribute()
65 {
66  return m_Prms.Item( 0 );
67 }
68 
69 /* return a parameter
70  * aIdx = the index of the parameter
71  * aIdx = 0 is the parameter read after the TF function
72  * (the same as GetAttribute())
73  */
74 const wxString& X2_ATTRIBUTE::GetPrm( int aIdx)
75 {
76  static const wxString dummy;
77 
78  if( GetPrmCount() > aIdx && aIdx >= 0 )
79  return m_Prms.Item( aIdx );
80 
81  return dummy;
82 }
83 
84 // Debug function: pring using wxLogMessage the list of parameters
86 {
87  wxLogMessage( wxT("prms count %d"), GetPrmCount() );
88 
89  for( int ii = 0; ii < GetPrmCount(); ii++ )
90  wxLogMessage( m_Prms.Item( ii ) );
91 }
92 
93 bool X2_ATTRIBUTE::ParseAttribCmd( FILE* aFile, char *aBuffer, int aBuffSize, char* &aText,
94  int& aLineNum )
95 {
96  // parse a TF, TA, TO ... command and fill m_Prms by the parameters found.
97  // the "%TF" (start of command) is already read by the caller
98 
99  bool ok = true;
100  std::string data;
101 
102  for( ; ; )
103  {
104  while( *aText )
105  {
106  switch( *aText )
107  {
108  case '%': // end of command
109  return ok; // success completion
110 
111  case ' ':
112  case '\r':
113  case '\n':
114  aText++;
115  break;
116 
117  case '*': // End of block
118  m_Prms.Add( FROM_UTF8( data.c_str() ) );
119  data.clear();
120  aText++;
121  break;
122 
123  case ',': // End of parameter (separator)
124  aText++;
125  m_Prms.Add( FROM_UTF8( data.c_str() ) );
126  data.clear();
127  break;
128 
129  default:
130  data += *aText;
131  aText++;
132  break;
133  }
134  }
135 
136  // end of current line, read another one.
137  if( aBuffer && aFile )
138  {
139  if( fgets( aBuffer, aBuffSize, aFile ) == NULL )
140  {
141  // end of file
142  ok = false;
143  break;
144  }
145 
146  aLineNum++;
147  aText = aBuffer;
148  }
149  else
150  return ok;
151  }
152 
153  return ok;
154 }
155 
156 /*
157  * class X2_ATTRIBUTE_FILEFUNCTION ( from %TF.FileFunction in Gerber file)
158  * Example file function:
159  * %TF.FileFunction,Copper,L1,Top*%
160  * - Type. Such as copper, solder mask etc.
161  * - Position. Specifies where the file appears in the PCB layer structure.
162  * Corresponding position substring:
163  * Copper layer: L1, L2, L3...to indicate the layer position followed by Top, Inr or
164  * Bot. L1 is always the top copper layer. E.g. L2,Inr.
165  * Extra layer, e.g. solder mask: Top or Bot - defines the attachment of the layer.
166  * Drill/rout layer: E.g. 1,4 - where 1 is the start and 4 is the end copper layer. The
167  * pair 1,4 defines the span of the drill/rout file
168  * Optional index. This can be used in instances where for example there are two solder
169  * masks on the same side. The index counts from the PCB surface outwards.
170  */
172  : X2_ATTRIBUTE()
173 {
174  m_Prms = aAttributeBase.GetPrms();
175  m_z_order = 0;
176 
177  // ensure at least 7 parameters exist.
178  while( GetPrmCount() < 7 )
179  m_Prms.Add( wxEmptyString );
180 
181  set_Z_Order();
182 }
183 
185 {
186  // the type of layer (Copper, Soldermask ... )
187  return m_Prms.Item( 1 );
188 }
189 
191 {
192  // the brd layer identifier: Ln (for Copper type) or Top, Bot
193  return m_Prms.Item( 2 );
194 }
195 
197 {
198  // the layer pair identifiers, for drill files, i.e.
199  // with m_Prms.Item( 1 ) = "Plated" or "NonPlated"
200  wxString lpair = m_Prms.Item( 2 ) + ',' + m_Prms.Item( 3 );
201  return lpair;
202 }
203 
205 {
206  if( IsCopper() )
207  // the brd layer identifier: Top, Bot, Inr
208  return m_Prms.Item( 3 );
209  else
210  // the brd layer identifier: Top, Bot ( same as GetBrdLayerId() )
211  return m_Prms.Item( 2 );
212 }
213 
214 
216 {
217  if( IsCopper() )
218  return m_Prms.Item( 4 );
219  else
220  return m_Prms.Item( 3 );
221 }
222 
223 
225 {
226  // Only for drill files: the Layer Pair type (PTH, NPTH, Blind or Buried)
227  return m_Prms.Item( 4 );
228 }
229 
230 
232 {
233  // Only for drill files: the drill/routing type(Drill, Route, Mixed)
234  return m_Prms.Item( 5 );
235 }
236 
237 
239 {
240  // the filefunction label, if any
241  return GetFileType().IsSameAs( wxT( "Copper" ), false );
242 }
243 
244 
246 {
247  // the filefunction label, if any
248  return GetFileType().IsSameAs( wxT( "Plated" ), false )
249  || GetFileType().IsSameAs( wxT( "NonPlated" ), false );
250 }
251 
252 
253 // Initialize the z order priority of the current file, from its attributes
254 // this priority is the order of layers from top to bottom to draw/display gerber images
255 // Stack up is( from external copper layer to external)
256 // copper, then solder paste, then solder mask, then silk screen.
257 // and global stackup is Front (top) layers then internal copper layers then Back (bottom) layers
259 {
260  m_z_order = -100; // low level
261  m_z_sub_order = 0;
262 
263  if( IsCopper() )
264  {
265  // Copper layer: the priority is the layer Id
266  m_z_order = 0;
267  wxString num = GetBrdLayerId().Mid( 1 );
268  long lnum;
269  if( num.ToLong( &lnum ) )
270  m_z_sub_order = -lnum;
271  }
272 
273  if( GetFileType().IsSameAs( wxT( "Paste" ), false ) )
274  {
275  // solder paste layer: the priority is top then bottom
276  m_z_order = 1; // for top
277 
278  if( GetBrdLayerId().IsSameAs( wxT( "Bot" ), false ) )
279  m_z_order = -m_z_order;
280  }
281 
282  if( GetFileType().IsSameAs( wxT( "Soldermask" ), false ) )
283  {
284  // solder mask layer: the priority is top then bottom
285  m_z_order = 2; // for top
286 
287  if( GetBrdLayerId().IsSameAs( wxT( "Bot" ), false ) )
288  m_z_order = -m_z_order;
289  }
290 
291  if( GetFileType().IsSameAs( wxT( "Legend" ), false ) )
292  {
293  // Silk screen layer: the priority is top then bottom
294  m_z_order = 3; // for top
295 
296  if( GetBrdLayerId().IsSameAs( wxT( "Bot" ), false ) )
297  m_z_order = -m_z_order;
298  }
299 
300  if( GetFileType().IsSameAs( wxT( "Glue" ), false ) )
301  {
302  // Glue spots used to fix components to the board prior to soldering:
303  // the priority is top then bottom
304  m_z_order = 4; // for top
305 
306  if( GetBrdLayerId().IsSameAs( wxT( "Bot" ), false ) )
307  m_z_order = -m_z_order;
308  }
309 }
310 
const wxString & GetFileType()
the type of layer (Copper, Soldermask ... )
class X2_ATTRIBUTE The attribute value consists of a number of substrings separated by a comma
static wxString FROM_UTF8(const char *cstring)
function FROM_UTF8 converts a UTF8 encoded C string to a wxString for all wxWidgets build modes.
Definition: macros.h:62
const wxString & GetPrm(int aIdx)
bool IsCopper()
return true if the filefunction type is "Copper"
This file contains miscellaneous commonly used macros and functions.
wxArrayString & GetPrms()
void set_Z_Order()
Initialize the z order priority of the current file, from its attributes.
X2_ATTRIBUTE_FILEFUNCTION(X2_ATTRIBUTE &aAttributeBase)
const wxString & GetLabel()
the filefunction label, if any
const wxString & GetBrdLayerId()
the brd layer identifier: Ln, only for Copper type or Top, Bot for other types
static LIB_PART * dummy()
Used to draw a dummy shape when a LIB_PART is not found in library.
const wxString & GetBrdLayerSide()
the brd layer Pos: Top, Bot, Inr same as GetBrdLayerId() for non copper type
bool ParseAttribCmd(FILE *aFile, char *aBuffer, int aBuffSize, char *&aText, int &aLineNum)
parse a TF command terminated with a % and fill m_Prms by the parameters found.
void DbgListPrms()
Debug function: pring using wxLogMessage le list of parameters.
const wxString & GetAttribute()
wxArrayString m_Prms
the list of parameters (after TF) in gbr file the first one is the attribute name,...