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/graphics.h" 
  32 IMPLEMENT_CLASS(wxPrinterDC
, wxDC
) 
  34 class wxNativePrinterDC
 
  37     wxNativePrinterDC() {} 
  38     virtual ~wxNativePrinterDC() {} 
  39     virtual bool StartDoc(  wxPrinterDC
* dc 
, const wxString
& message 
) = 0; 
  40     virtual void EndDoc( wxPrinterDC
* dc 
) = 0; 
  41     virtual void StartPage( wxPrinterDC
* dc 
) = 0; 
  42     virtual void EndPage( wxPrinterDC
* dc 
) = 0; 
  43     virtual void GetSize( int *w 
, int *h
) const = 0 ; 
  44     virtual wxSize 
GetPPI() const = 0 ; 
  46     // returns 0 in case of no Error, otherwise platform specific error codes 
  47     virtual wxUint32 
GetStatus() const = 0 ; 
  48     bool Ok() { return GetStatus() == 0 ; } 
  50     static wxNativePrinterDC
* Create(wxPrintData
* data
) ; 
  53 class wxMacCarbonPrinterDC 
: public wxNativePrinterDC
 
  56     wxMacCarbonPrinterDC( wxPrintData
* data 
) ; 
  57     virtual ~wxMacCarbonPrinterDC() ; 
  58     virtual bool StartDoc(  wxPrinterDC
* dc 
, const wxString
& message 
) ; 
  59     virtual void EndDoc( wxPrinterDC
* dc 
) ; 
  60     virtual void StartPage( wxPrinterDC
* dc 
) ; 
  61     virtual void EndPage( wxPrinterDC
* dc 
) ; 
  62     virtual wxUint32 
GetStatus() const { return m_err 
; } 
  63     virtual void GetSize( int *w 
, int *h
) const ; 
  64     virtual wxSize 
GetPPI() const ; 
  66 #if !wxMAC_USE_CORE_GRAPHICS 
  67     GrafPtr m_macPrintFormerPort 
; 
  75 wxMacCarbonPrinterDC::wxMacCarbonPrinterDC( wxPrintData
* data 
) 
  77 #if !wxMAC_USE_CORE_GRAPHICS 
  78     ::GetPort( & m_macPrintFormerPort 
) ; 
  81     wxMacCarbonPrintData 
*native 
= (wxMacCarbonPrintData
*) data
->GetNativeData() ; 
  84     m_err 
= PMGetAdjustedPageRect(native
->m_macPageFormat
, &rPage
); 
  88     m_maxX 
= wxCoord(rPage
.right 
- rPage
.left
) ; 
  89     m_maxY 
= wxCoord(rPage
.bottom 
- rPage
.top
); 
  92 #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5  
  94     PMSessionGetCurrentPrinter(native
->m_macPrintSession
, &printer
); 
  95     PMPrinterGetOutputResolution( printer
, native
->m_macPrintSettings
, &res
) ; 
  97     m_err 
= PMGetResolution((PMPageFormat
) (native
->m_macPageFormat
), &res
); 
  99     m_ppi 
= wxSize(int(res
.hRes
), int(res
.vRes
)); 
 102 wxMacCarbonPrinterDC::~wxMacCarbonPrinterDC() 
 104 #if !wxMAC_USE_CORE_GRAPHICS 
 105     // nothing to release from print data, as wxPrinterDC has all data in its wxPrintData member 
 106     ::SetPort( m_macPrintFormerPort 
) ; 
 110 wxNativePrinterDC
* wxNativePrinterDC::Create(wxPrintData
* data
) 
 112     return new wxMacCarbonPrinterDC(data
) ; 
 115 bool wxMacCarbonPrinterDC::StartDoc(  wxPrinterDC
* dc 
, const wxString
& WXUNUSED(message
)  ) 
 120     wxMacCarbonPrintData 
*native 
= (wxMacCarbonPrintData
*) dc
->GetPrintData().GetNativeData() ; 
 122 #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_4 && wxMAC_USE_CORE_GRAPHICS 
 124         CFStringRef s
[1] = { kPMGraphicsContextCoreGraphics 
}; 
 125         CFArrayRef  graphicsContextsArray 
= CFArrayCreate(NULL
, (const void**)s
, 1, &kCFTypeArrayCallBacks
); 
 126         PMSessionSetDocumentFormatGeneration(native
->m_macPrintSession
, kPMDocumentFormatPDF
, graphicsContextsArray
, NULL
); 
 127         CFRelease(graphicsContextsArray
); 
 130 #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_4 && wxMAC_USE_CORE_GRAPHICS 
 131     m_err 
= PMSessionBeginCGDocument(native
->m_macPrintSession
, 
 132               native
->m_macPrintSettings
, 
 133               native
->m_macPageFormat
); 
 135     m_err 
