Eeschema: Add Cairo printing to the Eeschema print engine. The current print engine (using wxDC draw engine) has frequently issues with each new wxWidgets version. Cairo printing engine, used for Pcbnew and Gerbview has less issues. On Eeschema, the cairo print is enabled only if the advanced config has the option "EnableEeschemaPrintCairo = 1"

This commit is contained in:
jean-pierre charras 2023-11-23 14:29:07 +01:00
parent 1c881bcbb8
commit 247a0e6501
12 changed files with 489 additions and 229 deletions

View File

@ -217,6 +217,8 @@ static const wxChar EnableGenerators[] = wxT( "EnableGenerators" );
static const wxChar EnableGit[] = wxT( "EnableGit" );
static const wxChar EnableEeschemaPrintCairo[] = wxT( "EnableEeschemaPrintCairo" );
/**
* The time in milliseconds to wait before displaying a disambiguation menu.
*/
@ -348,6 +350,7 @@ ADVANCED_CFG::ADVANCED_CFG()
m_ShowPropertiesPanel = false;
m_EnableGenerators = false;
m_EnableGit = false;
m_EnableEeschemaPrintCairo = false;
m_3DRT_BevelHeight_um = 30;
m_3DRT_BevelExtentFactor = 1.0 / 16.0;
@ -524,7 +527,8 @@ void ADVANCED_CFG::loadSettings( wxConfigBase& aCfg )
configParams.push_back( new PARAM_CFG_BOOL( true, AC_KEYS::EnableGit,
&m_EnableGit, m_EnableGit ) );
configParams.push_back( new PARAM_CFG_BOOL( true, AC_KEYS::EnableEeschemaPrintCairo,
&m_EnableEeschemaPrintCairo, m_EnableEeschemaPrintCairo ) );
// Special case for trace mask setting...we just grab them and set them immediately
// Because we even use wxLogTrace inside of advanced config

View File

@ -45,6 +45,7 @@ RENDER_SETTINGS::RENDER_SETTINGS() :
m_defaultPenWidth = 0;
m_minPenWidth = 0;
m_isPrinting = false;
m_printBlackAndWite = false;
}

View File

