2018-09-19 13:06:29 +00:00
|
|
|
/*
|
|
|
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
|
|
|
*
|
|
|
|
* Copyright (C) 2009 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
|
|
|
|
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
|
|
|
|
* Copyright (C) 2018 CERN
|
|
|
|
* Author: Maciej Suminski <maciej.suminski@cern.ch>
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, you may find one here:
|
|
|
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
|
|
|
* or you may search the http://www.gnu.org website for the version 2 license,
|
|
|
|
* or you may write to the Free Software Foundation, Inc.,
|
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <board_printout.h>
|
|
|
|
|
|
|
|
#include <view/view.h>
|
|
|
|
#include <gal/gal_print.h>
|
|
|
|
#include <painter.h>
|
2018-10-05 14:41:17 +00:00
|
|
|
#include <pcbplot.h>
|
2020-01-13 01:44:19 +00:00
|
|
|
#include <settings/app_settings.h>
|
2018-09-19 13:06:29 +00:00
|
|
|
|
2018-10-05 14:41:17 +00:00
|
|
|
|
|
|
|
BOARD_PRINTOUT_SETTINGS::BOARD_PRINTOUT_SETTINGS( const PAGE_INFO& aPageInfo )
|
|
|
|
: PRINTOUT_SETTINGS( aPageInfo )
|
2018-09-19 13:06:29 +00:00
|
|
|
{
|
2020-11-16 11:16:44 +00:00
|
|
|
m_LayerSet.set();
|
|
|
|
m_Mirror = false;
|
2018-09-19 13:06:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-01-13 01:44:19 +00:00
|
|
|
void BOARD_PRINTOUT_SETTINGS::Load( APP_SETTINGS_BASE* aConfig )
|
2018-10-05 14:41:17 +00:00
|
|
|
{
|
|
|
|
PRINTOUT_SETTINGS::Load( aConfig );
|
|
|
|
|
2020-11-16 11:16:44 +00:00
|
|
|
m_LayerSet.reset();
|
2020-01-13 01:44:19 +00:00
|
|
|
|
|
|
|
for( int layer : aConfig->m_Printing.layers )
|
2020-11-16 11:16:44 +00:00
|
|
|
m_LayerSet.set( layer, true );
|
2018-10-05 14:41:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-01-13 01:44:19 +00:00
|
|
|
void BOARD_PRINTOUT_SETTINGS::Save( APP_SETTINGS_BASE* aConfig )
|
2018-10-05 14:41:17 +00:00
|
|
|
{
|
|
|
|
PRINTOUT_SETTINGS::Save( aConfig );
|
|
|
|
|
2020-01-13 01:44:19 +00:00
|
|
|
aConfig->m_Printing.layers.clear();
|
|
|
|
|
2020-11-16 11:16:44 +00:00
|
|
|
for( unsigned layer = 0; layer < m_LayerSet.size(); ++layer )
|
|
|
|
if( m_LayerSet.test( layer ) )
|
2020-01-13 01:44:19 +00:00
|
|
|
aConfig->m_Printing.layers.push_back( layer );
|
2018-10-05 14:41:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-10-06 16:51:46 +00:00
|
|
|
BOARD_PRINTOUT::BOARD_PRINTOUT( const BOARD_PRINTOUT_SETTINGS& aParams,
|
2020-08-25 13:07:18 +00:00
|
|
|
const KIGFX::VIEW* aView, const wxString& aTitle ) :
|
|
|
|
wxPrintout( aTitle ),
|
|
|
|
m_settings( aParams )
|
2018-09-19 13:06:29 +00:00
|
|
|
{
|
|
|
|
m_view = aView;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void BOARD_PRINTOUT::GetPageInfo( int* minPage, int* maxPage, int* selPageFrom, int* selPageTo )
|
|
|
|
{
|
|
|
|
*minPage = 1;
|
|
|
|
*selPageFrom = 1;
|
|
|
|
|
2018-10-05 14:41:17 +00:00
|
|
|
*maxPage = m_settings.m_pageCount;
|
|
|
|
*selPageTo = m_settings.m_pageCount;
|
2018-09-19 13:06:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void BOARD_PRINTOUT::DrawPage( const wxString& aLayerName, int aPageNum, int aPageCount )
|
|
|
|
{
|
|
|
|
auto dc = GetDC();
|
|
|
|
KIGFX::GAL_DISPLAY_OPTIONS options;
|
|
|
|
auto galPrint = KIGFX::GAL_PRINT::Create( options, dc );
|
|
|
|
auto gal = galPrint->GetGAL();
|
|
|
|
auto printCtx = galPrint->GetPrintCtx();
|
|
|
|
auto painter = getPainter( gal );
|
|
|
|
std::unique_ptr<KIGFX::VIEW> view( m_view->DataReference() );
|
|
|
|
|
2018-10-06 19:34:51 +00:00
|
|
|
// Target paper size
|
2018-10-02 13:47:59 +00:00
|
|
|
wxRect pageSizePx = GetLogicalPageRect();
|
2018-10-06 19:34:51 +00:00
|
|
|
const VECTOR2D pageSizeIn( (double) pageSizePx.width / dc->GetPPI().x,
|
2018-10-02 13:47:59 +00:00
|
|
|
(double) pageSizePx.height / dc->GetPPI().y );
|
|
|
|
galPrint->SetSheetSize( pageSizeIn );
|
2018-10-06 19:34:51 +00:00
|
|
|
const VECTOR2D pageSizeIU( milsToIU( pageSizeIn.x * 1000 ), milsToIU( pageSizeIn.y * 1000 ) );
|
2018-09-19 13:06:29 +00:00
|
|
|
|
|
|
|
view->SetGAL( gal );
|
|
|
|
view->SetPainter( painter.get() );
|
|
|
|
view->SetScaleLimits( 10e9, 0.0001 );
|
|
|
|
view->SetScale( 1.0 );
|
|
|
|
|
2018-09-28 11:15:17 +00:00
|
|
|
|
|
|
|
// Set the color scheme
|
2021-02-02 15:36:45 +00:00
|
|
|
RENDER_SETTINGS* dstSettings = view->GetPainter()->GetSettings();
|
2020-05-16 17:15:43 +00:00
|
|
|
dstSettings->LoadColors( m_settings.m_colorSettings );
|
2018-09-28 11:15:17 +00:00
|
|
|
|
2018-10-05 14:41:17 +00:00
|
|
|
if( m_settings.m_blackWhite )
|
2018-09-28 11:15:17 +00:00
|
|
|
{
|
|
|
|
for( int i = 0; i < LAYER_ID_COUNT; ++i )
|
|
|
|
dstSettings->SetLayerColor( i, COLOR4D::BLACK );
|
|
|
|
}
|
|
|
|
else // color enabled
|
|
|
|
{
|
|
|
|
for( int i = 0; i < LAYER_ID_COUNT; ++i )
|
2018-12-22 12:44:49 +00:00
|
|
|
{
|
|
|
|
// Cairo does not support translucent colors on PostScript surfaces
|
|
|
|
// see 'Features support by the PostScript surface' on
|
2020-05-16 17:15:43 +00:00
|
|
|
// https://www.cairographics.org/documentation/using_the_postscript_surface/
|
|
|
|
dstSettings->SetLayerColor( i, dstSettings->GetLayerColor( i ).WithAlpha( 1.0 ) );
|
2018-12-22 12:44:49 +00:00
|
|
|
}
|
2018-09-28 11:15:17 +00:00
|
|
|
}
|
|
|
|
|
2021-02-02 15:36:45 +00:00
|
|
|
dstSettings->SetIsPrinting( true );
|
|
|
|
|
2020-01-17 11:56:07 +00:00
|
|
|
setupPainter( *painter );
|
2021-02-25 13:02:33 +00:00
|
|
|
setupViewLayers( *view, m_settings.m_LayerSet );
|
2018-09-19 13:06:29 +00:00
|
|
|
|
2018-10-06 16:51:46 +00:00
|
|
|
auto sheetSizeMils = m_settings.m_pageInfo.GetSizeMils();
|
|
|
|
VECTOR2I sheetSizeIU( milsToIU( sheetSizeMils.GetWidth() ), milsToIU( sheetSizeMils.GetHeight() ) );
|
2018-10-06 19:34:51 +00:00
|
|
|
BOX2I bBox;
|
2018-09-19 13:06:29 +00:00
|
|
|
|
2018-10-06 19:34:51 +00:00
|
|
|
// Determine printout bounding box
|
2018-10-05 14:41:17 +00:00
|
|
|
if( m_settings.PrintBorderAndTitleBlock() )
|
2018-09-19 13:06:29 +00:00
|
|
|
{
|
2018-10-06 16:51:46 +00:00
|
|
|
bBox = BOX2I( VECTOR2I( 0, 0 ), VECTOR2I( sheetSizeIU ) );
|
2021-02-22 16:37:43 +00:00
|
|
|
view->SetLayerVisible( LAYER_DRAWINGSHEET, true );
|
2018-09-19 13:06:29 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
EDA_RECT targetBbox = getBoundingBox();
|
|
|
|
bBox = BOX2I( targetBbox.GetOrigin(), targetBbox.GetSize() );
|
2021-02-22 16:37:43 +00:00
|
|
|
view->SetLayerVisible( LAYER_DRAWINGSHEET, false );
|
2018-09-19 13:06:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-10-03 07:50:05 +00:00
|
|
|
// Fit to page
|
2018-10-05 14:41:17 +00:00
|
|
|
if( m_settings.m_scale <= 0.0 )
|
2018-09-19 13:06:29 +00:00
|
|
|
{
|
2018-10-03 07:50:05 +00:00
|
|
|
if( bBox.GetWidth() == 0 || bBox.GetHeight() == 0 )
|
|
|
|
{
|
|
|
|
// Nothing to print
|
2018-10-05 14:41:17 +00:00
|
|
|
m_settings.m_scale = 1.0;
|
2018-10-03 07:50:05 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-10-06 19:34:51 +00:00
|
|
|
double scaleX = (double) pageSizeIU.x / bBox.GetWidth();
|
|
|
|
double scaleY = (double) pageSizeIU.y / bBox.GetHeight();
|
2018-10-05 14:41:17 +00:00
|
|
|
m_settings.m_scale = std::min( scaleX, scaleY );
|
2018-10-03 07:50:05 +00:00
|
|
|
}
|
2018-09-19 13:06:29 +00:00
|
|
|
}
|
|
|
|
|
2018-12-22 12:44:49 +00:00
|
|
|
view->SetPrintMode( 1 );
|
|
|
|
|
2018-09-29 10:13:06 +00:00
|
|
|
setupGal( gal );
|
2018-10-02 13:47:59 +00:00
|
|
|
galPrint->SetNativePaperSize( pageSizeIn, printCtx->HasNativeLandscapeRotation() );
|
2018-09-19 13:06:29 +00:00
|
|
|
gal->SetLookAtPoint( bBox.Centre() );
|
2018-10-05 14:41:17 +00:00
|
|
|
gal->SetZoomFactor( m_settings.m_scale );
|
2018-09-19 13:06:29 +00:00
|
|
|
|
2020-05-16 17:15:43 +00:00
|
|
|
gal->SetClearColor( dstSettings->GetBackgroundColor() );
|
|
|
|
gal->ClearScreen();
|
|
|
|
|
2018-09-19 13:06:29 +00:00
|
|
|
{
|
|
|
|
KIGFX::GAL_DRAWING_CONTEXT ctx( gal );
|
|
|
|
view->Redraw();
|
|
|
|
}
|
2018-12-22 12:44:49 +00:00
|
|
|
|
|
|
|
view->SetPrintMode( 0 );
|
2018-09-19 13:06:29 +00:00
|
|
|
}
|
2018-09-28 08:10:08 +00:00
|
|
|
|
|
|
|
|
2020-01-17 11:56:07 +00:00
|
|
|
void BOARD_PRINTOUT::setupViewLayers( KIGFX::VIEW& aView, const LSET& aLayerSet )
|
2018-09-28 08:10:08 +00:00
|
|
|
{
|
2021-04-05 13:24:57 +00:00
|
|
|
// Disable all layers by default, let specific implementations enable required layers
|
2018-09-28 08:10:08 +00:00
|
|
|
for( int i = 0; i < KIGFX::VIEW::VIEW_MAX_LAYERS; ++i )
|
|
|
|
{
|
2020-01-17 11:56:07 +00:00
|
|
|
aView.SetLayerVisible( i, false );
|
|
|
|
aView.SetTopLayer( i, false );
|
|
|
|
aView.SetLayerTarget( i, KIGFX::TARGET_NONCACHED );
|
2018-09-28 08:10:08 +00:00
|
|
|
}
|
|
|
|
}
|
2018-09-28 11:15:17 +00:00
|
|
|
|
|
|
|
|
2020-01-17 11:56:07 +00:00
|
|
|
void BOARD_PRINTOUT::setupPainter( KIGFX::PAINTER& aPainter )
|
2018-09-28 11:15:17 +00:00
|
|
|
{
|
2020-05-16 17:15:43 +00:00
|
|
|
if( !m_settings.m_background )
|
2020-01-17 11:56:07 +00:00
|
|
|
aPainter.GetSettings()->SetBackgroundColor( COLOR4D::WHITE );
|
2018-09-28 11:15:17 +00:00
|
|
|
}
|
2018-10-05 14:41:17 +00:00
|
|
|
|
|
|
|
|
|
|
|
void BOARD_PRINTOUT::setupGal( KIGFX::GAL* aGal )
|
|
|
|
{
|
2020-11-16 11:16:44 +00:00
|
|
|
aGal->SetFlip( m_settings.m_Mirror, false );
|
2018-10-05 14:41:17 +00:00
|
|
|
}
|