]>
git.saurik.com Git - wxWidgets.git/blob - src/html/htmprint.cpp
30b3dc23b35fe172c51ed59467f23d09432d7385
1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: html printing classes
4 // Author: Vaclav Slavik
7 // Copyright: (c) Vaclav Slavik, 1999
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation
16 // For compilers that support precompilation, includes "wx/wx.h".
17 #include "wx/wxprec.h"
27 #if wxUSE_HTML & wxUSE_PRINTING_ARCHITECTURE
30 #include "wx/printdlg.h"
31 #include "wx/html/htmprint.h"
32 #include "wx/wxhtml.h"
33 #include "wx/wfstream.h"
36 //--------------------------------------------------------------------------------
38 //--------------------------------------------------------------------------------
41 wxHtmlDCRenderer::wxHtmlDCRenderer() : wxObject()
44 m_Width
= m_Height
= 0;
46 m_Parser
= new wxHtmlWinParser(NULL
);
47 m_FS
= new wxFileSystem();
48 m_Parser
-> SetFS(m_FS
);
54 wxHtmlDCRenderer::~wxHtmlDCRenderer()
56 if (m_Cells
) delete m_Cells
;
57 if (m_Parser
) delete m_Parser
;
58 if (m_FS
) delete m_FS
;
63 void wxHtmlDCRenderer::SetDC(wxDC
*dc
, int maxwidth
)
67 wxDisplaySize(&dx
, &dy
);
68 m_MaxWidth
= maxwidth
;
70 m_Scale
= (float)dx
* 2 / 3 / (float)maxwidth
;
71 // let the width of A4 is approximately 2/3 the screen width
73 m_Scale
= (float)800 / (float)maxwidth
;
74 // for now, assume screen width = 800 => good results
77 m_Parser
-> SetDC(dc
);
82 void wxHtmlDCRenderer::SetSize(int width
, int height
)
84 m_Width
= (int)(width
* m_Scale
);
85 m_Height
= (int)(height
* m_Scale
);
90 void wxHtmlDCRenderer::SetHtmlText(const wxString
& html
, const wxString
& basepath
, bool isdir
)
92 if (m_DC
== NULL
) return;
94 if (m_Cells
!= NULL
) delete m_Cells
;
96 m_FS
-> ChangePathTo(basepath
, isdir
);
97 m_DC
-> SetUserScale(1.0, 1.0);
98 m_Cells
= (wxHtmlContainerCell
*) m_Parser
-> Parse(html
);
99 m_Cells
-> SetIndent(0, wxHTML_INDENT_ALL
, wxHTML_UNITS_PIXELS
);
100 m_Cells
-> Layout(m_Width
);
105 int wxHtmlDCRenderer::Render(int x
, int y
, int from
, int dont_render
)
109 if (m_Cells
== NULL
|| m_DC
== NULL
) return 0;
111 pbreak
= (int)(from
* m_Scale
+ m_Height
);
112 while (m_Cells
-> AdjustPagebreak(&pbreak
)) {}
116 m_DC
-> GetSize(&w
, &h
);
117 float overallScale
= (float)(w
/(float)m_MaxWidth
) / m_Scale
;
118 m_DC
-> SetUserScale(overallScale
, overallScale
);
120 m_DC
-> SetBrush(*wxWHITE_BRUSH
);
122 m_DC
-> SetClippingRegion(x
* m_Scale
, y
* m_Scale
, m_Width
, m_Height
);
123 m_Cells
-> Draw(*m_DC
,
124 x
* m_Scale
, (y
- from
) * m_Scale
,
125 y
* m_Scale
, pbreak
+ (y
- from
) * m_Scale
);
126 m_DC
-> DestroyClippingRegion();
129 if (pbreak
< m_Cells
-> GetHeight()) return (int)(pbreak
/ m_Scale
);
130 else return GetTotalHeight();
135 int wxHtmlDCRenderer::GetTotalHeight()
137 if (m_Cells
) return (int)(m_Cells
-> GetHeight() / m_Scale
);
156 //--------------------------------------------------------------------------------
158 //--------------------------------------------------------------------------------
162 wxHtmlPrintout::wxHtmlPrintout(const wxString
& title
) : wxPrintout(title
)
164 m_Renderer
= new wxHtmlDCRenderer
;
165 m_RendererHdr
= new wxHtmlDCRenderer
;
166 m_NumPages
= wxHTML_PRINT_MAX_PAGES
;
167 m_Document
= m_BasePath
= wxEmptyString
; m_BasePathIsDir
= TRUE
;
168 m_Headers
[0] = m_Headers
[1] = wxEmptyString
;
169 m_Footers
[0] = m_Footers
[1] = wxEmptyString
;
170 m_HeaderHeight
= m_FooterHeight
= 0;
171 SetMargins(); // to default values
176 wxHtmlPrintout::~wxHtmlPrintout()
179 delete m_RendererHdr
;
184 void wxHtmlPrintout::OnBeginPrinting()
186 int pageWidth
, pageHeight
, mm_w
, mm_h
;
187 float ppmm_h
, ppmm_v
;
189 wxPrintout::OnBeginPrinting();
191 GetPageSizePixels(&pageWidth
, &pageHeight
);
192 GetPageSizeMM(&mm_w
, &mm_h
);
193 ppmm_h
= (float)pageWidth
/ mm_w
;
194 ppmm_v
= (float)pageHeight
/ mm_h
;
196 /* prepare headers/footers renderer: */
198 m_RendererHdr
-> SetDC(GetDC(), pageWidth
);
199 m_RendererHdr
-> SetSize(ppmm_h
* (mm_w
- m_MarginLeft
- m_MarginTop
),
200 ppmm_v
* (mm_h
- m_MarginTop
- m_MarginBottom
));
201 if (m_Headers
[0] != wxEmptyString
) {
202 m_RendererHdr
-> SetHtmlText(TranslateHeader(m_Headers
[0], 1));
203 m_HeaderHeight
= m_RendererHdr
-> GetTotalHeight();
205 else if (m_Headers
[1] != wxEmptyString
) {
206 m_RendererHdr
-> SetHtmlText(TranslateHeader(m_Headers
[1], 1));
207 m_HeaderHeight
= m_RendererHdr
-> GetTotalHeight();
209 if (m_Footers
[0] != wxEmptyString
) {
210 m_RendererHdr
-> SetHtmlText(TranslateHeader(m_Footers
[0], 1));
211 m_FooterHeight
= m_RendererHdr
-> GetTotalHeight();
213 else if (m_Footers
[1] != wxEmptyString
) {
214 m_RendererHdr
-> SetHtmlText(TranslateHeader(m_Footers
[1], 1));
215 m_FooterHeight
= m_RendererHdr
-> GetTotalHeight();
218 /* prepare main renderer: */
219 m_Renderer
-> SetDC(GetDC(), pageWidth
);
220 m_Renderer
-> SetSize(ppmm_h
* (mm_w
- m_MarginLeft
- m_MarginTop
),
221 ppmm_v
* (mm_h
- m_MarginTop
- m_MarginBottom
) -
222 m_FooterHeight
- m_HeaderHeight
-
223 ((m_HeaderHeight
== 0) ? 0 : m_MarginSpace
* ppmm_v
) -
224 ((m_FooterHeight
== 0) ? 0 : m_MarginSpace
* ppmm_v
)
226 m_Renderer
-> SetHtmlText(m_Document
, m_BasePath
, m_BasePathIsDir
);
231 bool wxHtmlPrintout::OnPrintPage(int page
)
236 RenderPage(dc
, page
);
243 void wxHtmlPrintout::GetPageInfo(int *minPage
, int *maxPage
, int *selPageFrom
, int *selPageTo
)
246 *maxPage
= wxHTML_PRINT_MAX_PAGES
;
248 *selPageTo
= wxHTML_PRINT_MAX_PAGES
;
253 bool wxHtmlPrintout::HasPage(int pageNum
)
255 return (pageNum
>= 1 && pageNum
<= m_NumPages
);
260 void wxHtmlPrintout::SetHtmlText(const wxString
& html
, const wxString
&basepath
, bool isdir
)
263 m_BasePath
= basepath
;
264 m_BasePathIsDir
= isdir
;
269 void wxHtmlPrintout::SetHtmlFile(const wxString
& htmlfile
)
272 wxFSFile
*ff
= fs
.OpenFile(htmlfile
);
273 wxInputStream
*st
= ff
-> GetStream();
274 char *t
= new char[st
-> GetSize() + 1];
275 st
-> Read(t
, st
-> GetSize());
276 t
[st
-> GetSize()] = 0;
278 wxString doc
= wxString(t
);
282 SetHtmlText(doc
, htmlfile
, FALSE
);
287 void wxHtmlPrintout::SetHeader(const wxString
& header
, int pg
)
289 if (pg
== wxPAGE_ALL
|| pg
== wxPAGE_EVEN
)
290 m_Headers
[0] = header
;
291 if (pg
== wxPAGE_ALL
|| pg
== wxPAGE_ODD
)
292 m_Headers
[1] = header
;
297 void wxHtmlPrintout::SetFooter(const wxString
& footer
, int pg
)
299 if (pg
== wxPAGE_ALL
|| pg
== wxPAGE_EVEN
)
300 m_Footers
[0] = footer
;
301 if (pg
== wxPAGE_ALL
|| pg
== wxPAGE_ODD
)
302 m_Footers
[1] = footer
;
307 void wxHtmlPrintout::CountPages()
310 int pageWidth
, pageHeight
, mm_w
, mm_h
;
311 float ppmm_h
, ppmm_v
;
313 GetPageSizePixels(&pageWidth
, &pageHeight
);
314 GetPageSizeMM(&mm_w
, &mm_h
);
315 ppmm_h
= (float)pageWidth
/ mm_w
;
316 ppmm_v
= (float)pageHeight
/ mm_h
;
324 pos
= m_Renderer
-> Render(ppmm_h
* m_MarginLeft
,
325 ppmm_v
* (m_MarginTop
+ (m_HeaderHeight
== 0 ? 0 : m_MarginSpace
)) + m_HeaderHeight
,
327 m_PageBreaks
[++m_NumPages
] = pos
;
328 } while (pos
< m_Renderer
-> GetTotalHeight());
333 void wxHtmlPrintout::RenderPage(wxDC
*dc
, int page
)
337 int pageWidth
, pageHeight
, mm_w
, mm_h
;
338 float ppmm_h
, ppmm_v
;
340 GetPageSizePixels(&pageWidth
, &pageHeight
);
341 GetPageSizeMM(&mm_w
, &mm_h
);
342 ppmm_h
= (float)pageWidth
/ mm_w
;
343 ppmm_v
= (float)pageHeight
/ mm_h
;
345 m_Renderer
-> SetDC(dc
, pageWidth
);
347 dc
-> SetBackgroundMode(wxTRANSPARENT
);
349 m_Renderer
-> Render(ppmm_h
* m_MarginLeft
,
350 ppmm_v
* (m_MarginTop
+ (m_HeaderHeight
== 0 ? 0 : m_MarginSpace
)) + m_HeaderHeight
,
351 m_PageBreaks
[page
-1]);
353 m_RendererHdr
-> SetDC(dc
, pageWidth
);
354 if (m_Headers
[page
% 2] != wxEmptyString
) {
355 m_RendererHdr
-> SetHtmlText(TranslateHeader(m_Headers
[page
% 2], page
));
356 m_RendererHdr
-> Render(ppmm_h
* m_MarginLeft
, ppmm_v
* m_MarginTop
);
358 if (m_Footers
[page
% 2] != wxEmptyString
) {
359 m_RendererHdr
-> SetHtmlText(TranslateHeader(m_Footers
[page
% 2], page
));
360 m_RendererHdr
-> Render(ppmm_h
* m_MarginLeft
, pageHeight
- ppmm_v
* m_MarginBottom
- m_FooterHeight
);
366 wxString
wxHtmlPrintout::TranslateHeader(const wxString
& instr
, int page
)
371 num
.Printf("%i", page
);
372 r
.Replace("@PAGENUM@", num
);
374 num
.Printf("%i", m_NumPages
);
375 r
.Replace("@PAGESCNT@", num
);
382 void wxHtmlPrintout::SetMargins(float top
, float bottom
, float left
, float right
, float spaces
)
385 m_MarginBottom
= bottom
;
387 m_MarginRight
= right
;
388 m_MarginSpace
= spaces
;
396 //--------------------------------------------------------------------------------
397 // wxHtmlEasyPrinting
398 //--------------------------------------------------------------------------------
401 wxHtmlEasyPrinting::wxHtmlEasyPrinting(const wxString
& name
, wxFrame
*parent_frame
)
403 m_Frame
= parent_frame
;
405 m_PrintData
= new wxPrintData
;
406 m_PageSetupData
= new wxPageSetupDialogData
;
407 m_Headers
[0] = m_Headers
[1] = m_Footers
[0] = m_Footers
[1] = wxEmptyString
;
409 m_PageSetupData
-> EnableMargins(TRUE
);
410 m_PageSetupData
-> SetMarginTopLeft(wxPoint(25, 25));
411 m_PageSetupData
-> SetMarginBottomRight(wxPoint(25, 25));
413 #if defined(__WXGTK__) || defined(__WXMOTIF__)
414 m_PrintData
-> SetPrinterCommand("lpr");
420 wxHtmlEasyPrinting::~wxHtmlEasyPrinting()
423 delete m_PageSetupData
;
428 void wxHtmlEasyPrinting::PreviewFile(const wxString
&htmlfile
)
430 wxHtmlPrintout
*p1
= CreatePrintout();
431 p1
-> SetHtmlFile(htmlfile
);
432 wxHtmlPrintout
*p2
= CreatePrintout();
433 p2
-> SetHtmlFile(htmlfile
);
439 void wxHtmlEasyPrinting::PreviewText(const wxString
&htmltext
, const wxString
&basepath
)
441 wxHtmlPrintout
*p1
= CreatePrintout();
442 p1
-> SetHtmlText(htmltext
, basepath
, TRUE
);
443 wxHtmlPrintout
*p2
= CreatePrintout();
444 p2
-> SetHtmlText(htmltext
, basepath
, TRUE
);
450 void wxHtmlEasyPrinting::PrintFile(const wxString
&htmlfile
)
452 wxHtmlPrintout
*p
= CreatePrintout();
453 p
-> SetHtmlFile(htmlfile
);
459 void wxHtmlEasyPrinting::PrintText(const wxString
&htmltext
, const wxString
&basepath
)
461 wxHtmlPrintout
*p
= CreatePrintout();
462 p
-> SetHtmlText(htmltext
, basepath
, TRUE
);
468 void wxHtmlEasyPrinting::DoPreview(wxHtmlPrintout
*printout1
, wxHtmlPrintout
*printout2
)
470 // Pass two printout objects: for preview, and possible printing.
471 wxPrintDialogData
printDialogData(*m_PrintData
);
472 wxPrintPreview
*preview
= new wxPrintPreview(printout1
, printout2
, &printDialogData
);
473 if (!preview
-> Ok()) {
475 wxMessageBox(_("There was a problem previewing.\nPerhaps your current printer is not set correctly?"), _("Previewing"), wxOK
);
479 wxPreviewFrame
*frame
= new wxPreviewFrame(preview
, m_Frame
,
480 m_Name
+ _(" Preview"),
481 wxPoint(100, 100), wxSize(650, 500));
482 frame
-> Centre(wxBOTH
);
483 frame
-> Initialize();
490 void wxHtmlEasyPrinting::DoPrint(wxHtmlPrintout
*printout
)
492 wxPrintDialogData
printDialogData(*m_PrintData
);
493 wxPrinter
printer(&printDialogData
);
495 if (!printer
.Print(m_Frame
, printout
, TRUE
))
496 wxMessageBox(_("There was a problem printing.\nPerhaps your current printer is not set correctly?"), _("Printing"), wxOK
);
498 (*m_PrintData
) = printer
.GetPrintDialogData().GetPrintData();
503 void wxHtmlEasyPrinting::PrinterSetup()
505 wxPrintDialogData
printDialogData(*m_PrintData
);
506 wxPrintDialog
printerDialog(m_Frame
, &printDialogData
);
508 printerDialog
.GetPrintDialogData().SetSetupDialog(TRUE
);
510 if (printerDialog
.ShowModal() == wxID_OK
)
511 (*m_PrintData
) = printerDialog
.GetPrintDialogData().GetPrintData();
516 void wxHtmlEasyPrinting::PageSetup()
518 m_PageSetupData
-> SetPrintData(*m_PrintData
);
519 wxPageSetupDialog
pageSetupDialog(m_Frame
, m_PageSetupData
);
521 if (pageSetupDialog
.ShowModal() == wxID_OK
) {
522 (*m_PrintData
) = pageSetupDialog
.GetPageSetupData().GetPrintData();
523 (*m_PageSetupData
) = pageSetupDialog
.GetPageSetupData();
529 void wxHtmlEasyPrinting::SetHeader(const wxString
& header
, int pg
)
531 if (pg
== wxPAGE_ALL
|| pg
== wxPAGE_EVEN
)
532 m_Headers
[0] = header
;
533 if (pg
== wxPAGE_ALL
|| pg
== wxPAGE_ODD
)
534 m_Headers
[1] = header
;
539 void wxHtmlEasyPrinting::SetFooter(const wxString
& footer
, int pg
)
541 if (pg
== wxPAGE_ALL
|| pg
== wxPAGE_EVEN
)
542 m_Footers
[0] = footer
;
543 if (pg
== wxPAGE_ALL
|| pg
== wxPAGE_ODD
)
544 m_Footers
[1] = footer
;
549 wxHtmlPrintout
*wxHtmlEasyPrinting::CreatePrintout()
551 wxHtmlPrintout
*p
= new wxHtmlPrintout(m_Name
);
553 p
-> SetHeader(m_Headers
[0], wxPAGE_EVEN
);
554 p
-> SetHeader(m_Headers
[1], wxPAGE_ODD
);
555 p
-> SetFooter(m_Footers
[0], wxPAGE_EVEN
);
556 p
-> SetFooter(m_Footers
[1], wxPAGE_ODD
);
558 p
-> SetMargins(m_PageSetupData
-> GetMarginTopLeft().y
,
559 m_PageSetupData
-> GetMarginBottomRight().y
,
560 m_PageSetupData
-> GetMarginTopLeft().x
,
561 m_PageSetupData
-> GetMarginBottomRight().x
);
568 #endif // wxUSE_HTML & wxUSE_PRINTING_ARCHITECTURE