1 /////////////////////////////////////////////////////////////////////////////
2 // Name: samples/printing.cpp
3 // Purpose: Printing demo for wxWidgets
4 // Author: Julian Smart
5 // Modified by: Francesco Montorsi
6 // Created: 1995
7 // Copyright: (c) Julian Smart
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
11 // For compilers that support precompilation, includes "wx/wx.h".
12 #include "wx/wxprec.h"
13
14
15 #ifndef WX_PRECOMP
16 #include "wx/wx.h"
17 #include "wx/log.h"
18 #endif
19
20 #if !wxUSE_PRINTING_ARCHITECTURE
21 #error "You must set wxUSE_PRINTING_ARCHITECTURE to 1 in setup.h, and recompile the library."
22 #endif
23
24 #include <ctype.h>
25 #include "wx/metafile.h"
26 #include "wx/print.h"
27 #include "wx/printdlg.h"
28 #include "wx/image.h"
29 #include "wx/accel.h"
30
31 #if wxUSE_POSTSCRIPT
32 #include "wx/generic/printps.h"
33 #include "wx/generic/prntdlgg.h"
34 #endif
35
36 #if wxUSE_GRAPHICS_CONTEXT
37 #include "wx/graphics.h"
38 #include "wx/scopedptr.h"
39 #endif
40
41 #ifdef __WXMAC__
42 #include "wx/osx/printdlg.h"
43 #endif
44
45 #include "printing.h"
46
47 #ifndef wxHAS_IMAGES_IN_RESOURCES
48 #include "../sample.xpm"
49 #endif
50
51 // Global print data, to remember settings during the session
52 wxPrintData *g_printData = NULL;
53
54 // Global page setup data
55 wxPageSetupDialogData* g_pageSetupData = NULL;
56
57
58
59 // ----------------------------------------------------------------------------
60 // MyApp
61 // ----------------------------------------------------------------------------
62
63 wxIMPLEMENT_APP(MyApp);
64
OnInit(void)65 bool MyApp::OnInit(void)
66 {
67 if ( !wxApp::OnInit() )
68 return false;
69
70 wxInitAllImageHandlers();
71
72
73 // init global objects
74 // -------------------
75
76 g_printData = new wxPrintData;
77
78 // You could set an initial paper size here
79 #if 0
80 g_printData->SetPaperId(wxPAPER_LETTER); // for Americans
81 g_printData->SetPaperId(wxPAPER_A4); // for everyone else
82 #endif
83
84 g_pageSetupData = new wxPageSetupDialogData;
85
86 // copy over initial paper size from print record
87 (*g_pageSetupData) = *g_printData;
88
89 // Set some initial page margins in mm.
90 g_pageSetupData->SetMarginTopLeft(wxPoint(15, 15));
91 g_pageSetupData->SetMarginBottomRight(wxPoint(15, 15));
92
93
94 // init local GUI objects
95 // ----------------------
96
97 #if 0
98 wxImage image( "test.jpg" );
99 image.SetAlpha();
100 int i,j;
101 for (i = 0; i < image.GetWidth(); i++)
102 for (j = 0; j < image.GetHeight(); j++)
103 image.SetAlpha( i, j, 50 );
104 m_bitmap = image;
105 #endif
106 m_angle = 30;
107 m_testFont = wxFontInfo(10).Family(wxFONTFAMILY_SWISS);
108
109
110 // Create the main frame window
111 // ----------------------------
112
113 MyFrame* frame = new MyFrame((wxFrame *) NULL, "wxWidgets Printing Demo",
114 wxPoint(0, 0), wxSize(400, 400));
115
116 frame->Centre(wxBOTH);
117 frame->Show();
118
119 return true;
120 }
121
OnExit()122 int MyApp::OnExit()
123 {
124 delete g_printData;
125 delete g_pageSetupData;
126
127 return wxApp::OnExit();
128 }
129
Draw(wxDC & dc)130 void MyApp::Draw(wxDC&dc)
131 {
132 // This routine just draws a bunch of random stuff on the screen so that we
133 // can check that different types of object are being drawn consistently
134 // between the screen image, the print preview image (at various zoom
135 // levels), and the printed page.
136 dc.SetBackground(*wxWHITE_BRUSH);
137 // dc.Clear();
138 dc.SetFont(m_testFont);
139
140 // dc.SetBackgroundMode(wxBRUSHSTYLE_TRANSPARENT);
141
142 dc.SetPen(*wxBLACK_PEN);
143 dc.SetBrush(*wxLIGHT_GREY_BRUSH);
144
145 dc.DrawRectangle(0, 0, 230, 350);
146 dc.DrawLine(0, 0, 229, 349);
147 dc.DrawLine(229, 0, 0, 349);
148 dc.SetBrush(*wxTRANSPARENT_BRUSH);
149
150 dc.SetBrush(*wxCYAN_BRUSH);
151 dc.SetPen(*wxRED_PEN);
152
153 dc.DrawRoundedRectangle(0, 20, 200, 80, 20);
154
155 dc.DrawText( "Rectangle 200 by 80", 40, 40);
156
157 dc.SetPen( wxPen(*wxBLACK, 0, wxPENSTYLE_DOT_DASH) );
158 dc.DrawEllipse(50, 140, 100, 50);
159 dc.SetPen(*wxRED_PEN);
160
161 dc.DrawText( "Test message: this is in 10 point text", 10, 180);
162
163 dc.DrawRotatedText( "This\nis\na multi-line\ntext", 170, 100, -m_angle/1.5);
164
165 #if wxUSE_UNICODE
166 const char *test = "Hebrew שלום -- Japanese (日本語)";
167 wxString tmp = wxConvUTF8.cMB2WC( test );
168 dc.DrawText( tmp, 10, 200 );
169 #endif
170
171 wxPoint points[5];
172 points[0].x = 0;
173 points[0].y = 0;
174 points[1].x = 20;
175 points[1].y = 0;
176 points[2].x = 20;
177 points[2].y = 20;
178 points[3].x = 10;
179 points[3].y = 20;
180 points[4].x = 10;
181 points[4].y = -20;
182 dc.DrawPolygon( 5, points, 20, 250, wxODDEVEN_RULE );
183 dc.DrawPolygon( 5, points, 50, 250, wxWINDING_RULE );
184
185 dc.DrawArc( 20, 330, 40, 300, 20, 300 );
186 {
187 wxDCBrushChanger changeBrush(dc, *wxTRANSPARENT_BRUSH);
188 dc.DrawArc( 60, 330, 80, 300, 60, 300 );
189 }
190
191 dc.DrawEllipticArc( 80, 250, 60, 30, 0.0, 270.0 );
192
193 points[0].x = 150;
194 points[0].y = 250;
195 points[1].x = 180;
196 points[1].y = 250;
197 points[2].x = 180;
198 points[2].y = 220;
199 points[3].x = 200;
200 points[3].y = 220;
201 dc.DrawSpline( 4, points );
202
203 wxString str;
204 int i = 0;
205 str.Printf( "---- Text at angle %d ----", i );
206 dc.DrawRotatedText( str, 100, 300, i );
207
208 i = m_angle;
209 str.Printf( "---- Text at angle %d ----", i );
210 dc.DrawRotatedText( str, 100, 300, i );
211
212 wxIcon my_icon = wxICON(sample);
213
214 dc.DrawIcon( my_icon, 100, 100);
215
216 if (m_bitmap.IsOk())
217 dc.DrawBitmap( m_bitmap, 10, 10 );
218
219 #if wxUSE_GRAPHICS_CONTEXT
220 wxScopedPtr<wxGraphicsContext> gc(wxGraphicsContext::CreateFromUnknownDC(dc));
221
222 if (gc)
223 {
224 // make a path that contains a circle and some lines, centered at 100,100
225 gc->SetPen( *wxRED_PEN );
226
227 wxGraphicsPath path = gc->CreatePath();
228 path.AddCircle( 50.0, 50.0, 50.0 );
229 path.MoveToPoint(0.0, 50.0);
230 path.AddLineToPoint(100.0, 50.0);
231 path.MoveToPoint(50.0, 0.0);
232 path.AddLineToPoint(50.0, 100.0 );
233 path.CloseSubpath();
234 path.AddRectangle(25.0, 25.0, 50.0, 50.0);
235
236 gc->StrokePath(path);
237
238 // draw some text
239 wxString text("Text by wxGraphicsContext");
240 gc->SetFont( m_testFont, *wxBLACK );
241 gc->DrawText(text, 25.0, 60.0);
242
243 // draw rectangle around the text
244 double w, h;
245 gc->GetTextExtent(text, &w, &h);
246 gc->SetPen( *wxBLACK_PEN );
247 gc->DrawRectangle(25.0, 60.0, w, h);
248 }
249 #endif
250
251 }
252
253
254 // ----------------------------------------------------------------------------
255 // MyFrame
256 // ----------------------------------------------------------------------------
257
wxBEGIN_EVENT_TABLE(MyFrame,wxFrame)258 wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
259 EVT_MENU(wxID_EXIT, MyFrame::OnExit)
260 EVT_MENU(wxID_PRINT, MyFrame::OnPrint)
261 EVT_MENU(wxID_PREVIEW, MyFrame::OnPrintPreview)
262 EVT_MENU(WXPRINT_PAGE_SETUP, MyFrame::OnPageSetup)
263 EVT_MENU(wxID_ABOUT, MyFrame::OnPrintAbout)
264 #if wxUSE_POSTSCRIPT
265 EVT_MENU(WXPRINT_PRINT_PS, MyFrame::OnPrintPS)
266 EVT_MENU(WXPRINT_PREVIEW_PS, MyFrame::OnPrintPreviewPS)
267 EVT_MENU(WXPRINT_PAGE_SETUP_PS, MyFrame::OnPageSetupPS)
268 #endif
269 #ifdef __WXMAC__
270 EVT_MENU(WXPRINT_PAGE_MARGINS, MyFrame::OnPageMargins)
271 #endif
272 EVT_MENU(WXPRINT_ANGLEUP, MyFrame::OnAngleUp)
273 EVT_MENU(WXPRINT_ANGLEDOWN, MyFrame::OnAngleDown)
274
275 EVT_MENU_RANGE(WXPRINT_FRAME_MODAL_APP,
276 WXPRINT_FRAME_MODAL_NON,
277 MyFrame::OnPreviewFrameModalityKind)
278 wxEND_EVENT_TABLE()
279
280 MyFrame::MyFrame(wxFrame *frame, const wxString&title, const wxPoint&pos, const wxSize&size)
281 : wxFrame(frame, wxID_ANY, title, pos, size)
282 {
283 m_canvas = NULL;
284 m_previewModality = wxPreviewFrame_AppModal;
285
286 #if wxUSE_STATUSBAR
287 // Give us a status line
288 CreateStatusBar(2);
289 SetStatusText("Printing demo");
290 #endif // wxUSE_STATUSBAR
291
292 // Load icon and bitmap
293 SetIcon( wxICON( sample) );
294
295 // Make a menubar
296 wxMenu *file_menu = new wxMenu;
297
298 file_menu->Append(wxID_PRINT, "&Print...", "Print");
299 file_menu->Append(WXPRINT_PAGE_SETUP, "Page Set&up...", "Page setup");
300 #ifdef __WXMAC__
301 file_menu->Append(WXPRINT_PAGE_MARGINS, "Page Margins...", "Page margins");
302 #endif
303 file_menu->Append(wxID_PREVIEW, "Print Pre&view", "Preview");
304
305 wxMenu * const menuModalKind = new wxMenu;
306 menuModalKind->AppendRadioItem(WXPRINT_FRAME_MODAL_APP, "&App modal");
307 menuModalKind->AppendRadioItem(WXPRINT_FRAME_MODAL_WIN, "&Window modal");
308 menuModalKind->AppendRadioItem(WXPRINT_FRAME_MODAL_NON, "&Not modal");
309 file_menu->AppendSubMenu(menuModalKind, "Preview frame &modal kind");
310 #if wxUSE_ACCEL
311 // Accelerators
312 wxAcceleratorEntry entries[1];
313 entries[0].Set(wxACCEL_CTRL, (int) 'V', wxID_PREVIEW);
314 wxAcceleratorTable accel(1, entries);
315 SetAcceleratorTable(accel);
316 #endif
317
318 #if wxUSE_POSTSCRIPT
319 file_menu->AppendSeparator();
320 file_menu->Append(WXPRINT_PRINT_PS, "Print PostScript...", "Print (PostScript)");
321 file_menu->Append(WXPRINT_PAGE_SETUP_PS, "Page Setup PostScript...", "Page setup (PostScript)");
322 file_menu->Append(WXPRINT_PREVIEW_PS, "Print Preview PostScript", "Preview (PostScript)");
323 #endif
324
325 file_menu->AppendSeparator();
326 file_menu->Append(WXPRINT_ANGLEUP, "Angle up\tAlt-U", "Raise rotated text angle");
327 file_menu->Append(WXPRINT_ANGLEDOWN, "Angle down\tAlt-D", "Lower rotated text angle");
328 file_menu->AppendSeparator();
329 file_menu->Append(wxID_EXIT, "E&xit", "Exit program");
330
331 wxMenu *help_menu = new wxMenu;
332 help_menu->Append(wxID_ABOUT, "&About", "About this demo");
333
334 wxMenuBar *menu_bar = new wxMenuBar;
335
336 menu_bar->Append(file_menu, "&File");
337 menu_bar->Append(help_menu, "&Help");
338
339 // Associate the menu bar with the frame
340 SetMenuBar(menu_bar);
341
342
343 // create the canvas
344 // -----------------
345
346 m_canvas = new MyCanvas(this, wxPoint(0, 0), wxSize(100, 100),
347 wxRETAINED|wxHSCROLL|wxVSCROLL);
348
349 // Give it scrollbars: the virtual canvas is 20 * 50 = 1000 pixels in each direction
350 m_canvas->SetScrollbars(20, 20, 50, 50);
351 }
352
OnExit(wxCommandEvent & WXUNUSED (event))353 void MyFrame::OnExit(wxCommandEvent& WXUNUSED(event))
354 {
355 Close(true /*force closing*/);
356 }
357
OnPrint(wxCommandEvent & WXUNUSED (event))358 void MyFrame::OnPrint(wxCommandEvent& WXUNUSED(event))
359 {
360 wxPrintDialogData printDialogData(* g_printData);
361
362 wxPrinter printer(&printDialogData);
363 MyPrintout printout(this, "My printout");
364 if (!printer.Print(this, &printout, true /*prompt*/))
365 {
366 if (wxPrinter::GetLastError() == wxPRINTER_ERROR)
367 {
368 wxLogError("There was a problem printing. Perhaps your current printer is not set correctly?");
369 }
370 else
371 {
372 wxLogMessage("You canceled printing");
373 }
374 }
375 else
376 {
377 (*g_printData) = printer.GetPrintDialogData().GetPrintData();
378 }
379 }
380
OnPrintPreview(wxCommandEvent & WXUNUSED (event))381 void MyFrame::OnPrintPreview(wxCommandEvent& WXUNUSED(event))
382 {
383 // Pass two printout objects: for preview, and possible printing.
384 wxPrintDialogData printDialogData(* g_printData);
385 wxPrintPreview *preview =
386 new wxPrintPreview(new MyPrintout(this), new MyPrintout(this), &printDialogData);
387 if (!preview->IsOk())
388 {
389 delete preview;
390 wxLogError("There was a problem previewing.\nPerhaps your current printer is not set correctly?");
391 return;
392 }
393
394 wxPreviewFrame *frame =
395 new wxPreviewFrame(preview, this, "Demo Print Preview", wxPoint(100, 100), wxSize(600, 650));
396 frame->Centre(wxBOTH);
397 frame->InitializeWithModality(m_previewModality);
398 frame->Show();
399 }
400
OnPageSetup(wxCommandEvent & WXUNUSED (event))401 void MyFrame::OnPageSetup(wxCommandEvent& WXUNUSED(event))
402 {
403 (*g_pageSetupData) = *g_printData;
404
405 wxPageSetupDialog pageSetupDialog(this, g_pageSetupData);
406 pageSetupDialog.ShowModal();
407
408 (*g_printData) = pageSetupDialog.GetPageSetupDialogData().GetPrintData();
409 (*g_pageSetupData) = pageSetupDialog.GetPageSetupDialogData();
410 }
411
412 #if wxUSE_POSTSCRIPT
OnPrintPS(wxCommandEvent & WXUNUSED (event))413 void MyFrame::OnPrintPS(wxCommandEvent& WXUNUSED(event))
414 {
415 wxPrintDialogData printDialogData(* g_printData);
416
417 wxPostScriptPrinter printer(&printDialogData);
418 MyPrintout printout(this, "My printout");
419 printer.Print(this, &printout, true/*prompt*/);
420
421 (*g_printData) = printer.GetPrintDialogData().GetPrintData();
422 }
423
OnPrintPreviewPS(wxCommandEvent & WXUNUSED (event))424 void MyFrame::OnPrintPreviewPS(wxCommandEvent& WXUNUSED(event))
425 {
426 // Pass two printout objects: for preview, and possible printing.
427 wxPrintDialogData printDialogData(* g_printData);
428 wxPrintPreview *preview = new wxPrintPreview(new MyPrintout(this), new MyPrintout(this), &printDialogData);
429 wxPreviewFrame *frame =
430 new wxPreviewFrame(preview, this, "Demo Print Preview", wxPoint(100, 100), wxSize(600, 650));
431 frame->Centre(wxBOTH);
432 frame->Initialize();
433 frame->Show();
434 }
435
OnPageSetupPS(wxCommandEvent & WXUNUSED (event))436 void MyFrame::OnPageSetupPS(wxCommandEvent& WXUNUSED(event))
437 {
438 (*g_pageSetupData) = * g_printData;
439
440 wxGenericPageSetupDialog pageSetupDialog(this, g_pageSetupData);
441 pageSetupDialog.ShowModal();
442
443 (*g_printData) = pageSetupDialog.GetPageSetupDialogData().GetPrintData();
444 (*g_pageSetupData) = pageSetupDialog.GetPageSetupDialogData();
445 }
446 #endif
447
448 #ifdef __WXMAC__
OnPageMargins(wxCommandEvent & WXUNUSED (event))449 void MyFrame::OnPageMargins(wxCommandEvent& WXUNUSED(event))
450 {
451 (*g_pageSetupData) = *g_printData;
452
453 wxMacPageMarginsDialog pageMarginsDialog(this, g_pageSetupData);
454 pageMarginsDialog.ShowModal();
455
456 (*g_printData) = pageMarginsDialog.GetPageSetupDialogData().GetPrintData();
457 (*g_pageSetupData) = pageMarginsDialog.GetPageSetupDialogData();
458 }
459 #endif
460
OnPrintAbout(wxCommandEvent & WXUNUSED (event))461 void MyFrame::OnPrintAbout(wxCommandEvent& WXUNUSED(event))
462 {
463 (void)wxMessageBox("wxWidgets printing demo\nAuthor: Julian Smart",
464 "About wxWidgets printing demo", wxOK|wxCENTRE);
465 }
466
OnAngleUp(wxCommandEvent & WXUNUSED (event))467 void MyFrame::OnAngleUp(wxCommandEvent& WXUNUSED(event))
468 {
469 wxGetApp().IncrementAngle();
470 m_canvas->Refresh();
471 }
472
OnAngleDown(wxCommandEvent & WXUNUSED (event))473 void MyFrame::OnAngleDown(wxCommandEvent& WXUNUSED(event))
474 {
475 wxGetApp().DecrementAngle();
476 m_canvas->Refresh();
477 }
478
OnPreviewFrameModalityKind(wxCommandEvent & event)479 void MyFrame::OnPreviewFrameModalityKind(wxCommandEvent& event)
480 {
481 m_previewModality = static_cast<wxPreviewFrameModalityKind>(
482 wxPreviewFrame_AppModal +
483 (event.GetId() - WXPRINT_FRAME_MODAL_APP));
484 }
485
486 // ----------------------------------------------------------------------------
487 // MyCanvas
488 // ----------------------------------------------------------------------------
489
wxBEGIN_EVENT_TABLE(MyCanvas,wxScrolledWindow)490 wxBEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow)
491 // EVT_PAINT(MyCanvas::OnPaint)
492 wxEND_EVENT_TABLE()
493
494 MyCanvas::MyCanvas(wxFrame *frame, const wxPoint&pos, const wxSize&size, long style)
495 : wxScrolledWindow(frame, wxID_ANY, pos, size, style)
496 {
497 SetBackgroundColour(*wxWHITE);
498 }
499
500 //void MyCanvas::OnPaint(wxPaintEvent& WXUNUSED(evt))
OnDraw(wxDC & dc)501 void MyCanvas::OnDraw(wxDC& dc)
502 {
503 //wxPaintDC dc(this);
504 wxGetApp().Draw(dc);
505 }
506
507
508 // ----------------------------------------------------------------------------
509 // MyPrintout
510 // ----------------------------------------------------------------------------
511
OnPrintPage(int page)512 bool MyPrintout::OnPrintPage(int page)
513 {
514 wxDC *dc = GetDC();
515 if (dc)
516 {
517 if (page == 1)
518 DrawPageOne();
519 else if (page == 2)
520 DrawPageTwo();
521
522 // Draw page numbers at top left corner of printable area, sized so that
523 // screen size of text matches paper size.
524 MapScreenSizeToPage();
525
526 dc->DrawText(wxString::Format("PAGE %d", page), 0, 0);
527
528 return true;
529 }
530 else
531 return false;
532 }
533
OnBeginDocument(int startPage,int endPage)534 bool MyPrintout::OnBeginDocument(int startPage, int endPage)
535 {
536 if (!wxPrintout::OnBeginDocument(startPage, endPage))
537 return false;
538
539 return true;
540 }
541
GetPageInfo(int * minPage,int * maxPage,int * selPageFrom,int * selPageTo)542 void MyPrintout::GetPageInfo(int *minPage, int *maxPage, int *selPageFrom, int *selPageTo)
543 {
544 *minPage = 1;
545 *maxPage = 2;
546 *selPageFrom = 1;
547 *selPageTo = 2;
548 }
549
HasPage(int pageNum)550 bool MyPrintout::HasPage(int pageNum)
551 {
552 return (pageNum == 1 || pageNum == 2);
553 }
554
DrawPageOne()555 void MyPrintout::DrawPageOne()
556 {
557 // You might use THIS code if you were scaling graphics of known size to fit
558 // on the page. The commented-out code illustrates different ways of scaling
559 // the graphics.
560
561 // We know the graphic is 230x350. If we didn't know this, we'd need to
562 // calculate it.
563 wxCoord maxX = 230;
564 wxCoord maxY = 350;
565
566 // This sets the user scale and origin of the DC so that the image fits
567 // within the paper rectangle (but the edges could be cut off by printers
568 // that can't print to the edges of the paper -- which is most of them. Use
569 // this if your image already has its own margins.
570 // FitThisSizeToPaper(wxSize(maxX, maxY));
571 // wxRect fitRect = GetLogicalPaperRect();
572
573 // This sets the user scale and origin of the DC so that the image fits
574 // within the page rectangle, which is the printable area on Mac and MSW
575 // and is the entire page on other platforms.
576 // FitThisSizeToPage(wxSize(maxX, maxY));
577 // wxRect fitRect = GetLogicalPageRect();
578
579 // This sets the user scale and origin of the DC so that the image fits
580 // within the page margins as specified by g_PageSetupData, which you can
581 // change (on some platforms, at least) in the Page Setup dialog. Note that
582 // on Mac, the native Page Setup dialog doesn't let you change the margins
583 // of a wxPageSetupDialogData object, so you'll have to write your own dialog or
584 // use the Mac-only wxMacPageMarginsDialog, as we do in this program.
585 FitThisSizeToPageMargins(wxSize(maxX, maxY), *g_pageSetupData);
586 wxRect fitRect = GetLogicalPageMarginsRect(*g_pageSetupData);
587
588 // This sets the user scale and origin of the DC so that the image appears
589 // on the paper at the same size that it appears on screen (i.e., 10-point
590 // type on screen is 10-point on the printed page) and is positioned in the
591 // top left corner of the page rectangle (just as the screen image appears
592 // in the top left corner of the window).
593 // MapScreenSizeToPage();
594 // wxRect fitRect = GetLogicalPageRect();
595
596 // You could also map the screen image to the entire paper at the same size
597 // as it appears on screen.
598 // MapScreenSizeToPaper();
599 // wxRect fitRect = GetLogicalPaperRect();
600
601 // You might also wish to do you own scaling in order to draw objects at
602 // full native device resolution. In this case, you should do the following.
603 // Note that you can use the GetLogicalXXXRect() commands to obtain the
604 // appropriate rect to scale to.
605 // MapScreenSizeToDevice();
606 // wxRect fitRect = GetLogicalPageRect();
607
608 // Each of the preceding Fit or Map routines positions the origin so that
609 // the drawn image is positioned at the top left corner of the reference
610 // rectangle. You can easily center or right- or bottom-justify the image as
611 // follows.
612
613 // This offsets the image so that it is centered within the reference
614 // rectangle defined above.
615 wxCoord xoff = (fitRect.width - maxX) / 2;
616 wxCoord yoff = (fitRect.height - maxY) / 2;
617 OffsetLogicalOrigin(xoff, yoff);
618
619 // This offsets the image so that it is positioned at the bottom right of
620 // the reference rectangle defined above.
621 // wxCoord xoff = (fitRect.width - maxX);
622 // wxCoord yoff = (fitRect.height - maxY);
623 // OffsetLogicalOrigin(xoff, yoff);
624
625 wxGetApp().Draw(*GetDC());
626 }
627
DrawPageTwo()628 void MyPrintout::DrawPageTwo()
629 {
630 // You might use THIS code to set the printer DC to ROUGHLY reflect
631 // the screen text size. This page also draws lines of actual length
632 // 5cm on the page.
633
634 // Compare this to DrawPageOne(), which uses the really convenient routines
635 // from wxPrintout to fit the screen image onto the printed page. This page
636 // illustrates how to do all the scaling calculations yourself, if you're so
637 // inclined.
638
639 wxDC *dc = GetDC();
640
641 // Get the logical pixels per inch of screen and printer
642 int ppiScreenX, ppiScreenY;
643 GetPPIScreen(&ppiScreenX, &ppiScreenY);
644 int ppiPrinterX, ppiPrinterY;
645 GetPPIPrinter(&ppiPrinterX, &ppiPrinterY);
646
647 // This scales the DC so that the printout roughly represents the screen
648 // scaling. The text point size _should_ be the right size but in fact is
649 // too small for some reason. This is a detail that will need to be
650 // addressed at some point but can be fudged for the moment.
651 double scale = double(ppiPrinterX) / ppiScreenX;
652
653 // Now we have to check in case our real page size is reduced (e.g. because
654 // we're drawing to a print preview memory DC)
655 int pageWidth, pageHeight;
656 int w, h;
657 dc->GetSize(&w, &h);
658 GetPageSizePixels(&pageWidth, &pageHeight);
659
660 // If printer pageWidth == current DC width, then this doesn't change. But w
661 // might be the preview bitmap width, so scale down.
662 double overallScale = scale * w / pageWidth;
663 dc->SetUserScale(overallScale, overallScale);
664
665 // Calculate conversion factor for converting millimetres into logical
666 // units. There are approx. 25.4 mm to the inch. There are ppi device units
667 // to the inch. Therefore 1 mm corresponds to ppi/25.4 device units. We also
668 // divide by the screen-to-printer scaling factor, because we need to
669 // unscale to pass logical units to DrawLine.
670
671 // Draw 50 mm by 50 mm L shape
672 double logUnitsFactor = ppiPrinterX / (scale * 25.4);
673 int logUnits = int(50 * logUnitsFactor);
674 dc->SetPen(* wxBLACK_PEN);
675 dc->DrawLine(50, 250, 50 + logUnits, 250);
676 dc->DrawLine(50, 250, 50, 250 + logUnits);
677
678 dc->SetBackgroundMode(wxBRUSHSTYLE_TRANSPARENT);
679 dc->SetBrush(*wxTRANSPARENT_BRUSH);
680
681 { // GetTextExtent demo:
682 wxString words[7] = { "This ", "is ", "GetTextExtent ",
683 "testing ", "string. ", "Enjoy ", "it!" };
684 long x = 200, y= 250;
685
686 dc->SetFont(wxFontInfo(15).Family(wxFONTFAMILY_SWISS));
687
688 for (int i = 0; i < 7; i++)
689 {
690 wxCoord wordWidth, wordHeight;
691 wxString word = words[i];
692 word.Remove( word.Len()-1, 1 );
693 dc->GetTextExtent(word, &wordWidth, &wordHeight);
694 dc->DrawRectangle(x, y, wordWidth, wordHeight);
695 dc->GetTextExtent(words[i], &wordWidth, &wordHeight);
696 dc->DrawText(words[i], x, y);
697 x += wordWidth;
698 }
699
700 }
701
702 dc->SetFont(wxGetApp().GetTestFont());
703
704 dc->DrawText("Some test text", 200, 300 );
705
706 // TESTING
707
708 int leftMargin = 20;
709 int rightMargin = 20;
710 int topMargin = 20;
711 int bottomMargin = 20;
712
713 int pageWidthMM, pageHeightMM;
714 GetPageSizeMM(&pageWidthMM, &pageHeightMM);
715
716 int leftMarginLogical = int(logUnitsFactor * leftMargin);
717 int topMarginLogical = int(logUnitsFactor * topMargin);
718 int bottomMarginLogical = int(logUnitsFactor * (pageHeightMM - bottomMargin));
719 int rightMarginLogical = int(logUnitsFactor * (pageWidthMM - rightMargin));
720
721 dc->SetPen(* wxRED_PEN);
722 dc->DrawLine(leftMarginLogical, topMarginLogical,
723 rightMarginLogical, topMarginLogical);
724 dc->DrawLine(leftMarginLogical, bottomMarginLogical,
725 rightMarginLogical, bottomMarginLogical);
726
727 WritePageHeader(this, dc, "A header", logUnitsFactor);
728 }
729
730 // Writes a header on a page. Margin units are in millimetres.
WritePageHeader(wxPrintout * printout,wxDC * dc,const wxString & text,double mmToLogical)731 bool MyPrintout::WritePageHeader(wxPrintout *printout, wxDC *dc, const wxString&text, double mmToLogical)
732 {
733 int pageWidthMM, pageHeightMM;
734
735 printout->GetPageSizeMM(&pageWidthMM, &pageHeightMM);
736 wxUnusedVar(pageHeightMM);
737
738 int leftMargin = 10;
739 int topMargin = 10;
740 int rightMargin = 10;
741
742 int leftMarginLogical = int(mmToLogical * leftMargin);
743 int topMarginLogical = int(mmToLogical * topMargin);
744 int rightMarginLogical = int(mmToLogical * (pageWidthMM - rightMargin));
745
746 wxCoord xExtent, yExtent;
747 dc->GetTextExtent(text, &xExtent, &yExtent);
748
749 int xPos = int(((((pageWidthMM - leftMargin - rightMargin) / 2.0) + leftMargin) * mmToLogical) - (xExtent / 2.0));
750 dc->DrawText(text, xPos, topMarginLogical);
751
752 dc->SetPen(* wxBLACK_PEN);
753 dc->DrawLine(leftMarginLogical, topMarginLogical + yExtent,
754 rightMarginLogical, topMarginLogical + yExtent);
755
756 return true;
757 }
758