]> git.saurik.com Git - wxWidgets.git/blob - src/mac/carbon/dcprint.cpp
Fixup Blit so it can be used with a source that is a wxBufferedDC,
[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 GrafPtr m_macPrintFormerPort ;
66 wxCoord m_maxX ;
67 wxCoord m_maxY ;
68 wxSize m_ppi ;
69 OSStatus m_err ;
70 } ;
71
72 wxMacCarbonPrinterDC::wxMacCarbonPrinterDC( wxPrintData* data )
73 {
74 ::GetPort( & m_macPrintFormerPort ) ;
75
76 m_err = noErr ;
77 wxMacCarbonPrintData *native = (wxMacCarbonPrintData*) data->GetNativeData() ;
78
79 PMRect rPage;
80 m_err = PMGetAdjustedPageRect(native->m_macPageFormat, &rPage);
81 if ( m_err != noErr )
82 return;
83
84 m_maxX = wxCoord(rPage.right - rPage.left) ;
85 m_maxY = wxCoord(rPage.bottom - rPage.top);
86
87 PMResolution res;
88 m_err = PMGetResolution((PMPageFormat) (native->m_macPageFormat), &res);
89 m_ppi = wxSize(int(res.hRes), int(res.vRes));
90 }
91
92 wxMacCarbonPrinterDC::~wxMacCarbonPrinterDC()
93 {
94 // nothing to release from print data, as wxPrinterDC has all data in its wxPrintData member
95 ::SetPort( m_macPrintFormerPort ) ;
96 }
97
98 wxNativePrinterDC* wxNativePrinterDC::Create(wxPrintData* data)
99 {
100 return new wxMacCarbonPrinterDC(data) ;
101 }
102
103 bool wxMacCarbonPrinterDC::StartDoc( wxPrinterDC* dc , const wxString& WXUNUSED(message) )
104 {
105 if ( m_err )
106 return false ;
107
108 wxMacCarbonPrintData *native = (wxMacCarbonPrintData*) dc->GetPrintData().GetNativeData() ;
109
110 #if wxMAC_USE_CORE_GRAPHICS
111 {
112 CFStringRef s[1] = { kPMGraphicsContextCoreGraphics };
113 CFArrayRef graphicsContextsArray = CFArrayCreate(NULL, (const void**)s, 1, &kCFTypeArrayCallBacks);
114 PMSessionSetDocumentFormatGeneration(native->m_macPrintSession, kPMDocumentFormatPDF, graphicsContextsArray, NULL);
115 CFRelease(graphicsContextsArray);
116 }
117 #endif
118
119 m_err = PMSessionBeginDocument(native->m_macPrintSession,
120 native->m_macPrintSettings,
121 native->m_macPageFormat);
122 if ( m_err != noErr )
123 return false;
124
125 PMRect rPage;
126 m_err = PMGetAdjustedPageRect(native->m_macPageFormat, &rPage);
127 if ( m_err != noErr )
128 return false ;
129
130 m_maxX = wxCoord(rPage.right - rPage.left) ;
131 m_maxY = wxCoord(rPage.bottom - rPage.top);
132
133 PMResolution res;
134 m_err = PMGetResolution((PMPageFormat) (native->m_macPageFormat), &res);
135 m_ppi = wxSize(int(res.hRes), int(res.vRes));
136 return true ;
137 }
138
139 void wxMacCarbonPrinterDC::EndDoc( wxPrinterDC* dc )
140 {
141 if ( m_err )
142 return ;
143
144 wxMacCarbonPrintData *native = (wxMacCarbonPrintData*) dc->GetPrintData().GetNativeData() ;
145
146 m_err = PMSessionEndDocument(native->m_macPrintSession);
147 }
148
149 void wxMacCarbonPrinterDC::StartPage( wxPrinterDC* dc )
150 {
151 if ( m_err )
152 return ;
153
154 wxMacCarbonPrintData *native = (wxMacCarbonPrintData*) dc->GetPrintData().GetNativeData() ;
155
156 m_err = PMSessionBeginPage(native->m_macPrintSession,
157 native->m_macPageFormat,
158 nil);
159
160 #if wxMAC_USE_CORE_GRAPHICS
161 CGContextRef pageContext;
162 #endif
163 if ( m_err == noErr )
164 {
165 #if wxMAC_USE_CORE_GRAPHICS
166 m_err = PMSessionGetGraphicsContext(native->m_macPrintSession,
167 kPMGraphicsContextCoreGraphics,
168 (void**) &pageContext );
169 dc->MacSetCGContext(pageContext) ;
170 #else
171 m_err = PMSessionGetGraphicsContext(native->m_macPrintSession,
172 kPMGraphicsContextQuickdraw,
173 (void**) &dc->m_macPort );
174 #endif
175 }
176
177 if ( m_err != noErr )
178 {
179 PMSessionEndPage(native->m_macPrintSession);
180 PMSessionEndDocument(native->m_macPrintSession);
181 }
182 else
183 {
184 PMRect rPage;
185
186 m_err = PMGetAdjustedPageRect(native->m_macPageFormat, &rPage);
187 if ( !m_err )
188 {
189 #if wxMAC_USE_CORE_GRAPHICS
190 PMRect paperRect ;
191 PMGetAdjustedPaperRect( native->m_macPageFormat , &paperRect ) ;
192 CGContextTranslateCTM( pageContext , -paperRect.left , -paperRect.top + ( rPage.bottom - rPage.top ) ) ;
193 CGContextScaleCTM( pageContext , 1 , -1 ) ;
194 CGContextSaveGState( pageContext ) ;
195 #else
196 dc->m_macLocalOrigin.x = (int) rPage.left;
197 dc->m_macLocalOrigin.y = (int) rPage.top;
198 #endif
199 }
200 // since this is a non-critical error, we set the flag back
201 m_err = noErr ;
202 }
203 }
204
205 void wxMacCarbonPrinterDC::EndPage( wxPrinterDC* dc )
206 {
207 if ( m_err )
208 return ;
209
210 wxMacCarbonPrintData *native = (wxMacCarbonPrintData*) dc->GetPrintData().GetNativeData() ;
211
212 m_err = PMSessionEndPage(native->m_macPrintSession);
213 if ( m_err != noErr )
214 {
215 PMSessionEndDocument(native->m_macPrintSession);
216 }
217 }
218
219 void wxMacCarbonPrinterDC::GetSize( int *w , int *h) const
220 {
221 if ( w )
222 *w = m_maxX ;
223 if ( h )
224 *h = m_maxY ;
225 }
226
227 wxSize wxMacCarbonPrinterDC::GetPPI() const
228 {
229 return m_ppi ;
230 };
231
232 //
233 //
234 //
235
236 wxPrinterDC::wxPrinterDC(const wxPrintData& printdata)
237 {
238 m_ok = false ;
239 m_printData = printdata ;
240 m_printData.ConvertToNative() ;
241 m_nativePrinterDC = wxNativePrinterDC::Create( &m_printData ) ;
242 if ( m_nativePrinterDC )
243 {
244 m_ok = m_nativePrinterDC->Ok() ;
245 if ( !m_ok )
246 {
247 wxString message ;
248 message.Printf( wxT("Print Error %u"), m_nativePrinterDC->GetStatus() ) ;
249 wxMessageDialog dialog( NULL , message , wxEmptyString, wxICON_HAND | wxOK) ;
250 dialog.ShowModal();
251 }
252 else
253 {
254 wxSize sz = GetPPI();
255 m_mm_to_pix_x = mm2inches * sz.x;
256 m_mm_to_pix_y = mm2inches * sz.y;
257 }
258 #if wxMAC_USE_CORE_GRAPHICS
259 // the cgContext will only be handed over page by page
260 m_graphicContext = new wxMacCGContext() ;
261 #endif
262 }
263 }
264
265 wxSize wxPrinterDC::GetPPI() const
266 {
267 return m_nativePrinterDC->GetPPI() ;
268 }
269
270 wxPrinterDC::~wxPrinterDC(void)
271 {
272 #if wxMAC_USE_CORE_GRAPHICS
273 // this context was borrowed
274 ((wxMacCGContext*)(m_graphicContext))->SetNativeContext( NULL ) ;
275 #endif
276 delete m_nativePrinterDC ;
277 }
278
279 #if wxMAC_USE_CORE_GRAPHICS
280 void wxPrinterDC::MacSetCGContext( void * cg )
281 {
282 ((wxMacCGContext*)(m_graphicContext))->SetNativeContext( (CGContextRef) cg ) ;
283 m_graphicContext->SetPen( m_pen ) ;
284 m_graphicContext->SetBrush( m_brush ) ;
285 }
286 #endif
287 bool wxPrinterDC::StartDoc( const wxString& message )
288 {
289 wxASSERT_MSG( Ok() , wxT("Called wxPrinterDC::StartDoc from an invalid object") ) ;
290
291 if ( !m_ok )
292 return false ;
293
294 if ( m_nativePrinterDC->StartDoc(this, message ) )
295 {
296 // in case we have to do additional things when successful
297 }
298 m_ok = m_nativePrinterDC->Ok() ;
299 if ( !m_ok )
300 {
301 wxString message ;
302 message.Printf( wxT("Print Error %u"), m_nativePrinterDC->GetStatus() ) ;
303 wxMessageDialog dialog( NULL , message , wxEmptyString, wxICON_HAND | wxOK) ;
304 dialog.ShowModal();
305 }
306
307 return m_ok ;
308 }
309
310 void wxPrinterDC::EndDoc(void)
311 {
312 if ( !m_ok )
313 return ;
314
315 m_nativePrinterDC->EndDoc( this ) ;
316 m_ok = m_nativePrinterDC->Ok() ;
317
318 if ( !m_ok )
319 {
320 wxString message ;
321 message.Printf( wxT("Print Error %u"), m_nativePrinterDC->GetStatus() ) ;
322 wxMessageDialog dialog( NULL , message , wxEmptyString, wxICON_HAND | wxOK) ;
323 dialog.ShowModal();
324 }
325 }
326
327 void wxPrinterDC::StartPage(void)
328 {
329 if ( !m_ok )
330 return ;
331
332 m_logicalFunction = wxCOPY;
333 // m_textAlignment = wxALIGN_TOP_LEFT;
334 m_backgroundMode = wxTRANSPARENT;
335
336 m_textForegroundColour = *wxBLACK;
337 m_textBackgroundColour = *wxWHITE;
338 m_pen = *wxBLACK_PEN;
339 m_font = *wxNORMAL_FONT;
340 m_brush = *wxTRANSPARENT_BRUSH;
341 m_backgroundBrush = *wxWHITE_BRUSH;
342 #if !wxMAC_USE_CORE_GRAPHICS
343 m_macFontInstalled = false ;
344 m_macBrushInstalled = false ;
345 m_macPenInstalled = false ;
346 #endif
347
348 m_nativePrinterDC->StartPage(this) ;
349 m_ok = m_nativePrinterDC->Ok() ;
350
351 }
352
353 void wxPrinterDC::EndPage(void)
354 {
355 if ( !m_ok )
356 return ;
357
358 m_nativePrinterDC->EndPage(this) ;
359 m_ok = m_nativePrinterDC->Ok() ;
360 }
361
362 void wxPrinterDC::DoGetSize(int *width, int *height) const
363 {
364 wxCHECK_RET( m_ok , _T("GetSize() doesn't work without a valid wxPrinterDC") );
365 m_nativePrinterDC->GetSize(width, height ) ;
366 }
367
368 #endif