X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/87df17a11b0017d31c09f767bd921abb27193bee..9d5507f7a2701395e1d5c121bd877bb9066ee6ea:/src/mac/carbon/dcprint.cpp?ds=sidebyside diff --git a/src/mac/carbon/dcprint.cpp b/src/mac/carbon/dcprint.cpp index 904c5eedca..10c79a07ef 100644 --- a/src/mac/carbon/dcprint.cpp +++ b/src/mac/carbon/dcprint.cpp @@ -1,296 +1,369 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: dcprint.cpp +// Name: src/mac/carbon/dcprint.cpp // Purpose: wxPrinterDC class // Author: Julian Smart // Modified by: // Created: 01/02/97 // RCS-ID: $Id$ -// Copyright: (c) Julian Smart and Markus Holzem -// Licence: wxWindows licence +// Copyright: (c) Julian Smart +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#ifdef __GNUG__ -#pragma implementation "dcprint.h" -#endif - // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" +#if wxUSE_PRINTING_ARCHITECTURE + #ifdef __BORLANDC__ -#pragma hdrstop + #pragma hdrstop #endif +#include "wx/dcprint.h" + #ifndef WX_PRECOMP + #include "wx/msgdlg.h" + #include "wx/math.h" #endif -#include "wx/dcprint.h" -#include "wx/msgdlg.h" -#include #include "wx/mac/uma.h" +#include "wx/mac/private/print.h" +#include "wx/mac/carbon/dcprint.h" +#include "wx/graphics.h" -#if !USE_SHARED_LIBRARY -IMPLEMENT_CLASS(wxPrinterDC, wxDC) -#endif +IMPLEMENT_ABSTRACT_CLASS(wxPrinterDCImpl, wxGCDCImpl) -GrafPtr macPrintFormerPort = NULL ; +class wxNativePrinterDC +{ +public : + wxNativePrinterDC() {} + virtual ~wxNativePrinterDC() {} + virtual bool StartDoc( wxPrinterDC* dc , const wxString& message ) = 0; + virtual void EndDoc( wxPrinterDC* dc ) = 0; + virtual void StartPage( wxPrinterDC* dc ) = 0; + virtual void EndPage( wxPrinterDC* dc ) = 0; + virtual void GetSize( int *w , int *h) const = 0 ; + virtual wxSize GetPPI() const = 0 ; + + // returns 0 in case of no Error, otherwise platform specific error codes + virtual wxUint32 GetStatus() const = 0 ; + bool Ok() { return GetStatus() == 0 ; } -wxPrinterDC::wxPrinterDC(const wxPrintData& printdata) + static wxNativePrinterDC* Create(wxPrintData* data) ; +} ; + +class wxMacCarbonPrinterDC : public wxNativePrinterDC { - OSStatus err ; - wxString message ; - - m_printData = printdata ; - m_printData.ConvertToNative() ; - -#if PM_USE_SESSION_APIS - err = UMAPrOpen(&m_macPrintPort) ; -#else - err = UMAPrOpen() ; -#endif - if ( err ) - { - message.Printf( "Print Error %d", err ) ; - wxMessageDialog dialog( NULL , message , "", wxICON_HAND | wxOK) ; -#if PM_USE_SESSION_APIS - UMAPrClose(&m_macPrintPort) ; +public : + wxMacCarbonPrinterDC( wxPrintData* data ) ; + virtual ~wxMacCarbonPrinterDC() ; + virtual bool StartDoc( wxPrinterDC* dc , const wxString& message ) ; + virtual void EndDoc( wxPrinterDC* dc ) ; + virtual void StartPage( wxPrinterDC* dc ) ; + virtual void EndPage( wxPrinterDC* dc ) ; + virtual wxUint32 GetStatus() const { return m_err ; } + virtual void GetSize( int *w , int *h) const ; + virtual wxSize GetPPI() const ; +private : + wxCoord m_maxX ; + wxCoord m_maxY ; + wxSize m_ppi ; + OSStatus m_err ; +} ; + +wxMacCarbonPrinterDC::wxMacCarbonPrinterDC( wxPrintData* data ) +{ + m_err = noErr ; + wxMacCarbonPrintData *native = (wxMacCarbonPrintData*) data->GetNativeData() ; + + PMRect rPage; + m_err = PMGetAdjustedPageRect(native->m_macPageFormat, &rPage); + if ( m_err != noErr ) + return; + + m_maxX = wxCoord(rPage.right - rPage.left) ; + m_maxY = wxCoord(rPage.bottom - rPage.top); + + PMResolution res; +#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 + PMPrinter printer; + PMSessionGetCurrentPrinter(native->m_macPrintSession, &printer); + PMPrinterGetOutputResolution( printer, native->m_macPrintSettings, &res) ; #else - UMAPrClose() ; + m_err = PMGetResolution((PMPageFormat) (native->m_macPageFormat), &res); #endif - } - -#if !TARGET_CARBON - if ( ::PrValidate( m_printData.m_macPrintInfo ) ) - { - ::PrStlDialog( m_printData.m_macPrintInfo ) ; - // the driver has changed in the mean time, should we pop up a page setup dialog ? - } - err = PrError() ; - if ( err ) - { - message.Printf( "Print Error %d", err ) ; - wxMessageDialog dialog( NULL , message , "", wxICON_HAND | wxOK) ; - UMAPrClose() ; - } - ::GetPort( &macPrintFormerPort ) ; - m_macPrintPort = ::PrOpenDoc( m_printData.m_macPrintInfo , NULL , NULL ) ; - err = PrError() ; - if ( err ) - { - message.Printf( "Print Error %d", err ) ; - wxMessageDialog dialog( NULL , message , "", wxICON_HAND | wxOK) ; - UMAPrClose() ; - } - // sets current port - m_macPort = (GrafPtr ) m_macPrintPort ; -#else - m_macPrintPort = kPMNoReference ; - #if PM_USE_SESSION_APIS - err = PMSessionBeginDocument( - m_macPrintPort, - m_printData.m_macPrintSettings, - m_printData.m_macPageFormat); - #else - err = PMBeginDocument( - m_printData.m_macPrintSettings, - m_printData.m_macPageFormat, - &m_macPrintPort); - #endif - if ( err != noErr || m_macPrintPort == kPMNoReference ) + m_ppi = wxSize(int(res.hRes), int(res.vRes)); +} + +wxMacCarbonPrinterDC::~wxMacCarbonPrinterDC() +{ +} + +wxNativePrinterDC* wxNativePrinterDC::Create(wxPrintData* data) +{ + return new wxMacCarbonPrinterDC(data) ; +} + +bool wxMacCarbonPrinterDC::StartDoc( wxPrinterDC* dc , const wxString& WXUNUSED(message) ) +{ + if ( m_err ) + return false ; + + wxPrinterDCImpl *impl = (wxPrinterDCImpl*) dc->GetImpl(); + wxMacCarbonPrintData *native = (wxMacCarbonPrintData*) impl->GetPrintData().GetNativeData() ; + + m_err = PMSessionBeginCGDocumentNoDialog(native->m_macPrintSession, + native->m_macPrintSettings, + native->m_macPageFormat); + if ( m_err != noErr ) + return false; + + PMRect rPage; + m_err = PMGetAdjustedPageRect(native->m_macPageFormat, &rPage); + if ( m_err != noErr ) + return false ; + + m_maxX = wxCoord(rPage.right - rPage.left) ; + m_maxY = wxCoord(rPage.bottom - rPage.top); + + PMResolution res; +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + if ( PMPrinterGetOutputResolution != NULL ) { - message.Printf( "Print Error %d", err ) ; - wxMessageDialog dialog( NULL , message , "", wxICON_HAND | wxOK) ; - #if PM_USE_SESSION_APIS - UMAPrClose(&m_macPrintPort) ; - #else - UMAPrClose() ; - #endif + PMPrinter printer; + m_err = PMSessionGetCurrentPrinter(native->m_macPrintSession, &printer); + if ( m_err == noErr ) + m_err = PMPrinterGetOutputResolution( printer, native->m_macPrintSettings, &res) ; } - // sets current port - ::GetPort( &m_macPort ) ; + else #endif - m_ok = TRUE ; - m_minY = m_minX = 0 ; -#if TARGET_CARBON -#else - m_maxX = (**m_printData.m_macPrintInfo).rPaper.right - (**m_printData.m_macPrintInfo).rPaper.left ; - m_maxY = (**m_printData.m_macPrintInfo).rPaper.bottom - (**m_printData.m_macPrintInfo).rPaper.top ; + { +#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 + m_err = PMGetResolution((PMPageFormat) (native->m_macPageFormat), &res); #endif + } + + m_ppi = wxSize(int(res.hRes), int(res.vRes)); + return true ; } -wxPrinterDC::~wxPrinterDC(void) +void wxMacCarbonPrinterDC::EndDoc( wxPrinterDC* dc ) { - OSStatus err ; - wxString message ; -#if !TARGET_CARBON - if ( m_ok ) - { - ::PrCloseDoc( m_macPrintPort ) ; - err = PrError() ; - - if ( !err ) - { - if ( (**m_printData.m_macPrintInfo).prJob.bJDocLoop == bSpoolLoop ) - { - TPrStatus status ; - ::PrPicFile( m_printData.m_macPrintInfo , NULL , NULL , NULL , &status ) ; - } - } - else - { - message.Printf( "Print Error %d", err ) ; - wxMessageDialog dialog( NULL , message , "", wxICON_HAND | wxOK) ; - UMAPrClose() ; - } - ::UMAPrClose() ; -// ::SetPort( macPrintFormerPort ) ; - ::SetPort( LMGetWMgrPort() ) ; - } -#else - if ( m_ok ) - { - #if PM_USE_SESSION_APIS - err = PMSessionEndDocument(m_macPrintPort); - #else - err = PMEndDocument(m_macPrintPort); - #endif - if ( !err ) - { - message.Printf( "Print Error %d", err ) ; - wxMessageDialog dialog( NULL , message , "", wxICON_HAND | wxOK) ; - #if PM_USE_SESSION_APIS - UMAPrClose(&m_macPrintPort) ; - #else - UMAPrClose() ; - #endif - } - #if PM_USE_SESSION_APIS - UMAPrClose(&m_macPrintPort) ; - #else - UMAPrClose() ; - #endif - } -#endif + if ( m_err ) + return ; + + wxPrinterDCImpl *impl = (wxPrinterDCImpl*) dc->GetImpl(); + wxMacCarbonPrintData *native = (wxMacCarbonPrintData*) impl->GetPrintData().GetNativeData() ; + + m_err = PMSessionEndDocumentNoDialog(native->m_macPrintSession); +} + +void wxMacCarbonPrinterDC::StartPage( wxPrinterDC* dc ) +{ + if ( m_err ) + return ; + + wxPrinterDCImpl *impl = (wxPrinterDCImpl*) dc->GetImpl(); + wxMacCarbonPrintData *native = (wxMacCarbonPrintData*) impl->GetPrintData().GetNativeData() ; + + m_err = PMSessionBeginPageNoDialog(native->m_macPrintSession, + native->m_macPageFormat, + nil); + + CGContextRef pageContext; + + if ( m_err == noErr ) + { + m_err = PMSessionGetCGGraphicsContext(native->m_macPrintSession, + &pageContext ); + } + + if ( m_err != noErr ) + { + PMSessionEndPageNoDialog(native->m_macPrintSession); + PMSessionEndDocumentNoDialog(native->m_macPrintSession); + } + else + { + PMRect rPage; + + m_err = PMGetAdjustedPageRect(native->m_macPageFormat, &rPage); + if ( !m_err ) + { + PMRect paperRect ; + PMGetAdjustedPaperRect( native->m_macPageFormat , &paperRect ) ; + // make sure (0,0) is at the upper left of the printable area (wx conventions) + // Core Graphics initially has the lower left of the paper as 0,0 + CGContextTranslateCTM( pageContext , -paperRect.left , paperRect.bottom ) ; + CGContextScaleCTM( pageContext , 1 , -1 ) ; + } + // since this is a non-critical error, we set the flag back + m_err = noErr ; + } + impl->SetGraphicsContext( wxGraphicsContext::CreateFromNative( pageContext ) ); } -bool wxPrinterDC::StartDoc( const wxString& WXUNUSED(message) ) +void wxMacCarbonPrinterDC::EndPage( wxPrinterDC* dc ) { - return m_ok ; + if ( m_err ) + return ; + + wxPrinterDCImpl *impl = (wxPrinterDCImpl*) dc->GetImpl(); + wxMacCarbonPrintData *native = (wxMacCarbonPrintData*) impl->GetPrintData().GetNativeData() ; + + m_err = PMSessionEndPageNoDialog(native->m_macPrintSession); + if ( m_err != noErr ) + { + PMSessionEndDocumentNoDialog(native->m_macPrintSession); + } + // the cg context we got when starting the page isn't valid anymore, so replace it + impl->SetGraphicsContext( wxGraphicsContext::Create() ); } -void wxPrinterDC::EndDoc(void) +void wxMacCarbonPrinterDC::GetSize( int *w , int *h) const { + if ( w ) + *w = m_maxX ; + if ( h ) + *h = m_maxY ; } -void wxPrinterDC::StartPage(void) +wxSize wxMacCarbonPrinterDC::GetPPI() const { - if ( !m_ok ) - return ; - - m_logicalFunction = wxCOPY; -// m_textAlignment = wxALIGN_TOP_LEFT; - m_backgroundMode = wxTRANSPARENT; - - m_textForegroundColour = *wxBLACK; - m_textBackgroundColour = *wxWHITE; - m_pen = *wxBLACK_PEN; - m_font = *wxNORMAL_FONT; - m_brush = *wxTRANSPARENT_BRUSH; - m_backgroundBrush = *wxWHITE_BRUSH; - - m_macFontInstalled = false ; - m_macBrushInstalled = false ; - m_macPenInstalled = false ; - - - OSStatus err ; - wxString message ; - -#if !TARGET_CARBON - PrOpenPage( m_macPrintPort , NULL ) ; - m_macLocalOrigin.h = (**m_printData.m_macPrintInfo).rPaper.left ; - m_macLocalOrigin.v = (**m_printData.m_macPrintInfo).rPaper.top ; - - SetOrigin( - m_macLocalOrigin.h , - m_macLocalOrigin.v ) ; - Rect clip = { -32000 , -32000 , 32000 , 32000 } ; - ::ClipRect( &clip ) ; - err = PrError() ; - if ( err ) - { - message.Printf( "Print Error %d", err ) ; - wxMessageDialog dialog( NULL , message , "", wxICON_HAND | wxOK) ; - ::PrClosePage( m_macPrintPort) ; - ::PrCloseDoc( m_macPrintPort ) ; - ::UMAPrClose() ; - ::SetPort( macPrintFormerPort ) ; - m_ok = FALSE ; - } -#else - #if PM_USE_SESSION_APIS - err = PMSessionBeginPage(m_macPrintPort, - m_printData.m_macPageFormat, - nil); - #else - err = PMBeginPage(m_macPrintPort, nil); - #endif - if ( err ) - { - message.Printf( "Print Error %d", err ) ; - wxMessageDialog dialog( NULL , message , "", wxICON_HAND | wxOK) ; - #if PM_USE_SESSION_APIS - PMSessionEndPage(m_macPrintPort); - PMSessionEndDocument(m_macPrintPort); - UMAPrClose(&m_macPrintPort) ; - #else - PMEndPage(m_macPrintPort); - PMEndDocument(m_macPrintPort); - UMAPrClose() ; - #endif - ::SetPort( macPrintFormerPort ) ; - m_ok = FALSE ; - } -#endif + return m_ppi ; +}; + +// +// +// + +wxPrinterDCImpl::wxPrinterDCImpl( wxPrinterDC *owner, const wxPrintData& printdata ) + : wxGCDCImpl( owner ) +{ + m_ok = false ; + m_printData = printdata ; + m_printData.ConvertToNative() ; + m_nativePrinterDC = wxNativePrinterDC::Create( &m_printData ) ; + if ( m_nativePrinterDC ) + { + m_ok = m_nativePrinterDC->Ok() ; + if ( !m_ok ) + { + wxString message ; + message.Printf( wxT("Print Error %u"), m_nativePrinterDC->GetStatus() ) ; + wxMessageDialog dialog( NULL , message , wxEmptyString, wxICON_HAND | wxOK) ; + dialog.ShowModal(); + } + else + { + wxSize sz = GetPPI(); + m_mm_to_pix_x = mm2inches * sz.x; + m_mm_to_pix_y = mm2inches * sz.y; + } + // we need at least a measuring context because people start measuring before a page + // gets printed at all + SetGraphicsContext( wxGraphicsContext::Create() ); + } } -void wxPrinterDC::EndPage(void) +wxSize wxPrinterDCImpl::GetPPI() const { - if ( !m_ok ) - return ; - - OSStatus err ; - wxString message ; - -#if !TARGET_CARBON - PrClosePage( (TPrPort*) m_macPort ) ; - err = PrError() ; - if ( err ) - { - message.Printf( "Print Error %d", err ) ; - wxMessageDialog dialog( NULL , message , "", wxICON_HAND | wxOK) ; - ::PrCloseDoc( m_macPrintPort ) ; - ::UMAPrClose() ; - ::SetPort( macPrintFormerPort ) ; - m_ok = FALSE ; - } -#else - #if PM_USE_SESSION_APIS - err = PMSessionEndPage(m_macPrintPort); - #else - err = PMEndPage(m_macPrintPort); - #endif - if ( err ) - { - message.Printf( "Print Error %d", err ) ; - wxMessageDialog dialog( NULL , message , "", wxICON_HAND | wxOK) ; - #if PM_USE_SESSION_APIS - PMSessionEndDocument(m_macPrintPort); - UMAPrClose(&m_macPrintPort) ; - #else - PMEndDocument(m_macPrintPort); - UMAPrClose() ; - #endif - ::SetPort( macPrintFormerPort ) ; - m_ok = FALSE ; - } -#endif + return m_nativePrinterDC->GetPPI() ; +} + +wxPrinterDCImpl::~wxPrinterDCImpl() +{ + delete m_nativePrinterDC ; +} + +bool wxPrinterDCImpl::StartDoc( const wxString& message ) +{ + wxASSERT_MSG( IsOk() , wxT("Called wxPrinterDC::StartDoc from an invalid object") ) ; + + if ( !m_ok ) + return false ; + + if ( m_nativePrinterDC->StartDoc( (wxPrinterDC*) GetOwner(), message ) ) + { + // in case we have to do additional things when successful + } + m_ok = m_nativePrinterDC->Ok() ; + if ( !m_ok ) + { + wxString message ; + message.Printf( wxT("Print Error %u"), m_nativePrinterDC->GetStatus() ) ; + wxMessageDialog dialog( NULL , message , wxEmptyString, wxICON_HAND | wxOK) ; + dialog.ShowModal(); + } + return m_ok ; } + +void wxPrinterDCImpl::EndDoc(void) +{ + if ( !m_ok ) + return ; + + m_nativePrinterDC->EndDoc( (wxPrinterDC*) GetOwner() ) ; + m_ok = m_nativePrinterDC->Ok() ; + + if ( !m_ok ) + { + wxString message ; + message.Printf( wxT("Print Error %u"), m_nativePrinterDC->GetStatus() ) ; + wxMessageDialog dialog( NULL , message , wxEmptyString, wxICON_HAND | wxOK) ; + dialog.ShowModal(); + } +} + +wxRect wxPrinterDCImpl::GetPaperRect() +{ + wxCoord w, h; + GetOwner()->GetSize(&w, &h); + wxRect pageRect(0, 0, w, h); + wxMacCarbonPrintData *native = (wxMacCarbonPrintData*) m_printData.GetNativeData() ; + OSStatus err = noErr ; + PMRect rPaper; + err = PMGetAdjustedPaperRect(native->m_macPageFormat, &rPaper); + if ( err != noErr ) + return pageRect; + return wxRect(wxCoord(rPaper.left), wxCoord(rPaper.top), + wxCoord(rPaper.right - rPaper.left), wxCoord(rPaper.bottom - rPaper.top)); +} + +void wxPrinterDCImpl::StartPage() +{ + if ( !m_ok ) + return ; + + m_logicalFunction = wxCOPY; + // m_textAlignment = wxALIGN_TOP_LEFT; + m_backgroundMode = wxTRANSPARENT; + + m_textForegroundColour = *wxBLACK; + m_textBackgroundColour = *wxWHITE; + m_pen = *wxBLACK_PEN; + m_font = *wxNORMAL_FONT; + m_brush = *wxTRANSPARENT_BRUSH; + m_backgroundBrush = *wxWHITE_BRUSH; + + m_nativePrinterDC->StartPage( (wxPrinterDC*) GetOwner() ) ; + m_ok = m_nativePrinterDC->Ok() ; + +} + +void wxPrinterDCImpl::EndPage() +{ + if ( !m_ok ) + return ; + + m_nativePrinterDC->EndPage( (wxPrinterDC*) GetOwner() ); + m_ok = m_nativePrinterDC->Ok() ; +} + +void wxPrinterDCImpl::DoGetSize(int *width, int *height) const +{ + wxCHECK_RET( m_ok , _T("GetSize() doesn't work without a valid wxPrinterDC") ); + m_nativePrinterDC->GetSize(width, height ) ; +} + +#endif