1///////////////////////////////////////////////////////////////////////////// 2// Name: src/mac/classic/dcprint.cpp 3// Purpose: wxPrinterDC class 4// Author: Julian Smart 5// Modified by: 6// Created: 01/02/97 7// RCS-ID: $Id: dcprint.cpp 42522 2006-10-27 13:07:40Z JS $ 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#ifdef __BORLANDC__ 16 #pragma hdrstop 17#endif 18 19#include "wx/dcprint.h" 20 21#ifndef WX_PRECOMP 22 #include "wx/msgdlg.h" 23 #include "wx/math.h" 24#endif 25 26#include "wx/mac/uma.h" 27#include "wx/mac/private/print.h" 28 29IMPLEMENT_CLASS(wxPrinterDC, wxDC) 30 31class wxNativePrinterDC 32{ 33public : 34 wxNativePrinterDC() {} 35 virtual ~wxNativePrinterDC() {} 36 virtual bool StartDoc( wxPrinterDC* dc , const wxString& message ) = 0; 37 virtual void EndDoc( wxPrinterDC* dc ) = 0; 38 virtual void StartPage( wxPrinterDC* dc ) = 0; 39 virtual void EndPage( wxPrinterDC* dc ) = 0; 40 virtual wxCoord GetMaxX() const = 0 ; 41 virtual wxCoord GetMaxY() const = 0 ; 42 // returns 0 in case of no Error, otherwise platform specific error codes 43 virtual wxUint32 GetStatus() const = 0 ; 44 bool Ok() { return GetStatus() == 0 ; } 45 46 static wxNativePrinterDC* Create(wxPrintData* data) ; 47} ; 48 49#if TARGET_CARBON 50 51class wxMacCarbonPrinterDC : public wxNativePrinterDC 52{ 53public : 54 wxMacCarbonPrinterDC( wxPrintData* data ) ; 55 virtual ~wxMacCarbonPrinterDC() ; 56 virtual bool StartDoc( wxPrinterDC* dc , const wxString& message ) ; 57 virtual void EndDoc( wxPrinterDC* dc ) ; 58 virtual void StartPage( wxPrinterDC* dc ) ; 59 virtual void EndPage( wxPrinterDC* dc ) ; 60 virtual wxCoord GetMaxX() const { return m_maxX ; } 61 virtual wxCoord GetMaxY() const { return m_maxY ; } 62 virtual wxUint32 GetStatus() const { return m_err ; } 63private : 64 GrafPtr m_macPrintFormerPort ; 65 wxCoord m_maxX ; 66 wxCoord m_maxY ; 67 OSStatus m_err ; 68} ; 69 70wxMacCarbonPrinterDC::wxMacCarbonPrinterDC( wxPrintData* data ) 71{ 72 ::GetPort( & m_macPrintFormerPort ) ; 73 74 m_err = noErr ; 75 wxMacCarbonPrintData *native = (wxMacCarbonPrintData*) data->m_nativePrintData ; 76 77 PMRect rPage; 78 m_err = PMGetAdjustedPageRect(native->m_macPageFormat, &rPage); 79 if ( m_err != noErr ) 80 return; 81 82 m_maxX = wxCoord(rPage.right - rPage.left) ; 83 m_maxY = wxCoord(rPage.bottom - rPage.top); 84} 85 86wxMacCarbonPrinterDC::~wxMacCarbonPrinterDC() 87{ 88 // nothing to release from print data, as wxPrinterDC has all data in its wxPrintData member 89 ::SetPort( m_macPrintFormerPort ) ; 90} 91 92wxNativePrinterDC* wxNativePrinterDC::Create(wxPrintData* data) 93{ 94 return new wxMacCarbonPrinterDC(data) ; 95} 96 97bool wxMacCarbonPrinterDC::StartDoc( wxPrinterDC* dc , const wxString& WXUNUSED(message) ) 98{ 99 if ( m_err ) 100 return false ; 101 102 wxMacCarbonPrintData *native = (wxMacCarbonPrintData*) dc->GetPrintData().m_nativePrintData ; 103 104 m_err = PMSessionBeginDocument(native->m_macPrintSession, 105 native->m_macPrintSettings, 106 native->m_macPageFormat); 107 if ( m_err != noErr ) 108 return false; 109 110 PMRect rPage; 111 m_err = PMGetAdjustedPageRect(native->m_macPageFormat, &rPage); 112 if ( m_err != noErr ) 113 return false; 114 115 m_maxX = (wxCoord)(rPage.right - rPage.left); 116 m_maxY = (wxCoord)(rPage.bottom - rPage.top); 117 return true ; 118} 119 120void wxMacCarbonPrinterDC::EndDoc( wxPrinterDC* dc ) 121{ 122 if ( m_err ) 123 return ; 124 125 wxMacCarbonPrintData *native = (wxMacCarbonPrintData*) dc->GetPrintData().m_nativePrintData ; 126 127 m_err = PMSessionEndDocument(native->m_macPrintSession); 128} 129 130void wxMacCarbonPrinterDC::StartPage( wxPrinterDC* dc ) 131{ 132 if ( m_err ) 133 return ; 134 135 wxMacCarbonPrintData *native = (wxMacCarbonPrintData*) dc->GetPrintData().m_nativePrintData ; 136 137 m_err = PMSessionBeginPage(native->m_macPrintSession, 138 native->m_macPageFormat, 139 nil); 140 141 if ( m_err == noErr ) 142 { 143 m_err = PMSessionGetGraphicsContext(native->m_macPrintSession, 144 nil, 145 (void**) &dc->m_macPort ); 146 } 147 148 if ( m_err != noErr ) 149 { 150 PMSessionEndPage(native->m_macPrintSession); 151 PMSessionEndDocument(native->m_macPrintSession); 152 } 153 else 154 { 155 PMRect rPage; 156 157 m_err = PMGetAdjustedPageRect(native->m_macPageFormat, &rPage); 158 if ( !m_err ) 159 { 160 dc->m_macLocalOrigin.x = (int) rPage.left; 161 dc->m_macLocalOrigin.y = (int) rPage.top; 162 } 163 // since this is a non-critical error, we set the flag back 164 m_err = noErr ; 165 } 166} 167 168void wxMacCarbonPrinterDC::EndPage( wxPrinterDC* dc ) 169{ 170 if ( m_err ) 171 return ; 172 173 wxMacCarbonPrintData *native = (wxMacCarbonPrintData*) dc->GetPrintData().m_nativePrintData ; 174 175 m_err = PMSessionEndPage(native->m_macPrintSession); 176 if ( m_err != noErr ) 177 { 178 PMSessionEndDocument(native->m_macPrintSession); 179 } 180} 181 182#else 183 184class wxMacClassicPrinterDC : public wxNativePrinterDC 185{ 186public : 187 wxMacClassicPrinterDC( wxPrintData* data ) ; 188 virtual ~wxMacClassicPrinterDC() ; 189 virtual bool StartDoc( wxPrinterDC* dc , const wxString& message ) ; 190 virtual void EndDoc( wxPrinterDC* dc ) ; 191 virtual void StartPage( wxPrinterDC* dc ) ; 192 virtual void EndPage( wxPrinterDC* dc ) ; 193 virtual wxCoord GetMaxX() const { return m_maxX ; } 194 virtual wxCoord GetMaxY() const { return m_maxY ; } 195 virtual wxUint32 GetStatus() const { return m_err ; } 196private : 197 GrafPtr m_macPrintFormerPort ; 198 TPPrPort m_macPrintingPort ; 199 OSErr m_err ; 200 long m_maxX ; 201 long m_maxY ; 202} ; 203 204wxNativePrinterDC* wxNativePrinterDC::Create(wxPrintData* data) 205{ 206 return new wxMacClassicPrinterDC(data) ; 207} 208 209wxMacClassicPrinterDC::wxMacClassicPrinterDC(wxPrintData* data) 210{ 211 ::GetPort( &m_macPrintFormerPort ) ; 212 m_err = noErr ; 213 ::UMAPrOpen() ; 214 m_err = PrError() ; 215 if ( m_err != noErr ) 216 return; 217 218 wxMacClassicPrintData *native = (wxMacClassicPrintData*) data->m_nativePrintData ; 219 220 if ( ::PrValidate( native->m_macPrintSettings ) ) 221 { 222 // the driver has changed in the mean time, should we pop up a page setup dialog ? 223 if ( !::PrStlDialog( native->m_macPrintSettings ) ) 224 { 225 m_err = -1 ; 226 return; 227 } 228 } 229 m_err = PrError() ; 230 231 if ( m_err == noErr ) 232 { 233 m_maxX = (**native->m_macPrintSettings).prInfo.rPage.right - (**native->m_macPrintSettings).prInfo.rPage.left ; 234 m_maxY = (**native->m_macPrintSettings).prInfo.rPage.bottom - (**native->m_macPrintSettings).prInfo.rPage.top ; 235 } 236} 237 238wxMacClassicPrinterDC::~wxMacClassicPrinterDC() 239{ 240 ::UMAPrClose() ; 241 ::SetPort( LMGetWMgrPort() ) ; 242} 243 244bool wxMacClassicPrinterDC::StartDoc( wxPrinterDC* dc , const wxString& WXUNUSED(message) ) 245{ 246 if ( m_err ) 247 return false ; 248 249 wxMacClassicPrintData *native = (wxMacClassicPrintData*) dc->GetPrintData().m_nativePrintData ; 250 m_macPrintingPort = ::PrOpenDoc( native->m_macPrintSettings , NULL , NULL ) ; 251 m_err = PrError() ; 252 if ( m_err ) 253 return false ; 254 255 // sets current port 256 dc->m_macPort = (GrafPtr ) m_macPrintingPort ; 257 m_maxX = (**native->m_macPrintSettings).prInfo.rPage.right - (**native->m_macPrintSettings).prInfo.rPage.left ; 258 m_maxY = (**native->m_macPrintSettings).prInfo.rPage.bottom - (**native->m_macPrintSettings).prInfo.rPage.top ; 259 return true ; 260} 261 262void wxMacClassicPrinterDC::EndDoc( wxPrinterDC* dc ) 263{ 264 if ( m_err ) 265 return ; 266 267 PrCloseDoc( m_macPrintingPort ) ; 268 m_err = PrError() ; 269} 270 271void wxMacClassicPrinterDC::StartPage( wxPrinterDC* dc ) 272{ 273 if ( m_err ) 274 return ; 275 276 wxMacClassicPrintData *native = (wxMacClassicPrintData*) dc->GetPrintData().m_nativePrintData ; 277 278 PrOpenPage( m_macPrintingPort , NULL ) ; 279 dc->m_macLocalOrigin.x = (**native->m_macPrintSettings).rPaper.left ; 280 dc->m_macLocalOrigin.y = (**native->m_macPrintSettings).rPaper.top ; 281 // m_macPrintingPort is now the current port 282 Rect clip = { -32000 , -32000 , 32000 , 32000 } ; 283 ::ClipRect( &clip ) ; 284 m_err = PrError() ; 285 if ( m_err != noErr ) 286 ::PrCloseDoc( m_macPrintingPort ) ; 287} 288 289void wxMacClassicPrinterDC::EndPage( wxPrinterDC* dc ) 290{ 291 if ( m_err ) 292 return ; 293 294 PrClosePage( m_macPrintingPort ) ; 295 m_err = PrError() ; 296 if ( m_err != noErr ) 297 ::PrCloseDoc( m_macPrintingPort ) ; 298} 299 300#endif 301 302wxPrinterDC::wxPrinterDC(const wxPrintData& printdata) 303{ 304 m_ok = false ; 305 m_printData = printdata ; 306 m_printData.ConvertToNative() ; 307 m_nativePrinterDC = wxNativePrinterDC::Create( &m_printData ) ; 308 if ( m_nativePrinterDC ) 309 { 310 m_ok = m_nativePrinterDC->Ok() ; 311 312 if ( !m_ok ) 313 { 314 wxString message ; 315 message.Printf( wxT("Print Error %u"), m_nativePrinterDC->GetStatus() ) ; 316 wxMessageDialog dialog( NULL , message , wxEmptyString, wxICON_HAND | wxOK) ; 317 dialog.ShowModal(); 318 } 319 } 320} 321 322wxPrinterDC::~wxPrinterDC(void) 323{ 324 delete m_nativePrinterDC ; 325} 326 327bool wxPrinterDC::StartDoc( const wxString& message ) 328{ 329 wxASSERT_MSG( Ok() , wxT("Called wxPrinterDC::StartDoc from an invalid object") ) ; 330 331 if ( !m_ok ) 332 return false ; 333 334 if ( m_nativePrinterDC->StartDoc(this, message ) ) 335 { 336 // in case we have to do additional things when successful 337 } 338 m_ok = m_nativePrinterDC->Ok() ; 339 if ( !m_ok ) 340 { 341 wxString message ; 342 message.Printf( wxT("Print Error %u"), m_nativePrinterDC->GetStatus() ) ; 343 wxMessageDialog dialog( NULL , message , wxEmptyString, wxICON_HAND | wxOK) ; 344 dialog.ShowModal(); 345 } 346 347 return m_ok ; 348} 349 350void wxPrinterDC::EndDoc(void) 351{ 352 if ( !m_ok ) 353 return ; 354 355 m_nativePrinterDC->EndDoc( this ) ; 356 m_ok = m_nativePrinterDC->Ok() ; 357 358 if ( !m_ok ) 359 { 360 wxString message ; 361 message.Printf( wxT("Print Error %u"), m_nativePrinterDC->GetStatus() ) ; 362 wxMessageDialog dialog( NULL , message , wxEmptyString, wxICON_HAND | wxOK) ; 363 dialog.ShowModal(); 364 } 365} 366 367void wxPrinterDC::StartPage(void) 368{ 369 if ( !m_ok ) 370 return ; 371 372 m_logicalFunction = wxCOPY; 373 // m_textAlignment = wxALIGN_TOP_LEFT; 374 m_backgroundMode = wxTRANSPARENT; 375 376 m_textForegroundColour = *wxBLACK; 377 m_textBackgroundColour = *wxWHITE; 378 m_pen = *wxBLACK_PEN; 379 m_font = *wxNORMAL_FONT; 380 m_brush = *wxTRANSPARENT_BRUSH; 381 m_backgroundBrush = *wxWHITE_BRUSH; 382 383 m_macFontInstalled = false ; 384 m_macBrushInstalled = false ; 385 m_macPenInstalled = false ; 386 387 m_nativePrinterDC->StartPage(this) ; 388 m_ok = m_nativePrinterDC->Ok() ; 389 390} 391 392void wxPrinterDC::EndPage(void) 393{ 394 if ( !m_ok ) 395 return ; 396 397 m_nativePrinterDC->EndPage(this) ; 398 m_ok = m_nativePrinterDC->Ok() ; 399} 400 401wxRect wxPrinterDC::GetPaperRect() 402{ 403 wxMacCarbonPrintData *native = (wxMacCarbonPrintData*) m_printData.GetNativeData() ; 404 OSStatus err = noErr ; 405 PMRect rPaper; 406 err = PMGetAdjustedPaperRect(native->m_macPageFormat, &rPaper); 407 if ( err != noErr ) 408 return pageRect; 409 return wxRect(wxCoord(rPaper.left), wxCoord(rPaper.top), 410 wxCoord(rPaper.right - rPaper.left), wxCoord(rPaper.bottom - rPaper.top)); 411} 412 413void wxPrinterDC::DoGetSize(int *width, int *height) const 414{ 415 wxCHECK_RET( m_ok , _T("GetSize() doesn't work without a valid wxPrinterDC") ); 416 417 if ( width ) 418 * width = m_nativePrinterDC->GetMaxX() ; 419 if ( height ) 420 * height = m_nativePrinterDC->GetMaxY() ; 421} 422