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.

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