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