Include wx/dc.h according to precompiled headers of wx/wx.h (with other minor cleaning).
[wxWidgets.git] / src / html / htmprint.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/html/htmprint.cpp
3 // Purpose: html printing classes
4 // Author: Vaclav Slavik
5 // Created: 25/09/99
6 // RCS-ID: $Id$
7 // Copyright: (c) Vaclav Slavik, 1999
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
11 // For compilers that support precompilation, includes "wx/wx.h".
12 #include "wx/wxprec.h"
13
14 #ifdef __BORLANDC__
15 #pragma hdrstop
16 #endif
17
18 #if wxUSE_HTML && wxUSE_PRINTING_ARCHITECTURE && wxUSE_STREAMS
19
20 #ifndef WX_PRECOMP
21 #include "wx/log.h"
22 #include "wx/intl.h"
23 #include "wx/dc.h"
24 #endif
25
26 #include "wx/print.h"
27 #include "wx/printdlg.h"
28 #include "wx/html/htmprint.h"
29 #include "wx/wxhtml.h"
30 #include "wx/wfstream.h"
31 #include "wx/module.h"
32 #include "wx/settings.h"
33
34
35 //--------------------------------------------------------------------------------
36 // wxHtmlDCRenderer
37 //--------------------------------------------------------------------------------
38
39
40 wxHtmlDCRenderer::wxHtmlDCRenderer() : wxObject()
41 {
42 m_DC = NULL;
43 m_Width = m_Height = 0;
44 m_Cells = NULL;
45 m_Parser = new wxHtmlWinParser();
46 m_FS = new wxFileSystem();
47 m_Parser->SetFS(m_FS);
48 }
49
50
51
52 wxHtmlDCRenderer::~wxHtmlDCRenderer()
53 {
54 if (m_Cells) delete m_Cells;
55 if (m_Parser) delete m_Parser;
56 if (m_FS) delete m_FS;
57 }
58
59
60
61 void wxHtmlDCRenderer::SetDC(wxDC *dc, double pixel_scale)
62 {
63 m_DC = dc;
64 m_Parser->SetDC(m_DC, pixel_scale);
65 }
66
67
68
69 void wxHtmlDCRenderer::SetSize(int width, int height)
70 {
71 m_Width = width;
72 m_Height = height;
73 }
74
75
76 void wxHtmlDCRenderer::SetHtmlText(const wxString& html, const wxString& basepath, bool isdir)
77 {
78 if (m_DC == NULL) return;
79
80 if (m_Cells != NULL) delete m_Cells;
81
82 m_FS->ChangePathTo(basepath, isdir);
83 m_Cells = (wxHtmlContainerCell*) m_Parser->Parse(html);
84 m_Cells->SetIndent(0, wxHTML_INDENT_ALL, wxHTML_UNITS_PIXELS);
85 m_Cells->Layout(m_Width);
86 }
87
88
89 void wxHtmlDCRenderer::SetFonts(const wxString& normal_face, const wxString& fixed_face,
90 const int *sizes)
91 {
92 m_Parser->SetFonts(normal_face, fixed_face, sizes);
93 if (m_DC == NULL && m_Cells != NULL)
94 m_Cells->Layout(m_Width);
95 }
96
97 void wxHtmlDCRenderer::SetStandardFonts(int size,
98 const wxString& normal_face,
99 const wxString& fixed_face)
100 {
101 m_Parser->SetStandardFonts(size, normal_face, fixed_face);
102 if (m_DC == NULL && m_Cells != NULL)
103 m_Cells->Layout(m_Width);
104 }
105
106
107 int wxHtmlDCRenderer::Render(int x, int y, int from, int dont_render,
108 int maxHeight,
109 int *known_pagebreaks, int number_of_pages)
110 {
111 int pbreak, hght;
112
113 if (m_Cells == NULL || m_DC == NULL) return 0;
114
115 pbreak = (int)(from + m_Height);
116 while (m_Cells->AdjustPagebreak(&pbreak, known_pagebreaks, number_of_pages)) {}
117 hght = pbreak - from;
118 if (maxHeight < hght)
119 hght = maxHeight;
120
121 if (!dont_render)
122 {
123 wxHtmlRenderingInfo rinfo;
124 wxDefaultHtmlRenderingStyle rstyle;
125 rinfo.SetStyle(&rstyle);
126 m_DC->SetBrush(*wxWHITE_BRUSH);
127 m_DC->SetClippingRegion(x, y, m_Width, hght);
128 m_Cells->Draw(*m_DC,
129 x, (y - from),
130 y, pbreak + (y /*- from*/),
131 rinfo);
132 m_DC->DestroyClippingRegion();
133 }
134
135 if (pbreak < m_Cells->GetHeight()) return pbreak;
136 else return GetTotalHeight();
137 }
138
139
140
141 int wxHtmlDCRenderer::GetTotalHeight()
142 {
143 if (m_Cells) return m_Cells->GetHeight();
144 else return 0;
145 }
146
147
148 //--------------------------------------------------------------------------------
149 // wxHtmlPrintout
150 //--------------------------------------------------------------------------------
151
152
153 wxList wxHtmlPrintout::m_Filters;
154
155 wxHtmlPrintout::wxHtmlPrintout(const wxString& title) : wxPrintout(title)
156 {
157 m_Renderer = new wxHtmlDCRenderer;
158 m_RendererHdr = new wxHtmlDCRenderer;
159 m_NumPages = wxHTML_PRINT_MAX_PAGES;
160 m_Document = m_BasePath = wxEmptyString; m_BasePathIsDir = true;
161 m_Headers[0] = m_Headers[1] = wxEmptyString;
162 m_Footers[0] = m_Footers[1] = wxEmptyString;
163 m_HeaderHeight = m_FooterHeight = 0;
164 SetMargins(); // to default values
165 }
166
167
168
169 wxHtmlPrintout::~wxHtmlPrintout()
170 {
171 delete m_Renderer;
172 delete m_RendererHdr;
173 }
174
175 void wxHtmlPrintout::CleanUpStatics()
176 {
177 WX_CLEAR_LIST(wxList, m_Filters);
178 }
179
180 // Adds input filter
181 void wxHtmlPrintout::AddFilter(wxHtmlFilter *filter)
182 {
183 m_Filters.Append(filter);
184 }
185
186 void wxHtmlPrintout::OnPreparePrinting()
187 {
188 int pageWidth, pageHeight, mm_w, mm_h, scr_w, scr_h, dc_w, dc_h;
189 float ppmm_h, ppmm_v;
190
191 GetPageSizePixels(&pageWidth, &pageHeight);
192 GetPageSizeMM(&mm_w, &mm_h);
193 ppmm_h = (float)pageWidth / mm_w;
194 ppmm_v = (float)pageHeight / mm_h;
195
196 int ppiPrinterX, ppiPrinterY;
197 GetPPIPrinter(&ppiPrinterX, &ppiPrinterY);
198 int ppiScreenX, ppiScreenY;
199 GetPPIScreen(&ppiScreenX, &ppiScreenY);
200
201 wxDisplaySize(&scr_w, &scr_h);
202 GetDC()->GetSize(&dc_w, &dc_h);
203
204 GetDC()->SetUserScale((double)dc_w / (double)pageWidth, (double)dc_w / (double)pageWidth);
205
206 /* prepare headers/footers renderer: */
207
208 m_RendererHdr->SetDC(GetDC(), (double)ppiPrinterY / (double)ppiScreenY);
209 m_RendererHdr->SetSize((int) (ppmm_h * (mm_w - m_MarginLeft - m_MarginRight)),
210 (int) (ppmm_v * (mm_h - m_MarginTop - m_MarginBottom)));
211 if (m_Headers[0] != wxEmptyString)
212 {
213 m_RendererHdr->SetHtmlText(TranslateHeader(m_Headers[0], 1));
214 m_HeaderHeight = m_RendererHdr->GetTotalHeight();
215 }
216 else if (m_Headers[1] != wxEmptyString)
217 {
218 m_RendererHdr->SetHtmlText(TranslateHeader(m_Headers[1], 1));
219 m_HeaderHeight = m_RendererHdr->GetTotalHeight();
220 }
221 if (m_Footers[0] != wxEmptyString)
222 {
223 m_RendererHdr->SetHtmlText(TranslateHeader(m_Footers[0], 1));
224 m_FooterHeight = m_RendererHdr->GetTotalHeight();
225 }
226 else if (m_Footers[1] != wxEmptyString)
227 {
228 m_RendererHdr->SetHtmlText(TranslateHeader(m_Footers[1], 1));
229 m_FooterHeight = m_RendererHdr->GetTotalHeight();
230 }
231
232 /* prepare main renderer: */
233 m_Renderer->SetDC(GetDC(), (double)ppiPrinterY / (double)ppiScreenY);
234 m_Renderer->SetSize((int) (ppmm_h * (mm_w - m_MarginLeft - m_MarginRight)),
235 (int) (ppmm_v * (mm_h - m_MarginTop - m_MarginBottom) -
236 m_FooterHeight - m_HeaderHeight -
237 ((m_HeaderHeight == 0) ? 0 : m_MarginSpace * ppmm_v) -
238 ((m_FooterHeight == 0) ? 0 : m_MarginSpace * ppmm_v)
239 ));
240 m_Renderer->SetHtmlText(m_Document, m_BasePath, m_BasePathIsDir);
241 CountPages();
242 }
243
244 bool wxHtmlPrintout::OnBeginDocument(int startPage, int endPage)
245 {
246 if (!wxPrintout::OnBeginDocument(startPage, endPage)) return false;
247
248 return true;
249 }
250
251
252 bool wxHtmlPrintout::OnPrintPage(int page)
253 {
254 wxDC *dc = GetDC();
255 if (dc)
256 {
257 if (HasPage(page))
258 RenderPage(dc, page);
259 return true;
260 }
261 else return false;
262 }
263
264
265 void wxHtmlPrintout::GetPageInfo(int *minPage, int *maxPage, int *selPageFrom, int *selPageTo)
266 {
267 *minPage = 1;
268 *maxPage = m_NumPages;
269 *selPageFrom = 1;
270 *selPageTo = m_NumPages;
271 }
272
273
274
275 bool wxHtmlPrintout::HasPage(int pageNum)
276 {
277 return (pageNum >= 1 && pageNum <= m_NumPages);
278 }
279
280
281
282 void wxHtmlPrintout::SetHtmlText(const wxString& html, const wxString &basepath, bool isdir)
283 {
284 m_Document = html;
285 m_BasePath = basepath;
286 m_BasePathIsDir = isdir;
287 }
288
289 void wxHtmlPrintout::SetHtmlFile(const wxString& htmlfile)
290 {
291 wxFileSystem fs;
292 wxFSFile *ff;
293
294 if (wxFileExists(htmlfile))
295 ff = fs.OpenFile(wxFileSystem::FileNameToURL(htmlfile));
296 else
297 ff = fs.OpenFile(htmlfile);
298
299 if (ff == NULL)
300 {
301 wxLogError(htmlfile + _(": file does not exist!"));
302 return;
303 }
304
305 bool done = false;
306 wxHtmlFilterHTML defaultFilter;
307 wxString doc;
308
309 wxList::compatibility_iterator node = m_Filters.GetFirst();
310 while (node)
311 {
312 wxHtmlFilter *h = (wxHtmlFilter*) node->GetData();
313 if (h->CanRead(*ff))
314 {
315 doc = h->ReadFile(*ff);
316 done = true;
317 break;
318 }
319 node = node->GetNext();
320 }
321
322 if (!done)
323 doc = defaultFilter.ReadFile(*ff);
324
325 SetHtmlText(doc, htmlfile, false);
326 delete ff;
327 }
328
329
330
331 void wxHtmlPrintout::SetHeader(const wxString& header, int pg)
332 {
333 if (pg == wxPAGE_ALL || pg == wxPAGE_EVEN)
334 m_Headers[0] = header;
335 if (pg == wxPAGE_ALL || pg == wxPAGE_ODD)
336 m_Headers[1] = header;
337 }
338
339
340
341 void wxHtmlPrintout::SetFooter(const wxString& footer, int pg)
342 {
343 if (pg == wxPAGE_ALL || pg == wxPAGE_EVEN)
344 m_Footers[0] = footer;
345 if (pg == wxPAGE_ALL || pg == wxPAGE_ODD)
346 m_Footers[1] = footer;
347 }
348
349
350
351 void wxHtmlPrintout::CountPages()
352 {
353 wxBusyCursor wait;
354 int pageWidth, pageHeight, mm_w, mm_h;
355 float ppmm_h, ppmm_v;
356
357 GetPageSizePixels(&pageWidth, &pageHeight);
358 GetPageSizeMM(&mm_w, &mm_h);
359 ppmm_h = (float)pageWidth / mm_w;
360 ppmm_v = (float)pageHeight / mm_h;
361
362 int pos = 0;
363
364 m_NumPages = 0;
365
366 m_PageBreaks[0] = 0;
367 do
368 {
369 pos = m_Renderer->Render((int)( ppmm_h * m_MarginLeft),
370 (int) (ppmm_v * (m_MarginTop + (m_HeaderHeight == 0 ? 0 : m_MarginSpace)) + m_HeaderHeight),
371 pos, true, INT_MAX, m_PageBreaks, m_NumPages);
372 m_PageBreaks[++m_NumPages] = pos;
373 } while (pos < m_Renderer->GetTotalHeight());
374 }
375
376
377
378 void wxHtmlPrintout::RenderPage(wxDC *dc, int page)
379 {
380 wxBusyCursor wait;
381
382 int pageWidth, pageHeight, mm_w, mm_h, scr_w, scr_h, dc_w, dc_h;
383 float ppmm_h, ppmm_v;
384
385 GetPageSizePixels(&pageWidth, &pageHeight);
386 GetPageSizeMM(&mm_w, &mm_h);
387 ppmm_h = (float)pageWidth / mm_w;
388 ppmm_v = (float)pageHeight / mm_h;
389 wxDisplaySize(&scr_w, &scr_h);
390 dc->GetSize(&dc_w, &dc_h);
391
392 int ppiPrinterX, ppiPrinterY;
393 GetPPIPrinter(&ppiPrinterX, &ppiPrinterY);
394 wxUnusedVar(ppiPrinterX);
395 int ppiScreenX, ppiScreenY;
396 GetPPIScreen(&ppiScreenX, &ppiScreenY);
397 wxUnusedVar(ppiScreenX);
398
399 dc->SetUserScale((double)dc_w / (double)pageWidth, (double)dc_w / (double)pageWidth);
400
401 m_Renderer->SetDC(dc, (double)ppiPrinterY / (double)ppiScreenY);
402
403 dc->SetBackgroundMode(wxTRANSPARENT);
404
405 m_Renderer->Render((int) (ppmm_h * m_MarginLeft),
406 (int) (ppmm_v * (m_MarginTop + (m_HeaderHeight == 0 ? 0 : m_MarginSpace)) + m_HeaderHeight),
407 m_PageBreaks[page-1], false, m_PageBreaks[page]-m_PageBreaks[page-1]);
408
409 m_RendererHdr->SetDC(dc, (double)ppiPrinterY / (double)ppiScreenY);
410 if (m_Headers[page % 2] != wxEmptyString)
411 {
412 m_RendererHdr->SetHtmlText(TranslateHeader(m_Headers[page % 2], page));
413 m_RendererHdr->Render((int) (ppmm_h * m_MarginLeft), (int) (ppmm_v * m_MarginTop));
414 }
415 if (m_Footers[page % 2] != wxEmptyString)
416 {
417 m_RendererHdr->SetHtmlText(TranslateHeader(m_Footers[page % 2], page));
418 m_RendererHdr->Render((int) (ppmm_h * m_MarginLeft), (int) (pageHeight - ppmm_v * m_MarginBottom - m_FooterHeight));
419 }
420 }
421
422
423
424 wxString wxHtmlPrintout::TranslateHeader(const wxString& instr, int page)
425 {
426 wxString r = instr;
427 wxString num;
428
429 num.Printf(wxT("%i"), page);
430 r.Replace(wxT("@PAGENUM@"), num);
431
432 num.Printf(wxT("%i"), m_NumPages);
433 r.Replace(wxT("@PAGESCNT@"), num);
434
435 return r;
436 }
437
438
439
440 void wxHtmlPrintout::SetMargins(float top, float bottom, float left, float right, float spaces)
441 {
442 m_MarginTop = top;
443 m_MarginBottom = bottom;
444 m_MarginLeft = left;
445 m_MarginRight = right;
446 m_MarginSpace = spaces;
447 }
448
449
450
451
452 void wxHtmlPrintout::SetFonts(const wxString& normal_face, const wxString& fixed_face,
453 const int *sizes)
454 {
455 m_Renderer->SetFonts(normal_face, fixed_face, sizes);
456 m_RendererHdr->SetFonts(normal_face, fixed_face, sizes);
457 }
458
459 void wxHtmlPrintout::SetStandardFonts(int size,
460 const wxString& normal_face,
461 const wxString& fixed_face)
462 {
463 m_Renderer->SetStandardFonts(size, normal_face, fixed_face);
464 m_RendererHdr->SetStandardFonts(size, normal_face, fixed_face);
465 }
466
467
468
469 //----------------------------------------------------------------------------
470 // wxHtmlEasyPrinting
471 //----------------------------------------------------------------------------
472
473
474 wxHtmlEasyPrinting::wxHtmlEasyPrinting(const wxString& name, wxWindow *parentWindow)
475 {
476 m_ParentWindow = parentWindow;
477 m_Name = name;
478 m_PrintData = NULL;
479 m_PageSetupData = new wxPageSetupDialogData;
480 m_Headers[0] = m_Headers[1] = m_Footers[0] = m_Footers[1] = wxEmptyString;
481
482 m_PageSetupData->EnableMargins(true);
483 m_PageSetupData->SetMarginTopLeft(wxPoint(25, 25));
484 m_PageSetupData->SetMarginBottomRight(wxPoint(25, 25));
485
486 SetFonts(wxEmptyString, wxEmptyString, NULL);
487 }
488
489
490
491 wxHtmlEasyPrinting::~wxHtmlEasyPrinting()
492 {
493 delete m_PrintData;
494 delete m_PageSetupData;
495 }
496
497
498 wxPrintData *wxHtmlEasyPrinting::GetPrintData()
499 {
500 if (m_PrintData == NULL)
501 m_PrintData = new wxPrintData();
502 return m_PrintData;
503 }
504
505
506 bool wxHtmlEasyPrinting::PreviewFile(const wxString &htmlfile)
507 {
508 wxHtmlPrintout *p1 = CreatePrintout();
509 p1->SetHtmlFile(htmlfile);
510 wxHtmlPrintout *p2 = CreatePrintout();
511 p2->SetHtmlFile(htmlfile);
512 return DoPreview(p1, p2);
513 }
514
515
516
517 bool wxHtmlEasyPrinting::PreviewText(const wxString &htmltext, const wxString &basepath)
518 {
519 wxHtmlPrintout *p1 = CreatePrintout();
520 p1->SetHtmlText(htmltext, basepath, true);
521 wxHtmlPrintout *p2 = CreatePrintout();
522 p2->SetHtmlText(htmltext, basepath, true);
523 return DoPreview(p1, p2);
524 }
525
526
527
528 bool wxHtmlEasyPrinting::PrintFile(const wxString &htmlfile)
529 {
530 wxHtmlPrintout *p = CreatePrintout();
531 p->SetHtmlFile(htmlfile);
532 bool ret = DoPrint(p);
533 delete p;
534 return ret;
535 }
536
537
538
539 bool wxHtmlEasyPrinting::PrintText(const wxString &htmltext, const wxString &basepath)
540 {
541 wxHtmlPrintout *p = CreatePrintout();
542 p->SetHtmlText(htmltext, basepath, true);
543 bool ret = DoPrint(p);
544 delete p;
545 return ret;
546 }
547
548
549
550 bool wxHtmlEasyPrinting::DoPreview(wxHtmlPrintout *printout1, wxHtmlPrintout *printout2)
551 {
552 // Pass two printout objects: for preview, and possible printing.
553 wxPrintDialogData printDialogData(*GetPrintData());
554 wxPrintPreview *preview = new wxPrintPreview(printout1, printout2, &printDialogData);
555 if (!preview->Ok())
556 {
557 delete preview;
558 return false;
559 }
560
561 wxPreviewFrame *frame = new wxPreviewFrame(preview, m_ParentWindow,
562 m_Name + _(" Preview"),
563 wxPoint(100, 100), wxSize(650, 500));
564 frame->Centre(wxBOTH);
565 frame->Initialize();
566 frame->Show(true);
567 return true;
568 }
569
570
571
572 bool wxHtmlEasyPrinting::DoPrint(wxHtmlPrintout *printout)
573 {
574 wxPrintDialogData printDialogData(*GetPrintData());
575 wxPrinter printer(&printDialogData);
576
577 if (!printer.Print(m_ParentWindow, printout, true))
578 {
579 return false;
580 }
581
582 (*GetPrintData()) = printer.GetPrintDialogData().GetPrintData();
583 return true;
584 }
585
586
587
588
589 void wxHtmlEasyPrinting::PageSetup()
590 {
591 if (!GetPrintData()->Ok())
592 {
593 wxLogError(_("There was a problem during page setup: you may need to set a default printer."));
594 return;
595 }
596
597 m_PageSetupData->SetPrintData(*GetPrintData());
598 wxPageSetupDialog pageSetupDialog(m_ParentWindow, m_PageSetupData);
599
600 if (pageSetupDialog.ShowModal() == wxID_OK)
601 {
602 (*GetPrintData()) = pageSetupDialog.GetPageSetupData().GetPrintData();
603 (*m_PageSetupData) = pageSetupDialog.GetPageSetupData();
604 }
605 }
606
607
608
609 void wxHtmlEasyPrinting::SetHeader(const wxString& header, int pg)
610 {
611 if (pg == wxPAGE_ALL || pg == wxPAGE_EVEN)
612 m_Headers[0] = header;
613 if (pg == wxPAGE_ALL || pg == wxPAGE_ODD)
614 m_Headers[1] = header;
615 }
616
617
618
619 void wxHtmlEasyPrinting::SetFooter(const wxString& footer, int pg)
620 {
621 if (pg == wxPAGE_ALL || pg == wxPAGE_EVEN)
622 m_Footers[0] = footer;
623 if (pg == wxPAGE_ALL || pg == wxPAGE_ODD)
624 m_Footers[1] = footer;
625 }
626
627
628 void wxHtmlEasyPrinting::SetFonts(const wxString& normal_face, const wxString& fixed_face,
629 const int *sizes)
630 {
631 m_fontMode = FontMode_Explicit;
632 m_FontFaceNormal = normal_face;
633 m_FontFaceFixed = fixed_face;
634
635 if (sizes)
636 {
637 m_FontsSizes = m_FontsSizesArr;
638 for (int i = 0; i < 7; i++) m_FontsSizes[i] = sizes[i];
639 }
640 else
641 m_FontsSizes = NULL;
642 }
643
644 void wxHtmlEasyPrinting::SetStandardFonts(int size,
645 const wxString& normal_face,
646 const wxString& fixed_face)
647 {
648 m_fontMode = FontMode_Standard;
649 m_FontFaceNormal = normal_face;
650 m_FontFaceFixed = fixed_face;
651 m_FontsSizesArr[0] = size;
652 }
653
654
655 wxHtmlPrintout *wxHtmlEasyPrinting::CreatePrintout()
656 {
657 wxHtmlPrintout *p = new wxHtmlPrintout(m_Name);
658
659 if (m_fontMode == FontMode_Explicit)
660 {
661 p->SetFonts(m_FontFaceNormal, m_FontFaceFixed, m_FontsSizes);
662 }
663 else // FontMode_Standard
664 {
665 p->SetStandardFonts(m_FontsSizesArr[0],
666 m_FontFaceNormal, m_FontFaceFixed);
667 }
668
669 p->SetHeader(m_Headers[0], wxPAGE_EVEN);
670 p->SetHeader(m_Headers[1], wxPAGE_ODD);
671 p->SetFooter(m_Footers[0], wxPAGE_EVEN);
672 p->SetFooter(m_Footers[1], wxPAGE_ODD);
673
674 p->SetMargins(m_PageSetupData->GetMarginTopLeft().y,
675 m_PageSetupData->GetMarginBottomRight().y,
676 m_PageSetupData->GetMarginTopLeft().x,
677 m_PageSetupData->GetMarginBottomRight().x);
678
679 return p;
680 }
681
682 // A module to allow initialization/cleanup
683 // without calling these functions from app.cpp or from
684 // the user's application.
685
686 class wxHtmlPrintingModule: public wxModule
687 {
688 DECLARE_DYNAMIC_CLASS(wxHtmlPrintingModule)
689 public:
690 wxHtmlPrintingModule() : wxModule() {}
691 bool OnInit() { return true; }
692 void OnExit() { wxHtmlPrintout::CleanUpStatics(); }
693 };
694
695 IMPLEMENT_DYNAMIC_CLASS(wxHtmlPrintingModule, wxModule)
696
697
698 // This hack forces the linker to always link in m_* files
699 // (wxHTML doesn't work without handlers from these files)
700 #include "wx/html/forcelnk.h"
701 FORCE_WXHTML_MODULES()
702
703 #endif // wxUSE_HTML & wxUSE_PRINTING_ARCHITECTURE