KiCad PCB EDA Suite
BOARD_PRINTOUT_CONTROLLER Class Reference

Class BOARD_PRINTOUT_CONTROLLER is a class derived from wxPrintout to handle the necessary information to control a printer when printing a board. More...

#include <printout_controler.h>

Inheritance diagram for BOARD_PRINTOUT_CONTROLLER:

Public Member Functions

 BOARD_PRINTOUT_CONTROLLER (const PRINT_PARAMETERS &aParams, EDA_DRAW_FRAME *aParent, const wxString &aTitle)
 
bool OnPrintPage (int aPage) override
 
bool HasPage (int aPage) override
 
void GetPageInfo (int *minPage, int *maxPage, int *selPageFrom, int *selPageTo) override
 
void DrawPage (const wxString &aLayerName=wxEmptyString, int aPageNum=1, int aPageCount=1)
 Print a page ( or a set of pages ). More...
 

Private Attributes

EDA_DRAW_FRAMEm_Parent
 
PRINT_PARAMETERS m_PrintParams
 

Detailed Description

Class BOARD_PRINTOUT_CONTROLLER is a class derived from wxPrintout to handle the necessary information to control a printer when printing a board.

Definition at line 103 of file printout_controler.h.

Constructor & Destructor Documentation

BOARD_PRINTOUT_CONTROLLER::BOARD_PRINTOUT_CONTROLLER ( const PRINT_PARAMETERS aParams,
EDA_DRAW_FRAME aParent,
const wxString &  aTitle 
)

Definition at line 68 of file printout_controler.cpp.

References m_Parent, and m_PrintParams.

70  :
71  wxPrintout( aTitle )
72 {
73  m_PrintParams = aParams; // Make a local copy of the print parameters.
74  m_Parent = aParent;
75 }

Member Function Documentation

void BOARD_PRINTOUT_CONTROLLER::DrawPage ( const wxString &  aLayerName = wxEmptyString,
int  aPageNum = 1,
int  aPageCount = 1 
)

Print a page ( or a set of pages ).

Note: this function prepare print parameters for the function which actually print the draw layers.

Parameters
aLayerName= a text which can be printed as layer name
aPageNum= the number of the current page (only used to print this value)
aPageCount= the number of pages to ptint (only used to print this value)

Definition at line 135 of file printout_controler.cpp.

References PRINT_PARAMETERS::CenterOnBoardOutline(), EDA_RECT::Centre(), BOARD::ComputeBoundingBox(), EDA_DRAW_FRAME::DrawWorkSheet(), dummy(), FRAME_PCB_MODULE_EDITOR, BOARD_ITEM::GetBoard(), EDA_RECT::GetBottom(), EDA_DRAW_FRAME::GetCanvas(), EDA_DRAW_PANEL::GetClipBox(), EDA_DRAW_FRAME::GetDrawBgColor(), BOARD::GetFileName(), EDA_RECT::GetHeight(), EDA_DRAW_FRAME::GetPageSizeIU(), EDA_RECT::GetRight(), EDA_DRAW_FRAME::GetScreen(), EDA_RECT::GetSize(), EDA_RECT::GetWidth(), EDA_RECT::GetX(), EDA_RECT::GetY(), GRForceBlackPen(), GRResetPenAndBrush(), EDA_BASE_FRAME::IsType(), KiROUND(), BASE_SCREEN::m_IsPrinting, BASE_SCREEN::m_NumberOfScreens, PRINT_PARAMETERS::m_PageSetupData, m_Parent, PRINT_PARAMETERS::m_PenDefaultSize, PRINT_PARAMETERS::m_Print_Black_and_White, PRINT_PARAMETERS::m_PrintMaskLayer, PRINT_PARAMETERS::m_PrintMirror, m_PrintParams, PRINT_PARAMETERS::m_PrintScale, BASE_SCREEN::m_ScreenNumber, PRINT_PARAMETERS::m_XScaleAdjust, PRINT_PARAMETERS::m_YScaleAdjust, MAX_VALUE, EDA_RECT::Move(), PRINT_PARAMETERS::PrintBorderAndTitleBlock(), EDA_DRAW_FRAME::PrintPage(), EDA_DRAW_PANEL::SetClipBox(), EDA_DRAW_FRAME::SetDrawBgColor(), EDA_RECT::SetSize(), tracePrinting, WHITE, wxPoint::x, and wxPoint::y.

Referenced by OnPrintPage().

