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.

742 lines
23 KiB

12 years ago
  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation; either version 2
  9. * of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, you may find one here:
  18. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  19. * or you may search the http://www.gnu.org website for the version 2 license,
  20. * or you may write to the Free Software Foundation, Inc.,
  21. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  22. */
  23. #include <board_design_settings.h>
  24. #include <charconv>
  25. #include <layer_ids.h>
  26. #include <lset.h>
  27. #include <string_utils.h>
  28. #include <math/util.h> // for KiROUND
  29. #include <pcb_plot_params.h>
  30. #include <pcb_plot_params_parser.h>
  31. #include <plotters/plotter.h>
  32. #include <io/kicad/kicad_io_utils.h>
  33. #include <settings/color_settings.h>
  34. #define PLOT_LINEWIDTH_DEFAULT ( DEFAULT_TEXT_WIDTH * IU_PER_MM )
  35. #define HPGL_PEN_DIAMETER_MIN 0
  36. #define HPGL_PEN_DIAMETER_MAX 100.0 // Unit = mil
  37. #define HPGL_PEN_SPEED_MIN 1 // this param is always in cm/s
  38. #define HPGL_PEN_SPEED_MAX 99 // this param is always in cm/s
  39. #define HPGL_PEN_NUMBER_MIN 1
  40. #define HPGL_PEN_NUMBER_MAX 16
  41. #define SVG_PRECISION_MIN 3U
  42. #define SVG_PRECISION_MAX 6U
  43. #define SVG_PRECISION_DEFAULT 4
  44. // default trailing digits in Gerber coordinates, when units are mm
  45. // This is also the max usable precision (i.e. internal Pcbnew Units)
  46. static const int gbrDefaultPrecision = 6;
  47. using namespace PCBPLOTPARAMS_T;
  48. static const char* getTokenName( T aTok )
  49. {
  50. return PCB_PLOT_PARAMS_LEXER::TokenName( aTok );
  51. }
  52. static bool setInt( int* aTarget, int aValue, int aMin, int aMax )
  53. {
  54. int temp = aValue;
  55. if( aValue < aMin )
  56. temp = aMin;
  57. else if( aValue > aMax )
  58. temp = aMax;
  59. *aTarget = temp;
  60. return ( temp == aValue );
  61. }
  62. static bool setDouble( double* aTarget, double aValue, double aMin, double aMax )
  63. {
  64. double temp = aValue;
  65. if( aValue < aMin )
  66. temp = aMin;
  67. else if( aValue > aMax )
  68. temp = aMax;
  69. *aTarget = temp;
  70. return ( temp == aValue );
  71. }
  72. PCB_PLOT_PARAMS::PCB_PLOT_PARAMS()
  73. {
  74. m_useGerberProtelExtensions = false;
  75. m_gerberDisableApertMacros = false;
  76. m_useGerberX2format = true;
  77. m_includeGerberNetlistInfo = true;
  78. m_createGerberJobFile = true;
  79. m_gerberPrecision = gbrDefaultPrecision;
  80. m_dashedLineDashRatio = 12.0; // From ISO 128-2
  81. m_dashedLineGapRatio = 3.0; // From ISO 128-2
  82. // we used 0.1mils for SVG step before, but nm precision is more accurate, so we use nm
  83. m_svgPrecision = SVG_PRECISION_DEFAULT;
  84. m_plotDrawingSheet = false;
  85. m_plotMode = FILLED;
  86. m_DXFPolygonMode = true;
  87. m_DXFUnits = DXF_UNITS::INCHES;
  88. m_useAuxOrigin = false;
  89. m_HPGLPenNum = 1;
  90. m_HPGLPenSpeed = 20; // this param is always in cm/s
  91. m_HPGLPenDiam = 15; // in mils
  92. m_negative = false;
  93. m_A4Output = false;
  94. m_plotReference = true;
  95. m_plotValue = true;
  96. m_plotFPText = true;
  97. m_plotInvisibleText = false;
  98. m_sketchPadsOnFabLayers = false;
  99. m_plotPadNumbers = false;
  100. m_subtractMaskFromSilk = false;
  101. m_format = PLOT_FORMAT::GERBER;
  102. m_mirror = false;
  103. m_drillMarks = DRILL_MARKS::SMALL_DRILL_SHAPE;
  104. m_autoScale = false;
  105. m_scale = 1.0;
  106. m_scaleSelection = 1;
  107. m_fineScaleAdjustX = 1.0;
  108. m_fineScaleAdjustY = 1.0;
  109. m_widthAdjust = 0.;
  110. m_textMode = PLOT_TEXT_MODE::DEFAULT;
  111. m_outputDirectory.clear();
  112. m_layerSelection = LSET( { F_SilkS, B_SilkS, F_Mask, B_Mask,
  113. F_Paste, B_Paste, Edge_Cuts } )
  114. | LSET::AllCuMask();
  115. m_PDFFrontFPPropertyPopups = true;
  116. m_PDFBackFPPropertyPopups = true;
  117. m_PDFMetadata = true;
  118. // This parameter controls if the NPTH pads will be plotted or not
  119. // it is a "local" parameter
  120. m_skipNPTH_Pads = false;
  121. // line width to plot items in outline mode.
  122. m_sketchPadLineWidth = pcbIUScale.mmToIU( 0.1 );
  123. m_default_colors = std::make_shared<COLOR_SETTINGS>();
  124. m_colors = m_default_colors.get();
  125. m_blackAndWhite = true;
  126. }
  127. void PCB_PLOT_PARAMS::SetGerberPrecision( int aPrecision )
  128. {
  129. // Currently Gerber files use mm.
  130. // accepted precision is only 6 (max value, this is the resolution of Pcbnew)
  131. // or 5, min value for professional boards, when 6 creates problems
  132. // to board makers.
  133. m_gerberPrecision = aPrecision == gbrDefaultPrecision-1 ? gbrDefaultPrecision-1 :
  134. gbrDefaultPrecision;
  135. }
  136. void PCB_PLOT_PARAMS::SetSvgPrecision( unsigned aPrecision )
  137. {
  138. m_svgPrecision = Clamp( SVG_PRECISION_MIN, aPrecision, SVG_PRECISION_MAX );
  139. }
  140. void PCB_PLOT_PARAMS::Format( OUTPUTFORMATTER* aFormatter,
  141. int aNestLevel, int aControl ) const
  142. {
  143. aFormatter->Print( aNestLevel, "(pcbplotparams\n" );
  144. aFormatter->Print( aNestLevel+1, "(layerselection 0x%s)\n",
  145. m_layerSelection.FmtHex().c_str() );
  146. aFormatter->Print( aNestLevel+1, "(plot_on_all_layers_selection 0x%s)\n",
  147. m_plotOnAllLayersSelection.FmtHex().c_str() );
  148. KICAD_FORMAT::FormatBool( aFormatter, aNestLevel + 1, "disableapertmacros",
  149. m_gerberDisableApertMacros );
  150. KICAD_FORMAT::FormatBool( aFormatter, aNestLevel + 1, "usegerberextensions",
  151. m_useGerberProtelExtensions );
  152. KICAD_FORMAT::FormatBool( aFormatter, aNestLevel + 1, "usegerberattributes",
  153. GetUseGerberX2format() );
  154. KICAD_FORMAT::FormatBool( aFormatter, aNestLevel + 1, "usegerberadvancedattributes",
  155. GetIncludeGerberNetlistInfo() );
  156. KICAD_FORMAT::FormatBool( aFormatter, aNestLevel + 1, "creategerberjobfile",
  157. GetCreateGerberJobFile() );
  158. // save this option only if it is not the default value,
  159. // to avoid incompatibility with older Pcbnew version
  160. if( m_gerberPrecision != gbrDefaultPrecision )
  161. aFormatter->Print( aNestLevel+1, "(gerberprecision %d)\n", m_gerberPrecision );
  162. aFormatter->Print( aNestLevel+1, "(dashed_line_dash_ratio %f)\n", GetDashedLineDashRatio() );
  163. aFormatter->Print( aNestLevel+1, "(dashed_line_gap_ratio %f)\n", GetDashedLineGapRatio() );
  164. // SVG options
  165. aFormatter->Print( aNestLevel+1, "(svgprecision %d)\n", m_svgPrecision );
  166. KICAD_FORMAT::FormatBool( aFormatter, aNestLevel + 1, "plotframeref", m_plotDrawingSheet );
  167. aFormatter->Print( aNestLevel+1, "(mode %d)\n", GetPlotMode() == SKETCH ? 2 : 1 );
  168. KICAD_FORMAT::FormatBool( aFormatter, aNestLevel + 1, "useauxorigin", m_useAuxOrigin );
  169. // HPGL options
  170. aFormatter->Print( aNestLevel+1, "(hpglpennumber %d)\n", m_HPGLPenNum );
  171. aFormatter->Print( aNestLevel+1, "(hpglpenspeed %d)\n", m_HPGLPenSpeed );
  172. aFormatter->Print( aNestLevel+1, "(hpglpendiameter %f)\n", m_HPGLPenDiam );
  173. // PDF options
  174. KICAD_FORMAT::FormatBool( aFormatter, aNestLevel + 1,
  175. getTokenName( T_pdf_front_fp_property_popups ),
  176. m_PDFFrontFPPropertyPopups );
  177. KICAD_FORMAT::FormatBool( aFormatter, aNestLevel + 1,
  178. getTokenName( T_pdf_back_fp_property_popups ),
  179. m_PDFBackFPPropertyPopups );
  180. KICAD_FORMAT::FormatBool( aFormatter, aNestLevel + 1,
  181. getTokenName( T_pdf_metadata ),
  182. m_PDFMetadata );
  183. // DXF options
  184. KICAD_FORMAT::FormatBool( aFormatter, aNestLevel + 1, getTokenName( T_dxfpolygonmode ),
  185. m_DXFPolygonMode );
  186. KICAD_FORMAT::FormatBool( aFormatter, aNestLevel + 1, getTokenName( T_dxfimperialunits ),
  187. m_DXFUnits == DXF_UNITS::INCHES );
  188. KICAD_FORMAT::FormatBool( aFormatter, aNestLevel + 1, getTokenName( T_dxfusepcbnewfont ),
  189. m_textMode != PLOT_TEXT_MODE::NATIVE );
  190. KICAD_FORMAT::FormatBool( aFormatter, aNestLevel + 1, getTokenName( T_psnegative ),
  191. m_negative );
  192. KICAD_FORMAT::FormatBool( aFormatter, aNestLevel + 1, getTokenName( T_psa4output ),
  193. m_A4Output );
  194. KICAD_FORMAT::FormatBool( aFormatter, aNestLevel + 1, "plotreference", m_plotReference );
  195. KICAD_FORMAT::FormatBool( aFormatter, aNestLevel + 1, "plotvalue", m_plotValue );
  196. KICAD_FORMAT::FormatBool( aFormatter, aNestLevel + 1, "plotfptext", m_plotFPText );
  197. KICAD_FORMAT::FormatBool( aFormatter, aNestLevel + 1, "plotinvisibletext", m_plotInvisibleText );
  198. KICAD_FORMAT::FormatBool( aFormatter, aNestLevel + 1, "sketchpadsonfab", m_sketchPadsOnFabLayers );
  199. KICAD_FORMAT::FormatBool( aFormatter, aNestLevel + 1, "plotpadnumbers", m_plotPadNumbers );
  200. KICAD_FORMAT::FormatBool( aFormatter, aNestLevel + 1, "subtractmaskfromsilk", m_subtractMaskFromSilk );
  201. aFormatter->Print( aNestLevel+1, "(outputformat %d)\n", static_cast<int>( m_format ) );
  202. KICAD_FORMAT::FormatBool( aFormatter, aNestLevel + 1, "mirror", m_mirror );
  203. aFormatter->Print( aNestLevel+1, "(drillshape %d)\n", (int)m_drillMarks );
  204. aFormatter->Print( aNestLevel+1, "(scaleselection %d)\n", m_scaleSelection );
  205. aFormatter->Print( aNestLevel+1, "(outputdirectory \"%s\")",
  206. (const char*) m_outputDirectory.utf8_str() );
  207. aFormatter->Print( 0, "\n" );
  208. aFormatter->Print( aNestLevel, ")\n" );
  209. }
  210. void PCB_PLOT_PARAMS::Parse( PCB_PLOT_PARAMS_PARSER* aParser )
  211. {
  212. aParser->Parse( this );
  213. }
  214. bool PCB_PLOT_PARAMS::IsSameAs( const PCB_PLOT_PARAMS &aPcbPlotParams ) const
  215. {
  216. if( m_layerSelection != aPcbPlotParams.m_layerSelection )
  217. return false;
  218. if( m_plotOnAllLayersSelection != aPcbPlotParams.m_plotOnAllLayersSelection )
  219. return false;
  220. if( m_useGerberProtelExtensions != aPcbPlotParams.m_useGerberProtelExtensions )
  221. return false;
  222. if( m_gerberDisableApertMacros != aPcbPlotParams.m_gerberDisableApertMacros )
  223. return false;
  224. if( m_useGerberX2format != aPcbPlotParams.m_useGerberX2format )
  225. return false;
  226. if( m_includeGerberNetlistInfo != aPcbPlotParams.m_includeGerberNetlistInfo )
  227. return false;
  228. if( m_createGerberJobFile != aPcbPlotParams.m_createGerberJobFile )
  229. return false;
  230. if( m_gerberPrecision != aPcbPlotParams.m_gerberPrecision )
  231. return false;
  232. if( m_dashedLineDashRatio != aPcbPlotParams.m_dashedLineDashRatio )
  233. return false;
  234. if( m_dashedLineGapRatio != aPcbPlotParams.m_dashedLineGapRatio )
  235. return false;
  236. if( m_plotDrawingSheet != aPcbPlotParams.m_plotDrawingSheet )
  237. return false;
  238. if( m_plotMode != aPcbPlotParams.m_plotMode )
  239. return false;
  240. if( m_DXFPolygonMode != aPcbPlotParams.m_DXFPolygonMode )
  241. return false;
  242. if( m_DXFUnits != aPcbPlotParams.m_DXFUnits )
  243. return false;
  244. if( m_svgPrecision != aPcbPlotParams.m_svgPrecision )
  245. return false;
  246. if( m_useAuxOrigin != aPcbPlotParams.m_useAuxOrigin )
  247. return false;
  248. if( m_HPGLPenNum != aPcbPlotParams.m_HPGLPenNum )
  249. return false;
  250. if( m_HPGLPenSpeed != aPcbPlotParams.m_HPGLPenSpeed )
  251. return false;
  252. if( m_HPGLPenDiam != aPcbPlotParams.m_HPGLPenDiam )
  253. return false;
  254. if( m_negative != aPcbPlotParams.m_negative )
  255. return false;
  256. if( m_PDFFrontFPPropertyPopups != aPcbPlotParams.m_PDFFrontFPPropertyPopups )
  257. return false;
  258. if( m_PDFBackFPPropertyPopups != aPcbPlotParams.m_PDFBackFPPropertyPopups )
  259. return false;
  260. if( m_PDFMetadata != aPcbPlotParams.m_PDFMetadata )
  261. return false;
  262. if( m_A4Output != aPcbPlotParams.m_A4Output )
  263. return false;
  264. if( m_plotReference != aPcbPlotParams.m_plotReference )
  265. return false;
  266. if( m_plotValue != aPcbPlotParams.m_plotValue )
  267. return false;
  268. if( m_plotFPText != aPcbPlotParams.m_plotFPText )
  269. return false;
  270. if( m_plotInvisibleText != aPcbPlotParams.m_plotInvisibleText )
  271. return false;
  272. if( m_sketchPadsOnFabLayers != aPcbPlotParams.m_sketchPadsOnFabLayers )
  273. return false;
  274. if( m_plotPadNumbers != aPcbPlotParams.m_plotPadNumbers )
  275. return false;
  276. if( m_subtractMaskFromSilk != aPcbPlotParams.m_subtractMaskFromSilk )
  277. return false;
  278. if( m_format != aPcbPlotParams.m_format )
  279. return false;
  280. if( m_mirror != aPcbPlotParams.m_mirror )
  281. return false;
  282. if( m_drillMarks != aPcbPlotParams.m_drillMarks )
  283. return false;
  284. if( m_scaleSelection != aPcbPlotParams.m_scaleSelection )
  285. return false;
  286. if( m_autoScale != aPcbPlotParams.m_autoScale )
  287. return false;
  288. if( m_scale != aPcbPlotParams.m_scale )
  289. return false;
  290. if( m_fineScaleAdjustX != aPcbPlotParams.m_fineScaleAdjustX )
  291. return false;
  292. if( m_fineScaleAdjustY != aPcbPlotParams.m_fineScaleAdjustY )
  293. return false;
  294. if( m_widthAdjust != aPcbPlotParams.m_widthAdjust )
  295. return false;
  296. if( m_textMode != aPcbPlotParams.m_textMode )
  297. return false;
  298. if( m_blackAndWhite != aPcbPlotParams.m_blackAndWhite )
  299. return false;
  300. if( !m_outputDirectory.IsSameAs( aPcbPlotParams.m_outputDirectory ) )
  301. return false;
  302. return true;
  303. }
  304. bool PCB_PLOT_PARAMS::SetHPGLPenDiameter( double aValue )
  305. {
  306. return setDouble( &m_HPGLPenDiam, aValue, HPGL_PEN_DIAMETER_MIN, HPGL_PEN_DIAMETER_MAX );
  307. }
  308. bool PCB_PLOT_PARAMS::SetHPGLPenSpeed( int aValue )
  309. {
  310. return setInt( &m_HPGLPenSpeed, aValue, HPGL_PEN_SPEED_MIN, HPGL_PEN_SPEED_MAX );
  311. }
  312. PCB_PLOT_PARAMS_PARSER::PCB_PLOT_PARAMS_PARSER( LINE_READER* aReader ) :
  313. PCB_PLOT_PARAMS_LEXER( aReader )
  314. {
  315. }
  316. PCB_PLOT_PARAMS_PARSER::PCB_PLOT_PARAMS_PARSER( char* aLine, const wxString& aSource ) :
  317. PCB_PLOT_PARAMS_LEXER( aLine, aSource )
  318. {
  319. }
  320. void PCB_PLOT_PARAMS_PARSER::Parse( PCB_PLOT_PARAMS* aPcbPlotParams )
  321. {
  322. T token;
  323. while( ( token = NextTok() ) != T_RIGHT )
  324. {
  325. if( token == T_EOF)
  326. Unexpected( T_EOF );
  327. if( token == T_LEFT )
  328. token = NextTok();
  329. if( token == T_pcbplotparams )
  330. continue;
  331. bool skip_right = false;
  332. switch( token )
  333. {
  334. case T_layerselection:
  335. {
  336. token = NeedSYMBOLorNUMBER();
  337. const std::string& cur = CurStr();
  338. if( token == T_NUMBER ) // pretty 3 format had legacy Cu stack.
  339. {
  340. // It's not possible to convert a legacy Cu layer number to a new Cu layer
  341. // number without knowing the number or total Cu layers in the legacy board.
  342. // We do not have that information here, so simply set all layers ON. User
  343. // can turn them off in the UI.
  344. aPcbPlotParams->m_layerSelection = LSET( { F_SilkS, B_SilkS } ) | LSET::AllCuMask();
  345. }
  346. else if( cur.find_first_of( "0x" ) == 0 ) // pretty ver. 4.
  347. {
  348. // skip the leading 2 0x bytes.
  349. aPcbPlotParams->m_layerSelection.ParseHex( cur.c_str() + 2, cur.size() - 2 );
  350. }
  351. else
  352. {
  353. Expecting( "integer or hex layerSelection" );
  354. }
  355. break;
  356. }
  357. case T_plot_on_all_layers_selection:
  358. {
  359. token = NeedSYMBOLorNUMBER();
  360. const std::string& cur = CurStr();
  361. if( cur.find_first_of( "0x" ) == 0 )
  362. {
  363. // skip the leading 2 0x bytes.
  364. aPcbPlotParams->m_plotOnAllLayersSelection.ParseHex( cur.c_str() + 2,
  365. cur.size() - 2 );
  366. }
  367. else
  368. {
  369. Expecting( "hex plot_on_all_layers_selection" );
  370. }
  371. break;
  372. }
  373. case T_disableapertmacros:
  374. aPcbPlotParams->m_gerberDisableApertMacros = parseBool();
  375. break;
  376. case T_usegerberextensions:
  377. aPcbPlotParams->m_useGerberProtelExtensions = parseBool();
  378. break;
  379. case T_usegerberattributes:
  380. aPcbPlotParams->m_useGerberX2format = parseBool();
  381. break;
  382. case T_usegerberadvancedattributes:
  383. aPcbPlotParams->m_includeGerberNetlistInfo = parseBool();
  384. break;
  385. case T_creategerberjobfile:
  386. aPcbPlotParams->m_createGerberJobFile = parseBool();
  387. break;
  388. case T_gerberprecision:
  389. aPcbPlotParams->m_gerberPrecision = parseInt( gbrDefaultPrecision - 1,
  390. gbrDefaultPrecision);
  391. break;
  392. case T_dashed_line_dash_ratio:
  393. aPcbPlotParams->m_dashedLineDashRatio = parseDouble();
  394. break;
  395. case T_dashed_line_gap_ratio:
  396. aPcbPlotParams->m_dashedLineGapRatio = parseDouble();
  397. break;
  398. case T_svgprecision:
  399. aPcbPlotParams->m_svgPrecision = parseInt( SVG_PRECISION_MIN, SVG_PRECISION_MAX );
  400. break;
  401. case T_svguseinch:
  402. parseBool(); // Unused. For compatibility
  403. break;
  404. case T_psa4output:
  405. aPcbPlotParams->m_A4Output = parseBool();
  406. break;
  407. case T_excludeedgelayer:
  408. if( !parseBool() )
  409. aPcbPlotParams->m_plotOnAllLayersSelection.set( Edge_Cuts );
  410. break;
  411. case T_plotframeref:
  412. aPcbPlotParams->m_plotDrawingSheet = parseBool();
  413. break;
  414. case T_viasonmask:
  415. aPcbPlotParams->m_plotViaOnMaskLayer = parseBool();
  416. break;
  417. case T_mode:
  418. aPcbPlotParams->SetPlotMode( parseInt( 0, 2 ) > 1 ? SKETCH : FILLED );
  419. break;
  420. case T_useauxorigin:
  421. aPcbPlotParams->m_useAuxOrigin = parseBool();
  422. break;
  423. case T_hpglpennumber:
  424. aPcbPlotParams->m_HPGLPenNum = parseInt( HPGL_PEN_NUMBER_MIN, HPGL_PEN_NUMBER_MAX );
  425. break;
  426. case T_hpglpenspeed:
  427. aPcbPlotParams->m_HPGLPenSpeed = parseInt( HPGL_PEN_SPEED_MIN, HPGL_PEN_SPEED_MAX );
  428. break;
  429. case T_hpglpendiameter:
  430. aPcbPlotParams->m_HPGLPenDiam = parseDouble();
  431. break;
  432. case T_hpglpenoverlay:
  433. // No more used. just here for compatibility with old versions
  434. parseInt( 0, HPGL_PEN_DIAMETER_MAX );
  435. break;
  436. case T_pdf_front_fp_property_popups:
  437. aPcbPlotParams->m_PDFFrontFPPropertyPopups = parseBool();
  438. break;
  439. case T_pdf_back_fp_property_popups:
  440. aPcbPlotParams->m_PDFFrontFPPropertyPopups = parseBool();
  441. break;
  442. case T_pdf_metadata:
  443. aPcbPlotParams->m_PDFMetadata = parseBool();
  444. break;
  445. case T_dxfpolygonmode:
  446. aPcbPlotParams->m_DXFPolygonMode = parseBool();
  447. break;
  448. case T_dxfimperialunits:
  449. aPcbPlotParams->m_DXFUnits = parseBool() ? DXF_UNITS::INCHES
  450. : DXF_UNITS::MILLIMETERS;
  451. break;
  452. case T_dxfusepcbnewfont:
  453. aPcbPlotParams->m_textMode = parseBool() ? PLOT_TEXT_MODE::DEFAULT
  454. : PLOT_TEXT_MODE::NATIVE;
  455. break;
  456. case T_pscolor:
  457. NeedSYMBOL(); // This actually was never used...
  458. break;
  459. case T_psnegative:
  460. aPcbPlotParams->m_negative = parseBool();
  461. break;
  462. case T_plotreference:
  463. aPcbPlotParams->m_plotReference = parseBool();
  464. break;
  465. case T_plotfptext:
  466. aPcbPlotParams->m_plotFPText = parseBool();
  467. break;
  468. case T_plotvalue:
  469. aPcbPlotParams->m_plotValue = parseBool();
  470. break;
  471. case T_plotinvisibletext:
  472. aPcbPlotParams->m_plotInvisibleText = parseBool();
  473. break;
  474. case T_sketchpadsonfab:
  475. aPcbPlotParams->m_sketchPadsOnFabLayers= parseBool();
  476. break;
  477. case T_plotpadnumbers:
  478. aPcbPlotParams->m_plotPadNumbers = parseBool();
  479. break;
  480. case T_subtractmaskfromsilk:
  481. aPcbPlotParams->m_subtractMaskFromSilk = parseBool();
  482. break;
  483. case T_outputformat:
  484. aPcbPlotParams->m_format = static_cast<PLOT_FORMAT>(
  485. parseInt( static_cast<int>( PLOT_FORMAT::FIRST_FORMAT ),
  486. static_cast<int>( PLOT_FORMAT::LAST_FORMAT ) ) );
  487. break;
  488. case T_mirror:
  489. aPcbPlotParams->m_mirror = parseBool();
  490. break;
  491. case T_drillshape:
  492. aPcbPlotParams->m_drillMarks = static_cast<DRILL_MARKS> ( parseInt( 0, 2 ) );
  493. break;
  494. case T_scaleselection:
  495. aPcbPlotParams->m_scaleSelection = parseInt( 0, 4 );
  496. break;
  497. case T_outputdirectory:
  498. NeedSYMBOLorNUMBER(); // a dir name can be like a number
  499. aPcbPlotParams->m_outputDirectory = From_UTF8( CurText() );
  500. break;
  501. default:
  502. skipCurrent(); // skip unknown or outdated plot parameter
  503. skip_right = true; // the closing right token is already read.
  504. break;
  505. }
  506. if( ! skip_right )
  507. NeedRIGHT();
  508. }
  509. }
  510. bool PCB_PLOT_PARAMS_PARSER::parseBool()
  511. {
  512. T token = NeedSYMBOL();
  513. switch( token )
  514. {
  515. case T_false:
  516. case T_no:
  517. return false;
  518. case T_true:
  519. case T_yes:
  520. return true;
  521. default:
  522. Expecting( "true, false, yes, or no" );
  523. return false;
  524. }
  525. }
  526. int PCB_PLOT_PARAMS_PARSER::parseInt( int aMin, int aMax )
  527. {
  528. T token = NextTok();
  529. if( token != T_NUMBER )
  530. Expecting( T_NUMBER );
  531. int val = atoi( CurText() );
  532. if( val < aMin )
  533. val = aMin;
  534. else if( val > aMax )
  535. val = aMax;
  536. return val;
  537. }
  538. double PCB_PLOT_PARAMS_PARSER::parseDouble()
  539. {
  540. T token = NextTok();
  541. if( token != T_NUMBER )
  542. Expecting( T_NUMBER );
  543. return DSNLEXER::parseDouble();
  544. }
  545. void PCB_PLOT_PARAMS_PARSER::skipCurrent()
  546. {
  547. int curr_level = 0;
  548. T token;
  549. while( ( token = NextTok() ) != T_EOF )
  550. {
  551. if( token == T_LEFT )
  552. curr_level--;
  553. if( token == T_RIGHT )
  554. {
  555. curr_level++;
  556. if( curr_level > 0 )
  557. return;
  558. }
  559. }
  560. }