]> git.saurik.com Git - wxWidgets.git/blob - src/mac/carbon/dcprint.cpp
new graphics context implementation
[wxWidgets.git] / src / mac / carbon / dcprint.cpp
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$
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
31 IMPLEMENT_CLASS(wxPrinterDC, wxDC)
32
33 class wxNativePrinterDC
34 {
35 public :
36 wxNativePrinterDC() {}
37 virtual ~wxNativePrinterDC() {}
38 virtual bool StartDoc( wxPrinterDC* dc , const wxString& message ) = 0;
39 virtual void EndDoc( wxPrinterDC* dc ) = 0;
40 virtual void StartPage( wxPrinterDC* dc ) = 0;
41 virtual void EndPage( wxPrinterDC* dc ) = 0;
42 virtual void GetSize( int *w , int *h) const = 0 ;
43 virtual wxSize GetPPI() const = 0 ;
44
45 // returns 0 in case of no Error, otherwise platform specific error codes
46 virtual wxUint32 GetStatus() const = 0 ;
47 bool Ok() { return GetStatus() == 0 ; }
48
49 static wxNativePrinterDC* Create(wxPrintData* data) ;
50 } ;
51
52 class wxMacCarbonPrinterDC : public wxNativePrinterDC
53 {
54 public :
55 wxMacCarbonPrinterDC( wxPrintData* data ) ;
56 virtual ~wxMacCarbonPrinterDC() ;
57 virtual bool StartDoc( wxPrinterDC* dc , const wxString& message ) ;
58 virtual void EndDoc( wxPrinterDC* dc ) ;
59 virtual void StartPage( wxPrinterDC* dc ) ;
60 virtual void EndPage( wxPrinterDC* dc ) ;
61 virtual wxUint32 GetStatus() const { return m_err ; }
62 virtual void GetSize( int *w , int *h) const ;
63 virtual wxSize GetPPI() const ;
64 private :
65 #if !wxMAC_USE_CORE_GRAPHICS
66 GrafPtr m_macPrintFormerPort ;
67 #endif
68 wxCoord m_maxX ;
69 wxCoord m_maxY ;
70 wxSize m_ppi ;
71 OSStatus m_err ;
72 } ;
73
74 wxMacCarbonPrinterDC::wxMacCarbonPrinterDC( wxPrintData* data )
75 {
76 #if !wxMAC_USE_CORE_GRAPHICS
77 ::GetPort( & m_macPrintFormerPort ) ;
78 #endif
79 m_err = noErr ;
80 wxMacCarbonPrintData *native = (wxMacCarbonPrintData*) data->GetNativeData() ;
81
82 PMRect rPage;
83 m_err = PMGetAdjustedPageRect(native->m_macPageFormat, &rPage);
84 if ( m_err != noErr )
85 return;
86
87 m_maxX = wxCoord(rPage.right - rPage.left) ;
88 m_maxY = wxCoord(rPage.bottom - rPage.top);
89
90 PMResolution res;
91 #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
92 PMPrinter printer;
93 PMSessionGetCurrentPrinter(native->m_macPrintSession, &printer);
94 PMPrinterGetOutputResolution( printer, native->m_macPrintSettings, &res) ;
95 #else
96 m_err = PMGetResolution((PMPageFormat) (native->m_macPageFormat), &res);
97 #endif
98 m_ppi = wxSize(int(res.hRes), int(res.vRes));
99 }
100
101 wxMacCarbonPrinterDC::~wxMacCarbonPrinterDC()
102 {
103 #if !wxMAC_USE_CORE_GRAPHICS
104 // nothing to release from print data, as wxPrinterDC has all data in its wxPrintData member
105 ::SetPort( m_macPrintFormerPort ) ;
106 #endif
107 }
108
109 wxNativePrinterDC* wxNativePrinterDC::Create(wxPrintData* data)
110 {
111 return new wxMacCarbonPrinterDC(data) ;
112 }
113
114 bool wxMacCarbonPrinterDC::StartDoc( wxPrinterDC* dc , const wxString& WXUNUSED(message) )
115 {
116 if ( m_err )
117 return false ;
118
119 wxMacCarbonPrintData *native = (wxMacCarbonPrintData*) dc->GetPrintData().GetNativeData() ;
120
121 #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_4 && wxMAC_USE_CORE_GRAPHICS
122 {
123 CFStringRef s[1] = { kPMGraphicsContextCoreGraphics };
124 CFArrayRef graphicsContextsArray = CFArrayCreate(NULL, (const void**)s, 1, &kCFTypeArrayCallBacks);
125 PMSessionSetDocumentFormatGeneration(native->m_macPrintSession, kPMDocumentFormatPDF, graphicsContextsArray, NULL);
126 CFRelease(graphicsContextsArray);
127 }
128 #endif
129 #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_4 && wxMAC_USE_CORE_GRAPHICS
130 m_err = PMSessionBeginCGDocument(native->m_macPrintSession,
131 native->m_macPrintSettings,
132 native->m_macPageFormat);
133 #else
134 m_err = PMSessionBeginDocument(native->m_macPrintSession,
135 native->m_macPrintSettings,
136 native->m_macPageFormat);
137
138 #endif
139
140 if ( m_err != noErr )
141 return false;
142
143 PMRect rPage;
144 m_err = PMGetAdjustedPageRect(native->m_macPageFormat, &rPage);
145 if ( m_err != noErr )
146 return false ;
147
148 m_maxX = wxCoord(rPage.right - rPage.left) ;
149 m_maxY = wxCoord(rPage.bottom - rPage.top);
150
151 PMResolution res;
152 #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
153 PMPrinter printer;
154 PMSessionGetCurrentPrinter(native->m_macPrintSession, &printer);
155 PMPrinterGetOutputResolution( printer, native->m_macPrintSettings, &res) ;
156 #else
157 m_err = PMGetResolution((PMPageFormat) (native->m_macPageFormat), &res);
158 #endif
159 m_ppi = wxSize(int(res.hRes), int(res.vRes));
160 return true ;
161 }
162
163 void wxMacCarbonPrinterDC::EndDoc( wxPrinterDC* dc )
164 {
165 if ( m_err )
166 return ;
167
168 wxMacCarbonPrintData *native = (wxMacCarbonPrintData*) dc->GetPrintData().GetNativeData() ;
169
170 m_err = PMSessionEndDocument(native->m_macPrintSession);
171 }
172
173 void wxMacCarbonPrinterDC::StartPage( wxPrinterDC* dc )
174 {
175 if ( m_err )
176 return ;
177
178 wxMacCarbonPrintData *native = (wxMacCarbonPrintData*) dc->GetPrintData().GetNativeData() ;
179
180 m_err = PMSessionBeginPage(native->m_macPrintSession,
181 native->m_macPageFormat,
182 nil);
183
184 #if wxMAC_USE_CORE_GRAPHICS
185 CGContextRef pageContext;
186 #endif
187 if ( m_err == noErr )
188 {
189 #if wxMAC_USE_CORE_GRAPHICS
190 #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_4
191 m_err = PMSessionGetCGGraphicsContext(native->m_macPrintSession,
192 &pageContext );
193
194 #else
195 m_err = PMSessionGetGraphicsContext(native->m_macPrintSession,
196 kPMGraphicsContextCoreGraphics,
197 (void**) &pageContext );
198 #endif
199 dc->MacSetCGContext(pageContext) ;
200 #else
201 m_err = PMSessionGetGraphicsContext(native->m_macPrintSession,
202 kPMGraphicsContextQuickdraw,
203 (void**) &dc->m_macPort );
204 #endif
205 }
206
207 if ( m_err != noErr )
208 {
209 PMSessionEndPage(native->m_macPrintSession);
210 PMSessionEndDocument(native->m_macPrintSession);
211 }
212 else
213 {
214 PMRect rPage;
215
216 m_err = PMGetAdjustedPageRect(native->m_macPageFormat, &rPage);
217 if ( !m_err )
218 {
219 #if wxMAC_USE_CORE_GRAPHICS
220 PMRect paperRect ;
221 PMGetAdjustedPaperRect( native->m_macPageFormat , &paperRect ) ;
222 CGContextTranslateCTM( pageContext , -paperRect.left , -paperRect.top + ( rPage.bottom - rPage.top ) ) ;
223 CGContextScaleCTM( pageContext , 1 , -1 ) ;
224 CGContextSaveGState( pageContext ) ;
225 #else
226 dc->m_macLocalOrigin.x = (int) rPage.left;
227 dc->m_macLocalOrigin.y = (int) rPage.top;
228 #endif
229 }
230 // since this is a non-critical error, we set the flag back
231 m_err = noErr ;
232 }
233 }
234
235 void wxMacCarbonPrinterDC::EndPage( wxPrinterDC* dc )
236 {
237 if ( m_err )
238 return ;
239
240 wxMacCarbonPrintData *native = (wxMacCarbonPrintData*) dc->GetPrintData().GetNativeData() ;
241
242 m_err = PMSessionEndPage(native->m_macPrintSession);
243 if ( m_err != noErr )
244 {
245 PMSessionEndDocument(native->m_macPrintSession);
246 }
247 }
248
249 void wxMacCarbonPrinterDC::GetSize( int *w , int *h) const
250 {
251 if ( w )
252 *w = m_maxX ;
253 if ( h )
254 *h = m_maxY ;
255 }
256
257 wxSize wxMacCarbonPrinterDC::GetPPI() const
258 {
259 return m_ppi ;
260 };
261
262 //
263 //
264 //
265
266 wxPrinterDC::wxPrinterDC(const wxPrintData& printdata)
267 {
268 m_ok = false ;
269 m_printData = printdata ;
270 m_printData.ConvertToNative() ;
271 m_nativePrinterDC = wxNativePrinterDC::Create( &m_printData ) ;
272 if ( m_nativePrinterDC )
273 {
274 m_ok = m_nativePrinterDC->Ok() ;
275 if ( !m_ok )
276 {
277 wxString message ;
278 message.Printf( wxT("Print Error %u"), m_nativePrinterDC->GetStatus() ) ;
279 wxMessageDialog dialog( NULL , message , wxEmptyString, wxICON_HAND | wxOK) ;
280 dialog.ShowModal();
281 }
282 else
283 {
284 wxSize sz = GetPPI();
285 m_mm_to_pix_x = mm2inches * sz.x;
286 m_mm_to_pix_y = mm2inches * sz.y;
287 }
288 #if wxMAC_USE_CORE_GRAPHICS
289 /*
290 // the cgContext will only be handed over page by page
291 m_graphicContext = new wxMacCGContext() ;
292 */
293 #endif
294 }
295 }
296
297 wxSize wxPrinterDC::GetPPI() const
298 {
299 return m_nativePrinterDC->GetPPI() ;
300 }
301
302 wxPrinterDC::~wxPrinterDC(void)
303 {
304 #if wxMAC_USE_CORE_GRAPHICS
305 /*
306 // this context was borrowed
307 ((wxMacCGContext*)(m_graphicContext))->SetNativeContext( NULL ) ;
308 */
309 #endif
310 delete m_nativePrinterDC ;
311 }
312
313 #if wxMAC_USE_CORE_GRAPHICS
314 void wxPrinterDC::MacSetCGContext( void * cg )
315 {
316 SetGraphicsContext( wxGraphicsContext::CreateFromNative( cg ) );
317 m_graphicContext->SetPen( m_pen ) ;
318 m_graphicContext->SetBrush( m_brush ) ;
319 }
320 #endif
321 bool wxPrinterDC::StartDoc( const wxString& message )
322 {
323 wxASSERT_MSG( Ok() , wxT("Called wxPrinterDC::StartDoc from an invalid object") ) ;
324
325 if ( !m_ok )
326 return false ;
327
328 if ( m_nativePrinterDC->StartDoc(this, 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
344 void wxPrinterDC::EndDoc(void)
345 {
346 if ( !m_ok )
347 return ;
348
349 m_nativePrinterDC->EndDoc( this ) ;
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
361 void wxPrinterDC::StartPage(void)
362 {
363 if ( !m_ok )
364 return ;
365
366 m_logicalFunction = wxCOPY;
367 // m_textAlignment = wxALIGN_TOP_LEFT;
368 m_backgroundMode = wxTRANSPARENT;
369
370 m_textForegroundColour = *wxBLACK;
371 m_textBackgroundColour = *wxWHITE;
372 m_pen = *wxBLACK_PEN;
373 m_font = *wxNORMAL_FONT;
374 m_brush = *wxTRANSPARENT_BRUSH;
375 m_backgroundBrush = *wxWHITE_BRUSH;
376 #if !wxMAC_USE_CORE_GRAPHICS
377 m_macFontInstalled = false ;
378 m_macBrushInstalled = false ;
379 m_macPenInstalled = false ;
380 #endif
381
382 m_nativePrinterDC->StartPage(this) ;
383 m_ok = m_nativePrinterDC->Ok() ;
384
385 }
386
387 void wxPrinterDC::EndPage(void)
388 {
389 if ( !m_ok )
390 return ;
391
392 m_nativePrinterDC->EndPage(this) ;
393 m_ok = m_nativePrinterDC->Ok() ;
394 }
395
396 void wxPrinterDC::DoGetSize(int *width, int *height) const
397 {
398 wxCHECK_RET( m_ok , _T("GetSize() doesn't work without a valid wxPrinterDC") );
399 m_nativePrinterDC->GetSize(width, height ) ;
400 }
401
402 #endif