X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/9b95e87cb00a02e8373d25f525910d689c176ce4..12bb29f5432174ecbd65549bda832d70d34a98ae:/src/html/htmprint.cpp diff --git a/src/html/htmprint.cpp b/src/html/htmprint.cpp index 60d681cff0..96d32d97c3 100644 --- a/src/html/htmprint.cpp +++ b/src/html/htmprint.cpp @@ -24,6 +24,7 @@ #include "wx/settings.h" #include "wx/msgdlg.h" #include "wx/module.h" + #include "wx/sizer.h" #endif #include "wx/print.h" @@ -31,12 +32,35 @@ #include "wx/html/htmprint.h" #include "wx/wxhtml.h" #include "wx/wfstream.h" +#include "wx/infobar.h" // default font size of normal text (HTML font size 0) for printing, in points: #define DEFAULT_PRINT_FONT_SIZE 12 +// CSS specification offer following guidance on dealing with pixel sizes +// when printing at +// http://www.w3.org/TR/2004/CR-CSS21-20040225/syndata.html#length-units: +// +// Pixel units are relative to the resolution of the viewing device, i.e., +// most often a computer display. If the pixel density of the output +// device is very different from that of a typical computer display, the +// user agent should rescale pixel values. It is recommended that the [ +// reference pixel] be the visual angle of one pixel on a device with a +// pixel density of 96dpi and a distance from the reader of an arm's +// length. For a nominal arm's length of 28 inches, the visual angle is +// therefore about 0.0213 degrees. +// +// For reading at arm's length, 1px thus corresponds to about 0.26 mm +// (1/96 inch). When printed on a laser printer, meant for reading at a +// little less than arm's length (55 cm, 21 inches), 1px is about 0.20 mm. +// On a 300 dots-per-inch (dpi) printer, that may be rounded up to 3 dots +// (0.25 mm); on a 600 dpi printer, it can be rounded to 5 dots. +// +// See also http://trac.wxwidgets.org/ticket/10942. +#define TYPICAL_SCREEN_DPI 96.0 + //-------------------------------------------------------------------------------- // wxHtmlDCRenderer //-------------------------------------------------------------------------------- @@ -64,10 +88,10 @@ wxHtmlDCRenderer::~wxHtmlDCRenderer() -void wxHtmlDCRenderer::SetDC(wxDC *dc, double pixel_scale) +void wxHtmlDCRenderer::SetDC(wxDC *dc, double pixel_scale, double font_scale) { m_DC = dc; - m_Parser->SetDC(m_DC, pixel_scale); + m_Parser->SetDC(m_DC, pixel_scale, font_scale); } @@ -127,7 +151,7 @@ int wxHtmlDCRenderer::Render(int x, int y, int pbreak, hght; pbreak = (int)(from + m_Height); - while (m_Cells->AdjustPagebreak(&pbreak, known_pagebreaks)) {} + while (m_Cells->AdjustPagebreak(&pbreak, known_pagebreaks, m_Height)) {} hght = pbreak - from; if(to < hght) hght = to; @@ -172,7 +196,7 @@ wxHtmlPrintout::wxHtmlPrintout(const wxString& title) : wxPrintout(title) { m_Renderer = new wxHtmlDCRenderer; m_RendererHdr = new wxHtmlDCRenderer; - m_NumPages = wxHTML_PRINT_MAX_PAGES; + m_NumPages = INT_MAX; m_Document = m_BasePath = wxEmptyString; m_BasePathIsDir = true; m_Headers[0] = m_Headers[1] = wxEmptyString; m_Footers[0] = m_Footers[1] = wxEmptyString; @@ -203,8 +227,42 @@ void wxHtmlPrintout::AddFilter(wxHtmlFilter *filter) bool wxHtmlPrintout::CheckFit(const wxSize& pageArea, const wxSize& docArea) const { - if ( docArea.x > pageArea.x ) + // Nothing to do if the contents fits horizontally. + if ( docArea.x <= pageArea.x ) + return true; + + // Otherwise warn the user more or less intrusively depending on whether + // we're previewing or printing: + if ( wxPrintPreview * const preview = GetPreview() ) + { + // Don't annoy the user too much when previewing by using info bar + // instead of a dialog box. +#if wxUSE_INFOBAR + wxFrame * const parent = preview->GetFrame(); + wxCHECK_MSG( parent, false, "No parent preview frame?" ); + + wxSizer * const sizer = parent->GetSizer(); + wxCHECK_MSG( sizer, false, "Preview frame should be using sizers" ); + + wxInfoBar * const bar = new wxInfoBar(parent); + sizer->Add(bar, wxSizerFlags().Expand()); + + // Note that the message here is similar to the one below but not + // exactly the same, notably we don't use the document title here + // because it's already clear which document it pertains to and the + // title may be long enough to make the text not fit in the window. + bar->ShowMessage + ( + _("This document doesn't fit on the page horizontally and " + "will be truncated when it is printed."), + wxICON_WARNING + ); +#endif // wxUSE_INFOBAR + } + else // We're going to really print and not just preview. { + // This is our last chance to warn the user that the output will be + // mangled so do show a message box. wxMessageDialog dlg ( @@ -225,7 +283,7 @@ wxHtmlPrintout::CheckFit(const wxSize& pageArea, const wxSize& docArea) const _("If possible, try changing the layout parameters to " "make the printout more narrow.") ); - dlg.SetOKLabel(_("&Print")); + dlg.SetOKLabel(wxID_PRINT); if ( dlg.ShowModal() == wxID_CANCEL ) return false; @@ -236,7 +294,7 @@ wxHtmlPrintout::CheckFit(const wxSize& pageArea, const wxSize& docArea) const void wxHtmlPrintout::OnPreparePrinting() { - int pageWidth, pageHeight, mm_w, mm_h, scr_w, scr_h, dc_w, dc_h; + int pageWidth, pageHeight, mm_w, mm_h, dc_w, dc_h; float ppmm_h, ppmm_v; GetPageSizePixels(&pageWidth, &pageHeight); @@ -251,7 +309,6 @@ void wxHtmlPrintout::OnPreparePrinting() GetPPIScreen(&ppiScreenX, &ppiScreenY); wxUnusedVar(ppiScreenX); - wxDisplaySize(&scr_w, &scr_h); GetDC()->GetSize(&dc_w, &dc_h); GetDC()->SetUserScale((double)dc_w / (double)pageWidth, @@ -259,7 +316,9 @@ void wxHtmlPrintout::OnPreparePrinting() /* prepare headers/footers renderer: */ - m_RendererHdr->SetDC(GetDC(), (double)ppiPrinterY / (double)ppiScreenY); + m_RendererHdr->SetDC(GetDC(), + (double)ppiPrinterY / TYPICAL_SCREEN_DPI, + (double)ppiPrinterY / (double)ppiScreenY); m_RendererHdr->SetSize((int) (ppmm_h * (mm_w - m_MarginLeft - m_MarginRight)), (int) (ppmm_v * (mm_h - m_MarginTop - m_MarginBottom))); if (m_Headers[0] != wxEmptyString) @@ -284,7 +343,9 @@ void wxHtmlPrintout::OnPreparePrinting() } /* prepare main renderer: */ - m_Renderer->SetDC(GetDC(), (double)ppiPrinterY / (double)ppiScreenY); + m_Renderer->SetDC(GetDC(), + (double)ppiPrinterY / TYPICAL_SCREEN_DPI, + (double)ppiPrinterY / (double)ppiScreenY); const int printAreaW = int(ppmm_h * (mm_w - m_MarginLeft - m_MarginRight)); int printAreaH = int(ppmm_v * (mm_h - m_MarginTop - m_MarginBottom)); @@ -298,7 +359,7 @@ void wxHtmlPrintout::OnPreparePrinting() if ( CheckFit(wxSize(printAreaW, printAreaH), wxSize(m_Renderer->GetTotalWidth(), - m_Renderer->GetTotalHeight())) ) + m_Renderer->GetTotalHeight())) || IsPreview() ) { // do paginate the document CountPages(); @@ -431,7 +492,6 @@ void wxHtmlPrintout::CountPages() int pos = 0; m_NumPages = 0; - // m_PageBreaks[0] = 0; m_PageBreaks.Clear(); m_PageBreaks.Add( 0); @@ -442,12 +502,6 @@ void wxHtmlPrintout::CountPages() m_PageBreaks, pos, true, INT_MAX); m_PageBreaks.Add( pos); - if( m_PageBreaks.GetCount() > wxHTML_PRINT_MAX_PAGES) - { - wxMessageBox( _("HTML pagination algorithm generated more than the allowed maximum number of pages and it can't continue any longer!"), - _("Warning"), wxCANCEL | wxICON_ERROR ); - break; - } } while (pos < m_Renderer->GetTotalHeight()); } @@ -457,14 +511,13 @@ void wxHtmlPrintout::RenderPage(wxDC *dc, int page) { wxBusyCursor wait; - int pageWidth, pageHeight, mm_w, mm_h, scr_w, scr_h, dc_w, dc_h; + int pageWidth, pageHeight, mm_w, mm_h, dc_w, dc_h; float ppmm_h, ppmm_v; GetPageSizePixels(&pageWidth, &pageHeight); GetPageSizeMM(&mm_w, &mm_h); ppmm_h = (float)pageWidth / mm_w; ppmm_v = (float)pageHeight / mm_h; - wxDisplaySize(&scr_w, &scr_h); dc->GetSize(&dc_w, &dc_h); int ppiPrinterX, ppiPrinterY; @@ -477,16 +530,20 @@ void wxHtmlPrintout::RenderPage(wxDC *dc, int page) dc->SetUserScale((double)dc_w / (double)pageWidth, (double)dc_h / (double)pageHeight); - m_Renderer->SetDC(dc, (double)ppiPrinterY / (double)ppiScreenY); + m_Renderer->SetDC(dc, + (double)ppiPrinterY / TYPICAL_SCREEN_DPI, + (double)ppiPrinterY / (double)ppiScreenY); - dc->SetBackgroundMode(wxBRUSHSTYLE_TRANSPARENT); + dc->SetBackgroundMode(wxTRANSPARENT); m_Renderer->Render((int) (ppmm_h * m_MarginLeft), (int) (ppmm_v * (m_MarginTop + (m_HeaderHeight == 0 ? 0 : m_MarginSpace)) + m_HeaderHeight), m_PageBreaks, m_PageBreaks[page-1], false, m_PageBreaks[page]-m_PageBreaks[page-1]); - m_RendererHdr->SetDC(dc, (double)ppiPrinterY / (double)ppiScreenY); + m_RendererHdr->SetDC(dc, + (double)ppiPrinterY / TYPICAL_SCREEN_DPI, + (double)ppiPrinterY / (double)ppiScreenY); if (m_Headers[page % 2] != wxEmptyString) { m_RendererHdr->SetHtmlText(TranslateHeader(m_Headers[page % 2], page)); @@ -638,7 +695,7 @@ bool wxHtmlEasyPrinting::DoPreview(wxHtmlPrintout *printout1, wxHtmlPrintout *pr // Pass two printout objects: for preview, and possible printing. wxPrintDialogData printDialogData(*GetPrintData()); wxPrintPreview *preview = new wxPrintPreview(printout1, printout2, &printDialogData); - if (!preview->Ok()) + if (!preview->IsOk()) { delete preview; return false; @@ -674,7 +731,7 @@ bool wxHtmlEasyPrinting::DoPrint(wxHtmlPrintout *printout) void wxHtmlEasyPrinting::PageSetup() { - if (!GetPrintData()->Ok()) + if (!GetPrintData()->IsOk()) { wxLogError(_("There was a problem during page setup: you may need to set a default printer.")); return;