]> git.saurik.com Git - wxWidgets.git/blame - src/osx/carbon/dcprint.cpp
guaranteeing autorelease pools for overridden OnRun on OSX
[wxWidgets.git] / src / osx / carbon / dcprint.cpp
CommitLineData
489468fe 1/////////////////////////////////////////////////////////////////////////////
524c47aa 2// Name: src/osx/carbon/dcprint.cpp
489468fe
SC
3// Purpose: wxPrinterDC class
4// Author: Julian Smart
5// Modified by:
6// Created: 01/02/97
7// RCS-ID: $Id$
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
524c47aa 28#include "wx/osx/private.h"
1f0c8f31 29#include "wx/osx/private/print.h"
e158da36 30#include "wx/osx/dcprint.h"
489468fe
SC
31#include "wx/graphics.h"
32
33IMPLEMENT_ABSTRACT_CLASS(wxPrinterDCImpl, wxGCDCImpl)
34
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;
44 virtual void GetSize( int *w , int *h) const = 0 ;
45 virtual wxSize GetPPI() const = 0 ;
46
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 ; }
50
51 static wxNativePrinterDC* Create(wxPrintData* data) ;
52} ;
53
54class wxMacCarbonPrinterDC : public wxNativePrinterDC
55{
56public :
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 ;
66private :
67 wxCoord m_maxX ;
68 wxCoord m_maxY ;
69 wxSize m_ppi ;
70 OSStatus m_err ;
71} ;
72
73wxMacCarbonPrinterDC::wxMacCarbonPrinterDC( wxPrintData* data )
74{
75 m_err = noErr ;
c347101b 76 wxOSXPrintData *native = (wxOSXPrintData*) data->GetNativeData() ;
489468fe
SC
77
78 PMRect rPage;
c347101b 79 m_err = PMGetAdjustedPageRect(native->GetPageFormat(), &rPage);
489468fe
SC
80 if ( m_err != noErr )
81 return;
82
83 m_maxX = wxCoord(rPage.right - rPage.left) ;
84 m_maxY = wxCoord(rPage.bottom - rPage.top);
85
86 PMResolution res;
87
6d52ca53 88#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
489468fe
SC
89 if ( PMPrinterGetOutputResolution != NULL )
90 {
91 PMPrinter printer;
c347101b 92 m_err = PMSessionGetCurrentPrinter(native->GetPrintSession(), &printer);
489468fe
SC
93 if ( m_err == noErr )
94 {
c347101b 95 m_err = PMPrinterGetOutputResolution( printer, native->GetPrintSettings(), &res) ;
489468fe
SC
96 if ( m_err == -9589 /* kPMKeyNotFound */ )
97 {
98 m_err = noErr ;
99 res.hRes = res.vRes = 300;
100 }
101 }
102 }
103 else
104#endif
105 {
6d52ca53 106#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
c347101b 107 m_err = PMGetResolution((PMPageFormat) (native->GetPageFormat()), &res);
489468fe
SC
108#endif
109 }
6d52ca53 110
489468fe
SC
111 m_ppi = wxSize(int(res.hRes), int(res.vRes));
112}
113
114wxMacCarbonPrinterDC::~wxMacCarbonPrinterDC()
115{
116}
117
118wxNativePrinterDC* wxNativePrinterDC::Create(wxPrintData* data)
119{
120 return new wxMacCarbonPrinterDC(data) ;
121}
122
e9e767f1 123bool wxMacCarbonPrinterDC::StartDoc( wxPrinterDC* dc , const wxString& message )
489468fe
SC
124{
125 if ( m_err )
126 return false ;
127
128 wxPrinterDCImpl *impl = (wxPrinterDCImpl*) dc->GetImpl();
c347101b 129 wxOSXPrintData *native = (wxOSXPrintData*) impl->GetPrintData().GetNativeData() ;
489468fe 130
e9e767f1
RR
131#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
132 if ( PMPrintSettingsSetJobName != NULL )
c347101b 133 PMPrintSettingsSetJobName(native->GetPrintSettings(), wxCFStringRef(message));
e9e767f1
RR
134#endif
135
c347101b
SC
136 m_err = PMSessionBeginCGDocumentNoDialog(native->GetPrintSession(),
137 native->GetPrintSettings(),
138 native->GetPageFormat());
489468fe
SC
139 if ( m_err != noErr )
140 return false;
141
142 PMRect rPage;
c347101b 143 m_err = PMGetAdjustedPageRect(native->GetPageFormat(), &rPage);
489468fe
SC
144 if ( m_err != noErr )
145 return false ;
146
147 m_maxX = wxCoord(rPage.right - rPage.left) ;
148 m_maxY = wxCoord(rPage.bottom - rPage.top);
149
150 PMResolution res;
6d52ca53 151#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
489468fe
SC
152 if ( PMPrinterGetOutputResolution != NULL )
153 {
154 PMPrinter printer;
c347101b 155 m_err = PMSessionGetCurrentPrinter(native->GetPrintSession(), &printer);
489468fe
SC
156 if ( m_err == noErr )
157 {
c347101b 158 m_err = PMPrinterGetOutputResolution( printer, native->GetPrintSettings(), &res) ;
489468fe
SC
159 if ( m_err == -9589 /* kPMKeyNotFound */ )
160 {
161 m_err = noErr ;
162 res.hRes = res.vRes = 300;
163 }
164 }
165 }
166 else
167#endif
168 {
6d52ca53 169#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
c347101b 170 m_err = PMGetResolution((PMPageFormat) (native->GetPageFormat()), &res);
489468fe
SC
171#endif
172 }
173
174 m_ppi = wxSize(int(res.hRes), int(res.vRes));
175 return true ;
176}
177
178void wxMacCarbonPrinterDC::EndDoc( wxPrinterDC* dc )
179{
180 if ( m_err )
181 return ;
182
183 wxPrinterDCImpl *impl = (wxPrinterDCImpl*) dc->GetImpl();
c347101b 184 wxOSXPrintData *native = (wxOSXPrintData*) impl->GetPrintData().GetNativeData() ;
489468fe 185
c347101b 186 m_err = PMSessionEndDocumentNoDialog(native->GetPrintSession());
489468fe
SC
187}
188
189void wxMacCarbonPrinterDC::StartPage( wxPrinterDC* dc )
190{
191 if ( m_err )
192 return ;
193
194 wxPrinterDCImpl *impl = (wxPrinterDCImpl*) dc->GetImpl();
c347101b 195 wxOSXPrintData *native = (wxOSXPrintData*) impl->GetPrintData().GetNativeData() ;
489468fe 196
c347101b
SC
197 m_err = PMSessionBeginPageNoDialog(native->GetPrintSession(),
198 native->GetPageFormat(),
489468fe
SC
199 nil);
200
201 CGContextRef pageContext;
202
203 if ( m_err == noErr )
204 {
c347101b 205 m_err = PMSessionGetCGGraphicsContext(native->GetPrintSession(),
489468fe
SC
206 &pageContext );
207 }
208
209 if ( m_err != noErr )
210 {
c347101b
SC
211 PMSessionEndPageNoDialog(native->GetPrintSession());
212 PMSessionEndDocumentNoDialog(native->GetPrintSession());
489468fe
SC
213 }
214 else
215 {
216 PMRect rPage;
217
c347101b 218 m_err = PMGetAdjustedPageRect(native->GetPageFormat(), &rPage);
489468fe
SC
219 if ( !m_err )
220 {
221 PMRect paperRect ;
c347101b 222 PMGetAdjustedPaperRect( native->GetPageFormat() , &paperRect ) ;
489468fe
SC
223 // make sure (0,0) is at the upper left of the printable area (wx conventions)
224 // Core Graphics initially has the lower left of the paper as 0,0
225 CGContextTranslateCTM( pageContext , (CGFloat) -paperRect.left , (CGFloat) paperRect.bottom ) ;
226 CGContextScaleCTM( pageContext , 1 , -1 ) ;
227 }
228 // since this is a non-critical error, we set the flag back
229 m_err = noErr ;
230 }
231 impl->SetGraphicsContext( wxGraphicsContext::CreateFromNative( pageContext ) );
232}
233
234void wxMacCarbonPrinterDC::EndPage( wxPrinterDC* dc )
235{
236 if ( m_err )
237 return ;
238
239 wxPrinterDCImpl *impl = (wxPrinterDCImpl*) dc->GetImpl();
c347101b 240 wxOSXPrintData *native = (wxOSXPrintData*) impl->GetPrintData().GetNativeData() ;
489468fe 241
c347101b 242 m_err = PMSessionEndPageNoDialog(native->GetPrintSession());
489468fe
SC
243 if ( m_err != noErr )
244 {
c347101b 245 PMSessionEndDocumentNoDialog(native->GetPrintSession());
489468fe
SC
246 }
247 // the cg context we got when starting the page isn't valid anymore, so replace it
248 impl->SetGraphicsContext( wxGraphicsContext::Create() );
249}
250
251void wxMacCarbonPrinterDC::GetSize( int *w , int *h) const
252{
253 if ( w )
254 *w = m_maxX ;
255 if ( h )
256 *h = m_maxY ;
257}
258
6d52ca53 259wxSize wxMacCarbonPrinterDC::GetPPI() const
489468fe
SC
260{
261 return m_ppi ;
262};
263
264//
265//
266//
267
268wxPrinterDCImpl::wxPrinterDCImpl( wxPrinterDC *owner, const wxPrintData& printdata )
269 : wxGCDCImpl( owner )
270{
271 m_ok = false ;
272 m_printData = printdata ;
273 m_printData.ConvertToNative() ;
274 m_nativePrinterDC = wxNativePrinterDC::Create( &m_printData ) ;
275 if ( m_nativePrinterDC )
276 {
277 m_ok = m_nativePrinterDC->Ok() ;
278 if ( !m_ok )
279 {
280 wxString message ;
281 message.Printf( wxT("Print Error %u"), m_nativePrinterDC->GetStatus() ) ;
282 wxMessageDialog dialog( NULL , message , wxEmptyString, wxICON_HAND | wxOK) ;
283 dialog.ShowModal();
284 }
285 else
286 {
287 wxSize sz = GetPPI();
288 m_mm_to_pix_x = mm2inches * sz.x;
6d52ca53 289 m_mm_to_pix_y = mm2inches * sz.y;
489468fe
SC
290 }
291 // we need at least a measuring context because people start measuring before a page
292 // gets printed at all
293 SetGraphicsContext( wxGraphicsContext::Create() );
294 }
295}
296
297wxSize wxPrinterDCImpl::GetPPI() const
298{
299 return m_nativePrinterDC->GetPPI() ;
300}
301
302wxPrinterDCImpl::~wxPrinterDCImpl()
303{
304 delete m_nativePrinterDC ;
305}
306
307bool wxPrinterDCImpl::StartDoc( const wxString& message )
308{
309 wxASSERT_MSG( IsOk() , wxT("Called wxPrinterDC::StartDoc from an invalid object") ) ;
310
311 if ( !m_ok )
312 return false ;
313
314 if ( m_nativePrinterDC->StartDoc( (wxPrinterDC*) GetOwner(), message ) )
315 {
316 // in case we have to do additional things when successful
317 }
318 m_ok = m_nativePrinterDC->Ok() ;
319 if ( !m_ok )
320 {
321 wxString message ;
322 message.Printf( wxT("Print Error %u"), m_nativePrinterDC->GetStatus() ) ;
323 wxMessageDialog dialog( NULL , message , wxEmptyString, wxICON_HAND | wxOK) ;
324 dialog.ShowModal();
325 }
326
327 return m_ok ;
328}
329
330void wxPrinterDCImpl::EndDoc(void)
331{
332 if ( !m_ok )
333 return ;
334
335 m_nativePrinterDC->EndDoc( (wxPrinterDC*) GetOwner() ) ;
336 m_ok = m_nativePrinterDC->Ok() ;
337
338 if ( !m_ok )
339 {
340 wxString message ;
341 message.Printf( wxT("Print Error %u"), m_nativePrinterDC->GetStatus() ) ;
342 wxMessageDialog dialog( NULL , message , wxEmptyString, wxICON_HAND | wxOK) ;
343 dialog.ShowModal();
344 }
345}
346
6d52ca53 347wxRect wxPrinterDCImpl::GetPaperRect() const
489468fe
SC
348{
349 wxCoord w, h;
350 GetOwner()->GetSize(&w, &h);
351 wxRect pageRect(0, 0, w, h);
c347101b 352 wxOSXPrintData *native = (wxOSXPrintData*) m_printData.GetNativeData() ;
489468fe
SC
353 OSStatus err = noErr ;
354 PMRect rPaper;
c347101b 355 err = PMGetAdjustedPaperRect(native->GetPageFormat(), &rPaper);
489468fe
SC
356 if ( err != noErr )
357 return pageRect;
358 return wxRect(wxCoord(rPaper.left), wxCoord(rPaper.top),
359 wxCoord(rPaper.right - rPaper.left), wxCoord(rPaper.bottom - rPaper.top));
360}
361
362void wxPrinterDCImpl::StartPage()
363{
364 if ( !m_ok )
365 return ;
366
367 m_logicalFunction = wxCOPY;
368 // m_textAlignment = wxALIGN_TOP_LEFT;
369 m_backgroundMode = wxTRANSPARENT;
370
371 m_textForegroundColour = *wxBLACK;
372 m_textBackgroundColour = *wxWHITE;
373 m_pen = *wxBLACK_PEN;
374 m_font = *wxNORMAL_FONT;
375 m_brush = *wxTRANSPARENT_BRUSH;
376 m_backgroundBrush = *wxWHITE_BRUSH;
377
378 m_nativePrinterDC->StartPage( (wxPrinterDC*) GetOwner() ) ;
379 m_ok = m_nativePrinterDC->Ok() ;
380
381}
382
383void wxPrinterDCImpl::EndPage()
384{
385 if ( !m_ok )
386 return ;
387
388 m_nativePrinterDC->EndPage( (wxPrinterDC*) GetOwner() );
389 m_ok = m_nativePrinterDC->Ok() ;
390}
391
392void wxPrinterDCImpl::DoGetSize(int *width, int *height) const
393{
394 wxCHECK_RET( m_ok , _T("GetSize() doesn't work without a valid wxPrinterDC") );
395 m_nativePrinterDC->GetSize(width, height ) ;
396}
397
398#endif