1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/mac/carbon/dcprint.cpp 
   3 // Purpose:     wxPrinterDC class 
   4 // Author:      Julian Smart 
   8 // Copyright:   (c) Julian Smart 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // For compilers that support precompilation, includes "wx.h". 
  13 #include "wx/wxprec.h" 
  15 #if wxUSE_PRINTING_ARCHITECTURE 
  21 #include "wx/dcprint.h" 
  24     #include "wx/msgdlg.h" 
  28 #include "wx/mac/uma.h" 
  29 #include "wx/mac/private/print.h" 
  30 #include "wx/mac/carbon/dcprint.h" 
  31 #include "wx/graphics.h" 
  33 IMPLEMENT_ABSTRACT_CLASS(wxPrinterDCImpl
, wxGCDCImpl
) 
  35 class wxNativePrinterDC
 
  38     wxNativePrinterDC() {} 
  39     virtual ~wxNativePrinterDC() {} 
  40     virtual bool StartDoc(  wxPrinterDC
* dc 
, const wxString
& message 
) = 0; 
  41     virtual void EndDoc( wxPrinterDC
* dc 
) = 0; 
  42     virtual void StartPage( wxPrinterDC
* dc 
) = 0; 
  43     virtual void EndPage( wxPrinterDC
* dc 
) = 0; 
  44     virtual void GetSize( int *w 
, int *h
) const = 0 ; 
  45     virtual wxSize 
GetPPI() const = 0 ; 
  47     // returns 0 in case of no Error, otherwise platform specific error codes 
  48     virtual wxUint32 
GetStatus() const = 0 ; 
  49     bool Ok() { return GetStatus() == 0 ; } 
  51     static wxNativePrinterDC
* Create(wxPrintData
* data
) ; 
  54 class wxMacCarbonPrinterDC 
: public wxNativePrinterDC
 
  57     wxMacCarbonPrinterDC( wxPrintData
* data 
) ; 
  58     virtual ~wxMacCarbonPrinterDC() ; 
  59     virtual bool StartDoc(  wxPrinterDC
* dc 
, const wxString
& message 
) ; 
  60     virtual void EndDoc( wxPrinterDC
* dc 
) ; 
  61     virtual void StartPage( wxPrinterDC
* dc 
) ; 
  62     virtual void EndPage( wxPrinterDC
* dc 
) ; 
  63     virtual wxUint32 
GetStatus() const { return m_err 
; } 
  64     virtual void GetSize( int *w 
, int *h
) const ; 
  65     virtual wxSize 
GetPPI() const ; 
  73 wxMacCarbonPrinterDC::wxMacCarbonPrinterDC( wxPrintData
* data 
) 
  76     wxMacCarbonPrintData 
*native 
= (wxMacCarbonPrintData
*) data
->GetNativeData() ; 
  79     m_err 
= PMGetAdjustedPageRect(native
->m_macPageFormat
, &rPage
); 
  83     m_maxX 
= wxCoord(rPage
.right 
- rPage
.left
) ; 
  84     m_maxY 
= wxCoord(rPage
.bottom 
- rPage
.top
); 
  88 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5  
  89     if ( PMPrinterGetOutputResolution 
!= NULL 
) 
  92         m_err 
= PMSessionGetCurrentPrinter(native
->m_macPrintSession
, &printer
); 
  95             m_err 
= PMPrinterGetOutputResolution( printer
, native
->m_macPrintSettings
, &res
) ; 
  96             if ( m_err 
== -9589 /* kPMKeyNotFound */ ) 
  99                 res
.hRes 
= res
.vRes 
= 300; 
 106 #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5  
 107         m_err 
= PMGetResolution((PMPageFormat
) (native
->m_macPageFormat
), &res
); 
 111     m_ppi 
= wxSize(int(res
.hRes
), int(res
.vRes
)); 
 114 wxMacCarbonPrinterDC::~wxMacCarbonPrinterDC() 
 118 wxNativePrinterDC
* wxNativePrinterDC::Create(wxPrintData
* data
) 
 120     return new wxMacCarbonPrinterDC(data
) ; 
 123 bool wxMacCarbonPrinterDC::StartDoc(  wxPrinterDC
* dc 
, const wxString
& WXUNUSED(message
)  ) 
 128     wxPrinterDCImpl 
*impl 
= (wxPrinterDCImpl
*) dc
->GetImpl(); 
 129     wxMacCarbonPrintData 
*native 
= (wxMacCarbonPrintData
*) impl
->GetPrintData().GetNativeData() ; 
 131     m_err 
