KiCad PCB EDA Suite
print_board_functions.cpp
Go to the documentation of this file.
1 
5 /*
6  * This program source code file is part of KiCad, a free EDA CAD application.
7  *
8  * Copyright (C) 1992-2013 KiCad Developers, see AUTHORS.txt for contributors.
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 <fctsys.h>
29 #include <class_drawpanel.h>
30 #include <wxPcbStruct.h>
31 #include <printout_controler.h>
32 #include <class_board.h>
33 #include <class_module.h>
34 #include <class_edge_mod.h>
35 #include <class_track.h>
36 #include <class_zone.h>
37 
38 #include <pcbnew.h>
39 #include <pcbplot.h>
40 #include <module_editor_frame.h>
41 
42 
43 static void Print_Module( EDA_DRAW_PANEL* aPanel, wxDC* aDC, MODULE* aModule,
44  GR_DRAWMODE aDraw_mode, LSET aMasklayer,
45  PRINT_PARAMETERS::DrillShapeOptT aDrillShapeOpt );
46 
48  LSET aPrintMaskLayer,
49  bool aPrintMirrorMode,
50  void * aData)
51 {
52  const GR_DRAWMODE drawmode = (GR_DRAWMODE) 0;
53  int defaultPenSize = Millimeter2iu( 0.2 );
54  auto displ_opts = (PCB_DISPLAY_OPTIONS*) GetDisplayOptions();
55  PCB_DISPLAY_OPTIONS save_opt;
56 
57  PRINT_PARAMETERS * printParameters = (PRINT_PARAMETERS*) aData; // can be null
59 
60  if( printParameters )
61  defaultPenSize = printParameters->m_PenDefaultSize;
62 
63  save_opt = *displ_opts;
64 
65  displ_opts->m_ContrastModeDisplay = false;
66  displ_opts->m_DisplayPadFill = true;
67  displ_opts->m_DisplayViaFill = true;
68  displ_opts->m_DisplayPadNum = false;
69  bool nctmp = GetBoard()->IsElementVisible( LAYER_NO_CONNECTS );
71  displ_opts->m_DisplayPadIsol = false;
72  displ_opts->m_DisplayModEdgeFill = FILLED;
73  displ_opts->m_DisplayModTextFill = FILLED;
74  displ_opts->m_DisplayPcbTrackFill = true;
75  displ_opts->m_ShowTrackClearanceMode = PCB_DISPLAY_OPTIONS::DO_NOT_SHOW_CLEARANCE;
76  displ_opts->m_DisplayDrawItemsFill = FILLED;
77  displ_opts->m_DisplayZonesMode = 0;
78  displ_opts->m_DisplayNetNamesMode = 0;
79 
80  m_canvas->SetPrintMirrored( aPrintMirrorMode );
81 
82  // Draw footprints, this is done at last in order to print the pad holes in
83  // white after the tracks and zones
85  D_PAD::m_PadSketchModePenSize = defaultPenSize;
86 
87  wxSize pageSizeIU = GetPageSizeIU() / 2;
88  wxPoint offset( pageSizeIU.x, pageSizeIU.y );
89 
90  for( MODULE* module = GetBoard()->m_Modules; module; module = module->Next() )
91  {
92  module->Move( offset );
93  Print_Module( m_canvas, aDC, module, drawmode, aPrintMaskLayer, drillShapeOpt );
94  module->Move( -offset );
95  }
96 
98 
99  m_canvas->SetPrintMirrored( false );
100 
101  *displ_opts = save_opt;
103 }
104 
105 
107  LSET aPrintMask,
108  bool aPrintMirrorMode,
109  void* aData)
110 {
111  const GR_DRAWMODE drawmode = (GR_DRAWMODE) 0;
112  PCB_DISPLAY_OPTIONS save_opt;
113  BOARD* Pcb = GetBoard();
114  int defaultPenSize = Millimeter2iu( 0.2 );
115  bool onePagePerLayer = false;
116 
117  PRINT_PARAMETERS* printParameters = (PRINT_PARAMETERS*) aData; // can be null
118  auto displ_opts = (PCB_DISPLAY_OPTIONS*) GetDisplayOptions();
119 
120  if( printParameters && printParameters->m_OptionPrintPage == 0 )
121  onePagePerLayer = true;
122 
124 
125  if( printParameters )
126  {
127  drillShapeOpt = printParameters->m_DrillShapeOpt;
128  defaultPenSize = printParameters->m_PenDefaultSize;
129  }
130 
131  save_opt = *displ_opts;
132 
133  PCB_LAYER_ID activeLayer = GetScreen()->m_Active_Layer;
134 
135  displ_opts->m_ContrastModeDisplay = false;
136  displ_opts->m_DisplayPadFill = true;
137  displ_opts->m_DisplayViaFill = true;
138 
139  if( !( aPrintMask & LSET::AllCuMask() ).any() )
140  {
141  if( onePagePerLayer )
142  {
143  // We can print mask layers (solder mask and solder paste) with the actual
144  // pad sizes. To do that, we must set ContrastModeDisplay to true and set
145  // the GetScreen()->m_Active_Layer to the current printed layer
146  displ_opts->m_ContrastModeDisplay = true;
147  displ_opts->m_DisplayPadFill = true;
148 
149  // Calculate the active layer number to print from its mask layer:
151 
152  for( LAYER_NUM id = PCB_LAYER_ID_COUNT-1; id >= 0; --id )
153  {
154  if( aPrintMask[id] )
155  {
157  break;
158  }
159  }
160 
161  // pads on Silkscreen layer are usually plot in sketch mode:
162  if( GetScreen()->m_Active_Layer == B_SilkS ||
163  GetScreen()->m_Active_Layer == F_SilkS )
164  {
165  displ_opts->m_DisplayPadFill = false;
166  }
167  }
168  else
169  {
170  displ_opts->m_DisplayPadFill = false;
171  }
172  }
173 
174  displ_opts->m_DisplayPadNum = false;
175 
176  bool nctmp = GetBoard()->IsElementVisible( LAYER_NO_CONNECTS );
177 
179 
180  bool anchorsTmp = GetBoard()->IsElementVisible( LAYER_ANCHOR );
181 
183 
184  displ_opts->m_DisplayPadIsol = false;
185  displ_opts->m_DisplayModEdgeFill = FILLED;
186  displ_opts->m_DisplayModTextFill = FILLED;
187  displ_opts->m_DisplayPcbTrackFill = true;
188  displ_opts->m_ShowTrackClearanceMode = PCB_DISPLAY_OPTIONS::DO_NOT_SHOW_CLEARANCE;
189  displ_opts->m_DisplayDrawItemsFill = FILLED;
190  displ_opts->m_DisplayZonesMode = 0;
191  displ_opts->m_DisplayNetNamesMode = 0;
192 
193  m_canvas->SetPrintMirrored( aPrintMirrorMode );
194 
195  for( auto item : Pcb->Drawings() )
196  {
197  switch( item->Type() )
198  {
199  case PCB_LINE_T:
200  case PCB_DIMENSION_T:
201  case PCB_TEXT_T:
202  case PCB_TARGET_T:
203  if( aPrintMask[item->GetLayer()] )
204  item->Draw( m_canvas, aDC, drawmode );
205  break;
206 
207  case PCB_MARKER_T:
208  default:
209  break;
210  }
211  }
212 
213  // Print tracks
214  for( TRACK* track = Pcb->m_Track; track; track = track->Next() )
215  {
216  if( !( aPrintMask & track->GetLayerSet() ).any() )
217  continue;
218 
219  if( track->Type() == PCB_VIA_T ) // VIA encountered.
220  {
221  int radius = track->GetWidth() / 2;
222  const VIA* via = static_cast<const VIA*>( track );
223 
225 
227  via->GetStart().x,
228  via->GetStart().y,
229  radius,
230  0, color, color );
231  }
232  else
233  {
234  track->Draw( m_canvas, aDC, drawmode );
235  }
236  }
237 
238  // Outdated: only for compatibility to old boards
239  for( TRACK* track = Pcb->m_Zone; track; track = track->Next() )
240  {
241  if( !( aPrintMask & track->GetLayerSet() ).any() )
242  continue;
243 
244  track->Draw( m_canvas, aDC, drawmode );
245  }
246 
247  // Draw filled areas (i.e. zones)
248  for( int ii = 0; ii < Pcb->GetAreaCount(); ii++ )
249  {
250  ZONE_CONTAINER* zone = Pcb->GetArea( ii );
251 
252  if( aPrintMask[zone->GetLayer()] )
253  zone->DrawFilledArea( m_canvas, aDC, drawmode );
254  }
255 
256  // Draw footprints, this is done at last in order to print the pad holes in
257  // white after the tracks and zones
259  D_PAD::m_PadSketchModePenSize = defaultPenSize;
260 
261  for( MODULE* module = (MODULE*) Pcb->m_Modules; module; module = module->Next() )
262  {
263  Print_Module( m_canvas, aDC, module, drawmode, aPrintMask, drillShapeOpt );
264  }
265 
267 
268  /* Print via holes in bg color: Not sure it is good for buried or blind
269  * vias */
270  if( drillShapeOpt != PRINT_PARAMETERS::NO_DRILL_SHAPE )
271  {
272  TRACK* track = Pcb->m_Track;
274 
275  bool blackpenstate = GetGRForceBlackPenState();
276 
277  GRForceBlackPen( false );
278 
279  for( ; track; track = track->Next() )
280  {
281  if( !( aPrintMask & track->GetLayerSet() ).any() )
282  continue;
283 
284  if( track->Type() == PCB_VIA_T ) // VIA encountered.
285  {
286  int diameter;
287  const VIA *via = static_cast<const VIA*>( track );
288 
289  if( drillShapeOpt == PRINT_PARAMETERS::SMALL_DRILL_SHAPE )
290  diameter = std::min( SMALL_DRILL, via->GetDrillValue() );
291  else
292  diameter = via->GetDrillValue();
293 
295  track->GetStart().x, track->GetStart().y,
296  diameter/2,
297  0, color, color );
298  }
299  }
300 
301  GRForceBlackPen( blackpenstate );
302  }
303 
304  m_canvas->SetPrintMirrored( false );
305 
306  *displ_opts = save_opt;
307  GetScreen()->m_Active_Layer = activeLayer;
308 
310  GetBoard()->SetElementVisibility( LAYER_ANCHOR, anchorsTmp );
311 }
312 
313 
314 static void Print_Module( EDA_DRAW_PANEL* aPanel, wxDC* aDC, MODULE* aModule,
315  GR_DRAWMODE aDraw_mode, LSET aMask,
316  PRINT_PARAMETERS::DrillShapeOptT aDrillShapeOpt )
317 {
318  // Print pads
319  for( D_PAD* pad = aModule->PadsList(); pad; pad = pad->Next() )
320  {
321  if( !( pad->GetLayerSet() & aMask ).any() )
322  continue;
323 
324  // Manage hole according to the print drill option
325  wxSize drill_tmp = pad->GetDrillSize();
326 
327  switch( aDrillShapeOpt )
328  {
330  pad->SetDrillSize( wxSize(0,0) );
331  break;
332 
334  {
335  wxSize sz( std::min( SMALL_DRILL, pad->GetDrillSize().x ),
336  std::min( SMALL_DRILL, pad->GetDrillSize().y ) );
337 
338  pad->SetDrillSize( sz );
339  }
340  break;
341 
343  // Do nothing
344  break;
345  }
346 
347  pad->Draw( aPanel, aDC, aDraw_mode );
348  pad->SetDrillSize( drill_tmp );
349  }
350 
351  if( aModule->Reference().IsVisible() && aMask[aModule->Reference().GetLayer()] )
352  aModule->Reference().Draw( aPanel, aDC, aDraw_mode );
353 
354  if( aModule->Value().IsVisible() && aMask[aModule->Value().GetLayer()] )
355  aModule->Value().Draw( aPanel, aDC, aDraw_mode );
356 
357  for( EDA_ITEM* item = aModule->GraphicalItemsList(); item; item = item->Next() )
358  {
359  switch( item->Type() )
360  {
361  case PCB_MODULE_TEXT_T:
362  {
363  TEXTE_MODULE* textMod = static_cast<TEXTE_MODULE*>( item );
364 
365  if( !aMask[textMod->GetLayer()] )
366  break;
367 
368  textMod->Draw( aPanel, aDC, aDraw_mode );
369  break;
370  }
371 
372  case PCB_MODULE_EDGE_T:
373  {
374  EDGE_MODULE* edge = static_cast<EDGE_MODULE*>( item );
375 
376  if( !aMask[edge->GetLayer()] )
377  break;
378 
379  edge->Draw( aPanel, aDC, aDraw_mode );
380  }
381  break;
382 
383  default:
384  break;
385  }
386  }
387 }
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Function AllCuMask returns a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:646
KICAD_T Type() const
Function Type()
Definition: base_struct.h:212
static int m_PadSketchModePenSize
Pen size used to draw pads in sketch mode (mode used to print pads on silkscreen layer) ...
Definition: class_pad.h:137
#define SMALL_DRILL
Definition: pcbplot.h:72
Class ZONE_CONTAINER handles a list of polygons defining a copper zone.
Definition: class_zone.h:78
Definition of class FOOTPRINT_EDIT_FRAME.
show a marker on pads with no nets
TEXTE_MODULE & Reference()
Definition: class_module.h:483
void SetElementVisibility(GAL_LAYER_ID aLayer, bool aNewState)
Function SetElementVisibility changes the visibility of an element category.
Board print handler definition file.
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
anchor of items having an anchor point (texts, footprints)
Class BOARD to handle a board.
void DrawFilledArea(EDA_DRAW_PANEL *panel, wxDC *DC, GR_DRAWMODE aDrawMode, const wxPoint &offset=ZeroOffset)
Function DrawDrawFilledArea Draws the filled area for this zone (polygon list .m_FilledPolysList) ...
Definition: class_zone.cpp:413
MODULE * Next() const
Definition: class_module.h:120
Class PRINT_PARAMETERS handles the parameters used to print a board drawing.
virtual PCB_LAYER_ID GetLayer() const override
Function GetLayer returns the primary layer this item is on.
Definition: class_zone.cpp:182
class TEXTE_PCB, text on a layer
Definition: typeinfo.h:92
BOARD * GetBoard() const
Classes to handle copper zones.
DLIST< SEGZONE > m_Zone
Definition: class_board.h:247
void GRFilledCircle(EDA_RECT *ClipBox, wxDC *DC, int x, int y, int r, int width, COLOR4D Color, COLOR4D BgColor)
Definition: gr_basic.cpp:851
PCB_LAYER_ID m_Active_Layer
class EDGE_MODULE, a footprint edge
Definition: typeinfo.h:94
Functions relatives to tracks, vias and segments used to fill zones.
void * GetDisplayOptions() override
Function GetDisplayOptions returns the display options current in use Display options are relative to...
SEGZONE * Next() const
Definition: class_track.h:362
Board plot function definition file.
BOARD_ITEM * Next() const
COLOR4D GetItemColor(int aItemIdx) const
Function GetItemColor.
Class PCB_DISPLAY_OPTIONS handles display options like enable/disable some optional drawings...
PCB_LAYER_ID
A quick note on layer IDs:
Class LSET is a set of PCB_LAYER_IDs.
virtual void PrintPage(wxDC *aDC, LSET aPrintMaskLayer, bool aPrintMirrorMode, void *aData=NULL) override
Function PrintPage is used to print a page.
VIATYPE_T GetViaType() const
Definition: class_track.h:443
void GRForceBlackPen(bool flagforce)
Function GRForceBlackPen.
Definition: gr_basic.cpp:277
GR_DRAWMODE
Drawmode. Compositing mode plus a flag or two.
Definition: gr_basic.h:41
TEXTE_MODULE & Value()
read/write accessors:
Definition: class_module.h:482
PCB_GENERAL_SETTINGS & Settings()
const wxPoint & GetStart() const
Definition: class_track.h:123
virtual LSET GetLayerSet() const
Function GetLayerSet returns a "layer mask", which is a bitmap of all layers on which the TRACK segme...
D_PAD * Next() const
Definition: class_pad.h:160
EDA_RECT * GetClipBox()
DrillShapeOptT m_DrillShapeOpt
int GetAreaCount() const
Function GetAreaCount.
Definition: class_board.h:1011
void Draw(EDA_DRAW_PANEL *panel, wxDC *DC, GR_DRAWMODE aDrawMode, const wxPoint &offset=ZeroOffset) override
Function Draw BOARD_ITEMs have their own color information.
virtual void PrintPage(wxDC *aDC, LSET aPrintMaskLayer, bool aPrintMirrorMode, void *aData=NULL) override
Function PrintPage , virtual used to print a page Print the page pointed by the current screen...
void Draw(EDA_DRAW_PANEL *aPanel, wxDC *aDC, GR_DRAWMODE aDrawMode, const wxPoint &aOffset=ZeroOffset) override
Function Draw Draw the text according to the footprint pos and orient.
class DIMENSION, a dimension (graphic item)
Definition: typeinfo.h:100
COLORS_DESIGN_SETTINGS & Colors()
class PCB_TARGET, a target (graphic item)
Definition: typeinfo.h:101
int LAYER_NUM
Type LAYER_NUM can be replaced with int and removed.
class TEXTE_MODULE, text in a footprint
Definition: typeinfo.h:93
EDA_DRAW_PANEL * m_canvas
The area to draw on.
Definition: draw_frame.h:93
bool IsElementVisible(GAL_LAYER_ID aLayer) const
Function IsElementVisible tests whether a given element category is visible.
class MARKER_PCB, a marker used to show something
Definition: typeinfo.h:99
TRACK * Next() const
Definition: class_track.h:100
ZONE_CONTAINER * GetArea(int index) const
Function GetArea returns the Area (Zone Container) at a given index.
Definition: class_board.h:982
int GetDrillValue() const
Function GetDrillValue "calculates" the drill value for vias (m-Drill if > 0, or default drill value ...
Class BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:169
DLIST< MODULE > m_Modules
Definition: class_board.h:245
bool IsVisible() const
Definition: eda_text.h:176
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:165
PCB_SCREEN * GetScreen() const override
Function GetScreen returns a pointer to a BASE_SCREEN or one of its derivatives.
Definition: colors.h:49
void SetPrintMirrored(bool aMirror)
const wxSize GetPageSizeIU() const override
Function GetPageSizeIU works off of GetPageSettings() to return the size of the paper page in the int...
DLIST< BOARD_ITEM > & GraphicalItemsList()
Definition: class_module.h:157
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
DLIST< D_PAD > & PadsList()
Definition: class_module.h:154
DLIST< TRACK > m_Track
Definition: class_board.h:246
Module description (excepted pads)
bool GetGRForceBlackPenState(void)
Function GetGRForceBlackPenState.
Definition: gr_basic.cpp:287
EDGE_MODULE class definition.
class DRAWSEGMENT, a segment not on copper layers
Definition: typeinfo.h:91
DLIST_ITERATOR_WRAPPER< BOARD_ITEM > Drawings()
Definition: class_board.h:251
#define min(a, b)
Definition: auxiliary.h:85
Class COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39