]> git.saurik.com Git - wxWidgets.git/blame - src/mac/carbon/dcprint.cpp
Performance optimization
[wxWidgets.git] / src / mac / carbon / dcprint.cpp
CommitLineData
72e7876b 1/////////////////////////////////////////////////////////////////////////////
6d50343d 2// Name: src/mac/carbon/dcprint.cpp
72e7876b
SC
3// Purpose: wxPrinterDC class
4// Author: Julian Smart
5// Modified by:
6// Created: 01/02/97
7// RCS-ID: $Id$
6aa89a22 8// Copyright: (c) Julian Smart
6d50343d 9// Licence: wxWindows licence
72e7876b
SC
10/////////////////////////////////////////////////////////////////////////////
11
72e7876b
SC
12// For compilers that support precompilation, includes "wx.h".
13#include "wx/wxprec.h"
14
179e085f
RN
15#if wxUSE_PRINTING_ARCHITECTURE
16
72e7876b 17#ifdef __BORLANDC__
6d50343d 18 #pragma hdrstop
72e7876b
SC
19#endif
20
6d50343d
WS
21#include "wx/dcprint.h"
22
72e7876b 23#ifndef WX_PRECOMP
246c5004 24 #include "wx/msgdlg.h"
18680f86 25 #include "wx/math.h"
72e7876b
SC
26#endif
27
2f1ae414 28#include "wx/mac/uma.h"
746d7582 29#include "wx/mac/private/print.h"
888dde65 30#include "wx/mac/carbon/dcprint.h"
8acd14d1 31#include "wx/graphics.h"
a3d3d3bf 32
888dde65 33IMPLEMENT_ABSTRACT_CLASS(wxPrinterDCImpl, wxGCDCImpl)
72e7876b 34
746d7582
SC
35class wxNativePrinterDC
36{
37public :
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;
db49000e
SC
44 virtual void GetSize( int *w , int *h) const = 0 ;
45 virtual wxSize GetPPI() const = 0 ;
46
746d7582
SC
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 ; }
eb7f8ac5 50
746d7582
SC
51 static wxNativePrinterDC* Create(wxPrintData* data) ;
52} ;
72e7876b 53
746d7582
SC
54class wxMacCarbonPrinterDC : public wxNativePrinterDC
55{
56public :
57 wxMacCarbonPrinterDC( wxPrintData* data ) ;
d3c7fc99 58 virtual ~wxMacCarbonPrinterDC() ;
746d7582
SC
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 ) ;
746d7582 63 virtual wxUint32 GetStatus() const { return m_err ; }
db49000e
SC
64 virtual void GetSize( int *w , int *h) const ;
65 virtual wxSize GetPPI() const ;
746d7582 66private :
746d7582
SC
67 wxCoord m_maxX ;
68 wxCoord m_maxY ;
db49000e 69 wxSize m_ppi ;
746d7582
SC
70 OSStatus m_err ;
71} ;
72
73wxMacCarbonPrinterDC::wxMacCarbonPrinterDC( wxPrintData* data )
72e7876b 74{
746d7582 75 m_err = noErr ;
dc7ccb9c 76 wxMacCarbonPrintData *native = (wxMacCarbonPrintData*) data->GetNativeData() ;
eb7f8ac5 77
746d7582
SC
78 PMRect rPage;
79 m_err = PMGetAdjustedPageRect(native->m_macPageFormat, &rPage);
80 if ( m_err != noErr )
81 return;
a689a4d0 82
746d7582
SC
83 m_maxX = wxCoord(rPage.right - rPage.left) ;
84 m_maxY = wxCoord(rPage.bottom - rPage.top);
db49000e
SC
85
86 PMResolution res;
c0f2dd1a
SC
87
88#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
89 if ( PMPrinterGetOutputResolution != NULL )
90 {
91 PMPrinter printer;
92 m_err = PMSessionGetCurrentPrinter(native->m_macPrintSession, &printer);
93 if ( m_err == noErr )
94 {
95 m_err = PMPrinterGetOutputResolution( printer, native->m_macPrintSettings, &res) ;
96 if ( m_err == -9589 /* kPMKeyNotFound */ )
97 {
98 m_err = noErr ;
99 res.hRes = res.vRes = 300;
100 }
101 }
102 }
103 else
4f74e0d1 104#endif
c0f2dd1a
SC
105 {
106#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
107 m_err = PMGetResolution((PMPageFormat) (native->m_macPageFormat), &res);
108#endif
109 }
110
f7862d3e 111 m_ppi = wxSize(int(res.hRes), int(res.vRes));
746d7582 112}
75411508 113
746d7582
SC
114wxMacCarbonPrinterDC::~wxMacCarbonPrinterDC()
115{
746d7582
SC
116}
117
118wxNativePrinterDC* wxNativePrinterDC::Create(wxPrintData* data)
119{
120 return new wxMacCarbonPrinterDC(data) ;
121}
122
eb7f8ac5 123bool wxMacCarbonPrinterDC::StartDoc( wxPrinterDC* dc , const wxString& WXUNUSED(message) )
746d7582
SC
124{
125 if ( m_err )
126 return false ;
127
888dde65
RR
128 wxPrinterDCImpl *impl = (wxPrinterDCImpl*) dc->GetImpl();
129 wxMacCarbonPrintData *native = (wxMacCarbonPrintData*) impl->GetPrintData().GetNativeData() ;
746d7582 130
3cd25cff 131 m_err = PMSessionBeginCGDocumentNoDialog(native->m_macPrintSession,
4f74e0d1 132 native->m_macPrintSettings,
3cd25cff 133 native->m_macPageFormat);
746d7582
SC
134 if ( m_err != noErr )
135 return false;
136
137 PMRect rPage;
138 m_err = PMGetAdjustedPageRect(native->m_macPageFormat, &rPage);
139 if ( m_err != noErr )
9fff7273 140 return false ;
db49000e
SC
141
142 m_maxX = wxCoord(rPage.right - rPage.left) ;
143 m_maxY = wxCoord(rPage.bottom - rPage.top);
746d7582 144
db49000e 145 PMResolution res;
3cd25cff
SC
146#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
147 if ( PMPrinterGetOutputResolution != NULL )
148 {
149 PMPrinter printer;
150 m_err = PMSessionGetCurrentPrinter(native->m_macPrintSession, &printer);
151 if ( m_err == noErr )
c0f2dd1a 152 {
3cd25cff 153 m_err = PMPrinterGetOutputResolution( printer, native->m_macPrintSettings, &res) ;
c0f2dd1a
SC
154 if ( m_err == -9589 /* kPMKeyNotFound */ )
155 {
156 m_err = noErr ;
157 res.hRes = res.vRes = 300;
158 }
159 }
3cd25cff
SC
160 }
161 else
4f74e0d1 162#endif
3cd25cff
SC
163 {
164#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
165 m_err = PMGetResolution((PMPageFormat) (native->m_macPageFormat), &res);
166#endif
167 }
168
db49000e 169 m_ppi = wxSize(int(res.hRes), int(res.vRes));
746d7582
SC
170 return true ;
171}
172
eb7f8ac5 173void wxMacCarbonPrinterDC::EndDoc( wxPrinterDC* dc )
746d7582
SC
174{
175 if ( m_err )
176 return ;
177
888dde65
RR
178 wxPrinterDCImpl *impl = (wxPrinterDCImpl*) dc->GetImpl();
179 wxMacCarbonPrintData *native = (wxMacCarbonPrintData*) impl->GetPrintData().GetNativeData() ;
746d7582 180
3cd25cff 181 m_err = PMSessionEndDocumentNoDialog(native->m_macPrintSession);
746d7582
SC
182}
183
eb7f8ac5 184void wxMacCarbonPrinterDC::StartPage( wxPrinterDC* dc )
746d7582
SC
185{
186 if ( m_err )
187 return ;
188
888dde65
RR
189 wxPrinterDCImpl *impl = (wxPrinterDCImpl*) dc->GetImpl();
190 wxMacCarbonPrintData *native = (wxMacCarbonPrintData*) impl->GetPrintData().GetNativeData() ;
746d7582 191
3cd25cff 192 m_err = PMSessionBeginPageNoDialog(native->m_macPrintSession,
746d7582
SC
193 native->m_macPageFormat,
194 nil);
eb7f8ac5 195
20b69855 196 CGContextRef pageContext;
e1673e52 197
746d7582 198 if ( m_err == noErr )
e40298d5 199 {
4f74e0d1
SC
200 m_err = PMSessionGetCGGraphicsContext(native->m_macPrintSession,
201 &pageContext );
e40298d5 202 }
eb7f8ac5 203
746d7582 204 if ( m_err != noErr )
e40298d5 205 {
3cd25cff
SC
206 PMSessionEndPageNoDialog(native->m_macPrintSession);
207 PMSessionEndDocumentNoDialog(native->m_macPrintSession);
e40298d5 208 }
746d7582 209 else
e40298d5 210 {
746d7582 211 PMRect rPage;
eb7f8ac5 212
746d7582
SC
213 m_err = PMGetAdjustedPageRect(native->m_macPageFormat, &rPage);
214 if ( !m_err )
215 {
a06e389f
SC
216 PMRect paperRect ;
217 PMGetAdjustedPaperRect( native->m_macPageFormat , &paperRect ) ;
3925a44c
SC
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 ) ;
20b69855 221 CGContextScaleCTM( pageContext , 1 , -1 ) ;
746d7582
SC
222 }
223 // since this is a non-critical error, we set the flag back
224 m_err = noErr ;
e40298d5 225 }
888dde65 226 impl->SetGraphicsContext( wxGraphicsContext::CreateFromNative( pageContext ) );
746d7582
SC
227}
228
eb7f8ac5 229void wxMacCarbonPrinterDC::EndPage( wxPrinterDC* dc )
746d7582
SC
230{
231 if ( m_err )
232 return ;
233
888dde65
RR
234 wxPrinterDCImpl *impl = (wxPrinterDCImpl*) dc->GetImpl();
235 wxMacCarbonPrintData *native = (wxMacCarbonPrintData*) impl->GetPrintData().GetNativeData() ;
746d7582 236
3cd25cff 237 m_err = PMSessionEndPageNoDialog(native->m_macPrintSession);
746d7582 238 if ( m_err != noErr )
f520d381 239 {
3cd25cff 240 PMSessionEndDocumentNoDialog(native->m_macPrintSession);
f520d381 241 }
ad667945 242 // the cg context we got when starting the page isn't valid anymore, so replace it
888dde65 243 impl->SetGraphicsContext( wxGraphicsContext::Create() );
746d7582
SC
244}
245
db49000e
SC
246void wxMacCarbonPrinterDC::GetSize( int *w , int *h) const
247{
248 if ( w )
249 *w = m_maxX ;
250 if ( h )
251 *h = m_maxY ;
252}
253
254wxSize wxMacCarbonPrinterDC::GetPPI() const
255{
256 return m_ppi ;
257};
258
259//
260//
261//
262
888dde65
RR
263wxPrinterDCImpl::wxPrinterDCImpl( wxPrinterDC *owner, const wxPrintData& printdata )
264 : wxGCDCImpl( owner )
746d7582 265{
6d50343d 266 m_ok = false ;
746d7582
SC
267 m_printData = printdata ;
268 m_printData.ConvertToNative() ;
269 m_nativePrinterDC = wxNativePrinterDC::Create( &m_printData ) ;
eb7f8ac5 270 if ( m_nativePrinterDC )
75411508 271 {
746d7582 272 m_ok = m_nativePrinterDC->Ok() ;
746d7582
SC
273 if ( !m_ok )
274 {
275 wxString message ;
eb7f8ac5 276 message.Printf( wxT("Print Error %u"), m_nativePrinterDC->GetStatus() ) ;
746d7582
SC
277 wxMessageDialog dialog( NULL , message , wxEmptyString, wxICON_HAND | wxOK) ;
278 dialog.ShowModal();
279 }
db49000e
SC
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 }
ad667945
SC
286 // we need at least a measuring context because people start measuring before a page
287 // gets printed at all
288 SetGraphicsContext( wxGraphicsContext::Create() );
75411508 289 }
746d7582
SC
290}
291
888dde65 292wxSize wxPrinterDCImpl::GetPPI() const
db49000e
SC
293{
294 return m_nativePrinterDC->GetPPI() ;
295}
296
888dde65 297wxPrinterDCImpl::~wxPrinterDCImpl()
746d7582
SC
298{
299 delete m_nativePrinterDC ;
300}
301
888dde65 302bool wxPrinterDCImpl::StartDoc( const wxString& message )
746d7582 303{
f896f240 304 wxASSERT_MSG( IsOk() , wxT("Called wxPrinterDC::StartDoc from an invalid object") ) ;
eb7f8ac5 305
746d7582
SC
306 if ( !m_ok )
307 return false ;
308
888dde65 309 if ( m_nativePrinterDC->StartDoc( (wxPrinterDC*) GetOwner(), message ) )
746d7582
SC
310 {
311 // in case we have to do additional things when successful
312 }
313 m_ok = m_nativePrinterDC->Ok() ;
314 if ( !m_ok )
75411508 315 {
746d7582 316 wxString message ;
eb7f8ac5 317 message.Printf( wxT("Print Error %u"), m_nativePrinterDC->GetStatus() ) ;
427ff662 318 wxMessageDialog dialog( NULL , message , wxEmptyString, wxICON_HAND | wxOK) ;
75411508 319 dialog.ShowModal();
75411508 320 }
746d7582 321
e40298d5 322 return m_ok ;
72e7876b
SC
323}
324
888dde65 325void wxPrinterDCImpl::EndDoc(void)
72e7876b 326{
746d7582
SC
327 if ( !m_ok )
328 return ;
329
888dde65 330 m_nativePrinterDC->EndDoc( (wxPrinterDC*) GetOwner() ) ;
746d7582
SC
331 m_ok = m_nativePrinterDC->Ok() ;
332
333 if ( !m_ok )
75411508 334 {
746d7582 335 wxString message ;
eb7f8ac5 336 message.Printf( wxT("Print Error %u"), m_nativePrinterDC->GetStatus() ) ;
746d7582
SC
337 wxMessageDialog dialog( NULL , message , wxEmptyString, wxICON_HAND | wxOK) ;
338 dialog.ShowModal();
75411508 339 }
72e7876b
SC
340}
341
888dde65 342wxRect wxPrinterDCImpl::GetPaperRect()
f415cab9
JS
343{
344 wxCoord w, h;
888dde65 345 GetOwner()->GetSize(&w, &h);
f415cab9
JS
346 wxRect pageRect(0, 0, w, h);
347 wxMacCarbonPrintData *native = (wxMacCarbonPrintData*) m_printData.GetNativeData() ;
348 OSStatus err = noErr ;
349 PMRect rPaper;
350 err = PMGetAdjustedPaperRect(native->m_macPageFormat, &rPaper);
351 if ( err != noErr )
352 return pageRect;
353 return wxRect(wxCoord(rPaper.left), wxCoord(rPaper.top),
354 wxCoord(rPaper.right - rPaper.left), wxCoord(rPaper.bottom - rPaper.top));
355}
356
888dde65 357void wxPrinterDCImpl::StartPage()
72e7876b 358{
e40298d5
JS
359 if ( !m_ok )
360 return ;
2f1ae414 361
746d7582
SC
362 m_logicalFunction = wxCOPY;
363 // m_textAlignment = wxALIGN_TOP_LEFT;
364 m_backgroundMode = wxTRANSPARENT;
365
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;
2f1ae414 372
888dde65 373 m_nativePrinterDC->StartPage( (wxPrinterDC*) GetOwner() ) ;
746d7582 374 m_ok = m_nativePrinterDC->Ok() ;
eb7f8ac5 375
72e7876b
SC
376}
377
888dde65 378void wxPrinterDCImpl::EndPage()
72e7876b 379{
e40298d5
JS
380 if ( !m_ok )
381 return ;
72e7876b 382
888dde65 383 m_nativePrinterDC->EndPage( (wxPrinterDC*) GetOwner() );
746d7582
SC
384 m_ok = m_nativePrinterDC->Ok() ;
385}
72e7876b 386
888dde65 387void wxPrinterDCImpl::DoGetSize(int *width, int *height) const
746d7582
SC
388{
389 wxCHECK_RET( m_ok , _T("GetSize() doesn't work without a valid wxPrinterDC") );
db49000e 390 m_nativePrinterDC->GetSize(width, height ) ;
72e7876b 391}
746d7582 392
179e085f 393#endif