= PMSessionBeginCGDocumentNoDialog(native
->m_macPrintSession
, 
 132               native
->m_macPrintSettings
, 
 133               native
->m_macPageFormat
);     
 134     if ( m_err 
!= noErr 
) 
 138     m_err 
= PMGetAdjustedPageRect(native
->m_macPageFormat
, &rPage
); 
 139     if ( m_err 
!= noErr 
) 
 142     m_maxX 
= wxCoord(rPage
.right 
- rPage
.left
) ; 
 143     m_maxY 
= wxCoord(rPage
.bottom 
- rPage
.top
); 
 146 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5  
 147     if ( PMPrinterGetOutputResolution 
!= NULL 
) 
 150         m_err 
= PMSessionGetCurrentPrinter(native
->m_macPrintSession
, &printer
); 
 151         if ( m_err 
== noErr 
) 
 153             m_err 
= PMPrinterGetOutputResolution( printer
, native
->m_macPrintSettings
, &res
) ; 
 154             if ( m_err 
== -9589 /* kPMKeyNotFound */ ) 
 157                 res
.hRes 
= res
.vRes 
= 300; 
 164 #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5  
 165        m_err 
= PMGetResolution((PMPageFormat
) (native
->m_macPageFormat
), &res
); 
 169     m_ppi 
= wxSize(int(res
.hRes
), int(res
.vRes
)); 
 173 void wxMacCarbonPrinterDC::EndDoc( wxPrinterDC
* dc 
) 
 178     wxPrinterDCImpl 
*impl 
= (wxPrinterDCImpl
*) dc
->GetImpl(); 
 179     wxMacCarbonPrintData 
*native 
= (wxMacCarbonPrintData
*) impl
->GetPrintData().GetNativeData() ; 
 181     m_err 
= PMSessionEndDocumentNoDialog(native
->m_macPrintSession
); 
 184 void wxMacCarbonPrinterDC::StartPage( wxPrinterDC
* dc 
) 
 189     wxPrinterDCImpl 
*impl 
= (wxPrinterDCImpl
*) dc
->GetImpl(); 
 190     wxMacCarbonPrintData 
*native 
= (wxMacCarbonPrintData
*) impl
->GetPrintData().GetNativeData() ; 
 192     m_err 
