1///////////////////////////////////////////////////////////////////////////// 2// Name: src/mac/carbon/dcprint.cpp 3// Purpose: wxPrinterDC class 4// Author: Julian Smart 5// Modified by: 6// Created: 01/02/97 7// RCS-ID: $Id: dcprint.cpp 57932 2009-01-09 10:01:11Z SC $ 8// Copyright: (c) Julian Smart 9// Licence: wxWindows licence 10///////////////////////////////////////////////////////////////////////////// 11 12// For compilers that support precompilation, includes "wx.h". 13#include "wx/wxprec.h" 14 15#if wxUSE_PRINTING_ARCHITECTURE 16 17#ifdef __BORLANDC__ 18 #pragma hdrstop 19#endif 20 21#include "wx/dcprint.h" 22 23#ifndef WX_PRECOMP 24 #include "wx/msgdlg.h" 25 #include "wx/math.h" 26#endif 27 28#include "wx/mac/uma.h" 29#include "wx/mac/private/print.h" 30#include "wx/graphics.h" 31 32IMPLEMENT_CLASS(wxPrinterDC, wxDC) 33 34class wxNativePrinterDC 35{ 36public : 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 ; 45 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 ; } 49 50 static wxNativePrinterDC* Create(wxPrintData* data) ; 51} ; 52 53class wxMacCarbonPrinterDC : public wxNativePrinterDC 54{ 55public : 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 ; 65private : 66#if !wxMAC_USE_CORE_GRAPHICS 67 GrafPtr m_macPrintFormerPort ; 68#endif 69 wxCoord m_maxX ; 70 wxCoord m_maxY ; 71 wxSize m_ppi ; 72 OSStatus m_err ; 73} ; 74 75wxMacCarbonPrinterDC::wxMacCarbonPrinterDC( wxPrintData* data ) 76{ 77#if !wxMAC_USE_CORE_GRAPHICS 78 ::GetPort( & m_macPrintFormerPort ) ; 79#endif 80 m_err = noErr ; 81 wxMacCarbonPrintData *native = (wxMacCarbonPrintData*) data->GetNativeData() ; 82 83 PMRect rPage; 84 m_err = PMGetAdjustedPageRect(native->m_macPageFormat, &rPage); 85 if ( m_err != noErr ) 86 return; 87 88 m_maxX = wxCoord(rPage.right - rPage.left) ; 89 m_maxY = wxCoord(rPage.bottom - rPage.top); 90 91 PMResolution res; 92 m_err = PMGetResolution((PMPageFormat) (native->m_macPageFormat), &res); 93 94 m_ppi = wxSize(int(res.hRes), int(res.vRes)); 95} 96 97wxMacCarbonPrinterDC::~wxMacCarbonPrinterDC() 98{ 99#if !wxMAC_USE_CORE_GRAPHICS 100 // nothing to release from print data, as wxPrinterDC has all data in its wxPrintData member 101 ::SetPort( m_macPrintFormerPort ) ; 102#endif 103} 104 105wxNativePrinterDC* wxNativePrinterDC::Create(wxPrintData* data) 106{ 107 return new wxMacCarbonPrinterDC(data) ; 108} 109 110bool wxMacCarbonPrinterDC::StartDoc( wxPrinterDC* dc , const wxString& WXUNUSED(message) ) 111{ 112 if ( m_err ) 113 return false ; 114 115 wxMacCarbonPrintData *native = (wxMacCarbonPrintData*) dc->GetPrintData().GetNativeData() ; 116 117#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_4 && wxMAC_USE_CORE_GRAPHICS 118 { 119 CFStringRef s[1] = { kPMGraphicsContextCoreGraphics }; 120 CFArrayRef graphicsContextsArray = CFArrayCreate(NULL, (const void**)s, 1, &kCFTypeArrayCallBacks); 121 PMSessionSetDocumentFormatGeneration(native->m_macPrintSession, kPMDocumentFormatPDF, graphicsContextsArray, NULL); 122 CFRelease(graphicsContextsArray); 123 } 124#endif 125#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_4 && wxMAC_USE_CORE_GRAPHICS 126 m_err = PMSessionBeginCGDocument(native->m_macPrintSession, 127 native->m_macPrintSettings, 128 native->m_macPageFormat); 129#else 130 m_err = PMSessionBeginDocument(native->m_macPrintSession, 131 native->m_macPrintSettings, 132 native->m_macPageFormat); 133 134#endif 135 136 if ( m_err != noErr ) 137 return false; 138 139 PMRect rPage; 140 m_err = PMGetAdjustedPageRect(native->m_macPageFormat, &rPage); 141 if ( m_err != noErr ) 142 return false ; 143 144 m_maxX = wxCoord(rPage.right - rPage.left) ; 145 m_maxY = wxCoord(rPage.bottom - rPage.top); 146 147 PMResolution res; 148 m_err = PMGetResolution((PMPageFormat) (native->m_macPageFormat), &res); 149 150 m_ppi = wxSize(int(res.hRes), int(res.vRes)); 151 return true ; 152} 153 154void wxMacCarbonPrinterDC::EndDoc( wxPrinterDC* dc ) 155{ 156 if ( m_err ) 157 return ; 158 159 wxMacCarbonPrintData *native = (wxMacCarbonPrintData*) dc->GetPrintData().GetNativeData() ; 160 161 m_err = PMSessionEndDocument(native->m_macPrintSession); 162} 163 164void wxMacCarbonPrinterDC::StartPage( wxPrinterDC* dc ) 165{ 166 if ( m_err ) 167 return ; 168 169 wxMacCarbonPrintData *native = (wxMacCarbonPrintData*) dc->GetPrintData().GetNativeData() ; 170 171 m_err = PMSessionBeginPage(native->m_macPrintSession, 172 native->m_macPageFormat, 173 nil); 174 175#if wxMAC_USE_CORE_GRAPHICS 176 CGContextRef pageContext; 177#endif 178 if ( m_err == noErr ) 179 { 180#if wxMAC_USE_CORE_GRAPHICS 181#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_4 182 m_err = PMSessionGetCGGraphicsContext(native->m_macPrintSession, 183 &pageContext ); 184 185#else 186 m_err = PMSessionGetGraphicsContext(native->m_macPrintSession, 187 kPMGraphicsContextCoreGraphics, 188 (void**) &pageContext ); 189#endif 190#else 191 m_err = PMSessionGetGraphicsContext(native->m_macPrintSession, 192 kPMGraphicsContextQuickdraw, 193 (void**) &dc->m_macPort ); 194#endif 195 } 196 197 if ( m_err != noErr ) 198 { 199 PMSessionEndPage(native->m_macPrintSession); 200 PMSessionEndDocument(native->m_macPrintSession); 201 } 202 else 203 { 204 PMRect rPage; 205 206 m_err = PMGetAdjustedPageRect(native->m_macPageFormat, &rPage); 207 if ( !m_err ) 208 { 209#if wxMAC_USE_CORE_GRAPHICS 210 PMRect paperRect ; 211 PMGetAdjustedPaperRect( native->m_macPageFormat , &paperRect ) ; 212 // make sure (0,0) is at the upper left of the printable area (wx conventions) 213 // Core Graphics initially has the lower left of the paper as 0,0 214 CGContextTranslateCTM( pageContext , -paperRect.left , paperRect.bottom ) ; 215 CGContextScaleCTM( pageContext , 1 , -1 ) ; 216#else 217 dc->m_macLocalOrigin.x = (int) rPage.left; 218 dc->m_macLocalOrigin.y = (int) rPage.top; 219#endif 220 } 221 // since this is a non-critical error, we set the flag back 222 m_err = noErr ; 223 } 224#if wxMAC_USE_CORE_GRAPHICS 225 dc->SetGraphicsContext( wxGraphicsContext::CreateFromNative( pageContext ) ); 226#endif 227} 228 229void wxMacCarbonPrinterDC::EndPage( wxPrinterDC* dc ) 230{ 231 if ( m_err ) 232 return ; 233 234 wxMacCarbonPrintData *native = (wxMacCarbonPrintData*) dc->GetPrintData().GetNativeData() ; 235 236 m_err = PMSessionEndPage(native->m_macPrintSession); 237 if ( m_err != noErr ) 238 { 239 PMSessionEndDocument(native->m_macPrintSession); 240 } 241#if wxMAC_USE_CORE_GRAPHICS 242 // the cg context we got when starting the page isn't valid anymore, so replace it 243 dc->SetGraphicsContext( wxGraphicsContext::Create() ); 244#endif 245} 246 247void wxMacCarbonPrinterDC::GetSize( int *w , int *h) const 248{ 249 if ( w ) 250 *w = m_maxX ; 251 if ( h ) 252 *h = m_maxY ; 253} 254 255wxSize wxMacCarbonPrinterDC::GetPPI() const 256{ 257 return m_ppi ; 258}; 259 260// 261// 262// 263 264wxPrinterDC::wxPrinterDC(const wxPrintData& printdata) 265{ 266 m_ok = false ; 267 m_printData = printdata ; 268 m_printData.ConvertToNative() ; 269 m_nativePrinterDC = wxNativePrinterDC::Create( &m_printData ) ; 270 if ( m_nativePrinterDC ) 271 { 272 m_ok = m_nativePrinterDC->Ok() ; 273 if ( !m_ok ) 274 { 275 wxString message ; 276 message.Printf( wxT("Print Error %u"), m_nativePrinterDC->GetStatus() ) ; 277 wxMessageDialog dialog( NULL , message , wxEmptyString, wxICON_HAND | wxOK) ; 278 dialog.ShowModal(); 279 } 280 else 281 { 282 wxSize sz = GetPPI(); 283 m_mm_to_pix_x = mm2inches * sz.x; 284 m_mm_to_pix_y = mm2inches * sz.y; 285 } 286#if wxMAC_USE_CORE_GRAPHICS 287 // we need at least a measuring context because people start measuring before a page 288 // gets printed at all 289 SetGraphicsContext( wxGraphicsContext::Create() ); 290#endif 291 } 292} 293 294wxSize wxPrinterDC::GetPPI() const 295{ 296 return m_nativePrinterDC->GetPPI() ; 297} 298 299wxPrinterDC::~wxPrinterDC(void) 300{ 301 delete m_nativePrinterDC ; 302} 303 304bool wxPrinterDC::StartDoc( const wxString& message ) 305{ 306 wxASSERT_MSG( Ok() , wxT("Called wxPrinterDC::StartDoc from an invalid object") ) ; 307 308 if ( !m_ok ) 309 return false ; 310 311 if ( m_nativePrinterDC->StartDoc(this, message ) ) 312 { 313 // in case we have to do additional things when successful 314 } 315 m_ok = m_nativePrinterDC->Ok() ; 316 if ( !m_ok ) 317 { 318 wxString message ; 319 message.Printf( wxT("Print Error %u"), m_nativePrinterDC->GetStatus() ) ; 320 wxMessageDialog dialog( NULL , message , wxEmptyString, wxICON_HAND | wxOK) ; 321 dialog.ShowModal(); 322 } 323 324 return m_ok ; 325} 326 327void wxPrinterDC::EndDoc(void) 328{ 329 if ( !m_ok ) 330 return ; 331 332 m_nativePrinterDC->EndDoc( this ) ; 333 m_ok = m_nativePrinterDC->Ok() ; 334 335 if ( !m_ok ) 336 { 337 wxString message ; 338 message.Printf( wxT("Print Error %u"), m_nativePrinterDC->GetStatus() ) ; 339 wxMessageDialog dialog( NULL , message , wxEmptyString, wxICON_HAND | wxOK) ; 340 dialog.ShowModal(); 341 } 342} 343 344wxRect wxPrinterDC::GetPaperRect() 345{ 346 wxCoord w, h; 347 GetSize(&w, &h); 348 wxRect pageRect(0, 0, w, h); 349 wxMacCarbonPrintData *native = (wxMacCarbonPrintData*) m_printData.GetNativeData() ; 350 OSStatus err = noErr ; 351 PMRect rPaper; 352 err = PMGetAdjustedPaperRect(native->m_macPageFormat, &rPaper); 353 if ( err != noErr ) 354 return pageRect; 355 return wxRect(wxCoord(rPaper.left), wxCoord(rPaper.top), 356 wxCoord(rPaper.right - rPaper.left), wxCoord(rPaper.bottom - rPaper.top)); 357} 358 359void wxPrinterDC::StartPage(void) 360{ 361 if ( !m_ok ) 362 return ; 363 364 m_logicalFunction = wxCOPY; 365 // m_textAlignment = wxALIGN_TOP_LEFT; 366 m_backgroundMode = wxTRANSPARENT; 367 368 m_textForegroundColour = *wxBLACK; 369 m_textBackgroundColour = *wxWHITE; 370 m_pen = *wxBLACK_PEN; 371 m_font = *wxNORMAL_FONT; 372 m_brush = *wxTRANSPARENT_BRUSH; 373 m_backgroundBrush = *wxWHITE_BRUSH; 374#if !wxMAC_USE_CORE_GRAPHICS 375 m_macFontInstalled = false ; 376 m_macBrushInstalled = false ; 377 m_macPenInstalled = false ; 378#endif 379 380 m_nativePrinterDC->StartPage(this) ; 381 m_ok = m_nativePrinterDC->Ok() ; 382 383} 384 385void wxPrinterDC::EndPage(void) 386{ 387 if ( !m_ok ) 388 return ; 389 390 m_nativePrinterDC->EndPage(this) ; 391 m_ok = m_nativePrinterDC->Ok() ; 392} 393 394void wxPrinterDC::DoGetSize(int *width, int *height) const 395{ 396 wxCHECK_RET( m_ok , _T("GetSize() doesn't work without a valid wxPrinterDC") ); 397 m_nativePrinterDC->GetSize(width, height ) ; 398} 399 400#endif 401