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 75 of file printout_controler.cpp.

References m_Parent, and m_PrintParams.

77  :
78  wxPrintout( aTitle )
79 {
80  m_PrintParams = aParams; // Make a local copy of the print parameters.
81  m_Parent = aParent;
82 }

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 142 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().

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

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

128 {
129  *minPage = 1;
130  *selPageFrom = 1;
131 
132  int icnt = 1;
133 
135  icnt = m_PrintParams.m_PageCount;
136 
137  *maxPage = icnt;
138  *selPageTo = icnt;
139 }
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 85 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.

86 {
88  int pageCount = lset.count();
89  wxString layer;
90  PCB_LAYER_ID extractLayer;
91 
92  // compute layer mask from page number if we want one page per layer
93  if( m_PrintParams.m_OptionPrintPage == 0 ) // One page per layer
94  {
95  // This sequence is TBD, call a different
96  // sequencer if needed, such as Seq(). Could not find documentation on
97  // page order.
98  LSEQ seq = lset.UIOrder();
99 
100  // aPage starts at 1, not 0
101  if( unsigned( aPage-1 ) < seq.size() )
102  m_PrintParams.m_PrintMaskLayer = LSET( seq[aPage-1] );
103  }
104 
105  if( !m_PrintParams.m_PrintMaskLayer.any() )
106  return false;
107 
109  if( extractLayer == UNDEFINED_LAYER )
110  layer = _( "Multiple Layers" );
111  else
112  layer = LSET::Name( extractLayer );
113 
114  // In Pcbnew we can want the layer EDGE always printed
115  if( m_PrintParams.m_Flags == 1 )
117 
118  DrawPage( layer, aPage, pageCount );
119 
121 
122  return true;
123 }
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:578
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:752

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: