diff --git a/common/board_printout.cpp b/common/board_printout.cpp index dc2d034ab4..ed1bacc19a 100644 --- a/common/board_printout.cpp +++ b/common/board_printout.cpp @@ -104,12 +104,7 @@ void BOARD_PRINTOUT::DrawPage( const wxString& aLayerName, int aPageNum, int aPa view->SetScaleLimits( 10e9, 0.0001 ); view->SetScale( 1.0 ); - for( int i = 0; i < KIGFX::VIEW::VIEW_MAX_LAYERS; i++ ) - { - view->SetLayerTarget( i, KIGFX::TARGET_NONCACHED ); - view->SetLayerVisible( i, true ); - } - + setupViewLayers( view, m_PrintParams.m_PrintMaskLayer ); BOX2I bBox; // determine printout bounding box @@ -155,3 +150,15 @@ void BOARD_PRINTOUT::DrawPage( const wxString& aLayerName, int aPageNum, int aPa view->Redraw(); } } + + +void BOARD_PRINTOUT::setupViewLayers( const std::unique_ptr& aView, + const LSET& aLayerSet ) +{ + // Disable all layers by default, let specific implementions enable required layers + for( int i = 0; i < KIGFX::VIEW::VIEW_MAX_LAYERS; ++i ) + { + aView->SetLayerVisible( i, false ); + aView->SetLayerTarget( i, KIGFX::TARGET_NONCACHED ); + } +} diff --git a/common/view/view.cpp b/common/view/view.cpp index f7d26e3ad5..3e8f5a001d 100644 --- a/common/view/view.cpp +++ b/common/view/view.cpp @@ -507,10 +507,12 @@ void VIEW::CopySettings( const VIEW* aOtherView ) void VIEW::SetGAL( GAL* aGal ) { + bool recacheGroups = ( m_gal != nullptr ); // recache groups only if GAL is reassigned m_gal = aGal; // clear group numbers, so everything is going to be recached - clearGroupCache(); + if( recacheGroups ) + clearGroupCache(); // every target has to be refreshed MarkDirty(); diff --git a/gerbview/dialogs/dialog_print_using_printer.cpp b/gerbview/dialogs/dialog_print_using_printer.cpp index 2a7198e2ba..a3e24df500 100644 --- a/gerbview/dialogs/dialog_print_using_printer.cpp +++ b/gerbview/dialogs/dialog_print_using_printer.cpp @@ -102,9 +102,6 @@ public: bool IsMirrored() { return m_Print_Mirror->IsChecked(); } bool PrintUsingSinglePage() { return true; } int SetLayerSetFromListSelection(); - // Prepare print parameters. return true if OK, - // false if there is an issue (mainly no printable layers) - bool PreparePrintPrms(); }; @@ -239,17 +236,19 @@ void DIALOG_PRINT_USING_PRINTER::InitValues( ) int DIALOG_PRINT_USING_PRINTER::SetLayerSetFromListSelection() { - std::vector layerList; + s_Parameters.m_PrintMaskLayer = LSET(); + s_Parameters.m_PageCount = 0; + s_Parameters.m_Flags = 0; - for( int ii = 0; ii < GERBER_DRAWLAYERS_COUNT; ++ii ) + for( unsigned layer = 0; layer < DIM( m_BoxSelectLayer ); ++layer ) { - if( m_BoxSelectLayer[ii]->IsChecked() && m_BoxSelectLayer[ii]->IsEnabled() ) - layerList.push_back( ii ); + if( m_BoxSelectLayer[layer]->IsChecked() && m_BoxSelectLayer[layer]->IsEnabled() ) + { + ++s_Parameters.m_PageCount; + s_Parameters.m_PrintMaskLayer.set( layer ); + } } - m_Parent->GetGerberLayout()->SetPrintableLayers( layerList ); - s_Parameters.m_PageCount = layerList.size(); - return s_Parameters.m_PageCount; } @@ -281,8 +280,7 @@ void DIALOG_PRINT_USING_PRINTER::OnCloseWindow( wxCloseEvent& event ) void DIALOG_PRINT_USING_PRINTER::SetPrintParameters() { s_Parameters.m_PrintMirror = m_Print_Mirror->GetValue(); - s_Parameters.m_Print_Black_and_White = - m_ModeColorOption->GetSelection() != 0; + s_Parameters.m_Print_Black_and_White = m_ModeColorOption->GetSelection() != 0; // Due to negative objects in gerber objects, always use one page per image, // because these objects create artefact when they are printed on an existing image. @@ -326,18 +324,20 @@ void DIALOG_PRINT_USING_PRINTER::SetPrintParameters() } } + void DIALOG_PRINT_USING_PRINTER::OnScaleSelectionClick( wxCommandEvent& event ) { double scale = s_ScaleList[m_ScaleOption->GetSelection()]; - bool enable = (scale == 1.0); + bool enable = ( scale == 1.0 ); if( m_FineAdjustXscaleOpt ) - m_FineAdjustXscaleOpt->Enable(enable); + m_FineAdjustXscaleOpt->Enable( enable ); if( m_FineAdjustYscaleOpt ) - m_FineAdjustYscaleOpt->Enable(enable); + m_FineAdjustYscaleOpt->Enable( enable ); } + // Open a dialog box for printer setup (printer options, page size ...) void DIALOG_PRINT_USING_PRINTER::OnPageSetup( wxCommandEvent& event ) { @@ -350,26 +350,20 @@ void DIALOG_PRINT_USING_PRINTER::OnPageSetup( wxCommandEvent& event ) (*s_pageSetupData) = pageSetupDialog.GetPageSetupDialogData(); } -bool DIALOG_PRINT_USING_PRINTER::PreparePrintPrms() + + +// Open and display a previewer frame for printing +void DIALOG_PRINT_USING_PRINTER::OnPrintPreview( wxCommandEvent& event ) { SetPrintParameters(); // If no layer selected, we have no plot. prompt user if it happens // because he could think there is a bug in Pcbnew: - if( m_Parent->GetGerberLayout()->GetPrintableLayers().size() == 0 ) + if( s_Parameters.m_PrintMaskLayer == 0 ) { DisplayError( this, _( "No layer selected" ) ); - return false; - } - - return true; -} - -// Open and display a previewer frame for printing -void DIALOG_PRINT_USING_PRINTER::OnPrintPreview( wxCommandEvent& event ) -{ - if( !PreparePrintPrms() ) return; + } // Pass two printout objects: for preview, and possible printing. wxString title = _( "Print Preview" ); @@ -400,11 +394,17 @@ void DIALOG_PRINT_USING_PRINTER::OnPrintPreview( wxCommandEvent& event ) void DIALOG_PRINT_USING_PRINTER::OnPrintButtonClick( wxCommandEvent& event ) { - if( !PreparePrintPrms() ) + SetPrintParameters(); + + // If no layer selected, we have no plot. prompt user if it happens + // because he could think there is a bug in Pcbnew: + if( s_Parameters.m_PrintMaskLayer == 0 ) + { + DisplayError( this, _( "No layer selected" ) ); return; + } wxPrintDialogData printDialogData( *s_printData ); - wxPrinter printer( &printDialogData ); wxString title = _( "Print" ); auto printout = std::unique_ptr( createPrintout( _( "Print" ) ) ); @@ -423,4 +423,3 @@ void DIALOG_PRINT_USING_PRINTER::OnPrintButtonClick( wxCommandEvent& event ) *s_printData = printer.GetPrintDialogData().GetPrintData(); } } - diff --git a/gerbview/draw_gerber_screen.cpp b/gerbview/draw_gerber_screen.cpp index 44e30bcc35..2ad83d4575 100644 --- a/gerbview/draw_gerber_screen.cpp +++ b/gerbview/draw_gerber_screen.cpp @@ -42,51 +42,6 @@ #include "gerbview_printout.h" -void GERBVIEW_FRAME::PrintPage( wxDC* aDC, LSET aPrintMasklayer, - bool aPrintMirrorMode, void* aData ) -{ - wxCHECK_RET( aData != NULL, wxT( "aData cannot be NULL." ) ); - - PRINT_PARAMETERS* printParameters = (PRINT_PARAMETERS*) aData; - - // Build a suitable draw options for printing: - GBR_DISPLAY_OPTIONS displayOptions; - displayOptions.m_DisplayFlashedItemsFill = true; - displayOptions.m_DisplayLinesFill = true; - displayOptions.m_DisplayPolygonsFill = true; - displayOptions.m_DisplayDCodes = false; - displayOptions.m_IsPrinting = true; - displayOptions.m_ForceBlackAndWhite = printParameters->m_Print_Black_and_White; - displayOptions.m_NegativeDrawColor = GetDrawBgColor(); - displayOptions.m_BgDrawColor = GetDrawBgColor(); - - // Find the graphic layer to be printed - int page_number = printParameters->m_Flags; // contains the page number (not necessarily graphic layer number) - - // Find the graphic layer number for the printed page (search through the mask and count bits) - std::vector printList = GetGerberLayout()->GetPrintableLayers(); - - if( printList.size() < 1 ) - return; - - int graphiclayer = printList[page_number-1]; - - // In Gerbview, only one graphic layer is printed by page. - // So we temporary set the graphic layer list to print with only one layer id - GetGerberLayout()->ClearPrintableLayers(); - GetGerberLayout()->AddLayerToPrintableList( graphiclayer ); - m_canvas->SetPrintMirrored( aPrintMirrorMode ); - - GetGerberLayout()->Draw( m_canvas, aDC, (GR_DRAWMODE) 0, - wxPoint( 0, 0 ), &displayOptions ); - - m_canvas->SetPrintMirrored( false ); - - // Restore the list of printable graphic layers list: - GetGerberLayout()->SetPrintableLayers( printList ); -} - - void GERBVIEW_FRAME::RedrawActiveWindow( wxDC* DC, bool EraseBg ) { GBR_SCREEN* screen = (GBR_SCREEN*) GetScreen(); diff --git a/gerbview/gbr_layout.cpp b/gerbview/gbr_layout.cpp index 5ae6ba1f0e..13bf416382 100644 --- a/gerbview/gbr_layout.cpp +++ b/gerbview/gbr_layout.cpp @@ -53,18 +53,6 @@ GERBER_FILE_IMAGE_LIST* GBR_LAYOUT::GetImagesList() const } -bool GBR_LAYOUT::IsLayerPrintable( int aLayer ) const -{ - for( unsigned ii = 0; ii < m_printLayersList.size(); ++ii ) - { - if( m_printLayersList[ii] == aLayer ) - return true; - } - - return false; -} - - EDA_RECT GBR_LAYOUT::ComputeBoundingBox() const { EDA_RECT bbox; @@ -204,12 +192,7 @@ void GBR_LAYOUT::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, GR_DRAWMODE aDrawMode, if( gerber == NULL ) // Graphic layer not yet used continue; - if( aDisplayOptions->m_IsPrinting ) - gerber->m_IsVisible = IsLayerPrintable( layer ); - else - gerber->m_IsVisible = gerbFrame->IsLayerVisible( layer ); - - if( !gerber->m_IsVisible ) + if( !gerbFrame->IsLayerVisible( layer ) ) continue; gerber->m_PositiveDrawColor = gerbFrame->GetLayerColor( GERBER_DRAW_LAYER( layer ) ); diff --git a/gerbview/gbr_layout.h b/gerbview/gbr_layout.h index 1c3312178a..5bfc8eaf45 100644 --- a/gerbview/gbr_layout.h +++ b/gerbview/gbr_layout.h @@ -24,7 +24,7 @@ /** * @file gbr_layout.h - * @brief Class CLASS_GBR_LAYOUT to handle info to draw/print loaded Gerber images + * @brief Class CLASS_GBR_LAYOUT to handle info to draw loaded Gerber images * and page frame reference */ @@ -56,7 +56,6 @@ private: mutable EDA_RECT m_BoundingBox; TITLE_BLOCK m_titles; wxPoint m_originAxisPosition; - std::vector m_printLayersList; // When printing: the list of graphic layers Id to print public: @@ -116,7 +115,7 @@ public: * @param aDC = the current device context * @param aDrawMode = GR_COPY, GR_OR ... (not always used) * @param aOffset = an draw offset value - * @param aDisplayOptions = a GBR_DISPLAY_OPTIONS for draw/print display opts + * @param aDisplayOptions = a GBR_DISPLAY_OPTIONS for draw display opts */ void Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, GR_DRAWMODE aDrawMode, const wxPoint& aOffset, @@ -134,54 +133,6 @@ public: void DrawItemsDCodeID( EDA_DRAW_PANEL* aPanel, wxDC* aDC, GR_DRAWMODE aDrawMode, COLOR4D aDrawColor ); - - /** - * Function SetPrintableLayers - * Set the list of printable graphic layers - * @param aLayerList = the new list (std::vector) of printable layer id - */ - void SetPrintableLayers( const std::vector& aLayerList ) - { - m_printLayersList = aLayerList; - } - - /** - * Function GetPrintableLayers - * @return the list of printable layers - */ - std::vector GetPrintableLayers() - { - return m_printLayersList; - } - - /** - * Function ClearPrintableLayers - * Clear the list of graphic layers to print - */ - void ClearPrintableLayers() - { - m_printLayersList.clear(); - } - - /** - * Function AddLayerToPrintableList - * Add a layer to the list of graphic layers to print - * @param aLayer = the id of the graphic layer. - */ - void AddLayerToPrintableList( int aLayer) - { - m_printLayersList.push_back( aLayer ); - } - - - /** - * Function IsLayerPrintable - * tests whether a given layer is visible - * @param aLayer = The layer to be tested - * @return bool - true if the layer is in print list. - */ - bool IsLayerPrintable( int aLayer ) const; - ///> @copydoc EDA_ITEM::Visit() SEARCH_RESULT Visit( INSPECTOR inspector, void* testData, const KICAD_T scanTypes[] ) override; diff --git a/gerbview/gerbview_frame.cpp b/gerbview/gerbview_frame.cpp index 48a931b81b..2902d0a177 100644 --- a/gerbview/gerbview_frame.cpp +++ b/gerbview/gerbview_frame.cpp @@ -840,10 +840,7 @@ void GERBVIEW_FRAME::SetVisibleLayers( long aLayerMask ) bool GERBVIEW_FRAME::IsLayerVisible( int aLayer ) const { - if( ! m_DisplayOptions.m_IsPrinting ) - return m_LayersManager->IsLayerVisible( aLayer ); - else - return GetGerberLayout()->IsLayerPrintable( aLayer ); + return m_LayersManager->IsLayerVisible( aLayer ); } diff --git a/gerbview/gerbview_frame.h b/gerbview/gerbview_frame.h index ff7a22b12b..b6463beb43 100644 --- a/gerbview/gerbview_frame.h +++ b/gerbview/gerbview_frame.h @@ -682,16 +682,6 @@ public: // currently: do nothing in GerbView. } - /** Virtual function PrintPage - * used to print a page - * @param aDC = wxDC given by the calling print function - * @param aPrintMasklayer = a 32 bits mask: bit n = 1 -> layer n is printed - * @param aPrintMirrorMode = not used here (Set when printing in mirror mode) - * @param aData = a pointer on an auxiliary data (not always used, NULL if not used) - */ - virtual void PrintPage( wxDC* aDC, LSET aPrintMasklayer, bool aPrintMirrorMode, - void* aData = NULL ) override; - ///> @copydoc EDA_DRAW_FRAME::UseGalCanvas virtual void UseGalCanvas( bool aEnable ) override; diff --git a/gerbview/gerbview_printout.cpp b/gerbview/gerbview_printout.cpp index a88f3b8ef9..7c25b49655 100644 --- a/gerbview/gerbview_printout.cpp +++ b/gerbview/gerbview_printout.cpp @@ -56,21 +56,24 @@ GERBVIEW_PRINTOUT::GERBVIEW_PRINTOUT( GBR_LAYOUT* aLayout, const PRINT_PARAMETER bool GERBVIEW_PRINTOUT::OnPrintPage( int aPage ) { - // in gerbview, draw layers are always printed on separate pages - // because handling negative objects when using only one page is tricky - m_PrintParams.m_Flags = aPage; + // Store the layerset, as it is going to be modified below and the original settings are needed + LSET lset = m_PrintParams.m_PrintMaskLayer; // The gerber filename of the page to print will be printed to the worksheet. // Find this filename: // Find the graphic layer number for the page to print - std::vector printList = m_layout->GetPrintableLayers(); + LSEQ seq = lset.UIOrder(); + wxCHECK( unsigned( aPage - 1 ) < seq.size(), false ); + auto layerId = seq[aPage - 1]; - if( printList.size() < 1 ) // Should not occur - return false; + // In gerbview, draw layers are always printed on separate pages + // because handling negative objects when using only one page is tricky + + // Enable only one layer to create a printout + m_PrintParams.m_PrintMaskLayer = LSET( layerId ); - int graphiclayer = printList[aPage-1]; GERBER_FILE_IMAGE_LIST& gbrImgList = GERBER_FILE_IMAGE_LIST::GetImagesList(); - GERBER_FILE_IMAGE* gbrImage = gbrImgList.GetGbrImage( graphiclayer ); + GERBER_FILE_IMAGE* gbrImage = gbrImgList.GetGbrImage( layerId ); wxString gbr_filename; if( gbrImage ) @@ -78,10 +81,23 @@ bool GERBVIEW_PRINTOUT::OnPrintPage( int aPage ) DrawPage( gbr_filename, aPage, m_PrintParams.m_PageCount ); + // Restore the original layer set, so the next page can be printed + m_PrintParams.m_PrintMaskLayer = lset; + return true; } +void GERBVIEW_PRINTOUT::setupViewLayers( const std::unique_ptr& aView, + const LSET& aLayerSet ) +{ + BOARD_PRINTOUT::setupViewLayers( aView, aLayerSet ); + + for( LSEQ layerSeq = m_PrintParams.m_PrintMaskLayer.Seq(); layerSeq; ++layerSeq ) + aView->SetLayerVisible( GERBVIEW_LAYER_ID_START + *layerSeq, true ); +} + + EDA_RECT GERBVIEW_PRINTOUT::getBoundingBox() { return m_layout->ComputeBoundingBox(); diff --git a/gerbview/gerbview_printout.h b/gerbview/gerbview_printout.h index f930542fe5..71270cc269 100644 --- a/gerbview/gerbview_printout.h +++ b/gerbview/gerbview_printout.h @@ -33,6 +33,8 @@ public: bool OnPrintPage( int aPage ) override; protected: + void setupViewLayers( const std::unique_ptr& aView, const LSET& aLayerSet ) override; + EDA_RECT getBoundingBox() override; std::unique_ptr getPainter( KIGFX::GAL* aGal ) override; diff --git a/include/board_printout.h b/include/board_printout.h index 5f20936375..c73e1f5abe 100644 --- a/include/board_printout.h +++ b/include/board_printout.h @@ -125,6 +125,9 @@ public: int aPageNum = 1, int aPageCount = 1 ); protected: + ///> Enables layers visibility for a printout + virtual void setupViewLayers( const std::unique_ptr& aView, const LSET& aLayerSet ); + ///> Returns bounding box of the printed objects (excluding worksheet frame) virtual EDA_RECT getBoundingBox() = 0; diff --git a/include/layers_id_colors_and_visibility.h b/include/layers_id_colors_and_visibility.h index 068b0608f9..00829a007e 100644 --- a/include/layers_id_colors_and_visibility.h +++ b/include/layers_id_colors_and_visibility.h @@ -75,7 +75,8 @@ enum PCB_LAYER_ID: int UNDEFINED_LAYER = -1, UNSELECTED_LAYER = -2, - F_Cu = 0, // 0 + PCBNEW_LAYER_ID_START = 0, + F_Cu = PCBNEW_LAYER_ID_START, In1_Cu, In2_Cu, In3_Cu, diff --git a/pcbnew/pcbnew_printout.cpp b/pcbnew/pcbnew_printout.cpp index f56023340e..dbfea3bfd4 100644 --- a/pcbnew/pcbnew_printout.cpp +++ b/pcbnew/pcbnew_printout.cpp @@ -29,6 +29,7 @@ #include #include +#include PCBNEW_PRINTOUT::PCBNEW_PRINTOUT( BOARD* aBoard, const PRINT_PARAMETERS& aParams, const KIGFX::VIEW* aView, const wxSize& aSheetSize, const wxString& aTitle ) : @@ -40,6 +41,7 @@ PCBNEW_PRINTOUT::PCBNEW_PRINTOUT( BOARD* aBoard, const PRINT_PARAMETERS& aParams bool PCBNEW_PRINTOUT::OnPrintPage( int aPage ) { + // Store the layerset, as it is going to be modified below and the original settings are needed LSET lset = m_PrintParams.m_PrintMaskLayer; int pageCount = lset.count(); wxString layer; @@ -74,12 +76,51 @@ bool PCBNEW_PRINTOUT::OnPrintPage( int aPage ) DrawPage( layer, aPage, pageCount ); + // Restore the original layer set, so the next page can be printed m_PrintParams.m_PrintMaskLayer = lset; return true; } +void PCBNEW_PRINTOUT::setupViewLayers( const std::unique_ptr& aView, + const LSET& aLayerSet ) +{ + BOARD_PRINTOUT::setupViewLayers( aView, aLayerSet ); + + for( LSEQ layerSeq = m_PrintParams.m_PrintMaskLayer.Seq(); layerSeq; ++layerSeq ) + aView->SetLayerVisible( PCBNEW_LAYER_ID_START + *layerSeq, true ); + + // Enable pad layers corresponding to the selected copper layers + if( aLayerSet.test( F_Cu ) ) + aView->SetLayerVisible( LAYER_PAD_FR, true ); + + if( aLayerSet.test( B_Cu ) ) + aView->SetLayerVisible( LAYER_PAD_BK, true ); + + if( ( aLayerSet & LSET::AllCuMask() ).any() ) // Items visible on any copper layer + { + // Enable items on copper layers, but do not draw holes + const int copperItems[] = { + LAYER_PADS_TH, LAYER_VIA_MICROVIA, LAYER_VIA_BBLIND, LAYER_VIA_THROUGH + }; + + for( int item : copperItems ) + aView->SetLayerVisible( item, true ); + } + + + // Keep certain items always enabled/disabled and just rely on the layer visibility + const int alwaysEnabled[] = { + LAYER_MOD_TEXT_FR, LAYER_MOD_TEXT_BK, LAYER_MOD_FR, LAYER_MOD_BK, + LAYER_MOD_VALUES, LAYER_MOD_REFERENCES, LAYER_TRACKS + }; + + for( int item : alwaysEnabled ) + aView->SetLayerVisible( item, true ); +} + + EDA_RECT PCBNEW_PRINTOUT::getBoundingBox() { return m_board->ComputeBoundingBox(); diff --git a/pcbnew/pcbnew_printout.h b/pcbnew/pcbnew_printout.h index dacff0ec53..04f9d4dc34 100644 --- a/pcbnew/pcbnew_printout.h +++ b/pcbnew/pcbnew_printout.h @@ -33,6 +33,8 @@ public: bool OnPrintPage( int aPage ) override; protected: + void setupViewLayers( const std::unique_ptr& aView, const LSET& aLayerSet ) override; + EDA_RECT getBoundingBox() override; std::unique_ptr getPainter( KIGFX::GAL* aGal ) override;