= PMSessionBeginDocument(native
->m_macPrintSession
, 
 136               native
->m_macPrintSettings
, 
 137               native
->m_macPageFormat
); 
 141     if ( m_err 
!= noErr 
) 
 145     m_err 
= PMGetAdjustedPageRect(native
->m_macPageFormat
, &rPage
); 
 146     if ( m_err 
!= noErr 
) 
 149     m_maxX 
= wxCoord(rPage
.right 
- rPage
.left
) ; 
 150     m_maxY 
= wxCoord(rPage
.bottom 
- rPage
.top
); 
 153 #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5  
 155     PMSessionGetCurrentPrinter(native
->m_macPrintSession
, &printer
); 
 156     PMPrinterGetOutputResolution( printer
, native
->m_macPrintSettings
, &res
) ; 
 158     m_err 
= PMGetResolution((PMPageFormat
) (native
->m_macPageFormat
), &res
); 
 160     m_ppi 
= wxSize(int(res
.hRes
), int(res
.vRes
)); 
 164 void wxMacCarbonPrinterDC::EndDoc( wxPrinterDC
* dc 
) 
 169     wxMacCarbonPrintData 
*native 
= (wxMacCarbonPrintData
*) dc
->GetPrintData().GetNativeData() ; 
 171     m_err 
= PMSessionEndDocument(native
->m_macPrintSession
); 
 174 void wxMacCarbonPrinterDC::StartPage( wxPrinterDC
* dc 
) 
 179     wxMacCarbonPrintData 
*native 
= (wxMacCarbonPrintData
*) dc
->GetPrintData().GetNativeData() ; 
 181     m_err 
