KiCad PCB EDA Suite
pcbnew_printout.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2009 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
5  * Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
6  * Copyright (C) 2018 CERN
7  * Author: Maciej Suminski <maciej.suminski@cern.ch>
8  * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, you may find one here:
22  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
23  * or you may search the http://www.gnu.org website for the version 2 license,
24  * or you may write to the Free Software Foundation, Inc.,
25  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
26  */
27 
28 #include "pcbnew_printout.h"
29 #include <board.h>
30 #include <math/util.h> // for KiROUND
31 #include <pcb_painter.h>
32 #include <pcbnew_settings.h>
33 #include <view/view.h>
34 #include <pcbplot.h>
35 #include <advanced_config.h>
36 
38  : BOARD_PRINTOUT_SETTINGS( aPageInfo )
39 {
42  m_noEdgeLayer = false;
43  m_asItemCheckboxes = false;
44 }
45 
46 
48 {
50 
51  if( auto cfg = dynamic_cast<PCBNEW_SETTINGS*>( aConfig ) )
52  {
53  m_drillMarks = static_cast<DRILL_MARK_SHAPE_T>( cfg->m_Plot.pads_drill_mode );
54  m_pagination = static_cast<PAGINATION_T>( cfg->m_Plot.all_layers_on_one_page );
55  m_Mirror = cfg->m_Plot.mirror;
56  }
57 }
58 
59 
61 {
63 
64  if( auto cfg = dynamic_cast<PCBNEW_SETTINGS*>( aConfig ) )
65  {
66  cfg->m_Plot.pads_drill_mode = m_drillMarks;
67  cfg->m_Plot.all_layers_on_one_page = m_pagination;
68  cfg->m_Plot.mirror = m_Mirror;
69  }
70 }
71 
72 
74  const KIGFX::VIEW* aView, const wxString& aTitle ) :
75  BOARD_PRINTOUT( aParams, aView, aTitle ), m_pcbnewSettings( aParams )
76 {
77  m_board = aBoard;
78 }
79 
80 
82 {
83  // Store the layerset, as it is going to be modified below and the original settings are
84  // needed.
85  LSET lset = m_settings.m_LayerSet;
86  int pageCount = lset.count();
87  wxString layerName;
88  PCB_LAYER_ID extractLayer;
89 
90  // compute layer mask from page number if we want one page per layer
92  {
93  // This sequence is TBD, call a different sequencer if needed, such as Seq().
94  // Could not find documentation on page order.
95  LSEQ seq = lset.UIOrder();
96 
97  // aPage starts at 1, not 0
98  if( unsigned( aPage - 1 ) < seq.size() )
99  m_settings.m_LayerSet = LSET( seq[ aPage - 1] );
100  }
101 
102  if( !m_settings.m_LayerSet.any() )
103  return false;
104 
105  extractLayer = m_settings.m_LayerSet.ExtractLayer();
106 
107  if( extractLayer == UNDEFINED_LAYER )
108  layerName = _( "Multiple Layers" );
109  else
110  layerName = LSET::Name( extractLayer );
111 
112  // In Pcbnew we can want the layer EDGE always printed
115 
116  DrawPage( layerName, aPage, pageCount );
117 
118  // Restore the original layer set, so the next page can be printed
119  m_settings.m_LayerSet = lset;
120 
121  return true;
122 }
123 
124 
125 int PCBNEW_PRINTOUT::milsToIU( double aMils ) const
126 {
127  return KiROUND( IU_PER_MILS * aMils );
128 }
129 
130 
131 void PCBNEW_PRINTOUT::setupViewLayers( KIGFX::VIEW& aView, const LSET& aLayerSet )
132 {
133  BOARD_PRINTOUT::setupViewLayers( aView, aLayerSet );
134 
135  for( PCB_LAYER_ID layer : m_settings.m_LayerSet.Seq() )
136  {
137  aView.SetLayerVisible( PCBNEW_LAYER_ID_START + layer, true );
138 
139  // Enable the corresponding zone layer
140  if( IsCopperLayer( layer ) )
141  aView.SetLayerVisible( LAYER_ZONE_START + layer, true );
142  }
143 
144  RENDER_SETTINGS* renderSettings = aView.GetPainter()->GetSettings();
145  COLOR4D backgroundColor = renderSettings->GetLayerColor( LAYER_PCB_BACKGROUND );
146 
148  {
149  auto setVisibility =
150  [&]( GAL_LAYER_ID aLayer )
151  {
152  if( m_board->IsElementVisible( aLayer ) )
153  aView.SetLayerVisible( aLayer, true );
154  else
155  renderSettings->SetLayerColor( aLayer, backgroundColor );
156  };
157 
158  setVisibility( LAYER_MOD_FR );
159  setVisibility( LAYER_MOD_BK );
160  setVisibility( LAYER_MOD_VALUES );
161  setVisibility( LAYER_MOD_REFERENCES );
162  setVisibility( LAYER_MOD_TEXT_FR );
163  setVisibility( LAYER_MOD_TEXT_BK );
164  setVisibility( LAYER_MOD_TEXT_INVISIBLE );
165  setVisibility( LAYER_PAD_FR );
166  setVisibility( LAYER_PAD_BK );
167  setVisibility( LAYER_PADS_TH );
168 
169  setVisibility( LAYER_TRACKS );
170  setVisibility( LAYER_VIAS );
171 
172  setVisibility( LAYER_NO_CONNECTS );
173  setVisibility( LAYER_DRC_WARNING );
174  setVisibility( LAYER_DRC_ERROR );
175  setVisibility( LAYER_DRC_EXCLUSION );
176  setVisibility( LAYER_ANCHOR );
177  setVisibility( LAYER_DRAWINGSHEET );
178  setVisibility( LAYER_GRID );
179 
180  // Keep certain items always enabled and just rely on either the finer or coarser
181  // visibility controls
182  const int alwaysEnabled[] =
183  {
186  };
187 
188  for( int layer : alwaysEnabled )
189  aView.SetLayerVisible( layer, true );
190  }
191  else
192  {
193  // Enable pad layers corresponding to the selected copper layers
194  if( aLayerSet.test( F_Cu ) )
195  aView.SetLayerVisible( LAYER_PAD_FR, true );
196  else
197  renderSettings->SetLayerColor( LAYER_PAD_FR, backgroundColor );
198 
199  if( aLayerSet.test( B_Cu ) )
200  aView.SetLayerVisible( LAYER_PAD_BK, true );
201  else
202  renderSettings->SetLayerColor( LAYER_PAD_BK, backgroundColor );
203 
204  // Enable items on copper layers, but do not draw holes
205  for( GAL_LAYER_ID layer : { LAYER_PADS_TH, LAYER_VIA_THROUGH } )
206  {
207  if( ( aLayerSet & LSET::AllCuMask() ).any() ) // Items visible on any copper layer
208  aView.SetLayerVisible( layer, true );
209  else
210  renderSettings->SetLayerColor( layer, backgroundColor );
211  }
212 
213  // Keep certain items always enabled/disabled and just rely on the layer visibility
214  const int alwaysEnabled[] =
215  {
219  };
220 
221  for( int layer : alwaysEnabled )
222  aView.SetLayerVisible( layer, true );
223  }
224 
226  {
227  // Enable hole layers to draw drill marks
229  {
230  aView.SetLayerVisible( layer, true );
231  aView.SetTopLayer( layer, true );
232  }
233  }
234 }
235 
236 
238 {
239  BOARD_PRINTOUT::setupPainter( aPainter );
240 
241  KIGFX::PCB_PRINT_PAINTER& painter = dynamic_cast<KIGFX::PCB_PRINT_PAINTER&>( aPainter );
242 
244  {
246  painter.SetDrillMarks( false, 0 );
247  break;
248 
250  painter.SetDrillMarks( false, Millimeter2iu( ADVANCED_CFG::GetCfg().m_SmallDrillMarkSize ) );
251 
255  break;
256 
258  painter.SetDrillMarks( true );
259 
263  break;
264  }
265 
268 }
269 
270 
272 {
273  BOARD_PRINTOUT::setupGal( aGal );
274  aGal->SetWorldUnitLength( 1e-9 /* 1 nm */ / 0.0254 /* 1 inch in meters */ );
275 }
276 
277 
279 {
280  return m_board->ComputeBoundingBox();
281 }
282 
283 
284 std::unique_ptr<KIGFX::PAINTER> PCBNEW_PRINTOUT::getPainter( KIGFX::GAL* aGal )
285 {
286  return std::make_unique<KIGFX::PCB_PRINT_PAINTER>( aGal );
287 }
288 
289 
291  PCB_PAINTER( aGal ),
292  m_drillMarkReal( false ),
293  m_drillMarkSize( 0 )
294 {
296 }
297 
298 
300 {
301  return m_drillMarkReal ? KIGFX::PCB_PAINTER::getDrillShape( aPad ) : PAD_DRILL_SHAPE_CIRCLE;
302 }
303 
304 
306 {
307  // TODO should it depend on the pad size?
308  return m_drillMarkReal ? KIGFX::PCB_PAINTER::getDrillSize( aPad ) :
309  VECTOR2D( m_drillMarkSize, m_drillMarkSize );
310 }
311 
312 
314 {
315  // TODO should it depend on the via size?
316  return m_drillMarkReal ? KIGFX::PCB_PAINTER::getDrillSize( aVia ) : m_drillMarkSize;
317 }
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:750
Virtual layers for stacking zones and tracks on a given copper layer.
bool m_noEdgeLayer
Disable board outline on each page.
Definition: track.h:343
to draw blind/buried vias
PCBNEW_PRINTOUT_SETTINGS(const PAGE_INFO &aPageInfo)
show a marker on pads with no nets
void Save(APP_SETTINGS_BASE *aConfig) override
virtual void SetTopLayer(int aLayer, bool aEnabled=true)
Set given layer to be displayed on the top or sets back the default order of layers.
Definition: view.cpp:832
Container for all the knowledge about how graphical objects are drawn on any output surface/device.
multilayer pads, usually with holes
to draw via holes (pad holes do not use this layer)
handle color for not plated holes (holes, not pads)
anchor of items having an anchor point (texts, footprints)
int getDrillShape(const PAD *aPad) const override
Return drill shape of a pad.
Special flavor of PCB_PAINTER that contains modifications to handle printing options.
Control for copper zone opacity/visibility (color ignored)
show footprints on back
void EnableZoneOutlines(bool aEnabled)
Turn on/off drawing outline and hatched lines for zones.
Definition: pcb_painter.h:136
const COLOR4D & GetLayerColor(int aLayer) const
Return the color used to draw a layer.
GAL_LAYER_ID
GAL layers are "virtual" layers, i.e.
void Load(APP_SETTINGS_BASE *aConfig) override
show footprints values (when texts are visibles)
LSET m_LayerSet
Layers to print.
PCBNEW_PRINTOUT(BOARD *aBoard, const PCBNEW_PRINTOUT_SETTINGS &aParams, const KIGFX::VIEW *aView, const wxString &aTitle)
virtual void DrawPage(const wxString &aLayerName=wxEmptyString, int aPageNum=1, int aPageCount=1)
Print a page (or a set of pages).
PCB_RENDER_SETTINGS m_pcbSettings
Definition: pcb_painter.h:295
Definition: color4d.h:44
LSEQ Seq(const PCB_LAYER_ID *aWishListSequence, unsigned aCount) const
Return an LSEQ from the union of this LSET and a desired sequence.
Definition: lset.cpp:411
Contains methods for drawing PCB-specific items.
Definition: pcb_painter.h:241
std::unique_ptr< KIGFX::PAINTER > getPainter(KIGFX::GAL *aGal) override
Source VIEW object (note that actual printing only refers to this object)
PAINTER * GetPainter() const
Return the painter object used by the view for drawing #VIEW_ITEMS.
Definition: view.h:207
BOARD_PRINTOUT_SETTINGS m_settings
virtual VECTOR2D getDrillSize(const PAD *aPad) const
Return drill size for a pad (internal units).
Board plot function definition file.
void setupPainter(KIGFX::PAINTER &aPainter) override
Configures GAL object for a printout.
show footprints on front
PCB_LAYER_ID
A quick note on layer IDs:
Contains all the knowledge about how to draw graphical object onto any particular output device.
Definition: painter.h:57
void Load(APP_SETTINGS_BASE *aConfig) override
void setupViewLayers(KIGFX::VIEW &aView, const LSET &aLayerSet) override
Configures PAINTER object for a printout.
LSET is a set of PCB_LAYER_IDs.
APP_SETTINGS_BASE is a settings class that should be derived for each standalone KiCad application.
Definition: app_settings.h:99
VECTOR2< double > VECTOR2D
Definition: vector2d.h:622
virtual PCB_RENDER_SETTINGS * GetSettings() override
Return a pointer to current settings that are going to be used when drawing items.
Definition: pcb_painter.h:247
virtual void setupPainter(KIGFX::PAINTER &aPainter)
Configures GAL object for a printout.
static const wxChar * Name(PCB_LAYER_ID aLayerId)
Return the fixed name association with aLayerId.
Definition: lset.cpp:82
int milsToIU(double aMils) const override
< Convert mils to internal units
Describe the page size and margins of a paper page on which to eventually print or plot.
Definition: page_info.h:53
Meta control for all pads opacity/visibility (color ignored)
to draw usual through hole vias
virtual void setupGal(KIGFX::GAL *aGal)
Returns bounding box of the printed objects (excluding drawing-sheet frame)
void SetLayerColor(int aLayer, const COLOR4D &aColor)
Change the color used to draw a layer.
void SetLayerVisible(int aLayer, bool aVisible=true)
Control the visibility of a particular layer.
Definition: view.h:387
bool m_asItemCheckboxes
Honor checkboxes in the Items tab of the Layers Manager.
void Save(APP_SETTINGS_BASE *aConfig) override
void SetWorldUnitLength(double aWorldUnitLength)
Set the unit length.
void SetDrawIndividualViaLayers(bool aFlag)
Definition: pcb_painter.h:175
LSEQ is a sequence (and therefore also a set) of PCB_LAYER_IDs.
virtual void setupViewLayers(KIGFX::VIEW &aView, const LSET &aLayerSet)
Configures PAINTER object for a printout.
layer for drc markers which have been individually excluded
bool IsElementVisible(GAL_LAYER_ID aLayer) const
Test whether a given element category is visible.
Definition: board.cpp:507
layer for drc markers with SEVERITY_WARNING
virtual RENDER_SETTINGS * GetSettings()=0
Return a pointer to current settings that are going to be used when drawing items.
smd pads, front layer
An object derived from wxPrintout to handle the necessary information to control a printer when print...
Meta control for all vias opacity/visibility.
PCB_LAYER_ID ExtractLayer() const
Find the first set PCB_LAYER_ID.
Definition: lset.cpp:661
PCBNEW_PRINTOUT_SETTINGS m_pcbnewSettings
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:190
#define _(s)
Definition: 3d_actions.cpp:33
Handle the component boundary box.
Definition: eda_rect.h:42
VECTOR2D getDrillSize(const PAD *aPad) const override
Return drill size for a pad (internal units).
#define IU_PER_MILS
Definition: plotter.cpp:137
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:68
enum PCBNEW_PRINTOUT_SETTINGS::PAGINATION_T m_pagination
EDA_RECT ComputeBoundingBox(bool aBoardEdgesOnly=false) const
Calculate the bounding box containing all board items (or board edge segments).
Definition: board.cpp:1029
bool IsCopperLayer(LAYER_NUM aLayerId)
Tests whether a layer is a copper layer.
EDA_RECT getBoundingBox() override
Returns a PAINTER instance used to draw the items.
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
enum PCBNEW_PRINTOUT_SETTINGS::DRILL_MARK_SHAPE_T m_drillMarks
drawingsheet frame and titleblock
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition: view.h:67
void setupGal(KIGFX::GAL *aGal) override
Returns bounding box of the printed objects (excluding drawing-sheet frame)
Definition: pad.h:60
virtual int getDrillShape(const PAD *aPad) const
Return drill shape of a pad.
LSEQ UIOrder() const
Definition: lset.cpp:895
static constexpr int Millimeter2iu(double mm)
bool OnPrintPage(int aPage) override
bool m_Mirror
Print mirrored.
show footprints references (when texts are visibles)
layer for drc markers with SEVERITY_ERROR
void SetDrillMarks(bool aRealSize, unsigned int aSize=0)
Set drill marks visibility and options.
Abstract interface for drawing on a 2D-surface.
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:98