X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/6445acc7832ccd1f2fc5211a68c90f4426ab4346..ddabd45b6148976e174ca7487ab283517d8825df:/src/common/prntbase.cpp diff --git a/src/common/prntbase.cpp b/src/common/prntbase.cpp index 94b3de2a39..4da0d2fa96 100644 --- a/src/common/prntbase.cpp +++ b/src/common/prntbase.cpp @@ -27,12 +27,14 @@ #include "wx/utils.h" #include "wx/dc.h" #include "wx/app.h" + #include "wx/math.h" #include "wx/msgdlg.h" #include "wx/layout.h" #include "wx/choice.h" #include "wx/button.h" #include "wx/settings.h" #include "wx/dcmemory.h" + #include "wx/dcclient.h" #include "wx/stattext.h" #include "wx/intl.h" #include "wx/textdlg.h" @@ -50,9 +52,14 @@ #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__) #include "wx/msw/printdlg.h" +#include "wx/msw/dcprint.h" #elif defined(__WXMAC__) -#include "wx/mac/printdlg.h" -#include "wx/mac/private/print.h" +#include "wx/osx/printdlg.h" +#include "wx/osx/private/print.h" +#include "wx/osx/dcprint.h" +#elif defined(__WXPM__) +#include "wx/os2/dcprint.h" +#include "wx/generic/prntdlgg.h" #else #include "wx/generic/prntdlgg.h" #include "wx/dcps.h" @@ -203,14 +210,12 @@ wxDialog *wxNativePrintFactory::CreatePrintSetupDialog( wxWindow *parent, #endif } -wxDC* wxNativePrintFactory::CreatePrinterDC( const wxPrintData& data ) +wxDCImpl* wxNativePrintFactory::CreatePrinterDCImpl( wxPrinterDC *owner, const wxPrintData& data ) { -#if defined(__WXMSW__) && !defined(__WXUNIVERSAL__) - return new wxPrinterDC(data); -#elif defined(__WXMAC__) - return new wxPrinterDC(data); +#if defined(__WXGTK__) || defined(__WXMOTIF__) || ( defined(__WXUNIVERSAL__) && !defined(__WXMAC__) ) + return new wxPostScriptDCImpl( owner, data ); #else - return new wxPostScriptDC(data); + return new wxPrinterDCImpl( owner, data ); #endif } @@ -617,10 +622,10 @@ void wxPrintout::FitThisSizeToPageMargins(const wxSize& imageSize, const wxPageS GetPageSizeMM(&mw, &mh); float mmToDeviceX = float(pw) / mw; float mmToDeviceY = float(ph) / mh; - wxRect pageMarginsRect(paperRect.x + wxCoordRound(mmToDeviceX * topLeft.x), - paperRect.y + wxCoordRound(mmToDeviceY * topLeft.y), - paperRect.width - wxCoordRound(mmToDeviceX * (topLeft.x + bottomRight.x)), - paperRect.height - wxCoordRound(mmToDeviceY * (topLeft.y + bottomRight.y))); + wxRect pageMarginsRect(paperRect.x + wxRound(mmToDeviceX * topLeft.x), + paperRect.y + wxRound(mmToDeviceY * topLeft.y), + paperRect.width - wxRound(mmToDeviceX * (topLeft.x + bottomRight.x)), + paperRect.height - wxRound(mmToDeviceY * (topLeft.y + bottomRight.y))); wxCoord w, h; m_printoutDC->GetSize(&w, &h); float scaleX = (float(pageMarginsRect.width) * w) / (float(pw) * imageSize.x); @@ -708,10 +713,10 @@ wxRect wxPrintout::GetLogicalPaperRect() const // This DC doesn't match the printed page, so we have to scale. float scaleX = float(w) / pw; float scaleY = float(h) / ph; - return wxRect(m_printoutDC->DeviceToLogicalX(wxCoordRound(paperRect.x * scaleX)), - m_printoutDC->DeviceToLogicalY(wxCoordRound(paperRect.y * scaleY)), - m_printoutDC->DeviceToLogicalXRel(wxCoordRound(paperRect.width * scaleX)), - m_printoutDC->DeviceToLogicalYRel(wxCoordRound(paperRect.height * scaleY))); + return wxRect(m_printoutDC->DeviceToLogicalX(wxRound(paperRect.x * scaleX)), + m_printoutDC->DeviceToLogicalY(wxRound(paperRect.y * scaleY)), + m_printoutDC->DeviceToLogicalXRel(wxRound(paperRect.width * scaleX)), + m_printoutDC->DeviceToLogicalYRel(wxRound(paperRect.height * scaleY))); } wxRect wxPrintout::GetLogicalPageRect() const @@ -731,51 +736,66 @@ wxRect wxPrintout::GetLogicalPageMarginsRect(const wxPageSetupDialogData& pageSe // Return the rectangle in logical units that corresponds to the region // within the page margins as specified by the given wxPageSetupDialogData // object. - wxRect paperRect = GetPaperRectPixels(); + + // We get the paper size in device units and the margins in mm, + // so we need to calculate the conversion with this trick wxCoord pw, ph; GetPageSizePixels(&pw, &ph); - wxPoint topLeft = pageSetupData.GetMarginTopLeft(); - wxPoint bottomRight = pageSetupData.GetMarginBottomRight(); wxCoord mw, mh; GetPageSizeMM(&mw, &mh); float mmToDeviceX = float(pw) / mw; float mmToDeviceY = float(ph) / mh; - wxRect pageMarginsRect(paperRect.x + wxCoordRound(mmToDeviceX * topLeft.x), - paperRect.y + wxCoordRound(mmToDeviceY * topLeft.y), - paperRect.width - wxCoordRound(mmToDeviceX * (topLeft.x + bottomRight.x)), - paperRect.height - wxCoordRound(mmToDeviceY * (topLeft.y + bottomRight.y))); + + // paper size in device units + wxRect paperRect = GetPaperRectPixels(); + + // margins in mm + wxPoint topLeft = pageSetupData.GetMarginTopLeft(); + wxPoint bottomRight = pageSetupData.GetMarginBottomRight(); + + // calculate margins in device units + wxRect pageMarginsRect( + paperRect.x + wxRound(mmToDeviceX * topLeft.x), + paperRect.y + wxRound(mmToDeviceY * topLeft.y), + paperRect.width - wxRound(mmToDeviceX * (topLeft.x + bottomRight.x)), + paperRect.height - wxRound(mmToDeviceY * (topLeft.y + bottomRight.y))); + wxCoord w, h; m_printoutDC->GetSize(&w, &h); - if (w == pw && h == ph) { + if (w == pw && h == ph) + { // this DC matches the printed page, so no scaling - return wxRect(m_printoutDC->DeviceToLogicalX(pageMarginsRect.x), + return wxRect( + m_printoutDC->DeviceToLogicalX(pageMarginsRect.x), m_printoutDC->DeviceToLogicalY(pageMarginsRect.y), m_printoutDC->DeviceToLogicalXRel(pageMarginsRect.width), m_printoutDC->DeviceToLogicalYRel(pageMarginsRect.height)); } + // This DC doesn't match the printed page, so we have to scale. float scaleX = float(w) / pw; float scaleY = float(h) / ph; - return wxRect(m_printoutDC->DeviceToLogicalX(wxCoordRound(pageMarginsRect.x * scaleX)), - m_printoutDC->DeviceToLogicalY(wxCoordRound(pageMarginsRect.y * scaleY)), - m_printoutDC->DeviceToLogicalXRel(wxCoordRound(pageMarginsRect.width * scaleX)), - m_printoutDC->DeviceToLogicalYRel(wxCoordRound(pageMarginsRect.height * scaleY))); + return wxRect(m_printoutDC->DeviceToLogicalX(wxRound(pageMarginsRect.x * scaleX)), + m_printoutDC->DeviceToLogicalY(wxRound(pageMarginsRect.y * scaleY)), + m_printoutDC->DeviceToLogicalXRel(wxRound(pageMarginsRect.width * scaleX)), + m_printoutDC->DeviceToLogicalYRel(wxRound(pageMarginsRect.height * scaleY))); } void wxPrintout::SetLogicalOrigin(wxCoord x, wxCoord y) { // Set the device origin by specifying a point in logical coordinates. - m_printoutDC->SetDeviceOrigin(m_printoutDC->LogicalToDeviceX(x), - m_printoutDC->LogicalToDeviceY(y)); + m_printoutDC->SetDeviceOrigin( + m_printoutDC->LogicalToDeviceX(x), + m_printoutDC->LogicalToDeviceY(y) ); } void wxPrintout::OffsetLogicalOrigin(wxCoord xoff, wxCoord yoff) { // Offset the device origin by a specified distance in device coordinates. - wxCoord x = m_printoutDC->LogicalToDeviceX(0); - wxCoord y = m_printoutDC->LogicalToDeviceY(0); - m_printoutDC->SetDeviceOrigin(x + m_printoutDC->LogicalToDeviceXRel(xoff), - y + m_printoutDC->LogicalToDeviceYRel(yoff)); + wxPoint dev_org = m_printoutDC->GetDeviceOrigin(); + m_printoutDC->SetDeviceOrigin( + dev_org.x + m_printoutDC->LogicalToDeviceXRel(xoff), + dev_org.y + m_printoutDC->LogicalToDeviceYRel(yoff) ); } @@ -788,6 +808,7 @@ IMPLEMENT_CLASS(wxPreviewCanvas, wxWindow) BEGIN_EVENT_TABLE(wxPreviewCanvas, wxScrolledWindow) EVT_PAINT(wxPreviewCanvas::OnPaint) EVT_CHAR(wxPreviewCanvas::OnChar) + EVT_IDLE(wxPreviewCanvas::OnIdle) EVT_SYS_COLOUR_CHANGED(wxPreviewCanvas::OnSysColourChanged) #if wxUSE_MOUSEWHEEL EVT_MOUSEWHEEL(wxPreviewCanvas::OnMouseWheel) @@ -839,6 +860,25 @@ void wxPreviewCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) } } +void wxPreviewCanvas::OnIdle(wxIdleEvent& event) +{ + event.Skip(); + + // prevent UpdatePageRendering() from being called recursively: + static bool s_inIdle = false; + if ( s_inIdle ) + return; + s_inIdle = true; + + if ( m_printPreview ) + { + if ( m_printPreview->UpdatePageRendering() ) + Refresh(); + } + + s_inIdle = false; +} + // Responds to colour changes, and passes event on to children. void wxPreviewCanvas::OnSysColourChanged(wxSysColourChangedEvent& event) { @@ -861,20 +901,14 @@ void wxPreviewCanvas::OnSysColourChanged(wxSysColourChangedEvent& event) void wxPreviewCanvas::OnChar(wxKeyEvent &event) { wxPreviewControlBar* controlBar = ((wxPreviewFrame*) GetParent())->GetControlBar(); - if (event.GetKeyCode() == WXK_ESCAPE) + switch (event.GetKeyCode()) { - ((wxPreviewFrame*) GetParent())->Close(true); - return; - } - else if (event.GetKeyCode() == WXK_TAB) - { - controlBar->OnGoto(); - return; - } - else if (event.GetKeyCode() == WXK_RETURN) - { - controlBar->OnPrint(); - return; + case WXK_TAB: + controlBar->OnGoto(); + return; + case WXK_RETURN: + controlBar->OnPrint(); + return; } if (!event.ControlDown()) @@ -1207,9 +1241,22 @@ int wxPreviewControlBar::GetZoomControl() IMPLEMENT_CLASS(wxPreviewFrame, wxFrame) BEGIN_EVENT_TABLE(wxPreviewFrame, wxFrame) + EVT_CHAR_HOOK(wxPreviewFrame::OnChar) EVT_CLOSE(wxPreviewFrame::OnCloseWindow) END_EVENT_TABLE() +void wxPreviewFrame::OnChar(wxKeyEvent &event) +{ + if ( event.GetKeyCode() == WXK_ESCAPE ) + { + Close(true); + } + else + { + event.Skip(); + } +} + wxPreviewFrame::wxPreviewFrame(wxPrintPreviewBase *preview, wxWindow *parent, const wxString& title, const wxPoint& pos, const wxSize& size, long style, const wxString& name): wxFrame(parent, wxID_ANY, title, pos, size, style, name) @@ -1245,7 +1292,9 @@ void wxPreviewFrame::OnCloseWindow(wxCloseEvent& WXUNUSED(event)) m_printPreview->SetCanvas(NULL); m_printPreview->SetFrame(NULL); } - delete m_printPreview; + + m_previewCanvas->SetPreview(NULL); + wxDELETE(m_printPreview); Destroy(); } @@ -1332,6 +1381,7 @@ void wxPrintPreviewBase::Init(wxPrintout *printout, m_previewCanvas = NULL; m_previewFrame = NULL; m_previewBitmap = NULL; + m_previewFailed = false; m_currentPage = 1; m_currentZoom = 70; m_topMargin = 40; @@ -1359,18 +1409,13 @@ bool wxPrintPreviewBase::SetCurrentPage(int pageNum) return true; m_currentPage = pageNum; - if (m_previewBitmap) - { - delete m_previewBitmap; - m_previewBitmap = NULL; - } + + InvalidatePreviewBitmap(); if (m_previewCanvas) { AdjustScrollbars(m_previewCanvas); - if (!RenderPage(pageNum)) - return false; m_previewCanvas->Refresh(); m_previewCanvas->SetFocus(); } @@ -1427,13 +1472,35 @@ void wxPrintPreviewBase::CalcRects(wxPreviewCanvas *canvas, wxRect& pageRect, wx } +void wxPrintPreviewBase::InvalidatePreviewBitmap() +{ + wxDELETE(m_previewBitmap); + // if there was a problem with rendering the preview, try again now + // that it changed in some way (less memory may be needed, for example): + m_previewFailed = false; +} + +bool wxPrintPreviewBase::UpdatePageRendering() +{ + if ( m_previewBitmap ) + return false; + + if ( m_previewFailed ) + return false; + + if ( !RenderPage(m_currentPage) ) + { + m_previewFailed = true; // don't waste time failing again + return false; + } + + return true; +} + bool wxPrintPreviewBase::PaintPage(wxPreviewCanvas *canvas, wxDC& dc) { DrawBlankPage(canvas, dc); - if (!m_previewBitmap) - if (!RenderPage(m_currentPage)) - return false; if (!m_previewBitmap) return false; if (!canvas) @@ -1468,6 +1535,47 @@ void wxPrintPreviewBase::AdjustScrollbars(wxPreviewCanvas *canvas) canvas->SetScrollbars(10, 10, scrollUnitsX, scrollUnitsY, 0, 0, true); } +bool wxPrintPreviewBase::RenderPageIntoDC(wxDC& dc, int pageNum) +{ + m_previewPrintout->SetDC(&dc); + m_previewPrintout->SetPageSizePixels(m_pageWidth, m_pageHeight); + + // Need to delay OnPreparePrinting() until here, so we have enough + // information. + if (!m_printingPrepared) + { + m_previewPrintout->OnPreparePrinting(); + int selFrom, selTo; + m_previewPrintout->GetPageInfo(&m_minPage, &m_maxPage, &selFrom, &selTo); + m_printingPrepared = true; + } + + m_previewPrintout->OnBeginPrinting(); + + if (!m_previewPrintout->OnBeginDocument(m_printDialogData.GetFromPage(), m_printDialogData.GetToPage())) + { + wxMessageBox(_("Could not start document preview."), _("Print Preview Failure"), wxOK); + return false; + } + + m_previewPrintout->OnPrintPage(pageNum); + m_previewPrintout->OnEndDocument(); + m_previewPrintout->OnEndPrinting(); + + m_previewPrintout->SetDC(NULL); + + return true; +} + +bool wxPrintPreviewBase::RenderPageIntoBitmap(wxBitmap& bmp, int pageNum) +{ + wxMemoryDC memoryDC; + memoryDC.SelectObject(bmp); + memoryDC.Clear(); + + return RenderPageIntoDC(memoryDC, pageNum); +} + bool wxPrintPreviewBase::RenderPage(int pageNum) { wxBusyCursor busy; @@ -1487,53 +1595,19 @@ bool wxPrintPreviewBase::RenderPage(int pageNum) if (!m_previewBitmap || !m_previewBitmap->Ok()) { - if (m_previewBitmap) { - delete m_previewBitmap; - m_previewBitmap = NULL; - } + InvalidatePreviewBitmap(); wxMessageBox(_("Sorry, not enough memory to create a preview."), _("Print Preview Failure"), wxOK); return false; } } - wxMemoryDC memoryDC; - memoryDC.SelectObject(*m_previewBitmap); - - memoryDC.Clear(); - - m_previewPrintout->SetDC(&memoryDC); - m_previewPrintout->SetPageSizePixels(m_pageWidth, m_pageHeight); - - // Need to delay OnPreparePrinting until here, so we have enough information. - if (!m_printingPrepared) - { - m_previewPrintout->OnPreparePrinting(); - int selFrom, selTo; - m_previewPrintout->GetPageInfo(&m_minPage, &m_maxPage, &selFrom, &selTo); - m_printingPrepared = true; - } - - m_previewPrintout->OnBeginPrinting(); - - if (!m_previewPrintout->OnBeginDocument(m_printDialogData.GetFromPage(), m_printDialogData.GetToPage())) + if ( !RenderPageIntoBitmap(*m_previewBitmap, pageNum) ) { - wxMessageBox(_("Could not start document preview."), _("Print Preview Failure"), wxOK); - - memoryDC.SelectObject(wxNullBitmap); - - delete m_previewBitmap; - m_previewBitmap = NULL; + InvalidatePreviewBitmap(); + wxMessageBox(_("Sorry, not enough memory to create a preview."), _("Print Preview Failure"), wxOK); return false; } - m_previewPrintout->OnPrintPage(pageNum); - m_previewPrintout->OnEndDocument(); - m_previewPrintout->OnEndPrinting(); - - m_previewPrintout->SetDC(NULL); - - memoryDC.SelectObject(wxNullBitmap); - #if wxUSE_STATUSBAR wxString status; if (m_maxPage != 0) @@ -1580,16 +1654,12 @@ void wxPrintPreviewBase::SetZoom(int percent) return; m_currentZoom = percent; - if (m_previewBitmap) - { - delete m_previewBitmap; - m_previewBitmap = NULL; - } + + InvalidatePreviewBitmap(); if (m_previewCanvas) { AdjustScrollbars(m_previewCanvas); - RenderPage(m_currentPage); ((wxScrolledWindow *) m_previewCanvas)->Scroll(0, 0); m_previewCanvas->ClearBackground(); m_previewCanvas->Refresh(); @@ -1697,6 +1767,11 @@ bool wxPrintPreview::PaintPage(wxPreviewCanvas *canvas, wxDC& dc) return m_pimpl->PaintPage( canvas, dc ); } +bool wxPrintPreview::UpdatePageRendering() +{ + return m_pimpl->UpdatePageRendering(); +} + bool wxPrintPreview::DrawBlankPage(wxPreviewCanvas *canvas, wxDC& dc) { return m_pimpl->DrawBlankPage( canvas, dc );