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

References m_Parent, and m_PrintParams.

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

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

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

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

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

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