KiCad PCB EDA Suite
Loading...
Searching...
No Matches
sch_plotter.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 1992-2018 Jean-Pierre Charras jp.charras at wanadoo.fr
5 * Copyright (C) 1992-2010 Lorenzo Marcantonio
6 * Copyright (C) 2011 Wayne Stambaugh <[email protected]>
7 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, you may find one here:
21 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
22 * or you may search the http://www.gnu.org website for the version 2 license,
23 * or you may write to the Free Software Foundation, Inc.,
24 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25 */
26
27#include <wx/log.h>
28#include <common.h>
29#include <sch_plotter.h>
30#include <locale_io.h>
33
34#include <pgm_base.h>
35#include <trace_helpers.h>
36
37#include <sch_edit_frame.h>
38#include <sch_painter.h>
39#include <schematic.h>
40#include <sch_screen.h>
42
43// Note:
44// We need to switch between sheets to plot a hierarchy and update references and sheet number
45// Use SCHEMATIC::SetCurrentSheet( xxx ) to switch to a sheet.
46// Do not use SCH_EDIT_FRAME::SetCurrentSheet( xxx ) to switch to a sheet, because the new sheet
47// is not displayed, but SCH_EDIT_FRAME::SetCurrentSheet() has side effects to the current VIEW
48// (clear some data used to show the sheet on screen) and does not fully restore the "old" screen
49
50
52 m_schematic( aSchematic )
53{
54 m_colorSettings = nullptr;
55}
56
57
59 m_schematic( &aFrame->Schematic() )
60{
61 m_colorSettings = nullptr;
62}
63
64
66 REPORTER* aReporter, const wxString& aExt )
67{
68 if( !aPlotOpts.m_outputFile.empty() )
69 {
70 return aPlotOpts.m_outputFile;
71 }
72 else
73 {
75
76 // The sub sheet can be in a sub_hierarchy, but we plot the file in the main
77 // project folder (or the folder specified by the caller), so replace separators
78 // to create a unique filename:
79 fname.Replace( "/", "_" );
80 fname.Replace( "\\", "_" );
81
82 return createPlotFileName( aPlotOpts, fname, aExt, aReporter );
83 }
84
85}
86
87
89 SCH_RENDER_SETTINGS* aRenderSettings, REPORTER* aReporter )
90{
91 SCH_SHEET_PATH oldsheetpath = m_schematic->CurrentSheet(); // sheetpath is saved here
92
93 /* When printing all pages, the printed page is not the current page. In complex hierarchies,
94 * we must update symbol references and other parameters in the given printed SCH_SCREEN,
95 * according to the sheet path because in complex hierarchies a SCH_SCREEN (a drawing ) is
96 * shared between many sheets and symbol references depend on the actual sheet path used.
97 */
98 SCH_SHEET_LIST sheetList;
99
100 if( aPlotOpts.m_plotAll || aPlotOpts.m_plotPages.size() > 0 )
101 {
102 sheetList.BuildSheetList( &m_schematic->Root(), true );
104
105 // remove the non-selected pages if we are in plot pages mode
106 if( aPlotOpts.m_plotPages.size() > 0 )
107 sheetList.TrimToPageNumbers( aPlotOpts.m_plotPages );
108 }
109 else
110 {
111 // in Eeschema, this prints the current page
112 sheetList.push_back( m_schematic->CurrentSheet() );
113 }
114
115 if( sheetList.empty() )
116 {
117 if( aReporter )
118 aReporter->Report( _( "No sheets to plot." ), RPT_SEVERITY_ERROR );
119
120 return;
121 }
122
123 wxCHECK( m_schematic, /* void */ );
124
125 // Allocate the plotter and set the job level parameter
126 PDF_PLOTTER* plotter = new PDF_PLOTTER( &m_schematic->Prj() );
127 plotter->SetRenderSettings( aRenderSettings );
128 plotter->SetColorMode( !aPlotOpts.m_blackAndWhite );
129 plotter->SetCreator( wxT( "Eeschema-PDF" ) );
131 &m_schematic->Prj() ) );
132
133 wxString msg;
134 wxFileName plotFileName;
135 LOCALE_IO toggle; // Switch the locale to standard C
136
137 for( unsigned i = 0; i < sheetList.size(); i++ )
138 {
139 m_schematic->SetCurrentSheet( sheetList[i] );
142
144 wxString sheetName = sheetList[i].Last()->GetField( FIELD_T::SHEET_NAME )->GetShownText( false );
145
146 if( aPlotOpts.m_PDFMetadata )
147 {
148 msg = wxS( "AUTHOR" );
149
150 if( m_schematic->ResolveTextVar( &sheetList[i], &msg, 0 ) )
151 plotter->SetAuthor( msg );
152
153 msg = wxS( "SUBJECT" );
154
155 if( m_schematic->ResolveTextVar( &sheetList[i], &msg, 0 ) )
156 plotter->SetSubject( msg );
157 }
158
159 if( i == 0 )
160 {
161 try
162 {
164 plotFileName = getOutputFilenameSingle( aPlotOpts, aReporter, ext );
165
166 m_lastOutputFilePath = plotFileName.GetFullPath();
167
168 if( !plotFileName.IsOk() )
169 return;
170
171 if( !plotter->OpenFile( plotFileName.GetFullPath() ) )
172 {
173 if( aReporter )
174 {
175 msg.Printf( _( "Failed to create file '%s'." ),
176 plotFileName.GetFullPath() );
177 aReporter->Report( msg, RPT_SEVERITY_ERROR );
178 }
179 delete plotter;
180 return;
181 }
182
183 // Open the plotter and do the first page
184 setupPlotPagePDF( plotter, screen, aPlotOpts );
185
186 plotter->StartPlot( sheetList[i].GetPageNumber(), sheetName );
187 }
188 catch( const IO_ERROR& e )
189 {
190 // Cannot plot PDF file
191 if( aReporter )
192 {
193 msg.Printf( wxT( "PDF Plotter exception: %s" ), e.What() );
194 aReporter->Report( msg, RPT_SEVERITY_ERROR );
195 }
196
197 restoreEnvironment( plotter, oldsheetpath );
198 return;
199 }
200 }
201 else
202 {
203 /* For the following pages you need to close the (finished) page,
204 * reconfigure, and then start a new one */
205 plotter->ClosePage();
206 setupPlotPagePDF( plotter, screen, aPlotOpts );
207 SCH_SHEET_PATH parentSheet = sheetList[i];
208
209 if( parentSheet.size() > 1 )
210 {
211 // The sheet path is the full path to the sheet, so we need to remove the last
212 // sheet name to get the parent sheet path
213 parentSheet.pop_back();
214 }
215
216 wxString parentSheetName =
217 parentSheet.Last()->GetField( FIELD_T::SHEET_NAME )->GetShownText( false );
218
219 plotter->StartPage( sheetList[i].GetPageNumber(), sheetName,
220 parentSheet.GetPageNumber(), parentSheetName );
221 }
222
223 plotOneSheetPDF( plotter, screen, aPlotOpts );
224 }
225
226 // Everything done, close the plot and restore the environment
227 if( aReporter )
228 {
229 msg.Printf( _( "Plotted to '%s'.\n" ), plotFileName.GetFullPath() );
230 aReporter->Report( msg, RPT_SEVERITY_ACTION );
231 aReporter->ReportTail( _( "Done." ), RPT_SEVERITY_INFO );
232 }
233
234 restoreEnvironment( plotter, oldsheetpath );
235}
236
237
239 const SCH_PLOT_OPTS& aPlotOpts )
240{
241 if( aPlotOpts.m_useBackgroundColor && aPlotter->GetColorMode() )
242 {
243 aPlotter->SetColor( aPlotter->RenderSettings()->GetBackgroundColor() );
244
245 // Use page size selected in schematic to know the schematic bg area
246 const PAGE_INFO& actualPage = aScreen->GetPageSettings(); // page size selected in schematic
248 actualPage.GetHeightIU( schIUScale.IU_PER_MILS ) );
249
250 aPlotter->Rect( VECTOR2I( 0, 0 ), end, FILL_T::FILLED_SHAPE, 1.0 );
251 }
252
253 if( aPlotOpts.m_plotDrawingSheet )
254 {
255 COLOR4D color = COLOR4D::BLACK;
256
257 if( aPlotter->GetColorMode() )
259
260 wxString sheetName = m_schematic->CurrentSheet().Last()->GetName();
261 wxString sheetPath = m_schematic->CurrentSheet().PathHumanReadable();
262 const PAGE_INFO& actualPage = aScreen->GetPageSettings(); // page size selected in schematic
263
264 PlotDrawingSheet( aPlotter, &aScreen->Schematic()->Prj(),
265 aScreen->GetTitleBlock(),
266 actualPage,
267 aScreen->Schematic()->GetProperties(),
268 aScreen->GetPageNumber(), aScreen->GetPageCount(), sheetName, sheetPath,
269 aScreen->GetFileName(), color, aScreen->GetVirtualPageNumber() == 1 );
270 }
271
272 aScreen->Plot( aPlotter, aPlotOpts );
273}
274
275
277 const SCH_PLOT_OPTS& aPlotOpts )
278{
279 PAGE_INFO plotPage; // page size selected to plot
280
281 // Considerations on page size and scaling requests
282 const PAGE_INFO& actualPage = aScreen->GetPageSettings(); // page size selected in schematic
283
284 switch( aPlotOpts.m_pageSizeSelect )
285 {
286 case PAGE_SIZE_A:
287 plotPage.SetType( wxT( "A" ) );
288 plotPage.SetPortrait( actualPage.IsPortrait() );
289 break;
290
291 case PAGE_SIZE_A4:
292 plotPage.SetType( wxT( "A4" ) );
293 plotPage.SetPortrait( actualPage.IsPortrait() );
294 break;
295
296 case PAGE_SIZE_AUTO:
297 default:
298 plotPage = actualPage;
299 break;
300 }
301
302 double scalex = (double) plotPage.GetWidthMils() / actualPage.GetWidthMils();
303 double scaley = (double) plotPage.GetHeightMils() / actualPage.GetHeightMils();
304 double scale = std::min( scalex, scaley );
305 aPlotter->SetPageSettings( plotPage );
306
307 // Currently, plot units are in decimil
308 aPlotter->SetViewport( VECTOR2I( 0, 0 ), schIUScale.IU_PER_MILS / 10, scale, false );
309}
310
311
313 SCH_RENDER_SETTINGS* aRenderSettings, REPORTER* aReporter )
314{
315 SCH_SHEET_PATH oldsheetpath = m_schematic->CurrentSheet(); // sheetpath is saved here
316 PAGE_INFO plotPage; // page size selected to plot
317 wxString msg;
318
319 /* When printing all pages, the printed page is not the current page.
320 * In complex hierarchies, we must update symbol references and other parameters in the
321 * given printed SCH_SCREEN, accordant to the sheet path because in complex hierarchies
322 * a SCH_SCREEN (a drawing ) is shared between many sheets and symbol references
323 * depend on the actual sheet path used.
324 */
325 SCH_SHEET_LIST sheetList;
326
327 if( aPlotOpts.m_plotAll )
328 {
329 sheetList.BuildSheetList( &m_schematic->Root(), true );
330 sheetList.SortByPageNumbers();
331
332 // remove the non-selected pages if we are in plot pages mode
333 if( aPlotOpts.m_plotPages.size() > 0 )
334 {
335 sheetList.TrimToPageNumbers( aPlotOpts.m_plotPages );
336 }
337 }
338 else
339 {
340 sheetList.push_back( m_schematic->CurrentSheet() );
341 }
342
343 for( unsigned i = 0; i < sheetList.size(); i++ )
344 {
345 m_schematic->SetCurrentSheet( sheetList[i] );
348
350 PAGE_INFO actualPage = screen->GetPageSettings();
351
352 switch( aPlotOpts.m_pageSizeSelect )
353 {
354 case PAGE_SIZE_A:
355 plotPage.SetType( wxT( "A" ) );
356 plotPage.SetPortrait( actualPage.IsPortrait() );
357 break;
358
359 case PAGE_SIZE_A4:
360 plotPage.SetType( wxT( "A4" ) );
361 plotPage.SetPortrait( actualPage.IsPortrait() );
362 break;
363
364 case PAGE_SIZE_AUTO:
365 default:
366 plotPage = actualPage;
367 break;
368 }
369
370 double scalex = (double) plotPage.GetWidthMils() / actualPage.GetWidthMils();
371 double scaley = (double) plotPage.GetHeightMils() / actualPage.GetHeightMils();
372 double scale = std::min( scalex, scaley );
373 VECTOR2I plot_offset;
374
375 try
376 {
378
379 // The sub sheet can be in a sub_hierarchy, but we plot the file in the
380 // main project folder (or the folder specified by the caller),
381 // so replace separators to create a unique filename:
382 fname.Replace( "/", "_" );
383 fname.Replace( "\\", "_" );
385 wxFileName plotFileName = createPlotFileName( aPlotOpts, fname, ext, aReporter );
386
387 m_lastOutputFilePath = plotFileName.GetFullPath();
388
389 if( !plotFileName.IsOk() )
390 {
391 if( aReporter )
392 {
393 // Error
394 msg.Printf( _( "Failed to create file '%s'." ), plotFileName.GetFullPath() );
395 aReporter->Report( msg, RPT_SEVERITY_ERROR );
396 }
397 }
398 else if( plotOneSheetPS( plotFileName.GetFullPath(), screen, aRenderSettings,
399 actualPage, plot_offset, scale, aPlotOpts ) )
400 {
401 if( aReporter )
402 {
403 msg.Printf( _( "Plotted to '%s'." ), plotFileName.GetFullPath() );
404 aReporter->Report( msg, RPT_SEVERITY_ACTION );
405 }
406 }
407 else
408 {
409 if( aReporter )
410 {
411 // Error
412 msg.Printf( _( "Failed to create file '%s'." ), plotFileName.GetFullPath() );
413 aReporter->Report( msg, RPT_SEVERITY_ERROR );
414 }
415 }
416 }
417 catch( IO_ERROR& e )
418 {
419 if( aReporter )
420 {
421 msg.Printf( wxT( "PS Plotter exception: %s" ), e.What() );
422 aReporter->Report( msg, RPT_SEVERITY_ERROR );
423 }
424 }
425 }
426
427 if( aReporter )
428 aReporter->ReportTail( _( "Done." ), RPT_SEVERITY_INFO );
429
430 restoreEnvironment( nullptr, oldsheetpath );
431}
432
433
434bool SCH_PLOTTER::plotOneSheetPS( const wxString& aFileName, SCH_SCREEN* aScreen,
435 RENDER_SETTINGS* aRenderSettings, const PAGE_INFO& aPageInfo,
436 const VECTOR2I& aPlot0ffset, double aScale,
437 const SCH_PLOT_OPTS& aPlotOpts )
438{
439 PS_PLOTTER* plotter = new PS_PLOTTER();
440 plotter->SetRenderSettings( aRenderSettings );
441 plotter->SetPageSettings( aPageInfo );
442 plotter->SetColorMode( !aPlotOpts.m_blackAndWhite );
443
444 // Currently, plot units are in decimil
445 plotter->SetViewport( aPlot0ffset, schIUScale.IU_PER_MILS / 10, aScale, false );
446
447 // Init :
448 plotter->SetCreator( wxT( "Eeschema-PS" ) );
449
450 if( !plotter->OpenFile( aFileName ) )
451 {
452 delete plotter;
453 return false;
454 }
455
456 LOCALE_IO toggle; // Switch the locale to standard C
457
459
460 if( aPlotOpts.m_useBackgroundColor && plotter->GetColorMode() )
461 {
463
464 // Use page size selected in schematic to know the schematic bg area
465 const PAGE_INFO& actualPage = aScreen->GetPageSettings(); // page size selected in schematic
467 actualPage.GetHeightIU( schIUScale.IU_PER_MILS ) );
468
469 plotter->Rect( VECTOR2I( 0, 0 ), end, FILL_T::FILLED_SHAPE, 1.0 );
470 }
471
472 if( aPlotOpts.m_plotDrawingSheet )
473 {
474 wxString sheetName = m_schematic->CurrentSheet().Last()->GetName();
475 wxString sheetPath = m_schematic->CurrentSheet().PathHumanReadable();
477
478 PlotDrawingSheet( plotter, &aScreen->Schematic()->Prj(),
479 aScreen->GetTitleBlock(),
480 aPageInfo, aScreen->Schematic()->GetProperties(),
481 aScreen->GetPageNumber(), aScreen->GetPageCount(), sheetName, sheetPath,
482 aScreen->GetFileName(), plotter->GetColorMode() ? color : COLOR4D::BLACK,
483 aScreen->GetVirtualPageNumber() == 1 );
484 }
485
486 aScreen->Plot( plotter, aPlotOpts );
487
488 plotter->EndPlot();
489 delete plotter;
490
491 return true;
492}
493
494
496 SCH_RENDER_SETTINGS* aRenderSettings, REPORTER* aReporter )
497{
498 wxString msg;
499 SCH_SHEET_PATH oldsheetpath = m_schematic->CurrentSheet();
500 SCH_SHEET_LIST sheetList;
501
502 if( aPlotOpts.m_plotAll )
503 {
504 sheetList.BuildSheetList( &m_schematic->Root(), true );
505 sheetList.SortByPageNumbers();
506
507 // remove the non-selected pages if we are in plot pages mode
508 if( aPlotOpts.m_plotPages.size() > 0 )
509 {
510 sheetList.TrimToPageNumbers( aPlotOpts.m_plotPages );
511 }
512 }
513 else
514 {
515 // in Eeschema, this prints the current page
516 sheetList.push_back( m_schematic->CurrentSheet() );
517 }
518
519 for( unsigned i = 0; i < sheetList.size(); i++ )
520 {
521 SCH_SCREEN* screen;
522
523 m_schematic->SetCurrentSheet( sheetList[i] );
526
527 screen = m_schematic->CurrentSheet().LastScreen();
528
529 try
530 {
532
533 // The sub sheet can be in a sub_hierarchy, but we plot the file in the
534 // main project folder (or the folder specified by the caller),
535 // so replace separators to create a unique filename:
536 fname.Replace( "/", "_" );
537 fname.Replace( "\\", "_" );
539 wxFileName plotFileName = createPlotFileName( aPlotOpts, fname, ext, aReporter );
540
541 m_lastOutputFilePath = plotFileName.GetFullPath();
542
543 if( !plotFileName.IsOk() )
544 return;
545
546 bool success = plotOneSheetSVG( plotFileName.GetFullPath(), screen, aRenderSettings,
547 aPlotOpts );
548
549 if( !success )
550 {
551 if( aReporter )
552 {
553 msg.Printf( _( "Failed to create file '%s'." ), plotFileName.GetFullPath() );
554 aReporter->Report( msg, RPT_SEVERITY_ERROR );
555 }
556 }
557 else
558 {
559 if( aReporter )
560 {
561 msg.Printf( _( "Plotted to '%s'." ), plotFileName.GetFullPath() );
562 aReporter->Report( msg, RPT_SEVERITY_ACTION );
563 }
564 }
565 }
566 catch( const IO_ERROR& e )
567 {
568 if( aReporter )
569 {
570 // Cannot plot SVG file
571 msg.Printf( wxT( "SVG Plotter exception: %s" ), e.What() );
572 aReporter->Report( msg, RPT_SEVERITY_ERROR );
573 }
574 break;
575 }
576 }
577
578 if( aReporter )
579 {
580 aReporter->ReportTail( _( "Done." ), RPT_SEVERITY_INFO );
581 }
582
583 restoreEnvironment( nullptr, oldsheetpath );
584}
585
586
587bool SCH_PLOTTER::plotOneSheetSVG( const wxString& aFileName, SCH_SCREEN* aScreen,
588 RENDER_SETTINGS* aRenderSettings,
589 const SCH_PLOT_OPTS& aPlotOpts )
590{
591 PAGE_INFO plotPage;
592
593 // Adjust page size and scaling requests
594 const PAGE_INFO& actualPage = aScreen->GetPageSettings(); // page size selected in schematic
595
596 switch( aPlotOpts.m_pageSizeSelect )
597 {
598 case PAGE_SIZE_A:
599 plotPage.SetType( wxT( "A" ) );
600 plotPage.SetPortrait( actualPage.IsPortrait() );
601 break;
602
603 case PAGE_SIZE_A4:
604 plotPage.SetType( wxT( "A4" ) );
605 plotPage.SetPortrait( actualPage.IsPortrait() );
606 break;
607
608 case PAGE_SIZE_AUTO:
609 default:
610 plotPage = actualPage;
611 break;
612 }
613
614 SVG_PLOTTER* plotter = new SVG_PLOTTER();
615 plotter->SetRenderSettings( aRenderSettings );
616 plotter->SetPageSettings( plotPage );
617 plotter->SetColorMode( aPlotOpts.m_blackAndWhite ? false : true );
618 VECTOR2I plot_offset;
619
620 double scalex = (double) plotPage.GetWidthMils() / actualPage.GetWidthMils();
621 double scaley = (double) plotPage.GetHeightMils() / actualPage.GetHeightMils();
622 double scale = std::min( scalex, scaley );
623
624 // Currently, plot units are in decimil
625 plotter->SetViewport( plot_offset, schIUScale.IU_PER_MILS / 10, scale, false );
626
627 // Init :
628 plotter->SetCreator( wxT( "Eeschema-SVG" ) );
629
630 if( !plotter->OpenFile( aFileName ) )
631 {
632 delete plotter;
633 return false;
634 }
635
636 LOCALE_IO toggle;
637
639
640 if( aPlotOpts.m_useBackgroundColor && plotter->GetColorMode() )
641 {
643
644 // Use page size selected in schematic to know the schematic bg area
646 actualPage.GetHeightIU( schIUScale.IU_PER_MILS ) );
647
648 plotter->Rect( VECTOR2I( 0, 0 ), end, FILL_T::FILLED_SHAPE, 1.0 );
649 }
650
651 if( aPlotOpts.m_plotDrawingSheet )
652 {
653 wxString sheetName = m_schematic->CurrentSheet().Last()->GetName();
654 wxString sheetPath = m_schematic->CurrentSheet().PathHumanReadable();
656
657 PlotDrawingSheet( plotter, &aScreen->Schematic()->Prj(),
658 aScreen->GetTitleBlock(),
659 actualPage, aScreen->Schematic()->GetProperties(),
660 aScreen->GetPageNumber(),
661 aScreen->GetPageCount(), sheetName, sheetPath, aScreen->GetFileName(),
662 plotter->GetColorMode() ? color : COLOR4D::BLACK,
663 aScreen->GetVirtualPageNumber() == 1 );
664 }
665
666 aScreen->Plot( plotter, aPlotOpts );
667
668 plotter->EndPlot();
669 delete plotter;
670
671 return true;
672}
673
674
676 SCH_RENDER_SETTINGS* aRenderSettings, REPORTER* aReporter )
677{
678 SCH_SHEET_PATH oldsheetpath = m_schematic->CurrentSheet();
679
680 /* When printing all pages, the printed page is not the current page. In complex hierarchies,
681 * we must update symbol references and other parameters in the given printed SCH_SCREEN,
682 * according to the sheet path because in complex hierarchies a SCH_SCREEN (a drawing ) is
683 * shared between many sheets and symbol references depend on the actual sheet path used.
684 */
685 SCH_SHEET_LIST sheetList;
686
687 if( aPlotOpts.m_plotAll )
688 {
689 sheetList.BuildSheetList( &m_schematic->Root(), true );
690 sheetList.SortByPageNumbers();
691
692 // remove the non-selected pages if we are in plot pages mode
693 if( aPlotOpts.m_plotPages.size() > 0 )
694 sheetList.TrimToPageNumbers( aPlotOpts.m_plotPages );
695 }
696 else
697 {
698 // in Eeschema, this prints the current page
699 sheetList.push_back( m_schematic->CurrentSheet() );
700 }
701
702 for( unsigned i = 0; i < sheetList.size(); i++ )
703 {
704 m_schematic->SetCurrentSheet( sheetList[i] );
707
709 VECTOR2I plot_offset;
710 wxString msg;
711
712 try
713 {
715
716 // The sub sheet can be in a sub_hierarchy, but we plot the file in the
717 // main project folder (or the folder specified by the caller),
718 // so replace separators to create a unique filename:
719 fname.Replace( "/", "_" );
720 fname.Replace( "\\", "_" );
722 wxFileName plotFileName = createPlotFileName( aPlotOpts, fname, ext, aReporter );
723
724 m_lastOutputFilePath = plotFileName.GetFullPath();
725
726 if( !plotFileName.IsOk() )
727 return;
728
729 if( plotOneSheetDXF( plotFileName.GetFullPath(), screen, aRenderSettings, plot_offset,
730 1.0, aPlotOpts ) )
731 {
732 if( aReporter )
733 {
734 msg.Printf( _( "Plotted to '%s'." ), plotFileName.GetFullPath() );
735 aReporter->Report( msg, RPT_SEVERITY_ACTION );
736 }
737 }
738 else // Error
739 {
740 if( aReporter )
741 {
742 msg.Printf( _( "Failed to create file '%s'." ), plotFileName.GetFullPath() );
743 aReporter->Report( msg, RPT_SEVERITY_ERROR );
744 }
745 }
746 }
747 catch( IO_ERROR& e )
748 {
749 if( aReporter )
750 {
751 msg.Printf( wxT( "DXF Plotter exception: %s" ), e.What() );
752 aReporter->Report( msg, RPT_SEVERITY_ERROR );
753 }
754
755 m_schematic->SetCurrentSheet( oldsheetpath );
758 return;
759 }
760 }
761
762 if( aReporter )
763 aReporter->ReportTail( _( "Done." ), RPT_SEVERITY_INFO );
764
765 restoreEnvironment( nullptr, oldsheetpath );
766}
767
768
769bool SCH_PLOTTER::plotOneSheetDXF( const wxString& aFileName, SCH_SCREEN* aScreen,
770 RENDER_SETTINGS* aRenderSettings, const VECTOR2I& aPlotOffset,
771 double aScale, const SCH_PLOT_OPTS& aPlotOpts )
772{
773 aRenderSettings->LoadColors( m_colorSettings );
774 aRenderSettings->SetDefaultPenWidth( 0 );
775
776 const PAGE_INFO& pageInfo = aScreen->GetPageSettings();
777 DXF_PLOTTER* plotter = new DXF_PLOTTER();
778
779 plotter->SetRenderSettings( aRenderSettings );
780 plotter->SetPageSettings( pageInfo );
781 plotter->SetColorMode( !aPlotOpts.m_blackAndWhite );
782
783 // Currently, plot units are in decimil
784 plotter->SetViewport( aPlotOffset, schIUScale.IU_PER_MILS / 10, aScale, false );
785
786 // Init :
787 plotter->SetCreator( wxT( "Eeschema-DXF" ) );
788
789 if( !plotter->OpenFile( aFileName ) )
790 {
791 delete plotter;
792 return false;
793 }
794
795 LOCALE_IO toggle;
796
798
799 if( aPlotOpts.m_plotDrawingSheet )
800 {
801 wxString sheetName = m_schematic->CurrentSheet().Last()->GetName();
802 wxString sheetPath = m_schematic->CurrentSheet().PathHumanReadable();
804
805 PlotDrawingSheet( plotter, &m_schematic->Prj(),
806 aScreen->GetTitleBlock(),
807 pageInfo,
808 aScreen->Schematic()->GetProperties(), aScreen->GetPageNumber(),
809 aScreen->GetPageCount(), sheetName, sheetPath, aScreen->GetFileName(),
810 plotter->GetColorMode() ? color : COLOR4D::BLACK,
811 aScreen->GetVirtualPageNumber() == 1 );
812 }
813
814 aScreen->Plot( plotter, aPlotOpts );
815
816 // finish
817 plotter->EndPlot();
818 delete plotter;
819
820 return true;
821}
822
823
825{
826 if( aPlotter )
827 {
828 aPlotter->EndPlot();
829 delete aPlotter;
830 }
831
832 // Restore the initial sheet
833 m_schematic->SetCurrentSheet( aOldsheetpath );
836}
837
838
840 const wxString& aPlotFileName,
841 const wxString& aExtension, REPORTER* aReporter )
842{
843 wxFileName retv;
844 wxFileName tmp;
845
846 tmp.SetPath( aPlotOpts.m_outputDirectory );
847 retv.SetPath( tmp.GetPath() );
848
849 if( !aPlotFileName.IsEmpty() )
850 retv.SetName( aPlotFileName );
851 else
852 retv.SetName( _( "Schematic" ) );
853
854 retv.SetExt( aExtension );
855
856 if( !EnsureFileDirectoryExists( &tmp, retv.GetFullName(), aReporter ) || !tmp.IsDirWritable() )
857 {
858 if( aReporter )
859 {
860 wxString msg = wxString::Format( _( "Failed to write plot files to folder '%s'." ),
861 tmp.GetPath() );
862 aReporter->Report( msg, RPT_SEVERITY_ERROR );
863 }
864
865 retv.Clear();
866
868 settings.m_PlotDirectoryName.Clear();
869 }
870 else
871 {
872 retv.SetPath( tmp.GetPath() );
873 }
874
875 wxLogTrace( tracePathsAndFiles, "Writing plot file '%s'.", retv.GetFullPath() );
876
877 return retv;
878}
879
880
881void SCH_PLOTTER::Plot( PLOT_FORMAT aPlotFormat, const SCH_PLOT_OPTS& aPlotOpts,
882 SCH_RENDER_SETTINGS* aRenderSettings, REPORTER* aReporter )
883{
885
886 switch( aPlotFormat )
887 {
888 default:
889 case PLOT_FORMAT::POST: createPSFiles( aPlotOpts, aRenderSettings, aReporter ); break;
890 case PLOT_FORMAT::DXF: createDXFFiles( aPlotOpts, aRenderSettings, aReporter ); break;
891 case PLOT_FORMAT::PDF: createPDFFile( aPlotOpts, aRenderSettings, aReporter ); break;
892 case PLOT_FORMAT::SVG: createSVGFiles( aPlotOpts, aRenderSettings, aReporter ); break;
893 case PLOT_FORMAT::HPGL: /* no longer supported */ break;
894 }
895}
int color
Definition: DXF_plotter.cpp:63
constexpr EDA_IU_SCALE schIUScale
Definition: base_units.h:114
int GetPageCount() const
Definition: base_screen.h:72
int GetVirtualPageNumber() const
Definition: base_screen.h:75
const wxString & GetPageNumber() const
Definition: base_screen.cpp:70
static wxString GetDefaultFileExtension()
Definition: plotter_dxf.h:42
virtual void SetViewport(const VECTOR2I &aOffset, double aIusPerDecimil, double aScale, bool aMirror) override
Set the scale/position for the DXF plot.
virtual bool StartPlot(const wxString &aPageNumber) override
Open the DXF plot with a skeleton header.
virtual bool EndPlot() override
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:77
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:30
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:104
Container for all the knowledge about how graphical objects are drawn on any output surface/device.
void SetDefaultPenWidth(int aWidth)
virtual void LoadColors(const COLOR_SETTINGS *aSettings)
const COLOR4D & GetLayerColor(int aLayer) const
Return the color used to draw a layer.
virtual const COLOR4D & GetBackgroundColor() const =0
Return current background color settings.
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition: locale_io.h:41
Describe the page size and margins of a paper page on which to eventually print or plot.
Definition: page_info.h:59
void SetPortrait(bool aIsPortrait)
Rotate the paper page 90 degrees.
Definition: page_info.cpp:188
int GetHeightIU(double aIUScale) const
Gets the page height in IU.
Definition: page_info.h:162
double GetHeightMils() const
Definition: page_info.h:141
int GetWidthIU(double aIUScale) const
Gets the page width in IU.
Definition: page_info.h:153
double GetWidthMils() const
Definition: page_info.h:136
bool IsPortrait() const
Definition: page_info.h:122
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:121
virtual void ClosePage()
Close the current page in the PDF document (and emit its compressed stream).
virtual bool EndPlot() override
virtual bool OpenFile(const wxString &aFullFilename) override
Open or create the plot file aFullFilename.
virtual bool StartPlot(const wxString &aPageNumber) override
The PDF engine supports multiple pages; the first one is opened 'for free' the following are to be cl...
static wxString GetDefaultFileExtension()
virtual void StartPage(const wxString &aPageNumber, const wxString &aPageName=wxEmptyString, const wxString &aParentPageNumber=wxEmptyString, const wxString &aParentPageName=wxEmptyString)
Start a new page in the PDF document.
Base plotter engine class.
Definition: plotter.h:121
virtual bool OpenFile(const wxString &aFullFilename)
Open or create the plot file aFullFilename.
Definition: plotter.cpp:75
virtual void SetAuthor(const wxString &aAuthor)
Definition: plotter.h:175
virtual void SetPageSettings(const PAGE_INFO &aPageSettings)
Definition: plotter.h:154
void SetRenderSettings(RENDER_SETTINGS *aSettings)
Definition: plotter.h:151
virtual void SetTitle(const wxString &aTitle)
Definition: plotter.h:174
virtual void Rect(const VECTOR2I &p1, const VECTOR2I &p2, FILL_T fill, int width)=0
RENDER_SETTINGS * RenderSettings()
Definition: plotter.h:152
virtual void SetCreator(const wxString &aCreator)
Definition: plotter.h:173
bool GetColorMode() const
Definition: plotter.h:149
virtual void SetViewport(const VECTOR2I &aOffset, double aIusPerDecimil, double aScale, bool aMirror)=0
Set the plot offset and scaling for the current plot.
virtual void SetColorMode(bool aColorMode)
Plot in B/W or color.
Definition: plotter.h:148
virtual void SetSubject(const wxString &aSubject)
Definition: plotter.h:176
virtual void SetColor(const COLOR4D &color)=0
virtual void SetColor(const COLOR4D &color) override
The SetColor implementation is split with the subclasses: the PSLIKE computes the rgb values,...
Definition: PS_plotter.cpp:64
virtual bool EndPlot() override
Definition: PS_plotter.cpp:853
virtual void Rect(const VECTOR2I &p1, const VECTOR2I &p2, FILL_T fill, int width) override
Definition: PS_plotter.cpp:460
virtual void SetViewport(const VECTOR2I &aOffset, double aIusPerDecimil, double aScale, bool aMirror) override
Set the plot offset and scaling for the current plot.
Definition: PS_plotter.cpp:285
virtual bool StartPlot(const wxString &aPageNumber) override
The code within this function (and the CloseFilePS function) creates postscript files whose contents ...
Definition: PS_plotter.cpp:703
static wxString GetDefaultFileExtension()
A pure virtual class used to derive REPORTER objects from.
Definition: reporter.h:73
virtual void Clear()
Definition: reporter.h:150
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Report a string with a given severity.
Definition: reporter.h:102
virtual REPORTER & ReportTail(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Places the report at the end of the list, for objects that support report ordering.
Definition: reporter.h:112
These are loaded from Eeschema settings but then overwritten by the project settings.
Holds all the data relating to one schematic.
Definition: schematic.h:87
PROJECT & Prj() const
Return a reference to the project this schematic is part of.
Definition: schematic.h:102
void SetCurrentSheet(const SCH_SHEET_PATH &aPath)
Definition: schematic.h:172
SCHEMATIC_SETTINGS & Settings() const
Definition: schematic.cpp:317
SCH_SCREEN * RootScreen() const
Helper to retrieve the screen of the root sheet.
Definition: schematic.cpp:213
bool ResolveTextVar(const SCH_SHEET_PATH *aSheetPath, wxString *token, int aDepth) const
Definition: schematic.cpp:258
const std::map< wxString, wxString > * GetProperties()
Definition: schematic.h:105
SCH_SHEET & Root() const
Definition: schematic.h:136
wxString GetUniqueFilenameForCurrentSheet()
Get the unique file name for the current sheet.
Definition: schematic.cpp:651
void SetSheetNumberAndCount()
Set the m_ScreenNumber and m_NumberOfScreens members for screens.
Definition: schematic.cpp:667
SCH_SHEET_PATH & CurrentSheet() const
Definition: schematic.h:167
Schematic editor (Eeschema) main window.
wxString GetShownText(const SCH_SHEET_PATH *aPath, bool aAllowExtraText, int aDepth=0) const
Definition: sch_field.cpp:191
void Plot(PLOT_FORMAT aPlotFormat, const SCH_PLOT_OPTS &aPlotOpts, SCH_RENDER_SETTINGS *aRenderSettings, REPORTER *aReporter=nullptr)
Perform the plotting of the schematic using the given aPlotFormat and a\ aPlotSettings.
wxFileName getOutputFilenameSingle(const SCH_PLOT_OPTS &aPlotOpts, REPORTER *aReporter, const wxString &ext)
Return the output filename for formats where the output is a single file.
Definition: sch_plotter.cpp:65
void createSVGFiles(const SCH_PLOT_OPTS &aPlotOpts, SCH_RENDER_SETTINGS *aRenderSettings, REPORTER *aReporter)
void createPSFiles(const SCH_PLOT_OPTS &aPlotOpts, SCH_RENDER_SETTINGS *aRenderSettings, REPORTER *aReporter)
void plotOneSheetPDF(PLOTTER *aPlotter, SCH_SCREEN *aScreen, const SCH_PLOT_OPTS &aPlotOpts)
wxFileName createPlotFileName(const SCH_PLOT_OPTS &aPlotOpts, const wxString &aPlotFileName, const wxString &aExtension, REPORTER *aReporter=nullptr)
Create a file name with an absolute path name.
SCH_PLOTTER(SCH_EDIT_FRAME *aFrame)
Constructor for usage with a frame having the schematic we want to print loaded.
Definition: sch_plotter.cpp:58
bool plotOneSheetDXF(const wxString &aFileName, SCH_SCREEN *aScreen, RENDER_SETTINGS *aRenderSettings, const VECTOR2I &aPlotOffset, double aScale, const SCH_PLOT_OPTS &aPlotOpts)
void createDXFFiles(const SCH_PLOT_OPTS &aPlotOpts, SCH_RENDER_SETTINGS *aRenderSettings, REPORTER *aReporter)
wxString m_lastOutputFilePath
Definition: sch_plotter.h:183
void restoreEnvironment(PDF_PLOTTER *aPlotter, SCH_SHEET_PATH &aOldsheetpath)
Everything done, close the plot and restore the environment.
bool plotOneSheetSVG(const wxString &aFileName, SCH_SCREEN *aScreen, RENDER_SETTINGS *aRenderSettings, const SCH_PLOT_OPTS &aPlotOpts)
void setupPlotPagePDF(PLOTTER *aPlotter, SCH_SCREEN *aScreen, const SCH_PLOT_OPTS &aPlotOpts)
void createPDFFile(const SCH_PLOT_OPTS &aPlotOpts, SCH_RENDER_SETTINGS *aRenderSettings, REPORTER *aReporter)
Definition: sch_plotter.cpp:88
COLOR_SETTINGS * m_colorSettings
Definition: sch_plotter.h:182
bool plotOneSheetPS(const wxString &aFileName, SCH_SCREEN *aScreen, RENDER_SETTINGS *aRenderSettings, const PAGE_INFO &aPageInfo, const VECTOR2I &aPlot0ffset, double aScale, const SCH_PLOT_OPTS &aPlotOpts)
SCHEMATIC * m_schematic
Definition: sch_plotter.h:181
const PAGE_INFO & GetPageSettings() const
Definition: sch_screen.h:134
const wxString & GetFileName() const
Definition: sch_screen.h:147
SCHEMATIC * Schematic() const
Definition: sch_screen.cpp:105
const TITLE_BLOCK & GetTitleBlock() const
Definition: sch_screen.h:158
void Plot(PLOTTER *aPlotter, const SCH_PLOT_OPTS &aPlotOpts) const
Plot all the schematic objects to aPlotter.
Definition: sch_screen.cpp:850
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
void TrimToPageNumbers(const std::vector< wxString > &aPageInclusions)
Truncates the list by removing sheet's with page numbers not in the given list.
void SortByPageNumbers(bool aUpdateVirtualPageNums=true)
Sort the list of sheets by page number.
void SortByHierarchicalPageNumbers(bool aUpdateVirtualPageNums=true)
This works like SortByPageNumbers, but it sorts the sheets first by their hierarchical depth and then...
void BuildSheetList(SCH_SHEET *aSheet, bool aCheckIntegrity)
Build the list of sheets and their sheet path from aSheet.
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
wxString PathHumanReadable(bool aUseShortRootName=true, bool aStripTrailingSeparator=false) const
Return the sheet path in a human readable form made from the sheet names.
void UpdateAllScreenReferences() const
Update all the symbol references for this sheet path.
SCH_SCREEN * LastScreen()
wxString GetPageNumber() const
SCH_SHEET * Last() const
Return a pointer to the last SCH_SHEET of the list.
size_t size() const
Forwarded method from std::vector.
void pop_back()
Forwarded method from std::vector.
SCH_FIELD * GetField(FIELD_T aFieldType)
Return a mandatory field in this sheet.
Definition: sch_sheet.cpp:367
wxString GetName() const
Definition: sch_sheet.h:113
virtual bool StartPlot(const wxString &aPageNumber) override
Create SVG file header.
virtual void SetViewport(const VECTOR2I &aOffset, double aIusPerDecimil, double aScale, bool aMirror) override
Set the plot offset and scaling for the current plot.
virtual void Rect(const VECTOR2I &p1, const VECTOR2I &p2, FILL_T fill, int width) override
virtual bool EndPlot() override
static wxString GetDefaultFileExtension()
const wxString & GetTitle() const
Definition: title_block.h:63
wxString ExpandTextVars(const wxString &aSource, const PROJECT *aProject, int aFlags)
Definition: common.cpp:59
bool EnsureFileDirectoryExists(wxFileName *aTargetFullFileName, const wxString &aBaseFilename, REPORTER *aReporter)
Make aTargetFullFileName absolute and create the path of this file if it doesn't yet exist.
Definition: common.cpp:374
The common library.
void PlotDrawingSheet(PLOTTER *plotter, const PROJECT *aProject, const TITLE_BLOCK &aTitleBlock, const PAGE_INFO &aPageInfo, const std::map< wxString, wxString > *aProperties, const wxString &aSheetNumber, int aSheetCount, const wxString &aSheetName, const wxString &aSheetPath, const wxString &aFilename, COLOR4D aColor, bool aIsFirstPage)
#define _(s)
const wxChar *const tracePathsAndFiles
Flag to enable path and file name debug output.
@ LAYER_SCHEMATIC_DRAWINGSHEET
Definition: layer_ids.h:484
@ LAYER_SCHEMATIC_BACKGROUND
Definition: layer_ids.h:477
see class PGM_BASE
PLOT_FORMAT
The set of supported output plot formats.
Definition: plotter.h:64
Plotting engines similar to ps (PostScript, Gerber, svg)
@ RPT_SEVERITY_ERROR
@ RPT_SEVERITY_INFO
@ RPT_SEVERITY_ACTION
@ PAGE_SIZE_AUTO
Definition: sch_plotter.h:48
@ PAGE_SIZE_A
Definition: sch_plotter.h:50
@ PAGE_SIZE_A4
Definition: sch_plotter.h:49
COLOR_SETTINGS * GetColorSettings(const wxString &aName)
const int scale
const double IU_PER_MILS
Definition: base_units.h:77
std::vector< wxString > m_plotPages
Definition: sch_plotter.h:58
wxString m_theme
Definition: sch_plotter.h:67
wxString m_outputDirectory
Definition: sch_plotter.h:69
wxString m_outputFile
Definition: sch_plotter.h:70
int m_pageSizeSelect
Definition: sch_plotter.h:62
bool m_PDFMetadata
Definition: sch_plotter.h:66
bool m_blackAndWhite
Definition: sch_plotter.h:61
bool m_useBackgroundColor
Definition: sch_plotter.h:63
bool m_plotDrawingSheet
Definition: sch_plotter.h:57
VECTOR2I end
wxLogTrace helper definitions.
VECTOR2< int32_t > VECTOR2I
Definition: vector2d.h:695