/** * @file dialog_svg_print.cpp */ /* * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2012 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 2012 KiCad Developers, see change_log.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, you may find one here: * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html * or you may search the http://www.gnu.org website for the version 2 license, * or you may write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include #include #include #include #include #include #include #include #include #include #include #include #include // Keys for configuration #define PLOTSVGMODECOLOR_KEY wxT( "PlotSVGModeColor" ) #define PLOTSVGPAGESIZEOPT_KEY wxT( "PlotSVGPageOpt" ) #define PLOTSVGPLOT_BRD_EDGE_KEY wxT( "PlotSVGBrdEdge" ) // reasonnable values for default pen width #define WIDTH_MAX_VALUE (2 *IU_PER_MM) #define WIDTH_MIN_VALUE (0.05 *IU_PER_MM) // Local variables: static PRINT_PARAMETERS s_Parameters; static long s_SelectedLayers = LAYER_BACK | LAYER_FRONT | SILKSCREEN_LAYER_FRONT | SILKSCREEN_LAYER_BACK; /*! * DIALOG_SVG_PRINT functions */ DIALOG_SVG_PRINT::DIALOG_SVG_PRINT( EDA_DRAW_FRAME* parent ) : DIALOG_SVG_PRINT_base( parent ) { m_Parent = (PCB_BASE_FRAME*) parent; m_Config = wxGetApp().GetSettings(); initDialog(); GetSizer()->SetSizeHints( this ); Centre(); m_buttonBoard->SetDefault(); } void DIALOG_SVG_PRINT::initDialog( ) { SetFocus(); // Make ESC key working if( m_Config ) { m_Config->Read( PLOTSVGMODECOLOR_KEY, &s_Parameters.m_Print_Black_and_White ); long ltmp; m_Config->Read( PLOTSVGPAGESIZEOPT_KEY, <mp, 0 ); m_rbSvgPageSizeOpt->SetSelection( ltmp ); m_Config->Read( PLOTSVGPLOT_BRD_EDGE_KEY, <mp, 1 ); m_PrintBoardEdgesCtrl->SetValue(ltmp ); } if( s_Parameters.m_Print_Black_and_White ) m_ModeColorOption->SetSelection( 1 ); else m_ModeColorOption->SetSelection( 0 ); s_Parameters.m_PenDefaultSize = g_DrawDefaultLineThickness; AddUnitSymbol( *m_TextPenWidth, g_UserUnit ); m_DialogDefaultPenSize->SetValue( ReturnStringFromValue( g_UserUnit, s_Parameters.m_PenDefaultSize ) ); // Create layers list BOARD* board = m_Parent->GetBoard(); int layer; for( layer = 0; layer < NB_LAYERS; ++layer ) { if( !board->IsLayerEnabled( layer ) ) m_BoxSelectLayer[layer] = NULL; else m_BoxSelectLayer[layer] = new wxCheckBox( this, -1, board->GetLayerName( layer ) ); } // Add wxCheckBoxes in layers lists dialog // List layers in same order than in setup layers dialog // (Front or Top to Back or Bottom) DECLARE_LAYERS_ORDER_LIST(layersOrder); for( int layer_idx = 0; layer_idx < NB_LAYERS; ++layer_idx ) { layer = layersOrder[layer_idx]; wxASSERT(layer < NB_LAYERS); if( m_BoxSelectLayer[layer] == NULL ) continue; long mask = 1 << layer; if( mask & s_SelectedLayers ) m_BoxSelectLayer[layer]->SetValue( true ); if( layer < 16 ) m_CopperLayersBoxSizer->Add( m_BoxSelectLayer[layer], 0, wxGROW | wxALL, 1 ); else m_TechnicalBoxSizer->Add( m_BoxSelectLayer[layer], 0, wxGROW | wxALL, 1 ); } if( m_Config ) { wxString layerKey; for( int layer = 0; layerRead( layerKey, &option ) ) m_BoxSelectLayer[layer]->SetValue( option ); } } } void DIALOG_SVG_PRINT::SetPenWidth() { s_Parameters.m_PenDefaultSize = ReturnValueFromTextCtrl( *m_DialogDefaultPenSize ); if( s_Parameters.m_PenDefaultSize > WIDTH_MAX_VALUE ) { s_Parameters.m_PenDefaultSize = WIDTH_MAX_VALUE; } if( s_Parameters.m_PenDefaultSize < WIDTH_MIN_VALUE ) { s_Parameters.m_PenDefaultSize = WIDTH_MIN_VALUE; } g_DrawDefaultLineThickness = s_Parameters.m_PenDefaultSize; m_DialogDefaultPenSize->SetValue( ReturnStringFromValue( g_UserUnit, s_Parameters.m_PenDefaultSize ) ); } void DIALOG_SVG_PRINT::PrintSVGDoc( bool aPrintAll ) { wxFileName fn; wxString msg; s_Parameters.m_Print_Black_and_White = m_ModeColorOption->GetSelection(); SetPenWidth(); PCB_SCREEN* screen = m_Parent->GetScreen(); if( aPrintAll ) m_PrintMaskLayer = 0xFFFFFFFF; else m_PrintMaskLayer = 0; if( m_PrintBoardEdgesCtrl->IsChecked() ) m_PrintMaskLayer |= EDGE_LAYER; else m_PrintMaskLayer &= ~EDGE_LAYER; for( int layer = 0; layerGetValue() ) continue; fn = m_FileNameCtrl->GetValue(); if( !fn.IsOk() ) { fn = m_Parent->GetBoard()->GetFileName(); } if( aPrintAll ) fn.SetName( fn.GetName() + wxT( "-brd" ) ); else { wxString extraname = m_BoxSelectLayer[layer]->GetLabel(); extraname.Trim(); // remove leading and trailing spaces if any extraname.Trim(false); fn.SetName( fn.GetName() + wxT( "-" ) + extraname ); m_PrintMaskLayer = 1 << layer; if( m_PrintBoardEdgesCtrl->IsChecked() ) m_PrintMaskLayer |= EDGE_LAYER; } fn.SetExt( wxT( "svg" ) ); bool success = DrawPage( fn.GetFullPath(), screen ); msg = _( "Create file " ) + fn.GetFullPath(); if( !success ) msg += _( " error" ); msg += wxT( "\n" ); m_MessagesBox->AppendText( msg ); if( aPrintAll ) break; } } /* * Actual print function. */ bool DIALOG_SVG_PRINT::DrawPage( const wxString& FullFileName, BASE_SCREEN* screen ) { LOCALE_IO toggle; int tmpzoom; wxPoint tmp_startvisu; wxPoint old_org; bool success = true; // Change frames and local settings tmp_startvisu = screen->m_StartVisu; tmpzoom = screen->GetZoom(); old_org = screen->m_DrawOrg; screen->m_DrawOrg.x = screen->m_DrawOrg.y = 0; screen->m_StartVisu.x = screen->m_StartVisu.y = 0; screen->SetScalingFactor( 1.0 ); double dpi = IU_PER_MILS * 1000.0; EDA_DRAW_PANEL* panel = m_Parent->GetCanvas(); // paper pageSize is in internal units, either nanometers or deci-mils EDA_RECT rect; rect.SetSize( m_Parent->GetPageSizeIU() ); if( PageIsBoardBoundarySize() ) { rect = m_Parent->GetBoard()->ComputeBoundingBox(); } KicadSVGFileDC dc( FullFileName, rect.GetOrigin(), rect.GetSize(), dpi ); EDA_RECT tmp = *panel->GetClipBox(); GRResetPenAndBrush( &dc ); GRForceBlackPen( s_Parameters.m_Print_Black_and_White ); s_Parameters.m_DrillShapeOpt = PRINT_PARAMETERS::FULL_DRILL_SHAPE; // Set clip box to the max size #define MAX_VALUE (INT_MAX/2) // MAX_VALUE is the max we can use in an integer // and that allows calculations without overflow panel->SetClipBox( EDA_RECT( wxPoint( 0, 0 ), wxSize( MAX_VALUE, MAX_VALUE ) ) ); screen->m_IsPrinting = true; EDA_COLOR_T bg_color = g_DrawBgColor; g_DrawBgColor = WHITE; if( PrintPageRef() ) m_Parent->TraceWorkSheet( &dc, screen, s_Parameters.m_PenDefaultSize, IU_PER_MILS, wxT( "" ) ); m_Parent->PrintPage( &dc, m_PrintMaskLayer, false, &s_Parameters); g_DrawBgColor = bg_color; screen->m_IsPrinting = false; panel->SetClipBox( tmp ); GRForceBlackPen( false ); screen->m_StartVisu = tmp_startvisu; screen->m_DrawOrg = old_org; screen->SetZoom( tmpzoom ); return success; } void DIALOG_SVG_PRINT::OnButtonPrintBoardClick( wxCommandEvent& event ) { PrintSVGDoc( true ); } void DIALOG_SVG_PRINT::OnButtonPrintSelectedClick( wxCommandEvent& event ) { PrintSVGDoc( false ); } void DIALOG_SVG_PRINT::OnButtonCancelClick( wxCommandEvent& event ) { Close(); } void DIALOG_SVG_PRINT::OnCloseWindow( wxCloseEvent& event ) { SetPenWidth(); s_Parameters.m_Print_Black_and_White = m_ModeColorOption->GetSelection(); if( m_Config ) { m_Config->Write( PLOTSVGMODECOLOR_KEY, s_Parameters.m_Print_Black_and_White ); m_Config->Write( PLOTSVGPAGESIZEOPT_KEY, m_rbSvgPageSizeOpt->GetSelection() ); m_Config->Write( PLOTSVGPLOT_BRD_EDGE_KEY, m_PrintBoardEdgesCtrl->GetValue() ); wxString layerKey; for( int layer = 0; layerWrite( layerKey, m_BoxSelectLayer[layer]->IsChecked() ); } } EndModal( 0 ); }