]>
git.saurik.com Git - wxWidgets.git/blob - src/html/htmprint.cpp
1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: html printing classes
4 // Author: Vaclav Slavik
7 // Copyright: (c) Vaclav Slavik, 1999
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "htmprint.h"
16 // For compilers that support precompilation, includes "wx/wx.h".
17 #include "wx/wxprec.h"
31 #if wxUSE_HTML && wxUSE_PRINTING_ARCHITECTURE && wxUSE_STREAMS
35 #include "wx/printdlg.h"
36 #include "wx/html/htmprint.h"
37 #include "wx/wxhtml.h"
38 #include "wx/wfstream.h"
41 //--------------------------------------------------------------------------------
43 //--------------------------------------------------------------------------------
46 wxHtmlDCRenderer::wxHtmlDCRenderer() : wxObject()
49 m_Width
= m_Height
= 0;
51 m_Parser
= new wxHtmlWinParser(NULL
);
52 m_FS
= new wxFileSystem();
53 m_Parser
->SetFS(m_FS
);
58 wxHtmlDCRenderer::~wxHtmlDCRenderer()
60 if (m_Cells
) delete m_Cells
;
61 if (m_Parser
) delete m_Parser
;
62 if (m_FS
) delete m_FS
;
67 void wxHtmlDCRenderer::SetDC(wxDC
*dc
, double pixel_scale
)
70 m_Parser
->SetDC(m_DC
, pixel_scale
);
75 void wxHtmlDCRenderer::SetSize(int width
, int height
)
82 void wxHtmlDCRenderer::SetHtmlText(const wxString
& html
, const wxString
& basepath
, bool isdir
)
84 if (m_DC
== NULL
) return;
86 if (m_Cells
!= NULL
) delete m_Cells
;
88 m_FS
->ChangePathTo(basepath
, isdir
);
89 m_Cells
= (wxHtmlContainerCell
*) m_Parser
->Parse(html
);
90 m_Cells
->SetIndent(0, wxHTML_INDENT_ALL
, wxHTML_UNITS_PIXELS
);
91 m_Cells
->Layout(m_Width
);
95 void wxHtmlDCRenderer::SetFonts(wxString normal_face
, wxString fixed_face
,
98 m_Parser
->SetFonts(normal_face
, fixed_face
, sizes
);
99 if (m_DC
== NULL
&& m_Cells
!= NULL
) m_Cells
->Layout(m_Width
);
103 int wxHtmlDCRenderer::Render(int x
, int y
, int from
, int dont_render
, int to
, int *known_pagebreaks
, int number_of_pages
)
107 if (m_Cells
== NULL
|| m_DC
== NULL
) return 0;
109 pbreak
= (int)(from
+ m_Height
);
110 while (m_Cells
->AdjustPagebreak(&pbreak
, known_pagebreaks
, number_of_pages
)) {}
111 hght
= pbreak
- from
;
117 wxHtmlRenderingState
rstate(NULL
);
118 m_DC
->SetBrush(*wxWHITE_BRUSH
);
119 m_DC
->SetClippingRegion(x
, y
, m_Width
, hght
);
122 y
, pbreak
+ (y
/*- from*/),
124 m_DC
->DestroyClippingRegion();
127 if (pbreak
< m_Cells
->GetHeight()) return pbreak
;
128 else return GetTotalHeight();
133 int wxHtmlDCRenderer::GetTotalHeight()
135 if (m_Cells
) return m_Cells
->GetHeight();
154 //--------------------------------------------------------------------------------
156 //--------------------------------------------------------------------------------
160 wxHtmlPrintout::wxHtmlPrintout(const wxString
& title
) : wxPrintout(title
)
162 m_Renderer
= new wxHtmlDCRenderer
;
163 m_RendererHdr
= new wxHtmlDCRenderer
;
164 m_NumPages
= wxHTML_PRINT_MAX_PAGES
;
165 m_Document
= m_BasePath
= wxEmptyString
; m_BasePathIsDir
= TRUE
;
166 m_Headers
[0] = m_Headers
[1] = wxEmptyString
;
167 m_Footers
[0] = m_Footers
[1] = wxEmptyString
;
168 m_HeaderHeight
= m_FooterHeight
= 0;
169 SetMargins(); // to default values
174 wxHtmlPrintout::~wxHtmlPrintout()
177 delete m_RendererHdr
;
182 bool wxHtmlPrintout::OnBeginDocument(int startPage
, int endPage
)
184 int pageWidth
, pageHeight
, mm_w
, mm_h
, scr_w
, scr_h
, dc_w
, dc_h
;
185 float ppmm_h
, ppmm_v
;
187 if (!wxPrintout::OnBeginDocument(startPage
, endPage
)) return FALSE
;
189 GetPageSizePixels(&pageWidth
, &pageHeight
);
190 GetPageSizeMM(&mm_w
, &mm_h
);
191 ppmm_h
= (float)pageWidth
/ mm_w
;
192 ppmm_v
= (float)pageHeight
/ mm_h
;
194 int ppiPrinterX
, ppiPrinterY
;
195 GetPPIPrinter(&ppiPrinterX
, &ppiPrinterY
);
196 int ppiScreenX
, ppiScreenY
;
197 GetPPIScreen(&ppiScreenX
, &ppiScreenY
);
199 wxDisplaySize(&scr_w
, &scr_h
);
200 GetDC()->GetSize(&dc_w
, &dc_h
);
202 GetDC()->SetUserScale((double)dc_w
/ (double)pageWidth
, (double)dc_w
/ (double)pageWidth
);
204 /* prepare headers/footers renderer: */
206 m_RendererHdr
->SetDC(GetDC(), (double)ppiPrinterY
/ (double)ppiScreenY
);
207 m_RendererHdr
->SetSize((int) (ppmm_h
* (mm_w
- m_MarginLeft
- m_MarginRight
)),
208 (int) (ppmm_v
* (mm_h
- m_MarginTop
- m_MarginBottom
)));
209 if (m_Headers
[0] != wxEmptyString
)
211 m_RendererHdr
->SetHtmlText(TranslateHeader(m_Headers
[0], 1));
212 m_HeaderHeight
= m_RendererHdr
->GetTotalHeight();
214 else if (m_Headers
[1] != wxEmptyString
)
216 m_RendererHdr
->SetHtmlText(TranslateHeader(m_Headers
[1], 1));
217 m_HeaderHeight
= m_RendererHdr
->GetTotalHeight();
219 if (m_Footers
[0] != wxEmptyString
)
221 m_RendererHdr
->SetHtmlText(TranslateHeader(m_Footers
[0], 1));
222 m_FooterHeight
= m_RendererHdr
->GetTotalHeight();
224 else if (m_Footers
[1] != wxEmptyString
)
226 m_RendererHdr
->SetHtmlText(TranslateHeader(m_Footers
[1], 1));
227 m_FooterHeight
= m_RendererHdr
->GetTotalHeight();
230 /* prepare main renderer: */
231 m_Renderer
->SetDC(GetDC(), (double)ppiPrinterY
/ (double)ppiScreenY
);
232 m_Renderer
->SetSize((int) (ppmm_h
* (mm_w
- m_MarginLeft
- m_MarginRight
)),
233 (int) (ppmm_v
* (mm_h
- m_MarginTop
- m_MarginBottom
) -
234 m_FooterHeight
- m_HeaderHeight
-
235 ((m_HeaderHeight
== 0) ? 0 : m_MarginSpace
* ppmm_v
) -
236 ((m_FooterHeight
== 0) ? 0 : m_MarginSpace
* ppmm_v
)
238 m_Renderer
->SetHtmlText(m_Document
, m_BasePath
, m_BasePathIsDir
);
244 bool wxHtmlPrintout::OnPrintPage(int page
)
250 RenderPage(dc
, page
);
257 void wxHtmlPrintout::GetPageInfo(int *minPage
, int *maxPage
, int *selPageFrom
, int *selPageTo
)
260 *maxPage
= wxHTML_PRINT_MAX_PAGES
;
262 *selPageTo
= wxHTML_PRINT_MAX_PAGES
;
267 bool wxHtmlPrintout::HasPage(int pageNum
)
269 return (pageNum
>= 1 && pageNum
<= m_NumPages
);
274 void wxHtmlPrintout::SetHtmlText(const wxString
& html
, const wxString
&basepath
, bool isdir
)
277 m_BasePath
= basepath
;
278 m_BasePathIsDir
= isdir
;
281 void wxHtmlPrintout::SetHtmlFile(const wxString
& htmlfile
)
284 wxFSFile
*ff
= fs
.OpenFile(htmlfile
);
288 wxLogError(htmlfile
+ _(": file does not exist!"));
292 wxHtmlFilterHTML filter
;
293 wxString doc
= filter
.ReadFile(*ff
);
295 SetHtmlText(doc
, htmlfile
, FALSE
);
301 void wxHtmlPrintout::SetHeader(const wxString
& header
, int pg
)
303 if (pg
== wxPAGE_ALL
|| pg
== wxPAGE_EVEN
)
304 m_Headers
[0] = header
;
305 if (pg
== wxPAGE_ALL
|| pg
== wxPAGE_ODD
)
306 m_Headers
[1] = header
;
311 void wxHtmlPrintout::SetFooter(const wxString
& footer
, int pg
)
313 if (pg
== wxPAGE_ALL
|| pg
== wxPAGE_EVEN
)
314 m_Footers
[0] = footer
;
315 if (pg
== wxPAGE_ALL
|| pg
== wxPAGE_ODD
)
316 m_Footers
[1] = footer
;
321 void wxHtmlPrintout::CountPages()
324 int pageWidth
, pageHeight
, mm_w
, mm_h
;
325 float ppmm_h
, ppmm_v
;
327 GetPageSizePixels(&pageWidth
, &pageHeight
);
328 GetPageSizeMM(&mm_w
, &mm_h
);
329 ppmm_h
= (float)pageWidth
/ mm_w
;
330 ppmm_v
= (float)pageHeight
/ mm_h
;
339 pos
= m_Renderer
->Render((int)( ppmm_h
* m_MarginLeft
),
340 (int) (ppmm_v
* (m_MarginTop
+ (m_HeaderHeight
== 0 ? 0 : m_MarginSpace
)) + m_HeaderHeight
),
341 pos
, TRUE
, INT_MAX
, m_PageBreaks
, m_NumPages
);
342 m_PageBreaks
[++m_NumPages
] = pos
;
343 } while (pos
< m_Renderer
->GetTotalHeight());
348 void wxHtmlPrintout::RenderPage(wxDC
*dc
, int page
)
352 int pageWidth
, pageHeight
, mm_w
, mm_h
, scr_w
, scr_h
, dc_w
, dc_h
;
353 float ppmm_h
, ppmm_v
;
355 GetPageSizePixels(&pageWidth
, &pageHeight
);
356 GetPageSizeMM(&mm_w
, &mm_h
);
357 ppmm_h
= (float)pageWidth
/ mm_w
;
358 ppmm_v
= (float)pageHeight
/ mm_h
;
359 wxDisplaySize(&scr_w
, &scr_h
);
360 dc
->GetSize(&dc_w
, &dc_h
);
362 int ppiPrinterX
, ppiPrinterY
;
363 GetPPIPrinter(&ppiPrinterX
, &ppiPrinterY
);
364 int ppiScreenX
, ppiScreenY
;
365 GetPPIScreen(&ppiScreenX
, &ppiScreenY
);
367 dc
->SetUserScale((double)dc_w
/ (double)pageWidth
, (double)dc_w
/ (double)pageWidth
);
369 m_Renderer
->SetDC(dc
, (double)ppiPrinterY
/ (double)ppiScreenY
);
371 dc
->SetBackgroundMode(wxTRANSPARENT
);
373 m_Renderer
->Render((int) (ppmm_h
* m_MarginLeft
),
374 (int) (ppmm_v
* (m_MarginTop
+ (m_HeaderHeight
== 0 ? 0 : m_MarginSpace
)) + m_HeaderHeight
),
375 m_PageBreaks
[page
-1], FALSE
, m_PageBreaks
[page
]-m_PageBreaks
[page
-1]);
377 m_RendererHdr
->SetDC(dc
, (double)ppiPrinterY
/ (double)ppiScreenY
);
378 if (m_Headers
[page
% 2] != wxEmptyString
)
380 m_RendererHdr
->SetHtmlText(TranslateHeader(m_Headers
[page
% 2], page
));
381 m_RendererHdr
->Render((int) (ppmm_h
* m_MarginLeft
), (int) (ppmm_v
* m_MarginTop
));
383 if (m_Footers
[page
% 2] != wxEmptyString
)
385 m_RendererHdr
->SetHtmlText(TranslateHeader(m_Footers
[page
% 2], page
));
386 m_RendererHdr
->Render((int) (ppmm_h
* m_MarginLeft
), (int) (pageHeight
- ppmm_v
* m_MarginBottom
- m_FooterHeight
));
392 wxString
wxHtmlPrintout::TranslateHeader(const wxString
& instr
, int page
)
397 num
.Printf(wxT("%i"), page
);
398 r
.Replace(wxT("@PAGENUM@"), num
);
400 num
.Printf(wxT("%i"), m_NumPages
);
401 r
.Replace(wxT("@PAGESCNT@"), num
);
408 void wxHtmlPrintout::SetMargins(float top
, float bottom
, float left
, float right
, float spaces
)
411 m_MarginBottom
= bottom
;
413 m_MarginRight
= right
;
414 m_MarginSpace
= spaces
;
420 void wxHtmlPrintout::SetFonts(wxString normal_face
, wxString fixed_face
,
423 m_Renderer
->SetFonts(normal_face
, fixed_face
, sizes
);
424 m_RendererHdr
->SetFonts(normal_face
, fixed_face
, sizes
);
429 //----------------------------------------------------------------------------
430 // wxHtmlEasyPrinting
431 //----------------------------------------------------------------------------
434 wxHtmlEasyPrinting::wxHtmlEasyPrinting(const wxString
& name
, wxWindow
*parentWindow
)
436 m_ParentWindow
= parentWindow
;
438 m_PrintData
= new wxPrintData
;
439 m_PageSetupData
= new wxPageSetupDialogData
;
440 m_Headers
[0] = m_Headers
[1] = m_Footers
[0] = m_Footers
[1] = wxEmptyString
;
442 m_PageSetupData
->EnableMargins(TRUE
);
443 m_PageSetupData
->SetMarginTopLeft(wxPoint(25, 25));
444 m_PageSetupData
->SetMarginBottomRight(wxPoint(25, 25));
446 SetFonts(wxEmptyString
, wxEmptyString
, NULL
);
451 wxHtmlEasyPrinting::~wxHtmlEasyPrinting()
454 delete m_PageSetupData
;
459 bool wxHtmlEasyPrinting::PreviewFile(const wxString
&htmlfile
)
461 wxHtmlPrintout
*p1
= CreatePrintout();
462 p1
->SetHtmlFile(htmlfile
);
463 wxHtmlPrintout
*p2
= CreatePrintout();
464 p2
->SetHtmlFile(htmlfile
);
465 return DoPreview(p1
, p2
);
470 bool wxHtmlEasyPrinting::PreviewText(const wxString
&htmltext
, const wxString
&basepath
)
472 wxHtmlPrintout
*p1
= CreatePrintout();
473 p1
->SetHtmlText(htmltext
, basepath
, TRUE
);
474 wxHtmlPrintout
*p2
= CreatePrintout();
475 p2
->SetHtmlText(htmltext
, basepath
, TRUE
);
476 return DoPreview(p1
, p2
);
481 bool wxHtmlEasyPrinting::PrintFile(const wxString
&htmlfile
)
483 wxHtmlPrintout
*p
= CreatePrintout();
484 p
->SetHtmlFile(htmlfile
);
485 bool ret
= DoPrint(p
);
492 bool wxHtmlEasyPrinting::PrintText(const wxString
&htmltext
, const wxString
&basepath
)
494 wxHtmlPrintout
*p
= CreatePrintout();
495 p
->SetHtmlText(htmltext
, basepath
, TRUE
);
496 bool ret
= DoPrint(p
);
503 bool wxHtmlEasyPrinting::DoPreview(wxHtmlPrintout
*printout1
, wxHtmlPrintout
*printout2
)
505 // Pass two printout objects: for preview, and possible printing.
506 wxPrintDialogData
printDialogData(*m_PrintData
);
507 wxPrintPreview
*preview
= new wxPrintPreview(printout1
, printout2
, &printDialogData
);
514 wxPreviewFrame
*frame
= new wxPreviewFrame(preview
, m_ParentWindow
,
515 m_Name
+ _(" Preview"),
516 wxPoint(100, 100), wxSize(650, 500));
517 frame
->Centre(wxBOTH
);
525 bool wxHtmlEasyPrinting::DoPrint(wxHtmlPrintout
*printout
)
527 wxPrintDialogData
printDialogData(*m_PrintData
);
528 wxPrinter
printer(&printDialogData
);
530 if (!printer
.Print(m_ParentWindow
, printout
, TRUE
))
535 (*m_PrintData
) = printer
.GetPrintDialogData().GetPrintData();
541 void wxHtmlEasyPrinting::PrinterSetup()
543 wxPrintDialogData
printDialogData(*m_PrintData
);
544 wxPrintDialog
printerDialog(m_ParentWindow
, &printDialogData
);
546 printerDialog
.GetPrintDialogData().SetSetupDialog(TRUE
);
548 if (printerDialog
.ShowModal() == wxID_OK
)
549 (*m_PrintData
) = printerDialog
.GetPrintDialogData().GetPrintData();
554 void wxHtmlEasyPrinting::PageSetup()
556 if (!m_PrintData
->Ok())
558 wxLogError(_("There was a problem during page setup: you may need to set a default printer."));
562 m_PageSetupData
->SetPrintData(*m_PrintData
);
563 wxPageSetupDialog
pageSetupDialog(m_ParentWindow
, m_PageSetupData
);
565 if (pageSetupDialog
.ShowModal() == wxID_OK
)
567 (*m_PrintData
) = pageSetupDialog
.GetPageSetupData().GetPrintData();
568 (*m_PageSetupData
) = pageSetupDialog
.GetPageSetupData();
574 void wxHtmlEasyPrinting::SetHeader(const wxString
& header
, int pg
)
576 if (pg
== wxPAGE_ALL
|| pg
== wxPAGE_EVEN
)
577 m_Headers
[0] = header
;
578 if (pg
== wxPAGE_ALL
|| pg
== wxPAGE_ODD
)
579 m_Headers
[1] = header
;
584 void wxHtmlEasyPrinting::SetFooter(const wxString
& footer
, int pg
)
586 if (pg
== wxPAGE_ALL
|| pg
== wxPAGE_EVEN
)
587 m_Footers
[0] = footer
;
588 if (pg
== wxPAGE_ALL
|| pg
== wxPAGE_ODD
)
589 m_Footers
[1] = footer
;
593 void wxHtmlEasyPrinting::SetFonts(wxString normal_face
, wxString fixed_face
,
596 m_FontFaceNormal
= normal_face
;
597 m_FontFaceFixed
= fixed_face
;
601 m_FontsSizes
= m_FontsSizesArr
;
602 for (int i
= 0; i
< 7; i
++) m_FontsSizes
[i
] = sizes
[i
];
609 wxHtmlPrintout
*wxHtmlEasyPrinting::CreatePrintout()
611 wxHtmlPrintout
*p
= new wxHtmlPrintout(m_Name
);
613 p
->SetFonts(m_FontFaceNormal
, m_FontFaceFixed
, m_FontsSizes
);
615 p
->SetHeader(m_Headers
[0], wxPAGE_EVEN
);
616 p
->SetHeader(m_Headers
[1], wxPAGE_ODD
);
617 p
->SetFooter(m_Footers
[0], wxPAGE_EVEN
);
618 p
->SetFooter(m_Footers
[1], wxPAGE_ODD
);
620 p
->SetMargins(m_PageSetupData
->GetMarginTopLeft().y
,
621 m_PageSetupData
->GetMarginBottomRight().y
,
622 m_PageSetupData
->GetMarginTopLeft().x
,
623 m_PageSetupData
->GetMarginBottomRight().x
);
629 // This hack forces the linker to always link in m_* files
630 // (wxHTML doesn't work without handlers from these files)
631 #include "wx/html/forcelnk.h"
632 FORCE_WXHTML_MODULES()
634 #endif // wxUSE_HTML & wxUSE_PRINTING_ARCHITECTURE