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, see <https://www.gnu.org/licenses/>.
21 */
22
23#include "core/typeinfo.h"
24#include <wx/log.h>
25#include <common.h>
26#include <sch_plotter.h>
30
31#include <pgm_base.h>
32#include <trace_helpers.h>
33
34#include <lib_symbol.h>
35#include <locale_io.h>
36#include <sch_edit_frame.h>
37#include <sch_painter.h>
38#include <sch_shape.h>
39#include <schematic.h>
40#include <sch_screen.h>
42
43#include <algorithm>
44
45// Note:
46// We need to switch between sheets to plot a hierarchy and update references and sheet number
47// Use SCHEMATIC::SetCurrentSheet( xxx ) to switch to a sheet.
48// Do not use SCH_EDIT_FRAME::SetCurrentSheet( xxx ) to switch to a sheet, because the new sheet
49// is not displayed, but SCH_EDIT_FRAME::SetCurrentSheet() has side effects to the current VIEW
50// (clear some data used to show the sheet on screen) and does not fully restore the "old" screen
51
52
54 m_schematic( aSchematic )
55{
56 m_colorSettings = nullptr;
57}
58
59
61 m_schematic( &aFrame->Schematic() )
62{
63 m_colorSettings = nullptr;
64}
65
66
68 REPORTER* aReporter, const wxString& aExt )
69{
70 if( !aPlotOpts.m_outputFile.empty() )
71 {
72 return aPlotOpts.m_outputFile;
73 }
74 else
75 {
76 wxString fname = m_schematic->GetUniqueFilenameForCurrentSheet();
77
78 // The sub sheet can be in a sub_hierarchy, but we plot the file in the main
79 // project folder (or the folder specified by the caller), so replace separators
80 // to create a unique filename:
81 fname.Replace( "/", "_" );
82 fname.Replace( "\\", "_" );
83
84 return createPlotFileName( aPlotOpts, fname, aExt, aReporter );
85 }
86
87}
88
89
91{
92public:
93 PLOT_CONTEXT( PLOTTER* aPlotter, SCHEMATIC* aSchematic ) :
94 m_plotter( aPlotter ),
95 m_schematic( aSchematic )
96 {
97 m_previousSheetPath = m_schematic->CurrentSheet();
98 }
99
101 {
102 if( m_plotter )
103 {
104 m_plotter->EndPlot();
105 delete m_plotter;
106 }
107
108 // Restore the initial sheet
109 m_schematic->SetCurrentSheet( m_previousSheetPath );
110 m_schematic->CurrentSheet().UpdateAllScreenReferences();
111 m_schematic->SetSheetNumberAndCount();
112 }
113
114private:
118};
119
120
121void SCH_PLOTTER::createPDFFile( const SCH_PLOT_OPTS& aPlotOpts, SCH_RENDER_SETTINGS* aRenderSettings,
122 REPORTER* aReporter )
123{
124 /* When printing all pages, the printed page is not the current page. In complex hierarchies,
125 * we must update symbol references and other parameters in the given printed SCH_SCREEN,
126 * according to the sheet path because in complex hierarchies a SCH_SCREEN (a drawing ) is
127 * shared between many sheets and symbol references depend on the actual sheet path used.
128 */
129 SCH_SHEET_LIST sheetList;
130
131 if( aPlotOpts.m_plotAll || aPlotOpts.m_plotPages.size() > 0 )
132 {
133 sheetList.BuildSheetList( &m_schematic->Root(), true );
135
136 // remove the non-selected pages if we are in plot pages mode
137 if( aPlotOpts.m_plotPages.size() > 0 )
138 sheetList.TrimToPageNumbers( aPlotOpts.m_plotPages );
139 }
140 else
141 {
142 // in Eeschema, this prints the current page
143 sheetList.push_back( aPlotOpts.m_sheetPath.value_or( m_schematic->CurrentSheet() ) );
144 }
145
146 if( sheetList.empty() )
147 {
148 if( aReporter )
149 aReporter->Report( _( "No sheets to plot." ), RPT_SEVERITY_ERROR );
150
151 return;
152 }
153
154 wxCHECK( m_schematic, /* void */ );
155
156 // Allocate the plotter and set the job level parameter
157 PDF_PLOTTER* plotter = new PDF_PLOTTER( &m_schematic->Project() );
158 PLOT_CONTEXT raii( plotter, m_schematic );
159
160 plotter->SetRenderSettings( aRenderSettings );
161 plotter->SetColorMode( !aPlotOpts.m_blackAndWhite );
162 plotter->SetCreator( wxT( "Eeschema-PDF" ) );
163 plotter->SetTitle( ExpandTextVars( m_schematic->RootScreen()->GetTitleBlock().GetTitle(),
164 &m_schematic->Project(), FOR_GUI ) );
165
166 wxString msg;
167 wxFileName plotFileName;
168
169 for( unsigned i = 0; i < sheetList.size(); i++ )
170 {
171 m_schematic->SetCurrentSheet( sheetList[i] );
172 m_schematic->CurrentSheet().UpdateAllScreenReferences();
173 m_schematic->SetSheetNumberAndCount();
174
175 SCH_SCREEN* screen = m_schematic->CurrentSheet().LastScreen();
176 wxString sheetName = sheetList[i].Last()->GetField( FIELD_T::SHEET_NAME )->GetShownText( FOR_GUI );
177
178 if( aPlotOpts.m_PDFMetadata )
179 {
180 msg = wxS( "AUTHOR" );
181
182 if( m_schematic->ResolveTextVar( &sheetList[i], &msg, 0 ) )
183 plotter->SetAuthor( msg );
184
185 msg = wxS( "SUBJECT" );
186
187 if( m_schematic->ResolveTextVar( &sheetList[i], &msg, 0 ) )
188 plotter->SetSubject( msg );
189 }
190
191 if( i == 0 )
192 {
193 try
194 {
196 plotFileName = getOutputFilenameSingle( aPlotOpts, aReporter, ext );
197
198 m_lastOutputFilePath = plotFileName.GetFullPath();
200
201 if( !plotFileName.IsOk() )
202 return;
203
204 if( !plotter->OpenFile( plotFileName.GetFullPath() ) )
205 {
206 if( aReporter )
207 {
208 msg.Printf( _( "Failed to create file '%s'." ), plotFileName.GetFullPath() );
209 aReporter->Report( msg, RPT_SEVERITY_ERROR );
210 }
211
212 return;
213 }
214
215 // Open the plotter and do the first page
216 setupPlotPagePDF( plotter, screen, aPlotOpts );
217
218 plotter->StartPlot( sheetList[i].GetPageNumber(), sheetName );
219 }
220 catch( const IO_ERROR& e )
221 {
222 // Cannot plot PDF file
223 if( aReporter )
224 {
225 msg.Printf( wxT( "PDF Plotter exception: %s" ), e.What() );
226 aReporter->Report( msg, RPT_SEVERITY_ERROR );
227 }
228
229 return;
230 }
231 }
232 else
233 {
234 /* For the following pages you need to close the (finished) page,
235 * reconfigure, and then start a new one */
236 plotter->ClosePage();
237 setupPlotPagePDF( plotter, screen, aPlotOpts );
238 SCH_SHEET_PATH parentSheet = sheetList[i];
239
240 if( parentSheet.size() > 1 )
241 {
242 // The sheet path is the full path to the sheet, so we need to remove the last
243 // sheet name to get the parent sheet path
244 parentSheet.pop_back();
245 }
246
247 wxString parentSheetName = parentSheet.Last()->GetField( FIELD_T::SHEET_NAME )->GetShownText( FOR_GUI );
248
249 plotter->StartPage( sheetList[i].GetPageNumber(), sheetName, parentSheet.GetPageNumber(), parentSheetName );
250 }
251
252 plotOneSheetPDF( plotter, screen, aPlotOpts );
253 }
254
255 // Everything done, close the plot and restore the environment
256 if( aReporter )
257 {
258 msg.Printf( _( "Plotted to '%s'.\n" ), plotFileName.GetFullPath() );
259 aReporter->Report( msg, RPT_SEVERITY_ACTION );
260 aReporter->ReportTail( _( "Done." ), RPT_SEVERITY_INFO );
261 }
262}
263
264
266 const SCH_PLOT_OPTS& aPlotOpts )
267{
268 if( aPlotOpts.m_useBackgroundColor && aPlotter->GetColorMode() )
269 {
270 aPlotter->SetColor( aPlotter->RenderSettings()->GetBackgroundColor() );
271
272 // Use page size selected in schematic to know the schematic bg area
273 const PAGE_INFO& actualPage = aScreen->GetPageSettings(); // page size selected in schematic
274 VECTOR2I end( actualPage.GetWidthIU( schIUScale.IU_PER_MILS ),
275 actualPage.GetHeightIU( schIUScale.IU_PER_MILS ) );
276
277 aPlotter->Rect( VECTOR2I( 0, 0 ), end, FILL_T::FILLED_SHAPE, 1.0 );
278 }
279
280 if( aPlotOpts.m_plotDrawingSheet )
281 {
282 COLOR4D color = COLOR4D::BLACK;
283
284 if( aPlotter->GetColorMode() )
286
287 wxString sheetName = m_schematic->CurrentSheet().Last()->GetName();
288 wxString sheetPath = m_schematic->CurrentSheet().PathHumanReadable();
289 const PAGE_INFO& actualPage = aScreen->GetPageSettings(); // page size selected in schematic
290
291 SCHEMATIC* sch = aScreen->Schematic();
292 wxString variantName = sch->GetCurrentVariant();
293 wxString variantDesc = sch->GetVariantDescription( variantName );
294
295 PlotDrawingSheet( aPlotter, &sch->Project(), aScreen->GetTitleBlock(), actualPage, sch->GetProperties(),
296 aScreen->GetPageNumber(), aScreen->GetPageCount(), sheetName, sheetPath,
297 aScreen->GetFileName(), color, aScreen->GetVirtualPageNumber() == 1, variantName,
298 variantDesc );
299 }
300
301 aScreen->Plot( aPlotter, aPlotOpts );
302}
303
304
306 const SCH_PLOT_OPTS& aPlotOpts )
307{
308 PAGE_INFO plotPage; // page size selected to plot
309
310 // Considerations on page size and scaling requests
311 const PAGE_INFO& actualPage = aScreen->GetPageSettings(); // page size selected in schematic
312
313 switch( aPlotOpts.m_pageSizeSelect )
314 {
315 case PAGE_SIZE_A:
316 plotPage.SetType( wxT( "A" ) );
317 plotPage.SetPortrait( actualPage.IsPortrait() );
318 break;
319
320 case PAGE_SIZE_A4:
321 plotPage.SetType( wxT( "A4" ) );
322 plotPage.SetPortrait( actualPage.IsPortrait() );
323 break;
324
325 case PAGE_SIZE_AUTO:
326 default:
327 plotPage = actualPage;
328 break;
329 }
330
331 double scalex = (double) plotPage.GetWidthMils() / actualPage.GetWidthMils();
332 double scaley = (double) plotPage.GetHeightMils() / actualPage.GetHeightMils();
333 double scale = std::min( scalex, scaley );
334 aPlotter->SetPageSettings( plotPage );
335
336 // Currently, plot units are in decimil
337 aPlotter->SetViewport( VECTOR2I( 0, 0 ), schIUScale.IU_PER_MILS / 10, scale, false );
338}
339
340
342 SCH_RENDER_SETTINGS* aRenderSettings, REPORTER* aReporter )
343{
344 SCH_SHEET_PATH oldsheetpath = m_schematic->CurrentSheet(); // sheetpath is saved here
345 PAGE_INFO plotPage; // page size selected to plot
346 wxString msg;
347 PLOT_CONTEXT raii( nullptr, m_schematic );
348
349 /* When printing all pages, the printed page is not the current page.
350 * In complex hierarchies, we must update symbol references and other parameters in the
351 * given printed SCH_SCREEN, accordant to the sheet path because in complex hierarchies
352 * a SCH_SCREEN (a drawing ) is shared between many sheets and symbol references
353 * depend on the actual sheet path used.
354 */
355 SCH_SHEET_LIST sheetList;
356
357 if( aPlotOpts.m_plotAll || aPlotOpts.m_plotPages.size() > 0 )
358 {
359 sheetList.BuildSheetList( &m_schematic->Root(), true );
361
362 // remove the non-selected pages if we are in plot pages mode
363 if( aPlotOpts.m_plotPages.size() > 0 )
364 sheetList.TrimToPageNumbers( aPlotOpts.m_plotPages );
365 }
366 else
367 {
368 sheetList.push_back( aPlotOpts.m_sheetPath.value_or( m_schematic->CurrentSheet() ) );
369 }
370
371 for( unsigned i = 0; i < sheetList.size(); i++ )
372 {
373 m_schematic->SetCurrentSheet( sheetList[i] );
374 m_schematic->CurrentSheet().UpdateAllScreenReferences();
375 m_schematic->SetSheetNumberAndCount();
376
377 SCH_SCREEN* screen = m_schematic->CurrentSheet().LastScreen();
378 PAGE_INFO actualPage = screen->GetPageSettings();
379
380 switch( aPlotOpts.m_pageSizeSelect )
381 {
382 case PAGE_SIZE_A:
383 plotPage.SetType( wxT( "A" ) );
384 plotPage.SetPortrait( actualPage.IsPortrait() );
385 break;
386
387 case PAGE_SIZE_A4:
388 plotPage.SetType( wxT( "A4" ) );
389 plotPage.SetPortrait( actualPage.IsPortrait() );
390 break;
391
392 case PAGE_SIZE_AUTO:
393 default:
394 plotPage = actualPage;
395 break;
396 }
397
398 double scalex = (double) plotPage.GetWidthMils() / actualPage.GetWidthMils();
399 double scaley = (double) plotPage.GetHeightMils() / actualPage.GetHeightMils();
400 double scale = std::min( scalex, scaley );
401 VECTOR2I plot_offset;
402
403 try
404 {
405 wxFileName plotFileName;
406
407 if( !aPlotOpts.m_outputFile.empty() )
408 {
409 plotFileName = wxFileName( aPlotOpts.m_outputFile );
410
411 if( plotFileName.GetExt().IsEmpty() )
412 plotFileName.SetExt( PS_PLOTTER::GetDefaultFileExtension() );
413 }
414 else
415 {
416 wxString fname = m_schematic->GetUniqueFilenameForCurrentSheet();
417
418 // The sub sheet can be in a sub_hierarchy, but we plot the file in the
419 // main project folder (or the folder specified by the caller),
420 // so replace separators to create a unique filename:
421 fname.Replace( "/", "_" );
422 fname.Replace( "\\", "_" );
423
424 plotFileName = createPlotFileName( aPlotOpts, fname, PS_PLOTTER::GetDefaultFileExtension(),
425 aReporter );
426 }
427
428 m_lastOutputFilePath = plotFileName.GetFullPath();
430
431 if( !plotFileName.IsOk() )
432 {
433 if( aReporter )
434 {
435 // Error
436 msg.Printf( _( "Failed to create file '%s'." ), plotFileName.GetFullPath() );
437 aReporter->Report( msg, RPT_SEVERITY_ERROR );
438 }
439 }
440 else if( plotOneSheetPS( plotFileName.GetFullPath(), screen, aRenderSettings,
441 actualPage, plot_offset, scale, aPlotOpts ) )
442 {
443 if( aReporter )
444 {
445 msg.Printf( _( "Plotted to '%s'." ), plotFileName.GetFullPath() );
446 aReporter->Report( msg, RPT_SEVERITY_ACTION );
447 }
448 }
449 else
450 {
451 if( aReporter )
452 {
453 // Error
454 msg.Printf( _( "Failed to create file '%s'." ), plotFileName.GetFullPath() );
455 aReporter->Report( msg, RPT_SEVERITY_ERROR );
456 }
457 }
458
459 if( !aPlotOpts.m_outputFile.empty() )
460 break;
461 }
462 catch( IO_ERROR& e )
463 {
464 if( aReporter )
465 {
466 msg.Printf( wxT( "PS Plotter exception: %s" ), e.What() );
467 aReporter->Report( msg, RPT_SEVERITY_ERROR );
468 }
469 }
470 }
471
472 if( aReporter )
473 aReporter->ReportTail( _( "Done." ), RPT_SEVERITY_INFO );
474}
475
476
477bool SCH_PLOTTER::plotOneSheetPS( const wxString& aFileName, SCH_SCREEN* aScreen,
478 RENDER_SETTINGS* aRenderSettings, const PAGE_INFO& aPageInfo,
479 const VECTOR2I& aPlot0ffset, double aScale,
480 const SCH_PLOT_OPTS& aPlotOpts )
481{
482 PS_PLOTTER* plotter = new PS_PLOTTER();
483 plotter->SetRenderSettings( aRenderSettings );
484 plotter->SetPageSettings( aPageInfo );
485 plotter->SetColorMode( !aPlotOpts.m_blackAndWhite );
486
487 // Currently, plot units are in decimil
488 plotter->SetViewport( aPlot0ffset, schIUScale.IU_PER_MILS / 10, aScale, false );
489
490 // Init :
491 plotter->SetCreator( wxT( "Eeschema-PS" ) );
492
493 if( !plotter->OpenFile( aFileName ) )
494 {
495 delete plotter;
496 return false;
497 }
498
499 plotter->StartPlot( m_schematic->CurrentSheet().GetPageNumber() );
500
501 if( aPlotOpts.m_useBackgroundColor && plotter->GetColorMode() )
502 {
504
505 // Use page size selected in schematic to know the schematic bg area
506 const PAGE_INFO& actualPage = aScreen->GetPageSettings(); // page size selected in schematic
507 VECTOR2I end( actualPage.GetWidthIU( schIUScale.IU_PER_MILS ),
508 actualPage.GetHeightIU( schIUScale.IU_PER_MILS ) );
509
510 plotter->Rect( VECTOR2I( 0, 0 ), end, FILL_T::FILLED_SHAPE, 1.0, 0 );
511 }
512
513 if( aPlotOpts.m_plotDrawingSheet )
514 {
515 wxString sheetName = m_schematic->CurrentSheet().Last()->GetName();
516 wxString sheetPath = m_schematic->CurrentSheet().PathHumanReadable();
518
519 SCHEMATIC* sch = aScreen->Schematic();
520 wxString variantName = sch->GetCurrentVariant();
521 wxString variantDesc = sch->GetVariantDescription( variantName );
522
523 PlotDrawingSheet( plotter, &sch->Project(), aScreen->GetTitleBlock(), aPageInfo, sch->GetProperties(),
524 aScreen->GetPageNumber(), aScreen->GetPageCount(), sheetName, sheetPath,
525 aScreen->GetFileName(), plotter->GetColorMode() ? color : COLOR4D::BLACK,
526 aScreen->GetVirtualPageNumber() == 1, variantName, variantDesc );
527 }
528
529 aScreen->Plot( plotter, aPlotOpts );
530
531 plotter->EndPlot();
532 delete plotter;
533
534 return true;
535}
536
537
539 SCH_RENDER_SETTINGS* aRenderSettings, REPORTER* aReporter )
540{
541 wxString msg;
542 SCH_SHEET_PATH oldsheetpath = m_schematic->CurrentSheet();
543 SCH_SHEET_LIST sheetList;
544 PLOT_CONTEXT raii( nullptr, m_schematic );
545
546 if( aPlotOpts.m_plotAll || aPlotOpts.m_plotPages.size() > 0 )
547 {
548 sheetList.BuildSheetList( &m_schematic->Root(), true );
550
551 // remove the non-selected pages if we are in plot pages mode
552 if( aPlotOpts.m_plotPages.size() > 0 )
553 sheetList.TrimToPageNumbers( aPlotOpts.m_plotPages );
554 }
555 else
556 {
557 // in Eeschema, this prints the current page
558 sheetList.push_back( aPlotOpts.m_sheetPath.value_or( m_schematic->CurrentSheet() ) );
559 }
560
561 for( unsigned i = 0; i < sheetList.size(); i++ )
562 {
563 SCH_SCREEN* screen;
564
565 m_schematic->SetCurrentSheet( sheetList[i] );
566 m_schematic->CurrentSheet().UpdateAllScreenReferences();
567 m_schematic->SetSheetNumberAndCount();
568
569 screen = m_schematic->CurrentSheet().LastScreen();
570
571 try
572 {
573 wxFileName plotFileName;
574
575 if( !aPlotOpts.m_outputFile.empty() )
576 {
577 plotFileName = wxFileName( aPlotOpts.m_outputFile );
578
579 if( plotFileName.GetExt().IsEmpty() )
580 plotFileName.SetExt( SVG_PLOTTER::GetDefaultFileExtension() );
581 }
582 else
583 {
584 wxString fname = m_schematic->GetUniqueFilenameForCurrentSheet();
585
586 // The sub sheet can be in a sub_hierarchy, but we plot the file in the
587 // main project folder (or the folder specified by the caller),
588 // so replace separators to create a unique filename:
589 fname.Replace( "/", "_" );
590 fname.Replace( "\\", "_" );
591
592 plotFileName = createPlotFileName( aPlotOpts, fname, SVG_PLOTTER::GetDefaultFileExtension(),
593 aReporter );
594 }
595
596 m_lastOutputFilePath = plotFileName.GetFullPath();
598
599 if( !plotFileName.IsOk() )
600 return;
601
602 bool success = plotOneSheetSVG( plotFileName.GetFullPath(), screen, aRenderSettings, aPlotOpts );
603
604 if( !success )
605 {
606 if( aReporter )
607 {
608 msg.Printf( _( "Failed to create file '%s'." ), plotFileName.GetFullPath() );
609 aReporter->Report( msg, RPT_SEVERITY_ERROR );
610 }
611 }
612 else
613 {
614 if( aReporter )
615 {
616 msg.Printf( _( "Plotted to '%s'." ), plotFileName.GetFullPath() );
617 aReporter->Report( msg, RPT_SEVERITY_ACTION );
618 }
619 }
620
621 if( !aPlotOpts.m_outputFile.empty() )
622 break;
623 }
624 catch( const IO_ERROR& e )
625 {
626 if( aReporter )
627 {
628 // Cannot plot SVG file
629 msg.Printf( wxT( "SVG Plotter exception: %s" ), e.What() );
630 aReporter->Report( msg, RPT_SEVERITY_ERROR );
631 }
632
633 break;
634 }
635 }
636
637 if( aReporter )
638 aReporter->ReportTail( _( "Done." ), RPT_SEVERITY_INFO );
639}
640
641
642bool SCH_PLOTTER::plotOneSheetSVG( const wxString& aFileName, SCH_SCREEN* aScreen,
643 RENDER_SETTINGS* aRenderSettings,
644 const SCH_PLOT_OPTS& aPlotOpts )
645{
646 PAGE_INFO plotPage;
647
648 // Adjust page size and scaling requests
649 const PAGE_INFO& actualPage = aScreen->GetPageSettings(); // page size selected in schematic
650
651 switch( aPlotOpts.m_pageSizeSelect )
652 {
653 case PAGE_SIZE_A:
654 plotPage.SetType( wxT( "A" ) );
655 plotPage.SetPortrait( actualPage.IsPortrait() );
656 break;
657
658 case PAGE_SIZE_A4:
659 plotPage.SetType( wxT( "A4" ) );
660 plotPage.SetPortrait( actualPage.IsPortrait() );
661 break;
662
663 case PAGE_SIZE_AUTO:
664 default:
665 plotPage = actualPage;
666 break;
667 }
668
669 SVG_PLOTTER* plotter = new SVG_PLOTTER();
670 plotter->SetRenderSettings( aRenderSettings );
671 plotter->SetPageSettings( plotPage );
672 plotter->SetColorMode( aPlotOpts.m_blackAndWhite ? false : true );
673 VECTOR2I plot_offset;
674
675 double scalex = (double) plotPage.GetWidthMils() / actualPage.GetWidthMils();
676 double scaley = (double) plotPage.GetHeightMils() / actualPage.GetHeightMils();
677 double scale = std::min( scalex, scaley );
678
679 // Currently, plot units are in decimil
680 plotter->SetViewport( plot_offset, schIUScale.IU_PER_MILS / 10, scale, false );
681
682 // Init :
683 plotter->SetCreator( wxT( "Eeschema-SVG" ) );
684
685 if( !plotter->OpenFile( aFileName ) )
686 {
687 delete plotter;
688 return false;
689 }
690
691 plotter->StartPlot( m_schematic->CurrentSheet().GetPageNumber() );
692
693 if( aPlotOpts.m_useBackgroundColor && plotter->GetColorMode() )
694 {
696
697 // Use page size selected in schematic to know the schematic bg area
698 VECTOR2I end( actualPage.GetWidthIU( schIUScale.IU_PER_MILS ),
699 actualPage.GetHeightIU( schIUScale.IU_PER_MILS ) );
700
701 plotter->Rect( VECTOR2I( 0, 0 ), end, FILL_T::FILLED_SHAPE, 1.0, 0 );
702 }
703
704 if( aPlotOpts.m_plotDrawingSheet )
705 {
706 wxString sheetName = m_schematic->CurrentSheet().Last()->GetName();
707 wxString sheetPath = m_schematic->CurrentSheet().PathHumanReadable();
709
710 SCHEMATIC* sch = aScreen->Schematic();
711 wxString variantName = sch->GetCurrentVariant();
712 wxString variantDesc = sch->GetVariantDescription( variantName );
713
714 PlotDrawingSheet( plotter, &sch->Project(), aScreen->GetTitleBlock(), actualPage, sch->GetProperties(),
715 aScreen->GetPageNumber(), aScreen->GetPageCount(), sheetName, sheetPath,
716 aScreen->GetFileName(), plotter->GetColorMode() ? color : COLOR4D::BLACK,
717 aScreen->GetVirtualPageNumber() == 1, variantName, variantDesc );
718 }
719
720 aScreen->Plot( plotter, aPlotOpts );
721
722 plotter->EndPlot();
723 delete plotter;
724
725 return true;
726}
727
728
730 SCH_RENDER_SETTINGS* aRenderSettings, REPORTER* aReporter )
731{
732 wxString msg;
733 SCH_SHEET_PATH oldsheetpath = m_schematic->CurrentSheet();
734 SCH_SHEET_LIST sheetList;
735 PLOT_CONTEXT raii( nullptr, m_schematic );
736
737 if( aPlotOpts.m_plotAll || aPlotOpts.m_plotPages.size() > 0 )
738 {
739 sheetList.BuildSheetList( &m_schematic->Root(), true );
741
742 if( aPlotOpts.m_plotPages.size() > 0 )
743 sheetList.TrimToPageNumbers( aPlotOpts.m_plotPages );
744 }
745 else
746 {
747 sheetList.push_back( aPlotOpts.m_sheetPath.value_or( m_schematic->CurrentSheet() ) );
748 }
749
750 for( unsigned i = 0; i < sheetList.size(); i++ )
751 {
752 SCH_SCREEN* screen;
753
754 m_schematic->SetCurrentSheet( sheetList[i] );
755 m_schematic->CurrentSheet().UpdateAllScreenReferences();
756 m_schematic->SetSheetNumberAndCount();
757
758 screen = m_schematic->CurrentSheet().LastScreen();
759
760 try
761 {
762 wxFileName plotFileName;
763
764 if( !aPlotOpts.m_outputFile.empty() )
765 {
766 plotFileName = wxFileName( aPlotOpts.m_outputFile );
767
768 if( plotFileName.GetExt().IsEmpty() )
769 plotFileName.SetExt( PNG_PLOTTER::GetDefaultFileExtension() );
770 }
771 else
772 {
773 wxString fname = m_schematic->GetUniqueFilenameForCurrentSheet();
774
775 fname.Replace( "/", "_" );
776 fname.Replace( "\\", "_" );
777
778 plotFileName = createPlotFileName( aPlotOpts, fname, PNG_PLOTTER::GetDefaultFileExtension(),
779 aReporter );
780 }
781
782 m_lastOutputFilePath = plotFileName.GetFullPath();
784
785 if( !plotFileName.IsOk() )
786 return;
787
788 bool success = plotOneSheetPNG( plotFileName.GetFullPath(), screen, aRenderSettings,
789 aPlotOpts );
790
791 if( aReporter )
792 {
793 if( !success )
794 {
795 msg.Printf( _( "Failed to create file '%s'." ), plotFileName.GetFullPath() );
796 aReporter->Report( msg, RPT_SEVERITY_ERROR );
797 }
798 else
799 {
800 msg.Printf( _( "Plotted to '%s'." ), plotFileName.GetFullPath() );
801 aReporter->Report( msg, RPT_SEVERITY_ACTION );
802 }
803 }
804
805 if( !aPlotOpts.m_outputFile.empty() )
806 break;
807 }
808 catch( const IO_ERROR& e )
809 {
810 if( aReporter )
811 {
812 msg.Printf( wxT( "PNG Plotter exception: %s" ), e.What() );
813 aReporter->Report( msg, RPT_SEVERITY_ERROR );
814 }
815
816 break;
817 }
818 }
819
820 if( aReporter )
821 aReporter->ReportTail( _( "Done." ), RPT_SEVERITY_INFO );
822}
823
824
825bool SCH_PLOTTER::plotOneSheetPNG( const wxString& aFileName, SCH_SCREEN* aScreen,
826 RENDER_SETTINGS* aRenderSettings,
827 const SCH_PLOT_OPTS& aPlotOpts )
828{
829 PAGE_INFO plotPage;
830 const PAGE_INFO& actualPage = aScreen->GetPageSettings();
831
832 switch( aPlotOpts.m_pageSizeSelect )
833 {
834 case PAGE_SIZE_A:
835 plotPage.SetType( wxT( "A" ) );
836 plotPage.SetPortrait( actualPage.IsPortrait() );
837 break;
838
839 case PAGE_SIZE_A4:
840 plotPage.SetType( wxT( "A4" ) );
841 plotPage.SetPortrait( actualPage.IsPortrait() );
842 break;
843
844 case PAGE_SIZE_AUTO:
845 default:
846 plotPage = actualPage;
847 break;
848 }
849
850 int dpi = std::clamp( aPlotOpts.m_pngDPI, MIN_PNG_DPI, MAX_PNG_DPI );
851
852 int pixelW = KiROUND( static_cast<double>( plotPage.GetWidthMils() ) * dpi / 1000.0 );
853 int pixelH = KiROUND( static_cast<double>( plotPage.GetHeightMils() ) * dpi / 1000.0 );
854
855 PNG_PLOTTER* plotter = new PNG_PLOTTER();
856
857 plotter->SetPixelSize( pixelW, pixelH );
858 plotter->SetResolution( dpi );
859 plotter->SetAntialias( aPlotOpts.m_pngAntialias );
860
861 // Schematic IU is Y-down (matches Cairo); leave SetYAxisReversed at its default of false.
862 // pcbnew sets it true because PCB IU is Y-up. Do not copy that wiring here.
863
864 plotter->SetRenderSettings( aRenderSettings );
865 plotter->SetPageSettings( plotPage );
866 plotter->SetColorMode( !aPlotOpts.m_blackAndWhite );
867
868 VECTOR2I plot_offset;
869 double scalex = (double) plotPage.GetWidthMils() / actualPage.GetWidthMils();
870 double scaley = (double) plotPage.GetHeightMils() / actualPage.GetHeightMils();
871 double scale = std::min( scalex, scaley );
872
873 plotter->SetViewport( plot_offset, schIUScale.IU_PER_MILS / 10, scale, false );
874 plotter->SetCreator( wxT( "Eeschema-PNG" ) );
875
876 if( !plotter->OpenFile( aFileName ) )
877 {
878 delete plotter;
879 return false;
880 }
881
882 plotter->StartPlot( m_schematic->CurrentSheet().GetPageNumber() );
883
884 if( aPlotOpts.m_useBackgroundColor && plotter->GetColorMode() )
885 {
887
888 VECTOR2I end( actualPage.GetWidthIU( schIUScale.IU_PER_MILS ),
889 actualPage.GetHeightIU( schIUScale.IU_PER_MILS ) );
890
891 plotter->Rect( VECTOR2I( 0, 0 ), end, FILL_T::FILLED_SHAPE, 1.0, 0 );
892 }
893
894 if( aPlotOpts.m_plotDrawingSheet )
895 {
896 wxString sheetName = m_schematic->CurrentSheet().Last()->GetName();
897 wxString sheetPath = m_schematic->CurrentSheet().PathHumanReadable();
899
900 SCHEMATIC* sch = aScreen->Schematic();
901 wxString variantName = sch->GetCurrentVariant();
902 wxString variantDesc = sch->GetVariantDescription( variantName );
903
904 PlotDrawingSheet( plotter, &sch->Project(), aScreen->GetTitleBlock(), actualPage,
905 sch->GetProperties(), aScreen->GetPageNumber(), aScreen->GetPageCount(),
906 sheetName, sheetPath, aScreen->GetFileName(),
907 plotter->GetColorMode() ? color : COLOR4D::BLACK,
908 aScreen->GetVirtualPageNumber() == 1, variantName, variantDesc );
909 }
910
911 aScreen->Plot( plotter, aPlotOpts );
912
913 bool success = plotter->EndPlot();
914 delete plotter;
915
916 return success;
917}
918
919
920void SCH_PLOTTER::createDXFFiles( const SCH_PLOT_OPTS& aPlotOpts, SCH_RENDER_SETTINGS* aRenderSettings,
921 REPORTER* aReporter )
922{
923 PLOT_CONTEXT( nullptr, m_schematic );
924
925 /* When printing all pages, the printed page is not the current page. In complex hierarchies,
926 * we must update symbol references and other parameters in the given printed SCH_SCREEN,
927 * according to the sheet path because in complex hierarchies a SCH_SCREEN (a drawing ) is
928 * shared between many sheets and symbol references depend on the actual sheet path used.
929 */
930 SCH_SHEET_LIST sheetList;
931
932 if( aPlotOpts.m_plotAll || aPlotOpts.m_plotPages.size() > 0 )
933 {
934 sheetList.BuildSheetList( &m_schematic->Root(), true );
936
937 // remove the non-selected pages if we are in plot pages mode
938 if( aPlotOpts.m_plotPages.size() > 0 )
939 sheetList.TrimToPageNumbers( aPlotOpts.m_plotPages );
940 }
941 else
942 {
943 // in Eeschema, this prints the current page
944 sheetList.push_back( aPlotOpts.m_sheetPath.value_or( m_schematic->CurrentSheet() ) );
945 }
946
947 for( unsigned i = 0; i < sheetList.size(); i++ )
948 {
949 m_schematic->SetCurrentSheet( sheetList[i] );
950 m_schematic->CurrentSheet().UpdateAllScreenReferences();
951 m_schematic->SetSheetNumberAndCount();
952
953 SCH_SCREEN* screen = m_schematic->CurrentSheet().LastScreen();
954 VECTOR2I plot_offset;
955 wxString msg;
956
957 try
958 {
959 wxFileName plotFileName;
960
961 if( !aPlotOpts.m_outputFile.empty() )
962 {
963 plotFileName = wxFileName( aPlotOpts.m_outputFile );
964
965 if( plotFileName.GetExt().IsEmpty() )
966 plotFileName.SetExt( DXF_PLOTTER::GetDefaultFileExtension() );
967 }
968 else
969 {
970 wxString fname = m_schematic->GetUniqueFilenameForCurrentSheet();
971
972 // The sub sheet can be in a sub_hierarchy, but we plot the file in the
973 // main project folder (or the folder specified by the caller),
974 // so replace separators to create a unique filename:
975 fname.Replace( "/", "_" );
976 fname.Replace( "\\", "_" );
977
978 plotFileName = createPlotFileName( aPlotOpts, fname, DXF_PLOTTER::GetDefaultFileExtension(),
979 aReporter );
980 }
981
982 m_lastOutputFilePath = plotFileName.GetFullPath();
984
985 if( !plotFileName.IsOk() )
986 return;
987
988 if( plotOneSheetDXF( plotFileName.GetFullPath(), screen, aRenderSettings, plot_offset,
989 1.0, aPlotOpts ) )
990 {
991 if( aReporter )
992 {
993 msg.Printf( _( "Plotted to '%s'." ), plotFileName.GetFullPath() );
994 aReporter->Report( msg, RPT_SEVERITY_ACTION );
995 }
996 }
997 else // Error
998 {
999 if( aReporter )
1000 {
1001 msg.Printf( _( "Failed to create file '%s'." ), plotFileName.GetFullPath() );
1002 aReporter->Report( msg, RPT_SEVERITY_ERROR );
1003 }
1004 }
1005
1006 if( !aPlotOpts.m_outputFile.empty() )
1007 break;
1008 }
1009 catch( IO_ERROR& e )
1010 {
1011 if( aReporter )
1012 {
1013 msg.Printf( wxT( "DXF Plotter exception: %s" ), e.What() );
1014 aReporter->Report( msg, RPT_SEVERITY_ERROR );
1015 }
1016
1017 return;
1018 }
1019 }
1020
1021 if( aReporter )
1022 aReporter->ReportTail( _( "Done." ), RPT_SEVERITY_INFO );
1023}
1024
1025
1026bool SCH_PLOTTER::plotOneSheetDXF( const wxString& aFileName, SCH_SCREEN* aScreen,
1027 RENDER_SETTINGS* aRenderSettings, const VECTOR2I& aPlotOffset,
1028 double aScale, const SCH_PLOT_OPTS& aPlotOpts )
1029{
1030 aRenderSettings->LoadColors( m_colorSettings );
1031 aRenderSettings->SetDefaultPenWidth( 0 );
1032
1033 const PAGE_INFO& pageInfo = aScreen->GetPageSettings();
1034 DXF_PLOTTER* plotter = new DXF_PLOTTER();
1035
1036 plotter->SetUnits( aPlotOpts.m_DXF_File_Unit );
1037
1038 plotter->SetRenderSettings( aRenderSettings );
1039 plotter->SetPageSettings( pageInfo );
1040 plotter->SetColorMode( !aPlotOpts.m_blackAndWhite );
1041
1042 // Currently, plot units are in decimil
1043 plotter->SetViewport( aPlotOffset, schIUScale.IU_PER_MILS / 10, aScale, false );
1044
1045 // Init :
1046 plotter->SetCreator( wxT( "Eeschema-DXF" ) );
1047
1048 if( !plotter->OpenFile( aFileName ) )
1049 {
1050 delete plotter;
1051 return false;
1052 }
1053
1054 plotter->StartPlot( m_schematic->CurrentSheet().GetPageNumber() );
1055
1056 if( aPlotOpts.m_plotDrawingSheet )
1057 {
1058 wxString sheetName = m_schematic->CurrentSheet().Last()->GetName();
1059 wxString sheetPath = m_schematic->CurrentSheet().PathHumanReadable();
1061
1062 wxString variantName = m_schematic->GetCurrentVariant();
1063 wxString variantDesc = m_schematic->GetVariantDescription( variantName );
1064
1065 PlotDrawingSheet( plotter, &m_schematic->Project(), aScreen->GetTitleBlock(), pageInfo,
1066 m_schematic->GetProperties(), aScreen->GetPageNumber(), aScreen->GetPageCount(), sheetName,
1067 sheetPath, aScreen->GetFileName(), plotter->GetColorMode() ? color : COLOR4D::BLACK,
1068 aScreen->GetVirtualPageNumber() == 1, variantName, variantDesc );
1069 }
1070
1071 aScreen->Plot( plotter, aPlotOpts );
1072
1073 // finish
1074 plotter->EndPlot();
1075 delete plotter;
1076
1077 return true;
1078}
1079
1080
1082 const wxString& aPlotFileName,
1083 const wxString& aExtension, REPORTER* aReporter )
1084{
1085 wxFileName retv;
1086 wxFileName tmp;
1087
1088 tmp.SetPath( aPlotOpts.m_outputDirectory );
1089 retv.SetPath( tmp.GetPath() );
1090
1091 if( !aPlotFileName.IsEmpty() )
1092 retv.SetName( aPlotFileName );
1093 else
1094 retv.SetName( _( "Schematic" ) );
1095
1096 retv.SetExt( aExtension );
1097
1098 if( !EnsureFileDirectoryExists( &tmp, retv.GetFullName(), aReporter ) || !tmp.IsDirWritable() )
1099 {
1100 if( aReporter )
1101 {
1102 wxString msg = wxString::Format( _( "Failed to write plot files to folder '%s'." ),
1103 tmp.GetPath() );
1104 aReporter->Report( msg, RPT_SEVERITY_ERROR );
1105 }
1106
1107 retv.Clear();
1108
1109 SCHEMATIC_SETTINGS& settings = m_schematic->Settings();
1110 settings.m_PlotDirectoryName.Clear();
1111 }
1112 else
1113 {
1114 retv.SetPath( tmp.GetPath() );
1115 }
1116
1117 wxLogTrace( tracePathsAndFiles, "Writing plot file '%s'.", retv.GetFullPath() );
1118
1119 return retv;
1120}
1121
1122
1123void SCH_PLOTTER::Plot( PLOT_FORMAT aPlotFormat, const SCH_PLOT_OPTS& aPlotOpts,
1124 SCH_RENDER_SETTINGS* aRenderSettings, REPORTER* aReporter )
1125{
1126 m_outputFilePaths.clear();
1127
1128 wxString oldVariant = m_schematic->GetCurrentVariant();
1129 m_schematic->SetCurrentVariant( aPlotOpts.m_variant );
1131
1132 switch( aPlotFormat )
1133 {
1134 default:
1135 case PLOT_FORMAT::POST: createPSFiles( aPlotOpts, aRenderSettings, aReporter ); break;
1136 case PLOT_FORMAT::DXF: createDXFFiles( aPlotOpts, aRenderSettings, aReporter ); break;
1137 case PLOT_FORMAT::PDF: createPDFFile( aPlotOpts, aRenderSettings, aReporter ); break;
1138 case PLOT_FORMAT::SVG: createSVGFiles( aPlotOpts, aRenderSettings, aReporter ); break;
1139 case PLOT_FORMAT::PNG: createPNGFiles( aPlotOpts, aRenderSettings, aReporter ); break;
1140 case PLOT_FORMAT::HPGL: /* no longer supported */ break;
1141 }
1142
1143 m_schematic->SetCurrentVariant( oldVariant );
1144}
1145
1146
1147BOX2I GetSymbolPlotBBox( const LIB_SYMBOL& aSymbol, int aUnit, int aBodyStyle, bool aIncludeHiddenFields )
1148{
1149 std::unique_ptr<LIB_SYMBOL> flatSymbol = aSymbol.Flatten();
1150
1151 BOX2I symbolBB = flatSymbol->GetUnitBoundingBox( aUnit, aBodyStyle, !aIncludeHiddenFields );
1152
1153 // Inflate the bbox by "some margin". A lot bounding boxes are slightly
1154 // small because a stroke size of '0' is actually 'inherit', by default 6 mils,
1155 // but the actual value can unly be known for sure with the schematic context.
1156 // A margin of 2mm seems to cover most evantualities, but this is a bit of a
1157 // guess.
1158
1159 const int expansion = schIUScale.mmToIU( 2 );
1160 symbolBB.Inflate( expansion );
1161
1162 return symbolBB;
1163}
1164
1165
1166bool PlotSymbolToSVG( LIB_SYMBOL& aDrawSymbol, LIB_SYMBOL& aFieldsSymbol, int aUnit, int aBodyStyle, const BOX2I& aBBox,
1167 SCH_RENDER_SETTINGS& aRenderSettings, bool aBlackAndWhite, const wxString& aFileName,
1168 REPORTER* aReporter )
1169{
1170 PAGE_INFO pageInfo( PAGE_SIZE_TYPE::User );
1171 pageInfo.SetHeightMils( schIUScale.IUToMils( aBBox.GetHeight() ) );
1172 pageInfo.SetWidthMils( schIUScale.IUToMils( aBBox.GetWidth() ) );
1173
1174 std::unique_ptr<SVG_PLOTTER> plotter = std::make_unique<SVG_PLOTTER>();
1175 plotter->SetRenderSettings( &aRenderSettings );
1176 plotter->SetPageSettings( pageInfo );
1177 plotter->SetColorMode( !aBlackAndWhite );
1178
1179 // Currently, plot units are in decimal. Keep the symbol origin at the SVG origin; the
1180 // viewBox is the content bbox.
1181 plotter->SetViewport( VECTOR2I( 0, 0 ), schIUScale.IU_PER_MILS / 10, 1.0, false );
1182 plotter->SetPlotBBox( aBBox );
1183
1184 plotter->SetCreator( wxT( "Eeschema-SVG" ) );
1185
1186 if( !plotter->OpenFile( aFileName ) )
1187 {
1188 if( aReporter )
1189 {
1190 aReporter->Report( wxString::Format( _( "Unable to open destination '%s'" ) + wxS( "\n" ),
1191 aFileName ),
1193 }
1194 return false;
1195 }
1196
1197 LOCALE_IO toggle;
1198 SCH_PLOT_OPTS plotOpts;
1199
1200 plotter->StartPlot( wxS( "1" ) );
1201
1202 constexpr bool background = true;
1203 aDrawSymbol.Plot( plotter.get(), background, plotOpts, aUnit, aBodyStyle, VECTOR2I( 0, 0 ), false );
1204 aDrawSymbol.Plot( plotter.get(), !background, plotOpts, aUnit, aBodyStyle, VECTOR2I( 0, 0 ), false );
1205 aFieldsSymbol.PlotFields( plotter.get(), !background, plotOpts, aUnit, aBodyStyle, VECTOR2I( 0, 0 ), false );
1206
1207 plotter->EndPlot();
1208 return true;
1209}
constexpr EDA_IU_SCALE schIUScale
Definition base_units.h:130
BOX2< VECTOR2I > BOX2I
Definition box2.h:914
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Definition box2.h:982
int GetPageCount() const
Definition base_screen.h:68
int GetVirtualPageNumber() const
Definition base_screen.h:71
const wxString & GetPageNumber() const
constexpr BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition box2.h:553
constexpr size_type GetWidth() const
Definition box2.h:211
constexpr size_type GetHeight() const
Definition box2.h:212
static const COLOR4D BLACK
Definition color4d.h:404
static wxString GetDefaultFileExtension()
void SetUnits(DXF_UNITS aUnit)
Set the units to use for plotting the DXF file.
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.
virtual const wxString What() const
A composite of Problem() and Where()
A color representation with 4 components: red, green, blue, alpha.
Definition color4d.h:101
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.
Define a library symbol object.
Definition lib_symbol.h:114
void Plot(PLOTTER *aPlotter, bool aBackground, const SCH_PLOT_OPTS &aPlotOpts, int aUnit, int aBodyStyle, const VECTOR2I &aOffset, bool aDimmed) override
Plot the item to aPlotter.
void PlotFields(PLOTTER *aPlotter, bool aBackground, const SCH_PLOT_OPTS &aPlotOpts, int aUnit, int aBodyStyle, const VECTOR2I &aOffset, bool aDimmed)
Plot symbol fields.
std::unique_ptr< LIB_SYMBOL > Flatten() const
Return a flattened symbol inheritance to the caller.
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition locale_io.h:37
Describe the page size and margins of a paper page on which to eventually print or plot.
Definition page_info.h:75
void SetPortrait(bool aIsPortrait)
Rotate the paper page 90 degrees.
int GetHeightIU(double aIUScale) const
Get the page height in IU.
Definition page_info.h:163
bool SetType(PAGE_SIZE_TYPE aPageSize, bool aIsPortrait=false)
Set the name of the page type and also the sizes and margins commonly associated with that type name.
void SetHeightMils(double aHeightInMils)
double GetHeightMils() const
Definition page_info.h:142
int GetWidthIU(double aIUScale) const
Get the page width in IU.
Definition page_info.h:154
double GetWidthMils() const
Definition page_info.h:137
bool IsPortrait() const
Definition page_info.h:123
void SetWidthMils(double aWidthInMils)
virtual void ClosePage()
Close the current page in the PDF document (and emit its compressed stream).
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:136
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:190
virtual void SetPageSettings(const PAGE_INFO &aPageSettings)
Definition plotter.h:169
void SetRenderSettings(RENDER_SETTINGS *aSettings)
Definition plotter.h:166
virtual void SetTitle(const wxString &aTitle)
Definition plotter.h:189
RENDER_SETTINGS * RenderSettings()
Definition plotter.h:167
virtual void Rect(const VECTOR2I &p1, const VECTOR2I &p2, FILL_T fill, int width, int aCornerRadius=0)=0
virtual void SetCreator(const wxString &aCreator)
Definition plotter.h:188
bool GetColorMode() const
Definition plotter.h:164
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:163
virtual void SetSubject(const wxString &aSubject)
Definition plotter.h:191
virtual void SetColor(const COLOR4D &color)=0
SCH_SHEET_PATH m_previousSheetPath
SCHEMATIC * m_schematic
PLOTTER * m_plotter
PLOT_CONTEXT(PLOTTER *aPlotter, SCHEMATIC *aSchematic)
PNG rasterization plotter using Cairo graphics library.
Definition plotter_png.h:40
void SetPixelSize(int aWidth, int aHeight)
Set the output image dimensions in pixels.
Definition plotter_png.h:64
virtual void Rect(const VECTOR2I &p1, const VECTOR2I &p2, FILL_T aFill, int aWidth, int aCornerRadius=0) override
void SetResolution(int aDPI)
Set the output resolution in dots per inch.
Definition plotter_png.h:56
virtual bool EndPlot() override
void SetAntialias(bool aEnable)
Enable or disable anti-aliasing.
Definition plotter_png.h:84
virtual void SetColor(const COLOR4D &aColor) override
static wxString GetDefaultFileExtension()
Definition plotter_png.h:50
virtual bool OpenFile(const wxString &aFullFilename) override
Open or create the plot file aFullFilename.
virtual void SetViewport(const VECTOR2I &aOffset, double aIusPerDecimil, double aScale, bool aMirror) override
Set the plot offset and scaling for the current plot.
virtual bool StartPlot(const wxString &aPageNumber) override
virtual void SetColor(const COLOR4D &color) override
The SetColor implementation is split with the subclasses: the PSLIKE computes the rgb values,...
virtual bool EndPlot() override
virtual void Rect(const VECTOR2I &p1, const VECTOR2I &p2, FILL_T fill, int width, int aCornerRadius=0) override
virtual void SetViewport(const VECTOR2I &aOffset, double aIusPerDecimil, double aScale, bool aMirror) override
Set the plot offset and scaling for the current plot.
virtual bool StartPlot(const wxString &aPageNumber) override
The code within this function (and the CloseFilePS function) creates postscript files whose contents ...
static wxString GetDefaultFileExtension()
A pure virtual class used to derive REPORTER objects from.
Definition reporter.h:73
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:121
These are loaded from Eeschema settings but then overwritten by the project settings.
Holds all the data relating to one schematic.
Definition schematic.h:149
wxString GetVariantDescription(const wxString &aVariantName) const
Return the description for a variant.
PROJECT & Project() const
Return a reference to the project this schematic is part of.
Definition schematic.h:171
wxString GetCurrentVariant() const
Return the current variant being edited.
const std::map< wxString, wxString > * GetProperties()
Definition schematic.h:174
Schematic editor (Eeschema) main window.
wxString GetShownText(const SCH_SHEET_PATH *aPath, RESOLUTION_CONTEXT aContext, const wxString &aVariantName=wxEmptyString, int aDepth=0) const
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.
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.
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
std::vector< wxString > m_outputFilePaths
void createPNGFiles(const SCH_PLOT_OPTS &aPlotOpts, SCH_RENDER_SETTINGS *aRenderSettings, REPORTER *aReporter)
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)
bool plotOneSheetPNG(const wxString &aFileName, SCH_SCREEN *aScreen, RENDER_SETTINGS *aRenderSettings, const SCH_PLOT_OPTS &aPlotOpts)
void createPDFFile(const SCH_PLOT_OPTS &aPlotOpts, SCH_RENDER_SETTINGS *aRenderSettings, REPORTER *aReporter)
COLOR_SETTINGS * m_colorSettings
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
const PAGE_INFO & GetPageSettings() const
Definition sch_screen.h:144
const wxString & GetFileName() const
Definition sch_screen.h:157
SCHEMATIC * Schematic() const
TITLE_BLOCK & GetTitleBlock()
Definition sch_screen.h:168
void Plot(PLOTTER *aPlotter, const SCH_PLOT_OPTS &aPlotOpts) const
Plot all the schematic objects to aPlotter.
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 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 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.
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, int aCornerRadius=0) override
virtual bool EndPlot() override
static wxString GetDefaultFileExtension()
wxString ExpandTextVars(const wxString &aSource, const PROJECT *aProject, RESOLUTION_CONTEXT aContext)
Definition common.cpp:60
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:797
@ FOR_GUI
Definition common.h:91
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, const wxString &aVariantName, const wxString &aVariantDesc)
#define _(s)
@ FILLED_SHAPE
Fill with object color.
Definition eda_fill.h:31
const wxChar *const tracePathsAndFiles
Flag to enable path and file name debug output.
@ LAYER_SCHEMATIC_DRAWINGSHEET
Definition layer_ids.h:518
@ LAYER_SCHEMATIC_BACKGROUND
Definition layer_ids.h:510
see class PGM_BASE
PLOT_FORMAT
The set of supported output plot formats.
Definition plotter.h:63
constexpr int MIN_PNG_DPI
Definition plotter_png.h:29
constexpr int MAX_PNG_DPI
Definition plotter_png.h:30
Plotting engines similar to ps (PostScript, Gerber, svg)
@ RPT_SEVERITY_ERROR
@ RPT_SEVERITY_INFO
@ RPT_SEVERITY_ACTION
bool PlotSymbolToSVG(LIB_SYMBOL &aDrawSymbol, LIB_SYMBOL &aFieldsSymbol, int aUnit, int aBodyStyle, const BOX2I &aBBox, SCH_RENDER_SETTINGS &aRenderSettings, bool aBlackAndWhite, const wxString &aFileName, REPORTER *aReporter)
Plot a single symbol variant (unit and body style) to an SVG file.
BOX2I GetSymbolPlotBBox(const LIB_SYMBOL &aSymbol, int aUnit, int aBodyStyle, bool aIncludeHiddenFields)
Compute the bounding box used to size a symbol SVG plot.
@ PAGE_SIZE_AUTO
Definition sch_plotter.h:47
@ PAGE_SIZE_A
Definition sch_plotter.h:49
@ PAGE_SIZE_A4
Definition sch_plotter.h:48
COLOR_SETTINGS * GetColorSettings(const wxString &aName)
const int scale
std::vector< wxString > m_plotPages
Definition sch_plotter.h:57
wxString m_theme
Definition sch_plotter.h:69
DXF_UNITS m_DXF_File_Unit
Definition sch_plotter.h:76
wxString m_outputDirectory
Definition sch_plotter.h:71
std::optional< SCH_SHEET_PATH > m_sheetPath
Definition sch_plotter.h:60
bool m_pngAntialias
Definition sch_plotter.h:79
wxString m_outputFile
Definition sch_plotter.h:72
bool m_blackAndWhite
Definition sch_plotter.h:63
wxString m_variant
Definition sch_plotter.h:73
bool m_useBackgroundColor
Definition sch_plotter.h:65
bool m_plotDrawingSheet
Definition sch_plotter.h:56
VECTOR2I end
wxLogTrace helper definitions.
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:708