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.

238 lines
7.5 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2009 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
  5. * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
  6. * Copyright (C) 2018 CERN
  7. * Author: Maciej Suminski <maciej.suminski@cern.ch>
  8. * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
  9. *
  10. * This program is free software; you can redistribute it and/or
  11. * modify it under the terms of the GNU General Public License
  12. * as published by the Free Software Foundation; either version 2
  13. * of the License, or (at your option) any later version.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with this program; if not, you may find one here:
  22. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  23. * or you may search the http://www.gnu.org website for the version 2 license,
  24. * or you may write to the Free Software Foundation, Inc.,
  25. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  26. */
  27. #include "pcbnew_printout.h"
  28. #include <class_board.h>
  29. #include <pcb_painter.h>
  30. #include <view/view.h>
  31. #include <pcbplot.h>
  32. PCBNEW_PRINTOUT_SETTINGS::PCBNEW_PRINTOUT_SETTINGS( const PAGE_INFO& aPageInfo )
  33. : BOARD_PRINTOUT_SETTINGS( aPageInfo )
  34. {
  35. m_drillMarks = SMALL_DRILL_SHAPE;
  36. m_pagination = ALL_LAYERS;
  37. m_noEdgeLayer = false;
  38. }
  39. void PCBNEW_PRINTOUT_SETTINGS::Load( wxConfigBase* aConfig )
  40. {
  41. BOARD_PRINTOUT_SETTINGS::Load( aConfig );
  42. aConfig->Read( OPTKEY_PRINT_PADS_DRILL, (int*) &m_drillMarks, FULL_DRILL_SHAPE );
  43. aConfig->Read( OPTKEY_PRINT_PAGE_PER_LAYER, (int*) &m_pagination, ALL_LAYERS );
  44. }
  45. void PCBNEW_PRINTOUT_SETTINGS::Save( wxConfigBase* aConfig )
  46. {
  47. BOARD_PRINTOUT_SETTINGS::Save( aConfig );
  48. aConfig->Write( OPTKEY_PRINT_PADS_DRILL, (int) m_drillMarks );
  49. aConfig->Write( OPTKEY_PRINT_PAGE_PER_LAYER, (int) m_pagination );
  50. }
  51. PCBNEW_PRINTOUT::PCBNEW_PRINTOUT( BOARD* aBoard, const PCBNEW_PRINTOUT_SETTINGS& aParams,
  52. const KIGFX::VIEW* aView, const wxString& aTitle ) :
  53. BOARD_PRINTOUT( aParams, aView, aTitle ), m_pcbnewSettings( aParams )
  54. {
  55. m_board = aBoard;
  56. }
  57. bool PCBNEW_PRINTOUT::OnPrintPage( int aPage )
  58. {
  59. // Store the layerset, as it is going to be modified below and the original settings are needed
  60. LSET lset = m_settings.m_layerSet;
  61. int pageCount = lset.count();
  62. wxString layer;
  63. PCB_LAYER_ID extractLayer;
  64. // compute layer mask from page number if we want one page per layer
  65. if( m_pcbnewSettings.m_pagination == 0 ) // One page per layer
  66. {
  67. // This sequence is TBD, call a different
  68. // sequencer if needed, such as Seq(). Could not find documentation on
  69. // page order.
  70. LSEQ seq = lset.UIOrder();
  71. // aPage starts at 1, not 0
  72. if( unsigned( aPage - 1 ) < seq.size() )
  73. m_settings.m_layerSet = LSET( seq[aPage - 1] );
  74. }
  75. if( !m_settings.m_layerSet.any() )
  76. return false;
  77. extractLayer = m_settings.m_layerSet.ExtractLayer();
  78. if( extractLayer == UNDEFINED_LAYER )
  79. layer = _( "Multiple Layers" );
  80. else
  81. layer = LSET::Name( extractLayer );
  82. // In Pcbnew we can want the layer EDGE always printed
  83. if( !m_pcbnewSettings.m_noEdgeLayer )
  84. m_settings.m_layerSet.set( Edge_Cuts );
  85. DrawPage( layer, aPage, pageCount );
  86. // Restore the original layer set, so the next page can be printed
  87. m_settings.m_layerSet = lset;
  88. return true;
  89. }
  90. int PCBNEW_PRINTOUT::milsToIU( double aMils ) const
  91. {
  92. return KiROUND( IU_PER_MILS * aMils );
  93. }
  94. void PCBNEW_PRINTOUT::setupViewLayers( const std::unique_ptr<KIGFX::VIEW>& aView,
  95. const LSET& aLayerSet )
  96. {
  97. BOARD_PRINTOUT::setupViewLayers( aView, aLayerSet );
  98. for( LSEQ layerSeq = m_settings.m_layerSet.Seq(); layerSeq; ++layerSeq )
  99. aView->SetLayerVisible( PCBNEW_LAYER_ID_START + *layerSeq, true );
  100. // Enable pad layers corresponding to the selected copper layers
  101. if( aLayerSet.test( F_Cu ) )
  102. aView->SetLayerVisible( LAYER_PAD_FR, true );
  103. if( aLayerSet.test( B_Cu ) )
  104. aView->SetLayerVisible( LAYER_PAD_BK, true );
  105. if( ( aLayerSet & LSET::AllCuMask() ).any() ) // Items visible on any copper layer
  106. {
  107. // Enable items on copper layers, but do not draw holes
  108. for( auto item : { LAYER_PADS_TH, LAYER_VIA_MICROVIA,
  109. LAYER_VIA_BBLIND, LAYER_VIA_THROUGH } )
  110. {
  111. aView->SetLayerVisible( item, true );
  112. }
  113. if( m_pcbnewSettings.m_drillMarks != PCBNEW_PRINTOUT_SETTINGS::NO_DRILL_SHAPE )
  114. {
  115. // Enable hole layers to draw drill marks
  116. for( auto holeLayer : { LAYER_PADS_PLATEDHOLES,
  117. LAYER_NON_PLATEDHOLES, LAYER_VIAS_HOLES })
  118. {
  119. aView->SetLayerVisible( holeLayer, true );
  120. aView->SetTopLayer( holeLayer, true );
  121. }
  122. }
  123. }
  124. // Keep certain items always enabled/disabled and just rely on the layer visibility
  125. const int alwaysEnabled[] = {
  126. LAYER_MOD_TEXT_FR, LAYER_MOD_TEXT_BK, LAYER_MOD_FR, LAYER_MOD_BK,
  127. LAYER_MOD_VALUES, LAYER_MOD_REFERENCES, LAYER_TRACKS
  128. };
  129. for( int item : alwaysEnabled )
  130. aView->SetLayerVisible( item, true );
  131. }
  132. void PCBNEW_PRINTOUT::setupPainter( const std::unique_ptr<KIGFX::PAINTER>& aPainter )
  133. {
  134. BOARD_PRINTOUT::setupPainter( aPainter );
  135. auto painter = static_cast<KIGFX::PCB_PRINT_PAINTER*>( aPainter.get() );
  136. switch( m_pcbnewSettings.m_drillMarks )
  137. {
  138. case PCBNEW_PRINTOUT_SETTINGS::NO_DRILL_SHAPE:
  139. painter->SetDrillMarks( false, 0 );
  140. break;
  141. case PCBNEW_PRINTOUT_SETTINGS::SMALL_DRILL_SHAPE:
  142. painter->SetDrillMarks( false, Millimeter2iu( 0.3 ) );
  143. break;
  144. case PCBNEW_PRINTOUT_SETTINGS::FULL_DRILL_SHAPE:
  145. painter->SetDrillMarks( true );
  146. break;
  147. }
  148. painter->GetSettings()->SetLayerColor( LAYER_PADS_PLATEDHOLES, COLOR4D::WHITE );
  149. painter->GetSettings()->SetLayerColor( LAYER_NON_PLATEDHOLES, COLOR4D::WHITE );
  150. painter->GetSettings()->SetLayerColor( LAYER_VIAS_HOLES, COLOR4D::WHITE );
  151. }
  152. void PCBNEW_PRINTOUT::setupGal( KIGFX::GAL* aGal )
  153. {
  154. BOARD_PRINTOUT::setupGal( aGal );
  155. aGal->SetWorldUnitLength( 1e-9 /* 1 nm */ / 0.0254 /* 1 inch in meters */ );
  156. }
  157. EDA_RECT PCBNEW_PRINTOUT::getBoundingBox()
  158. {
  159. return m_board->ComputeBoundingBox();
  160. }
  161. std::unique_ptr<KIGFX::PAINTER> PCBNEW_PRINTOUT::getPainter( KIGFX::GAL* aGal )
  162. {
  163. return std::unique_ptr<KIGFX::PAINTER>( new KIGFX::PCB_PRINT_PAINTER( aGal ) );
  164. }
  165. KIGFX::PCB_PRINT_PAINTER::PCB_PRINT_PAINTER( GAL* aGal )
  166. : PCB_PAINTER( aGal ), m_drillMarkReal( false ), m_drillMarkSize( 0 )
  167. {
  168. m_pcbSettings.EnableZoneOutlines( false );
  169. }
  170. int KIGFX::PCB_PRINT_PAINTER::getDrillShape( const D_PAD* aPad ) const
  171. {
  172. return m_drillMarkReal ? KIGFX::PCB_PAINTER::getDrillShape( aPad ) : PAD_DRILL_SHAPE_CIRCLE;
  173. }
  174. VECTOR2D KIGFX::PCB_PRINT_PAINTER::getDrillSize( const D_PAD* aPad ) const
  175. {
  176. // TODO should it depend on the pad size?
  177. return m_drillMarkReal ? KIGFX::PCB_PAINTER::getDrillSize( aPad ) :
  178. VECTOR2D( m_drillMarkSize, m_drillMarkSize );
  179. }
  180. int KIGFX::PCB_PRINT_PAINTER::getDrillSize( const VIA* aVia ) const
  181. {
  182. // TODO should it depend on the via size?
  183. return m_drillMarkReal ? KIGFX::PCB_PAINTER::getDrillSize( aVia ) : m_drillMarkSize;
  184. }