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.

221 lines
7.4 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 at wanadoo.fr
  5. * Copyright The 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 <lset.h>
  28. #include <view/view.h>
  29. #include <gal/gal_print.h>
  30. #include <gal/graphics_abstraction_layer.h>
  31. #include <gal/painter.h>
  32. #include <pcbplot.h>
  33. #include <settings/app_settings.h>
  34. BOARD_PRINTOUT_SETTINGS::BOARD_PRINTOUT_SETTINGS( const PAGE_INFO& aPageInfo )
  35. : PRINTOUT_SETTINGS( aPageInfo )
  36. {
  37. m_LayerSet.set();
  38. m_Mirror = false;
  39. }
  40. void BOARD_PRINTOUT_SETTINGS::Load( APP_SETTINGS_BASE* aConfig )
  41. {
  42. PRINTOUT_SETTINGS::Load( aConfig );
  43. m_LayerSet.reset();
  44. for( int layer : aConfig->m_Printing.layers )
  45. m_LayerSet.set( layer, true );
  46. }
  47. void BOARD_PRINTOUT_SETTINGS::Save( APP_SETTINGS_BASE* aConfig )
  48. {
  49. PRINTOUT_SETTINGS::Save( aConfig );
  50. aConfig->m_Printing.layers.clear();
  51. for( unsigned layer = 0; layer < m_LayerSet.size(); ++layer )
  52. if( m_LayerSet.test( layer ) )
  53. aConfig->m_Printing.layers.push_back( layer );
  54. }
  55. BOARD_PRINTOUT::BOARD_PRINTOUT( const BOARD_PRINTOUT_SETTINGS& aParams,
  56. const KIGFX::VIEW* aView, const wxString& aTitle ) :
  57. wxPrintout( aTitle ),
  58. m_settings( aParams )
  59. {
  60. m_view = aView;
  61. m_gerbviewPrint = false;
  62. }
  63. void BOARD_PRINTOUT::GetPageInfo( int* minPage, int* maxPage, int* selPageFrom, int* selPageTo )
  64. {
  65. *minPage = 1;
  66. *selPageFrom = 1;
  67. *maxPage = m_settings.m_pageCount;
  68. *selPageTo = m_settings.m_pageCount;
  69. }
  70. void BOARD_PRINTOUT::DrawPage( const wxString& aLayerName, int aPageNum, int aPageCount )
  71. {
  72. wxDC* dc = GetDC();
  73. KIGFX::GAL_DISPLAY_OPTIONS options;
  74. std::unique_ptr<KIGFX::GAL_PRINT> galPrint = KIGFX::GAL_PRINT::Create( options, dc );
  75. KIGFX::GAL* gal = galPrint->GetGAL();
  76. KIGFX::PRINT_CONTEXT* printCtx = galPrint->GetPrintCtx();
  77. std::unique_ptr<KIGFX::PAINTER> painter = getPainter( gal );
  78. std::unique_ptr<KIGFX::VIEW> view( m_view->DataReference() );
  79. // Target paper size
  80. wxRect pageSizePx = GetLogicalPageRect();
  81. const VECTOR2D pageSizeIn( (double) pageSizePx.width / dc->GetPPI().x,
  82. (double) pageSizePx.height / dc->GetPPI().y );
  83. const VECTOR2D pageSizeIU( milsToIU( pageSizeIn.x * 1000 ), milsToIU( pageSizeIn.y * 1000 ) );
  84. galPrint->SetSheetSize( pageSizeIn );
  85. view->SetGAL( gal );
  86. view->SetPainter( painter.get() );
  87. view->SetScaleLimits( 10e9, 0.0001 );
  88. view->SetScale( 1.0 );
  89. // Set the color scheme
  90. RENDER_SETTINGS* dstSettings = view->GetPainter()->GetSettings();
  91. dstSettings->LoadColors( m_settings.m_colorSettings );
  92. if( m_settings.m_blackWhite )
  93. {
  94. for( int i = 0; i < LAYER_ID_COUNT; ++i )
  95. dstSettings->SetLayerColor( i, COLOR4D::BLACK );
  96. // In B&W mode, draw the background only in wxhite, because any other color
  97. // will be replaced by a black background
  98. dstSettings->SetBackgroundColor( COLOR4D::WHITE );
  99. }
  100. else // color enabled
  101. {
  102. for( int i = 0; i < LAYER_ID_COUNT; ++i )
  103. {
  104. // Cairo does not support translucent colors on PostScript surfaces
  105. // see 'Features support by the PostScript surface' on
  106. // https://www.cairographics.org/documentation/using_the_postscript_surface/
  107. dstSettings->SetLayerColor( i, dstSettings->GetLayerColor( i ).WithAlpha( 1.0 ) );
  108. }
  109. }
  110. dstSettings->SetIsPrinting( true );
  111. setupPainter( *painter );
  112. setupViewLayers( *view, m_settings.m_LayerSet );
  113. dstSettings->SetPrintLayers( m_settings.m_LayerSet );
  114. dstSettings->SetLayerName( aLayerName );
  115. VECTOR2I sheetSizeMils = m_settings.m_pageInfo.GetSizeMils();
  116. VECTOR2I sheetSizeIU( milsToIU( sheetSizeMils.x ),
  117. milsToIU( sheetSizeMils.y ) );
  118. BOX2I drawingAreaBBox = BOX2I( VECTOR2I( 0, 0 ), VECTOR2I( sheetSizeIU ) );
  119. // When printing the board without worksheet items, move board center to the
  120. // drawing area center.
  121. if( !m_settings.PrintBorderAndTitleBlock() )
  122. drawingAreaBBox = getBoundingBox();
  123. view->SetLayerVisible( LAYER_DRAWINGSHEET, m_settings.PrintBorderAndTitleBlock() );
  124. // Fit to page (drawingAreaBBox)
  125. if( m_settings.m_scale <= 0.0 )
  126. {
  127. if( drawingAreaBBox.GetWidth() == 0 || drawingAreaBBox.GetHeight() == 0 )
  128. {
  129. // Nothing to print (empty board and no worksheet)
  130. m_settings.m_scale = 1.0;
  131. }
  132. else
  133. {
  134. double scaleX = (double) pageSizeIU.x / drawingAreaBBox.GetWidth();
  135. double scaleY = (double) pageSizeIU.y / drawingAreaBBox.GetHeight();
  136. m_settings.m_scale = std::min( scaleX, scaleY );
  137. }
  138. }
  139. setupGal( gal );
  140. galPrint->SetNativePaperSize( pageSizeIn, printCtx->HasNativeLandscapeRotation() );
  141. gal->SetLookAtPoint( drawingAreaBBox.Centre() );
  142. gal->SetZoomFactor( m_settings.m_scale );
  143. gal->SetClearColor( dstSettings->GetBackgroundColor() );
  144. // Clearing the screen for the background color needs the screen set to the page size
  145. // in pixels. This can ?somehow? prevent some but not all foreground elements from being printed
  146. // TODO: figure out what's going on here and fix printing. See also sch_printout
  147. VECTOR2I size = gal->GetScreenPixelSize();
  148. gal->ResizeScreen( pageSizePx.GetWidth(),pageSizePx.GetHeight() );
  149. gal->ClearScreen();
  150. gal->ResizeScreen( size.x, size.y );
  151. if( m_gerbviewPrint )
  152. // Mandatory in Gerbview to use the same order for printing as for screen redraw
  153. // due to negative objects that need a specific order
  154. view->UseDrawPriority( true );
  155. {
  156. KIGFX::GAL_DRAWING_CONTEXT ctx( gal );
  157. view->Redraw();
  158. }
  159. }
  160. void BOARD_PRINTOUT::setupViewLayers( KIGFX::VIEW& aView, const LSET& aLayerSet )
  161. {
  162. // Disable all layers by default, let specific implementations enable required layers
  163. for( int i = 0; i < KIGFX::VIEW::VIEW_MAX_LAYERS; ++i )
  164. {
  165. aView.SetLayerVisible( i, false );
  166. aView.SetTopLayer( i, false );
  167. aView.SetLayerTarget( i, KIGFX::TARGET_NONCACHED );
  168. }
  169. }
  170. void BOARD_PRINTOUT::setupPainter( KIGFX::PAINTER& aPainter )
  171. {
  172. if( !m_settings.m_background )
  173. aPainter.GetSettings()->SetBackgroundColor( COLOR4D::WHITE );
  174. }
  175. void BOARD_PRINTOUT::setupGal( KIGFX::GAL* aGal )
  176. {
  177. aGal->SetFlip( m_settings.m_Mirror, false );
  178. }