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.

290 lines
7.3 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-2021 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. X2_ATTRIBUTE::X2_ATTRIBUTE()
  45. {
  46. }
  47. X2_ATTRIBUTE::~X2_ATTRIBUTE()
  48. {
  49. }
  50. const wxString& X2_ATTRIBUTE::GetAttribute()
  51. {
  52. return m_Prms.Item( 0 );
  53. }
  54. const wxString& X2_ATTRIBUTE::GetPrm( int aIdx )
  55. {
  56. static const wxString dummy;
  57. if( GetPrmCount() > aIdx && aIdx >= 0 )
  58. return m_Prms.Item( aIdx );
  59. return dummy;
  60. }
  61. void X2_ATTRIBUTE::DbgListPrms()
  62. {
  63. wxLogMessage( wxT( "prms count %d" ), GetPrmCount() );
  64. for( int ii = 0; ii < GetPrmCount(); ii++ )
  65. wxLogMessage( m_Prms.Item( ii ) );
  66. }
  67. bool X2_ATTRIBUTE::ParseAttribCmd( FILE* aFile, char *aBuffer, int aBuffSize, char* &aText,
  68. int& aLineNum )
  69. {
  70. // parse a TF, TA, TO ... command and fill m_Prms by the parameters found.
  71. // the "%TF" (start of command) is already read by the caller
  72. bool ok = true;
  73. std::string data;
  74. for( ; ; )
  75. {
  76. while( *aText )
  77. {
  78. switch( *aText )
  79. {
  80. case '%': // end of command
  81. return ok; // success completion
  82. case ' ':
  83. case '\r':
  84. case '\n':
  85. aText++;
  86. break;
  87. case '*': // End of block
  88. m_Prms.Add( FROM_UTF8( data.c_str() ) );
  89. data.clear();
  90. aText++;
  91. break;
  92. case ',': // End of parameter (separator)
  93. aText++;
  94. m_Prms.Add( FROM_UTF8( data.c_str() ) );
  95. data.clear();
  96. break;
  97. default:
  98. data += *aText;
  99. aText++;
  100. break;
  101. }
  102. }
  103. // end of current line, read another one.
  104. if( aBuffer && aFile )
  105. {
  106. if( fgets( aBuffer, aBuffSize, aFile ) == nullptr )
  107. {
  108. // end of file
  109. ok = false;
  110. break;
  111. }
  112. aLineNum++;
  113. aText = aBuffer;
  114. }
  115. else
  116. {
  117. return ok;
  118. }
  119. }
  120. return ok;
  121. }
  122. X2_ATTRIBUTE_FILEFUNCTION::X2_ATTRIBUTE_FILEFUNCTION( X2_ATTRIBUTE& aAttributeBase )
  123. : X2_ATTRIBUTE()
  124. {
  125. m_Prms = aAttributeBase.GetPrms();
  126. m_z_order = 0;
  127. // ensure at least 7 parameters exist.
  128. while( GetPrmCount() < 7 )
  129. m_Prms.Add( wxEmptyString );
  130. set_Z_Order();
  131. }
  132. const wxString& X2_ATTRIBUTE_FILEFUNCTION::GetFileType()
  133. {
  134. // the type of layer (Copper, Soldermask ... )
  135. return m_Prms.Item( 1 );
  136. }
  137. const wxString& X2_ATTRIBUTE_FILEFUNCTION::GetBrdLayerId()
  138. {
  139. // the brd layer identifier: Ln (for Copper type) or Top, Bot
  140. return m_Prms.Item( 2 );
  141. }
  142. const wxString X2_ATTRIBUTE_FILEFUNCTION::GetDrillLayerPair()
  143. {
  144. // the layer pair identifiers, for drill files, i.e.
  145. // with m_Prms.Item( 1 ) = "Plated" or "NonPlated"
  146. wxString lpair = m_Prms.Item( 2 ) + ',' + m_Prms.Item( 3 );
  147. return lpair;
  148. }
  149. const wxString& X2_ATTRIBUTE_FILEFUNCTION::GetBrdLayerSide()
  150. {
  151. if( IsCopper() )
  152. // the brd layer identifier: Top, Bot, Inr
  153. return m_Prms.Item( 3 );
  154. else
  155. // the brd layer identifier: Top, Bot ( same as GetBrdLayerId() )
  156. return m_Prms.Item( 2 );
  157. }
  158. const wxString& X2_ATTRIBUTE_FILEFUNCTION::GetLabel()
  159. {
  160. if( IsCopper() )
  161. return m_Prms.Item( 4 );
  162. else
  163. return m_Prms.Item( 3 );
  164. }
  165. const wxString& X2_ATTRIBUTE_FILEFUNCTION::GetLPType()
  166. {
  167. // Only for drill files: the Layer Pair type (PTH, NPTH, Blind or Buried)
  168. return m_Prms.Item( 4 );
  169. }
  170. const wxString& X2_ATTRIBUTE_FILEFUNCTION::GetRouteType()
  171. {
  172. // Only for drill files: the drill/routing type(Drill, Route, Mixed)
  173. return m_Prms.Item( 5 );
  174. }
  175. bool X2_ATTRIBUTE_FILEFUNCTION::IsCopper()
  176. {
  177. // the filefunction label, if any
  178. return GetFileType().IsSameAs( wxT( "Copper" ), false );
  179. }
  180. bool X2_ATTRIBUTE_FILEFUNCTION::IsDrillFile()
  181. {
  182. // the filefunction label, if any
  183. return GetFileType().IsSameAs( wxT( "Plated" ), false )
  184. || GetFileType().IsSameAs( wxT( "NonPlated" ), false );
  185. }
  186. void X2_ATTRIBUTE_FILEFUNCTION::set_Z_Order()
  187. {
  188. m_z_order = -100; // low level
  189. m_z_sub_order = 0;
  190. if( IsCopper() )
  191. {
  192. // Copper layer: the priority is the layer Id
  193. m_z_order = 0;
  194. wxString num = GetBrdLayerId().Mid( 1 );
  195. long lnum;
  196. if( num.ToLong( &lnum ) )
  197. m_z_sub_order = -lnum;
  198. }
  199. if( GetFileType().IsSameAs( wxT( "Paste" ), false ) )
  200. {
  201. // solder paste layer: the priority is top then bottom
  202. m_z_order = 1; // for top
  203. if( GetBrdLayerId().IsSameAs( wxT( "Bot" ), false ) )
  204. m_z_order = -m_z_order;
  205. }
  206. if( GetFileType().IsSameAs( wxT( "Soldermask" ), false ) )
  207. {
  208. // solder mask layer: the priority is top then bottom
  209. m_z_order = 2; // for top
  210. if( GetBrdLayerId().IsSameAs( wxT( "Bot" ), false ) )
  211. m_z_order = -m_z_order;
  212. }
  213. if( GetFileType().IsSameAs( wxT( "Legend" ), false ) )
  214. {
  215. // Silk screen layer: the priority is top then bottom
  216. m_z_order = 3; // for top
  217. if( GetBrdLayerId().IsSameAs( wxT( "Bot" ), false ) )
  218. m_z_order = -m_z_order;
  219. }
  220. if( GetFileType().IsSameAs( wxT( "Glue" ), false ) )
  221. {
  222. // Glue spots used to fix components to the board prior to soldering:
  223. // the priority is top then bottom
  224. m_z_order = 4; // for top
  225. if( GetBrdLayerId().IsSameAs( wxT( "Bot" ), false ) )
  226. m_z_order = -m_z_order;
  227. }
  228. }