= PMSessionBeginPageNoDialog(native
->m_macPrintSession
, 
 193                  native
->m_macPageFormat
, 
 196     CGContextRef pageContext
; 
 198     if ( m_err 
== noErr 
) 
 200         m_err 
= PMSessionGetCGGraphicsContext(native
->m_macPrintSession
, 
 204     if ( m_err 
!= noErr 
) 
 206         PMSessionEndPageNoDialog(native
->m_macPrintSession
); 
 207         PMSessionEndDocumentNoDialog(native
->m_macPrintSession
); 
 213         m_err 
= PMGetAdjustedPageRect(native
->m_macPageFormat
, &rPage
); 
 217             PMGetAdjustedPaperRect( native
->m_macPageFormat 
, &paperRect 
) ; 
 218             // make sure (0,0) is at the upper left of the printable area (wx conventions) 
 219             // Core Graphics initially has the lower left of the paper as 0,0 
 220             CGContextTranslateCTM( pageContext 
, -paperRect
.left 
, paperRect
.bottom 
) ; 
 221             CGContextScaleCTM( pageContext 
, 1 , -1 ) ; 
 223         // since this is a non-critical error, we set the flag back 
 226     impl
->SetGraphicsContext( wxGraphicsContext::CreateFromNative( pageContext 
) ); 
 229 void wxMacCarbonPrinterDC::EndPage( wxPrinterDC
* dc 
) 
 234     wxPrinterDCImpl 
*impl 
= (wxPrinterDCImpl
*) dc
->GetImpl(); 
 235     wxMacCarbonPrintData 
*native 
= (wxMacCarbonPrintData
*) impl
->GetPrintData().GetNativeData() ; 
 237     m_err 
= PMSessionEndPageNoDialog(native
->m_macPrintSession
); 
 238     if ( m_err 
!= noErr 
) 
 240         PMSessionEndDocumentNoDialog(native
->m_macPrintSession
); 
 242     // the cg context we got when starting the page isn't valid anymore, so replace it 
 243     impl
->SetGraphicsContext( wxGraphicsContext::Create() ); 
 246 void wxMacCarbonPrinterDC::GetSize( int *w 
, int *h
) const 
 254 wxSize 
wxMacCarbonPrinterDC::GetPPI() const  
 263 wxPrinterDCImpl::wxPrinterDCImpl( wxPrinterDC 
*owner
, const wxPrintData
& printdata 
) 
 264    : wxGCDCImpl( owner 
) 
 267     m_printData 
= printdata 
; 
 268     m_printData
.ConvertToNative() ; 
 269     m_nativePrinterDC 
= wxNativePrinterDC::Create( &m_printData 
) ; 
 270     if ( m_nativePrinterDC 
) 
 272         m_ok 
= m_nativePrinterDC
->Ok() ; 
 276             message
.Printf( wxT("Print Error %u"), m_nativePrinterDC
->GetStatus() ) ; 
 277             wxMessageDialog 
dialog( NULL 
, message 
, wxEmptyString
, wxICON_HAND 
| wxOK
) ; 
 282             wxSize sz 
= GetPPI(); 
 283             m_mm_to_pix_x 
= mm2inches 
* sz
.x
; 
 284             m_mm_to_pix_y 
= mm2inches 
* sz
.y
;         
 286         // we need at least a measuring context because people start measuring before a page 
 287         // gets printed at all 
 288         SetGraphicsContext( wxGraphicsContext::Create() ); 
 292 wxSize 
wxPrinterDCImpl::GetPPI() const 
 294     return m_nativePrinterDC
->GetPPI() ; 
 297 wxPrinterDCImpl::~wxPrinterDCImpl() 
 299     delete m_nativePrinterDC 
; 
 302 bool wxPrinterDCImpl::StartDoc( const wxString
& message 
) 
 304     wxASSERT_MSG( IsOk() , wxT("Called wxPrinterDC::StartDoc from an invalid object") ) ; 
 309     if ( m_nativePrinterDC
->StartDoc( (wxPrinterDC
*) GetOwner(), message 
) ) 
 311         // in case we have to do additional things when successful 
 313     m_ok 
= m_nativePrinterDC
->Ok() ; 
 317         message
.Printf( wxT("Print Error %u"), m_nativePrinterDC
->GetStatus() ) ; 
 318         wxMessageDialog 
dialog( NULL 
, message 
, wxEmptyString
, wxICON_HAND 
| wxOK
) ; 
 325 void wxPrinterDCImpl::EndDoc(void) 
 330     m_nativePrinterDC
->EndDoc( (wxPrinterDC
*) GetOwner() ) ; 
 331     m_ok 
= m_nativePrinterDC
->Ok() ; 
 336         message
.Printf( wxT("Print Error %u"), m_nativePrinterDC
->GetStatus() ) ; 
 337         wxMessageDialog 
dialog( NULL 
, message 
, wxEmptyString
, wxICON_HAND 
| wxOK
) ; 
 342 wxRect 
wxPrinterDCImpl::GetPaperRect() 
 345     GetOwner()->GetSize(&w
, &h
); 
 346     wxRect 
pageRect(0, 0, w
, h
); 
 347     wxMacCarbonPrintData 
*native 
= (wxMacCarbonPrintData
*) m_printData
.GetNativeData() ; 
 348     OSStatus err 
= noErr 
; 
 350     err 
= PMGetAdjustedPaperRect(native
->m_macPageFormat
, &rPaper
); 
 353     return wxRect(wxCoord(rPaper
.left
), wxCoord(rPaper
.top
), 
 354         wxCoord(rPaper
.right 
- rPaper
.left
), wxCoord(rPaper
.bottom 
- rPaper
.top
)); 
 357 void wxPrinterDCImpl::StartPage() 
 362     m_logicalFunction 
= wxCOPY
; 
 363     //  m_textAlignment = wxALIGN_TOP_LEFT; 
 364     m_backgroundMode 
= wxTRANSPARENT
; 
 366     m_textForegroundColour 
= *wxBLACK
; 
 367     m_textBackgroundColour 
= *wxWHITE
; 
 368     m_pen 
= *wxBLACK_PEN
; 
 369     m_font 
= *wxNORMAL_FONT
; 
 370     m_brush 
= *wxTRANSPARENT_BRUSH
; 
 371     m_backgroundBrush 
= *wxWHITE_BRUSH
; 
 373     m_nativePrinterDC
->StartPage( (wxPrinterDC
*) GetOwner() ) ; 
 374     m_ok 
= m_nativePrinterDC
->Ok() ; 
 378 void wxPrinterDCImpl::EndPage() 
 383     m_nativePrinterDC
->EndPage( (wxPrinterDC
*) GetOwner() ); 
 384     m_ok 
= m_nativePrinterDC
->Ok() ; 
 387 void wxPrinterDCImpl::DoGetSize(int *width
, int *height
) const 
 389     wxCHECK_RET( m_ok 
, _T("GetSize() doesn't work without a valid wxPrinterDC") ); 
 390     m_nativePrinterDC
->GetSize(width
,  height 
) ;