]>
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
16 // For compilers that support precompilation, includes "wx/wx.h".
17 #include "wx/wxprec.h"
30 #if wxUSE_HTML && wxUSE_PRINTING_ARCHITECTURE && wxUSE_STREAMS
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
);
56 wxHtmlDCRenderer::~wxHtmlDCRenderer()
58 if (m_Cells
) delete m_Cells
;
59 if (m_Parser
) delete m_Parser
;
60 if (m_FS
) delete m_FS
;
65 void wxHtmlDCRenderer::SetDC(wxDC
*dc
, double pixel_scale
)
68 m_Parser
->SetDC(m_DC
, pixel_scale
);
73 void wxHtmlDCRenderer::SetSize(int width
, int height
)
81 void wxHtmlDCRenderer::SetHtmlText(const wxString
& html
, const wxString
& basepath
, bool isdir
)
83 if (m_DC
== NULL
) return;
85 if (m_Cells
!= NULL
) delete m_Cells
;
87 m_FS
->ChangePathTo(basepath
, isdir
);
88 m_Cells
= (wxHtmlContainerCell
*) m_Parser
->Parse(html
);
89 m_Cells
->SetIndent(0, wxHTML_INDENT_ALL
, wxHTML_UNITS_PIXELS
);
90 m_Cells
->Layout(m_Width
);
95 int wxHtmlDCRenderer::Render(int x
, int y
, int from
, int dont_render
)
99 if (m_Cells
== NULL
|| m_DC
== NULL
) return 0;
101 pbreak
= (int)(from
+ m_Height
);
102 while (m_Cells
->AdjustPagebreak(&pbreak
)) {}
103 hght
= pbreak
- from
;
107 m_DC
->SetBrush(*wxWHITE_BRUSH
);
109 m_DC
->SetClippingRegion(x
, y
, m_Width
, hght
);
112 y
, pbreak
+ (y
/*- from*/));
113 m_DC
->DestroyClippingRegion();
116 if (pbreak
< m_Cells
->GetHeight()) return pbreak
;
117 else return GetTotalHeight();
122 int wxHtmlDCRenderer::GetTotalHeight()
124 if (m_Cells
) return m_Cells
->GetHeight();
143 //--------------------------------------------------------------------------------
145 //--------------------------------------------------------------------------------
149 wxHtmlPrintout::wxHtmlPrintout(const wxString
& title
) : wxPrintout(title
)
151 m_Renderer
= new wxHtmlDCRenderer
;
152 m_RendererHdr
= new wxHtmlDCRenderer
;
153 m_NumPages
= wxHTML_PRINT_MAX_PAGES
;
154 m_Document
= m_BasePath
= wxEmptyString
; m_BasePathIsDir
= TRUE
;
155 m_Headers
[0] = m_Headers
[1] = wxEmptyString
;
156 m_Footers
[0] = m_Footers
[1] = wxEmptyString
;
157 m_HeaderHeight
= m_FooterHeight
= 0;
158 SetMargins(); // to default values
163 wxHtmlPrintout::~wxHtmlPrintout()
166 delete m_RendererHdr
;
171 bool wxHtmlPrintout::OnBeginDocument(int startPage
, int endPage
)
173 int pageWidth
, pageHeight
, mm_w
, mm_h
, scr_w
, scr_h
, dc_w
, dc_h
;
174 float ppmm_h
, ppmm_v
;
176 if (!wxPrintout::OnBeginDocument(startPage
, endPage
)) return FALSE
;
178 GetPageSizePixels(&pageWidth
, &pageHeight
);
179 GetPageSizeMM(&mm_w
, &mm_h
);
180 ppmm_h
= (float)pageWidth
/ mm_w
;
181 ppmm_v
= (float)pageHeight
/ mm_h
;
183 int ppiPrinterX
, ppiPrinterY
;
184 GetPPIPrinter(&ppiPrinterX
, &ppiPrinterY
);
185 int ppiScreenX
, ppiScreenY
;
186 GetPPIScreen(&ppiScreenX
, &ppiScreenY
);
188 wxDisplaySize(&scr_w
, &scr_h
);
189 GetDC()->GetSize(&dc_w
, &dc_h
);
191 GetDC()->SetUserScale((double)dc_w
/ (double)pageWidth
, (double)dc_w
/ (double)pageWidth
);
193 /* prepare headers/footers renderer: */
195 m_RendererHdr
->SetDC(GetDC(), (double)ppiPrinterY
/ (double)ppiScreenY
);
196 m_RendererHdr
->SetSize((int) (ppmm_h
* (mm_w
- m_MarginLeft
- m_MarginRight
)),
197 (int) (ppmm_v
* (mm_h
- m_MarginTop
- m_MarginBottom
)));
198 if (m_Headers
[0] != wxEmptyString
)
200 m_RendererHdr
->SetHtmlText(TranslateHeader(m_Headers
[0], 1));
201 m_HeaderHeight
= m_RendererHdr
->GetTotalHeight();
203 else if (m_Headers
[1] != wxEmptyString
)
205 m_RendererHdr
->SetHtmlText(TranslateHeader(m_Headers
[1], 1));
206 m_HeaderHeight
= m_RendererHdr
->GetTotalHeight();
208 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
)
215 m_RendererHdr
->SetHtmlText(TranslateHeader(m_Footers
[1], 1));
216 m_FooterHeight
= m_RendererHdr
->GetTotalHeight();
219 /* prepare main renderer: */
220 m_Renderer
->SetDC(GetDC(), (double)ppiPrinterY
/ (double)ppiScreenY
);
221 m_Renderer
->SetSize((int) (ppmm_h
* (mm_w
- m_MarginLeft
- m_MarginRight
)),
222 (int) (ppmm_v
* (mm_h
- m_MarginTop
- m_MarginBottom
) -
223 m_FooterHeight
- m_HeaderHeight
-
224 ((m_HeaderHeight
== 0) ? 0 : m_MarginSpace
* ppmm_v
) -
225 ((m_FooterHeight
== 0) ? 0 : m_MarginSpace
* ppmm_v
)
227 m_Renderer
->SetHtmlText(m_Document
, m_BasePath
, m_BasePathIsDir
);
233 bool wxHtmlPrintout::OnPrintPage(int page
)
239 RenderPage(dc
, page
);
246 void wxHtmlPrintout::GetPageInfo(int *minPage
, int *maxPage
, int *selPageFrom
, int *selPageTo
)
249 *maxPage
= wxHTML_PRINT_MAX_PAGES
;
251 *selPageTo
= wxHTML_PRINT_MAX_PAGES
;
256 bool wxHtmlPrintout::HasPage(int pageNum
)
258 return (pageNum
>= 1 && pageNum
<= m_NumPages
);
263 void wxHtmlPrintout::SetHtmlText(const wxString
& html
, const wxString
&basepath
, bool isdir
)
266 m_BasePath
= basepath
;
267 m_BasePathIsDir
= isdir
;
272 void wxHtmlPrintout::SetHtmlFile(const wxString
& htmlfile
)
275 wxFSFile
*ff
= fs
.OpenFile(htmlfile
);
279 wxLogError(htmlfile
+ _(": file does not exist!"));
283 wxInputStream
*st
= ff
->GetStream();
284 char *t
= new char[st
->GetSize() + 1];
285 st
->Read(t
, st
->GetSize());
286 t
[st
->GetSize()] = 0;
288 wxString doc
= wxString(t
);
292 SetHtmlText(doc
, htmlfile
, FALSE
);
297 void wxHtmlPrintout::SetHeader(const wxString
& header
, int pg
)
299 if (pg
== wxPAGE_ALL
|| pg
== wxPAGE_EVEN
)
300 m_Headers
[0] = header
;
301 if (pg
== wxPAGE_ALL
|| pg
== wxPAGE_ODD
)
302 m_Headers
[1] = header
;
307 void wxHtmlPrintout::SetFooter(const wxString
& footer
, int pg
)
309 if (pg
== wxPAGE_ALL
|| pg
== wxPAGE_EVEN
)
310 m_Footers
[0] = footer
;
311 if (pg
== wxPAGE_ALL
|| pg
== wxPAGE_ODD
)
312 m_Footers
[1] = footer
;
317 void wxHtmlPrintout::CountPages()
320 int pageWidth
, pageHeight
, mm_w
, mm_h
;
321 float ppmm_h
, ppmm_v
;
323 GetPageSizePixels(&pageWidth
, &pageHeight
);
324 GetPageSizeMM(&mm_w
, &mm_h
);
325 ppmm_h
= (float)pageWidth
/ mm_w
;
326 ppmm_v
= (float)pageHeight
/ mm_h
;
335 pos
= m_Renderer
->Render((int)( ppmm_h
* m_MarginLeft
),
336 (int) (ppmm_v
* (m_MarginTop
+ (m_HeaderHeight
== 0 ? 0 : m_MarginSpace
)) + m_HeaderHeight
),
338 m_PageBreaks
[++m_NumPages
] = pos
;
339 } while (pos
< m_Renderer
->GetTotalHeight());
344 void wxHtmlPrintout::RenderPage(wxDC
*dc
, int page
)
348 int pageWidth
, pageHeight
, mm_w
, mm_h
, scr_w
, scr_h
, dc_w
, dc_h
;
349 float ppmm_h
, ppmm_v
;
351 GetPageSizePixels(&pageWidth
, &pageHeight
);
352 GetPageSizeMM(&mm_w
, &mm_h
);
353 ppmm_h
= (float)pageWidth
/ mm_w
;
354 ppmm_v
= (float)pageHeight
/ mm_h
;
355 wxDisplaySize(&scr_w
, &scr_h
);
356 dc
->GetSize(&dc_w
, &dc_h
);
358 int ppiPrinterX
, ppiPrinterY
;
359 GetPPIPrinter(&ppiPrinterX
, &ppiPrinterY
);
360 int ppiScreenX
, ppiScreenY
;
361 GetPPIScreen(&ppiScreenX
, &ppiScreenY
);
363 dc
->SetUserScale((double)dc_w
/ (double)pageWidth
, (double)dc_w
/ (double)pageWidth
);
365 m_Renderer
->SetDC(dc
, (double)ppiPrinterY
/ (double)ppiScreenY
);
367 dc
->SetBackgroundMode(wxTRANSPARENT
);
369 m_Renderer
->Render((int) (ppmm_h
* m_MarginLeft
),
370 (int) (ppmm_v
* (m_MarginTop
+ (m_HeaderHeight
== 0 ? 0 : m_MarginSpace
)) + m_HeaderHeight
),
371 m_PageBreaks
[page
-1]);
373 m_RendererHdr
->SetDC(dc
, (double)ppiPrinterY
/ (double)ppiScreenY
);
374 if (m_Headers
[page
% 2] != wxEmptyString
)
376 m_RendererHdr
->SetHtmlText(TranslateHeader(m_Headers
[page
% 2], page
));
377 m_RendererHdr
->Render((int) (ppmm_h
* m_MarginLeft
), (int) (ppmm_v
* m_MarginTop
));
379 if (m_Footers
[page
% 2] != wxEmptyString
)
381 m_RendererHdr
->SetHtmlText(TranslateHeader(m_Footers
[page
% 2], page
));
382 m_RendererHdr
->Render((int) (ppmm_h
* m_MarginLeft
), (int) (pageHeight
- ppmm_v
* m_MarginBottom
- m_FooterHeight
));
388 wxString
wxHtmlPrintout::TranslateHeader(const wxString
& instr
, int page
)
393 num
.Printf(wxT("%i"), page
);
394 r
.Replace(wxT("@PAGENUM@"), num
);
396 num
.Printf(wxT("%i"), m_NumPages
);
397 r
.Replace(wxT("@PAGESCNT@"), num
);
404 void wxHtmlPrintout::SetMargins(float top
, float bottom
, float left
, float right
, float spaces
)
407 m_MarginBottom
= bottom
;
409 m_MarginRight
= right
;
410 m_MarginSpace
= spaces
;
418 //--------------------------------------------------------------------------------
419 // wxHtmlEasyPrinting
420 //--------------------------------------------------------------------------------
423 wxHtmlEasyPrinting::wxHtmlEasyPrinting(const wxString
& name
, wxFrame
*parent_frame
)
425 m_Frame
= parent_frame
;
427 m_PrintData
= new wxPrintData
;
428 #if (defined __WXGTK__) || (defined __WXMOTIF__)
429 (*m_PrintData
) = (*wxThePrintSetupData
);
431 m_PageSetupData
= new wxPageSetupDialogData
;
432 m_Headers
[0] = m_Headers
[1] = m_Footers
[0] = m_Footers
[1] = wxEmptyString
;
434 m_PageSetupData
->EnableMargins(TRUE
);
435 m_PageSetupData
->SetMarginTopLeft(wxPoint(25, 25));
436 m_PageSetupData
->SetMarginBottomRight(wxPoint(25, 25));
441 wxHtmlEasyPrinting::~wxHtmlEasyPrinting()
444 delete m_PageSetupData
;
449 bool wxHtmlEasyPrinting::PreviewFile(const wxString
&htmlfile
)
451 wxHtmlPrintout
*p1
= CreatePrintout();
452 p1
->SetHtmlFile(htmlfile
);
453 wxHtmlPrintout
*p2
= CreatePrintout();
454 p2
->SetHtmlFile(htmlfile
);
455 return DoPreview(p1
, p2
);
460 bool wxHtmlEasyPrinting::PreviewText(const wxString
&htmltext
, const wxString
&basepath
)
462 wxHtmlPrintout
*p1
= CreatePrintout();
463 p1
->SetHtmlText(htmltext
, basepath
, TRUE
);
464 wxHtmlPrintout
*p2
= CreatePrintout();
465 p2
->SetHtmlText(htmltext
, basepath
, TRUE
);
466 return DoPreview(p1
, p2
);
471 bool wxHtmlEasyPrinting::PrintFile(const wxString
&htmlfile
)
473 wxHtmlPrintout
*p
= CreatePrintout();
474 p
->SetHtmlFile(htmlfile
);
475 bool ret
= DoPrint(p
);
482 bool wxHtmlEasyPrinting::PrintText(const wxString
&htmltext
, const wxString
&basepath
)
484 wxHtmlPrintout
*p
= CreatePrintout();
485 p
->SetHtmlText(htmltext
, basepath
, TRUE
);
486 bool ret
= DoPrint(p
);
493 bool wxHtmlEasyPrinting::DoPreview(wxHtmlPrintout
*printout1
, wxHtmlPrintout
*printout2
)
495 // Pass two printout objects: for preview, and possible printing.
496 wxPrintDialogData
printDialogData(*m_PrintData
);
497 wxPrintPreview
*preview
= new wxPrintPreview(printout1
, printout2
, &printDialogData
);
504 wxPreviewFrame
*frame
= new wxPreviewFrame(preview
, m_Frame
,
505 m_Name
+ _(" Preview"),
506 wxPoint(100, 100), wxSize(650, 500));
507 frame
->Centre(wxBOTH
);
515 bool wxHtmlEasyPrinting::DoPrint(wxHtmlPrintout
*printout
)
517 wxPrintDialogData
printDialogData(*m_PrintData
);
518 wxPrinter
printer(&printDialogData
);
520 if (!printer
.Print(m_Frame
, printout
, TRUE
))
525 (*m_PrintData
) = printer
.GetPrintDialogData().GetPrintData();
531 void wxHtmlEasyPrinting::PrinterSetup()
533 wxPrintDialogData
printDialogData(*m_PrintData
);
534 wxPrintDialog
printerDialog(m_Frame
, &printDialogData
);
536 printerDialog
.GetPrintDialogData().SetSetupDialog(TRUE
);
538 if (printerDialog
.ShowModal() == wxID_OK
)
539 (*m_PrintData
) = printerDialog
.GetPrintDialogData().GetPrintData();
544 void wxHtmlEasyPrinting::PageSetup()
546 m_PageSetupData
->SetPrintData(*m_PrintData
);
547 wxPageSetupDialog
pageSetupDialog(m_Frame
, m_PageSetupData
);
549 if (pageSetupDialog
.ShowModal() == wxID_OK
)
551 (*m_PrintData
) = pageSetupDialog
.GetPageSetupData().GetPrintData();
552 (*m_PageSetupData
) = pageSetupDialog
.GetPageSetupData();
558 void wxHtmlEasyPrinting::SetHeader(const wxString
& header
, int pg
)
560 if (pg
== wxPAGE_ALL
|| pg
== wxPAGE_EVEN
)
561 m_Headers
[0] = header
;
562 if (pg
== wxPAGE_ALL
|| pg
== wxPAGE_ODD
)
563 m_Headers
[1] = header
;
568 void wxHtmlEasyPrinting::SetFooter(const wxString
& footer
, int pg
)
570 if (pg
== wxPAGE_ALL
|| pg
== wxPAGE_EVEN
)
571 m_Footers
[0] = footer
;
572 if (pg
== wxPAGE_ALL
|| pg
== wxPAGE_ODD
)
573 m_Footers
[1] = footer
;
578 wxHtmlPrintout
*wxHtmlEasyPrinting::CreatePrintout()
580 wxHtmlPrintout
*p
= new wxHtmlPrintout(m_Name
);
582 p
->SetHeader(m_Headers
[0], wxPAGE_EVEN
);
583 p
->SetHeader(m_Headers
[1], wxPAGE_ODD
);
584 p
->SetFooter(m_Footers
[0], wxPAGE_EVEN
);
585 p
->SetFooter(m_Footers
[1], wxPAGE_ODD
);
587 p
->SetMargins(m_PageSetupData
->GetMarginTopLeft().y
,
588 m_PageSetupData
->GetMarginBottomRight().y
,
589 m_PageSetupData
->GetMarginTopLeft().x
,
590 m_PageSetupData
->GetMarginBottomRight().x
);
597 #endif // wxUSE_HTML & wxUSE_PRINTING_ARCHITECTURE