Handle layer settings in printouts

This commit is contained in:
Maciej Suminski 2018-09-28 10:10:08 +02:00
parent 5b94f20e6f
commit 1cce194c8a
14 changed files with 123 additions and 174 deletions

View File

@ -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<KIGFX::VIEW>& 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 );
}
}

View File

@ -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();

View File

@ -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<int> 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<GERBVIEW_PRINTOUT>( createPrintout( _( "Print" ) ) );
@ -423,4 +423,3 @@ void DIALOG_PRINT_USING_PRINTER::OnPrintButtonClick( wxCommandEvent& event )
*s_printData = printer.GetPrintDialogData().GetPrintData();
}
}

View File

@ -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<int> 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();

View File

@ -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 ) );

View File

@ -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<int> 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<int>& aLayerList )
{
m_printLayersList = aLayerList;
}
/**
* Function GetPrintableLayers
* @return the list of printable layers
*/
std::vector<int> 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;

View File

@ -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 );
}

View File

@ -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;

View File

@ -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<int> 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<KIGFX::VIEW>& 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();

View File

@ -33,6 +33,8 @@ public:
bool OnPrintPage( int aPage ) override;
protected:
void setupViewLayers( const std::unique_ptr<KIGFX::VIEW>& aView, const LSET& aLayerSet ) override;
EDA_RECT getBoundingBox() override;
std::unique_ptr<KIGFX::PAINTER> getPainter( KIGFX::GAL* aGal ) override;

View File

@ -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<KIGFX::VIEW>& aView, const LSET& aLayerSet );
///> Returns bounding box of the printed objects (excluding worksheet frame)
virtual EDA_RECT getBoundingBox() = 0;

View File

@ -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,

View File

@ -29,6 +29,7 @@
#include <class_board.h>
#include <pcb_painter.h>
#include <view/view.h>
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<KIGFX::VIEW>& 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();

View File

@ -33,6 +33,8 @@ public:
bool OnPrintPage( int aPage ) override;
protected:
void setupViewLayers( const std::unique_ptr<KIGFX::VIEW>& aView, const LSET& aLayerSet ) override;
EDA_RECT getBoundingBox() override;
std::unique_ptr<KIGFX::PAINTER> getPainter( KIGFX::GAL* aGal ) override;