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 <class_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 
37  : BOARD_PRINTOUT_SETTINGS( aPageInfo )
38 {
41  m_noEdgeLayer = false;
42  m_asItemCheckboxes = false;
43 }
44 
45 
47 {
49 
50  if( auto cfg = dynamic_cast<PCBNEW_SETTINGS*>( aConfig ) )
51  {
52  m_drillMarks = static_cast<DRILL_MARK_SHAPE_T>( cfg->m_Plot.pads_drill_mode );
53  m_pagination = static_cast<PAGINATION_T>( cfg->m_Plot.one_page_per_layer );
54  m_mirror = cfg->m_Plot.mirror;
55  }
56 }
57 
58 
60 {
62 
63  if( auto cfg = dynamic_cast<PCBNEW_SETTINGS*>( aConfig ) )
64  {
65  cfg->m_Plot.pads_drill_mode = m_drillMarks;
66  cfg->m_Plot.one_page_per_layer = m_pagination;
67  cfg->m_Plot.mirror = m_mirror;
68  }
69 }
70 
71 
73  const KIGFX::VIEW* aView, const wxString& aTitle ) :
74  BOARD_PRINTOUT( aParams, aView, aTitle ), m_pcbnewSettings( aParams )
75 {
76  m_board = aBoard;
77 }
78 
79 
81 {
82  // Store the layerset, as it is going to be modified below and the original settings are
83  // needed.
84  LSET lset = m_settings.m_layerSet;
85  int pageCount = lset.count();
86  wxString layerName;
87  PCB_LAYER_ID extractLayer;
88 
89  // compute layer mask from page number if we want one page per layer
91  {
92  // This sequence is TBD, call a different sequencer if needed, such as Seq().
93  // Could not find documentation on page order.
94  LSEQ seq = lset.UIOrder();
95 
96  // aPage starts at 1, not 0
97  if( unsigned( aPage - 1 ) < seq.size() )
98  m_settings.m_layerSet = LSET( seq[aPage - 1] );
99  }
100 
101  if( !m_settings.m_layerSet.any() )
102  return false;
103 
104  extractLayer = m_settings.m_layerSet.ExtractLayer();
105 
106  if( extractLayer == UNDEFINED_LAYER )
107  layerName = _( "Multiple Layers" );
108  else
109  layerName = LSET::Name( extractLayer );
110 
111  // In Pcbnew we can want the layer EDGE always printed
114 
115  DrawPage( layerName, aPage, pageCount );
116 
117  // Restore the original layer set, so the next page can be printed
118  m_settings.m_layerSet = lset;
119 
120  return true;
121 }
122 
123 
124 int PCBNEW_PRINTOUT::milsToIU( double aMils ) const
125 {
126  return KiROUND( IU_PER_MILS * aMils );
127 }
128 
129 
130 void PCBNEW_PRINTOUT::setupViewLayers( KIGFX::VIEW& aView, const LSET& aLayerSet )
131 {
132  BOARD_PRINTOUT::setupViewLayers( aView, aLayerSet );
133 
134  for( LSEQ layerSeq = m_settings.m_layerSet.Seq(); layerSeq; ++layerSeq )
135  {
136  aView.SetLayerVisible( PCBNEW_LAYER_ID_START + *layerSeq, true );
137 
138  // Enable the corresponding zone layer
139  if( IsCopperLayer( *layerSeq ) )
140  aView.SetLayerVisible( LAYER_ZONE_START + *layerSeq, true );
141  }
142 
144  {
145  auto setVisibility =
146  [&]( GAL_LAYER_ID aLayer )
147  {
148  if( m_board->IsElementVisible( aLayer ) )
149  aView.SetLayerVisible( aLayer );
150  };
151 
152  setVisibility( LAYER_MOD_FR );
153  setVisibility( LAYER_MOD_BK );
154  setVisibility( LAYER_MOD_VALUES );
155  setVisibility( LAYER_MOD_REFERENCES );
156  setVisibility( LAYER_MOD_TEXT_FR );
157  setVisibility( LAYER_MOD_TEXT_BK );
158  setVisibility( LAYER_MOD_TEXT_INVISIBLE );
159  setVisibility( LAYER_PAD_FR );
160  setVisibility( LAYER_PAD_BK );
161  setVisibility( LAYER_PADS_TH );
162 
163  setVisibility( LAYER_TRACKS );
164  setVisibility( LAYER_VIAS );
165 
166  setVisibility( LAYER_NO_CONNECTS );
167  setVisibility( LAYER_DRC_WARNING );
168  setVisibility( LAYER_DRC_ERROR );
169  setVisibility( LAYER_DRC_EXCLUSION );
170  setVisibility( LAYER_ANCHOR );
171  setVisibility( LAYER_WORKSHEET );
172  setVisibility( LAYER_GRID );
173 
174  // Keep certain items always enabled and just rely on either the finer or coarser
175  // visibility controls
176  const int alwaysEnabled[] =
177  {
180  };
181 
182  for( int item : alwaysEnabled )
183  aView.SetLayerVisible( item, true );
184  }
185  else
186  {
187  // Enable pad layers corresponding to the selected copper layers
188  if( aLayerSet.test( F_Cu ) )
189  aView.SetLayerVisible( LAYER_PAD_FR, true );
190 
191  if( aLayerSet.test( B_Cu ) )
192  aView.SetLayerVisible( LAYER_PAD_BK, true );
193 
194  if( ( aLayerSet & LSET::AllCuMask() ).any() ) // Items visible on any copper layer
195  {
196  // Enable items on copper layers, but do not draw holes
197  for( GAL_LAYER_ID item : { LAYER_PADS_TH, LAYER_VIA_THROUGH } )
198  {
199  aView.SetLayerVisible( item, true );
200  }
201  }
202 
203  // Keep certain items always enabled/disabled and just rely on the layer visibility
204  const int alwaysEnabled[] =
205  {
209  };
210 
211  for( int item : alwaysEnabled )
212  aView.SetLayerVisible( item, true );
213  }
214 
216  {
217  // Enable hole layers to draw drill marks
219  LAYER_VIAS_HOLES } )
220  {
221  aView.SetLayerVisible( holeLayer, true );
222  aView.SetTopLayer( holeLayer, true );
223  }
224  }
225 }
226 
227 
229 {
230  BOARD_PRINTOUT::setupPainter( aPainter );
231 
232  KIGFX::PCB_PRINT_PAINTER& painter = dynamic_cast<KIGFX::PCB_PRINT_PAINTER&>( aPainter );
233 
235  {
237  painter.SetDrillMarks( false, 0 );
238  break;
239 
241  painter.SetDrillMarks( false, Millimeter2iu( 0.3 ) );
242 
246  break;
247 
249  painter.SetDrillMarks( true );
250 
254  break;
255  }
256 
259 }
260 
261 
263 {
264  BOARD_PRINTOUT::setupGal( aGal );
265  aGal->SetWorldUnitLength( 1e-9 /* 1 nm */ / 0.0254 /* 1 inch in meters */ );
266 }
267 
268 
270 {
271  return m_board->ComputeBoundingBox();
272 }
273 
274 
275 std::unique_ptr<KIGFX::PAINTER> PCBNEW_PRINTOUT::getPainter( KIGFX::GAL* aGal )
276 {
277  return std::make_unique<KIGFX::PCB_PRINT_PAINTER>( aGal );
278 }
279 
280 
282  : PCB_PAINTER( aGal ), m_drillMarkReal( false ), m_drillMarkSize( 0 )
283 {
285 }
286 
287 
289 {
290  return m_drillMarkReal ? KIGFX::PCB_PAINTER::getDrillShape( aPad ) : PAD_DRILL_SHAPE_CIRCLE;
291 }
292 
293 
295 {
296  // TODO should it depend on the pad size?
297  return m_drillMarkReal ? KIGFX::PCB_PAINTER::getDrillSize( aPad ) :
298  VECTOR2D( m_drillMarkSize, m_drillMarkSize );
299 }
300 
301 
303 {
304  // TODO should it depend on the via size?
305  return m_drillMarkReal ? KIGFX::PCB_PAINTER::getDrillSize( aVia ) : m_drillMarkSize;
306 }
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:749
Virtual layers for stacking zones and tracks on a given copper layer.
bool m_noEdgeLayer
Disable board outline on each page.
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)
Function SetTopLayer() Sets given layer to be displayed on the top or sets back the default order of ...
Definition: view.cpp:838
multilayer pads, usually with holes
handle color for not plated holes (holes, not pads)
anchor of items having an anchor point (texts, footprints)
Special flavor of PCB_PAINTER that contains modifications to handle printing options.
Control for copper zone opacity/visibility (color ignored)
virtual VECTOR2D getDrillSize(const D_PAD *aPad) const
Return drill size for a pad (internal units).
show footprints on back
void EnableZoneOutlines(bool aEnabled)
Turns on/off drawing outline and hatched lines for zones.
Definition: pcb_painter.h:135
GAL_LAYER_ID
GAL layers are "virtual" layers, i.e.
to draw via holes (pad holes do not use this layer)
void Load(APP_SETTINGS_BASE *aConfig) override
show footprints values (when texts are visibles)
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:281
Definition: color4d.h:45
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:410
PCB_PAINTER Contains methods for drawing PCB-specific items.
Definition: pcb_painter.h:260
std::unique_ptr< KIGFX::PAINTER > getPainter(KIGFX::GAL *aGal) override
Returns a PAINTER instance used to draw the items.
BOARD_PRINTOUT_SETTINGS m_settings
Printout parameters
Board plot function definition file.
void setupPainter(KIGFX::PAINTER &aPainter) override
Configures PAINTER object for a printout
show footprints on front
PCB_LAYER_ID
A quick note on layer IDs:
PAINTER contains all the knowledge about how to draw graphical object onto any particular output devi...
Definition: painter.h:57
void Load(APP_SETTINGS_BASE *aConfig) override
void setupViewLayers(KIGFX::VIEW &aView, const LSET &aLayerSet) override
Enables layers visibility 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:593
virtual PCB_RENDER_SETTINGS * GetSettings() override
Definition: pcb_painter.h:272
virtual void setupPainter(KIGFX::PAINTER &aPainter)
Configures PAINTER object for a printout
bool m_mirror
Print mirrored.
static const wxChar * Name(PCB_LAYER_ID aLayerId)
Return the fixed name association with aLayerId.
Definition: lset.cpp:81
int milsToIU(double aMils) const override
Convert mils to internal units
PAGE_INFO describes the page size and margins of a paper page on which to eventually print or plot.
Definition: page_info.h:54
Meta control for all pads opacity/visibility (color ignored)
to draw usual through hole vias
virtual void setupGal(KIGFX::GAL *aGal)
Configures GAL object for a printout
VECTOR2D getDrillSize(const D_PAD *aPad) const override
Return drill size for a pad (internal units).
void SetLayerColor(int aLayer, const COLOR4D &aColor)
Function SetLayerColor Changes the color used to draw a layer.
void SetLayerVisible(int aLayer, bool aVisible=true)
Function SetLayerVisible() Controls the visibility of a particular layer.
Definition: view.h:385
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:172
LSEQ is a sequence (and therefore also a set) of PCB_LAYER_IDs.
virtual void setupViewLayers(KIGFX::VIEW &aView, const LSET &aLayerSet)
Enables layers visibility 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.
layer for drc markers with SEVERITY_WARNING
smd pads, front layer
BOARD_PRINTOUT is a class derived from wxPrintout to handle the necessary information to control a pr...
Meta control for all vias opacity/visibility.
PCB_LAYER_ID ExtractLayer() const
Find the first set PCB_LAYER_ID.
Definition: lset.cpp:660
PCBNEW_PRINTOUT_SETTINGS m_pcbnewSettings
Information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:186
#define _(s)
Definition: 3d_actions.cpp:33
EDA_RECT handles the component boundary box.
Definition: eda_rect.h:44
#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).
bool IsCopperLayer(LAYER_NUM aLayerId)
Tests whether a layer is a copper layer.
EDA_RECT getBoundingBox() override
Returns bounding box of the printed objects (excluding worksheet frame)
enum PCBNEW_PRINTOUT_SETTINGS::DRILL_MARK_SHAPE_T m_drillMarks
VIEW.
Definition: view.h:63
void setupGal(KIGFX::GAL *aGal) override
Configures GAL object for a printout
int getDrillShape(const D_PAD *aPad) const override
Return drill shape of a pad.
LSEQ UIOrder() const
Definition: lset.cpp:887
static constexpr int Millimeter2iu(double mm)
bool OnPrintPage(int aPage) override
show footprints references (when texts are visibles)
layer for drc markers with SEVERITY_ERROR
LSET m_layerSet
Layers to print.
void SetDrillMarks(bool aRealSize, unsigned int aSize=0)
Set drill marks visibility and options.
Class GAL is the abstract interface for drawing on a 2D-surface.
virtual int getDrillShape(const D_PAD *aPad) const
Return drill shape of a pad.