136 {
137  wxPoint offset;
138  double userscale;
139  EDA_RECT boardBoundingBox;
140  EDA_RECT drawRect;
141  wxDC* dc = GetDC();
142  BASE_SCREEN* screen = m_Parent->GetScreen();
143  bool printMirror = m_PrintParams.m_PrintMirror;
144  wxSize pageSizeIU = m_Parent->GetPageSizeIU();
145  int tempScreenNumber;
146  int tempNumberOfScreens;
147 
148  wxBusyCursor dummy;
149 
150  BOARD* brd = ((PCB_BASE_FRAME*) m_Parent)->GetBoard();
151  boardBoundingBox = brd->ComputeBoundingBox();
152  const wxString& titleblockFilename = brd->GetFileName();
153 
154  // Use the page size as the drawing area when the board is shown or the user scale
155  // is less than 1.
157  boardBoundingBox = EDA_RECT( wxPoint( 0, 0 ), pageSizeIU );
158 
159  wxLogTrace( tracePrinting, wxT( "Drawing bounding box: x=%d, y=%d, w=%d, h=%d" ),
160  boardBoundingBox.GetX(), boardBoundingBox.GetY(),
161  boardBoundingBox.GetWidth(), boardBoundingBox.GetHeight() );
162 
163  // Compute the PCB size in internal units
164  userscale = m_PrintParams.m_PrintScale;
165 
166  if( m_PrintParams.m_PrintScale == 0 ) // fit in page option
167  {
168  if( boardBoundingBox.GetWidth() && boardBoundingBox.GetHeight() )
169  {
170  int margin = Millimeter2iu( 10.0 ); // add a margin around the drawings
171  double scaleX = (double)(pageSizeIU.x - (2 * margin)) /
172  boardBoundingBox.GetWidth();
173  double scaleY = (double)(pageSizeIU.y - (2 * margin)) /
174  boardBoundingBox.GetHeight();
175  userscale = (scaleX < scaleY) ? scaleX : scaleY;
176  }
177  else
178  userscale = 1.0;
179  }
180 
181  wxSize scaledPageSize = pageSizeIU;
182  drawRect.SetSize( scaledPageSize );
183  scaledPageSize.x = wxRound( scaledPageSize.x / userscale );
184  scaledPageSize.y = wxRound( scaledPageSize.y / userscale );
185 
186 
188  {
189  wxLogTrace( tracePrinting, wxT( "Fit size to page margins: x=%d, y=%d" ),
190  scaledPageSize.x, scaledPageSize.y );
191 
192  // Always scale to the size of the paper.
193  FitThisSizeToPageMargins( scaledPageSize, *m_PrintParams.m_PageSetupData );
194  }
195 
196  // Compute Accurate scale 1
197  if( m_PrintParams.m_PrintScale == 1.0 )
198  {
199  // We want a 1:1 scale, regardless the page setup
200  // like page size, margin ...
201  MapScreenSizeToPaper(); // set best scale and offset (scale is not used)
202  int w, h;
203  GetPPIPrinter( &w, &h );
204  double accurate_Xscale = (double) w / (IU_PER_MILS*1000);
205  double accurate_Yscale = (double) h / (IU_PER_MILS*1000);
206 
207  if( IsPreview() ) // Scale must take in account the DC size in Preview
208  {
209  // Get the size of the DC in pixels
210  wxSize PlotAreaSize;
211  dc->GetSize( &PlotAreaSize.x, &PlotAreaSize.y );
212  GetPageSizePixels( &w, &h );
213  accurate_Xscale *= (double)PlotAreaSize.x / w;
214  accurate_Yscale *= (double)PlotAreaSize.y / h;
215  }
216  // Fine scale adjust
217  accurate_Xscale *= m_PrintParams.m_XScaleAdjust;
218  accurate_Yscale *= m_PrintParams.m_YScaleAdjust;
219 
220  // Set print scale for 1:1 exact scale
221  dc->SetUserScale( accurate_Xscale, accurate_Yscale );
222  }
223 
224  // Get the final size of the DC in pixels
225  wxSize PlotAreaSizeInPixels;
226  dc->GetSize( &PlotAreaSizeInPixels.x, &PlotAreaSizeInPixels.y );
227  wxLogTrace( tracePrinting, wxT( "Plot area in pixels: x=%d, y=%d" ),
228  PlotAreaSizeInPixels.x, PlotAreaSizeInPixels.y );
229  double scalex, scaley;
230  dc->GetUserScale( &scalex, &scaley );
231  wxLogTrace( tracePrinting, wxT( "DC user scale: x=%g, y=%g" ),
232  scalex, scaley );
233 
234  wxSize PlotAreaSizeInUserUnits;
235  PlotAreaSizeInUserUnits.x = KiROUND( PlotAreaSizeInPixels.x / scalex );
236  PlotAreaSizeInUserUnits.y = KiROUND( PlotAreaSizeInPixels.y / scaley );
237  wxLogTrace( tracePrinting, wxT( "Scaled plot area in user units: x=%d, y=%d" ),
238  PlotAreaSizeInUserUnits.x, PlotAreaSizeInUserUnits.y );
239 
240  // In module editor, the module is located at 0,0 but for printing
241  // it is moved to pageSizeIU.x/2, pageSizeIU.y/2.
242  // So the equivalent board must be moved to the center of the page:
244  {
245  boardBoundingBox.Move( wxPoint( pageSizeIU.x/2, pageSizeIU.y/2 ) );
246  }
247 
248  // In some cases the plot origin is the centre of the board outline rather than the center
249  // of the selected paper size.
251  {
252  // Here we are only drawing the board and it's contents.
253  drawRect = boardBoundingBox;
254  offset.x += wxRound( (double) -scaledPageSize.x / 2.0 );
255  offset.y += wxRound( (double) -scaledPageSize.y / 2.0 );
256 
257  wxPoint center = boardBoundingBox.Centre();
258 
259  if( printMirror )
260  {
261  // Calculate the mirrored center of the board.
262  center.x = m_Parent->GetPageSizeIU().x - boardBoundingBox.Centre().x;
263  }
264 
265  offset += center;
266  }
267 
268  GRResetPenAndBrush( dc );
269 
270  EDA_DRAW_PANEL* panel = m_Parent->GetCanvas();
271  EDA_RECT tmp = *panel->GetClipBox();
272 
273  // Set clip box to the max size
274  #define MAX_VALUE (INT_MAX/2) // MAX_VALUE is the max we can use in an integer
275  // and that allows calculations without overflow
276  panel->SetClipBox( EDA_RECT( wxPoint( 0, 0 ), wxSize( MAX_VALUE, MAX_VALUE ) ) );
277 
278  screen->m_IsPrinting = true;
279  COLOR4D bg_color = m_Parent->GetDrawBgColor();
280 
281  // Print frame reference, if requested, before
283  GRForceBlackPen( true );
284 
286  {
287  tempScreenNumber = screen->m_ScreenNumber;
288  tempNumberOfScreens = screen->m_NumberOfScreens;
289  screen->m_ScreenNumber = aPageNum;
290  screen->m_NumberOfScreens = aPageCount;
292  IU_PER_MILS, titleblockFilename, aLayerName );
293  screen->m_ScreenNumber = tempScreenNumber;
294  screen->m_NumberOfScreens = tempNumberOfScreens;
295  }
296 
297  if( printMirror )
298  {
299  // To plot mirror, we reverse the x axis, and modify the plot x origin
300  dc->SetAxisOrientation( false, false);
301 
302  /* Plot offset x is moved by the x plot area size in order to have
303  * the old draw area in the new draw area, because the draw origin has not moved
304  * (this is the upper left corner) but the X axis is reversed, therefore the plotting area
305  * is the x coordinate values from - PlotAreaSize.x to 0 */
306  int x_dc_offset = PlotAreaSizeInPixels.x;
307  x_dc_offset = KiROUND( x_dc_offset * userscale );
308  dc->SetDeviceOrigin( x_dc_offset, 0 );
309 
310  wxLogTrace( tracePrinting, wxT( "Device origin: x=%d, y=%d" ),
311  x_dc_offset, 0 );
312 
313  panel->SetClipBox( EDA_RECT( wxPoint( -MAX_VALUE/2, -MAX_VALUE/2 ),
314  panel->GetClipBox()->GetSize() ) );
315  }
316 
317  // screen->m_DrawOrg = offset;
318  dc->SetLogicalOrigin( offset.x, offset.y );
319 
320  wxLogTrace( tracePrinting, wxT( "Logical origin: x=%d, y=%d" ),
321  offset.x, offset.y );
322 
323 #if defined(wxUSE_LOG_TRACE) && defined( DEBUG )
324  wxRect paperRect = GetPaperRectPixels();
325  wxLogTrace( tracePrinting, wxT( "Paper rectangle: left=%d, top=%d, "
326  "right=%d, bottom=%d" ),
327  paperRect.GetLeft(), paperRect.GetTop(), paperRect.GetRight(),
328  paperRect.GetBottom() );
329 
330  int devLeft = dc->LogicalToDeviceX( drawRect.GetX() );
331  int devTop = dc->LogicalToDeviceY( drawRect.GetY() );
332  int devRight = dc->LogicalToDeviceX( drawRect.GetRight() );
333  int devBottom = dc->LogicalToDeviceY( drawRect.GetBottom() );
334  wxLogTrace( tracePrinting, wxT( "Final device rectangle: left=%d, top=%d, "
335  "right=%d, bottom=%d\n" ),
336  devLeft, devTop, devRight, devBottom );
337 #endif
338 
340 
341  /* when printing in color mode, we use the graphic OR mode that gives the same look as
342  * the screen but because the background is white when printing, we must use a trick:
343  * In order to plot on a white background in OR mode we must:
344  * 1 - Plot all items in black, this creates a local black background
345  * 2 - Plot in OR mode on black "local" background
346  */
348  {
349  // Creates a "local" black background
350  GRForceBlackPen( true );
352  printMirror, &m_PrintParams );
353  GRForceBlackPen( false );
354  }
355  else
356  GRForceBlackPen( true );
357 
358 
360  &m_PrintParams );
361 
362  m_Parent->SetDrawBgColor( bg_color );
363  screen->m_IsPrinting = false;
364  panel->SetClipBox( tmp );
365  GRForceBlackPen( false );
366 }
void GRResetPenAndBrush(wxDC *DC)
Definition: gr_basic.cpp:218
void Move(const wxPoint &aMoveVector)
Function Move moves the rectangle by the aMoveVector.
int m_ScreenNumber
Definition: base_screen.h:216
static int KiROUND(double v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: common.h:120
EDA_DRAW_PANEL * GetCanvas()
Definition: draw_frame.h:377
const wxSize GetSize() const
Definition: eda_rect.h:101
EDA_RECT ComputeBoundingBox(bool aBoardEdgesOnly=false) const
Function ComputeBoundingBox calculates the bounding box containing all board items (or board edge seg...
const wxChar *const tracePrinting
Flag to enable print controller debug output.
bool PrintBorderAndTitleBlock() const
Function PrintBorderAndTitleBlock returns true if the drawing border and title block should be printe...
int GetHeight() const
Definition: eda_rect.h:118
virtual void SetDrawBgColor(COLOR4D aColor)
Definition: draw_frame.h:369
virtual const wxSize GetPageSizeIU() const =0
Function GetPageSizeIU works off of GetPageSettings() to return the size of the paper page in the int...
void SetClipBox(const EDA_RECT &aRect)
virtual BASE_SCREEN * GetScreen() const
Function GetScreen returns a pointer to a BASE_SCREEN or one of its derivatives.
Definition: draw_frame.h:387
virtual COLOR4D GetDrawBgColor() const
Definition: draw_frame.h:364
virtual void PrintPage(wxDC *aDC, LSET aPrintMask, bool aPrintMirrorMode, void *aData=NULL)
Function PrintPage used to print a page Print the page pointed by current screen, set by the calling ...
Definition: draw_frame.cpp:468
void GRForceBlackPen(bool flagforce)
Function GRForceBlackPen.
Definition: gr_basic.cpp:299
const wxString & GetFileName() const
Definition: class_board.h:236
Class BASE_SCREEN handles how to draw a screen (a board, a schematic ...)
Definition: base_screen.h:76
EDA_RECT * GetClipBox()
int GetBottom() const
Definition: eda_rect.h:122
wxPoint Centre() const
Definition: eda_rect.h:60
int GetRight() const
Definition: eda_rect.h:119
bool m_IsPrinting
Definition: base_screen.h:220
wxPageSetupDialogData * m_PageSetupData
void SetSize(const wxSize &size)
Definition: eda_rect.h:126
#define MAX_VALUE
static LIB_PART * dummy()
Used when a LIB_PART is not found in library to draw a dummy shape This component is a 400 mils squar...
Class BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:169
Class EDA_RECT handles the component boundary box.
Definition: eda_rect.h:44
int GetX() const
Definition: eda_rect.h:109
int GetWidth() const
Definition: eda_rect.h:117
bool CenterOnBoardOutline() const
Function CenterOnBoardOutline returns true if the print should be centered by the board outline inste...
Definition: colors.h:49
int GetY() const
Definition: eda_rect.h:110
virtual BOARD * GetBoard() const
Function GetBoard returns the BOARD in which this BOARD_ITEM resides, or NULL if none.
int m_NumberOfScreens
Definition: base_screen.h:217
bool IsType(FRAME_T aType) const
void DrawWorkSheet(wxDC *aDC, BASE_SCREEN *aScreen, int aLineWidth, double aScale, const wxString &aFilename, const wxString &aSheetLayer=wxEmptyString)
Function DrawWorkSheet Draws on screen the page layout with the frame and the basic inscriptions...
Definition: worksheet.cpp:76
class PCB_BASE_FRAME basic PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer...
Class COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39
void BOARD_PRINTOUT_CONTROLLER::GetPageInfo ( int *  minPage,
int *  maxPage,
int *  selPageFrom,
int *  selPageTo 
)
override

Definition at line 119 of file printout_controler.cpp.

References PRINT_PARAMETERS::m_OptionPrintPage, PRINT_PARAMETERS::m_PageCount, and m_PrintParams.

121 {
122  *minPage = 1;
123  *selPageFrom = 1;
124 
125  int icnt = 1;
126 
128  icnt = m_PrintParams.m_PageCount;
129 
130  *maxPage = icnt;
131  *selPageTo = icnt;
132 }
bool BOARD_PRINTOUT_CONTROLLER::HasPage ( int  aPage)
inlineoverride

Definition at line 116 of file printout_controler.h.

References PRINT_PARAMETERS::m_PageCount.

117  {
118  if( aPage <= m_PrintParams.m_PageCount )
119  return true;
120  else
121  return false;
122  }
bool BOARD_PRINTOUT_CONTROLLER::OnPrintPage ( int  aPage)
override

Definition at line 78 of file printout_controler.cpp.

References DrawPage(), Edge_Cuts, LSET::ExtractLayer(), PRINT_PARAMETERS::m_Flags, PRINT_PARAMETERS::m_OptionPrintPage, PRINT_PARAMETERS::m_PrintMaskLayer, m_PrintParams, LSET::Name(), LSET::UIOrder(), and UNDEFINED_LAYER.

79 {
81  int pageCount = lset.count();
82  wxString layer;
83  PCB_LAYER_ID extractLayer;
84 
85  // compute layer mask from page number if we want one page per layer
86  if( m_PrintParams.m_OptionPrintPage == 0 ) // One page per layer
87  {
88  // This sequence is TBD, call a different
89  // sequencer if needed, such as Seq(). Could not find documentation on
90  // page order.
91  LSEQ seq = lset.UIOrder();
92 
93  // aPage starts at 1, not 0
94  if( unsigned( aPage-1 ) < seq.size() )
95  m_PrintParams.m_PrintMaskLayer = LSET( seq[aPage-1] );
96  }
97 
98  if( !m_PrintParams.m_PrintMaskLayer.any() )
99  return false;
100 
102  if( extractLayer == UNDEFINED_LAYER )
103  layer = _( "Multiple Layers" );
104  else
105  layer = LSET::Name( extractLayer );
106 
107  // In Pcbnew we can want the layer EDGE always printed
108  if( m_PrintParams.m_Flags == 1 )
110 
111  DrawPage( layer, aPage, pageCount );
112 
114 
115  return true;
116 }
void DrawPage(const wxString &aLayerName=wxEmptyString, int aPageNum=1, int aPageCount=1)
Print a page ( or a set of pages ).
PCB_LAYER_ID ExtractLayer() const
Find the first set PCB_LAYER_ID.
Definition: lset.cpp:612
PCB_LAYER_ID
A quick note on layer IDs:
Class LSET is a set of PCB_LAYER_IDs.
static const wxChar * Name(PCB_LAYER_ID aLayerId)
Function Name returns the fixed name association with aLayerId.
Definition: lset.cpp:73
Class LSEQ is a sequence (and therefore also a set) of PCB_LAYER_IDs.
LSEQ UIOrder() const
Definition: lset.cpp:793

Member Data Documentation

EDA_DRAW_FRAME* BOARD_PRINTOUT_CONTROLLER::m_Parent
private

Definition at line 106 of file printout_controler.h.

Referenced by BOARD_PRINTOUT_CONTROLLER(), and DrawPage().

PRINT_PARAMETERS BOARD_PRINTOUT_CONTROLLER::m_PrintParams
private

The documentation for this class was generated from the following files: