KiCad PCB EDA Suite
plot_schematic_PDF.cpp
Go to the documentation of this file.
1 
4 /*
5  * This program source code file is part of KiCad, a free EDA CAD application.
6  *
7  * Copyright (C) 1992-2010 Jean-Pierre Charras jp.charras at wanadoo.fr
8  * Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, you may find one here:
22  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
23  * or you may search the http://www.gnu.org website for the version 2 license,
24  * or you may write to the Free Software Foundation, Inc.,
25  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
26  */
27 
28 #include <plotters_specific.h>
29 #include <sch_edit_frame.h>
30 #include <base_units.h>
31 #include <locale_io.h>
32 #include <sch_sheet_path.h>
33 #include <sch_painter.h>
34 #include <schematic.h>
35 #include <pgm_base.h>
36 #include <project.h>
37 #include <general.h>
39 
40 #include <reporter.h>
41 
42 #include <dialog_plot_schematic.h>
43 #include <wx_html_report_panel.h>
44 
45 void DIALOG_PLOT_SCHEMATIC::createPDFFile( bool aPlotAll, bool aPlotDrawingSheet,
46  RENDER_SETTINGS* aRenderSettings )
47 {
48  SCH_SHEET_PATH oldsheetpath = m_parent->GetCurrentSheet(); // sheetpath is saved here
49 
50  /* When printing all pages, the printed page is not the current page. In
51  * complex hierarchies, we must update component references and others
52  * parameters in the given printed SCH_SCREEN, accordant to the sheet path
53  * because in complex hierarchies a SCH_SCREEN (a drawing ) is shared
54  * between many sheets and component references depend on the actual sheet
55  * path used
56  */
57  SCH_SHEET_LIST sheetList;
58 
59  if( aPlotAll )
60  {
61  sheetList.BuildSheetList( &m_parent->Schematic().Root(), true );
62  sheetList.SortByPageNumbers();
63  }
64  else
65  {
66  sheetList.push_back( m_parent->GetCurrentSheet() );
67  }
68 
69  // Allocate the plotter and set the job level parameter
70  PDF_PLOTTER* plotter = new PDF_PLOTTER();
71  plotter->SetRenderSettings( aRenderSettings );
72  plotter->SetColorMode( getModeColor() );
73  plotter->SetCreator( wxT( "Eeschema-PDF" ) );
74  plotter->SetTitle( m_parent->GetTitleBlock().GetTitle() );
75 
76  wxString msg;
77  wxFileName plotFileName;
78  REPORTER& reporter = m_MessagesBox->Reporter();
79  LOCALE_IO toggle; // Switch the locale to standard C
80 
81  for( unsigned i = 0; i < sheetList.size(); i++ )
82  {
83  m_parent->SetCurrentSheet( sheetList[i] );
87 
88  if( i == 0 )
89  {
90 
91  try
92  {
93  wxString fname = m_parent->GetUniqueFilenameForCurrentSheet();
94  // The sub sheet can be in a sub_hierarchy, but we plot the file in the
95  // main project folder (or the folder specified by the caller),
96  // so replace separators to create a unique filename:
97  fname.Replace("/", "_" );
98  fname.Replace("\\", "_" );
99  wxString ext = PDF_PLOTTER::GetDefaultFileExtension();
100  plotFileName = createPlotFileName( fname, ext, &reporter );
101 
102  if( !plotter->OpenFile( plotFileName.GetFullPath() ) )
103  {
104  msg.Printf( _( "Unable to create file \"%s\".\n" ), plotFileName.GetFullPath() );
105  reporter.Report( msg, RPT_SEVERITY_ERROR );
106  delete plotter;
107  return;
108  }
109 
110  // Open the plotter and do the first page
111  setupPlotPagePDF( plotter, screen );
112  plotter->StartPlot();
113  }
114  catch( const IO_ERROR& e )
115  {
116  // Cannot plot PDF file
117  msg.Printf( wxT( "PDF Plotter exception: %s" ), e.What() );
118  reporter.Report( msg, RPT_SEVERITY_ERROR );
119 
120  restoreEnvironment( plotter, oldsheetpath );
121  return;
122  }
123 
124  }
125  else
126  {
127  /* For the following pages you need to close the (finished) page,
128  * reconfigure, and then start a new one */
129  plotter->ClosePage();
130  setupPlotPagePDF( plotter, screen );
131  plotter->StartPage();
132  }
133 
134  plotOneSheetPDF( plotter, screen, aPlotDrawingSheet );
135  }
136 
137  // Everything done, close the plot and restore the environment
138  msg.Printf( _( "Plot: \"%s\" OK.\n" ), plotFileName.GetFullPath() );
139  reporter.Report( msg, RPT_SEVERITY_ACTION );
140 
141  restoreEnvironment( plotter, oldsheetpath );
142 }
143 
144 
146  SCH_SHEET_PATH& aOldsheetpath )
147 {
148  aPlotter->EndPlot();
149  delete aPlotter;
150 
151  // Restore the previous sheet
152  m_parent->SetCurrentSheet( aOldsheetpath );
155 }
156 
157 
159  bool aPlotDrawingSheet )
160 {
161  if( m_plotBackgroundColor->GetValue() )
162  {
163  aPlotter->SetColor( aPlotter->RenderSettings()->GetBackgroundColor() );
164  wxPoint end( aPlotter->PageSettings().GetWidthIU(),
165  aPlotter->PageSettings().GetHeightIU() );
166  aPlotter->Rect( wxPoint( 0, 0 ), end, FILL_TYPE::FILLED_SHAPE, 1.0 );
167  }
168 
169  if( aPlotDrawingSheet )
170  {
172 
173  if( aPlotter->GetColorMode() )
175 
176  PlotDrawingSheet( aPlotter, &aScreen->Schematic()->Prj(), m_parent->GetTitleBlock(),
177  m_parent->GetPageSettings(), aScreen->GetPageNumber(),
178  aScreen->GetPageCount(), m_parent->GetScreenDesc(),
179  aScreen->GetFileName(), color, aScreen->GetVirtualPageNumber() == 1 );
180  }
181 
182  aScreen->Plot( aPlotter );
183 }
184 
185 
187 {
188  PAGE_INFO plotPage; // page size selected to plot
189  // Considerations on page size and scaling requests
190  const PAGE_INFO& actualPage = aScreen->GetPageSettings(); // page size selected in schematic
191 
192  switch( m_pageSizeSelect )
193  {
194  case PAGE_SIZE_A:
195  plotPage.SetType( wxT( "A" ) );
196  plotPage.SetPortrait( actualPage.IsPortrait() );
197  break;
198 
199  case PAGE_SIZE_A4:
200  plotPage.SetType( wxT( "A4" ) );
201  plotPage.SetPortrait( actualPage.IsPortrait() );
202  break;
203 
204  case PAGE_SIZE_AUTO:
205  default:
206  plotPage = actualPage;
207  break;
208  }
209 
210  double scalex = (double) plotPage.GetWidthMils() / actualPage.GetWidthMils();
211  double scaley = (double) plotPage.GetHeightMils() / actualPage.GetHeightMils();
212  double scale = std::min( scalex, scaley );
213  aPlotter->SetPageSettings( plotPage );
214  // Currently, plot units are in decimil
215  aPlotter->SetViewport( wxPoint( 0, 0 ), IU_PER_MILS/10, scale, false );
216 }
217 
static wxString GetDefaultFileExtension()
void SetCurrentSheet(const SCH_SHEET_PATH &aSheet)
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
const wxString & GetFileName() const
Definition: sch_screen.h:192
virtual void SetCreator(const wxString &aCreator)
Definition: plotter.h:172
void plotOneSheetPDF(PLOTTER *aPlotter, SCH_SCREEN *aScreen, bool aPlotDrawingSheet)
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition: locale_io.h:40
Container for all the knowledge about how graphical objects are drawn on any output surface/device.
virtual bool EndPlot() override
Implementation of conversion functions that require both schematic and board internal units.
Plotting engines (PostScript, Gerber, HPGL and DXF)
virtual const COLOR4D & GetBackgroundColor()=0
Return current background color settings.
virtual void SetColor(COLOR4D color)=0
int GetHeightMils() const
Definition: page_info.h:133
virtual void Rect(const wxPoint &p1, const wxPoint &p2, FILL_TYPE fill, int width=USE_DEFAULT_LINE_WIDTH)=0
virtual void StartPage()
Starts a new page in the PDF document.
virtual void SetTitle(const wxString &aTitle)
Definition: plotter.h:174
virtual void SetColorMode(bool aColorMode)
Plot in B/W or color.
Definition: plotter.h:151
int color
Definition: DXF_plotter.cpp:60
int GetVirtualPageNumber() const
Definition: base_screen.h:79
void SetRenderSettings(RENDER_SETTINGS *aSettings)
Definition: plotter.h:154
bool SetType(const wxString &aStandardPageDescriptionName, bool aIsPortrait=false)
Set the name of the page type and also the sizes and margins commonly associated with that type name.
Definition: page_info.cpp:119
const COLOR4D & GetLayerColor(int aLayer) const
Return the color used to draw a layer.
int GetPageCount() const
Definition: base_screen.h:76
Definition: color4d.h:44
void createPDFFile(bool aPlotAll, bool aPlotDrawingSheet, RENDER_SETTINGS *aRenderSettings)
A pure virtual class used to derive REPORTER objects from.
Definition: reporter.h:64
void UpdateAllScreenReferences()
Update all the symbol references for this sheet path.
const PAGE_INFO & GetPageSettings() const
Definition: sch_screen.h:187
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)=0
Report a string with a given severity.
void restoreEnvironment(PDF_PLOTTER *aPlotter, SCH_SHEET_PATH &aOldsheetpath)
Everything done, close the plot and restore the environment.
const wxString & GetPageNumber() const
Definition: base_screen.cpp:78
void setupPlotPagePDF(PLOTTER *aPlotter, SCH_SCREEN *aScreen)
wxString GetScreenDesc() const override
Return a human-readable description of the current screen.
virtual void ClosePage()
Close the current page in the PDF document (and emit its compressed stream)
wxFileName createPlotFileName(const wxString &aPlotFileName, const wxString &aExtension, REPORTER *aReporter=NULL)
Create a file name with an absolute path name.
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:29
Describe the page size and margins of a paper page on which to eventually print or plot.
Definition: page_info.h:53
void BuildSheetList(SCH_SHEET *aSheet, bool aCheckIntegrity)
Build the list of sheets and their sheet path from aSheet.
SCHEMATIC & Schematic() const
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
virtual void SetViewport(const wxPoint &aOffset, double aIusPerDecimil, double aScale, bool aMirror)=0
Set the plot offset and scaling for the current plot.
void Plot(PLOTTER *aPlotter)
Plot all the schematic objects to aPlotter.
Definition: sch_screen.cpp:778
PROJECT & Prj() const override
Return a reference to the project this schematic is part of.
Definition: schematic.h:99
const PAGE_INFO & GetPageSettings() const override
Base plotter engine class.
Definition: plotter.h:121
SCH_SHEET & Root() const
Definition: schematic.h:116
RENDER_SETTINGS * RenderSettings()
Definition: plotter.h:155
const int scale
see class PGM_BASE
SCH_SCREEN * LastScreen()
void SetSheetNumberAndCount()
Set the m_ScreenNumber and m_NumberOfScreens members for screens.
bool IsPortrait() const
Definition: page_info.h:117
#define _(s)
Definition: 3d_actions.cpp:33
SCHEMATIC * Schematic() const
Definition: sch_screen.cpp:87
const TITLE_BLOCK & GetTitleBlock() const override
void PlotDrawingSheet(PLOTTER *plotter, const PROJECT *aProject, const TITLE_BLOCK &aTitleBlock, const PAGE_INFO &aPageInfo, const wxString &aSheetNumber, int aSheetCount, const wxString &aSheetDesc, const wxString &aFilename, COLOR4D aColor, bool aIsFirstPage)
void SortByPageNumbers(bool aUpdateVirtualPageNums=true)
Sorts the list of sheets by page number.
#define IU_PER_MILS
Definition: plotter.cpp:137
wxString GetUniqueFilenameForCurrentSheet()
virtual bool OpenFile(const wxString &aFullFilename) override
Open or create the plot file aFullFilename.
SCH_SHEET_PATH & GetCurrentSheet() const
const wxString & GetTitle() const
Definition: title_block.h:63
WX_HTML_REPORT_PANEL * m_MessagesBox
Definition of the SCH_SHEET_PATH and SCH_SHEET_LIST classes for Eeschema.
virtual bool StartPlot() override
The PDF engine supports multiple pages; the first one is opened 'for free' the following are to be cl...
PAGE_INFO & PageSettings()
Definition: plotter.h:158
void SetPortrait(bool aIsPortrait)
Rotate the paper page 90 degrees.
Definition: page_info.cpp:186
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:75
int GetWidthMils() const
Definition: page_info.h:130
virtual void SetPageSettings(const PAGE_INFO &aPageSettings)
Definition: plotter.h:157
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:98
bool GetColorMode() const
Definition: plotter.h:152