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 if( sheetList.empty() )
372 {
373 if( aReporter )
374 aReporter->Report( _( "No sheets to plot." ), RPT_SEVERITY_ERROR );
375
376 return;
377 }
378
379 for( unsigned i = 0; i < sheetList.size(); i++ )
380 {
381 m_schematic->SetCurrentSheet( sheetList[i] );
382 m_schematic->CurrentSheet().UpdateAllScreenReferences();
383 m_schematic->SetSheetNumberAndCount();
384
385 SCH_SCREEN* screen = m_schematic->CurrentSheet().LastScreen();
386 PAGE_INFO actualPage = screen->GetPageSettings();
387
388 switch( aPlotOpts.m_pageSizeSelect )
389 {
390 case PAGE_SIZE_A:
391 plotPage.SetType( wxT( "A" ) );
392 plotPage.SetPortrait( actualPage.IsPortrait() );
393 break;
394
395 case PAGE_SIZE_A4:
396 plotPage.SetType( wxT( "A4" ) );
397 plotPage.SetPortrait( actualPage.IsPortrait() );
398 break;
399
400 case PAGE_SIZE_AUTO:
401 default:
402 plotPage = actualPage;
403 break;
404 }
405
406 double scalex = (double) plotPage.GetWidthMils() / actualPage.GetWidthMils();
407 double scaley = (double) plotPage.GetHeightMils() / actualPage.GetHeightMils();
408 double scale = std::min( scalex, scaley );
409 VECTOR2I plot_offset;
410
411 try
412 {
413 wxFileName plotFileName;
414
415 if( !aPlotOpts.m_outputFile.empty() )
416 {
417 plotFileName = wxFileName( aPlotOpts.m_outputFile );
418
419 if( plotFileName.GetExt().IsEmpty() )
420 plotFileName.SetExt( PS_PLOTTER::GetDefaultFileExtension() );
421 }
422 else
423 {
424 wxString fname = m_schematic->GetUniqueFilenameForCurrentSheet();
425
426 // The sub sheet can be in a sub_hierarchy, but we plot the file in the
427 // main project folder (or the folder specified by the caller),
428 // so replace separators to create a unique filename:
429 fname.Replace( "/", "_" );
430 fname.Replace( "\\", "_" );
431
432 plotFileName = createPlotFileName( aPlotOpts, fname, PS_PLOTTER::GetDefaultFileExtension(),
433 aReporter );
434 }
435
436 m_lastOutputFilePath = plotFileName.GetFullPath();
438
439 if( !plotFileName.IsOk() )
440 {
441 if( aReporter )
442 {
443 // Error
444 msg.Printf( _( "Failed to create file '%s'." ), plotFileName.GetFullPath() );
445 aReporter->Report( msg, RPT_SEVERITY_ERROR );
446 }
447 }
448 else if( plotOneSheetPS( plotFileName.GetFullPath(), screen, aRenderSettings,
449 actualPage, plot_offset, scale, aPlotOpts ) )
450 {
451 if( aReporter )
452 {
453 msg.Printf( _( "Plotted to '%s'." ), plotFileName.GetFullPath() );
454 aReporter->Report( msg, RPT_SEVERITY_ACTION );
455 }
456 }
457 else
458 {
459 if( aReporter )
460 {
461 // Error
462 msg.Printf( _( "Failed to create file '%s'." ), plotFileName.GetFullPath() );
463 aReporter->Report( msg, RPT_SEVERITY_ERROR );
464 }
465 }
466
467 if( !aPlotOpts.m_outputFile.empty() )
468 break;
469 }
470 catch( IO_ERROR& e )
471 {
472 if( aReporter )
473 {
474 msg.Printf( wxT( "PS Plotter exception: %s" ), e.What() );
475 aReporter->Report( msg, RPT_SEVERITY_ERROR );
476 }
477 }
478 }
479
480 if( aReporter )
481 aReporter->ReportTail( _( "Done." ), RPT_SEVERITY_INFO );
482}
483
484
485bool SCH_PLOTTER::plotOneSheetPS( const wxString& aFileName, SCH_SCREEN* aScreen,
486 RENDER_SETTINGS* aRenderSettings, const PAGE_INFO& aPageInfo,
487 const VECTOR2I& aPlot0ffset, double aScale,
488 const SCH_PLOT_OPTS& aPlotOpts )
489{
490 PS_PLOTTER* plotter = new PS_PLOTTER();
491 plotter->SetRenderSettings( aRenderSettings );
492 plotter->SetPageSettings( aPageInfo );
493 plotter->SetColorMode( !aPlotOpts.m_blackAndWhite );
494
495 // Currently, plot units are in decimil
496 plotter->SetViewport( aPlot0ffset, schIUScale.IU_PER_MILS / 10, aScale, false );
497
498 // Init :
499 plotter->SetCreator( wxT( "Eeschema-PS" ) );
500
501 if( !plotter->OpenFile( aFileName ) )
502 {
503 delete plotter;
504 return false;
505 }
506
507 plotter->StartPlot( m_schematic->CurrentSheet().GetPageNumber() );
508
509 if( aPlotOpts.m_useBackgroundColor && plotter->GetColorMode() )
510 {
512
513 // Use page size selected in schematic to know the schematic bg area
514 const PAGE_INFO& actualPage = aScreen->GetPageSettings(); // page size selected in schematic
515 VECTOR2I end( actualPage.GetWidthIU( schIUScale.IU_PER_MILS ),
516 actualPage.GetHeightIU( schIUScale.IU_PER_MILS ) );
517
518 plotter->Rect( VECTOR2I( 0, 0 ), end, FILL_T::FILLED_SHAPE, 1.0, 0 );
519 }
520
521 if( aPlotOpts.m_plotDrawingSheet )
522 {
523 wxString sheetName = m_schematic->CurrentSheet().Last()->GetName();
524 wxString sheetPath = m_schematic->CurrentSheet().PathHumanReadable();
526
527 SCHEMATIC* sch = aScreen->Schematic();
528 wxString variantName = sch->GetCurrentVariant();
529 wxString variantDesc = sch->GetVariantDescription( variantName );
530
531 PlotDrawingSheet( plotter, &sch->Project(), aScreen->GetTitleBlock(), aPageInfo, sch->GetProperties(),
532 aScreen->GetPageNumber(), aScreen->GetPageCount(), sheetName, sheetPath,
533 aScreen->GetFileName(), plotter->GetColorMode() ? color : COLOR4D::BLACK,
534 aScreen->GetVirtualPageNumber() == 1, variantName, variantDesc );
535 }
536
537 aScreen->Plot( plotter, aPlotOpts );
538
539 plotter->EndPlot();
540 delete plotter;
541
542 return true;
543}
544
545
547 SCH_RENDER_SETTINGS* aRenderSettings, REPORTER* aReporter )
548{
549 wxString msg;
550 SCH_SHEET_PATH oldsheetpath = m_schematic->CurrentSheet();
551 SCH_SHEET_LIST sheetList;
552 PLOT_CONTEXT raii( nullptr, m_schematic );
553
554 if( aPlotOpts.m_plotAll || aPlotOpts.m_plotPages.size() > 0 )
555 {
556 sheetList.BuildSheetList( &m_schematic->Root(), true );
558
559 // remove the non-selected pages if we are in plot pages mode
560 if( aPlotOpts.m_plotPages.size() > 0 )
561 sheetList.TrimToPageNumbers( aPlotOpts.m_plotPages );
562 }
563 else
564 {
565 // in Eeschema, this prints the current page
566 sheetList.push_back( aPlotOpts.m_sheetPath.value_or( m_schematic->CurrentSheet() ) );
567 }
568
569 if( sheetList.empty() )
570 {
571 if( aReporter )
572 aReporter->Report( _( "No sheets to plot." ), RPT_SEVERITY_ERROR );
573
574 return;
575 }
576
577 for( unsigned i = 0; i < sheetList.size(); i++ )
578 {
579 SCH_SCREEN* screen;
580
581 m_schematic->SetCurrentSheet( sheetList[i] );
582 m_schematic->CurrentSheet().UpdateAllScreenReferences();
583 m_schematic->SetSheetNumberAndCount();
584
585 screen = m_schematic->CurrentSheet().LastScreen();
586
587 try
588 {
589 wxFileName plotFileName;
590
591 if( !aPlotOpts.m_outputFile.empty() )
592 {
593 plotFileName = wxFileName( aPlotOpts.m_outputFile );
594
595 if( plotFileName.GetExt().IsEmpty() )
596 plotFileName.SetExt( SVG_PLOTTER::GetDefaultFileExtension() );
597 }
598 else
599 {
600 wxString fname = m_schematic->GetUniqueFilenameForCurrentSheet();
601
602 // The sub sheet can be in a sub_hierarchy, but we plot the file in the
603 // main project folder (or the folder specified by the caller),
604 // so replace separators to create a unique filename:
605 fname.Replace( "/", "_" );
606 fname.Replace( "\\", "_" );
607
608 plotFileName = createPlotFileName( aPlotOpts, fname, SVG_PLOTTER::GetDefaultFileExtension(),
609 aReporter );
610 }
611
612 m_lastOutputFilePath = plotFileName.GetFullPath();
614
615 if( !plotFileName.IsOk() )
616 return;
617
618 bool success = plotOneSheetSVG( plotFileName.GetFullPath(), screen, aRenderSettings, aPlotOpts );
619
620 if( !success )
621 {
622 if( aReporter )
623 {
624 msg.Printf( _( "Failed to create file '%s'." ), plotFileName.GetFullPath() );
625 aReporter->Report( msg, RPT_SEVERITY_ERROR );
626 }
627 }
628 else
629 {
630 if( aReporter )
631 {
632 msg.Printf( _( "Plotted to '%s'." ), plotFileName.GetFullPath() );
633 aReporter->Report( msg, RPT_SEVERITY_ACTION );
634 }
635 }
636
637 if( !aPlotOpts.m_outputFile.empty() )
638 break;
639 }
640 catch( const IO_ERROR& e )
641 {
642 if( aReporter )
643 {
644 // Cannot plot SVG file
645 msg.Printf( wxT( "SVG Plotter exception: %s" ), e.What() );
646 aReporter->Report( msg, RPT_SEVERITY_ERROR );
647 }
648
649 break;
650 }
651 }
652
653 if( aReporter )
654 aReporter->ReportTail( _( "Done." ), RPT_SEVERITY_INFO );
655}
656
657
658bool SCH_PLOTTER::plotOneSheetSVG( const wxString& aFileName, SCH_SCREEN* aScreen,
659 RENDER_SETTINGS* aRenderSettings,
660 const SCH_PLOT_OPTS& aPlotOpts )
661{
662 PAGE_INFO plotPage;
663
664 // Adjust page size and scaling requests
665 const PAGE_INFO& actualPage = aScreen->GetPageSettings(); // page size selected in schematic
666
667 switch( aPlotOpts.m_pageSizeSelect )
668 {
669 case PAGE_SIZE_A:
670 plotPage.SetType( wxT( "A" ) );
671 plotPage.SetPortrait( actualPage.IsPortrait() );
672 break;
673
674 case PAGE_SIZE_A4:
675 plotPage.SetType( wxT( "A4" ) );
676 plotPage.SetPortrait( actualPage.IsPortrait() );
677 break;
678
679 case PAGE_SIZE_AUTO:
680 default:
681 plotPage = actualPage;
682 break;
683 }
684
685 SVG_PLOTTER* plotter = new SVG_PLOTTER();
686 plotter->SetRenderSettings( aRenderSettings );
687 plotter->SetPageSettings( plotPage );
688 plotter->SetColorMode( aPlotOpts.m_blackAndWhite ? false : true );
689 VECTOR2I plot_offset;
690
691 double scalex = (double) plotPage.GetWidthMils() / actualPage.GetWidthMils();
692 double scaley = (double) plotPage.GetHeightMils() / actualPage.GetHeightMils();
693 double scale = std::min( scalex, scaley );
694
695 // Currently, plot units are in decimil
696 plotter->SetViewport( plot_offset, schIUScale.IU_PER_MILS / 10, scale, false );
697
698 // Init :
699 plotter->SetCreator( wxT( "Eeschema-SVG" ) );
700
701 if( !plotter->OpenFile( aFileName ) )
702 {
703 delete plotter;
704 return false;
705 }
706
707 plotter->StartPlot( m_schematic->CurrentSheet().GetPageNumber() );
708
709 if( aPlotOpts.m_useBackgroundColor && plotter->GetColorMode() )
710 {
712
713 // Use page size selected in schematic to know the schematic bg area
714 VECTOR2I end( actualPage.GetWidthIU( schIUScale.IU_PER_MILS ),
715 actualPage.GetHeightIU( schIUScale.IU_PER_MILS ) );
716
717 plotter->Rect( VECTOR2I( 0, 0 ), end, FILL_T::FILLED_SHAPE, 1.0, 0 );
718 }
719
720 if( aPlotOpts.m_plotDrawingSheet )
721 {
722 wxString sheetName = m_schematic->CurrentSheet().Last()->GetName();
723 wxString sheetPath = m_schematic->CurrentSheet().PathHumanReadable();
725
726 SCHEMATIC* sch = aScreen->Schematic();
727 wxString variantName = sch->GetCurrentVariant();
728 wxString variantDesc = sch->GetVariantDescription( variantName );
729
730 PlotDrawingSheet( plotter, &sch->Project(), aScreen->GetTitleBlock(), actualPage, sch->GetProperties(),
731 aScreen->GetPageNumber(), aScreen->GetPageCount(), sheetName, sheetPath,
732 aScreen->GetFileName(), plotter->GetColorMode() ? color : COLOR4D::BLACK,
733 aScreen->GetVirtualPageNumber() == 1, variantName, variantDesc );
734 }
735
736 aScreen->Plot( plotter, aPlotOpts );
737
738 plotter->EndPlot();
739 delete plotter;
740
741 return true;
742}
743
744
746 SCH_RENDER_SETTINGS* aRenderSettings, REPORTER* aReporter )
747{
748 wxString msg;
749 SCH_SHEET_PATH oldsheetpath = m_schematic->CurrentSheet();
750 SCH_SHEET_LIST sheetList;
751 PLOT_CONTEXT raii( nullptr, m_schematic );
752
753 if( aPlotOpts.m_plotAll || aPlotOpts.m_plotPages.size() > 0 )
754 {
755 sheetList.BuildSheetList( &m_schematic->Root(), true );
757
758 if( aPlotOpts.m_plotPages.size() > 0 )
759 sheetList.TrimToPageNumbers( aPlotOpts.m_plotPages );
760 }
761 else
762 {
763 sheetList.push_back( aPlotOpts.m_sheetPath.value_or( m_schematic->CurrentSheet() ) );
764 }
765
766 if( sheetList.empty() )
767 {
768 if( aReporter )
769 aReporter->Report( _( "No sheets to plot." ), RPT_SEVERITY_ERROR );
770
771 return;
772 }
773
774 for( unsigned i = 0; i < sheetList.size(); i++ )
775 {
776 SCH_SCREEN* screen;
777
778 m_schematic->SetCurrentSheet( sheetList[i] );
779 m_schematic->CurrentSheet().UpdateAllScreenReferences();
780 m_schematic->SetSheetNumberAndCount();
781
782 screen = m_schematic->CurrentSheet().LastScreen();
783
784 try
785 {
786 wxFileName plotFileName;
787
788 if( !aPlotOpts.m_outputFile.empty() )
789 {
790 plotFileName = wxFileName( aPlotOpts.m_outputFile );
791
792 if( plotFileName.GetExt().IsEmpty() )
793 plotFileName.SetExt( PNG_PLOTTER::GetDefaultFileExtension() );
794 }
795 else
796 {
797 wxString fname = m_schematic->GetUniqueFilenameForCurrentSheet();
798
799 fname.Replace( "/", "_" );
800 fname.Replace( "\\", "_" );
801
802 plotFileName = createPlotFileName( aPlotOpts, fname, PNG_PLOTTER::GetDefaultFileExtension(),
803 aReporter );
804 }
805
806 m_lastOutputFilePath = plotFileName.GetFullPath();
808
809 if( !plotFileName.IsOk() )
810 return;
811
812 bool success = plotOneSheetPNG( plotFileName.GetFullPath(), screen, aRenderSettings,
813 aPlotOpts );
814
815 if( aReporter )
816 {
817 if( !success )
818 {
819 msg.Printf( _( "Failed to create file '%s'." ), plotFileName.GetFullPath() );
820 aReporter->Report( msg, RPT_SEVERITY_ERROR );
821 }
822 else
823 {
824 msg.Printf( _( "Plotted to '%s'." ), plotFileName.GetFullPath() );
825 aReporter->Report( msg, RPT_SEVERITY_ACTION );
826 }
827 }
828
829 if( !aPlotOpts.m_outputFile.empty() )
830 break;
831 }
832 catch( const IO_ERROR& e )
833 {
834 if( aReporter )
835 {
836 msg.Printf( wxT( "PNG Plotter exception: %s" ), e.What() );
837 aReporter->Report( msg, RPT_SEVERITY_ERROR );
838 }
839
840 break;
841 }
842 }
843
844 if( aReporter )
845 aReporter->ReportTail( _( "Done." ), RPT_SEVERITY_INFO );
846}
847
848
849bool SCH_PLOTTER::plotOneSheetPNG( const wxString& aFileName, SCH_SCREEN* aScreen,
850 RENDER_SETTINGS* aRenderSettings,
851 const SCH_PLOT_OPTS& aPlotOpts )
852{
853 PAGE_INFO plotPage;
854 const PAGE_INFO& actualPage = aScreen->GetPageSettings();
855
856 switch( aPlotOpts.m_pageSizeSelect )
857 {
858 case PAGE_SIZE_A:
859 plotPage.SetType( wxT( "A" ) );
860 plotPage.SetPortrait( actualPage.IsPortrait() );
861 break;
862
863 case PAGE_SIZE_A4:
864 plotPage.SetType( wxT( "A4" ) );
865 plotPage.SetPortrait( actualPage.IsPortrait() );
866 break;
867
868 case PAGE_SIZE_AUTO:
869 default:
870 plotPage = actualPage;
871 break;
872 }
873
874 int dpi = std::clamp( aPlotOpts.m_pngDPI, MIN_PNG_DPI, MAX_PNG_DPI );
875
876 int pixelW = KiROUND( static_cast<double>( plotPage.GetWidthMils() ) * dpi / 1000.0 );
877 int pixelH = KiROUND( static_cast<double>( plotPage.GetHeightMils() ) * dpi / 1000.0 );
878
879 PNG_PLOTTER* plotter = new PNG_PLOTTER();
880
881 plotter->SetPixelSize( pixelW, pixelH );
882 plotter->SetResolution( dpi );
883 plotter->SetAntialias( aPlotOpts.m_pngAntialias );
884
885 // Schematic IU is Y-down (matches Cairo); leave SetYAxisReversed at its default of false.
886 // pcbnew sets it true because PCB IU is Y-up. Do not copy that wiring here.
887
888 plotter->SetRenderSettings( aRenderSettings );
889 plotter->SetPageSettings( plotPage );
890 plotter->SetColorMode( !aPlotOpts.m_blackAndWhite );
891
892 VECTOR2I plot_offset;
893 double scalex = (double) plotPage.GetWidthMils() / actualPage.GetWidthMils();
894 double scaley = (double) plotPage.GetHeightMils() / actualPage.GetHeightMils();
895 double scale = std::min( scalex, scaley );
896
897 plotter->SetViewport( plot_offset, schIUScale.IU_PER_MILS / 10, scale, false );
898 plotter->SetCreator( wxT( "Eeschema-PNG" ) );
899
900 if( !plotter->OpenFile( aFileName ) )
901 {
902 delete plotter;
903 return false;
904 }
905
906 plotter->StartPlot( m_schematic->CurrentSheet().GetPageNumber() );
907
908 if( aPlotOpts.m_useBackgroundColor && plotter->GetColorMode() )
909 {
911
912 VECTOR2I end( actualPage.GetWidthIU( schIUScale.IU_PER_MILS ),
913 actualPage.GetHeightIU( schIUScale.IU_PER_MILS ) );
914
915 plotter->Rect( VECTOR2I( 0, 0 ), end, FILL_T::FILLED_SHAPE, 1.0, 0 );
916 }
917
918 if( aPlotOpts.m_plotDrawingSheet )
919 {
920 wxString sheetName = m_schematic->CurrentSheet().Last()->GetName();
921 wxString sheetPath = m_schematic->CurrentSheet().PathHumanReadable();
923
924 SCHEMATIC* sch = aScreen->Schematic();
925 wxString variantName = sch->GetCurrentVariant();
926 wxString variantDesc = sch->GetVariantDescription( variantName );
927
928 PlotDrawingSheet( plotter, &sch->Project(), aScreen->GetTitleBlock(), actualPage,
929 sch->GetProperties(), aScreen->GetPageNumber(), aScreen->GetPageCount(),
930 sheetName, sheetPath, aScreen->GetFileName(),
931 plotter->GetColorMode() ? color : COLOR4D::BLACK,
932 aScreen->GetVirtualPageNumber() == 1, variantName, variantDesc );
933 }
934
935 aScreen->Plot( plotter, aPlotOpts );
936
937 bool success = plotter->EndPlot();
938 delete plotter;
939
940 return success;
941}
942
943
944void SCH_PLOTTER::createDXFFiles( const SCH_PLOT_OPTS& aPlotOpts, SCH_RENDER_SETTINGS* aRenderSettings,
945 REPORTER* aReporter )
946{
947 PLOT_CONTEXT raii( nullptr, m_schematic );
948
949 /* When printing all pages, the printed page is not the current page. In complex hierarchies,
950 * we must update symbol references and other parameters in the given printed SCH_SCREEN,
951 * according to the sheet path because in complex hierarchies a SCH_SCREEN (a drawing ) is
952 * shared between many sheets and symbol references depend on the actual sheet path used.
953 */
954 SCH_SHEET_LIST sheetList;
955
956 if( aPlotOpts.m_plotAll || aPlotOpts.m_plotPages.size() > 0 )
957 {
958 sheetList.BuildSheetList( &m_schematic->Root(), true );
960
961 // remove the non-selected pages if we are in plot pages mode
962 if( aPlotOpts.m_plotPages.size() > 0 )
963 sheetList.TrimToPageNumbers( aPlotOpts.m_plotPages );
964 }
965 else
966 {
967 // in Eeschema, this prints the current page
968 sheetList.push_back( aPlotOpts.m_sheetPath.value_or( m_schematic->CurrentSheet() ) );
969 }
970
971 if( sheetList.empty() )
972 {
973 if( aReporter )
974 aReporter->Report( _( "No sheets to plot." ), RPT_SEVERITY_ERROR );
975
976 return;
977 }
978
979 for( unsigned i = 0; i < sheetList.size(); i++ )
980 {
981 m_schematic->SetCurrentSheet( sheetList[i] );
982 m_schematic->CurrentSheet().UpdateAllScreenReferences();
983 m_schematic->SetSheetNumberAndCount();
984
985 SCH_SCREEN* screen = m_schematic->CurrentSheet().LastScreen();
986 VECTOR2I plot_offset;
987 wxString msg;
988
989 try
990 {
991 wxFileName plotFileName;
992
993 if( !aPlotOpts.m_outputFile.empty() )
994 {
995 plotFileName = wxFileName( aPlotOpts.m_outputFile );
996
997 if( plotFileName.GetExt().IsEmpty() )
998 plotFileName.SetExt( DXF_PLOTTER::GetDefaultFileExtension() );
999 }
1000 else
1001 {
1002 wxString fname = m_schematic->GetUniqueFilenameForCurrentSheet();
1003
1004 // The sub sheet can be in a sub_hierarchy, but we plot the file in the
1005 // main project folder (or the folder specified by the caller),
1006 // so replace separators to create a unique filename:
1007 fname.Replace( "/", "_" );
1008 fname.Replace( "\\", "_" );
1009
1010 plotFileName = createPlotFileName( aPlotOpts, fname, DXF_PLOTTER::GetDefaultFileExtension(),
1011 aReporter );
1012 }
1013
1014 m_lastOutputFilePath = plotFileName.GetFullPath();
1016
1017 if( !plotFileName.IsOk() )
1018 return;
1019
1020 if( plotOneSheetDXF( plotFileName.GetFullPath(), screen, aRenderSettings, plot_offset,
1021 1.0, aPlotOpts ) )
1022 {
1023 if( aReporter )
1024 {
1025 msg.Printf( _( "Plotted to '%s'." ), plotFileName.GetFullPath() );
1026 aReporter->Report( msg, RPT_SEVERITY_ACTION );
1027 }
1028 }
1029 else // Error
1030 {
1031 if( aReporter )
1032 {
1033 msg.Printf( _( "Failed to create file '%s'." ), plotFileName.GetFullPath() );
1034 aReporter->Report( msg, RPT_SEVERITY_ERROR );
1035 }
1036 }
1037
1038 if( !aPlotOpts.m_outputFile.empty() )
1039 break;
1040 }
1041 catch( IO_ERROR& e )
1042 {
1043 if( aReporter )
1044 {
1045 msg.Printf( wxT( "DXF Plotter exception: %s" ), e.What() );
1046 aReporter->Report( msg, RPT_SEVERITY_ERROR );
1047 }
1048
1049 return;
1050 }
1051 }
1052
1053 if( aReporter )
1054 aReporter->ReportTail( _( "Done." ), RPT_SEVERITY_INFO );
1055}
1056
1057
1058bool SCH_PLOTTER::plotOneSheetDXF( const wxString& aFileName, SCH_SCREEN* aScreen,
1059 RENDER_SETTINGS* aRenderSettings, const VECTOR2I& aPlotOffset,
1060 double aScale, const SCH_PLOT_OPTS& aPlotOpts )
1061{
1062 aRenderSettings->LoadColors( m_colorSettings );
1063 aRenderSettings->SetDefaultPenWidth( 0 );
1064
1065 const PAGE_INFO& pageInfo = aScreen->GetPageSettings();
1066 DXF_PLOTTER* plotter = new DXF_PLOTTER();
1067
1068 plotter->SetUnits( aPlotOpts.m_DXF_File_Unit );
1069
1070 plotter->SetRenderSettings( aRenderSettings );
1071 plotter->SetPageSettings( pageInfo );
1072 plotter->SetColorMode( !aPlotOpts.m_blackAndWhite );
1073
1074 // Currently, plot units are in decimil
1075 plotter->SetViewport( aPlotOffset, schIUScale.IU_PER_MILS / 10, aScale, false );
1076
1077 // Init :
1078 plotter->SetCreator( wxT( "Eeschema-DXF" ) );
1079
1080 if( !plotter->OpenFile( aFileName ) )
1081 {
1082 delete plotter;
1083 return false;
1084 }
1085
1086 plotter->StartPlot( m_schematic->CurrentSheet().GetPageNumber() );
1087
1088 if( aPlotOpts.m_plotDrawingSheet )
1089 {
1090 wxString sheetName = m_schematic->CurrentSheet().Last()->GetName();
1091 wxString sheetPath = m_schematic->CurrentSheet().PathHumanReadable();
1093
1094 wxString variantName = m_schematic->GetCurrentVariant();
1095 wxString variantDesc = m_schematic->GetVariantDescription( variantName );
1096
1097 PlotDrawingSheet( plotter, &m_schematic->Project(), aScreen->GetTitleBlock(), pageInfo,
1098 m_schematic->GetProperties(), aScreen->GetPageNumber(), aScreen->GetPageCount(), sheetName,
1099 sheetPath, aScreen->GetFileName(), plotter->GetColorMode() ? color : COLOR4D::BLACK,
1100 aScreen->GetVirtualPageNumber() == 1, variantName, variantDesc );
1101 }
1102
1103 aScreen->Plot( plotter, aPlotOpts );
1104
1105 // finish
1106 plotter->EndPlot();
1107 delete plotter;
1108
1109 return true;
1110}
1111
1112
1114 const wxString& aPlotFileName,
1115 const wxString& aExtension, REPORTER* aReporter )
1116{
1117 wxFileName retv;
1118 wxFileName tmp;
1119
1120 tmp.SetPath( aPlotOpts.m_outputDirectory );
1121 retv.SetPath( tmp.GetPath() );
1122
1123 if( !aPlotFileName.IsEmpty() )
1124 retv.SetName( aPlotFileName );
1125 else
1126 retv.SetName( _( "Schematic" ) );
1127
1128 retv.SetExt( aExtension );
1129
1130 if( !EnsureFileDirectoryExists( &tmp, retv.GetFullName(), aReporter ) || !tmp.IsDirWritable() )
1131 {
1132 if( aReporter )
1133 {
1134 wxString msg = wxString::Format( _( "Failed to write plot files to folder '%s'." ),
1135 tmp.GetPath() );
1136 aReporter->Report( msg, RPT_SEVERITY_ERROR );
1137 }
1138
1139 retv.Clear();
1140
1141 SCHEMATIC_SETTINGS& settings = m_schematic->Settings();
1142 settings.m_PlotDirectoryName.Clear();
1143 }
1144 else
1145 {
1146 retv.SetPath( tmp.GetPath() );
1147 }
1148
1149 wxLogTrace( tracePathsAndFiles, "Writing plot file '%s'.", retv.GetFullPath() );
1150
1151 return retv;
1152}
1153
1154
1155void SCH_PLOTTER::Plot( PLOT_FORMAT aPlotFormat, const SCH_PLOT_OPTS& aPlotOpts,
1156 SCH_RENDER_SETTINGS* aRenderSettings, REPORTER* aReporter )
1157{
1158 m_outputFilePaths.clear();
1159
1160 wxString oldVariant = m_schematic->GetCurrentVariant();
1161 m_schematic->SetCurrentVariant( aPlotOpts.m_variant );
1163
1164 switch( aPlotFormat )
1165 {
1166 default:
1167 case PLOT_FORMAT::POST: createPSFiles( aPlotOpts, aRenderSettings, aReporter ); break;
1168 case PLOT_FORMAT::DXF: createDXFFiles( aPlotOpts, aRenderSettings, aReporter ); break;
1169 case PLOT_FORMAT::PDF: createPDFFile( aPlotOpts, aRenderSettings, aReporter ); break;
1170 case PLOT_FORMAT::SVG: createSVGFiles( aPlotOpts, aRenderSettings, aReporter ); break;
1171 case PLOT_FORMAT::PNG: createPNGFiles( aPlotOpts, aRenderSettings, aReporter ); break;
1172 case PLOT_FORMAT::HPGL: /* no longer supported */ break;
1173 }
1174
1175 m_schematic->SetCurrentVariant( oldVariant );
1176}
1177
1178
1179BOX2I GetSymbolPlotBBox( const LIB_SYMBOL& aSymbol, int aUnit, int aBodyStyle, bool aIncludeHiddenFields )
1180{
1181 std::unique_ptr<LIB_SYMBOL> flatSymbol = aSymbol.Flatten();
1182
1183 BOX2I symbolBB = flatSymbol->GetUnitBoundingBox( aUnit, aBodyStyle, !aIncludeHiddenFields );
1184
1185 // Inflate the bbox by "some margin". A lot bounding boxes are slightly
1186 // small because a stroke size of '0' is actually 'inherit', by default 6 mils,
1187 // but the actual value can unly be known for sure with the schematic context.
1188 // A margin of 2mm seems to cover most evantualities, but this is a bit of a
1189 // guess.
1190
1191 const int expansion = schIUScale.mmToIU( 2 );
1192 symbolBB.Inflate( expansion );
1193
1194 return symbolBB;
1195}
1196
1197
1198bool PlotSymbolToSVG( LIB_SYMBOL& aDrawSymbol, LIB_SYMBOL& aFieldsSymbol, int aUnit, int aBodyStyle, const BOX2I& aBBox,
1199 SCH_RENDER_SETTINGS& aRenderSettings, bool aBlackAndWhite, const wxString& aFileName,
1200 REPORTER* aReporter )
1201{
1202 PAGE_INFO pageInfo( PAGE_SIZE_TYPE::User );
1203 pageInfo.SetHeightMils( schIUScale.IUToMils( aBBox.GetHeight() ) );
1204 pageInfo.SetWidthMils( schIUScale.IUToMils( aBBox.GetWidth() ) );
1205
1206 std::unique_ptr<SVG_PLOTTER> plotter = std::make_unique<SVG_PLOTTER>();
1207 plotter->SetRenderSettings( &aRenderSettings );
1208 plotter->SetPageSettings( pageInfo );
1209 plotter->SetColorMode( !aBlackAndWhite );
1210
1211 // Currently, plot units are in decimal. Keep the symbol origin at the SVG origin; the
1212 // viewBox is the content bbox.
1213 plotter->SetViewport( VECTOR2I( 0, 0 ), schIUScale.IU_PER_MILS / 10, 1.0, false );
1214 plotter->SetPlotBBox( aBBox );
1215
1216 plotter->SetCreator( wxT( "Eeschema-SVG" ) );
1217
1218 if( !plotter->OpenFile( aFileName ) )
1219 {
1220 if( aReporter )
1221 {
1222 aReporter->Report( wxString::Format( _( "Unable to open destination '%s'" ) + wxS( "\n" ),
1223 aFileName ),
1225 }
1226 return false;
1227 }
1228
1229 LOCALE_IO toggle;
1230 SCH_PLOT_OPTS plotOpts;
1231
1232 plotter->StartPlot( wxS( "1" ) );
1233
1234 constexpr bool background = true;
1235 aDrawSymbol.Plot( plotter.get(), background, plotOpts, aUnit, aBodyStyle, VECTOR2I( 0, 0 ), false );
1236 aDrawSymbol.Plot( plotter.get(), !background, plotOpts, aUnit, aBodyStyle, VECTOR2I( 0, 0 ), false );
1237 aFieldsSymbol.PlotFields( plotter.get(), !background, plotOpts, aUnit, aBodyStyle, VECTOR2I( 0, 0 ), false );
1238
1239 plotter->EndPlot();
1240 return true;
1241}
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.
void SetViewport(const VECTOR2I &aOffset, double aIusPerDecimil, double aScale, bool aMirror) override
Set the scale/position for the DXF plot.
bool StartPlot(const wxString &aPageNumber) override
Open the DXF plot with a skeleton header.
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:138
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:192
virtual void SetPageSettings(const PAGE_INFO &aPageSettings)
Definition plotter.h:171
void SetRenderSettings(RENDER_SETTINGS *aSettings)
Definition plotter.h:168
virtual void SetTitle(const wxString &aTitle)
Definition plotter.h:191
RENDER_SETTINGS * RenderSettings()
Definition plotter.h:169
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:190
bool GetColorMode() const
Definition plotter.h:166
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:165
virtual void SetSubject(const wxString &aSubject)
Definition plotter.h:193
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:829
@ FOR_GUI
Definition common.h:93
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:524
@ LAYER_SCHEMATIC_BACKGROUND
Definition layer_ids.h:516
see class PGM_BASE
PLOT_FORMAT
The set of supported output plot formats.
Definition plotter.h:65
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