You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

309 lines
8.8 KiB

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