/** @file plot_schematic_PDF.cpp */ /* * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 1992-2010 Jean-Pierre Charras #include #include #include #include #include #include #include #include #include void DIALOG_PLOT_SCHEMATIC::createPDFFile( bool aPlotAll, bool aPlotFrameRef ) { SCH_SCREEN* screen = m_parent->GetScreen(); SCH_SHEET_PATH* sheetpath; SCH_SHEET_PATH oldsheetpath = m_parent->GetCurrentSheet(); // sheetpath is saved here /* When printing all pages, the printed page is not the current page. In * complex hierarchies, we must update component references and others * parameters in the given printed SCH_SCREEN, accordint to the sheet path * because in complex hierarchies a SCH_SCREEN (a drawing ) is shared * between many sheets and component references depend on the actual sheet * path used */ SCH_SHEET_LIST SheetList( NULL ); sheetpath = SheetList.GetFirst(); // Allocate the plotter and set the job level parameter PDF_PLOTTER* plotter = new PDF_PLOTTER(); plotter->SetDefaultLineWidth( GetDefaultLineThickness() ); plotter->SetColorMode( getModeColor() ); plotter->SetCreator( wxT( "Eeschema-PDF" ) ); wxString msg; wxFileName plotFileName; REPORTER& reporter = m_MessagesBox->Reporter(); LOCALE_IO toggle; // Switch the locale to standard C // First page handling is different bool first_page = true; do { // Step over the schematic hierarchy if( aPlotAll ) { SCH_SHEET_PATH list; if( list.BuildSheetPathInfoFromSheetPathValue( sheetpath->Path() ) ) { m_parent->SetCurrentSheet( list ); m_parent->GetCurrentSheet().UpdateAllScreenReferences(); m_parent->SetSheetNumberAndCount(); screen = m_parent->GetCurrentSheet().LastScreen(); } else // Should not happen wxASSERT( 0 ); sheetpath = SheetList.GetNext(); } if( first_page ) { try { wxString fname = m_parent->GetUniqueFilenameForCurrentSheet(); wxString ext = PDF_PLOTTER::GetDefaultFileExtension(); plotFileName = createPlotFileName( m_outputDirectoryName, fname, ext, &reporter ); if( !plotter->OpenFile( plotFileName.GetFullPath() ) ) { msg.Printf( _( "Unable to create file '%s'.\n" ), GetChars( plotFileName.GetFullPath() ) ); reporter.Report( msg, REPORTER::RPT_ERROR ); delete plotter; return; } // Open the plotter and do the first page setupPlotPagePDF( plotter, screen ); plotter->StartPlot(); first_page = false; } catch( const IO_ERROR& e ) { // Cannot plot PDF file msg.Printf( wxT( "PDF Plotter exception: %s" ), GetChars( e.errorText ) ); reporter.Report( msg, REPORTER::RPT_ERROR ); restoreEnvironment( plotter, oldsheetpath ); return; } } else { /* For the following pages you need to close the (finished) page, * reconfigure, and then start a new one */ plotter->ClosePage(); setupPlotPagePDF( plotter, screen ); plotter->StartPage(); } plotOneSheetPDF( plotter, screen, aPlotFrameRef ); } while( aPlotAll && sheetpath ); // Everything done, close the plot and restore the environment msg.Printf( _( "Plot: '%s' OK.\n" ), GetChars( plotFileName.GetFullPath() ) ); reporter.Report( msg, REPORTER::RPT_ACTION ); restoreEnvironment(plotter, oldsheetpath ); } void DIALOG_PLOT_SCHEMATIC::restoreEnvironment( PDF_PLOTTER* aPlotter, SCH_SHEET_PATH& aOldsheetpath ) { aPlotter->EndPlot(); delete aPlotter; // Restore the previous sheet m_parent->SetCurrentSheet( aOldsheetpath ); m_parent->GetCurrentSheet().UpdateAllScreenReferences(); m_parent->SetSheetNumberAndCount(); } void DIALOG_PLOT_SCHEMATIC::plotOneSheetPDF( PLOTTER* aPlotter, SCH_SCREEN* aScreen, bool aPlotFrameRef ) { if( aPlotFrameRef ) { aPlotter->SetColor( BLACK ); PlotWorkSheet( aPlotter, m_parent->GetTitleBlock(), m_parent->GetPageSettings(), aScreen->m_ScreenNumber, aScreen->m_NumberOfScreens, m_parent->GetScreenDesc(), aScreen->GetFileName() ); } aScreen->Plot( aPlotter ); } void DIALOG_PLOT_SCHEMATIC::setupPlotPagePDF( PLOTTER * aPlotter, SCH_SCREEN* aScreen ) { PAGE_INFO plotPage; // page size selected to plot // Considerations on page size and scaling requests PAGE_INFO actualPage = aScreen->GetPageSettings(); // page size selected in schematic switch( m_pageSizeSelect ) { case PAGE_SIZE_A: plotPage.SetType( wxT( "A" ) ); plotPage.SetPortrait( actualPage.IsPortrait() ); break; case PAGE_SIZE_A4: plotPage.SetType( wxT( "A4" ) ); plotPage.SetPortrait( actualPage.IsPortrait() ); break; case PAGE_SIZE_AUTO: default: plotPage = actualPage; break; } double scalex = (double) plotPage.GetWidthMils() / actualPage.GetWidthMils(); double scaley = (double) plotPage.GetHeightMils() / actualPage.GetHeightMils(); double scale = std::min( scalex, scaley ); aPlotter->SetPageSettings( plotPage ); aPlotter->SetViewport( wxPoint( 0, 0 ), IU_PER_DECIMILS, scale, false ); }