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.

204 lines
6.2 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. *
  9. * This program is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU General Public License
  11. * as published by the Free Software Foundation; either version 2
  12. * of the License, or (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program; if not, you may find one here:
  21. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  22. * or you may search the http://www.gnu.org website for the version 2 license,
  23. * or you may write to the Free Software Foundation, Inc.,
  24. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  25. */
  26. #include <board_printout.h>
  27. #include <view/view.h>
  28. #include <gal/gal_print.h>
  29. #include <painter.h>
  30. #include <pcbplot.h>
  31. #include <settings/app_settings.h>
  32. BOARD_PRINTOUT_SETTINGS::BOARD_PRINTOUT_SETTINGS( const PAGE_INFO& aPageInfo )
  33. : PRINTOUT_SETTINGS( aPageInfo )
  34. {
  35. m_layerSet.set();
  36. m_mirror = false;
  37. }
  38. void BOARD_PRINTOUT_SETTINGS::Load( APP_SETTINGS_BASE* aConfig )
  39. {
  40. PRINTOUT_SETTINGS::Load( aConfig );
  41. m_layerSet.reset();
  42. for( int layer : aConfig->m_Printing.layers )
  43. m_layerSet.set( layer, true );
  44. }
  45. void BOARD_PRINTOUT_SETTINGS::Save( APP_SETTINGS_BASE* aConfig )
  46. {
  47. PRINTOUT_SETTINGS::Save( aConfig );
  48. aConfig->m_Printing.layers.clear();
  49. for( unsigned layer = 0; layer < m_layerSet.size(); ++layer )
  50. if( m_layerSet.test( layer ) )
  51. aConfig->m_Printing.layers.push_back( layer );
  52. }
  53. BOARD_PRINTOUT::BOARD_PRINTOUT( const BOARD_PRINTOUT_SETTINGS& aParams,
  54. const KIGFX::VIEW* aView, const wxString& aTitle ) :
  55. wxPrintout( aTitle ), m_settings( aParams )
  56. {
  57. m_view = aView;
  58. }
  59. void BOARD_PRINTOUT::GetPageInfo( int* minPage, int* maxPage, int* selPageFrom, int* selPageTo )
  60. {
  61. *minPage = 1;
  62. *selPageFrom = 1;
  63. *maxPage = m_settings.m_pageCount;
  64. *selPageTo = m_settings.m_pageCount;
  65. }
  66. void BOARD_PRINTOUT::DrawPage( const wxString& aLayerName, int aPageNum, int aPageCount )
  67. {
  68. auto dc = GetDC();
  69. KIGFX::GAL_DISPLAY_OPTIONS options;
  70. auto galPrint = KIGFX::GAL_PRINT::Create( options, dc );
  71. auto gal = galPrint->GetGAL();
  72. auto printCtx = galPrint->GetPrintCtx();
  73. auto painter = getPainter( gal );
  74. std::unique_ptr<KIGFX::VIEW> view( m_view->DataReference() );
  75. // Target paper size
  76. wxRect pageSizePx = GetLogicalPageRect();
  77. const VECTOR2D pageSizeIn( (double) pageSizePx.width / dc->GetPPI().x,
  78. (double) pageSizePx.height / dc->GetPPI().y );
  79. galPrint->SetSheetSize( pageSizeIn );
  80. const VECTOR2D pageSizeIU( milsToIU( pageSizeIn.x * 1000 ), milsToIU( pageSizeIn.y * 1000 ) );
  81. view->SetGAL( gal );
  82. view->SetPainter( painter.get() );
  83. view->SetScaleLimits( 10e9, 0.0001 );
  84. view->SetScale( 1.0 );
  85. // Set the color scheme
  86. auto srcSettings = m_view->GetPainter()->GetSettings();
  87. auto dstSettings = view->GetPainter()->GetSettings();
  88. if( m_settings.m_blackWhite )
  89. {
  90. for( int i = 0; i < LAYER_ID_COUNT; ++i )
  91. dstSettings->SetLayerColor( i, COLOR4D::BLACK );
  92. }
  93. else // color enabled
  94. {
  95. for( int i = 0; i < LAYER_ID_COUNT; ++i )
  96. {
  97. // Cairo does not support translucent colors on PostScript surfaces
  98. // see 'Features support by the PostScript surface' on
  99. // ttps://www.cairographics.org/documentation/using_the_postscript_surface/
  100. dstSettings->SetLayerColor( i, srcSettings->GetLayerColor( i ).WithAlpha( 1.0 ) );
  101. }
  102. }
  103. setupViewLayers( view, m_settings.m_layerSet );
  104. setupPainter( painter );
  105. auto sheetSizeMils = m_settings.m_pageInfo.GetSizeMils();
  106. VECTOR2I sheetSizeIU( milsToIU( sheetSizeMils.GetWidth() ), milsToIU( sheetSizeMils.GetHeight() ) );
  107. BOX2I bBox;
  108. // Determine printout bounding box
  109. if( m_settings.PrintBorderAndTitleBlock() )
  110. {
  111. bBox = BOX2I( VECTOR2I( 0, 0 ), VECTOR2I( sheetSizeIU ) );
  112. view->SetLayerVisible( LAYER_WORKSHEET, true );
  113. }
  114. else
  115. {
  116. EDA_RECT targetBbox = getBoundingBox();
  117. bBox = BOX2I( targetBbox.GetOrigin(), targetBbox.GetSize() );
  118. view->SetLayerVisible( LAYER_WORKSHEET, false );
  119. }
  120. // Fit to page
  121. if( m_settings.m_scale <= 0.0 )
  122. {
  123. if( bBox.GetWidth() == 0 || bBox.GetHeight() == 0 )
  124. {
  125. // Nothing to print
  126. m_settings.m_scale = 1.0;
  127. }
  128. else
  129. {
  130. double scaleX = (double) pageSizeIU.x / bBox.GetWidth();
  131. double scaleY = (double) pageSizeIU.y / bBox.GetHeight();
  132. m_settings.m_scale = std::min( scaleX, scaleY );
  133. }
  134. }
  135. view->SetPrintMode( 1 );
  136. setupGal( gal );
  137. galPrint->SetNativePaperSize( pageSizeIn, printCtx->HasNativeLandscapeRotation() );
  138. gal->SetLookAtPoint( bBox.Centre() );
  139. gal->SetZoomFactor( m_settings.m_scale );
  140. {
  141. KIGFX::GAL_DRAWING_CONTEXT ctx( gal );
  142. view->Redraw();
  143. }
  144. view->SetPrintMode( 0 );
  145. }
  146. void BOARD_PRINTOUT::setupViewLayers( const std::unique_ptr<KIGFX::VIEW>& aView,
  147. const LSET& aLayerSet )
  148. {
  149. // Disable all layers by default, let specific implementions enable required layers
  150. for( int i = 0; i < KIGFX::VIEW::VIEW_MAX_LAYERS; ++i )
  151. {
  152. aView->SetLayerVisible( i, false );
  153. aView->SetTopLayer( i, false );
  154. aView->SetLayerTarget( i, KIGFX::TARGET_NONCACHED );
  155. }
  156. }
  157. void BOARD_PRINTOUT::setupPainter( const std::unique_ptr<KIGFX::PAINTER>& aPainter )
  158. {
  159. aPainter->GetSettings()->SetBackgroundColor( COLOR4D::WHITE );
  160. }
  161. void BOARD_PRINTOUT::setupGal( KIGFX::GAL* aGal )
  162. {
  163. aGal->SetFlip( m_settings.m_mirror, false );
  164. }