diff --git a/3d-viewer/3d_canvas.cpp b/3d-viewer/3d_canvas.cpp index df8ad2e694..c2794485a3 100644 --- a/3d-viewer/3d_canvas.cpp +++ b/3d-viewer/3d_canvas.cpp @@ -586,7 +586,7 @@ void EDA_3D_CANVAS::SetLights() */ void EDA_3D_CANVAS::TakeScreenshot( wxCommandEvent& event ) { - wxFileName fn( Parent()->Parent()->GetScreen()->GetFileName() ); + wxFileName fn( Parent()->GetDefaultFileName() ); wxString FullFileName; wxString file_ext, mask; bool fmt_is_jpeg = false; @@ -598,7 +598,7 @@ void EDA_3D_CANVAS::TakeScreenshot( wxCommandEvent& event ) { file_ext = fmt_is_jpeg ? wxT( "jpg" ) : wxT( "png" ); mask = wxT( "*." ) + file_ext; - FullFileName = Parent()->Parent()->GetScreen()->GetFileName(); + FullFileName = Parent()->GetDefaultFileName(); fn.SetExt( file_ext ); FullFileName = EDA_FileSelector( _( "3D Image filename:" ), wxEmptyString, diff --git a/3d-viewer/3d_viewer.h b/3d-viewer/3d_viewer.h index 7af89351df..7efa7d6a70 100644 --- a/3d-viewer/3d_viewer.h +++ b/3d-viewer/3d_viewer.h @@ -187,6 +187,7 @@ private: wxSize m_FrameSize; wxAuiManager m_auimgr; bool m_reloadRequest; + wxString m_defaultFileName; /// Filename to propose for screenshot public: EDA_3D_FRAME( PCB_BASE_FRAME* parent, const wxString& title, @@ -216,6 +217,8 @@ public: */ void NewDisplay(); + void SetDefaultFileName(const wxString &aFn) { m_defaultFileName = aFn; } + const wxString &GetDefaultFileName() const { return m_defaultFileName; } private: void Exit3DFrame( wxCommandEvent& event ); void OnCloseWindow( wxCloseEvent& Event ); diff --git a/common/common_plotDXF_functions.cpp b/common/common_plotDXF_functions.cpp index f08042b0b2..eaa0b1960c 100644 --- a/common/common_plotDXF_functions.cpp +++ b/common/common_plotDXF_functions.cpp @@ -43,8 +43,8 @@ void DXF_PLOTTER::SetViewport( const wxPoint& aOffset, double aIusPerDecimil, iuPerDeviceUnit = 1.0 / aIusPerDecimil; // Gives a DXF in decimils iuPerDeviceUnit *= 0.00254; // ... now in mm - SetDefaultLineWidth( 0 ); // No line width on DXF - plotMirror = false; // No mirroring on DXF + SetDefaultLineWidth( 0 ); // No line width on DXF + plotMirror = false; // No mirroring on DXF currentColor = BLACK; } diff --git a/common/common_plot_functions.cpp b/common/common_plot_functions.cpp index e2e9a22dc0..714544d9ed 100644 --- a/common/common_plot_functions.cpp +++ b/common/common_plot_functions.cpp @@ -45,20 +45,18 @@ wxString GetDefaultPlotExtension( PlotFormat aFormat ) /* Plot sheet references * margin is in mils (1/1000 inch) */ -void EDA_DRAW_FRAME::PlotWorkSheet( PLOTTER* plotter, BASE_SCREEN* screen, int aLineWidth ) +void PlotWorkSheet( PLOTTER* plotter, const TITLE_BLOCK& aTitleBlock, + const PAGE_INFO& aPageInfo, + int aSheetNumber, int aNumberOfSheets, + const wxString &aSheetDesc, + const wxString &aFilename ) { -#define WSTEXTSIZE 50 // Text size in mils - - const PAGE_INFO& pageInfo = GetPageSettings(); - wxSize pageSize = pageInfo.GetSizeMils(); // mils - int xg, yg; - - wxPoint pos, ref; - EDA_COLOR_T color; - - // Paper is sized in mils. Here is a conversion factor to scale mils to internal units. - int iusPerMil = screen->MilsToIuScalar(); + static const int WSTEXTSIZE = 50; // Text size in mils + int iusPerMil = plotter->GetIUsPerDecimil() * 10; + wxSize pageSize = aPageInfo.GetSizeMils(); // in mils + int xg, yg; + wxPoint pos, ref; wxString msg; wxSize text_size; @@ -68,22 +66,17 @@ void EDA_DRAW_FRAME::PlotWorkSheet( PLOTTER* plotter, BASE_SCREEN* screen, int a wxSize text_size1_5; #else int UpperLimit = VARIABLE_BLOCK_START_POSITION; - bool bold = false; #endif - bool italic = false; - int thickness = aLineWidth; - - color = BLACK; - plotter->SetColor( color ); - plotter->SetCurrentLineWidth( thickness ); + plotter->SetColor( BLACK ); + plotter->SetCurrentLineWidth( PLOTTER::DEFAULT_LINE_WIDTH ); // Plot edge. - ref.x = pageInfo.GetLeftMarginMils() * iusPerMil; - ref.y = pageInfo.GetTopMarginMils() * iusPerMil; + ref.x = aPageInfo.GetLeftMarginMils() * iusPerMil; + ref.y = aPageInfo.GetTopMarginMils() * iusPerMil; - xg = ( pageSize.x - pageInfo.GetRightMarginMils() ) * iusPerMil; - yg = ( pageSize.y - pageInfo.GetBottomMarginMils() ) * iusPerMil; + xg = ( pageSize.x - aPageInfo.GetRightMarginMils() ) * iusPerMil; + yg = ( pageSize.y - aPageInfo.GetBottomMarginMils() ) * iusPerMil; #if defined(KICAD_GOST) plotter->MoveTo( ref ); @@ -131,12 +124,12 @@ void EDA_DRAW_FRAME::PlotWorkSheet( PLOTTER* plotter, BASE_SCREEN* screen, int a text_size.y = WSTEXTSIZE * iusPerMil; // upper left corner in mils - ref.x = pageInfo.GetLeftMarginMils(); - ref.y = pageInfo.GetTopMarginMils(); + ref.x = aPageInfo.GetLeftMarginMils(); + ref.y = aPageInfo.GetTopMarginMils(); // lower right corner in mils - xg = ( pageSize.x - pageInfo.GetRightMarginMils() ); - yg = ( pageSize.y - pageInfo.GetBottomMarginMils() ); + xg = ( pageSize.x - aPageInfo.GetRightMarginMils() ); + yg = ( pageSize.y - aPageInfo.GetBottomMarginMils() ); #if defined(KICAD_GOST) for( Ki_WorkSheetData* WsItem = &WS_Segm1_LU; @@ -154,10 +147,10 @@ void EDA_DRAW_FRAME::PlotWorkSheet( PLOTTER* plotter, BASE_SCREEN* screen, int a case WS_PODPIS_LU: if( WsItem->m_Legende ) msg = WsItem->m_Legende; - plotter->Text( pos, color, + plotter->Text( pos, BLACK, msg, TEXT_ORIENT_VERT, text_size, GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_BOTTOM, - thickness, italic, false ); + PLOTTER::DEFAULT_LINE_WIDTH, false, false ); break; case WS_SEGMENT_LU: @@ -209,10 +202,10 @@ void EDA_DRAW_FRAME::PlotWorkSheet( PLOTTER* plotter, BASE_SCREEN* screen, int a pos.x = ( ii - gxpas / 2 ) * iusPerMil; pos.y = ( ref.y + GRID_REF_W / 2 ) * iusPerMil; - plotter->Text( pos, color, + plotter->Text( pos, BLACK, msg, TEXT_ORIENT_HORIZ, text_size, GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER, - thickness, italic, false ); + PLOTTER::DEFAULT_LINE_WIDTH, false, false ); if( ii < xg - PAS_REF / 2 ) { @@ -225,10 +218,10 @@ void EDA_DRAW_FRAME::PlotWorkSheet( PLOTTER* plotter, BASE_SCREEN* screen, int a } pos.x = ( ii - gxpas / 2 ) * iusPerMil; pos.y = ( yg - GRID_REF_W / 2 ) * iusPerMil; - plotter->Text( pos, color, + plotter->Text( pos, BLACK, msg, TEXT_ORIENT_HORIZ, text_size, GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER, - thickness, italic, false ); + PLOTTER::DEFAULT_LINE_WIDTH, false, false ); } // Plot legend along the Y axis. @@ -251,10 +244,10 @@ void EDA_DRAW_FRAME::PlotWorkSheet( PLOTTER* plotter, BASE_SCREEN* screen, int a } pos.x = ( ref.x + GRID_REF_W / 2 ) * iusPerMil; pos.y = ( ii - gypas / 2 ) * iusPerMil; - plotter->Text( pos, color, + plotter->Text( pos, BLACK, msg, TEXT_ORIENT_HORIZ, text_size, GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER, - thickness, italic, false ); + PLOTTER::DEFAULT_LINE_WIDTH, false, false ); if( ii < yg - PAS_REF / 2 ) { @@ -268,9 +261,9 @@ void EDA_DRAW_FRAME::PlotWorkSheet( PLOTTER* plotter, BASE_SCREEN* screen, int a pos.x = ( xg - GRID_REF_W / 2 ) * iusPerMil; pos.y = ( ii - gypas / 2 ) * iusPerMil; - plotter->Text( pos, color, msg, TEXT_ORIENT_HORIZ, text_size, + plotter->Text( pos, BLACK, msg, TEXT_ORIENT_HORIZ, text_size, GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER, - thickness, italic, false ); + PLOTTER::DEFAULT_LINE_WIDTH, false, false ); } #endif @@ -287,10 +280,10 @@ void EDA_DRAW_FRAME::PlotWorkSheet( PLOTTER* plotter, BASE_SCREEN* screen, int a text_size1_5.x = SIZETEXT * iusPerMil * 1.5; text_size1_5.y = SIZETEXT * iusPerMil * 1.5; - ref.x = pageSize.x - pageInfo.GetRightMarginMils(); - ref.y = pageSize.y - pageInfo.GetBottomMarginMils(); + ref.x = pageSize.x - aPageInfo.GetRightMarginMils(); + ref.y = pageSize.y - aPageInfo.GetBottomMarginMils(); - if( screen->m_ScreenNumber == 1 ) + if( aSheetNumber == 1 ) { for( Ki_WorkSheetData* WsItem = &WS_Date; WsItem != NULL; @@ -314,10 +307,10 @@ void EDA_DRAW_FRAME::PlotWorkSheet( PLOTTER* plotter, BASE_SCREEN* screen, int a case WS_PODPIS: if( WsItem->m_Legende ) msg = WsItem->m_Legende; - plotter->Text( pos, color, + plotter->Text( pos, BLACK, msg, TEXT_ORIENT_HORIZ, text_size, GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_CENTER, - thickness, italic, false ); + PLOTTER::DEFAULT_LINE_WIDTH, false, false ); break; case WS_SIZESHEET: @@ -326,93 +319,93 @@ void EDA_DRAW_FRAME::PlotWorkSheet( PLOTTER* plotter, BASE_SCREEN* screen, int a case WS_IDENTSHEET: if( WsItem->m_Legende ) msg = WsItem->m_Legende; - if( screen->m_NumberOfScreens > 1 ) - msg << screen->m_ScreenNumber; - plotter->Text( pos, color, + if( aNumberOfSheets > 1 ) + msg << aSheetNumber; + plotter->Text( pos, BLACK, msg, TEXT_ORIENT_HORIZ, text_size, GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_CENTER, - thickness, italic, false ); + PLOTTER::DEFAULT_LINE_WIDTH, false, false ); break; case WS_SHEETS: if( WsItem->m_Legende ) msg = WsItem->m_Legende; - msg << screen->m_NumberOfScreens; - plotter->Text( pos, color, + msg << aNumberOfSheets; + plotter->Text( pos, BLACK, msg, TEXT_ORIENT_HORIZ, text_size, GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_CENTER, - thickness, italic, false ); + PLOTTER::DEFAULT_LINE_WIDTH, false, false ); break; case WS_COMPANY_NAME: - msg = GetTitleBlock().GetCompany(); + msg = aTitleBlock.GetCompany(); if( !msg.IsEmpty() ) { - plotter->Text( pos, color, + plotter->Text( pos, BLACK, msg, TEXT_ORIENT_HORIZ, text_size1_5, GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER, - thickness, italic, false ); + PLOTTER::DEFAULT_LINE_WIDTH, false, false ); } break; case WS_TITLE: - msg = GetTitleBlock().GetTitle(); + msg = aTitleBlock.GetTitle(); if( !msg.IsEmpty() ) { - plotter->Text( pos, color, + plotter->Text( pos, BLACK, msg, TEXT_ORIENT_HORIZ, text_size1_5, GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER, - thickness, italic, false ); + PLOTTER::DEFAULT_LINE_WIDTH, false, false ); } break; case WS_COMMENT1: - msg = GetTitleBlock().GetComment1(); + msg = aTitleBlock.GetComment1(); if( !msg.IsEmpty() ) { - plotter->Text( pos, color, + plotter->Text( pos, BLACK, msg, TEXT_ORIENT_HORIZ, text_size3, GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER, - thickness, italic, false ); - pos.x = (pageInfo.GetLeftMarginMils() + 1260) * iusPerMil; - pos.y = (pageInfo.GetTopMarginMils() + 270) * iusPerMil; - plotter->Text( pos, color, + PLOTTER::DEFAULT_LINE_WIDTH, false, false ); + pos.x = (aPageInfo.GetLeftMarginMils() + 1260) * iusPerMil; + pos.y = (aPageInfo.GetTopMarginMils() + 270) * iusPerMil; + plotter->Text( pos, BLACK, msg.GetData(), 1800, text_size2, GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER, - thickness, italic, false ); + PLOTTER::DEFAULT_LINE_WIDTH, false, false ); } break; case WS_COMMENT2: - msg = GetTitleBlock().GetComment2(); + msg = aTitleBlock.GetComment2(); if( !msg.IsEmpty() ) { - plotter->Text( pos, color, + plotter->Text( pos, BLACK, msg, TEXT_ORIENT_HORIZ, text_size, GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_CENTER, - thickness, italic, false ); + PLOTTER::DEFAULT_LINE_WIDTH, false, false ); } break; case WS_COMMENT3: - msg = GetTitleBlock().GetComment3(); + msg = aTitleBlock.GetComment3(); if( !msg.IsEmpty() ) { - plotter->Text( pos, color, + plotter->Text( pos, BLACK, msg, TEXT_ORIENT_HORIZ, text_size, GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_CENTER, - thickness, italic, false ); + PLOTTER::DEFAULT_LINE_WIDTH, false, false ); } break; case WS_COMMENT4: - msg = GetTitleBlock().GetComment4(); + msg = aTitleBlock.GetComment4(); if( !msg.IsEmpty() ) { - plotter->Text( pos, color, + plotter->Text( pos, BLACK, msg, TEXT_ORIENT_HORIZ, text_size, GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_CENTER, - thickness, italic, false ); + PLOTTER::DEFAULT_LINE_WIDTH, false, false ); } break; @@ -441,37 +434,37 @@ void EDA_DRAW_FRAME::PlotWorkSheet( PLOTTER* plotter, BASE_SCREEN* screen, int a { case WS_CADRE: // Begin list number > 1 - msg = GetTitleBlock().GetComment1(); + msg = aTitleBlock.GetComment1(); if( !msg.IsEmpty() ) { - plotter->Text( pos, color, + plotter->Text( pos, BLACK, msg, TEXT_ORIENT_HORIZ, text_size3, GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER, - thickness, italic, false ); - pos.x = (pageInfo.GetLeftMarginMils() + 1260) * iusPerMil; - pos.y = (pageInfo.GetTopMarginMils() + 270) * iusPerMil; - plotter->Text( pos, color, + PLOTTER::DEFAULT_LINE_WIDTH, false, false ); + pos.x = (aPageInfo.GetLeftMarginMils() + 1260) * iusPerMil; + pos.y = (aPageInfo.GetTopMarginMils() + 270) * iusPerMil; + plotter->Text( pos, BLACK, msg, 1800, text_size2, GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER, - thickness, italic, false ); + PLOTTER::DEFAULT_LINE_WIDTH, false, false ); } break; case WS_PODPIS_D: if( WsItem->m_Legende ) msg = WsItem->m_Legende; - plotter->Text( pos, color, msg, TEXT_ORIENT_HORIZ, text_size, + plotter->Text( pos, BLACK, msg, TEXT_ORIENT_HORIZ, text_size, GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_CENTER, - thickness, italic, false ); + PLOTTER::DEFAULT_LINE_WIDTH, false, false ); break; case WS_IDENTSHEET_D: if( WsItem->m_Legende ) msg = WsItem->m_Legende; - msg << screen->m_ScreenNumber; - plotter->Text( pos, color, msg, TEXT_ORIENT_HORIZ, text_size, + msg << aSheetNumber; + plotter->Text( pos, BLACK, msg, TEXT_ORIENT_HORIZ, text_size, GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_CENTER, - thickness, italic, false ); + PLOTTER::DEFAULT_LINE_WIDTH, false, false ); break; case WS_LEFT_SEGMENT_D: @@ -487,16 +480,17 @@ void EDA_DRAW_FRAME::PlotWorkSheet( PLOTTER* plotter, BASE_SCREEN* screen, int a #else - ref.x = pageSize.x - GRID_REF_W - pageInfo.GetRightMarginMils(); - ref.y = pageSize.y - GRID_REF_W - pageInfo.GetBottomMarginMils(); + ref.x = pageSize.x - GRID_REF_W - aPageInfo.GetRightMarginMils(); + ref.y = pageSize.y - GRID_REF_W - aPageInfo.GetBottomMarginMils(); for( Ki_WorkSheetData* WsItem = &WS_Date; WsItem != NULL; WsItem = WsItem->Pnext ) { + bool bold = false; + pos.x = ( ref.x - WsItem->m_Posx ) * iusPerMil; pos.y = ( ref.y - WsItem->m_Posy ) * iusPerMil; - bold = false; if( WsItem->m_Legende ) msg = WsItem->m_Legende; else @@ -505,12 +499,12 @@ void EDA_DRAW_FRAME::PlotWorkSheet( PLOTTER* plotter, BASE_SCREEN* screen, int a switch( WsItem->m_Type ) { case WS_DATE: - msg += GetTitleBlock().GetDate(); + msg += aTitleBlock.GetDate(); bold = true; break; case WS_REV: - msg += GetTitleBlock().GetRevision(); + msg += aTitleBlock.GetRevision(); bold = true; break; @@ -519,61 +513,57 @@ void EDA_DRAW_FRAME::PlotWorkSheet( PLOTTER* plotter, BASE_SCREEN* screen, int a break; case WS_SIZESHEET: - msg += pageInfo.GetType(); + msg += aPageInfo.GetType(); break; case WS_IDENTSHEET: - msg << screen->m_ScreenNumber << wxT( "/" ) << - screen->m_NumberOfScreens; + msg << aSheetNumber << wxT( "/" ) << aNumberOfSheets; break; case WS_FILENAME: { wxString fname, fext; - wxFileName::SplitPath( screen->GetFileName(), - (wxString*) NULL, - &fname, - &fext ); + wxFileName::SplitPath( aFilename, NULL, &fname, &fext ); msg << fname << wxT( "." ) << fext; } break; case WS_FULLSHEETNAME: - msg += GetScreenDesc(); + msg += aSheetDesc; break; case WS_COMPANY_NAME: - msg += GetTitleBlock().GetCompany(); + msg += aTitleBlock.GetCompany(); if( !msg.IsEmpty() ) UpperLimit = MAX( UpperLimit, WsItem->m_Posy + SIZETEXT ); bold = true; break; case WS_TITLE: - msg += GetTitleBlock().GetTitle(); + msg += aTitleBlock.GetTitle(); bold = true; break; case WS_COMMENT1: - msg += GetTitleBlock().GetComment1(); + msg += aTitleBlock.GetComment1(); if( !msg.IsEmpty() ) UpperLimit = MAX( UpperLimit, WsItem->m_Posy + SIZETEXT ); break; case WS_COMMENT2: - msg += GetTitleBlock().GetComment2(); + msg += aTitleBlock.GetComment2(); if( !msg.IsEmpty() ) UpperLimit = MAX( UpperLimit, WsItem->m_Posy + SIZETEXT ); break; case WS_COMMENT3: - msg += GetTitleBlock().GetComment3(); + msg += aTitleBlock.GetComment3(); if( !msg.IsEmpty() ) UpperLimit = MAX( UpperLimit, WsItem->m_Posy + SIZETEXT ); break; case WS_COMMENT4: - msg += GetTitleBlock().GetComment4(); + msg += aTitleBlock.GetComment4(); if( !msg.IsEmpty() ) UpperLimit = MAX( UpperLimit, WsItem->m_Posy + SIZETEXT ); break; @@ -600,10 +590,10 @@ void EDA_DRAW_FRAME::PlotWorkSheet( PLOTTER* plotter, BASE_SCREEN* screen, int a if( !msg.IsEmpty() ) { - plotter->Text( pos, color, + plotter->Text( pos, BLACK, msg, TEXT_ORIENT_HORIZ, text_size, GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_CENTER, - thickness, italic, bold ); + PLOTTER::DEFAULT_LINE_WIDTH, bold, false ); } } diff --git a/common/worksheet.cpp b/common/worksheet.cpp index 356bbb6740..1917d091aa 100644 --- a/common/worksheet.cpp +++ b/common/worksheet.cpp @@ -1004,7 +1004,7 @@ Ki_WorkSheetData WS_Segm5_LT = void EDA_DRAW_FRAME::TraceWorkSheet( wxDC* aDC, BASE_SCREEN* aScreen, int aLineWidth, - double aScalar ) + double aScalar, const wxString &aFilename ) { if( !m_showBorderAndTitleBlock ) return; @@ -1024,7 +1024,7 @@ void EDA_DRAW_FRAME::TraceWorkSheet( wxDC* aDC, BASE_SCREEN* aScreen, int aLineW wxPoint margin_left_top( pageInfo.GetLeftMarginMils(), pageInfo.GetTopMarginMils() ); wxPoint margin_right_bottom( pageInfo.GetRightMarginMils(), pageInfo.GetBottomMarginMils() ); wxString paper = pageInfo.GetType(); - wxString file = aScreen->GetFileName(); + wxString file = aFilename; TITLE_BLOCK t_block = GetTitleBlock(); int number_of_screens = aScreen->m_NumberOfScreens; int screen_to_draw = aScreen->m_ScreenNumber; diff --git a/eeschema/dialogs/dialog_SVG_print.cpp b/eeschema/dialogs/dialog_SVG_print.cpp index 5816f77655..d174312eaa 100644 --- a/eeschema/dialogs/dialog_SVG_print.cpp +++ b/eeschema/dialogs/dialog_SVG_print.cpp @@ -237,7 +237,8 @@ bool DIALOG_SVG_PRINT::DrawSVGPage( EDA_DRAW_FRAME* frame, sheetSize.y/2) ); if( aPrint_Sheet_Ref ) - frame->TraceWorkSheet( &dc, screen, g_DrawDefaultLineThickness, IU_PER_MILS ); + frame->TraceWorkSheet( &dc, screen, g_DrawDefaultLineThickness, + IU_PER_MILS, frame->GetScreenDesc() ); screen->m_IsPrinting = false; panel->SetClipBox( tmp ); diff --git a/eeschema/dialogs/dialog_plot_schematic_DXF.cpp b/eeschema/dialogs/dialog_plot_schematic_DXF.cpp index 643917943a..79537a4ca1 100644 --- a/eeschema/dialogs/dialog_plot_schematic_DXF.cpp +++ b/eeschema/dialogs/dialog_plot_schematic_DXF.cpp @@ -241,7 +241,11 @@ void DIALOG_PLOT_SCHEMATIC_DXF::PlotOneSheetDXF( const wxString& FileName, if( m_plot_Sheet_Ref ) { plotter->SetColor( BLACK ); - m_Parent->PlotWorkSheet( plotter, screen, g_DrawDefaultLineThickness ); + PlotWorkSheet( plotter, m_Parent->GetTitleBlock(), + m_Parent->GetPageSettings(), + screen->m_ScreenNumber, screen->m_NumberOfScreens, + m_Parent->GetScreenDesc(), + screen->GetFileName() ); } screen->Plot( plotter ); diff --git a/eeschema/dialogs/dialog_plot_schematic_HPGL.cpp b/eeschema/dialogs/dialog_plot_schematic_HPGL.cpp index 66e2d7da3c..fffc916e8a 100644 --- a/eeschema/dialogs/dialog_plot_schematic_HPGL.cpp +++ b/eeschema/dialogs/dialog_plot_schematic_HPGL.cpp @@ -394,7 +394,11 @@ void DIALOG_PLOT_SCHEMATIC_HPGL::Plot_1_Page_HPGL( const wxString& FileName, plotter->SetColor( BLACK ); if( s_plot_Sheet_Ref ) - m_Parent->PlotWorkSheet( plotter, screen, g_DrawDefaultLineThickness ); + PlotWorkSheet( plotter, m_Parent->GetTitleBlock(), + m_Parent->GetPageSettings(), + screen->m_ScreenNumber, screen->m_NumberOfScreens, + m_Parent->GetScreenDesc(), + screen->GetFileName() ); screen->Plot( plotter ); diff --git a/eeschema/dialogs/dialog_plot_schematic_PDF.cpp b/eeschema/dialogs/dialog_plot_schematic_PDF.cpp index 7814e1eba0..25799aef05 100644 --- a/eeschema/dialogs/dialog_plot_schematic_PDF.cpp +++ b/eeschema/dialogs/dialog_plot_schematic_PDF.cpp @@ -298,8 +298,12 @@ void DIALOG_PLOT_SCHEMATIC_PDF::plotOneSheet( PDF_PLOTTER* plotter, { if( m_plot_Sheet_Ref ) { - plotter->SetColor( BLACK ); - m_Parent->PlotWorkSheet( plotter, screen, g_DrawDefaultLineThickness ); + plotter->SetColor( BLACK ); + PlotWorkSheet( plotter, m_Parent->GetTitleBlock(), + m_Parent->GetPageSettings(), + screen->m_ScreenNumber, screen->m_NumberOfScreens, + m_Parent->GetScreenDesc(), + screen->GetFileName() ); } screen->Plot( plotter ); diff --git a/eeschema/dialogs/dialog_plot_schematic_PS.cpp b/eeschema/dialogs/dialog_plot_schematic_PS.cpp index c653c2cad2..94068191d8 100644 --- a/eeschema/dialogs/dialog_plot_schematic_PS.cpp +++ b/eeschema/dialogs/dialog_plot_schematic_PS.cpp @@ -294,7 +294,11 @@ void DIALOG_PLOT_SCHEMATIC_PS::plotOneSheetPS( const wxString& FileName, if( m_plot_Sheet_Ref ) { plotter->SetColor( BLACK ); - m_Parent->PlotWorkSheet( plotter, screen, g_DrawDefaultLineThickness ); + PlotWorkSheet( plotter, m_Parent->GetTitleBlock(), + m_Parent->GetPageSettings(), + screen->m_ScreenNumber, screen->m_NumberOfScreens, + m_Parent->GetScreenDesc(), + screen->GetFileName() ); } screen->Plot( plotter ); diff --git a/eeschema/dialogs/dialog_print_using_printer.cpp b/eeschema/dialogs/dialog_print_using_printer.cpp index ce73637993..aceacedff4 100644 --- a/eeschema/dialogs/dialog_print_using_printer.cpp +++ b/eeschema/dialogs/dialog_print_using_printer.cpp @@ -420,7 +420,8 @@ void SCH_PRINTOUT::DrawPage( SCH_SCREEN* aScreen ) aScreen->Draw( panel, dc, GR_DEFAULT_DRAWMODE ); if( printReference ) - parent->TraceWorkSheet( dc, aScreen, g_DrawDefaultLineThickness, IU_PER_MILS ); + parent->TraceWorkSheet( dc, aScreen, g_DrawDefaultLineThickness, + IU_PER_MILS, parent->GetScreenDesc() ); g_DrawBgColor = bg_color; aScreen->m_IsPrinting = false; diff --git a/eeschema/eeredraw.cpp b/eeschema/eeredraw.cpp index f14b07820a..63acb50cf0 100644 --- a/eeschema/eeredraw.cpp +++ b/eeschema/eeredraw.cpp @@ -71,7 +71,8 @@ void SCH_EDIT_FRAME::RedrawActiveWindow( wxDC* DC, bool EraseBg ) GetScreen()->Draw( m_canvas, DC, GR_DEFAULT_DRAWMODE ); - TraceWorkSheet( DC, GetScreen(), g_DrawDefaultLineThickness, IU_PER_MILS ); + TraceWorkSheet( DC, GetScreen(), g_DrawDefaultLineThickness, IU_PER_MILS, + GetScreenDesc() ); #ifdef USE_WX_OVERLAY if( IsShown() ) diff --git a/eeschema/schframe.cpp b/eeschema/schframe.cpp index 3ba1e35892..8267e620ca 100644 --- a/eeschema/schframe.cpp +++ b/eeschema/schframe.cpp @@ -861,7 +861,8 @@ void SCH_EDIT_FRAME::SVG_Print( wxCommandEvent& event ) void SCH_EDIT_FRAME::PrintPage( wxDC* aDC, int aPrintMask, bool aPrintMirrorMode, void* aData ) { GetScreen()->Draw( m_canvas, aDC, GR_DEFAULT_DRAWMODE ); - TraceWorkSheet( aDC, GetScreen(), g_DrawDefaultLineThickness, IU_PER_MILS ); + TraceWorkSheet( aDC, GetScreen(), g_DrawDefaultLineThickness, IU_PER_MILS, + GetScreenDesc() ); } diff --git a/gerbview/draw_gerber_screen.cpp b/gerbview/draw_gerber_screen.cpp index dce9aec1a2..d6b39f7bf5 100644 --- a/gerbview/draw_gerber_screen.cpp +++ b/gerbview/draw_gerber_screen.cpp @@ -105,7 +105,7 @@ void GERBVIEW_FRAME::RedrawActiveWindow( wxDC* DC, bool EraseBg ) if( IsElementVisible( DCODES_VISIBLE ) ) DrawItemsDCodeID( DC, GR_COPY ); - TraceWorkSheet( DC, screen, 0, IU_PER_MILS ); + TraceWorkSheet( DC, screen, 0, IU_PER_MILS, wxEmptyString ); if( m_canvas->IsMouseCaptured() ) m_canvas->CallMouseCapture( DC, wxDefaultPosition, false ); diff --git a/gerbview/files.cpp b/gerbview/files.cpp index 5679bc189f..5d0a8aaf7d 100644 --- a/gerbview/files.cpp +++ b/gerbview/files.cpp @@ -177,13 +177,13 @@ bool GERBVIEW_FRAME::LoadGerberFiles( const wxString& aFullFileName ) if( !filename.IsAbsolute() ) filename.SetPath( currentPath ); - GetScreen()->SetFileName( filename.GetFullPath() ); + m_lastFileName = filename.GetFullPath(); setActiveLayer( layer, false ); if( Read_GERBER_File( filename.GetFullPath(), filename.GetFullPath() ) ) { - UpdateFileHistory( GetScreen()->GetFileName() ); + UpdateFileHistory( m_lastFileName ); layer = getNextAvailableLayer( layer ); @@ -258,7 +258,7 @@ bool GERBVIEW_FRAME::LoadExcellonFiles( const wxString& aFullFileName ) if( !filename.IsAbsolute() ) filename.SetPath( currentPath ); - GetScreen()->SetFileName( filename.GetFullPath() ); + m_lastFileName = filename.GetFullPath(); setActiveLayer( layer, false ); @@ -301,7 +301,7 @@ bool GERBVIEW_FRAME::LoadDCodeFile( const wxString& aFullFileName ) { wildcard = _( "Gerber DCODE files" ); wildcard += wxT(" ") + AllFilesWildcard; - fn = GetScreen()->GetFileName(); + fn = m_lastFileName; wxFileDialog dlg( this, _( "Load GERBER DCODE File" ), fn.GetPath(), fn.GetFullName(), wildcard, wxFD_OPEN | wxFD_FILE_MUST_EXIST ); diff --git a/gerbview/gerbview_frame.h b/gerbview/gerbview_frame.h index 0cb7d9bf06..1c257b9b09 100644 --- a/gerbview/gerbview_frame.h +++ b/gerbview/gerbview_frame.h @@ -162,6 +162,8 @@ protected: // Auxiliary file history used to store drill files history. wxFileHistory m_drillFileHistory; + /// The last filename chosen to be proposed to the user + wxString m_lastFileName; public: GBR_LAYER_BOX_SELECTOR* m_SelLayerBox; DCODE_SELECTION_BOX* m_DCodeSelector; // a list box to select the dcode Id to highlight. diff --git a/include/class_base_screen.h b/include/class_base_screen.h index 2de82a5813..e7d665d808 100644 --- a/include/class_base_screen.h +++ b/include/class_base_screen.h @@ -76,7 +76,6 @@ class BASE_SCREEN : public EDA_ITEM { private: GRIDS m_grids; ///< List of valid grid sizes. - wxString m_fileName; ///< File used to load the screen. bool m_FlagModified; ///< Indicates current drawing has been modified. bool m_FlagSave; ///< Indicates automatic file save. EDA_ITEM* m_CurrentItem; ///< Currently selected object @@ -153,10 +152,6 @@ public: void InitDataPoints( const wxSize& aPageSizeInternalUnits ); - void SetFileName( const wxString& aFileName ) { m_fileName = aFileName; } - - wxString GetFileName() const { return m_fileName; } - /** * Function MilsToIuScalar * returns the scalar required to convert mils to internal units. diff --git a/include/class_sch_screen.h b/include/class_sch_screen.h index d50c3243df..5dc5ccbc27 100644 --- a/include/class_sch_screen.h +++ b/include/class_sch_screen.h @@ -62,6 +62,9 @@ enum SCH_LINE_TEST_T class SCH_SCREEN : public BASE_SCREEN { +private: + wxString m_fileName; ///< File used to load the screen. + int m_refCount; ///< Number of sheets referencing this screen. ///< Delete when it goes to zero. @@ -105,6 +108,10 @@ public: const PAGE_INFO& GetPageSettings() const { return m_paper; } void SetPageSettings( const PAGE_INFO& aPageSettings ) { m_paper = aPageSettings; } + void SetFileName( const wxString& aFileName ) { m_fileName = aFileName; } + + const wxString& GetFileName() const { return m_fileName; } + const wxPoint& GetOriginAxisPosition() const { return m_originAxisPosition; } void SetOriginAxisPosition( const wxPoint& aPosition ) { m_originAxisPosition = aPosition; } diff --git a/include/plot_common.h b/include/plot_common.h index 103d755aef..a5e56dd12d 100644 --- a/include/plot_common.h +++ b/include/plot_common.h @@ -844,6 +844,13 @@ protected: int currentColor; }; +class TITLE_BLOCK; +void PlotWorkSheet( PLOTTER* plotter, const TITLE_BLOCK& aTitleBlock, + const PAGE_INFO& aPageInfo, + int aSheetNumber, int aNumberOfSheets, + const wxString &aSheetDesc, + const wxString &aFilename ); + /** Returns the default plot extension for a format */ wxString GetDefaultPlotExtension( PlotFormat aFormat ); diff --git a/include/wxBasePcbFrame.h b/include/wxBasePcbFrame.h index 48893e37c4..05cae8b37c 100644 --- a/include/wxBasePcbFrame.h +++ b/include/wxBasePcbFrame.h @@ -564,73 +564,6 @@ public: */ void RecalculateAllTracksNetcode(); - /* Plotting functions: - * Return true if OK, false if the file is not created (or has a problem) - */ - - /** - * Function ExportToGerberFile - * create one output files one per board layer in the RS274X format. - *

- * The units are in inches and in the format 3.4 with the leading zeros omitted. - * Coordinates are absolute value. The 3.4 format is used because the native Pcbnew - * units are 1/10000 inch. - *

- */ - bool ExportToGerberFile( const wxString& aFullFileName, - int aLayer, - bool aPlotOriginIsAuxAxis, - EDA_DRAW_MODE_T aTraceMode ); - - bool ExportToHpglFile( const wxString& aFullFileName, - int aLayer, - EDA_DRAW_MODE_T aTraceMode ); - - bool ExportToPostScriptFile( const wxString& aFullFileName, - int aLayer, - bool aUseA4, - EDA_DRAW_MODE_T aTraceMode ); - - bool ExportToDxfFile( const wxString& aFullFileName, - int aLayer, - EDA_DRAW_MODE_T aTraceMode ); - - void Plot_Layer( PLOTTER* plotter, - int Layer, - EDA_DRAW_MODE_T trace_mode ); - - /** - * Function Plot_Standard_Layer - * plot copper or technical layers. - * not used for silk screen layers, because these layers have specific - * requirements, mainly for pads - * @param aPlotter = the plotter to use - * @param aLayerMask = the mask to define the layers to plot - * @param aPlotVia = true to plot vias, false to skip vias (has meaning - * only for solder mask layers). - * @param aPlotMode = the plot mode (files, sketch). Has meaning for some formats only - * @param aSkipNPTH_Pads = true to skip NPTH Pads, when the pad size and the pad hole - * have the same size. Used in GERBER format only. - */ - void Plot_Standard_Layer( PLOTTER* aPlotter, int aLayerMask, - bool aPlotVia, EDA_DRAW_MODE_T aPlotMode, - bool aSkipNPTH_Pads = false ); - - void PlotSilkScreen( PLOTTER* plotter, int masque_layer, EDA_DRAW_MODE_T trace_mode ); - - /** - * Function PlotDrillMark - * Draw a drill mark for pads and vias. - * Must be called after all drawings, because it - * redraw the drill mark on a pad or via, as a negative (i.e. white) shape - * in FILLED plot mode - * @param aPlotter = the PLOTTER - * @param aTraceMode = the mode of plot (FILLED, SKETCH) - * @param aSmallDrillShape = true to plot a small drill shape, false to - * plot the actual drill shape - */ - void PlotDrillMark( PLOTTER* aPlotter, EDA_DRAW_MODE_T aTraceMode, bool aSmallDrillShape ); - /* Functions relative to Undo/redo commands: */ diff --git a/include/wxstruct.h b/include/wxstruct.h index e1f1359ecf..8e25273b92 100644 --- a/include/wxstruct.h +++ b/include/wxstruct.h @@ -662,7 +662,8 @@ public: */ double GetZoom(); - void TraceWorkSheet( wxDC* aDC, BASE_SCREEN* aScreen, int aLineWidth, double aScalar ); + void TraceWorkSheet( wxDC* aDC, BASE_SCREEN* aScreen, int aLineWidth, + double aScale, const wxString &aFilename ); /** * Function TraceWorkSheet is a core function for drawing of the page layout with @@ -686,8 +687,6 @@ public: int aNScr, int aScr, int aLnW, double aScalar, EDA_COLOR_T aClr1 = RED, EDA_COLOR_T aClr2 = RED ); - void PlotWorkSheet( PLOTTER* aPlotter, BASE_SCREEN* aScreen, int aLineWidth ); - /** * Function GetXYSheetReferences * returns the X,Y sheet references where the point position is located diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index 6cd84b5da6..9410c14e92 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -187,10 +187,6 @@ set(PCBNEW_CLASS_SRCS pcbnew.cpp pcbnew_config.cpp pcbplot.cpp - plotgerb.cpp - plothpgl.cpp - plotps.cpp - plotdxf.cpp plot_rtn.cpp print_board_functions.cpp printout_controler.cpp diff --git a/pcbnew/build_BOM_from_board.cpp b/pcbnew/build_BOM_from_board.cpp index fe6660c426..e8f3474dc0 100644 --- a/pcbnew/build_BOM_from_board.cpp +++ b/pcbnew/build_BOM_from_board.cpp @@ -64,7 +64,7 @@ void PCB_EDIT_FRAME::RecreateBOMFileFromBoard( wxCommandEvent& aEvent ) } /* Set the file extension: */ - fn = GetScreen()->GetFileName(); + fn = GetBoard()->GetFileName(); fn.SetExt( CsvFileExtension ); wxFileDialog dlg( this, _( "Save Bill of Materials" ), wxGetCwd(), diff --git a/pcbnew/class_board.h b/pcbnew/class_board.h index ecf5b49028..b87402aa67 100644 --- a/pcbnew/class_board.h +++ b/pcbnew/class_board.h @@ -187,6 +187,9 @@ class BOARD : public BOARD_ITEM friend class PCB_EDIT_FRAME; private: + /// the board filename + wxString m_fileName; + // @todo: switch to boost:ptr_vector, and change ~BOARD() typedef std::vector MARKERS; @@ -237,6 +240,10 @@ private: public: + void SetFileName( const wxString& aFileName ) { m_fileName = aFileName; } + + const wxString &GetFileName() const { return m_fileName; } + /// Flags used in ratsnest calculation and update. int m_Status_Pcb; diff --git a/pcbnew/dialogs/dialog_SVG_print.cpp b/pcbnew/dialogs/dialog_SVG_print.cpp index 08ddb1219a..4a03ed178b 100644 --- a/pcbnew/dialogs/dialog_SVG_print.cpp +++ b/pcbnew/dialogs/dialog_SVG_print.cpp @@ -183,7 +183,7 @@ void DIALOG_SVG_PRINT::PrintSVGDoc( bool aPrintAll, bool aPrint_Frame_Ref ) fn = m_FileNameCtrl->GetValue(); if( !fn.IsOk() ) { - fn = screen->GetFileName(); + fn = m_Parent->GetBoard()->GetFileName(); } if( aPrintAll ) @@ -271,7 +271,8 @@ bool DIALOG_SVG_PRINT::DrawPage( const wxString& FullFileName, g_DrawBgColor = WHITE; if( aPrint_Frame_Ref ) - m_Parent->TraceWorkSheet( &dc, screen, s_Parameters.m_PenDefaultSize, IU_PER_MILS ); + 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; diff --git a/pcbnew/dialogs/dialog_drc.cpp b/pcbnew/dialogs/dialog_drc.cpp index 5e95dfe8d6..69566433a2 100644 --- a/pcbnew/dialogs/dialog_drc.cpp +++ b/pcbnew/dialogs/dialog_drc.cpp @@ -293,7 +293,7 @@ void DIALOG_DRC_CONTROL::OnButtonBrowseRptFileClick( wxCommandEvent& event ) wxString wildcard( _( "DRC report files (.rpt)|*.rpt" ) ); wxString Ext( wxT( "rpt" ) ); - fn = m_Parent->GetScreen()->GetFileName() + wxT( "-drc" ); + fn = m_Parent->GetBoard()->GetFileName() + wxT( "-drc" ); fn.SetExt( Ext ); wxFileDialog dlg( this, _( "Save DRC Report File" ), wxEmptyString, @@ -574,7 +574,7 @@ void DIALOG_DRC_CONTROL::writeReport( FILE* fp ) int count; fprintf( fp, "** Drc report for %s **\n", - TO_UTF8( m_Parent->GetScreen()->GetFileName() ) ); + TO_UTF8( m_Parent->GetBoard()->GetFileName() ) ); wxDateTime now = wxDateTime::Now(); diff --git a/pcbnew/dialogs/dialog_netlist.cpp b/pcbnew/dialogs/dialog_netlist.cpp index 6c7c07ed47..64e9b38703 100644 --- a/pcbnew/dialogs/dialog_netlist.cpp +++ b/pcbnew/dialogs/dialog_netlist.cpp @@ -14,6 +14,7 @@ #include #include +#include #include #include @@ -28,7 +29,7 @@ void PCB_EDIT_FRAME::InstallNetlistFrame( wxDC* DC ) if( !fn.FileExists() ) { - fn = GetScreen()->GetFileName(); + fn = GetBoard()->GetFileName(); fn.SetExt( NetlistFileExtension ); lastNetlistName = fn.GetFullPath(); } @@ -40,10 +41,10 @@ void PCB_EDIT_FRAME::InstallNetlistFrame( wxDC* DC ) // Save project settings if needed. // Project settings are saved in the corresponding .pro file if( lastNetlistName != GetLastNetListRead() && - !GetScreen()->GetFileName().IsEmpty() && + !GetBoard()->GetFileName().IsEmpty() && IsOK(NULL, _("Project config has changed. Save it ?") ) ) { - wxFileName fn = GetScreen()->GetFileName(); + wxFileName fn = GetBoard()->GetFileName(); fn.SetExt( ProjectFileExtension ); wxGetApp().WriteProjectConfig( fn.GetFullPath(), GROUP, GetProjectFileParameters() ); diff --git a/pcbnew/eagle_plugin.cpp b/pcbnew/eagle_plugin.cpp index 69ad4c9415..41efc9012e 100644 --- a/pcbnew/eagle_plugin.cpp +++ b/pcbnew/eagle_plugin.cpp @@ -1101,6 +1101,10 @@ BOARD* EAGLE_PLUGIN::Load( const wxString& aFileName, BOARD* aAppendToMe, PROPE m_board = aAppendToMe ? aAppendToMe : new BOARD(); + // Give the filename to the board if it's new + if( !aAppendToMe ) + m_board->SetFileName( aFileName ); + // delete on exception, iff I own m_board, according to aAppendToMe auto_ptr deleter( aAppendToMe ? NULL : m_board ); diff --git a/pcbnew/export_gencad.cpp b/pcbnew/export_gencad.cpp index 9ae7d4bef0..37861d53a8 100644 --- a/pcbnew/export_gencad.cpp +++ b/pcbnew/export_gencad.cpp @@ -119,7 +119,7 @@ static double MapYTo( int aY ) /* Driver function: processing starts here */ void PCB_EDIT_FRAME::ExportToGenCAD( wxCommandEvent& aEvent ) { - wxFileName fn = GetScreen()->GetFileName(); + wxFileName fn = GetBoard()->GetFileName(); wxString msg, ext, wildcard; FILE* file; @@ -688,7 +688,7 @@ static void CreateSignalsSection( FILE* aFile, BOARD* aPcb ) static bool CreateHeaderInfoData( FILE* aFile, PCB_EDIT_FRAME* aFrame ) { wxString msg; - PCB_SCREEN* screen = (PCB_SCREEN*) aFrame->GetScreen(); + BOARD *board = aFrame->GetBoard(); fputs( "$HEADER\n", aFile ); fputs( "GENCAD 1.4\n", aFile ); @@ -699,7 +699,7 @@ static bool CreateHeaderInfoData( FILE* aFile, PCB_EDIT_FRAME* aFrame ) GetChars( GetBuildVersion() ) ); fputs( TO_UTF8( msg ), aFile ); - msg = wxT( "DRAWING \"" ) + screen->GetFileName() + wxT( "\"\n" ); + msg = wxT( "DRAWING \"" ) + board->GetFileName() + wxT( "\"\n" ); fputs( TO_UTF8( msg ), aFile ); const TITLE_BLOCK& tb = aFrame->GetTitleBlock(); diff --git a/pcbnew/export_vrml.cpp b/pcbnew/export_vrml.cpp index 093070d2a8..c2c75e9d17 100644 --- a/pcbnew/export_vrml.cpp +++ b/pcbnew/export_vrml.cpp @@ -1197,7 +1197,7 @@ void PCB_EDIT_FRAME::OnExportVRML( wxCommandEvent& event ) // Build default file name wxString ext = wxT( "wrl" ); - fn = GetScreen()->GetFileName(); + fn = GetBoard()->GetFileName(); fn.SetExt( ext ); DIALOG_EXPORT_3DFILE dlg( this ); diff --git a/pcbnew/files.cpp b/pcbnew/files.cpp index 9be277668e..70b941ffb5 100644 --- a/pcbnew/files.cpp +++ b/pcbnew/files.cpp @@ -85,7 +85,7 @@ void PCB_EDIT_FRAME::Files_io( wxCommandEvent& event ) switch( id ) { case ID_LOAD_FILE: - LoadOnePcbFile( GetScreen()->GetFileName(), false, true ); + LoadOnePcbFile( GetBoard()->GetFileName(), false, true ); break; case ID_MENU_READ_LAST_SAVED_VERSION_BOARD: @@ -99,7 +99,7 @@ void PCB_EDIT_FRAME::Files_io( wxCommandEvent& event ) } else { - fn = GetScreen()->GetFileName(); + fn = GetBoard()->GetFileName(); fn.SetExt( pcbBackupFileExtension ); } @@ -119,7 +119,9 @@ void PCB_EDIT_FRAME::Files_io( wxCommandEvent& event ) LoadOnePcbFile( fn.GetFullPath(), false ); fn.SetExt( PcbFileExtension ); - GetScreen()->SetFileName( fn.GetFullPath() ); + + // Re-set the name since extension changed + GetBoard()->SetFileName( fn.GetFullPath() ); UpdateTitle(); } break; @@ -129,16 +131,20 @@ void PCB_EDIT_FRAME::Files_io( wxCommandEvent& event ) break; case ID_NEW_BOARD: - Clear_Pcb( true ); - GetScreen()->GetFileName().Printf( wxT( "%s%cnoname%s" ), - GetChars( wxGetCwd() ), DIR_SEP, - GetChars( PcbFileExtension ) ); - UpdateTitle(); - ReCreateLayerBox( NULL ); + { + Clear_Pcb( true ); + wxString newFilename; + newFilename.Printf( wxT( "%s%cnoname%s" ), + GetChars( wxGetCwd() ), DIR_SEP, + GetChars( PcbFileExtension ) ); + GetBoard()->SetFileName( newFilename ); + UpdateTitle(); + ReCreateLayerBox( NULL ); + } break; case ID_SAVE_BOARD: - SavePcbFile( GetScreen()->GetFileName() ); + SavePcbFile( GetBoard()->GetFileName() ); break; case ID_SAVE_BOARD_AS: @@ -163,7 +169,7 @@ the changes?" ) ) ) if( aAppend ) { - GetScreen()->SetFileName( wxEmptyString ); + GetBoard()->SetFileName( wxEmptyString ); OnModify(); GetBoard()->m_Status_Pcb = 0; } @@ -235,7 +241,7 @@ the changes?" ) ) ) CheckForAutoSaveFile( fileName, pcbBackupFileExtension ); - GetScreen()->SetFileName( fileName.GetFullPath() ); + GetBoard()->SetFileName( fileName.GetFullPath() ); if( !aAppend ) { @@ -247,7 +253,7 @@ the changes?" ) ) ) m_DisplayViaFill = DisplayOpt.DisplayViaFill; // load project settings before BOARD, in case BOARD file has overrides. - LoadProjectSettings( GetScreen()->GetFileName() ); + LoadProjectSettings( GetBoard()->GetFileName() ); } else { @@ -264,7 +270,11 @@ the changes?" ) ) ) props["page_height"] = wxString::Format( wxT( "%d" ), GetPageSizeIU().y ); // load or append either: - loadedBoard = pi->Load( GetScreen()->GetFileName(), aAppend ? GetBoard() : NULL, &props ); + loadedBoard = pi->Load( GetBoard()->GetFileName(), aAppend ? GetBoard() : NULL, &props ); + + // the Load plugin method makes a 'fresh' board, so we need to + // set its own name + GetBoard()->SetFileName( fileName.GetFullPath() ); if( !aAppend ) { @@ -301,7 +311,7 @@ this file again." ) ); // If append option: change the initial board name to -append.brd if( aAppend ) { - wxString new_filename = GetScreen()->GetFileName().BeforeLast( '.' ); + wxString new_filename = GetBoard()->GetFileName().BeforeLast( '.' ); if ( ! new_filename.EndsWith( wxT( "-append" ) ) ) new_filename += wxT( "-append" ); @@ -309,13 +319,16 @@ this file again." ) ); new_filename += wxT( "." ) + PcbFileExtension; OnModify(); - GetScreen()->SetFileName( new_filename ); + GetBoard()->SetFileName( new_filename ); } - GetScreen()->GetFileName().Replace( WIN_STRING_DIR_SEP, UNIX_STRING_DIR_SEP ); + // Fix the directory separator on Windows + wxString fn( GetBoard()->GetFileName() ); + fn.Replace( WIN_STRING_DIR_SEP, UNIX_STRING_DIR_SEP ); + GetBoard()->SetFileName( fn ); UpdateTitle(); - UpdateFileHistory( GetScreen()->GetFileName() ); + UpdateFileHistory( GetBoard()->GetFileName() ); // Rebuild the new pad list (for drc and ratsnet control ...) GetBoard()->m_Status_Pcb = 0; @@ -404,18 +417,18 @@ bool PCB_EDIT_FRAME::SavePcbFile( const wxString& aFileName, bool aCreateBackupF if( aFileName == wxEmptyString ) { - wxFileDialog dlg( this, _( "Save Board File" ), wxEmptyString, GetScreen()->GetFileName(), + wxFileDialog dlg( this, _( "Save Board File" ), wxEmptyString, GetBoard()->GetFileName(), wildcard, wxFD_SAVE | wxFD_OVERWRITE_PROMPT ); if( dlg.ShowModal() != wxID_OK ) return false; - GetScreen()->SetFileName( dlg.GetPath() ); + GetBoard()->SetFileName( dlg.GetPath() ); wildcardIndex = dlg.GetFilterIndex(); // Legacy or s-expression file format. } else { - GetScreen()->SetFileName( aFileName ); + GetBoard()->SetFileName( aFileName ); } // If changes are made, update the board date @@ -427,7 +440,7 @@ bool PCB_EDIT_FRAME::SavePcbFile( const wxString& aFileName, bool aCreateBackupF SetTitleBlock( tb ); } - pcbFileName = GetScreen()->GetFileName(); + pcbFileName = GetBoard()->GetFileName(); if( pcbFileName.GetExt().IsEmpty() ) pcbFileName.SetExt( IO_MGR::GetFileExtension( (IO_MGR::PCB_FILE_T) wildcardIndex ) ); @@ -500,7 +513,7 @@ bool PCB_EDIT_FRAME::SavePcbFile( const wxString& aFileName, bool aCreateBackupF if( saveok ) { - GetScreen()->SetFileName( pcbFileName.GetFullPath() ); + GetBoard()->SetFileName( pcbFileName.GetFullPath() ); UpdateTitle(); } @@ -537,7 +550,7 @@ bool PCB_EDIT_FRAME::SavePcbFile( const wxString& aFileName, bool aCreateBackupF bool PCB_EDIT_FRAME::doAutoSave() { - wxFileName tmpFileName = GetScreen()->GetFileName(); + wxFileName tmpFileName = GetBoard()->GetFileName(); wxFileName fn = tmpFileName; // Auto save file name is the normal file name prepended with $. @@ -549,13 +562,13 @@ bool PCB_EDIT_FRAME::doAutoSave() if( SavePcbFile( fn.GetFullPath(), NO_BACKUP_FILE ) ) { GetScreen()->SetModify(); - GetScreen()->SetFileName( tmpFileName.GetFullPath() ); + GetBoard()->SetFileName( tmpFileName.GetFullPath() ); UpdateTitle(); m_autoSaveState = false; return true; } - GetScreen()->SetFileName( tmpFileName.GetFullPath() ); + GetBoard()->SetFileName( tmpFileName.GetFullPath() ); return false; } diff --git a/pcbnew/gen_drill_report_files.cpp b/pcbnew/gen_drill_report_files.cpp index ed27229639..ca59c0256b 100644 --- a/pcbnew/gen_drill_report_files.cpp +++ b/pcbnew/gen_drill_report_files.cpp @@ -180,7 +180,7 @@ void GenDrillMapFile( BOARD* aPcb, FILE* aFile, const wxString& aFullFileName, // Plot title "Info" wxString Text = wxT( "Drill Map:" ); - plotter->Text( wxPoint( plotX, plotY ), BLACK, Text, 0, + plotter->Text( wxPoint( plotX, plotY ), UNSPECIFIED, Text, 0, wxSize( (int) ( charSize * charScale ), (int) ( charSize * charScale ) ), GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_CENTER, @@ -232,7 +232,7 @@ void GenDrillMapFile( BOARD* aPcb, FILE* aFile, const wxString& aFullFileName, aToolListBuffer[ii].m_OvalCount ); msg += FROM_UTF8( line ); - plotter->Text( wxPoint( plotX, y ), BLACK, + plotter->Text( wxPoint( plotX, y ), UNSPECIFIED, msg, 0, wxSize( (int) ( charSize * charScale ), (int) ( charSize * charScale ) ), GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_CENTER, diff --git a/pcbnew/gen_modules_placefile.cpp b/pcbnew/gen_modules_placefile.cpp index 4e65b009ce..91fbc0cfb6 100644 --- a/pcbnew/gen_modules_placefile.cpp +++ b/pcbnew/gen_modules_placefile.cpp @@ -161,7 +161,7 @@ void DIALOG_GEN_MODULE_POSITION::OnOutputDirectoryBrowseClicked( wxCommandEvent& if( dialog.ShowModal() == wxID_YES ) { - wxString boardFilePath = ( (wxFileName) m_parent->GetScreen()->GetFileName()).GetPath(); + wxString boardFilePath = ( (wxFileName) m_parent->GetBoard()->GetFileName()).GetPath(); if( !dirName.MakeRelativeTo( boardFilePath ) ) wxMessageBox( _( "Cannot make path relative (target volume different from board file volume)!" ), @@ -193,7 +193,6 @@ void DIALOG_GEN_MODULE_POSITION::OnOKButton( wxCommandEvent& event ) bool DIALOG_GEN_MODULE_POSITION::CreateFiles() { BOARD * brd = m_parent->GetBoard(); - PCB_SCREEN * screen = m_parent->GetScreen(); wxFileName fn; wxString msg; wxString frontLayerName; @@ -201,7 +200,7 @@ bool DIALOG_GEN_MODULE_POSITION::CreateFiles() bool singleFile = OneFileOnly(); int fullcount = 0; - fn = screen->GetFileName(); + fn = m_parent->GetBoard()->GetFileName(); fn.SetPath( GetOutputDirectory() ); frontLayerName = brd->GetLayerName( LAYER_N_FRONT ); backLayerName = brd->GetLayerName( LAYER_N_BACK ); @@ -250,7 +249,7 @@ bool DIALOG_GEN_MODULE_POSITION::CreateFiles() // Create the Back or Bottom side placement file fullcount = fpcount; side = 0; - fn = screen->GetFileName(); + fn = brd->GetFileName(); fn.SetPath( GetOutputDirectory() ); fn.SetName( fn.GetName() + wxT( "-" ) + backLayerName ); fn.SetExt( wxT( "pos" ) ); @@ -506,13 +505,13 @@ void PCB_EDIT_FRAME::GenFootprintsReport( wxCommandEvent& event ) { wxFileName fn; - wxString boardFilePath = ( (wxFileName) GetScreen()->GetFileName()).GetPath(); + wxString boardFilePath = ( (wxFileName) GetBoard()->GetFileName()).GetPath(); wxDirDialog dirDialog( this, _( "Select Output Directory" ), boardFilePath ); if( dirDialog.ShowModal() == wxID_CANCEL ) return; - fn = GetScreen()->GetFileName(); + fn = GetBoard()->GetFileName(); fn.SetPath( dirDialog.GetPath() ); fn.SetExt( wxT( "rpt" ) ); diff --git a/pcbnew/gendrill.cpp b/pcbnew/gendrill.cpp index 653619c91c..a14c2f3ae6 100644 --- a/pcbnew/gendrill.cpp +++ b/pcbnew/gendrill.cpp @@ -129,7 +129,7 @@ void DIALOG_GENDRILL::GenDrillAndReportFiles() if( s_ToolListBuffer.size() > 0 ) // holes? { - fn = m_parent->GetScreen()->GetFileName(); + fn = m_parent->GetBoard()->GetFileName(); layer_extend.Empty(); if( gen_NPTH_holes ) @@ -240,7 +240,7 @@ void DIALOG_GENDRILL::GenDrillAndReportFiles() if( m_Choice_Drill_Report->GetSelection() > 0 ) { - fn = m_parent->GetScreen()->GetFileName(); + fn = m_parent->GetBoard()->GetFileName(); GenDrillReport( fn.GetFullName() ); } @@ -693,7 +693,7 @@ void DIALOG_GENDRILL::GenDrillReport( const wxString aFileName ) } GenDrillReportFile( report_dest, m_parent->GetBoard(), - m_parent->GetScreen()->GetFileName(), + m_parent->GetBoard()->GetFileName(), m_UnitDrillIsInch, s_HoleListBuffer, s_ToolListBuffer ); diff --git a/pcbnew/initpcb.cpp b/pcbnew/initpcb.cpp index f9c44ba04d..5d180ab66c 100644 --- a/pcbnew/initpcb.cpp +++ b/pcbnew/initpcb.cpp @@ -51,7 +51,7 @@ bool PCB_EDIT_FRAME::Clear_Pcb( bool aQuery ) SetCurItem( NULL ); // clear filename, to avoid overwriting an old file - GetScreen()->GetFileName().Empty(); + GetBoard()->SetFileName( wxEmptyString ); // preserve grid size accross call to InitDataPoints() @@ -101,7 +101,7 @@ bool FOOTPRINT_EDIT_FRAME::Clear_Pcb( bool aQuery ) GetBoard()->m_Modules.DeleteAll(); // init pointeurs et variables - GetScreen()->GetFileName().Empty(); + GetBoard()->SetFileName( wxEmptyString ); SetCurItem( NULL ); diff --git a/pcbnew/kicad_plugin.cpp b/pcbnew/kicad_plugin.cpp index 9c3e65dc71..1d1c3dab6e 100644 --- a/pcbnew/kicad_plugin.cpp +++ b/pcbnew/kicad_plugin.cpp @@ -1204,5 +1204,11 @@ BOARD* PCB_IO::Load( const wxString& aFileName, BOARD* aAppendToMe, PROPERTIES* PCB_PARSER parser( new FILE_LINE_READER( file.fp(), aFileName ), aAppendToMe ); - return (BOARD*) parser.Parse(); + BOARD* board = dynamic_cast( parser.Parse() ); + wxASSERT( board ); + + // Give the filename to the board if it's new + if( !aAppendToMe ) + board->SetFileName( aFileName ); + return board; } diff --git a/pcbnew/legacy_plugin.cpp b/pcbnew/legacy_plugin.cpp index 676b376c36..747a833f43 100644 --- a/pcbnew/legacy_plugin.cpp +++ b/pcbnew/legacy_plugin.cpp @@ -232,6 +232,10 @@ BOARD* LEGACY_PLUGIN::Load( const wxString& aFileName, BOARD* aAppendToMe, PROPE m_board = aAppendToMe ? aAppendToMe : new BOARD(); + // Give the filename to the board if it's new + if( !aAppendToMe ) + m_board->SetFileName( aFileName ); + // delete on exception, iff I own m_board, according to aAppendToMe auto_ptr deleter( aAppendToMe ? NULL : m_board ); diff --git a/pcbnew/pcb_plot_params.cpp b/pcbnew/pcb_plot_params.cpp index 3bc80b305c..2cafdacc03 100644 --- a/pcbnew/pcb_plot_params.cpp +++ b/pcbnew/pcb_plot_params.cpp @@ -286,7 +286,6 @@ bool PCB_PLOT_PARAMS::SetLineWidth( int aValue ) return setInt( &m_lineWidth, aValue, PLOT_LINEWIDTH_MIN, PLOT_LINEWIDTH_MAX ); } - // PCB_PLOT_PARAMS_PARSER PCB_PLOT_PARAMS_PARSER::PCB_PLOT_PARAMS_PARSER( LINE_READER* aReader ) : diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index 087de07bbe..119a80cc5a 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -482,7 +482,7 @@ void PCB_EDIT_FRAME::OnCloseWindow( wxCloseEvent& Event ) { wxString msg; msg.Printf( _("Save the changes in\n<%s>\nbefore closing?"), - GetChars( GetScreen()->GetFileName() ) ); + GetChars( GetBoard()->GetFileName() ) ); int ii = DisplayExitDialog( this, msg ); switch( ii ) @@ -496,13 +496,13 @@ void PCB_EDIT_FRAME::OnCloseWindow( wxCloseEvent& Event ) case wxID_OK: case wxID_YES: - SavePcbFile( GetScreen()->GetFileName() ); + SavePcbFile( GetBoard()->GetFileName() ); break; } } // Delete the auto save file if it exists. - wxFileName fn = GetScreen()->GetFileName(); + wxFileName fn = GetBoard()->GetFileName(); // Auto save file name is the normal file name prefixed with a '$'. fn.SetName( wxT( "$" ) + fn.GetName() ); @@ -546,6 +546,7 @@ void PCB_EDIT_FRAME::Show3D_Frame( wxCommandEvent& event ) } m_Draw3DFrame = new EDA_3D_FRAME( this, _( "3D Viewer" ) ); + m_Draw3DFrame->SetDefaultFileName( GetBoard()->GetFileName() ); m_Draw3DFrame->Show( true ); } @@ -726,7 +727,7 @@ void PCB_EDIT_FRAME::SetLanguage( wxCommandEvent& event ) wxString PCB_EDIT_FRAME::GetLastNetListRead() { wxFileName absoluteFileName = m_lastNetListRead; - wxFileName pcbFileName = GetScreen()->GetFileName(); + wxFileName pcbFileName = GetBoard()->GetFileName(); if( !absoluteFileName.MakeAbsolute( pcbFileName.GetPath() ) || !absoluteFileName.FileExists() ) { @@ -741,7 +742,7 @@ wxString PCB_EDIT_FRAME::GetLastNetListRead() void PCB_EDIT_FRAME::SetLastNetListRead( const wxString& aLastNetListRead ) { wxFileName relativeFileName = aLastNetListRead; - wxFileName pcbFileName = GetScreen()->GetFileName(); + wxFileName pcbFileName = GetBoard()->GetFileName(); if( relativeFileName.MakeRelativeTo( pcbFileName.GetPath() ) && relativeFileName.GetFullPath() != aLastNetListRead ) @@ -771,7 +772,7 @@ void PCB_EDIT_FRAME::SVG_Print( wxCommandEvent& event ) void PCB_EDIT_FRAME::UpdateTitle() { wxString title; - wxFileName fileName = GetScreen()->GetFileName(); + wxFileName fileName = GetBoard()->GetFileName(); if( fileName.IsOk() && fileName.FileExists() ) { diff --git a/pcbnew/pcbnew.cpp b/pcbnew/pcbnew.cpp index bfa325e1ed..52b9817768 100644 --- a/pcbnew/pcbnew.cpp +++ b/pcbnew/pcbnew.cpp @@ -182,14 +182,14 @@ Changing extension to .brd." ), GetChars( fn.GetFullPath() ) ); else { // File does not exists: prepare an empty board wxSetWorkingDirectory( fn.GetPath() ); - frame->GetScreen()->SetFileName( fn.GetFullPath( wxPATH_UNIX ) ); + frame->GetBoard()->SetFileName( fn.GetFullPath( wxPATH_UNIX ) ); frame->UpdateTitle(); - frame->UpdateFileHistory( frame->GetScreen()->GetFileName() ); + frame->UpdateFileHistory( frame->GetBoard()->GetFileName() ); frame->OnModify(); // Ready to save the new empty board wxString msg; msg.Printf( _( "File <%s> does not exist.\nThis is normal for a new project" ), - GetChars( frame->GetScreen()->GetFileName() ) ); + GetChars( frame->GetBoard()->GetFileName() ) ); wxMessageBox( msg ); } } diff --git a/pcbnew/pcbnew_config.cpp b/pcbnew/pcbnew_config.cpp index 99c9a4dfa2..3dc0c3420d 100644 --- a/pcbnew/pcbnew_config.cpp +++ b/pcbnew/pcbnew_config.cpp @@ -105,7 +105,7 @@ void PCB_EDIT_FRAME::Process_Config( wxCommandEvent& event ) case ID_CONFIG_READ: { - fn = GetScreen()->GetFileName(); + fn = GetBoard()->GetFileName(); fn.SetExt( ProjectFileExtension ); wxFileDialog dlg( this, _( "Read Project File" ), fn.GetPath(), @@ -204,7 +204,7 @@ void PCB_EDIT_FRAME::SaveProjectSettings() { wxFileName fn; - fn = GetScreen()->GetFileName(); + fn = GetBoard()->GetFileName(); fn.SetExt( ProjectFileExtension ); wxFileDialog dlg( this, _( "Save Project File" ), fn.GetPath(), fn.GetFullName(), @@ -391,7 +391,7 @@ void PCB_EDIT_FRAME::SaveMacros() wxXmlProperty *macrosProp, *hkProp, *xProp, *yProp; wxString str, hkStr, xStr, yStr; - fn = GetScreen()->GetFileName(); + fn = GetBoard()->GetFileName(); fn.SetExt( MacrosFileExtension ); wxFileDialog dlg( this, _( "Save Macros File" ), fn.GetPath(), fn.GetFullName(), @@ -437,7 +437,7 @@ void PCB_EDIT_FRAME::ReadMacros() wxString str; wxFileName fn; - fn = GetScreen()->GetFileName(); + fn = GetBoard()->GetFileName(); fn.SetExt( MacrosFileExtension ); wxFileDialog dlg( this, _( "Read Macros File" ), fn.GetPath(), diff --git a/pcbnew/pcbplot.cpp b/pcbnew/pcbplot.cpp index d5d5df67f6..00610303e0 100644 --- a/pcbnew/pcbplot.cpp +++ b/pcbnew/pcbplot.cpp @@ -46,6 +46,9 @@ #include #include #include +#include +#include +#include /* Keywords to r/w options in m_config */ #define CONFIG_XFINESCALE_ADJ wxT( "PlotXFineScaleAdj" ) @@ -73,7 +76,135 @@ static bool setDouble( double* aDouble, double aValue, double aMin, double aMax return true; } +/** Get the 'traditional' gerber extension depending on the layer */ +static wxString GetGerberExtension( int layer )/*{{{*/ +{ + switch( layer ) + { + case LAYER_N_FRONT: + return wxString( wxT( "gtl" ) ); + case LAYER_N_2: + case LAYER_N_3: + case LAYER_N_4: + case LAYER_N_5: + case LAYER_N_6: + case LAYER_N_7: + case LAYER_N_8: + case LAYER_N_9: + case LAYER_N_10: + case LAYER_N_11: + case LAYER_N_12: + case LAYER_N_13: + case LAYER_N_14: + case LAYER_N_15: + + // TODO: see if we use .gbr or a layer identifier (gb1 .. gbnn ?) + // according to the new internal layers designation + // (1 is the first internal layer from the front layer) + return wxString( wxT( "gbr" ) ); + + case LAYER_N_BACK: + return wxString( wxT( "gbl" ) ); + + case ADHESIVE_N_BACK: + return wxString( wxT( "gba" ) ); + + case ADHESIVE_N_FRONT: + return wxString( wxT( "gta" ) ); + + case SOLDERPASTE_N_BACK: + return wxString( wxT( "gbp" ) ); + + case SOLDERPASTE_N_FRONT: + return wxString( wxT( "gtp" ) ); + + case SILKSCREEN_N_BACK: + return wxString( wxT( "gbo" ) ); + + case SILKSCREEN_N_FRONT: + return wxString( wxT( "gto" ) ); + + case SOLDERMASK_N_BACK: + return wxString( wxT( "gbs" ) ); + + case SOLDERMASK_N_FRONT: + return wxString( wxT( "gts" ) ); + + case DRAW_N: + case COMMENT_N: + case ECO1_N: + case ECO2_N: + case EDGE_N: + default: + return wxString( wxT( "gbr" ) ); + } +}/*}}}*/ + +/** Complete a plot filename: forces the output directory, add a suffix to the name + and sets the extension if specified */ +static void BuildPlotFileName( wxFileName *aFilename, /*{{{*/ + const wxString& aOutputDir, + wxString aSuffix, + const wxString& aExtension ) +{ + aFilename->SetPath( aOutputDir ); + + // Set the file extension + aFilename->SetExt( aExtension ); + + /* remove leading and trailing spaces if any from the suffix, if + something survives add it to the name; also the suffix can contain + an extension: if that's the case, apply it */ + aSuffix.Trim( true ); aSuffix.Trim( false ); + + wxFileName suffix_fn( aSuffix ); + + if( suffix_fn.HasName() ) + aFilename->SetName( aFilename->GetName() + wxT( "-" ) + suffix_fn.GetName() ); + if( suffix_fn.HasExt() ) + aFilename->SetExt( suffix_fn.GetExt() ); +}/*}}}*/ + +/** Fix the output directory pathname to absolute and ensure it exists */ +static bool EnsureOutputDirectory( wxFileName *aOutputDir, /*{{{*/ + const wxString& aBoardFilename, + wxTextCtrl* aMessageBox ) +{ + wxString boardFilePath = wxFileName( aBoardFilename ).GetPath(); + + if( !aOutputDir->MakeAbsolute( boardFilePath ) ) + { + wxString msg; + msg.Printf( _( "Cannot make %s absolute with respect to %s!" ), + GetChars( aOutputDir->GetPath() ), + GetChars( boardFilePath ) ); + wxMessageBox( msg, _( "Plot" ), wxOK | wxICON_ERROR ); + return false; + } + + wxString outputPath( aOutputDir->GetPath() ); + if( !wxFileName::DirExists( outputPath ) ) + { + if( wxMkdir( outputPath ) ) + { + if( aMessageBox ) + { + wxString msg; + msg.Printf( _( "Directory %s created.\n" ), GetChars( outputPath ) ); + aMessageBox->AppendText( msg ); + return true; + } + } + else + { + wxMessageBox( _( "Cannot create output directory!" ), + _( "Plot" ), wxOK | wxICON_ERROR ); + return false; + } + } + return true; +}/*}}}*/ /** * Class DIALOG_PLOT @@ -308,7 +439,7 @@ void DIALOG_PLOT::OnOutputDirectoryBrowseClicked( wxCommandEvent& event ) wxYES_NO | wxICON_QUESTION | wxYES_DEFAULT ); if( dialog.ShowModal() == wxID_YES ) { - wxString boardFilePath = ( (wxFileName) m_parent->GetScreen()->GetFileName()).GetPath(); + wxString boardFilePath = ( (wxFileName) m_parent->GetBoard()->GetFileName()).GetPath(); if( !dirName.MakeRelativeTo( boardFilePath ) ) wxMessageBox( _( "Cannot make path relative (target volume different from board file volume)!" ), @@ -613,39 +744,15 @@ void DIALOG_PLOT::applyPlotSettings() void DIALOG_PLOT::Plot( wxCommandEvent& event ) { int layer; - wxFileName fn; applyPlotSettings(); - // Create output directory if it does not exist + // Create output directory if it does not exist (also transform it in + // absolute form). Bail if it fails wxFileName outputDir = wxFileName::DirName( m_plotOpts.GetOutputDirectory() ); - wxString boardFilePath = ( (wxFileName) m_parent->GetScreen()->GetFileName()).GetPath(); - - if( !outputDir.MakeAbsolute( boardFilePath ) ) - { - wxString msg; - msg.Printf( _( " Cannot make %s absolute with respect to %s!" ), - GetChars( outputDir.GetPath() ), - GetChars( boardFilePath ) ); - wxMessageBox( msg, _( "Plot" ), wxOK | wxICON_ERROR ); + wxString boardFilename = m_parent->GetBoard()->GetFileName(); + if( !EnsureOutputDirectory( &outputDir, boardFilename, m_messagesBox ) ) return; - } - - if( !wxFileName::DirExists( outputDir.GetPath() ) ) - { - if( wxMkdir( outputDir.GetPath() ) ) - { - wxString msg; - msg.Printf( _( "Directory %s created.\n" ), GetChars( outputDir.GetPath() ) ); - m_messagesBox->AppendText( msg ); - } - else - { - wxMessageBox( _( "Cannot create output directory!" ), - _( "Plot" ), wxOK | wxICON_ERROR ); - return; - } - } m_plotOpts.SetAutoScale( false ); m_plotOpts.SetScale( 1 ); @@ -685,16 +792,6 @@ void DIALOG_PLOT::Plot( wxCommandEvent& event ) if( m_PSFineAdjustWidthOpt->IsEnabled() ) m_plotOpts.SetWidthAdjust( m_PSWidthAdjust ); - switch( m_plotOpts.GetFormat() ) - { - case PLOT_FORMAT_GERBER: - case PLOT_FORMAT_DXF: - m_plotOpts.SetScale( 1 ); // No scaling for these - break; - default: - break; - } - wxString file_ext( GetDefaultPlotExtension( m_plotOpts.GetFormat() ) ); // Test for a reasonable scale value @@ -715,132 +812,38 @@ void DIALOG_PLOT::Plot( wxCommandEvent& event ) for( layer = 0; layer < NB_LAYERS; layer++, layerMask <<= 1 ) { - bool success = false; - if( m_plotOpts.GetLayerSelection() & layerMask ) { - fn = m_parent->GetScreen()->GetFileName(); - fn.SetPath( outputDir.GetPath() ); - - // Create file name (from the English layer name for non copper layers). - wxString layername = m_board->GetLayerName( layer, false ); - // remove leading and trailing spaces if any - layername.Trim( true ); layername.Trim( false ); - fn.SetName( fn.GetName() + wxT( "-" ) + layername ); + // Pick the basename from the board file + wxFileName fn( boardFilename ); // Use Gerber Extensions based on layer number // (See http://en.wikipedia.org/wiki/Gerber_File) if( ( m_plotOpts.GetFormat() == PLOT_FORMAT_GERBER ) && m_useGerberExtensions->GetValue() ) - { - switch( layer ) - { - case LAYER_N_FRONT: - fn.SetExt( wxT( "gtl" ) ); - break; + file_ext = GetGerberExtension( layer ); - case LAYER_N_2: - case LAYER_N_3: - case LAYER_N_4: - case LAYER_N_5: - case LAYER_N_6: - case LAYER_N_7: - case LAYER_N_8: - case LAYER_N_9: - case LAYER_N_10: - case LAYER_N_11: - case LAYER_N_12: - case LAYER_N_13: - case LAYER_N_14: - case LAYER_N_15: + // Create file name (from the English layer name for non copper layers). + BuildPlotFileName( &fn, outputDir.GetPath(), + m_board->GetLayerName( layer, false ), + file_ext ); - // TODO: see if we use .gbr or a layer identifier (gb1 .. gbnn ?) - // according to the new internal layers designation - // (1 is the first internal layer from the front layer) - fn.SetExt( wxT( "gbr" ) ); - break; - - case LAYER_N_BACK: - fn.SetExt( wxT( "gbl" ) ); - break; - - case ADHESIVE_N_BACK: - fn.SetExt( wxT( "gba" ) ); - break; - - case ADHESIVE_N_FRONT: - fn.SetExt( wxT( "gta" ) ); - break; - - case SOLDERPASTE_N_BACK: - fn.SetExt( wxT( "gbp" ) ); - break; - - case SOLDERPASTE_N_FRONT: - fn.SetExt( wxT( "gtp" ) ); - break; - - case SILKSCREEN_N_BACK: - fn.SetExt( wxT( "gbo" ) ); - break; - - case SILKSCREEN_N_FRONT: - fn.SetExt( wxT( "gto" ) ); - break; - - case SOLDERMASK_N_BACK: - fn.SetExt( wxT( "gbs" ) ); - break; - - case SOLDERMASK_N_FRONT: - fn.SetExt( wxT( "gts" ) ); - break; - - case DRAW_N: - case COMMENT_N: - case ECO1_N: - case ECO2_N: - case EDGE_N: - default: - fn.SetExt( wxT( "gbr" ) ); - break; - } - } - else - { - fn.SetExt( file_ext ); - } - - switch( m_plotOpts.GetFormat() ) - { - case PLOT_FORMAT_POST: - success = m_parent->ExportToPostScriptFile( fn.GetFullPath(), layer, - m_plotOpts.GetA4Output(), - m_plotOpts.GetMode() ); - break; - - case PLOT_FORMAT_GERBER: - success = m_parent->ExportToGerberFile( fn.GetFullPath(), layer, - m_plotOpts.GetUseAuxOrigin(), - m_plotOpts.GetMode() ); - break; - - case PLOT_FORMAT_HPGL: - success = m_parent->ExportToHpglFile( fn.GetFullPath(), layer, - m_plotOpts.GetMode() ); - break; - - case PLOT_FORMAT_DXF: - success = m_parent->ExportToDxfFile( fn.GetFullPath(), layer, - m_plotOpts.GetMode() ); - break; - } + LOCALE_IO toggle; + BOARD *board = m_parent->GetBoard(); + PLOTTER *plotter = StartPlotBoard(board, &m_plotOpts, + fn.GetFullPath(), + wxEmptyString ); // Print diags in messages box: wxString msg; + if( plotter ) + { + PlotBoardLayer( board, plotter, layer, m_plotOpts ); + plotter->EndPlot(); + delete plotter; - if( success ) msg.Printf( _( "Plot file <%s> created" ), GetChars( fn.GetFullPath() ) ); + } else msg.Printf( _( "Unable to create <%s>" ), GetChars( fn.GetFullPath() ) ); @@ -861,3 +864,81 @@ void PCB_EDIT_FRAME::ToPlotter( wxCommandEvent& event ) DIALOG_PLOT dlg( this ); dlg.ShowModal(); } + +/** Batch plotter constructor, nothing interesting here */ +PLOT_CONTROLLER::PLOT_CONTROLLER( BOARD *aBoard ) + : m_plotter( NULL ), m_board( aBoard ) +{ +} + +/** Batch plotter destructor, ensures that the last plot is closed */ +PLOT_CONTROLLER::~PLOT_CONTROLLER() +{ + ClosePlot(); +} + +/* IMPORTANT THING TO KNOW: the locale during plots *MUST* be kept as + * C/POSIX using a LOCALE_IO object on the stack. This even when + * opening/closing the plotfile, since some drivers do I/O even then */ + +/** Close the current plot, nothing happens if it isn't open */ +void PLOT_CONTROLLER::ClosePlot() +{ + LOCALE_IO toggle; + + if( m_plotter ) + { + m_plotter->EndPlot(); + delete m_plotter; + m_plotter = NULL; + } +} + +/** Open a new plotfile; works as a factory for plotter objects + */ +bool PLOT_CONTROLLER::OpenPlotfile( const wxString &aSuffix, /*{{{*/ + PlotFormat aFormat, + const wxString &aSheetDesc ) +{ + LOCALE_IO toggle; + + /* Save the current format: sadly some plot routines depends on this + but the main reason is that the StartPlot method uses it to + dispatch the plotter creation */ + m_plotOpts.SetFormat( aFormat ); + + // Ensure that the previous plot is closed + ClosePlot(); + + // Now compute the full filename for the output and start the plot + // (after ensuring the output directory is OK) + wxString outputDirName = m_plotOpts.GetOutputDirectory() ; + wxFileName outputDir = wxFileName::DirName( outputDirName ); + wxString boardFilename = m_board->GetFileName(); + if( EnsureOutputDirectory( &outputDir, boardFilename, NULL ) ) + { + wxFileName fn( boardFilename ); + BuildPlotFileName( &fn, outputDirName, + aSuffix, GetDefaultPlotExtension( aFormat ) ); + + m_plotter = StartPlotBoard( m_board, &m_plotOpts, fn.GetFullPath(), + aSheetDesc ); + } + return( m_plotter != NULL ); +}/*}}}*/ + +/** Plot a single layer on the current plotfile */ +bool PLOT_CONTROLLER::PlotLayer( int aLayer )/*{{{*/ +{ + LOCALE_IO toggle; + + // No plot open, nothing to do... + if( !m_plotter ) + return false; + + // Fully delegated to the parent + PlotBoardLayer( m_board, m_plotter, aLayer, m_plotOpts ); + + return true; +}/*}}}*/ + diff --git a/pcbnew/pcbplot.h b/pcbnew/pcbplot.h index 255137c1a5..cea86fdf25 100644 --- a/pcbnew/pcbplot.h +++ b/pcbnew/pcbplot.h @@ -56,6 +56,46 @@ void Plot_1_EdgeModule( PLOTTER* plotter, const PCB_PLOT_PARAMS& aPlotOpts, EDGE void PlotFilledAreas( PLOTTER* plotter, const PCB_PLOT_PARAMS& aPlotOpts, ZONE_CONTAINER* aZone, EDA_DRAW_MODE_T trace_mode ); +PLOTTER *StartPlotBoard( BOARD *aBoard, + PCB_PLOT_PARAMS *aPlotOpts, + const wxString& aFullFileName, + const wxString& aSheetDesc ); + +void PlotBoardLayer( BOARD *aBoard, PLOTTER* aPlotter, int Layer, + const PCB_PLOT_PARAMS& plot_opts ); + +/** + * Function Plot_Standard_Layer + * plot copper or technical layers. + * not used for silk screen layers, because these layers have specific + * requirements, mainly for pads + * @param aPlotter = the plotter to use + * @param aLayerMask = the mask to define the layers to plot + * @param aPlotVia = true to plot vias, false to skip vias (has meaning + * only for solder mask layers). + * @param aPlotMode = the plot mode (files, sketch). Has meaning for some formats only + * @param aSkipNPTH_Pads = true to skip NPTH Pads, when the pad size and the pad hole + * have the same size. Used in GERBER format only. + */ +void PlotStandardLayer( BOARD *aBoard, PLOTTER* aPlotter, long aLayerMask, + const PCB_PLOT_PARAMS& plot_opts, + bool aPlotVia, bool aSkipNPTH_Pads ); + +void PlotSilkScreen( BOARD *aBoard, PLOTTER* aPlotter, long aLayerMask, + const PCB_PLOT_PARAMS& plot_opts ); + +/** + * Function PlotDrillMarks + * Draw a drill mark for pads and vias. + * Must be called after all drawings, because it + * redraw the drill mark on a pad or via, as a negative (i.e. white) shape + * in FILLED plot mode + * @param aPlotter = the PLOTTER + * @param aPlotOpts = plot options + */ +void PlotDrillMarks( BOARD *aBoard, PLOTTER* aPlotter, const PCB_PLOT_PARAMS& aPlotOpts ); + + // PLOTGERB.CPP void SelectD_CODE_For_LineDraw( PLOTTER* plotter, int aSize ); diff --git a/pcbnew/plot_rtn.cpp b/pcbnew/plot_rtn.cpp index 134e87af63..50fb516106 100644 --- a/pcbnew/plot_rtn.cpp +++ b/pcbnew/plot_rtn.cpp @@ -30,21 +30,22 @@ static void Plot_Edges_Modules( PLOTTER* aPlotter, const PCB_PLOT_PARAMS& aPlotOpts, BOARD* pcb, int aLayerMask, EDA_DRAW_MODE_T trace_mode ); -static void PlotTextModule( PLOTTER* aPlotter, TEXTE_MODULE* pt_texte, EDA_DRAW_MODE_T trace_mode ); +static void PlotTextModule( PLOTTER* aPlotter, TEXTE_MODULE* pt_texte, + EDA_DRAW_MODE_T trace_mode, EDA_COLOR_T aColor ); /* Creates the plot for silkscreen layers */ -void PCB_BASE_FRAME::PlotSilkScreen( PLOTTER* aPlotter, int aLayerMask, EDA_DRAW_MODE_T trace_mode ) +void PlotSilkScreen( BOARD *aBoard, PLOTTER* aPlotter, long aLayerMask, + const PCB_PLOT_PARAMS& plot_opts ) { - bool trace_val, trace_ref; TEXTE_MODULE* pt_texte; - const PCB_PLOT_PARAMS& plot_opts = GetPlotSettings(); + EDA_DRAW_MODE_T trace_mode = plot_opts.GetMode(); // Plot edge layer and graphic items - for( EDA_ITEM* item = m_Pcb->m_Drawings; item; item = item->Next() ) + for( EDA_ITEM* item = aBoard->m_Drawings; item; item = item->Next() ) { switch( item->Type() ) { @@ -68,13 +69,13 @@ void PCB_BASE_FRAME::PlotSilkScreen( PLOTTER* aPlotter, int aLayerMask, EDA_DRAW break; default: - DisplayError( this, wxT( "PlotSilkScreen() error: unexpected Type()" ) ); + DisplayError( NULL, wxT( "PlotSilkScreen() error: unexpected Type()" ) ); break; } } // Plot footprint outlines : - Plot_Edges_Modules( aPlotter, plot_opts, m_Pcb, aLayerMask, trace_mode ); + Plot_Edges_Modules( aPlotter, plot_opts, aBoard, aLayerMask, trace_mode ); // Plot pads (creates pads outlines, for pads on silkscreen layers) int layersmask_plotpads = aLayerMask; @@ -85,7 +86,7 @@ void PCB_BASE_FRAME::PlotSilkScreen( PLOTTER* aPlotter, int aLayerMask, EDA_DRAW if( layersmask_plotpads ) { - for( MODULE* Module = m_Pcb->m_Modules; Module; Module = Module->Next() ) + for( MODULE* Module = aBoard->m_Modules; Module; Module = Module->Next() ) { for( D_PAD * pad = Module->m_Pads; pad != NULL; pad = pad->Next() ) { @@ -126,11 +127,11 @@ void PCB_BASE_FRAME::PlotSilkScreen( PLOTTER* aPlotter, int aLayerMask, EDA_DRAW } // Plot footprints fields (ref, value ...) - for( MODULE* module = m_Pcb->m_Modules; module; module = module->Next() ) + for( MODULE* module = aBoard->m_Modules; module; module = module->Next() ) { // see if we want to plot VALUE and REF fields - trace_val = plot_opts.GetPlotValue(); - trace_ref = plot_opts.GetPlotReference(); + bool trace_val = plot_opts.GetPlotValue(); + bool trace_ref = plot_opts.GetPlotReference(); TEXTE_MODULE* text = module->m_Reference; unsigned textLayer = text->GetLayer(); @@ -142,7 +143,7 @@ void PCB_BASE_FRAME::PlotSilkScreen( PLOTTER* aPlotter, int aLayerMask, EDA_DRAW errMsg.Printf( _( "Your BOARD has a bad layer number of %u for \ module\n %s's \"reference\" text." ), textLayer, GetChars( module->GetReference() ) ); - DisplayError( this, errMsg ); + DisplayError( NULL, errMsg ); return; } @@ -162,7 +163,7 @@ module\n %s's \"reference\" text." ), errMsg.Printf( _( "Your BOARD has a bad layer number of %u for \ module\n %s's \"value\" text." ), textLayer, GetChars( module->GetReference() ) ); - DisplayError( this, errMsg ); + DisplayError( NULL, errMsg ); return; } @@ -174,10 +175,12 @@ module\n %s's \"value\" text." ), // Plot text fields, if allowed if( trace_ref ) - PlotTextModule( aPlotter, module->m_Reference, trace_mode ); + PlotTextModule( aPlotter, module->m_Reference, + trace_mode, plot_opts.GetReferenceColor() ); if( trace_val ) - PlotTextModule( aPlotter, module->m_Value, trace_mode ); + PlotTextModule( aPlotter, module->m_Value, + trace_mode, plot_opts.GetValueColor() ); for( pt_texte = (TEXTE_MODULE*) module->m_Drawings.GetFirst(); pt_texte != NULL; @@ -202,21 +205,22 @@ module\n %s's \"value\" text." ), for module\n %s's \"module text\" text of %s." ), textLayer, GetChars( module->GetReference() ), GetChars( pt_texte->m_Text ) ); - DisplayError( this, errMsg ); + DisplayError( NULL, errMsg ); return; } if( !( ( 1 << textLayer ) & aLayerMask ) ) continue; - PlotTextModule( aPlotter, pt_texte, trace_mode ); + PlotTextModule( aPlotter, pt_texte, + trace_mode, plot_opts.GetColor() ); } } // Plot filled areas - for( int ii = 0; ii < m_Pcb->GetAreaCount(); ii++ ) + for( int ii = 0; ii < aBoard->GetAreaCount(); ii++ ) { - ZONE_CONTAINER* edge_zone = m_Pcb->GetArea( ii ); + ZONE_CONTAINER* edge_zone = aBoard->GetArea( ii ); if( ( ( 1 << edge_zone->GetLayer() ) & aLayerMask ) == 0 ) continue; @@ -226,7 +230,7 @@ for module\n %s's \"module text\" text of %s." ), // Plot segments used to fill zone areas (outdated, but here for old boards // compatibility): - for( SEGZONE* seg = m_Pcb->m_Zone; seg != NULL; seg = seg->Next() ) + for( SEGZONE* seg = aBoard->m_Zone; seg != NULL; seg = seg->Next() ) { if( ( ( 1 << seg->GetLayer() ) & aLayerMask ) == 0 ) continue; @@ -236,7 +240,8 @@ for module\n %s's \"module text\" text of %s." ), } -static void PlotTextModule( PLOTTER* aPlotter, TEXTE_MODULE* pt_texte, EDA_DRAW_MODE_T trace_mode ) +static void PlotTextModule( PLOTTER* aPlotter, TEXTE_MODULE* pt_texte, + EDA_DRAW_MODE_T trace_mode, EDA_COLOR_T aColor ) { wxSize size; wxPoint pos; @@ -262,7 +267,7 @@ static void PlotTextModule( PLOTTER* aPlotter, TEXTE_MODULE* pt_texte, EDA_DRAW_ // So we set bold flag to true bool allow_bold = pt_texte->m_Bold || thickness; - aPlotter->Text( pos, BLACK, + aPlotter->Text( pos, aColor, pt_texte->m_Text, orient, size, pt_texte->m_HJustify, pt_texte->m_VJustify, @@ -270,7 +275,8 @@ static void PlotTextModule( PLOTTER* aPlotter, TEXTE_MODULE* pt_texte, EDA_DRAW_ } -void PlotDimension( PLOTTER* aPlotter, const PCB_PLOT_PARAMS& aPlotOpts, DIMENSION* aDim, int aLayerMask, +void PlotDimension( PLOTTER* aPlotter, const PCB_PLOT_PARAMS& aPlotOpts, + DIMENSION* aDim, int aLayerMask, EDA_DRAW_MODE_T trace_mode ) { if( (GetLayerMask( aDim->GetLayer() ) & aLayerMask) == 0 ) @@ -313,7 +319,8 @@ void PlotDimension( PLOTTER* aPlotter, const PCB_PLOT_PARAMS& aPlotOpts, DIMENSI } -void PlotPcbTarget( PLOTTER* aPlotter, const PCB_PLOT_PARAMS& aPlotOpts, PCB_TARGET* aMire, int aLayerMask, +void PlotPcbTarget( PLOTTER* aPlotter, const PCB_PLOT_PARAMS& aPlotOpts, + PCB_TARGET* aMire, int aLayerMask, EDA_DRAW_MODE_T trace_mode ) { int dx1, dx2, dy1, dy2, radius; @@ -359,7 +366,9 @@ void PlotPcbTarget( PLOTTER* aPlotter, const PCB_PLOT_PARAMS& aPlotOpts, PCB_TAR // Plot footprints graphic items (outlines) -void Plot_Edges_Modules( PLOTTER* aPlotter, const PCB_PLOT_PARAMS& aPlotOpts, BOARD* aPcb, int aLayerMask, EDA_DRAW_MODE_T trace_mode ) +static void Plot_Edges_Modules( PLOTTER* aPlotter, const PCB_PLOT_PARAMS& aPlotOpts, + BOARD* aPcb, int aLayerMask, + EDA_DRAW_MODE_T trace_mode ) { for( MODULE* module = aPcb->m_Modules; module; module = module->Next() ) { @@ -381,7 +390,8 @@ void Plot_Edges_Modules( PLOTTER* aPlotter, const PCB_PLOT_PARAMS& aPlotOpts, BO //* Plot a graphic item (outline) relative to a footprint void Plot_1_EdgeModule( PLOTTER* aPlotter, const PCB_PLOT_PARAMS& aPlotOpts, - EDGE_MODULE* aEdge, EDA_DRAW_MODE_T trace_mode, int masque_layer ) + EDGE_MODULE* aEdge, EDA_DRAW_MODE_T trace_mode, + int masque_layer ) { int type_trace; // Type of item to plot. int thickness; // Segment thickness. @@ -502,7 +512,7 @@ void PlotTextePcb( PLOTTER* aPlotter, const PCB_PLOT_PARAMS& aPlotOpts, TEXTE_PC for( unsigned i = 0; i < list->Count(); i++ ) { wxString txt = list->Item( i ); - aPlotter->Text( pos, BLACK, txt, orient, size, + aPlotter->Text( pos, UNSPECIFIED, txt, orient, size, pt_texte->m_HJustify, pt_texte->m_VJustify, thickness, pt_texte->m_Italic, allow_bold ); pos += offset; @@ -512,7 +522,7 @@ void PlotTextePcb( PLOTTER* aPlotter, const PCB_PLOT_PARAMS& aPlotOpts, TEXTE_PC } else { - aPlotter->Text( pos, BLACK, pt_texte->m_Text, orient, size, + aPlotter->Text( pos, UNSPECIFIED, pt_texte->m_Text, orient, size, pt_texte->m_HJustify, pt_texte->m_VJustify, thickness, pt_texte->m_Italic, allow_bold ); } @@ -597,7 +607,8 @@ void PlotFilledAreas( PLOTTER* aPlotter, const PCB_PLOT_PARAMS& aPlotOpts, ZONE_ /* Plot items type DRAWSEGMENT on layers allowed by aLayerMask */ -void PlotDrawSegment( PLOTTER* aPlotter, const PCB_PLOT_PARAMS& aPlotOpts, DRAWSEGMENT* aSeg, int aLayerMask, +void PlotDrawSegment( PLOTTER* aPlotter, const PCB_PLOT_PARAMS& aPlotOpts, + DRAWSEGMENT* aSeg, int aLayerMask, EDA_DRAW_MODE_T trace_mode ) { int thickness; @@ -650,9 +661,12 @@ void PlotDrawSegment( PLOTTER* aPlotter, const PCB_PLOT_PARAMS& aPlotOpts, DRAWS } -void PCB_BASE_FRAME::Plot_Layer( PLOTTER* aPlotter, int Layer, EDA_DRAW_MODE_T trace_mode ) +void PlotBoardLayer( BOARD *aBoard, PLOTTER* aPlotter, int Layer, + const PCB_PLOT_PARAMS& plot_opts ) { - const PCB_PLOT_PARAMS& plot_opts = GetPlotSettings(); + // Set the color and the text mode for this layer + aPlotter->SetColor( plot_opts.GetColor() ); + aPlotter->SetTextMode( plot_opts.GetTextMode() ); // Specify that the contents of the "Edges Pcb" layer are to be plotted // in addition to the contents of the currently specified layer. @@ -679,59 +693,49 @@ void PCB_BASE_FRAME::Plot_Layer( PLOTTER* aPlotter, int Layer, EDA_DRAW_MODE_T t case LAYER_N_14: case LAYER_N_15: case LAST_COPPER_LAYER: - // The last true make it skip NPTH pad plotting - Plot_Standard_Layer( aPlotter, layer_mask, true, trace_mode, true ); + // Skip NPTH pads on copper layers ( only if hole size == pad size ): + PlotStandardLayer( aBoard, aPlotter, layer_mask, plot_opts, true, true ); // Adding drill marks, if required and if the plotter is able to plot them: if( plot_opts.GetDrillMarksType() != PCB_PLOT_PARAMS::NO_DRILL_SHAPE ) - { - if( aPlotter->GetPlotterType() == PLOT_FORMAT_POST ) - PlotDrillMark( aPlotter, trace_mode, - plot_opts.GetDrillMarksType() == - PCB_PLOT_PARAMS::SMALL_DRILL_SHAPE ); - } + PlotDrillMarks( aBoard, aPlotter, plot_opts ); break; case SOLDERMASK_N_BACK: case SOLDERMASK_N_FRONT: - Plot_Standard_Layer( aPlotter, layer_mask, - plot_opts.GetPlotViaOnMaskLayer(), trace_mode ); + PlotStandardLayer( aBoard, aPlotter, layer_mask, plot_opts, + plot_opts.GetPlotViaOnMaskLayer(), false ); break; case SOLDERPASTE_N_BACK: case SOLDERPASTE_N_FRONT: - Plot_Standard_Layer( aPlotter, layer_mask, false, trace_mode ); + PlotStandardLayer( aBoard, aPlotter, layer_mask, plot_opts, + false, false ); break; case SILKSCREEN_N_FRONT: case SILKSCREEN_N_BACK: - PlotSilkScreen( aPlotter, layer_mask, trace_mode ); + PlotSilkScreen( aBoard, aPlotter, layer_mask, plot_opts ); // Gerber: Subtract soldermask from silkscreen if enabled if( aPlotter->GetPlotterType() == PLOT_FORMAT_GERBER && plot_opts.GetSubtractMaskFromSilk() ) { if( Layer == SILKSCREEN_N_FRONT ) - { layer_mask = GetLayerMask( SOLDERMASK_N_FRONT ); - } else - { layer_mask = GetLayerMask( SOLDERMASK_N_BACK ); - } // Set layer polarity to negative aPlotter->SetLayerPolarity( false ); - Plot_Standard_Layer( aPlotter, layer_mask, - plot_opts.GetPlotViaOnMaskLayer(), - trace_mode ); + PlotStandardLayer( aBoard, aPlotter, layer_mask, plot_opts, + plot_opts.GetPlotViaOnMaskLayer(), false ); } - break; default: - PlotSilkScreen( aPlotter, layer_mask, trace_mode ); + PlotSilkScreen( aBoard, aPlotter, layer_mask, plot_opts ); break; } } @@ -740,20 +744,18 @@ void PCB_BASE_FRAME::Plot_Layer( PLOTTER* aPlotter, int Layer, EDA_DRAW_MODE_T t /* Plot a copper layer or mask. * Silk screen layers are not plotted here. */ -void PCB_BASE_FRAME::Plot_Standard_Layer( PLOTTER* aPlotter, - int aLayerMask, - bool aPlotVia, - EDA_DRAW_MODE_T aPlotMode, - bool aSkipNPTH_Pads ) +void PlotStandardLayer( BOARD *aBoard, PLOTTER* aPlotter, + long aLayerMask, const PCB_PLOT_PARAMS& plot_opts, + bool aPlotVia, bool aSkipNPTH_Pads ) { wxPoint pos; wxSize size; wxString msg; - const PCB_PLOT_PARAMS& plot_opts = GetPlotSettings(); + EDA_DRAW_MODE_T aPlotMode = plot_opts.GetMode(); // Plot pcb draw items. - for( BOARD_ITEM* item = m_Pcb->m_Drawings; item; item = item->Next() ) + for( BOARD_ITEM* item = aBoard->m_Drawings; item; item = item->Next() ) { switch( item->Type() ) { @@ -777,13 +779,13 @@ void PCB_BASE_FRAME::Plot_Standard_Layer( PLOTTER* aPlotter, break; default: - wxMessageBox( wxT( "Plot_Standard_Layer() error : Unexpected Draw Type" ) ); + DisplayError( NULL, wxT( "Plot_Standard_Layer() error : Unexpected Draw Type" ) ); break; } } // Draw footprint shapes without pads (pads will plotted later) - for( MODULE* module = m_Pcb->m_Modules; module; module = module->Next() ) + for( MODULE* module = aBoard->m_Modules; module; module = module->Next() ) { for( BOARD_ITEM* item = module->m_Drawings; item; item = item->Next() ) { @@ -802,7 +804,7 @@ void PCB_BASE_FRAME::Plot_Standard_Layer( PLOTTER* aPlotter, } // Plot footprint pads - for( MODULE* module = m_Pcb->m_Modules; module; module = module->Next() ) + for( MODULE* module = aBoard->m_Modules; module; module = module->Next() ) { for( D_PAD* pad = module->m_Pads; pad; pad = pad->Next() ) { @@ -885,7 +887,7 @@ void PCB_BASE_FRAME::Plot_Standard_Layer( PLOTTER* aPlotter, // Plot vias : if( aPlotVia ) { - for( TRACK* track = m_Pcb->m_Track; track; track = track->Next() ) + for( TRACK* track = aBoard->m_Track; track; track = track->Next() ) { if( track->Type() != PCB_VIA_T ) continue; @@ -912,7 +914,7 @@ void PCB_BASE_FRAME::Plot_Standard_Layer( PLOTTER* aPlotter, // If the current layer is a solder mask, use the global mask // clearance for vias if( ( aLayerMask & ( SOLDERMASK_LAYER_BACK | SOLDERMASK_LAYER_FRONT ) ) ) - via_margin = GetBoard()->GetDesignSettings().m_SolderMaskMargin; + via_margin = aBoard->GetDesignSettings().m_SolderMaskMargin; if( aLayerMask & ALL_CU_LAYERS ) { @@ -931,7 +933,7 @@ void PCB_BASE_FRAME::Plot_Standard_Layer( PLOTTER* aPlotter, } // Plot tracks (not vias) : - for( TRACK* track = m_Pcb->m_Track; track; track = track->Next() ) + for( TRACK* track = aBoard->m_Track; track; track = track->Next() ) { wxPoint end; @@ -949,7 +951,7 @@ void PCB_BASE_FRAME::Plot_Standard_Layer( PLOTTER* aPlotter, } // Plot zones (outdated, for old boards compatibility): - for( TRACK* track = m_Pcb->m_Zone; track; track = track->Next() ) + for( TRACK* track = aBoard->m_Zone; track; track = track->Next() ) { wxPoint end; @@ -964,9 +966,9 @@ void PCB_BASE_FRAME::Plot_Standard_Layer( PLOTTER* aPlotter, } // Plot filled ares - for( int ii = 0; ii < m_Pcb->GetAreaCount(); ii++ ) + for( int ii = 0; ii < aBoard->GetAreaCount(); ii++ ) { - ZONE_CONTAINER* edge_zone = m_Pcb->GetArea( ii ); + ZONE_CONTAINER* edge_zone = aBoard->GetArea( ii ); if( ( ( 1 << edge_zone->GetLayer() ) & aLayerMask ) == 0 ) continue; @@ -975,85 +977,316 @@ void PCB_BASE_FRAME::Plot_Standard_Layer( PLOTTER* aPlotter, } } +/** Helper function to plot a single drill mark. It compensate and clamp + the drill mark size depending on the current plot options */ +static void PlotDrillMark( PLOTTER *aPlotter, PAD_SHAPE_T aDrillShape, + const wxPoint &aDrillPos, wxSize aDrillSize, + const wxSize &aPadSize, + double aOrientation, int aSmallDrill, + EDA_DRAW_MODE_T aTraceMode ) +{ + // Small drill marks have no significance when applied to slots + if( aSmallDrill && aDrillShape == PAD_ROUND ) + aDrillSize.x = std::min( aSmallDrill, aDrillSize.x ); + + // Round holes only have x diameter, slots have both + aDrillSize.x -= aPlotter->GetPlotWidthAdj(); + aDrillSize.x = Clamp( 1, aDrillSize.x, aPadSize.x - 1 ); + if( aDrillShape == PAD_OVAL ) + { + aDrillSize.y -= aPlotter->GetPlotWidthAdj(); + aDrillSize.y = Clamp( 1, aDrillSize.y, aPadSize.y - 1 ); + aPlotter->FlashPadOval( aDrillPos, aDrillSize, aOrientation, aTraceMode ); + } + else + aPlotter->FlashPadCircle( aDrillPos, aDrillSize.x, aTraceMode ); +} /** - * Function PlotDrillMark + * Function PlotDrillMarks * Draw a drill mark for pads and vias. * Must be called after all drawings, because it * redraw the drill mark on a pad or via, as a negative (i.e. white) shape in - * FILLED plot mode + * FILLED plot mode (for PS and PDF outputs) * @param aPlotter = the PLOTTER - * @param aTraceMode = the mode of plot (FILLED, SKETCH) * @param aSmallDrillShape = true to plot a small drill shape, false to plot * the actual drill shape */ -void PCB_BASE_FRAME::PlotDrillMark( PLOTTER* aPlotter, - EDA_DRAW_MODE_T aTraceMode, - bool aSmallDrillShape ) +void PlotDrillMarks( BOARD *aBoard, PLOTTER* aPlotter, + const PCB_PLOT_PARAMS& aPlotOpts ) { - wxPoint pos; - wxSize diam; - MODULE* Module; - D_PAD* pad; - TRACK* pts; + EDA_DRAW_MODE_T trace_mode = aPlotOpts.GetMode(); - const PCB_PLOT_PARAMS& plot_opts = GetPlotSettings(); + /* If small drills marks were requested prepare a clamp value to pass + to the helper function */ + int small_drill = (aPlotOpts.GetDrillMarksType() == PCB_PLOT_PARAMS::SMALL_DRILL_SHAPE) ? + SMALL_DRILL : 0; - if( aTraceMode == FILLED ) + /* In the filled trace mode drill marks are drawn white-on-black to scrape + the underlying pad. This works only for drivers supporting color change, + obviously... it means that: + - PS and PDF output is correct (i.e. you have a 'donut' pad) + - In HPGL you can't see them + - In gerbers you can't see them, too. This is arguably the right thing to + do since having drill marks and high speed drill stations is a sure + recipe for broken tools and angry manufacturers. If you *really* want them + you could start a layer with negative polarity to scrape the film. + - In DXF they go into the 'WHITE' layer. This could be useful. + */ + if( trace_mode == FILLED ) { aPlotter->SetColor( WHITE ); } - for( pts = m_Pcb->m_Track; pts != NULL; pts = pts->Next() ) + for( TRACK *pts = aBoard->m_Track; pts != NULL; pts = pts->Next() ) { if( pts->Type() != PCB_VIA_T ) continue; - pos = pts->m_Start; - - // It is quite possible that the real drill value is less then small drill value. - if( plot_opts.GetDrillMarksType() == PCB_PLOT_PARAMS::SMALL_DRILL_SHAPE ) - diam.x = diam.y = MIN( SMALL_DRILL, pts->GetDrillValue() ); - else - diam.x = diam.y = pts->GetDrillValue(); - - diam.x -= aPlotter->GetPlotWidthAdj(); - diam.x = Clamp( 1, diam.x, pts->m_Width - 1 ); - aPlotter->FlashPadCircle( pos, diam.x, aTraceMode ); + PlotDrillMark( aPlotter, PAD_CIRCLE, + pts->m_Start, wxSize( pts->GetDrillValue(), 0 ), + wxSize( pts->m_Width, 0 ), 0, small_drill, + trace_mode ); } - for( Module = m_Pcb->m_Modules; Module != NULL; Module = Module->Next() ) + for( MODULE *Module = aBoard->m_Modules; Module != NULL; Module = Module->Next() ) { - for( pad = Module->m_Pads; pad != NULL; pad = pad->Next() ) + for( D_PAD *pad = Module->m_Pads; pad != NULL; pad = pad->Next() ) { if( pad->GetDrillSize().x == 0 ) continue; - // Output hole shapes: - pos = pad->GetPosition(); - - if( pad->GetDrillShape() == PAD_OVAL ) - { - diam = pad->GetDrillSize(); - diam.x -= aPlotter->GetPlotWidthAdj(); - diam.x = Clamp( 1, diam.x, pad->GetSize().x - 1 ); - diam.y -= aPlotter->GetPlotWidthAdj(); - diam.y = Clamp( 1, diam.y, pad->GetSize().y - 1 ); - aPlotter->FlashPadOval( pos, diam, pad->GetOrientation(), aTraceMode ); - } - else - { - // It is quite possible that the real pad drill value is less then small drill value. - diam.x = aSmallDrillShape ? MIN( SMALL_DRILL, pad->GetDrillSize().x ) : pad->GetDrillSize().x; - diam.x -= aPlotter->GetPlotWidthAdj(); - diam.x = Clamp( 1, diam.x, pad->GetSize().x - 1 ); - aPlotter->FlashPadCircle( pos, diam.x, aTraceMode ); - } + PlotDrillMark( aPlotter, pad->GetDrillShape(), + pad->GetPosition(), pad->GetDrillSize(), + pad->GetSize(), pad->GetOrientation(), + small_drill, trace_mode ); } } - if( aTraceMode == FILLED ) + if( trace_mode == FILLED ) { - aPlotter->SetColor( BLACK ); + aPlotter->SetColor( aPlotOpts.GetColor() ); } } + +/** Set up most plot options for plotting a board (especially the viewport) + * Important thing: + * page size is the 'drawing' page size, + * paper size is the physical page size + */ +static void PlotSetupPlotter( PLOTTER *aPlotter, PCB_PLOT_PARAMS *aPlotOpts, + const PAGE_INFO &aPageInfo, + const EDA_RECT &aBbbox, + const wxPoint &aOrigin, + const wxString &aFilename ) +{ + PAGE_INFO pageA4( wxT( "A4" ) ); + const PAGE_INFO* sheet_info; + double paperscale; // Page-to-paper ratio + wxSize paperSizeIU; + wxSize pageSizeIU( aPageInfo.GetSizeIU() ); + bool autocenter = false; + + /* Special options: to fit the sheet to an A4 sheet replace + the paper size. However there is a difference between + the autoscale and the a4paper option: + - Autoscale fits the board to the paper size + - A4paper fits the original paper size to an A4 sheet + - Both of them fit the board to an A4 sheet + */ + if( aPlotOpts->GetA4Output() ) // Fit paper to A4 + { + sheet_info = &pageA4; + paperSizeIU = pageA4.GetSizeIU(); + paperscale = (double) paperSizeIU.x / pageSizeIU.x; + autocenter = true; + } + else + { + sheet_info = &aPageInfo; + paperSizeIU = pageSizeIU; + paperscale = 1; + + // Need autocentering only if scale is not 1:1 + autocenter = (aPlotOpts->GetScale() != 1.0); + } + + wxPoint boardCenter = aBbbox.Centre(); + + double compound_scale; + wxSize boardSize = aBbbox.GetSize(); + + /* Fit to 80% of the page if asked; it could be that the board is empty, + * in this case regress to 1:1 scale */ + if( aPlotOpts->GetAutoScale() && boardSize.x > 0 && boardSize.y > 0 ) + { + double xscale = (paperSizeIU.x * 0.8) / boardSize.x; + double yscale = (paperSizeIU.y * 0.8) / boardSize.y; + + compound_scale = std::min( xscale, yscale ) * paperscale; + } + else + compound_scale = aPlotOpts->GetScale() * paperscale; + + + /* For the plot offset we have to keep in mind the auxiliary origin + too: if autoscaling is off we check that plot option (i.e. autoscaling + overrides auxiliary origin) */ + wxPoint offset( 0, 0); + + if( autocenter ) + { + offset.x = KiROUND( boardCenter.x - ( paperSizeIU.x / 2.0 ) / compound_scale ); + offset.y = KiROUND( boardCenter.y - ( paperSizeIU.y / 2.0 ) / compound_scale ); + } + else + { + if( aPlotOpts->GetUseAuxOrigin() ) + offset = aOrigin; + } + + /* Configure the plotter object with all the stuff computed and + most of that taken from the options */ + aPlotter->SetPageSettings( *sheet_info ); + aPlotter->SetPlotWidthAdj( aPlotOpts->GetWidthAdjust() ); + aPlotter->SetViewport( offset, IU_PER_DECIMILS, compound_scale, + aPlotOpts->GetMirror() ); + aPlotter->SetDefaultLineWidth( aPlotOpts->GetLineWidth() ); + aPlotter->SetCreator( wxT( "PCBNEW" ) ); + aPlotter->SetColorMode( true ); + aPlotter->SetFilename( aFilename ); + aPlotter->SetTextMode( aPlotOpts->GetTextMode() ); +} + +/** Prefill in black an area a little bigger than the board to prepare for the + * negative plot */ +static void FillNegativeKnockout(PLOTTER *aPlotter, const EDA_RECT &aBbbox ) +{ + static const int margin = 500; // Add a 0.5 inch margin around the board + aPlotter->SetNegative( true ); + aPlotter->SetColor( WHITE ); // Which will be plotted as black + aPlotter->Rect( wxPoint( aBbbox.GetX() - margin, aBbbox.GetY() - margin ), + wxPoint( aBbbox.GetRight() + margin, aBbbox.GetBottom() + margin ), + FILLED_SHAPE ); + aPlotter->SetColor( BLACK ); +} + +/** Calculate the effective size of HPGL pens and set them in the + * plotter object */ +static void ConfigureHPGLPenSizes( HPGL_PLOTTER *aPlotter, + PCB_PLOT_PARAMS *aPlotOpts ) +{ + /* Compute pen_dim (the value is given in mils) in pcb units, + with plot scale (if Scale is 2, pen diameter value is always m_HPGLPenDiam + so apparent pen diam is real pen diam / Scale */ + int pen_diam = KiROUND( aPlotOpts->GetHPGLPenDiameter() * IU_PER_MILS / + aPlotOpts->GetScale() ); + + // compute pen_overlay (value comes in mils) in pcb units with plot scale + if( aPlotOpts->GetHPGLPenOverlay() < 0 ) + aPlotOpts->SetHPGLPenOverlay( 0 ); + + if( aPlotOpts->GetHPGLPenOverlay() >= aPlotOpts->GetHPGLPenDiameter() ) + aPlotOpts->SetHPGLPenOverlay( aPlotOpts->GetHPGLPenDiameter() - 1 ); + + int pen_overlay = KiROUND( aPlotOpts->GetHPGLPenOverlay() * IU_PER_MILS / + aPlotOpts->GetScale() ); + + // Set HPGL-specific options and start + aPlotter->SetPenSpeed( aPlotOpts->GetHPGLPenSpeed() ); + aPlotter->SetPenNumber( aPlotOpts->GetHPGLPenNum() ); + aPlotter->SetPenOverlap( pen_overlay ); + aPlotter->SetPenDiameter( pen_diam ); +} + +/** Open a new plotfile using the options (and especially the format) + * specified in the options and prepare the page for plotting. + * Return the plotter object if OK, NULL if the file is not created + * (or has a problem) + */ +PLOTTER *StartPlotBoard( BOARD *aBoard, + PCB_PLOT_PARAMS *aPlotOpts, + const wxString& aFullFileName, + const wxString& aSheetDesc ) +{ + const PAGE_INFO& pageInfo = aBoard->GetPageSettings(); + EDA_RECT bbbox = aBoard->ComputeBoundingBox(); + wxPoint auxOrigin( aBoard->GetOriginAxisPosition() ); + FILE* output_file = wxFopen( aFullFileName, wxT( "wt" ) ); + + if( output_file == NULL ) + return NULL; + + // Create the plotter driver and set the few plotter specific + // options + PLOTTER *the_plotter = NULL; + switch( aPlotOpts->GetFormat() ) + { + case PLOT_FORMAT_DXF: + the_plotter = new DXF_PLOTTER(); + break; + + case PLOT_FORMAT_POST: + PS_PLOTTER* PS_plotter; + PS_plotter = new PS_PLOTTER(); + PS_plotter->SetScaleAdjust( aPlotOpts->GetFineScaleAdjustX(), + aPlotOpts->GetFineScaleAdjustY() ); + the_plotter = PS_plotter; + break; + + case PLOT_FORMAT_PDF: + the_plotter = new PDF_PLOTTER(); + break; + + case PLOT_FORMAT_HPGL: + HPGL_PLOTTER* HPGL_plotter; + HPGL_plotter = new HPGL_PLOTTER(); + + /* HPGL options are a little more convoluted to compute, so + they're split in an other function */ + ConfigureHPGLPenSizes( HPGL_plotter, aPlotOpts ); + the_plotter = HPGL_plotter; + break; + + case PLOT_FORMAT_GERBER: + the_plotter = new GERBER_PLOTTER(); + break; + + default: + wxASSERT( false ); + } + + if( the_plotter ) + { + // Compute the viewport and set the other options + PlotSetupPlotter( the_plotter, aPlotOpts, pageInfo, bbbox, auxOrigin, + aFullFileName ); + + if( the_plotter->StartPlot( output_file ) ) + { + /* When plotting a negative board: draw a black rectangle + * (background for plot board in white) and switch the current + * color to WHITE; note the the color inversion is actually done + * in the driver (if supported) */ + if( aPlotOpts->GetNegative() ) + FillNegativeKnockout( the_plotter, bbbox ); + + // Plot the frame reference if requested + if( aPlotOpts->GetPlotFrameRef() ) + PlotWorkSheet( the_plotter, aBoard->GetTitleBlock(), + aBoard->GetPageSettings(), + 1, 1, // Only one page + aSheetDesc, + aBoard->GetFileName() ); + + return the_plotter; + } + } + + // error in start_plot( ) or before + DisplayError( NULL, _("Error creating plot file")); + + if( the_plotter ) + delete the_plotter; + return NULL; +} diff --git a/pcbnew/plotcontroller.h b/pcbnew/plotcontroller.h new file mode 100644 index 0000000000..b4afbc77b4 --- /dev/null +++ b/pcbnew/plotcontroller.h @@ -0,0 +1,43 @@ +/** + * @file pcbnew/pcbplot.h + */ + +#ifndef PLOTCONTROLLER_H_ +#define PLOTCONTROLLER_H_ + +#include +#include + +class PLOTTER; +class BOARD; + +/** + * Batch plotter state object. Keeps the plot options and handles multiple + * plot requests + */ +class PLOT_CONTROLLER +{ +public: + PLOT_CONTROLLER( BOARD *aBoard ); + ~PLOT_CONTROLLER(); + PCB_PLOT_PARAMS *AccessPlotOpts() { return &m_plotOpts; } + bool IsPlotOpen() const { return m_plotter != NULL; } + void ClosePlot(); + bool OpenPlotfile( const wxString &aSuffix, PlotFormat aFormat, + const wxString &aSheetDesc ); + bool PlotLayer( int layer ); + +private: + /// Option bank + PCB_PLOT_PARAMS m_plotOpts; + + /// This is the plotter object; it starts NULL and become instantiated + // when a plotfile is requested + PLOTTER *m_plotter; + + /// The board we're plotting + BOARD* m_board; +}; + +#endif + diff --git a/pcbnew/plotdxf.cpp b/pcbnew/plotdxf.cpp deleted file mode 100644 index 867bc18b6a..0000000000 --- a/pcbnew/plotdxf.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/** - * @file plotdxf.cpp - * @brief Plot DXF. - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - - -bool PCB_BASE_FRAME::ExportToDxfFile( const wxString& aFullFileName, int aLayer, - EDA_DRAW_MODE_T aTraceMode ) -{ - LOCALE_IO toggle; - - const PCB_PLOT_PARAMS& plot_opts = GetPlotSettings(); - - FILE* output_file = wxFopen( aFullFileName, wxT( "wt" ) ); - - if( output_file == NULL ) - { - return false; - } - - DXF_PLOTTER* plotter = new DXF_PLOTTER(); - plotter->SetPageSettings( GetPageSettings() ); - plotter->SetViewport( wxPoint( 0, 0 ), IU_PER_DECIMILS, 1, 0 ); - plotter->SetCreator( wxT( "PCBNEW-DXF" ) ); - plotter->SetFilename( aFullFileName ); - plotter->StartPlot( output_file ); - - if( plot_opts.GetPlotFrameRef() ) - PlotWorkSheet( plotter, GetScreen(), plot_opts.GetLineWidth() ); - - Plot_Layer( plotter, aLayer, aTraceMode ); - plotter->EndPlot(); - delete plotter; - return true; -} diff --git a/pcbnew/plotgerb.cpp b/pcbnew/plotgerb.cpp deleted file mode 100644 index ed8d21de92..0000000000 --- a/pcbnew/plotgerb.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/** - * @file plotgerb.cpp - * @brief Functions to plot a board in GERBER RS274X format. - */ - -/* Creates the output files, one per board layer: - * filenames are like xxxc.PHO and use the RS274X format - * Units = inches - * format 3.4, Leading zero omitted, Abs format - * format 3.4 uses the native Pcbnew units (1/10000 inch). - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - - -bool PCB_BASE_FRAME::ExportToGerberFile( const wxString& aFullFileName, int aLayer, - bool aPlotOriginIsAuxAxis, EDA_DRAW_MODE_T aTraceMode ) -{ - FILE* output_file = wxFopen( aFullFileName, wxT( "wt" ) ); - if( output_file == NULL ) - { - return false; - } - - PCB_PLOT_PARAMS plot_opts = GetPlotSettings(); - - wxPoint offset; - - // Calculate scaling from Pcbnew units (in 0.1 mil or 0.0001 inch) to gerber units - double scale = plot_opts.GetScale(); - - if( aPlotOriginIsAuxAxis ) - { - offset = GetOriginAxisPosition(); - } - else - { - offset.x = 0; - offset.y = 0; - } - - LOCALE_IO toggle; - - PLOTTER* plotter = new GERBER_PLOTTER(); - - // No mirror and scaling for gerbers! - plotter->SetViewport( offset, IU_PER_DECIMILS, scale, 0 ); - plotter->SetDefaultLineWidth( plot_opts.GetLineWidth() ); - plotter->SetCreator( wxT( "PCBNEW-RS274X" ) ); - plotter->SetFilename( aFullFileName ); - - if( plotter->StartPlot( output_file ) ) - { - SetPlotSettings( plot_opts ); - - // Sheet refs on gerber CAN be useful... and they're always 1:1 - if( plot_opts.GetPlotFrameRef() ) - PlotWorkSheet( plotter, GetScreen(), plot_opts.GetLineWidth() ); - - Plot_Layer( plotter, aLayer, aTraceMode ); - - plotter->EndPlot(); - - SetPlotSettings( plot_opts ); - } - else // error in start_plot( ): failed opening a temporary file - { - wxMessageBox( _("Error when creating %s file: unable to create a temporary file")); - } - - delete plotter; - - return true; -} diff --git a/pcbnew/plothpgl.cpp b/pcbnew/plothpgl.cpp deleted file mode 100644 index 4a10cfd38c..0000000000 --- a/pcbnew/plothpgl.cpp +++ /dev/null @@ -1,144 +0,0 @@ -/** - * @file plothpgl.cpp - */ - -/* - * This program source code file is part of KiCad, a free EDA CAD application. - * - * Copyright (C) 2012 KiCad Developers, see change_log.txt for contributors. - * Copyright (C) 2012 Dick Hollenbeck, dick@softplc.com - * - * 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 - - -bool PCB_BASE_FRAME::ExportToHpglFile( const wxString& aFullFileName, int aLayer, - EDA_DRAW_MODE_T aTraceMode ) -{ - wxSize boardSize; - wxPoint boardCenter; - bool center = false; - double scale; - wxPoint offset; - LOCALE_IO toggle; - FILE* output_file = wxFopen( aFullFileName, wxT( "wt" ) ); - - if( output_file == NULL ) - { - return false; - } - - PCB_PLOT_PARAMS plot_opts = GetPlotSettings(); - - // Compute pen_dim (from m_HPGLPenDiam in mils) in pcb units, - // with plot scale (if Scale is 2, pen diameter value is always m_HPGLPenDiam - // so apparent pen diam is real pen diam / Scale - int pen_diam = KiROUND( plot_opts.GetHPGLPenDiameter() * IU_PER_MILS / - plot_opts.GetScale() ); - - // compute pen_overlay (from m_HPGLPenOvr in mils) in pcb units - // with plot scale - if( plot_opts.GetHPGLPenOverlay() < 1 ) - plot_opts.SetHPGLPenOverlay( 0 ); - - if( plot_opts.GetHPGLPenOverlay() >= plot_opts.GetHPGLPenDiameter() ) - plot_opts.SetHPGLPenOverlay( plot_opts.GetHPGLPenDiameter() - 1 ); - - int pen_overlay = KiROUND( plot_opts.GetHPGLPenOverlay() * IU_PER_MILS / - plot_opts.GetScale() ); - - - if( plot_opts.GetScale() != 1.0 || plot_opts.GetAutoScale() ) - { - // when scale != 1.0 we must calculate the position in page - // because actual position has no meaning - center = true; - } - - wxSize pageSizeIU = GetPageSizeIU(); - - // Calculate the center of the PCB - EDA_RECT bbbox = GetBoardBoundingBox(); - - boardSize = bbbox.GetSize(); - boardCenter = bbbox.Centre(); - - if( plot_opts.GetAutoScale() ) // Optimum scale - { - // Fit to 80% of the page - double Xscale = ( ( pageSizeIU.x * 0.8 ) / boardSize.x ); - double Yscale = ( ( pageSizeIU.y * 0.8 ) / boardSize.y ); - scale = std::min( Xscale, Yscale ); - } - else - { - scale = plot_opts.GetScale(); - } - - // Calculate the page size offset. - if( center ) - { - offset.x = KiROUND( (double) boardCenter.x - - ( (double) pageSizeIU.x / 2.0 ) / scale ); - offset.y = KiROUND( (double) boardCenter.y - - ( (double) pageSizeIU.y / 2.0 ) / scale ); - } - else - { - offset.x = 0; - offset.y = 0; - } - - HPGL_PLOTTER* plotter = new HPGL_PLOTTER(); - - plotter->SetPageSettings( GetPageSettings() ); - - // why did we have to change these settings above? - SetPlotSettings( plot_opts ); - - plotter->SetViewport( offset, IU_PER_DECIMILS, scale, - plot_opts.GetMirror() ); - plotter->SetDefaultLineWidth( plot_opts.GetLineWidth() ); - plotter->SetCreator( wxT( "PCBNEW-HPGL" ) ); - plotter->SetFilename( aFullFileName ); - plotter->SetPenSpeed( plot_opts.GetHPGLPenSpeed() ); - plotter->SetPenNumber( plot_opts.GetHPGLPenNum() ); - plotter->SetPenOverlap( pen_overlay ); - plotter->SetPenDiameter( pen_diam ); - plotter->StartPlot( output_file ); - - // The worksheet is not significant with scale!=1... It is with paperscale!=1, anyway - if( plot_opts.GetPlotFrameRef() && !center ) - PlotWorkSheet( plotter, GetScreen(), plot_opts.GetLineWidth() ); - - Plot_Layer( plotter, aLayer, aTraceMode ); - plotter->EndPlot(); - delete plotter; - - return true; -} diff --git a/pcbnew/plotps.cpp b/pcbnew/plotps.cpp deleted file mode 100644 index 10ee29d6c2..0000000000 --- a/pcbnew/plotps.cpp +++ /dev/null @@ -1,146 +0,0 @@ -/** - * @file plotps.cpp - * @brief Plot Postscript. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - - -/* Generate a PostScript file (*. ps) of the circuit layer. - * If layer < 0: all layers are plotted. - */ -bool PCB_BASE_FRAME::ExportToPostScriptFile( const wxString& aFullFileName, int aLayer, - bool aUseA4, EDA_DRAW_MODE_T aTraceMode ) -{ - const PAGE_INFO& pageInfo = GetPageSettings(); - PCB_PLOT_PARAMS plotOpts = GetPlotSettings(); - - wxSize paperSizeIU; - wxSize boardSize; - wxPoint boardCenter; - bool center = false; - double scale; - double paperscale; - wxPoint offset; - LOCALE_IO toggle; - PAGE_INFO pageA4( wxT( "A4" ) ); - - const PAGE_INFO* sheetPS; - - FILE* output_file = wxFopen( aFullFileName, wxT( "wt" ) ); - - if( output_file == NULL ) - { - return false; - } - - if( plotOpts.GetScale() != 1.0 || plotOpts.GetAutoScale() ) - { - // when scale != 1.0 we must calculate the position in page - // because actual position has no meaning - center = true; - } - - // Set default line width - if( plotOpts.GetLineWidth() < 1 ) - plotOpts.SetLineWidth( 1 ); - - wxSize pageSizeIU = GetPageSizeIU(); - - if( aUseA4 ) - { - sheetPS = &pageA4; - paperSizeIU = pageA4.GetSizeIU(); - paperscale = (double) paperSizeIU.x / pageSizeIU.x; - } - else - { - sheetPS = &pageInfo; - paperSizeIU = pageSizeIU; - paperscale = 1; - } - - EDA_RECT bbbox = GetBoardBoundingBox(); - - boardSize = bbbox.GetSize(); - boardCenter = bbbox.Centre(); - - if( plotOpts.GetAutoScale() ) // Optimum scale - { - // Fit to 80% of the page - double Xscale = (paperSizeIU.x * 0.8) / boardSize.x; - double Yscale = (paperSizeIU.y * 0.8) / boardSize.y; - - scale = MIN( Xscale, Yscale ); - } - else - { - scale = plotOpts.GetScale() * paperscale; - } - - if( center ) - { - offset.x = KiROUND( (double) boardCenter.x - ( (double) paperSizeIU.x / 2.0 ) / scale ); - offset.y = KiROUND( (double) boardCenter.y - ( (double) paperSizeIU.y / 2.0 ) / scale ); - } - else - { - offset.x = 0; - offset.y = 0; - } - - PS_PLOTTER* plotter = new PS_PLOTTER(); - - plotter->SetPageSettings( *sheetPS ); - - // why did we have to change these settings? - SetPlotSettings( plotOpts ); - - plotter->SetScaleAdjust( plotOpts.GetFineScaleAdjustX(), - plotOpts.GetFineScaleAdjustY() ); - plotter->SetPlotWidthAdj( plotOpts.GetWidthAdjust() ); - plotter->SetViewport( offset, IU_PER_DECIMILS, scale, - plotOpts.GetMirror() ); - plotter->SetDefaultLineWidth( plotOpts.GetLineWidth() ); - plotter->SetCreator( wxT( "PCBNEW-PS" ) ); - plotter->SetFilename( aFullFileName ); - plotter->StartPlot( output_file ); - - /* The worksheet is not significant with scale!=1... It is with paperscale!=1, anyway */ - if( plotOpts.GetPlotFrameRef() && !center ) - PlotWorkSheet( plotter, GetScreen(), plotOpts.GetLineWidth() ); - - // If plot a negative board: - // Draw a black rectangle (background for plot board in white) - // and switch the current color to WHITE - if( plotOpts.GetNegative() ) - { - int margin = 500; // Add a 0.5 inch margin around the board - plotter->SetNegative( true ); - plotter->SetColor( WHITE ); // Which will be plotted as black - plotter->Rect( wxPoint( bbbox.GetX() - margin, - bbbox.GetY() - margin ), - wxPoint( bbbox.GetRight() + margin, - bbbox.GetBottom() + margin ), - FILLED_SHAPE ); - plotter->SetColor( BLACK ); - } - - Plot_Layer( plotter, aLayer, aTraceMode ); - plotter->EndPlot(); - delete plotter; - - return true; -} diff --git a/pcbnew/printout_controler.cpp b/pcbnew/printout_controler.cpp index 8c753bca74..7ae272445d 100644 --- a/pcbnew/printout_controler.cpp +++ b/pcbnew/printout_controler.cpp @@ -285,7 +285,7 @@ void BOARD_PRINTOUT_CONTROLER::DrawPage() if( m_PrintParams.m_Print_Sheet_Ref ) m_Parent->TraceWorkSheet( dc, screen, m_PrintParams.m_PenDefaultSize, - IU_PER_MILS ); + IU_PER_MILS, m_Parent->GetScreenDesc() ); if( printMirror ) { diff --git a/pcbnew/scripting/pcbnew.i b/pcbnew/scripting/pcbnew.i index efcb39d746..9484ab890f 100644 --- a/pcbnew/scripting/pcbnew.i +++ b/pcbnew/scripting/pcbnew.i @@ -95,7 +95,10 @@ #include #include #include - + + #include + #include + #include BOARD *GetBoard(); /* get current editor board */ %} @@ -127,6 +130,11 @@ %include %include +%include +%include +%include +%include + %include "board_item.i" %include diff --git a/pcbnew/specctra_export.cpp b/pcbnew/specctra_export.cpp index c79e1c0ebf..64f1cd9633 100644 --- a/pcbnew/specctra_export.cpp +++ b/pcbnew/specctra_export.cpp @@ -72,7 +72,7 @@ static const double safetyMargin = 0.1; // see wxPcbStruct.h void PCB_EDIT_FRAME::ExportToSpecctra( wxCommandEvent& event ) { - wxString fullFileName = GetScreen()->GetFileName(); + wxString fullFileName = GetBoard()->GetFileName(); wxString path; wxString name; wxString ext; diff --git a/pcbnew/specctra_import.cpp b/pcbnew/specctra_import.cpp index 92f4555bc9..771a76c6f7 100644 --- a/pcbnew/specctra_import.cpp +++ b/pcbnew/specctra_import.cpp @@ -69,7 +69,7 @@ void PCB_EDIT_FRAME::ImportSpecctraSession( wxCommandEvent& event ) } */ - wxString fullFileName = GetScreen()->GetFileName(); + wxString fullFileName = GetBoard()->GetFileName(); wxString path; wxString name; wxString ext; diff --git a/pcbnew/tracepcb.cpp b/pcbnew/tracepcb.cpp index ec9e1a1c1d..76f4bca84c 100644 --- a/pcbnew/tracepcb.cpp +++ b/pcbnew/tracepcb.cpp @@ -68,7 +68,7 @@ void FOOTPRINT_EDIT_FRAME::RedrawActiveWindow( wxDC* DC, bool EraseBg ) GRSetDrawMode( DC, GR_COPY ); m_canvas->DrawBackGround( DC ); - TraceWorkSheet( DC, screen, 0, IU_PER_MILS ); + TraceWorkSheet( DC, screen, 0, IU_PER_MILS, wxEmptyString ); // Redraw the footprints for( MODULE* module = GetBoard()->m_Modules; module; module = module->Next() ) @@ -106,7 +106,8 @@ void PCB_EDIT_FRAME::RedrawActiveWindow( wxDC* DC, bool EraseBg ) m_canvas->DrawBackGround( DC ); - TraceWorkSheet( DC, GetScreen(), g_DrawDefaultLineThickness, IU_PER_MILS ); + TraceWorkSheet( DC, GetScreen(), g_DrawDefaultLineThickness, + IU_PER_MILS, wxEmptyString ); GetBoard()->Draw( m_canvas, DC, GR_OR | GR_ALLOW_HIGHCONTRAST); diff --git a/pcbnew/xchgmod.cpp b/pcbnew/xchgmod.cpp index 3dd711c60f..738d404cc3 100644 --- a/pcbnew/xchgmod.cpp +++ b/pcbnew/xchgmod.cpp @@ -183,7 +183,7 @@ int DIALOG_EXCHANGE_MODULE::Maj_ListeCmp( const wxString& reference, return 0; /* Build CMP file name by changing the extension of NetList filename */ - fn = m_Parent->GetScreen()->GetFileName(); + fn = m_Parent->GetBoard()->GetFileName(); fn.SetExt( ComponentFileExtension ); FichCmp = wxFopen( fn.GetFullPath(), wxT( "rt" ) ); @@ -621,7 +621,7 @@ void PCB_EDIT_FRAME::RecreateCmpFileFromBoard( wxCommandEvent& aEvent ) } /* Calculation file name by changing the extension name to NetList */ - fn = GetScreen()->GetFileName(); + fn = GetBoard()->GetFileName(); fn.SetExt( ComponentFileExtension ); wildcard = wxGetTranslation( ComponentFileWildcard );