@ -119,8 +119,6 @@ set( EESCHEMA_DLGS
dialogs/dialog_pin_properties_base.cpp
dialogs/dialog_plot_schematic.cpp
dialogs/dialog_plot_schematic_base.cpp
dialogs/dialog_print_using_printer.cpp
dialogs/dialog_print_using_printer_base.cpp
dialogs/dialog_rescue_each.cpp
dialogs/dialog_rescue_each_base.cpp
dialogs/dialog_sch_import_settings.cpp
@ -288,6 +286,12 @@ set( EESCHEMA_IMPORT_GFX
import_gfx/graphics_importer_sch.cpp
)
set( EESCHEMA_PRINTING
printing/dialog_print_using_printer.cpp
printing/dialog_print_using_printer_base.cpp
printing/sch_printout.cpp
)
set( EESCHEMA_SRCS
${EESCHEMA_DLGS}
${EESCHEMA_LIBEDIT_SRCS}
@ -528,6 +532,7 @@ target_link_libraries( eeschema
# the main Eeschema program, in DSO form.
add_library( eeschema_kiface_objects OBJECT
${EESCHEMA_SRCS}
${EESCHEMA_PRINTING}
${EESCHEMA_COMMON_SRCS}
)

View File

@ -33,11 +33,13 @@
#include <sch_sheet.h>
#include <schematic.h>
#include <sch_sheet_path.h>
#include <dialog_print_using_printer_base.h>
#include "dialog_print_using_printer_base.h"
#include <sch_painter.h>
#include <wx/print.h>
#include <wx/printdlg.h>
#include "sch_printout.h"
class DIALOG_PRINT_USING_PRINTER : public DIALOG_PRINT_USING_PRINTER_BASE
{
@ -62,31 +64,6 @@ private:
};
/**
* Custom print out for printing schematics.
*/
class SCH_PRINTOUT : public wxPrintout
{
public:
SCH_PRINTOUT( SCH_EDIT_FRAME* aParent, const wxString& aTitle ) :
wxPrintout( aTitle )
{
wxASSERT( aParent != nullptr );
m_parent = aParent;
}
bool OnPrintPage( int page ) override;
bool HasPage( int page ) override;
bool OnBeginDocument( int startPage, int endPage ) override;
void GetPageInfo( int* minPage, int* maxPage, int* selPageFrom, int* selPageTo ) override;
void PrintPage( SCH_SCREEN* aScreen );
private:
SCH_EDIT_FRAME* m_parent;
};
/**
* Custom schematic print preview frame.
* This derived preview frame remembers its size and position during a session
@ -415,197 +392,6 @@ bool DIALOG_PRINT_USING_PRINTER::TransferDataFromWindow()
}
bool SCH_PRINTOUT::OnPrintPage( int page )
{
SCH_SHEET_LIST sheetList = m_parent->Schematic().GetSheets();
wxCHECK_MSG( page >= 1 && page <= (int)sheetList.size(), false,
wxT( "Cannot print invalid page number." ) );
wxCHECK_MSG( sheetList[ page - 1].LastScreen() != nullptr, false,
wxT( "Cannot print page with NULL screen." ) );
wxString msg;
msg.Printf( _( "Print page %d" ), page );
m_parent->SetMsgPanel( msg, wxEmptyString );
SCH_SCREEN* screen = m_parent->GetScreen();
SCH_SHEET_PATH oldsheetpath = m_parent->GetCurrentSheet();
m_parent->SetCurrentSheet( sheetList[ page - 1 ] );
m_parent->GetCurrentSheet().UpdateAllScreenReferences();
m_parent->SetSheetNumberAndCount();
m_parent->RecomputeIntersheetRefs();
screen = m_parent->GetCurrentSheet().LastScreen();
PrintPage( screen );
m_parent->SetCurrentSheet( oldsheetpath );
m_parent->GetCurrentSheet().UpdateAllScreenReferences();
m_parent->SetSheetNumberAndCount();
return true;
}
void SCH_PRINTOUT::GetPageInfo( int* minPage, int* maxPage, int* selPageFrom, int* selPageTo )
{
*minPage = *selPageFrom = 1;
*maxPage = *selPageTo = m_parent->Schematic().Root().CountSheets();
}
bool SCH_PRINTOUT::HasPage( int pageNum )
{
return m_parent->Schematic().Root().CountSheets() >= pageNum;
}
bool SCH_PRINTOUT::OnBeginDocument( int startPage, int endPage )
{
if( !wxPrintout::OnBeginDocument( startPage, endPage ) )
return false;
return true;
}
/*
* This is the real print function: print the active screen
*/
void SCH_PRINTOUT::PrintPage( SCH_SCREEN* aScreen )
{
// Warning:
// When printing many pages, changes in the current wxDC will affect all next printings
// because all prints are using the same wxPrinterDC after creation
// So be careful and reinit parameters, especially when using offsets.
VECTOR2I tmp_startvisu;
wxSize pageSizeIU; // Page size in internal units
VECTOR2I old_org;
wxRect fitRect;
wxDC* dc = GetDC();
wxBusyCursor dummy;
// Save current offsets and clip box.
tmp_startvisu = aScreen->m_StartVisu;
old_org = aScreen->m_DrawOrg;
SETTINGS_MANAGER& mgr = Pgm().GetSettingsManager();
EESCHEMA_SETTINGS* cfg = m_parent->eeconfig();
COLOR_SETTINGS* theme = mgr.GetColorSettings( cfg->m_Printing.color_theme );
// Change scale factor and offset to print the whole page.
bool printDrawingSheet = cfg->m_Printing.title_block;
pageSizeIU = ToWxSize( aScreen->GetPageSettings().GetSizeIU( schIUScale.IU_PER_MILS ) );
FitThisSizeToPaper( pageSizeIU );
fitRect = GetLogicalPaperRect();
// When is the actual paper size does not match the schematic page size, the drawing will
// not be centered on X or Y axis. Give a draw offset to center the schematic page on the
// paper draw area.
int xoffset = ( fitRect.width - pageSizeIU.x ) / 2;
int yoffset = ( fitRect.height - pageSizeIU.y ) / 2;
// Using a wxAffineMatrix2D has a big advantage: it handles different pages orientations
//(PORTRAIT/LANDSCAPE), but the affine matrix is not always supported
if( dc->CanUseTransformMatrix() )
{
wxAffineMatrix2D matrix; // starts from a unity matrix (the current wxDC default)
// Check for portrait/landscape mismatch:
if( ( fitRect.width > fitRect.height ) != ( pageSizeIU.x > pageSizeIU.y ) )
{
// Rotate the coordinates, and keep the draw coordinates inside the page
matrix.Rotate( M_PI_2 );
matrix.Translate( 0, -pageSizeIU.y );
// Recalculate the offsets and page sizes according to the page rotation
std::swap( pageSizeIU.x, pageSizeIU.y );
FitThisSizeToPaper( pageSizeIU );
fitRect = GetLogicalPaperRect();
xoffset = ( fitRect.width - pageSizeIU.x ) / 2;
yoffset = ( fitRect.height - pageSizeIU.y ) / 2;
// All the coordinates will be rotated 90 deg when printing,
// so the X,Y offset vector must be rotated -90 deg before printing
std::swap( xoffset, yoffset );
std::swap( fitRect.width, fitRect.height );
yoffset = -yoffset;
}
matrix.Translate( xoffset, yoffset );
dc->SetTransformMatrix( matrix );
fitRect.x -= xoffset;
fitRect.y -= yoffset;
}
else
{
SetLogicalOrigin( 0, 0 ); // Reset all offset settings made previously.
// When printing previous pages (all prints are using the same wxDC)
OffsetLogicalOrigin( xoffset, yoffset );
}
dc->SetLogicalFunction( wxCOPY );
GRResetPenAndBrush( dc );
COLOR4D savedBgColor = m_parent->GetDrawBgColor();
COLOR4D bgColor = m_parent->GetColorSettings()->GetColor( LAYER_SCHEMATIC_BACKGROUND );
if( cfg->m_Printing.background )
{
if( cfg->m_Printing.use_theme && theme )
bgColor = theme->GetColor( LAYER_SCHEMATIC_BACKGROUND );
}
else
{
bgColor = COLOR4D::WHITE;
}
m_parent->SetDrawBgColor( bgColor );
GRSFilledRect( dc, fitRect.GetX(), fitRect.GetY(), fitRect.GetRight(), fitRect.GetBottom(), 0,
bgColor, bgColor );
if( cfg->m_Printing.monochrome )
GRForceBlackPen( true );
KIGFX::SCH_RENDER_SETTINGS renderSettings( *m_parent->GetRenderSettings() );
renderSettings.SetPrintDC( dc );
if( cfg->m_Printing.use_theme && theme )
renderSettings.LoadColors( theme );
renderSettings.SetBackgroundColor( bgColor );
// The drawing-sheet-item print code is shared between PCBNew and Eeschema, so it's easier
// if they just use the PCB layer.
renderSettings.SetLayerColor( LAYER_DRAWINGSHEET,
renderSettings.GetLayerColor( LAYER_SCHEMATIC_DRAWINGSHEET ) );
renderSettings.SetDefaultFont( cfg->m_Appearance.default_font );
if( printDrawingSheet )
{
m_parent->PrintDrawingSheet( &renderSettings, aScreen, aScreen->Schematic()->GetProperties(),
schIUScale.IU_PER_MILS, aScreen->GetFileName(), wxEmptyString );
}
renderSettings.SetIsPrinting( true );
aScreen->Print( &renderSettings );
m_parent->SetDrawBgColor( savedBgColor );
GRForceBlackPen( false );
aScreen->m_StartVisu = tmp_startvisu;
aScreen->m_DrawOrg = old_org;
}
int InvokeDialogPrintUsingPrinter( SCH_EDIT_FRAME* aCaller )
{
DIALOG_PRINT_USING_PRINTER dlg( aCaller );

View File

@ -0,0 +1,375 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2023 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors.
*
* 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 3 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, see <http://www.gnu.org/licenses/>.
*/
#include "sch_printout.h"
#include <sch_edit_frame.h>
#include <math/vector2wx.h>
#include <pgm_base.h>
#include <settings/color_settings.h>
#include <settings/settings_manager.h>
#include <sch_painter.h>
#include <view/view.h>
#include <gal/gal_print.h>
#include <gal/graphics_abstraction_layer.h>
#include <gal/painter.h>
#include <zoom_defines.h>
#include <advanced_config.h>
void SCH_PRINTOUT::GetPageInfo( int* minPage, int* maxPage, int* selPageFrom, int* selPageTo )
{
*minPage = *selPageFrom = 1;
*maxPage = *selPageTo = m_parent->Schematic().Root().CountSheets();
}
bool SCH_PRINTOUT::HasPage( int pageNum )
{
return m_parent->Schematic().Root().CountSheets() >= pageNum;
}
bool SCH_PRINTOUT::OnBeginDocument( int startPage, int endPage )
{
if( !wxPrintout::OnBeginDocument( startPage, endPage ) )
return false;
return true;
}
bool SCH_PRINTOUT::OnPrintPage( int page )
{
SCH_SHEET_LIST sheetList = m_parent->Schematic().GetSheets();
wxCHECK_MSG( page >= 1 && page <= (int)sheetList.size(), false,
wxT( "Cannot print invalid page number." ) );
wxCHECK_MSG( sheetList[ page - 1].LastScreen() != nullptr, false,
wxT( "Cannot print page with NULL screen." ) );
wxString msg;
msg.Printf( _( "Print page %d" ), page );
m_parent->SetMsgPanel( msg, wxEmptyString );
SCH_SCREEN* screen = m_parent->GetScreen();
SCH_SHEET_PATH oldsheetpath = m_parent->GetCurrentSheet();
m_parent->SetCurrentSheet( sheetList[ page - 1 ] );
m_parent->GetCurrentSheet().UpdateAllScreenReferences();
m_parent->SetSheetNumberAndCount();
m_parent->RecomputeIntersheetRefs();
screen = m_parent->GetCurrentSheet().LastScreen();
PrintPage( screen );
m_parent->SetCurrentSheet( oldsheetpath );
m_parent->GetCurrentSheet().UpdateAllScreenReferences();
m_parent->SetSheetNumberAndCount();
return true;
}
int SCH_PRINTOUT::milsToIU( int aMils )
{
return KiROUND( aMils * schIUScale.IU_PER_MILS );
}
/*
* This is the real print function: print the active screen
*/
void SCH_PRINTOUT::PrintPage( SCH_SCREEN* aScreen )
{
if( !ADVANCED_CFG::GetCfg().m_EnableEeschemaPrintCairo )
{
// Version using print to a wxDC
// Warning:
// When printing many pages, changes in the current wxDC will affect all next printings
// because all prints are using the same wxPrinterDC after creation
// So be careful and reinit parameters, especially when using offsets.
VECTOR2I tmp_startvisu;
wxSize pageSizeIU; // Page size in internal units
VECTOR2I old_org;
wxRect fitRect;
wxDC* dc = GetDC();
wxBusyCursor dummy;
// Save current offsets and clip box.
tmp_startvisu = aScreen->m_StartVisu;
old_org = aScreen->m_DrawOrg;
SETTINGS_MANAGER& mgr = Pgm().GetSettingsManager();
EESCHEMA_SETTINGS* cfg = m_parent->eeconfig();
COLOR_SETTINGS* theme = mgr.GetColorSettings( cfg->m_Printing.color_theme );
// Change scale factor and offset to print the whole page.
bool printDrawingSheet = cfg->m_Printing.title_block;
pageSizeIU = ToWxSize( aScreen->GetPageSettings().GetSizeIU( schIUScale.IU_PER_MILS ) );
FitThisSizeToPaper( pageSizeIU );
fitRect = GetLogicalPaperRect();
// When is the actual paper size does not match the schematic page size, the drawing will
// not be centered on X or Y axis. Give a draw offset to center the schematic page on the
// paper draw area.
int xoffset = ( fitRect.width - pageSizeIU.x ) / 2;
int yoffset = ( fitRect.height - pageSizeIU.y ) / 2;
// Using a wxAffineMatrix2D has a big advantage: it handles different pages orientations
//(PORTRAIT/LANDSCAPE), but the affine matrix is not always supported
if( dc->CanUseTransformMatrix() )
{
wxAffineMatrix2D matrix; // starts from a unity matrix (the current wxDC default)
// Check for portrait/landscape mismatch:
if( ( fitRect.width > fitRect.height ) != ( pageSizeIU.x > pageSizeIU.y ) )
{
// Rotate the coordinates, and keep the draw coordinates inside the page
matrix.Rotate( M_PI_2 );
matrix.Translate( 0, -pageSizeIU.y );
// Recalculate the offsets and page sizes according to the page rotation
std::swap( pageSizeIU.x, pageSizeIU.y );
FitThisSizeToPaper( pageSizeIU );
fitRect = GetLogicalPaperRect();
xoffset = ( fitRect.width - pageSizeIU.x ) / 2;
yoffset = ( fitRect.height - pageSizeIU.y ) / 2;
// All the coordinates will be rotated 90 deg when printing,
// so the X,Y offset vector must be rotated -90 deg before printing
std::swap( xoffset, yoffset );
std::swap( fitRect.width, fitRect.height );
yoffset = -yoffset;
}
matrix.Translate( xoffset, yoffset );
dc->SetTransformMatrix( matrix );
fitRect.x -= xoffset;
fitRect.y -= yoffset;
}
else
{
SetLogicalOrigin( 0, 0 ); // Reset all offset settings made previously.
// When printing previous pages (all prints are using the same wxDC)
OffsetLogicalOrigin( xoffset, yoffset );
}
dc->SetLogicalFunction( wxCOPY );
GRResetPenAndBrush( dc );
COLOR4D savedBgColor = m_parent->GetDrawBgColor();
COLOR4D bgColor = m_parent->GetColorSettings()->GetColor( LAYER_SCHEMATIC_BACKGROUND );
if( cfg->m_Printing.background )
{
if( cfg->m_Printing.use_theme && theme )
bgColor = theme->GetColor( LAYER_SCHEMATIC_BACKGROUND );
}
else
{
bgColor = COLOR4D::WHITE;
}
m_parent->SetDrawBgColor( bgColor );
GRSFilledRect( dc, fitRect.GetX(), fitRect.GetY(), fitRect.GetRight(), fitRect.GetBottom(), 0,
bgColor, bgColor );
if( cfg->m_Printing.monochrome )
GRForceBlackPen( true );
KIGFX::SCH_RENDER_SETTINGS renderSettings( *m_parent->GetRenderSettings() );
renderSettings.SetPrintDC( dc );
if( cfg->m_Printing.use_theme && theme )
renderSettings.LoadColors( theme );
renderSettings.SetBackgroundColor( bgColor );
// The drawing-sheet-item print code is shared between PCBNew and Eeschema, so it's easier
// if they just use the PCB layer.
renderSettings.SetLayerColor( LAYER_DRAWINGSHEET,
renderSettings.GetLayerColor( LAYER_SCHEMATIC_DRAWINGSHEET ) );
renderSettings.SetDefaultFont( cfg->m_Appearance.default_font );
if( printDrawingSheet )
{
m_parent->PrintDrawingSheet( &renderSettings, aScreen, aScreen->Schematic()->GetProperties(),
schIUScale.IU_PER_MILS, aScreen->GetFileName(), wxEmptyString );
}
renderSettings.SetIsPrinting( true );
aScreen->Print( &renderSettings );
m_parent->SetDrawBgColor( savedBgColor );
GRForceBlackPen( false );
aScreen->m_StartVisu = tmp_startvisu;
aScreen->m_DrawOrg = old_org;
}
else
{
wxDC* dc = GetDC();
m_view = m_parent->GetCanvas()->GetView();
KIGFX::GAL_DISPLAY_OPTIONS options;
std::unique_ptr<KIGFX::GAL_PRINT> galPrint = KIGFX::GAL_PRINT::Create( options, dc );
KIGFX::GAL* gal = galPrint->GetGAL();
KIGFX::PRINT_CONTEXT* printCtx = galPrint->GetPrintCtx();
std::unique_ptr<KIGFX::SCH_PAINTER> painter = std::make_unique<KIGFX::SCH_PAINTER>( gal );
std::unique_ptr<KIGFX::VIEW> view( m_view->DataReference() );
painter->SetSchematic( &m_parent->Schematic() );
SETTINGS_MANAGER& mgr = Pgm().GetSettingsManager();
EESCHEMA_SETTINGS* cfg = m_parent->eeconfig();
COLOR_SETTINGS* theme = mgr.GetColorSettings( cfg->m_Printing.color_theme );
// Target paper size
wxRect pageSizePx = GetLogicalPageRect();
const VECTOR2D pageSizeIn( (double) pageSizePx.width / dc->GetPPI().x,
(double) pageSizePx.height / dc->GetPPI().y );
const VECTOR2D pageSizeIU( milsToIU( pageSizeIn.x * 1000 ), milsToIU( pageSizeIn.y * 1000 ) );
galPrint->SetSheetSize( pageSizeIn );
view->SetGAL( gal );
view->SetPainter( painter.get() );
view->SetScaleLimits( ZOOM_MAX_LIMIT_EESCHEMA, ZOOM_MIN_LIMIT_EESCHEMA );
view->SetScale( 1.0 );
gal->SetWorldUnitLength( SCH_WORLD_UNIT );
// Init the SCH_RENDER_SETTINGS used by the painter used to print schematic
KIGFX::SCH_RENDER_SETTINGS* dstSettings = painter->GetSettings();
dstSettings->m_ShowPinsElectricalType = false;
// Set the color scheme
dstSettings->LoadColors( m_parent->GetColorSettings( false ) );
if( cfg->m_Printing.use_theme && theme )
dstSettings->LoadColors( theme );
bool printDrawingSheet = cfg->m_Printing.title_block;
COLOR4D bgColor = m_parent->GetColorSettings()->GetColor( LAYER_SCHEMATIC_BACKGROUND );
if( cfg->m_Printing.background )
{
if( cfg->m_Printing.use_theme && theme )
bgColor = theme->GetColor( LAYER_SCHEMATIC_BACKGROUND );
}
else
{
bgColor = COLOR4D::WHITE;
}
dstSettings->SetBackgroundColor( bgColor );
// The drawing-sheet-item print code is shared between PCBNew and Eeschema, so it's easier
// if they just use the PCB layer.
dstSettings->SetLayerColor( LAYER_DRAWINGSHEET,
dstSettings->GetLayerColor( LAYER_SCHEMATIC_DRAWINGSHEET ) );
dstSettings->SetDefaultFont( cfg->m_Appearance.default_font );
if( cfg->m_Printing.monochrome )
{
for( int i = 0; i < LAYER_ID_COUNT; ++i )
dstSettings->SetLayerColor( i, COLOR4D::BLACK );
// In B&W mode, draw the background only in white, because any other color
// will be replaced by a black background
dstSettings->SetBackgroundColor( COLOR4D::WHITE );
dstSettings->m_OverrideItemColors = true;
// Disable print some backgrounds
dstSettings->SetPrintBlackAndWhite( true );
}
else // color enabled
{
for( int i = 0; i < LAYER_ID_COUNT; ++i )
{
// Cairo does not support translucent colors on PostScript surfaces
// see 'Features support by the PostScript surface' on
// https://www.cairographics.org/documentation/using_the_postscript_surface/
dstSettings->SetLayerColor( i, dstSettings->GetLayerColor( i ).WithAlpha( 1.0 ) );
}
}
dstSettings->SetIsPrinting( true );
VECTOR2I sheetSizeIU = aScreen->GetPageSettings().GetSizeIU( schIUScale.IU_PER_MILS );
BOX2I drawingAreaBBox = BOX2I( VECTOR2I( 0, 0 ), VECTOR2I( sheetSizeIU ) );
// When printing the board without worksheet items, move board center to the
// drawing area center.
//if( !m_settings.PrintBorderAndTitleBlock() )
// drawingAreaBBox = getBoundingBox();
// Enable all layers and use KIGFX::TARGET_NONCACHED to force update drawings
// for printing with current GAL instance
for( int i = 0; i < KIGFX::VIEW::VIEW_MAX_LAYERS; ++i )
{
view->SetLayerVisible( i, true );
view->SetLayerTarget( i, KIGFX::TARGET_NONCACHED );
}
view->SetLayerVisible( LAYER_DRAWINGSHEET, printDrawingSheet );
#if 0
// Fit to page (drawingAreaBBox)
if( m_settings.m_scale <= 0.0 )
{
if( drawingAreaBBox.GetWidth() == 0 || drawingAreaBBox.GetHeight() == 0 )
{
// Nothing to print (empty board and no worksheet)
m_settings.m_scale = 1.0;
}
else
{
double scaleX = (double) pageSizeIU.x / drawingAreaBBox.GetWidth();
double scaleY = (double) pageSizeIU.y / drawingAreaBBox.GetHeight();
m_settings.m_scale = std::min( scaleX, scaleY );
}
}
#endif
//setupGal( gal );
galPrint->SetNativePaperSize( pageSizeIn, printCtx->HasNativeLandscapeRotation() );
gal->SetLookAtPoint( drawingAreaBBox.Centre() );
gal->SetZoomFactor( 1.0);//m_settings.m_scale );
gal->SetClearColor( dstSettings->GetBackgroundColor() );
gal->ClearScreen();
// Needed to use the same order for printing as for screen redraw
view->UseDrawPriority( true );
{
KIGFX::GAL_DRAWING_CONTEXT ctx( gal );
view->Redraw();
}
}
}

View File

@ -0,0 +1,60 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2023 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors.
*
* 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 3 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, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <wx/print.h>
class SCH_EDIT_FRAME;
class SCH_SCREEN;
namespace KIGFX
{
class GAL;
class VIEW;
class PAINTER;
};
/**
* Custom print out for printing schematics.
*/
class SCH_PRINTOUT : public wxPrintout
{
public:
SCH_PRINTOUT( SCH_EDIT_FRAME* aParent, const wxString& aTitle ) :
wxPrintout( aTitle )
{
//wxASSERT( aParent != nullptr );
m_parent = aParent;
}
bool OnPrintPage( int page ) override;
bool HasPage( int page ) override;
bool OnBeginDocument( int startPage, int endPage ) override;
void GetPageInfo( int* minPage, int* maxPage, int* selPageFrom, int* selPageTo ) override;
void PrintPage( SCH_SCREEN* aScreen );
private:
SCH_EDIT_FRAME* m_parent;
///< Source VIEW object (note that actual printing only refers to this object)
const KIGFX::VIEW* m_view;
int milsToIU( int aMils );
};

View File

@ -971,7 +971,10 @@ void SCH_PAINTER::draw( const LIB_SHAPE* aShape, int aLayer, bool aDimmed )
}
else if( aLayer == LAYER_DEVICE_BACKGROUND || aLayer == LAYER_NOTES_BACKGROUND )
{
if( aShape->GetFillMode() == FILL_T::FILLED_WITH_BG_BODYCOLOR )
// Do not fill the shape in B&W print mode, to avoid to visible items
// inside the shape
if( aShape->GetFillMode() == FILL_T::FILLED_WITH_BG_BODYCOLOR
&& !m_schSettings.PrintBlackAndWhiteReq() )
{
m_gal->SetIsFill( true );
m_gal->SetIsStroke( false );
@ -1947,7 +1950,7 @@ void SCH_PAINTER::draw( const SCH_LINE* aLine, int aLayer )
if( drawingOP )
return;
color = COLOR4D( 0.0, 0.3, 0.2, 1.0 );
m_gal->SetIsStroke( true );
m_gal->SetStrokeColor( color );
m_gal->SetLineWidth( width );
@ -2056,7 +2059,9 @@ void SCH_PAINTER::draw( const SCH_SHAPE* aShape, int aLayer )
}
else if( aLayer == LAYER_NOTES_BACKGROUND )
{
if( aShape->IsFilled() )
// Do not fill the shape in B&W print mode, to avoid to visible items
// inside the shape
if( aShape->IsFilled() && !m_schSettings.PrintBlackAndWhiteReq() )
{
m_gal->SetIsFill( true );
m_gal->SetIsStroke( false );
@ -2296,7 +2301,9 @@ void SCH_PAINTER::draw( const SCH_TEXTBOX* aTextBox, int aLayer )
}
else if( aLayer == LAYER_NOTES_BACKGROUND )
{
if( aTextBox->IsFilled() )
// Do not fill the shape in B&W print mode, to avoid to visible items
// inside the shape
if( aTextBox->IsFilled() && !m_schSettings.PrintBlackAndWhiteReq() )
{
m_gal->SetIsFill( true );
m_gal->SetIsStroke( false );
@ -2922,11 +2929,16 @@ void SCH_PAINTER::draw( const SCH_SHEET* aSheet, int aLayer )
if( aLayer == LAYER_SHEET_BACKGROUND )
{
m_gal->SetFillColor( getRenderColor( aSheet, LAYER_SHEET_BACKGROUND, true ) );
m_gal->SetIsFill( true );
m_gal->SetIsStroke( false );
// Do not fill the shape in B&W print mode, to avoid to visible items
// inside the shape
if( !m_schSettings.PrintBlackAndWhiteReq() )
{
m_gal->SetFillColor( getRenderColor( aSheet, LAYER_SHEET_BACKGROUND, true ) );
m_gal->SetIsFill( true );
m_gal->SetIsStroke( false );
m_gal->DrawRectangle( pos, pos + size );
m_gal->DrawRectangle( pos, pos + size );
}
}
if( aLayer == LAYER_SHEET || aLayer == LAYER_SELECTION_SHADOWS )

View File

@ -284,6 +284,10 @@ public:
*/
bool m_EnableGit;
/**
* When true, enable Eeschema printing using Cairo
*/
bool m_EnableEeschemaPrintCairo;
///@}

View File

@ -226,6 +226,17 @@ public:
bool IsPrinting() const { return m_isPrinting; }
void SetIsPrinting( bool isPrinting ) { m_isPrinting = isPrinting; }
bool IsPrintBlackAndWhite() const { return m_printBlackAndWite; }
void SetPrintBlackAndWhite( bool aPrintBlackAndWhite )
{
m_printBlackAndWite = aPrintBlackAndWhite;
}
bool PrintBlackAndWhiteReq() const
{
return m_printBlackAndWite && m_isPrinting;
}
/**
* Return current background color settings.
*/
@ -340,7 +351,9 @@ protected:
wxString m_defaultFont;
bool m_isPrinting;
bool m_isPrinting; // true when draw to a printer
bool m_printBlackAndWite; // true if black and white printing is requested: some
// backgrounds are not printed to avoid not visible items
LSET m_printLayers;
wxDC* m_printDC; // This can go away once the drawing sheet is moved to