///////////////////////////////////////////////////////////////////////////// // Name: dialog_svg_print.cpp // Author: jean-pierre Charras // Modified by: // Licence: GPL ///////////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // Keys for configuration #define PLOTSVGMODECOLOR_KEY wxT( "PlotSVGModeColor" ) // reasonnable values for default pen width (in 1/10000 inch) #define WIDTH_MAX_VALUE 500 #define WIDTH_MIN_VALUE 1 extern int g_DrawDefaultLineThickness; // 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 ); } s_Parameters.m_PenDefaultSize = g_DrawDefaultLineThickness; AddUnitSymbol( *m_TextPenWidth, g_UserUnit ); m_DialogPenWidth->SetValue( ReturnStringFromValue( g_UserUnit, s_Parameters.m_PenDefaultSize, m_Parent->GetInternalUnits() ) ); m_Print_Frame_Ref_Ctrl->SetValue( s_Parameters.m_Print_Sheet_Ref ); // 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_DialogPenWidth, m_Parent->GetInternalUnits() ); 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_DialogPenWidth->SetValue( ReturnStringFromValue( g_UserUnit, s_Parameters.m_PenDefaultSize, m_Parent->GetInternalUnits() ) ); } void DIALOG_SVG_PRINT::PrintSVGDoc( bool aPrintAll, bool aPrint_Frame_Ref ) { wxFileName fn; wxString msg; 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 = screen->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, aPrint_Frame_Ref ); 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, bool aPrint_Frame_Ref ) { // const PAGE_INFO& pageInfo = m_Parent->GetPageSettings(); 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 ); float dpi = (float)m_Parent->GetInternalUnits(); EDA_DRAW_PANEL* panel = m_Parent->GetCanvas(); // paper pageSize is in internal units, either nanometers or deci-mils wxSize pageSize = m_Parent->GetPageSizeIU(); KicadSVGFileDC dc( FullFileName, pageSize.x, pageSize.y, dpi ); EDA_RECT tmp = *panel->GetClipBox(); GRResetPenAndBrush( &dc ); GRForceBlackPen( m_ModeColorOption->GetSelection() == 0 ? false : true ); 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; int bg_color = g_DrawBgColor; g_DrawBgColor = WHITE; if( aPrint_Frame_Ref ) m_Parent->TraceWorkSheet( &dc, screen, s_Parameters.m_PenDefaultSize ); 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 ) { s_Parameters.m_Print_Sheet_Ref = m_Print_Frame_Ref_Ctrl->IsChecked(); PrintSVGDoc( true, s_Parameters.m_Print_Sheet_Ref ); } void DIALOG_SVG_PRINT::OnButtonPrintSelectedClick( wxCommandEvent& event ) { s_Parameters.m_Print_Sheet_Ref = m_Print_Frame_Ref_Ctrl->IsChecked(); PrintSVGDoc( false, s_Parameters.m_Print_Sheet_Ref ); } 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 ); wxString layerKey; for( int layer = 0; layerWrite( layerKey, m_BoxSelectLayer[layer]->IsChecked() ); } } EndModal( 0 ); } /* called on radiobox color/black and white selection */ void DIALOG_SVG_PRINT::OnSetColorModeSelected( wxCommandEvent& event ) { s_Parameters.m_Print_Black_and_White = m_ModeColorOption->GetSelection(); }