From 5b94f20e6f59f21bc34741c1800666943c81b7d7 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 19 Sep 2018 15:06:29 +0200 Subject: [PATCH] Adapted printout controllers to the new printing routines --- common/CMakeLists.txt | 1 + common/board_printout.cpp | 157 ++++++++ gerbview/CMakeLists.txt | 2 +- .../dialogs/dialog_print_using_printer.cpp | 18 +- gerbview/draw_gerber_screen.cpp | 2 +- gerbview/gerbview_printout.cpp | 94 +++++ gerbview/gerbview_printout.h | 44 +++ gerbview/printout_control.cpp | 288 -------------- .../board_printout.h | 86 ++-- pcbnew/CMakeLists.txt | 2 +- pcbnew/dialogs/dialog_print_for_modedit.cpp | 18 +- pcbnew/dialogs/dialog_print_using_printer.cpp | 27 +- pcbnew/pcbnew_printout.cpp | 92 +++++ pcbnew/pcbnew_printout.h | 44 +++ pcbnew/print_board_functions.cpp | 2 +- pcbnew/printout_controler.cpp | 366 ------------------ 16 files changed, 517 insertions(+), 726 deletions(-) create mode 100644 common/board_printout.cpp create mode 100644 gerbview/gerbview_printout.cpp create mode 100644 gerbview/gerbview_printout.h delete mode 100644 gerbview/printout_control.cpp rename pcbnew/printout_controler.h => include/board_printout.h (70%) create mode 100644 pcbnew/pcbnew_printout.cpp create mode 100644 pcbnew/pcbnew_printout.h delete mode 100644 pcbnew/printout_controler.cpp diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 580fc890a2..a3cca81ee4 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -267,6 +267,7 @@ set( COMMON_SRCS bin_mod.cpp bitmap.cpp bitmap_base.cpp + board_printout.cpp build_version.cpp colors_design_settings.cpp colors.cpp diff --git a/common/board_printout.cpp b/common/board_printout.cpp new file mode 100644 index 0000000000..dc2d034ab4 --- /dev/null +++ b/common/board_printout.cpp @@ -0,0 +1,157 @@ +/* + * 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 + * + * 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 + +#include +#include +#include + +PRINT_PARAMETERS::PRINT_PARAMETERS() +{ + // TODO Millimeter2iu is depends on PCBNEW/GERBVIEW #ifdefs, so it cannot be compiled to libcommon + //m_PenDefaultSize = Millimeter2iu( 0.2 ); // A reasonable default value to draw items + // which do not have a specified line width + m_PenDefaultSize = 0.0; + m_PrintScale = 1.0; + m_XScaleAdjust = 1.0; + m_YScaleAdjust = 1.0; + m_Print_Sheet_Ref = false; + m_PrintMaskLayer.set(); + m_PrintMirror = false; + m_Print_Black_and_White = true; + m_OptionPrintPage = 1; + m_PageCount = 1; + m_ForceCentered = false; + m_Flags = 0; + m_DrillShapeOpt = PRINT_PARAMETERS::SMALL_DRILL_SHAPE; + m_PageSetupData = NULL; +} + + +BOARD_PRINTOUT::BOARD_PRINTOUT( const PRINT_PARAMETERS& aParams, const KIGFX::VIEW* aView, + const wxSize& aSheetSize, const wxString& aTitle ) : + wxPrintout( aTitle ) +{ + m_view = aView; + m_PrintParams = aParams; + m_sheetSize = aSheetSize; +} + + +void BOARD_PRINTOUT::GetPageInfo( int* minPage, int* maxPage, int* selPageFrom, int* selPageTo ) +{ + *minPage = 1; + *selPageFrom = 1; + + int icnt = 1; + + if( m_PrintParams.m_OptionPrintPage == 0 ) + icnt = m_PrintParams.m_PageCount; + + *maxPage = icnt; + *selPageTo = icnt; +} + + +bool BOARD_PRINTOUT::HasPage( int aPage ) +{ + if( aPage <= m_PrintParams.m_PageCount ) + return true; + else + return false; +} + + +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 view( m_view->DataReference() ); + + wxRect page = GetLogicalPageRect(); + galPrint->SetSheetSize( VECTOR2D( page.width / dc->GetPPI().x, page.height / dc->GetPPI().y ) ); + + view->SetGAL( gal ); + view->SetPainter( painter.get() ); + view->SetScaleLimits( 10e9, 0.0001 ); + view->SetScale( 1.0 ); + + for( int i = 0; i < KIGFX::VIEW::VIEW_MAX_LAYERS; i++ ) + { + view->SetLayerTarget( i, KIGFX::TARGET_NONCACHED ); + view->SetLayerVisible( i, true ); + } + + + BOX2I bBox; // determine printout bounding box + + if( m_PrintParams.PrintBorderAndTitleBlock() ) + { + bBox = BOX2I( VECTOR2I( 0, 0 ), VECTOR2I( m_sheetSize ) ); + view->SetLayerVisible( LAYER_WORKSHEET, true ); + } + else + { + EDA_RECT targetBbox = getBoundingBox(); + bBox = BOX2I( targetBbox.GetOrigin(), targetBbox.GetSize() ); + view->SetLayerVisible( LAYER_WORKSHEET, false ); + } + + + double scale = m_PrintParams.m_PrintScale; + + if( m_PrintParams.m_PrintScale == 0.0 ) + { + // Fit to page + scale = m_sheetSize.GetWidth() / bBox.GetWidth(); + } + else if( m_PrintParams.m_PrintScale == 1.0 ) + { + // TODO "accurate scale" that allows the user to specify custom scale + // I think it should be renamed to "custom scale", and "approx. scale 1" should be replaced with "Scale 1" + // TODO do not separate X and Y scale adjustments + scale = m_PrintParams.m_XScaleAdjust; + } + + + // TODO fix 'Preview' button + VECTOR2D nps( GetLogicalPageRect().width, GetLogicalPageRect().height ); + + galPrint->SetNativePaperSize( VECTOR2D( nps.x / dc->GetPPI().x, nps.y / dc->GetPPI().y ), + printCtx->HasNativeLandscapeRotation() ); + gal->SetLookAtPoint( bBox.Centre() ); + gal->SetZoomFactor( scale ); + + { + KIGFX::GAL_DRAWING_CONTEXT ctx( gal ); + view->Redraw(); + } +} diff --git a/gerbview/CMakeLists.txt b/gerbview/CMakeLists.txt index 9f76f86a76..ebb52e2955 100644 --- a/gerbview/CMakeLists.txt +++ b/gerbview/CMakeLists.txt @@ -38,6 +38,7 @@ set( GERBVIEW_SRCS gerber_file_image_list.cpp gerber_draw_item.cpp gerbview_layer_widget.cpp + gerbview_printout.cpp gbr_layer_box_selector.cpp X2_gerber_attributes.cpp clear_gbr_drawlayers.cpp @@ -58,7 +59,6 @@ set( GERBVIEW_SRCS menubar.cpp onleftclick.cpp onrightclick.cpp - printout_control.cpp readgerb.cpp rs274_read_XY_and_IJ_coordinates.cpp rs274d.cpp diff --git a/gerbview/dialogs/dialog_print_using_printer.cpp b/gerbview/dialogs/dialog_print_using_printer.cpp index cd3a025bed..2a7198e2ba 100644 --- a/gerbview/dialogs/dialog_print_using_printer.cpp +++ b/gerbview/dialogs/dialog_print_using_printer.cpp @@ -30,7 +30,7 @@ #include #include -#include +#include #include #include @@ -92,6 +92,12 @@ private: void SetPrintParameters(); void InitValues(); + GERBVIEW_PRINTOUT* createPrintout( const wxString& aTitle ) + { + return new GERBVIEW_PRINTOUT( m_Parent->GetGerberLayout(), s_Parameters, + m_Parent->GetGalCanvas()->GetView(), m_Parent->GetPageSettings().GetSizeIU(), aTitle ); + } + public: bool IsMirrored() { return m_Print_Mirror->IsChecked(); } bool PrintUsingSinglePage() { return true; } @@ -366,11 +372,9 @@ void DIALOG_PRINT_USING_PRINTER::OnPrintPreview( wxCommandEvent& event ) return; // Pass two printout objects: for preview, and possible printing. - wxString title = _( "Print Preview" ); + wxString title = _( "Print Preview" ); wxPrintPreview* preview = - new wxPrintPreview( new BOARD_PRINTOUT_CONTROLLER( s_Parameters, m_Parent, title ), - new BOARD_PRINTOUT_CONTROLLER( s_Parameters, m_Parent, title ), - s_printData ); + new wxPrintPreview( createPrintout( title ), createPrintout( title ), s_printData ); if( preview == NULL ) { @@ -403,13 +407,13 @@ void DIALOG_PRINT_USING_PRINTER::OnPrintButtonClick( wxCommandEvent& event ) wxPrinter printer( &printDialogData ); wxString title = _( "Print" ); - BOARD_PRINTOUT_CONTROLLER printout( s_Parameters, m_Parent, title ); + auto printout = std::unique_ptr( createPrintout( _( "Print" ) ) ); // Disable 'Print' button to prevent issuing another print // command before the previous one is finished (causes problems on Windows) ENABLER printBtnDisable( *m_buttonPrint, false ); - if( !printer.Print( this, &printout, true ) ) + if( !printer.Print( this, printout.get(), true ) ) { if( wxPrinter::GetLastError() == wxPRINTER_ERROR ) DisplayError( this, _( "There was a problem printing" ) ); diff --git a/gerbview/draw_gerber_screen.cpp b/gerbview/draw_gerber_screen.cpp index 0182d445f6..44e30bcc35 100644 --- a/gerbview/draw_gerber_screen.cpp +++ b/gerbview/draw_gerber_screen.cpp @@ -39,7 +39,7 @@ #include #include #include -#include +#include "gerbview_printout.h" void GERBVIEW_FRAME::PrintPage( wxDC* aDC, LSET aPrintMasklayer, diff --git a/gerbview/gerbview_printout.cpp b/gerbview/gerbview_printout.cpp new file mode 100644 index 0000000000..a88f3b8ef9 --- /dev/null +++ b/gerbview/gerbview_printout.cpp @@ -0,0 +1,94 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr + * Copyright (C) 1992-2016 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 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 + */ + +/** + * @file printout_control.cpp + * @brief Board print handler implementation file. + */ + + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "gerbview_printout.h" + +#include +#include +#include + + +GERBVIEW_PRINTOUT::GERBVIEW_PRINTOUT( GBR_LAYOUT* aLayout, const PRINT_PARAMETERS& aParams, + const KIGFX::VIEW* aView, const wxSize& aSheetSize, const wxString& aTitle ) : + BOARD_PRINTOUT( aParams, aView, aSheetSize, aTitle ) +{ + m_layout = aLayout; +} + + +bool GERBVIEW_PRINTOUT::OnPrintPage( int aPage ) +{ + // in gerbview, draw layers are always printed on separate pages + // because handling negative objects when using only one page is tricky + m_PrintParams.m_Flags = aPage; + + // The gerber filename of the page to print will be printed to the worksheet. + // Find this filename: + // Find the graphic layer number for the page to print + std::vector printList = m_layout->GetPrintableLayers(); + + if( printList.size() < 1 ) // Should not occur + return false; + + int graphiclayer = printList[aPage-1]; + GERBER_FILE_IMAGE_LIST& gbrImgList = GERBER_FILE_IMAGE_LIST::GetImagesList(); + GERBER_FILE_IMAGE* gbrImage = gbrImgList.GetGbrImage( graphiclayer ); + wxString gbr_filename; + + if( gbrImage ) + gbr_filename = gbrImage->m_FileName; + + DrawPage( gbr_filename, aPage, m_PrintParams.m_PageCount ); + + return true; +} + + +EDA_RECT GERBVIEW_PRINTOUT::getBoundingBox() +{ + return m_layout->ComputeBoundingBox(); +} + + +std::unique_ptr GERBVIEW_PRINTOUT::getPainter( KIGFX::GAL* aGal ) +{ + return std::unique_ptr( new KIGFX::GERBVIEW_PAINTER( aGal ) ); +} diff --git a/gerbview/gerbview_printout.h b/gerbview/gerbview_printout.h new file mode 100644 index 0000000000..f930542fe5 --- /dev/null +++ b/gerbview/gerbview_printout.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2018 CERN + * Author: Maciej Suminski + * + * 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 . + */ + +#ifndef GERBVIEW_PRINTOUT_H +#define GERBVIEW_PRINTOUT_H + +#include + +class GBR_LAYOUT; + +class GERBVIEW_PRINTOUT : public BOARD_PRINTOUT +{ +public: + GERBVIEW_PRINTOUT( GBR_LAYOUT* aLayout, const PRINT_PARAMETERS& aParams, + const KIGFX::VIEW* aView, const wxSize& aSheetSize, const wxString& aTitle ); + + bool OnPrintPage( int aPage ) override; + +protected: + EDA_RECT getBoundingBox() override; + + std::unique_ptr getPainter( KIGFX::GAL* aGal ) override; + +private: + GBR_LAYOUT* m_layout; +}; + +#endif /* GERBVIEW_PRINTOUT_H */ diff --git a/gerbview/printout_control.cpp b/gerbview/printout_control.cpp deleted file mode 100644 index 577f0a8e90..0000000000 --- a/gerbview/printout_control.cpp +++ /dev/null @@ -1,288 +0,0 @@ -/* - * This program source code file is part of KiCad, a free EDA CAD application. - * - * Copyright (C) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr - * Copyright (C) 1992-2016 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 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 - */ - -/** - * @file printout_control.cpp - * @brief Board print handler implementation file. - */ - - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - - - -PRINT_PARAMETERS::PRINT_PARAMETERS() -{ - m_PenDefaultSize = Millimeter2iu( 0.2 ); // A reasonable default value to draw items - // which do not have a specified line width - m_PrintScale = 1.0; - m_XScaleAdjust = 1.0; - m_YScaleAdjust = 1.0; - m_Print_Sheet_Ref = false; - m_PrintMaskLayer.set(); - m_PrintMirror = false; - m_Print_Black_and_White = true; - m_OptionPrintPage = 1; - m_PageCount = 1; - m_ForceCentered = false; - m_Flags = 0; - m_DrillShapeOpt = PRINT_PARAMETERS::SMALL_DRILL_SHAPE; - m_PageSetupData = NULL; -} - - -BOARD_PRINTOUT_CONTROLLER::BOARD_PRINTOUT_CONTROLLER( const PRINT_PARAMETERS& aParams, - EDA_DRAW_FRAME* aParent, - const wxString& aTitle ) : - wxPrintout( aTitle ) -{ - m_PrintParams = aParams; // Make a local copy of the print parameters. - m_Parent = aParent; -} - - -bool BOARD_PRINTOUT_CONTROLLER::OnPrintPage( int aPage ) -{ - // in gerbview, draw layers are always printed on separate pages - // because handling negative objects when using only one page is tricky - m_PrintParams.m_Flags = aPage; - - // The gerber filename of the page to print will be printed to the worksheet. - // Find this filename: - // Find the graphic layer number for the page to print - std::vector printList = - ((GERBVIEW_FRAME*) m_Parent)->GetGerberLayout()->GetPrintableLayers(); - - if( printList.size() < 1 ) // Should not occur - return false; - - int graphiclayer = printList[aPage-1]; - GERBER_FILE_IMAGE_LIST& gbrImgList = GERBER_FILE_IMAGE_LIST::GetImagesList(); - GERBER_FILE_IMAGE* gbrImage = gbrImgList.GetGbrImage( graphiclayer ); - wxString gbr_filename; - - if( gbrImage ) - gbr_filename = gbrImage->m_FileName; - - DrawPage( gbr_filename, aPage, m_PrintParams.m_PageCount ); - - return true; -} - - -void BOARD_PRINTOUT_CONTROLLER::GetPageInfo( int* minPage, int* maxPage, - int* selPageFrom, int* selPageTo ) -{ - *minPage = 1; - *selPageFrom = 1; - - int icnt = 1; - - if( m_PrintParams.m_OptionPrintPage == 0 ) - icnt = m_PrintParams.m_PageCount; - - *maxPage = icnt; - *selPageTo = icnt; -} - - -void BOARD_PRINTOUT_CONTROLLER::DrawPage( const wxString& aLayerName, - int aPageNum, int aPageCount) -{ - wxPoint offset; - double userscale; - EDA_RECT boardBoundingBox; - EDA_RECT drawRect; - wxDC* dc = GetDC(); - BASE_SCREEN* screen = m_Parent->GetScreen(); - bool printMirror = m_PrintParams.m_PrintMirror; - wxSize pageSizeIU = m_Parent->GetPageSizeIU(); - - wxBusyCursor dummy; - - boardBoundingBox = ((GERBVIEW_FRAME*) m_Parent)->GetGerberLayoutBoundingBox(); - const wxString& titleblockFilename = aLayerName; // TODO see if we uses the gerber file name - - // Use the page size as the drawing area when the board is shown or the user scale - // is less than 1. - if( m_PrintParams.PrintBorderAndTitleBlock() ) - boardBoundingBox = EDA_RECT( wxPoint( 0, 0 ), pageSizeIU ); - - // Compute the PCB size in internal units - userscale = m_PrintParams.m_PrintScale; - - if( m_PrintParams.m_PrintScale == 0 ) // fit in page option - { - if(boardBoundingBox.GetWidth() && boardBoundingBox.GetHeight()) - { - int margin = Millimeter2iu( 10.0 ); // add a margin around the drawings - double scaleX = (double)(pageSizeIU.x - (2 * margin)) / - boardBoundingBox.GetWidth(); - double scaleY = (double)(pageSizeIU.y - (2 * margin)) / - boardBoundingBox.GetHeight(); - userscale = (scaleX < scaleY) ? scaleX : scaleY; - } - else - userscale = 1.0; - } - - wxSize scaledPageSize = pageSizeIU; - drawRect.SetSize( scaledPageSize ); - scaledPageSize.x = wxRound( scaledPageSize.x / userscale ); - scaledPageSize.y = wxRound( scaledPageSize.y / userscale ); - - - if( m_PrintParams.m_PageSetupData ) - { - // Always scale to the size of the paper. - FitThisSizeToPageMargins( scaledPageSize, *m_PrintParams.m_PageSetupData ); - } - - // Compute Accurate scale 1 - if( m_PrintParams.m_PrintScale == 1.0 ) - { - // We want a 1:1 scale, regardless the page setup - // like page size, margin ... - MapScreenSizeToPaper(); // set best scale and offset (scale is not used) - int w, h; - GetPPIPrinter( &w, &h ); - double accurate_Xscale = (double) w / (IU_PER_MILS*1000); - double accurate_Yscale = (double) h / (IU_PER_MILS*1000); - - if( IsPreview() ) // Scale must take in account the DC size in Preview - { - // Get the size of the DC in pixels - wxSize PlotAreaSize; - dc->GetSize( &PlotAreaSize.x, &PlotAreaSize.y ); - GetPageSizePixels( &w, &h ); - accurate_Xscale *= (double)PlotAreaSize.x / w; - accurate_Yscale *= (double)PlotAreaSize.y / h; - } - // Fine scale adjust - accurate_Xscale *= m_PrintParams.m_XScaleAdjust; - accurate_Yscale *= m_PrintParams.m_YScaleAdjust; - - // Set print scale for 1:1 exact scale - dc->SetUserScale( accurate_Xscale, accurate_Yscale ); - } - - // Get the final size of the DC in pixels - wxSize PlotAreaSizeInPixels; - dc->GetSize( &PlotAreaSizeInPixels.x, &PlotAreaSizeInPixels.y ); - - double scalex, scaley; - dc->GetUserScale( &scalex, &scaley ); - - // In some cases the plot origin is the centre of the board outline rather than the center - // of the selected paper size. - if( m_PrintParams.CenterOnBoardOutline() ) - { - // Here we are only drawing the board and it's contents. - drawRect = boardBoundingBox; - offset.x += wxRound( (double) -scaledPageSize.x / 2.0 ); - offset.y += wxRound( (double) -scaledPageSize.y / 2.0 ); - - wxPoint center = boardBoundingBox.Centre(); - - if( printMirror ) - { - // Calculate the mirrored center of the board. - center.x = m_Parent->GetPageSizeIU().x - boardBoundingBox.Centre().x; - } - - offset += center; - } - - GRResetPenAndBrush( dc ); - - EDA_DRAW_PANEL* panel = m_Parent->GetCanvas(); - EDA_RECT tmp = *panel->GetClipBox(); - - // Set clip box to the max size - #define MAX_VALUE (INT_MAX/2) // MAX_VALUE is the max we can use in an integer - // and that allows calculations without overflow - panel->SetClipBox( EDA_RECT( wxPoint( 0, 0 ), wxSize( MAX_VALUE, MAX_VALUE ) ) ); - - screen->m_IsPrinting = true; - COLOR4D bg_color = m_Parent->GetDrawBgColor(); - - // Print frame reference, if requested, before printing draw layers - if( m_PrintParams.m_Print_Black_and_White ) - GRForceBlackPen( true ); - - if( m_PrintParams.PrintBorderAndTitleBlock() ) - { - int tempScreenNumber = screen->m_ScreenNumber; - int tempNumberOfScreens = screen->m_NumberOfScreens; - screen->m_ScreenNumber = aPageNum; - screen->m_NumberOfScreens = aPageCount; - m_Parent->DrawWorkSheet( dc, screen, m_PrintParams.m_PenDefaultSize, - IU_PER_MILS, titleblockFilename ); - screen->m_ScreenNumber = tempScreenNumber; - screen->m_NumberOfScreens = tempNumberOfScreens; - } - - if( printMirror ) - { - // To plot mirror, we reverse the x axis, and modify the plot x origin - dc->SetAxisOrientation( false, false ); - - /* Change plot offset in order to have the draw area at the same location. - * The plot origin X is just moved from 0 to PlotAreaSizeInPixels.x. - * just set offset x at PlotAreaSizeInPixels.x. - */ - int x_dc_offset = PlotAreaSizeInPixels.x; - x_dc_offset = KiROUND( x_dc_offset * userscale ); - dc->SetDeviceOrigin( x_dc_offset, 0 ); - - panel->SetClipBox( EDA_RECT( wxPoint( -MAX_VALUE / 2, -MAX_VALUE / 2 ), - panel->GetClipBox()->GetSize() ) ); - } - - // screen->m_DrawOrg = offset; - dc->SetLogicalOrigin( offset.x, offset.y ); - m_Parent->SetDrawBgColor( WHITE ); - - // Never force black pen to print draw layers - // because negative objects need a white pen, not a black pen - // B&W mode is handled in print page function - GRForceBlackPen( false ); - - m_Parent->PrintPage( dc, m_PrintParams.m_PrintMaskLayer, printMirror, &m_PrintParams ); - - m_Parent->SetDrawBgColor( bg_color ); - screen->m_IsPrinting = false; - panel->SetClipBox( tmp ); -} diff --git a/pcbnew/printout_controler.h b/include/board_printout.h similarity index 70% rename from pcbnew/printout_controler.h rename to include/board_printout.h index fcc6c194d1..5f20936375 100644 --- a/pcbnew/printout_controler.h +++ b/include/board_printout.h @@ -3,6 +3,8 @@ * * 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 * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -24,20 +26,22 @@ /** - * @file printout_controler.h + * @file board_printout.h * @brief Board print handler definition file. */ -#ifndef PRINTOUT_CONTROLLER_H -#define PRINTOUT_CONTROLLER_H +#ifndef BOARD_PRINTOUT_H +#define BOARD_PRINTOUT_H - -#include -#include #include +#include +#include -#define DEFAULT_ORIENTATION_PAPER wxLANDSCAPE // other option is wxPORTRAIT - +namespace KIGFX { +class GAL; +class VIEW; +class PAINTER; +}; /** * Class PRINT_PARAMETERS @@ -47,13 +51,15 @@ class PRINT_PARAMETERS { public: + PRINT_PARAMETERS(); + int m_PenDefaultSize; // The default value pen size to plot/print items // that have no defined pen size double m_PrintScale; // general scale when printing double m_XScaleAdjust; // fine scale adjust for X axis double m_YScaleAdjust; // fine scale adjust for Y axis bool m_Print_Sheet_Ref; // Option: print page references - LSET m_PrintMaskLayer; // Layers to print + LSET m_PrintMaskLayer; // Layers to print bool m_PrintMirror; // Option: Print mirrored bool m_Print_Black_and_White; // Option: Print in B&W or Color int m_OptionPrintPage; // Option: 0 = a layer per page, 1 = all layers at once @@ -70,12 +76,8 @@ public: DrillShapeOptT m_DrillShapeOpt; // Options to print pads and via holes -public: - PRINT_PARAMETERS(); - /** - * Function PrintBorderAndTitleBlock - * returns true if the drawing border and title block should be printed. + * Returns true if the drawing border and title block should be printed. * * For scale factors greater than one, the border is not printed because it will end up * scaling off of the page. @@ -83,56 +85,60 @@ public: bool PrintBorderAndTitleBlock() const { return m_PrintScale <= 1.0 && m_Print_Sheet_Ref; } /** - * Function CenterOnBoardOutline - * returns true if the print should be centered by the board outline instead of the + * Returns true if the print should be centered by the board outline instead of the * paper size. */ bool CenterOnBoardOutline() const { - return !PrintBorderAndTitleBlock() && ( m_ForceCentered || (m_PrintScale > 1.0) || - (m_PrintScale == 0) ); + return !PrintBorderAndTitleBlock() + && ( m_ForceCentered || ( m_PrintScale > 1.0 ) || ( m_PrintScale == 0 ) ); } }; /** - * Class BOARD_PRINTOUT_CONTROLLER + * Class BOARD_PRINTOUT * is a class derived from wxPrintout to handle the necessary information to control a printer * when printing a board */ -class BOARD_PRINTOUT_CONTROLLER : public wxPrintout +class BOARD_PRINTOUT : public wxPrintout { -private: - EDA_DRAW_FRAME* m_Parent; - PRINT_PARAMETERS m_PrintParams; - public: - BOARD_PRINTOUT_CONTROLLER( const PRINT_PARAMETERS& aParams, - EDA_DRAW_FRAME* aParent, - const wxString& aTitle ); + BOARD_PRINTOUT( const PRINT_PARAMETERS& aParams, const KIGFX::VIEW* aView, + const wxSize& aSheetSize, const wxString& aTitle ); - bool OnPrintPage( int aPage ) override; - - bool HasPage( int aPage ) override - { - if( aPage <= m_PrintParams.m_PageCount ) - return true; - else - return false; - } + virtual ~BOARD_PRINTOUT() {} void GetPageInfo( int* minPage, int* maxPage, int* selPageFrom, int* selPageTo ) override; + bool HasPage( int aPage ) override; + /** - * Print a page ( or a set of pages ). + * Print a page (or a set of pages). * Note: this function prepare print parameters for the function * which actually print the draw layers. * @param aLayerName = a text which can be printed as layer name * @param aPageNum = the number of the current page (only used to print this value) * @param aPageCount = the number of pages to ptint (only used to print this value) */ - void DrawPage( const wxString& aLayerName = wxEmptyString, - int aPageNum = 1, int aPageCount = 1 ); + virtual void DrawPage( const wxString& aLayerName = wxEmptyString, + int aPageNum = 1, int aPageCount = 1 ); + +protected: + ///> Returns bounding box of the printed objects (excluding worksheet frame) + virtual EDA_RECT getBoundingBox() = 0; + + ///> Returns a PAINTER instance used to draw the items. + virtual std::unique_ptr getPainter( KIGFX::GAL* aGal ) = 0; + + ///> Source VIEW object (note that actual printing only refers to this object) + const KIGFX::VIEW* m_view; + + ///> Printout parameters + PRINT_PARAMETERS m_PrintParams; + + ///> Sheet size expressed in internal units + wxSize m_sheetSize; }; -#endif // PRINTOUT_CONTROLLER_H +#endif // BOARD_PRINTOUT_H diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index efe36a5fe2..6f3a16be40 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -286,12 +286,12 @@ set( PCBNEW_CLASS_SRCS # pcb_view.cpp pcb_edit_frame.cpp pcbnew_config.cpp + pcbnew_printout.cpp pcb_legacy_draw_utils.cpp pcbplot.cpp plot_board_layers.cpp plot_brditems_plotter.cpp print_board_functions.cpp - printout_controler.cpp ratsnest.cpp specctra_import_export/specctra.cpp specctra_import_export/specctra_export.cpp diff --git a/pcbnew/dialogs/dialog_print_for_modedit.cpp b/pcbnew/dialogs/dialog_print_for_modedit.cpp index a349f7992a..e7197a25a1 100644 --- a/pcbnew/dialogs/dialog_print_for_modedit.cpp +++ b/pcbnew/dialogs/dialog_print_for_modedit.cpp @@ -34,7 +34,7 @@ #include #include -#include +#include #include static double s_scaleList[] = @@ -82,6 +82,12 @@ private: } void InitValues( ); + + PCBNEW_PRINTOUT* createPrintout( const wxString& aTitle ) + { + return new PCBNEW_PRINTOUT( m_parent->GetBoard(), s_Parameters, + m_parent->GetGalCanvas()->GetView(), m_parent->GetPageSettings().GetSizeIU(), aTitle ); + } }; @@ -179,11 +185,9 @@ void DIALOG_PRINT_FOR_MODEDIT::OnPrintPreview( wxCommandEvent& event ) s_Parameters.m_PrintScale = s_scaleList[m_ScaleOption->GetSelection()]; // Pass two printout objects: for preview, and possible printing. - wxString title = _( "Print Preview" ); + wxString title = _( "Print Preview" ); wxPrintPreview* preview = - new wxPrintPreview( new BOARD_PRINTOUT_CONTROLLER( s_Parameters, m_parent, title ), - new BOARD_PRINTOUT_CONTROLLER( s_Parameters, m_parent, title ), - s_PrintData ); + new wxPrintPreview( createPrintout( title ), createPrintout( title ), s_PrintData ); if( preview == NULL ) { @@ -233,13 +237,13 @@ void DIALOG_PRINT_FOR_MODEDIT::OnPrintButtonClick( wxCommandEvent& event ) wxPrintDialogData printDialogData( *s_PrintData ); wxPrinter printer( &printDialogData ); - BOARD_PRINTOUT_CONTROLLER printout( s_Parameters, m_parent, _( "Print Footprint" ) ); + auto printout = std::unique_ptr( createPrintout( _( "Print Footprint" ) ) ); // Disable 'Print' button to prevent issuing another print // command before the previous one is finished (causes problems on Windows) ENABLER printBtnDisable( *m_buttonPrint, false ); - if( !printer.Print( this, &printout, true ) ) + if( !printer.Print( this, printout.get(), true ) ) { if( wxPrinter::GetLastError() == wxPRINTER_ERROR ) DisplayError( this, _( "There was a problem printing." ) ); diff --git a/pcbnew/dialogs/dialog_print_using_printer.cpp b/pcbnew/dialogs/dialog_print_using_printer.cpp index cd54437829..a19caa16a3 100644 --- a/pcbnew/dialogs/dialog_print_using_printer.cpp +++ b/pcbnew/dialogs/dialog_print_using_printer.cpp @@ -22,16 +22,13 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -// Set this to 1 if you want to test PostScript printing under MSW. -//#define wxTEST_POSTSCRIPT_IN_MSW 1 - #include #include #include #include #include #include -#include +#include #include #include #include @@ -71,7 +68,6 @@ public: ~DIALOG_PRINT_USING_PRINTER() override; private: - PCB_EDIT_FRAME* m_parent; wxConfigBase* m_config; // the list of existing board layers in wxCheckListBox, with the board layers id: @@ -89,6 +85,12 @@ private: void SetPrintParameters(); int SetLayerSetFromListSelection(); + + PCBNEW_PRINTOUT* createPrintout( const wxString& aTitle ) + { + return new PCBNEW_PRINTOUT( m_parent->GetBoard(), s_Parameters, + m_parent->GetGalCanvas()->GetView(), m_parent->GetPageSettings().GetSizeIU(), aTitle ); + } }; @@ -375,7 +377,7 @@ void DIALOG_PRINT_USING_PRINTER::OnPageSetup( wxCommandEvent& event ) void DIALOG_PRINT_USING_PRINTER::OnPrintPreview( wxCommandEvent& event ) { - SetPrintParameters( ); + SetPrintParameters(); // If no layer selected, we have no plot. prompt user if it happens // because he could think there is a bug in Pcbnew: @@ -386,11 +388,9 @@ void DIALOG_PRINT_USING_PRINTER::OnPrintPreview( wxCommandEvent& event ) } // Pass two printout objects: for preview, and possible printing. - wxString title = _( "Print Preview" ); + wxString title = _( "Print Preview" ); wxPrintPreview* preview = - new wxPrintPreview( new BOARD_PRINTOUT_CONTROLLER( s_Parameters, m_parent, title ), - new BOARD_PRINTOUT_CONTROLLER( s_Parameters, m_parent, title ), - s_PrintData ); + new wxPrintPreview( createPrintout( title ), createPrintout( title ), s_PrintData ); preview->SetZoom( 100 ); @@ -425,7 +425,7 @@ void DIALOG_PRINT_USING_PRINTER::OnPrintButtonClick( wxCommandEvent& event ) // because he could think there is a bug in Pcbnew: if( s_Parameters.m_PrintMaskLayer == 0 ) { - DisplayError( this, _( "No layer selected." ) ); + DisplayError( this, _( "No layer selected" ) ); return; } @@ -433,14 +433,13 @@ void DIALOG_PRINT_USING_PRINTER::OnPrintButtonClick( wxCommandEvent& event ) printDialogData.SetMaxPage( s_Parameters.m_PageCount ); wxPrinter printer( &printDialogData ); - wxString title = _( "Print" ); - BOARD_PRINTOUT_CONTROLLER printout( s_Parameters, m_parent, title ); + auto printout = std::unique_ptr( createPrintout( _( "Print" ) ) ); // Disable 'Print' button to prevent issuing another print // command before the previous one is finished (causes problems on Windows) ENABLER printBtnDisable( *m_sdbSizer1OK, false ); - if( !printer.Print( this, &printout, true ) ) + if( !printer.Print( this, printout.get(), true ) ) { if( wxPrinter::GetLastError() == wxPRINTER_ERROR ) DisplayError( this, _( "There was a problem printing." ) ); diff --git a/pcbnew/pcbnew_printout.cpp b/pcbnew/pcbnew_printout.cpp new file mode 100644 index 0000000000..f56023340e --- /dev/null +++ b/pcbnew/pcbnew_printout.cpp @@ -0,0 +1,92 @@ +/* + * 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 + * Author: Tomasz Wlostowski + * + * 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 "pcbnew_printout.h" +#include + +#include + +PCBNEW_PRINTOUT::PCBNEW_PRINTOUT( BOARD* aBoard, const PRINT_PARAMETERS& aParams, + const KIGFX::VIEW* aView, const wxSize& aSheetSize, const wxString& aTitle ) : + BOARD_PRINTOUT( aParams, aView, aSheetSize, aTitle ) +{ + m_board = aBoard; +} + + +bool PCBNEW_PRINTOUT::OnPrintPage( int aPage ) +{ + LSET lset = m_PrintParams.m_PrintMaskLayer; + int pageCount = lset.count(); + wxString layer; + PCB_LAYER_ID extractLayer; + + // compute layer mask from page number if we want one page per layer + if( m_PrintParams.m_OptionPrintPage == 0 ) // One page per layer + { + // This sequence is TBD, call a different + // sequencer if needed, such as Seq(). Could not find documentation on + // page order. + LSEQ seq = lset.UIOrder(); + + // aPage starts at 1, not 0 + if( unsigned( aPage - 1 ) < seq.size() ) + m_PrintParams.m_PrintMaskLayer = LSET( seq[aPage - 1] ); + } + + if( !m_PrintParams.m_PrintMaskLayer.any() ) + return false; + + extractLayer = m_PrintParams.m_PrintMaskLayer.ExtractLayer(); + + if( extractLayer == UNDEFINED_LAYER ) + layer = _( "Multiple Layers" ); + else + layer = LSET::Name( extractLayer ); + + // In Pcbnew we can want the layer EDGE always printed + if( m_PrintParams.m_Flags == 1 ) + m_PrintParams.m_PrintMaskLayer.set( Edge_Cuts ); + + DrawPage( layer, aPage, pageCount ); + + m_PrintParams.m_PrintMaskLayer = lset; + + return true; +} + + +EDA_RECT PCBNEW_PRINTOUT::getBoundingBox() +{ + return m_board->ComputeBoundingBox(); +} + + +std::unique_ptr PCBNEW_PRINTOUT::getPainter( KIGFX::GAL* aGal ) +{ + return std::unique_ptr( new KIGFX::PCB_PAINTER( aGal ) ); +} diff --git a/pcbnew/pcbnew_printout.h b/pcbnew/pcbnew_printout.h new file mode 100644 index 0000000000..dacff0ec53 --- /dev/null +++ b/pcbnew/pcbnew_printout.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2018 CERN + * Author: Maciej Suminski + * + * 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 . + */ + +#ifndef PCBNEW_PRINTOUT_H +#define PCBNEW_PRINTOUT_H + +#include + +class BOARD; + +class PCBNEW_PRINTOUT : public BOARD_PRINTOUT +{ +public: + PCBNEW_PRINTOUT( BOARD* aBoard, const PRINT_PARAMETERS& aParams, + const KIGFX::VIEW* aView, const wxSize& aSheetSize, const wxString& aTitle ); + + bool OnPrintPage( int aPage ) override; + +protected: + EDA_RECT getBoundingBox() override; + + std::unique_ptr getPainter( KIGFX::GAL* aGal ) override; + +private: + BOARD* m_board; +}; + +#endif /* PCBNEW_PRINTOUT_H */ diff --git a/pcbnew/print_board_functions.cpp b/pcbnew/print_board_functions.cpp index 8759797c1e..8a2fb4eb44 100644 --- a/pcbnew/print_board_functions.cpp +++ b/pcbnew/print_board_functions.cpp @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/pcbnew/printout_controler.cpp b/pcbnew/printout_controler.cpp deleted file mode 100644 index af6ed1ca00..0000000000 --- a/pcbnew/printout_controler.cpp +++ /dev/null @@ -1,366 +0,0 @@ -/* - * 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-2018 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 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 - */ - -/** - * @file printout_controler.cpp - * @brief Board print handler implementation file. - */ - - -// Set this to 1 if you want to test PostScript printing under MSW. -#define wxTEST_POSTSCRIPT_IN_MSW 1 - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - - -PRINT_PARAMETERS::PRINT_PARAMETERS() -{ - m_PenDefaultSize = Millimeter2iu( 0.2 ); // A reasonable default value to draw items - // which do not have a specified line width - m_PrintScale = 1.0; - m_XScaleAdjust = 1.0; - m_YScaleAdjust = 1.0; - m_Print_Sheet_Ref = false; - m_PrintMaskLayer.set(); - m_PrintMirror = false; - m_Print_Black_and_White = true; - m_OptionPrintPage = 1; - m_PageCount = 1; - m_ForceCentered = false; - m_Flags = 0; - m_DrillShapeOpt = PRINT_PARAMETERS::SMALL_DRILL_SHAPE; - m_PageSetupData = NULL; -} - - -BOARD_PRINTOUT_CONTROLLER::BOARD_PRINTOUT_CONTROLLER( const PRINT_PARAMETERS& aParams, - EDA_DRAW_FRAME* aParent, - const wxString& aTitle ) : - wxPrintout( aTitle ) -{ - m_PrintParams = aParams; // Make a local copy of the print parameters. - m_Parent = aParent; -} - - -bool BOARD_PRINTOUT_CONTROLLER::OnPrintPage( int aPage ) -{ - LSET lset = m_PrintParams.m_PrintMaskLayer; - int pageCount = lset.count(); - wxString layer; - PCB_LAYER_ID extractLayer; - - // compute layer mask from page number if we want one page per layer - if( m_PrintParams.m_OptionPrintPage == 0 ) // One page per layer - { - // This sequence is TBD, call a different - // sequencer if needed, such as Seq(). Could not find documentation on - // page order. - LSEQ seq = lset.UIOrder(); - - // aPage starts at 1, not 0 - if( unsigned( aPage-1 ) < seq.size() ) - m_PrintParams.m_PrintMaskLayer = LSET( seq[aPage-1] ); - } - - if( !m_PrintParams.m_PrintMaskLayer.any() ) - return false; - - extractLayer = m_PrintParams.m_PrintMaskLayer.ExtractLayer(); - if( extractLayer == UNDEFINED_LAYER ) - layer = _( "Multiple Layers" ); - else - layer = LSET::Name( extractLayer ); - - // In Pcbnew we can want the layer EDGE always printed - if( m_PrintParams.m_Flags == 1 ) - m_PrintParams.m_PrintMaskLayer.set( Edge_Cuts ); - - DrawPage( layer, aPage, pageCount ); - - m_PrintParams.m_PrintMaskLayer = lset; - - return true; -} - - -void BOARD_PRINTOUT_CONTROLLER::GetPageInfo( int* minPage, int* maxPage, - int* selPageFrom, int* selPageTo ) -{ - *minPage = 1; - *selPageFrom = 1; - - int icnt = 1; - - if( m_PrintParams.m_OptionPrintPage == 0 ) - icnt = m_PrintParams.m_PageCount; - - *maxPage = icnt; - *selPageTo = icnt; -} - - -void BOARD_PRINTOUT_CONTROLLER::DrawPage( const wxString& aLayerName, int aPageNum, int aPageCount ) -{ - wxPoint offset; - double userscale; - EDA_RECT boardBoundingBox; - EDA_RECT drawRect; - wxDC* dc = GetDC(); - BASE_SCREEN* screen = m_Parent->GetScreen(); - bool printMirror = m_PrintParams.m_PrintMirror; - wxSize pageSizeIU = m_Parent->GetPageSizeIU(); - int tempScreenNumber; - int tempNumberOfScreens; - - wxBusyCursor dummy; - - BOARD* brd = ((PCB_BASE_FRAME*) m_Parent)->GetBoard(); - boardBoundingBox = brd->ComputeBoundingBox(); - const wxString& titleblockFilename = brd->GetFileName(); - - // Use the page size as the drawing area when the board is shown or the user scale - // is less than 1. - if( m_PrintParams.PrintBorderAndTitleBlock() ) - boardBoundingBox = EDA_RECT( wxPoint( 0, 0 ), pageSizeIU ); - - wxLogTrace( tracePrinting, wxT( "Drawing bounding box: x=%d, y=%d, w=%d, h=%d" ), - boardBoundingBox.GetX(), boardBoundingBox.GetY(), - boardBoundingBox.GetWidth(), boardBoundingBox.GetHeight() ); - - // Compute the PCB size in internal units - userscale = m_PrintParams.m_PrintScale; - - if( m_PrintParams.m_PrintScale == 0 ) // fit in page option - { - if( boardBoundingBox.GetWidth() && boardBoundingBox.GetHeight() ) - { - int margin = Millimeter2iu( 10.0 ); // add a margin around the drawings - double scaleX = (double)(pageSizeIU.x - (2 * margin)) / - boardBoundingBox.GetWidth(); - double scaleY = (double)(pageSizeIU.y - (2 * margin)) / - boardBoundingBox.GetHeight(); - userscale = (scaleX < scaleY) ? scaleX : scaleY; - } - else - userscale = 1.0; - } - - wxSize scaledPageSize = pageSizeIU; - drawRect.SetSize( scaledPageSize ); - scaledPageSize.x = wxRound( scaledPageSize.x / userscale ); - scaledPageSize.y = wxRound( scaledPageSize.y / userscale ); - - - if( m_PrintParams.m_PageSetupData ) - { - wxLogTrace( tracePrinting, wxT( "Fit size to page margins: x=%d, y=%d" ), - scaledPageSize.x, scaledPageSize.y ); - - // Always scale to the size of the paper. - FitThisSizeToPageMargins( scaledPageSize, *m_PrintParams.m_PageSetupData ); - } - - // Compute Accurate scale 1 - if( m_PrintParams.m_PrintScale == 1.0 ) - { - // We want a 1:1 scale, regardless the page setup - // like page size, margin ... - MapScreenSizeToPaper(); // set best scale and offset (scale is not used) - int w, h; - GetPPIPrinter( &w, &h ); - double accurate_Xscale = (double) w / (IU_PER_MILS*1000); - double accurate_Yscale = (double) h / (IU_PER_MILS*1000); - - if( IsPreview() ) // Scale must take in account the DC size in Preview - { - // Get the size of the DC in pixels - wxSize PlotAreaSize; - dc->GetSize( &PlotAreaSize.x, &PlotAreaSize.y ); - GetPageSizePixels( &w, &h ); - accurate_Xscale *= (double)PlotAreaSize.x / w; - accurate_Yscale *= (double)PlotAreaSize.y / h; - } - // Fine scale adjust - accurate_Xscale *= m_PrintParams.m_XScaleAdjust; - accurate_Yscale *= m_PrintParams.m_YScaleAdjust; - - // Set print scale for 1:1 exact scale - dc->SetUserScale( accurate_Xscale, accurate_Yscale ); - } - - // Get the final size of the DC in pixels - wxSize PlotAreaSizeInPixels; - dc->GetSize( &PlotAreaSizeInPixels.x, &PlotAreaSizeInPixels.y ); - wxLogTrace( tracePrinting, wxT( "Plot area in pixels: x=%d, y=%d" ), - PlotAreaSizeInPixels.x, PlotAreaSizeInPixels.y ); - double scalex, scaley; - dc->GetUserScale( &scalex, &scaley ); - wxLogTrace( tracePrinting, wxT( "DC user scale: x=%g, y=%g" ), - scalex, scaley ); - - wxSize PlotAreaSizeInUserUnits; - PlotAreaSizeInUserUnits.x = KiROUND( PlotAreaSizeInPixels.x / scalex ); - PlotAreaSizeInUserUnits.y = KiROUND( PlotAreaSizeInPixels.y / scaley ); - wxLogTrace( tracePrinting, wxT( "Scaled plot area in user units: x=%d, y=%d" ), - PlotAreaSizeInUserUnits.x, PlotAreaSizeInUserUnits.y ); - - // In module editor, the module is located at 0,0 but for printing - // it is moved to pageSizeIU.x/2, pageSizeIU.y/2. - // So the equivalent board must be moved to the center of the page: - if( m_Parent->IsType( FRAME_PCB_MODULE_EDITOR ) ) - { - boardBoundingBox.Move( wxPoint( pageSizeIU.x/2, pageSizeIU.y/2 ) ); - } - - // In some cases the plot origin is the centre of the board outline rather than the center - // of the selected paper size. - if( m_PrintParams.CenterOnBoardOutline() ) - { - // Here we are only drawing the board and it's contents. - drawRect = boardBoundingBox; - offset.x += wxRound( (double) -scaledPageSize.x / 2.0 ); - offset.y += wxRound( (double) -scaledPageSize.y / 2.0 ); - - wxPoint center = boardBoundingBox.Centre(); - - if( printMirror ) - { - // Calculate the mirrored center of the board. - center.x = m_Parent->GetPageSizeIU().x - boardBoundingBox.Centre().x; - } - - offset += center; - } - - GRResetPenAndBrush( dc ); - - EDA_DRAW_PANEL* panel = m_Parent->GetCanvas(); - EDA_RECT tmp = *panel->GetClipBox(); - - // Set clip box to the max size - #define MAX_VALUE (INT_MAX/2) // MAX_VALUE is the max we can use in an integer - // and that allows calculations without overflow - panel->SetClipBox( EDA_RECT( wxPoint( 0, 0 ), wxSize( MAX_VALUE, MAX_VALUE ) ) ); - - screen->m_IsPrinting = true; - COLOR4D bg_color = m_Parent->GetDrawBgColor(); - - // Print frame reference, if requested, before - if( m_PrintParams.m_Print_Black_and_White ) - GRForceBlackPen( true ); - - if( m_PrintParams.PrintBorderAndTitleBlock() ) - { - tempScreenNumber = screen->m_ScreenNumber; - tempNumberOfScreens = screen->m_NumberOfScreens; - screen->m_ScreenNumber = aPageNum; - screen->m_NumberOfScreens = aPageCount; - m_Parent->DrawWorkSheet( dc, screen, m_PrintParams.m_PenDefaultSize, - IU_PER_MILS, titleblockFilename, aLayerName ); - screen->m_ScreenNumber = tempScreenNumber; - screen->m_NumberOfScreens = tempNumberOfScreens; - } - - if( printMirror ) - { - // To plot mirror, we reverse the x axis, and modify the plot x origin - dc->SetAxisOrientation( false, false); - - /* Plot offset x is moved by the x plot area size in order to have - * the old draw area in the new draw area, because the draw origin has not moved - * (this is the upper left corner) but the X axis is reversed, therefore the plotting area - * is the x coordinate values from - PlotAreaSize.x to 0 */ - int x_dc_offset = PlotAreaSizeInPixels.x; - x_dc_offset = KiROUND( x_dc_offset * userscale ); - dc->SetDeviceOrigin( x_dc_offset, 0 ); - - wxLogTrace( tracePrinting, wxT( "Device origin: x=%d, y=%d" ), - x_dc_offset, 0 ); - - panel->SetClipBox( EDA_RECT( wxPoint( -MAX_VALUE/2, -MAX_VALUE/2 ), - panel->GetClipBox()->GetSize() ) ); - } - - // screen->m_DrawOrg = offset; - dc->SetLogicalOrigin( offset.x, offset.y ); - - wxLogTrace( tracePrinting, wxT( "Logical origin: x=%d, y=%d" ), - offset.x, offset.y ); - -#if defined(wxUSE_LOG_TRACE) && defined( DEBUG ) - wxRect paperRect = GetPaperRectPixels(); - wxLogTrace( tracePrinting, wxT( "Paper rectangle: left=%d, top=%d, " - "right=%d, bottom=%d" ), - paperRect.GetLeft(), paperRect.GetTop(), paperRect.GetRight(), - paperRect.GetBottom() ); - - int devLeft = dc->LogicalToDeviceX( drawRect.GetX() ); - int devTop = dc->LogicalToDeviceY( drawRect.GetY() ); - int devRight = dc->LogicalToDeviceX( drawRect.GetRight() ); - int devBottom = dc->LogicalToDeviceY( drawRect.GetBottom() ); - wxLogTrace( tracePrinting, wxT( "Final device rectangle: left=%d, top=%d, " - "right=%d, bottom=%d\n" ), - devLeft, devTop, devRight, devBottom ); -#endif - - m_Parent->SetDrawBgColor( WHITE ); - - /* when printing in color mode, we use the graphic OR mode that gives the same look as - * the screen but because the background is white when printing, we must use a trick: - * In order to plot on a white background in OR mode we must: - * 1 - Plot all items in black, this creates a local black background - * 2 - Plot in OR mode on black "local" background - */ - if( !m_PrintParams.m_Print_Black_and_White ) - { - // Creates a "local" black background - GRForceBlackPen( true ); - m_Parent->PrintPage( dc, m_PrintParams.m_PrintMaskLayer, - printMirror, &m_PrintParams ); - GRForceBlackPen( false ); - } - else - GRForceBlackPen( true ); - - - m_Parent->PrintPage( dc, m_PrintParams.m_PrintMaskLayer, printMirror, - &m_PrintParams ); - - m_Parent->SetDrawBgColor( bg_color ); - screen->m_IsPrinting = false; - panel->SetClipBox( tmp ); - GRForceBlackPen( false ); -}