= PMSessionBeginPage(native
->m_macPrintSession
, 
 182                  native
->m_macPageFormat
, 
 185 #if wxMAC_USE_CORE_GRAPHICS 
 186     CGContextRef pageContext
; 
 188     if ( m_err 
== noErr 
) 
 190 #if wxMAC_USE_CORE_GRAPHICS 
 191 #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_4 
 192         m_err 
= PMSessionGetCGGraphicsContext(native
->m_macPrintSession
, 
 196         m_err 
= PMSessionGetGraphicsContext(native
->m_macPrintSession
, 
 197                                             kPMGraphicsContextCoreGraphics
, 
 198                                             (void**) &pageContext 
); 
 201         m_err 
= PMSessionGetGraphicsContext(native
->m_macPrintSession
, 
 202                                             kPMGraphicsContextQuickdraw
, 
 203                                             (void**) &dc
->m_macPort 
); 
 207     if ( m_err 
!= noErr 
) 
 209         PMSessionEndPage(native
->m_macPrintSession
); 
 210         PMSessionEndDocument(native
->m_macPrintSession
); 
 216         m_err 
= PMGetAdjustedPageRect(native
->m_macPageFormat
, &rPage
); 
 219 #if wxMAC_USE_CORE_GRAPHICS 
 221             PMGetAdjustedPaperRect( native
->m_macPageFormat 
, &paperRect 
) ; 
 222             // make sure (0,0) is at the upper left of the printable area (wx conventions) 
 223             // Core Graphics initially has the lower left of the paper as 0,0 
 224             CGContextTranslateCTM( pageContext 
, -paperRect
.left 
, paperRect
.bottom 
) ; 
 225             CGContextScaleCTM( pageContext 
, 1 , -1 ) ; 
 227             dc
->SetDeviceLocalOrigin( (wxCoord
) rPage
.left
, (wxCoord
) rPage
.top 
); 
 230         // since this is a non-critical error, we set the flag back 
 233 #if wxMAC_USE_CORE_GRAPHICS 
 234     dc
->SetGraphicsContext( wxGraphicsContext::CreateFromNative( pageContext 
) ); 
 238 void wxMacCarbonPrinterDC::EndPage( wxPrinterDC
* dc 
) 
 243     wxMacCarbonPrintData 
*native 
= (wxMacCarbonPrintData
*) dc
->GetPrintData().GetNativeData() ; 
 245     m_err 
= PMSessionEndPage(native
->m_macPrintSession
); 
 246     if ( m_err 
!= noErr 
) 
 248         PMSessionEndDocument(native
->m_macPrintSession
); 
 250 #if wxMAC_USE_CORE_GRAPHICS 
 251     // the cg context we got when starting the page isn't valid anymore, so replace it 
 252     dc
->SetGraphicsContext( wxGraphicsContext::Create() ); 
 256 void wxMacCarbonPrinterDC::GetSize( int *w 
, int *h
) const 
 264 wxSize 
wxMacCarbonPrinterDC::GetPPI() const  
 273 wxPrinterDC::wxPrinterDC(const wxPrintData
& printdata
) 
 276     m_printData 
= printdata 
; 
 277     m_printData
.ConvertToNative() ; 
 278     m_nativePrinterDC 
= wxNativePrinterDC::Create( &m_printData 
) ; 
 279     if ( m_nativePrinterDC 
) 
 281         m_ok 
= m_nativePrinterDC
->Ok() ; 
 285             message
.Printf( wxT("Print Error %u"), m_nativePrinterDC
->GetStatus() ) ; 
 286             wxMessageDialog 
dialog( NULL 
, message 
, wxEmptyString
, wxICON_HAND 
| wxOK
) ; 
 291             wxSize sz 
= GetPPI(); 
 292             m_mm_to_pix_x 
= mm2inches 
* sz
.x
; 
 293             m_mm_to_pix_y 
= mm2inches 
* sz
.y
;         
 295 #if wxMAC_USE_CORE_GRAPHICS 
 296         // we need at least a measuring context because people start measuring before a page 
 297         // gets printed at all 
 298         SetGraphicsContext( wxGraphicsContext::Create() ); 
 303 wxSize 
wxPrinterDC::GetPPI() const 
 305     return m_nativePrinterDC
->GetPPI() ; 
 308 wxPrinterDC::~wxPrinterDC(void) 
 310     delete m_nativePrinterDC 
; 
 313 bool wxPrinterDC::StartDoc( const wxString
& message 
) 
 315     wxASSERT_MSG( Ok() , wxT("Called wxPrinterDC::StartDoc from an invalid object") ) ; 
 320     if ( m_nativePrinterDC
->StartDoc(this, message 
) ) 
 322         // in case we have to do additional things when successful 
 324     m_ok 
= m_nativePrinterDC
->Ok() ; 
 328         message
.Printf( wxT("Print Error %u"), m_nativePrinterDC
->GetStatus() ) ; 
 329         wxMessageDialog 
dialog( NULL 
, message 
, wxEmptyString
, wxICON_HAND 
| wxOK
) ; 
 336 void wxPrinterDC::EndDoc(void) 
 341     m_nativePrinterDC
->EndDoc( this ) ; 
 342     m_ok 
= m_nativePrinterDC
->Ok() ; 
 347         message
.Printf( wxT("Print Error %u"), m_nativePrinterDC
->GetStatus() ) ; 
 348         wxMessageDialog 
dialog( NULL 
, message 
, wxEmptyString
, wxICON_HAND 
| wxOK
) ; 
 353 wxRect 
wxPrinterDC::GetPaperRect() 
 357     wxRect 
pageRect(0, 0, w
, h
); 
 358     wxMacCarbonPrintData 
*native 
= (wxMacCarbonPrintData
*) m_printData
.GetNativeData() ; 
 359     OSStatus err 
= noErr 
; 
 361     err 
= PMGetAdjustedPaperRect(native
->m_macPageFormat
, &rPaper
); 
 364     return wxRect(wxCoord(rPaper
.left
), wxCoord(rPaper
.top
), 
 365         wxCoord(rPaper
.right 
- rPaper
.left
), wxCoord(rPaper
.bottom 
- rPaper
.top
)); 
 368 void wxPrinterDC::StartPage(void) 
 373     m_logicalFunction 
= wxCOPY
; 
 374     //  m_textAlignment = wxALIGN_TOP_LEFT; 
 375     m_backgroundMode 
= wxTRANSPARENT
; 
 377     m_textForegroundColour 
= *wxBLACK
; 
 378     m_textBackgroundColour 
= *wxWHITE
; 
 379     m_pen 
= *wxBLACK_PEN
; 
 380     m_font 
= *wxNORMAL_FONT
; 
 381     m_brush 
= *wxTRANSPARENT_BRUSH
; 
 382     m_backgroundBrush 
= *wxWHITE_BRUSH
; 
 383 #if !wxMAC_USE_CORE_GRAPHICS 
 384     m_macFontInstalled 
= false ; 
 385     m_macBrushInstalled 
= false ; 
 386     m_macPenInstalled 
= false ; 
 389     m_nativePrinterDC
->StartPage(this) ; 
 390     m_ok 
= m_nativePrinterDC
->Ok() ; 
 394 void wxPrinterDC::EndPage(void) 
 399     m_nativePrinterDC
->EndPage(this) ; 
 400     m_ok 
= m_nativePrinterDC
->Ok() ; 
 403 void wxPrinterDC::DoGetSize(int *width
, int *height
) const 
 405     wxCHECK_RET( m_ok 
, _T("GetSize() doesn't work without a valid wxPrinterDC") ); 
 406     m_nativePrinterDC
->GetSize(width
,  height 
) ;