]>
git.saurik.com Git - wxWidgets.git/blob - src/html/htmprint.cpp
2 /////////////////////////////////////////////////////////////////////////////
4 // Purpose: html printing classes
5 // Author: Vaclav Slavik
8 // Copyright: (c) Vaclav Slavik, 1999
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
14 #pragma implementation
17 // For compilers that support precompilation, includes "wx/wx.h".
18 #include "wx/wxprec.h"
30 #if wxUSE_HTML & wxUSE_PRINTING_ARCHITECTURE
33 #include "wx/printdlg.h"
34 #include "wx/html/htmprint.h"
35 #include "wx/wxhtml.h"
36 #include "wx/wfstream.h"
39 //--------------------------------------------------------------------------------
41 //--------------------------------------------------------------------------------
44 wxHtmlDCRenderer::wxHtmlDCRenderer() : wxObject()
47 m_Width
= m_Height
= 0;
49 m_Parser
= new wxHtmlWinParser(NULL
);
50 m_FS
= new wxFileSystem();
51 m_Parser
-> SetFS(m_FS
);
57 wxHtmlDCRenderer::~wxHtmlDCRenderer()
59 if (m_Cells
) delete m_Cells
;
60 if (m_Parser
) delete m_Parser
;
61 if (m_FS
) delete m_FS
;
66 void wxHtmlDCRenderer::SetDC(wxDC
*dc
, int maxwidth
)
70 wxDisplaySize(&dx
, &dy
);
71 m_MaxWidth
= maxwidth
;
73 m_Scale
= (float)dx
* 2 / 3 / (float)maxwidth
;
74 // let the width of A4 is approximately 2/3 the screen width
76 m_Scale
= (float)800 / (float)maxwidth
;
77 // for now, assume screen width = 800 => good results
80 m_Parser
-> SetDC(dc
);
85 void wxHtmlDCRenderer::SetSize(int width
, int height
)
87 m_Width
= (int)(width
* m_Scale
);
88 m_Height
= (int)(height
* m_Scale
);
93 void wxHtmlDCRenderer::SetHtmlText(const wxString
& html
, const wxString
& basepath
, bool isdir
)
95 if (m_DC
== NULL
) return;
97 if (m_Cells
!= NULL
) delete m_Cells
;
99 m_FS
-> ChangePathTo(basepath
, isdir
);
100 m_DC
-> SetUserScale(1.0, 1.0);
101 m_Cells
= (wxHtmlContainerCell
*) m_Parser
-> Parse(html
);
102 m_Cells
-> SetIndent(0, wxHTML_INDENT_ALL
, wxHTML_UNITS_PIXELS
);
103 m_Cells
-> Layout(m_Width
);
108 int wxHtmlDCRenderer::Render(int x
, int y
, int from
, int dont_render
)
112 if (m_Cells
== NULL
|| m_DC
== NULL
) return 0;
114 pbreak
= (int)(from
* m_Scale
+ m_Height
);
115 while (m_Cells
-> AdjustPagebreak(&pbreak
)) {}
119 m_DC
-> GetSize(&w
, &h
);
120 float overallScale
= (float)(w
/(float)m_MaxWidth
) / m_Scale
;
121 m_DC
-> SetUserScale(overallScale
, overallScale
);
123 m_DC
-> SetBrush(*wxWHITE_BRUSH
);
125 m_DC
-> SetClippingRegion(x
* m_Scale
, y
* m_Scale
, m_Width
, m_Height
);
126 m_Cells
-> Draw(*m_DC
,
127 x
* m_Scale
, (y
- from
) * m_Scale
,
128 y
* m_Scale
, pbreak
+ (y
- from
) * m_Scale
);
129 m_DC
-> DestroyClippingRegion();
132 if (pbreak
< m_Cells
-> GetHeight()) return (int)(pbreak
/ m_Scale
);
133 else return GetTotalHeight();
138 int wxHtmlDCRenderer::GetTotalHeight()
140 if (m_Cells
) return (int)(m_Cells
-> GetHeight() / m_Scale
);
159 //--------------------------------------------------------------------------------
161 //--------------------------------------------------------------------------------
165 wxHtmlPrintout::wxHtmlPrintout(const wxString
& title
) : wxPrintout(title
)
167 m_Renderer
= new wxHtmlDCRenderer
;
168 m_RendererHdr
= new wxHtmlDCRenderer
;
169 m_NumPages
= wxHTML_PRINT_MAX_PAGES
;
170 m_Document
= m_BasePath
= wxEmptyString
; m_BasePathIsDir
= TRUE
;
171 m_Headers
[0] = m_Headers
[1] = wxEmptyString
;
172 m_Footers
[0] = m_Footers
[1] = wxEmptyString
;
173 m_HeaderHeight
= m_FooterHeight
= 0;
174 SetMargins(); // to default values
179 wxHtmlPrintout::~wxHtmlPrintout()
182 delete m_RendererHdr
;
187 bool wxHtmlPrintout::OnBeginDocument(int startPage
, int endPage
)
189 int pageWidth
, pageHeight
, mm_w
, mm_h
;
190 float ppmm_h
, ppmm_v
;
192 if (!wxPrintout::OnBeginDocument(startPage
, endPage
)) return FALSE
;
194 GetPageSizePixels(&pageWidth
, &pageHeight
);
195 GetPageSizeMM(&mm_w
, &mm_h
);
196 ppmm_h
= (float)pageWidth
/ mm_w
;
197 ppmm_v
= (float)pageHeight
/ mm_h
;
199 /* prepare headers/footers renderer: */
201 m_RendererHdr
-> SetDC(GetDC(), pageWidth
);
202 m_RendererHdr
-> SetSize(ppmm_h
* (mm_w
- m_MarginLeft
- m_MarginTop
),
203 ppmm_v
* (mm_h
- m_MarginTop
- m_MarginBottom
));
204 if (m_Headers
[0] != wxEmptyString
) {
205 m_RendererHdr
-> SetHtmlText(TranslateHeader(m_Headers
[0], 1));
206 m_HeaderHeight
= m_RendererHdr
-> GetTotalHeight();
208 else if (m_Headers
[1] != wxEmptyString
) {
209 m_RendererHdr
-> SetHtmlText(TranslateHeader(m_Headers
[1], 1));
210 m_HeaderHeight
= m_RendererHdr
-> GetTotalHeight();
212 if (m_Footers
[0] != wxEmptyString
) {
213 m_RendererHdr
-> SetHtmlText(TranslateHeader(m_Footers
[0], 1));
214 m_FooterHeight
= m_RendererHdr
-> GetTotalHeight();
216 else if (m_Footers
[1] != wxEmptyString
) {
217 m_RendererHdr
-> SetHtmlText(TranslateHeader(m_Footers
[1], 1));
218 m_FooterHeight
= m_RendererHdr
-> GetTotalHeight();
221 /* prepare main renderer: */
222 m_Renderer
-> SetDC(GetDC(), pageWidth
);
223 m_Renderer
-> SetSize(ppmm_h
* (mm_w
- m_MarginLeft
- m_MarginTop
),
224 ppmm_v
* (mm_h
- m_MarginTop
- m_MarginBottom
) -
225 m_FooterHeight
- m_HeaderHeight
-
226 ((m_HeaderHeight
== 0) ? 0 : m_MarginSpace
* ppmm_v
) -
227 ((m_FooterHeight
== 0) ? 0 : m_MarginSpace
* ppmm_v
)
229 m_Renderer
-> SetHtmlText(m_Document
, m_BasePath
, m_BasePathIsDir
);
235 bool wxHtmlPrintout::OnPrintPage(int page
)
240 RenderPage(dc
, page
);
247 void wxHtmlPrintout::GetPageInfo(int *minPage
, int *maxPage
, int *selPageFrom
, int *selPageTo
)
250 *maxPage
= wxHTML_PRINT_MAX_PAGES
;
252 *selPageTo
= wxHTML_PRINT_MAX_PAGES
;
257 bool wxHtmlPrintout::HasPage(int pageNum
)
259 return (pageNum
>= 1 && pageNum
<= m_NumPages
);
264 void wxHtmlPrintout::SetHtmlText(const wxString
& html
, const wxString
&basepath
, bool isdir
)
267 m_BasePath
= basepath
;
268 m_BasePathIsDir
= isdir
;
273 void wxHtmlPrintout::SetHtmlFile(const wxString
& htmlfile
)
276 wxFSFile
*ff
= fs
.OpenFile(htmlfile
);
277 wxInputStream
*st
= ff
-> GetStream();
278 char *t
= new char[st
-> GetSize() + 1];
279 st
-> Read(t
, st
-> GetSize());
280 t
[st
-> GetSize()] = 0;
282 wxString doc
= wxString(t
);
286 SetHtmlText(doc
, htmlfile
, FALSE
);
291 void wxHtmlPrintout::SetHeader(const wxString
& header
, int pg
)
293 if (pg
== wxPAGE_ALL
|| pg
== wxPAGE_EVEN
)
294 m_Headers
[0] = header
;
295 if (pg
== wxPAGE_ALL
|| pg
== wxPAGE_ODD
)
296 m_Headers
[1] = header
;
301 void wxHtmlPrintout::SetFooter(const wxString
& footer
, int pg
)
303 if (pg
== wxPAGE_ALL
|| pg
== wxPAGE_EVEN
)
304 m_Footers
[0] = footer
;
305 if (pg
== wxPAGE_ALL
|| pg
== wxPAGE_ODD
)
306 m_Footers
[1] = footer
;
311 void wxHtmlPrintout::CountPages()
314 int pageWidth
, pageHeight
, mm_w
, mm_h
;
315 float ppmm_h
, ppmm_v
;
317 GetPageSizePixels(&pageWidth
, &pageHeight
);
318 GetPageSizeMM(&mm_w
, &mm_h
);
319 ppmm_h
= (float)pageWidth
/ mm_w
;
320 ppmm_v
= (float)pageHeight
/ mm_h
;
328 pos
= m_Renderer
-> Render(ppmm_h
* m_MarginLeft
,
329 ppmm_v
* (m_MarginTop
+ (m_HeaderHeight
== 0 ? 0 : m_MarginSpace
)) + m_HeaderHeight
,
331 m_PageBreaks
[++m_NumPages
] = pos
;
332 } while (pos
< m_Renderer
-> GetTotalHeight());
337 void wxHtmlPrintout::RenderPage(wxDC
*dc
, int page
)
341 int pageWidth
, pageHeight
, mm_w
, mm_h
;
342 float ppmm_h
, ppmm_v
;
344 GetPageSizePixels(&pageWidth
, &pageHeight
);
345 GetPageSizeMM(&mm_w
, &mm_h
);
346 ppmm_h
= (float)pageWidth
/ mm_w
;
347 ppmm_v
= (float)pageHeight
/ mm_h
;
349 m_Renderer
-> SetDC(dc
, pageWidth
);
351 dc
-> SetBackgroundMode(wxTRANSPARENT
);
353 m_Renderer
-> Render(ppmm_h
* m_MarginLeft
,
354 ppmm_v
* (m_MarginTop
+ (m_HeaderHeight
== 0 ? 0 : m_MarginSpace
)) + m_HeaderHeight
,
355 m_PageBreaks
[page
-1]);
357 m_RendererHdr
-> SetDC(dc
, pageWidth
);
358 if (m_Headers
[page
% 2] != wxEmptyString
) {
359 m_RendererHdr
-> SetHtmlText(TranslateHeader(m_Headers
[page
% 2], page
));
360 m_RendererHdr
-> Render(ppmm_h
* m_MarginLeft
, ppmm_v
* m_MarginTop
);
362 if (m_Footers
[page
% 2] != wxEmptyString
) {
363 m_RendererHdr
-> SetHtmlText(TranslateHeader(m_Footers
[page
% 2], page
));
364 m_RendererHdr
-> Render(ppmm_h
* m_MarginLeft
, pageHeight
- ppmm_v
* m_MarginBottom
- m_FooterHeight
);
370 wxString
wxHtmlPrintout::TranslateHeader(const wxString
& instr
, int page
)
375 num
.Printf(wxT("%i"), page
);
376 r
.Replace(wxT("@PAGENUM@"), num
);
378 num
.Printf(wxT("%i"), m_NumPages
);
379 r
.Replace(wxT("@PAGESCNT@"), num
);
386 void wxHtmlPrintout::SetMargins(float top
, float bottom
, float left
, float right
, float spaces
)
389 m_MarginBottom
= bottom
;
391 m_MarginRight
= right
;
392 m_MarginSpace
= spaces
;
400 //--------------------------------------------------------------------------------
401 // wxHtmlEasyPrinting
402 //--------------------------------------------------------------------------------
405 wxHtmlEasyPrinting::wxHtmlEasyPrinting(const wxString
& name
, wxFrame
*parent_frame
)
407 m_Frame
= parent_frame
;
409 m_PrintData
= new wxPrintData
;
410 #if (defined __WXGTK__) || (defined __WXMOTIF__)
411 (*m_PrintData
) = (*wxThePrintSetupData
);
413 m_PageSetupData
= new wxPageSetupDialogData
;
414 m_Headers
[0] = m_Headers
[1] = m_Footers
[0] = m_Footers
[1] = wxEmptyString
;
416 m_PageSetupData
-> EnableMargins(TRUE
);
417 m_PageSetupData
-> SetMarginTopLeft(wxPoint(25, 25));
418 m_PageSetupData
-> SetMarginBottomRight(wxPoint(25, 25));
423 wxHtmlEasyPrinting::~wxHtmlEasyPrinting()
426 delete m_PageSetupData
;
431 void wxHtmlEasyPrinting::PreviewFile(const wxString
&htmlfile
)
433 wxHtmlPrintout
*p1
= CreatePrintout();
434 p1
-> SetHtmlFile(htmlfile
);
435 wxHtmlPrintout
*p2
= CreatePrintout();
436 p2
-> SetHtmlFile(htmlfile
);
442 void wxHtmlEasyPrinting::PreviewText(const wxString
&htmltext
, const wxString
&basepath
)
444 wxHtmlPrintout
*p1
= CreatePrintout();
445 p1
-> SetHtmlText(htmltext
, basepath
, TRUE
);
446 wxHtmlPrintout
*p2
= CreatePrintout();
447 p2
-> SetHtmlText(htmltext
, basepath
, TRUE
);
453 void wxHtmlEasyPrinting::PrintFile(const wxString
&htmlfile
)
455 wxHtmlPrintout
*p
= CreatePrintout();
456 p
-> SetHtmlFile(htmlfile
);
462 void wxHtmlEasyPrinting::PrintText(const wxString
&htmltext
, const wxString
&basepath
)
464 wxHtmlPrintout
*p
= CreatePrintout();
465 p
-> SetHtmlText(htmltext
, basepath
, TRUE
);
471 void wxHtmlEasyPrinting::DoPreview(wxHtmlPrintout
*printout1
, wxHtmlPrintout
*printout2
)
473 // Pass two printout objects: for preview, and possible printing.
474 wxPrintDialogData
printDialogData(*m_PrintData
);
475 wxPrintPreview
*preview
= new wxPrintPreview(printout1
, printout2
, &printDialogData
);
476 if (!preview
-> Ok()) {
478 wxMessageBox(_("There was a problem previewing.\nPerhaps your current printer is not set correctly?"), _("Previewing"), wxOK
);
482 wxPreviewFrame
*frame
= new wxPreviewFrame(preview
, m_Frame
,
483 m_Name
+ _(" Preview"),
484 wxPoint(100, 100), wxSize(650, 500));
485 frame
-> Centre(wxBOTH
);
486 frame
-> Initialize();
493 void wxHtmlEasyPrinting::DoPrint(wxHtmlPrintout
*printout
)
495 wxPrintDialogData
printDialogData(*m_PrintData
);
496 wxPrinter
printer(&printDialogData
);
498 if (!printer
.Print(m_Frame
, printout
, TRUE
))
499 wxMessageBox(_("There was a problem printing.\nPerhaps your current printer is not set correctly?"), _("Printing"), wxOK
);
501 (*m_PrintData
) = printer
.GetPrintDialogData().GetPrintData();
506 void wxHtmlEasyPrinting::PrinterSetup()
508 wxPrintDialogData
printDialogData(*m_PrintData
);
509 wxPrintDialog
printerDialog(m_Frame
, &printDialogData
);
511 printerDialog
.GetPrintDialogData().SetSetupDialog(TRUE
);
513 if (printerDialog
.ShowModal() == wxID_OK
)
514 (*m_PrintData
) = printerDialog
.GetPrintDialogData().GetPrintData();
519 void wxHtmlEasyPrinting::PageSetup()
521 m_PageSetupData
-> SetPrintData(*m_PrintData
);
522 wxPageSetupDialog
pageSetupDialog(m_Frame
, m_PageSetupData
);
524 if (pageSetupDialog
.ShowModal() == wxID_OK
) {
525 (*m_PrintData
) = pageSetupDialog
.GetPageSetupData().GetPrintData();
526 (*m_PageSetupData
) = pageSetupDialog
.GetPageSetupData();
532 void wxHtmlEasyPrinting::SetHeader(const wxString
& header
, int pg
)
534 if (pg
== wxPAGE_ALL
|| pg
== wxPAGE_EVEN
)
535 m_Headers
[0] = header
;
536 if (pg
== wxPAGE_ALL
|| pg
== wxPAGE_ODD
)
537 m_Headers
[1] = header
;
542 void wxHtmlEasyPrinting::SetFooter(const wxString
& footer
, int pg
)
544 if (pg
== wxPAGE_ALL
|| pg
== wxPAGE_EVEN
)
545 m_Footers
[0] = footer
;
546 if (pg
== wxPAGE_ALL
|| pg
== wxPAGE_ODD
)
547 m_Footers
[1] = footer
;
552 wxHtmlPrintout
*wxHtmlEasyPrinting::CreatePrintout()
554 wxHtmlPrintout
*p
= new wxHtmlPrintout(m_Name
);
556 p
-> SetHeader(m_Headers
[0], wxPAGE_EVEN
);
557 p
-> SetHeader(m_Headers
[1], wxPAGE_ODD
);
558 p
-> SetFooter(m_Footers
[0], wxPAGE_EVEN
);
559 p
-> SetFooter(m_Footers
[1], wxPAGE_ODD
);
561 p
-> SetMargins(m_PageSetupData
-> GetMarginTopLeft().y
,
562 m_PageSetupData
-> GetMarginBottomRight().y
,
563 m_PageSetupData
-> GetMarginTopLeft().x
,
564 m_PageSetupData
-> GetMarginBottomRight().x
);
571 #endif // wxUSE_HTML & wxUSE_PRINTING_ARCHITECTURE