1/////////////////////////////////////////////////////////////////////////////
2// Name:        src/mac/classic/dcprint.cpp
3// Purpose:     wxPrinterDC class
4// Author:      Julian Smart
5// Modified by:
6// Created:     01/02/97
7// RCS-ID:      $Id: dcprint.cpp 42522 2006-10-27 13:07:40Z JS $
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#ifdef __BORLANDC__
16    #pragma hdrstop
17#endif
18
19#include "wx/dcprint.h"
20
21#ifndef WX_PRECOMP
22    #include "wx/msgdlg.h"
23    #include "wx/math.h"
24#endif
25
26#include "wx/mac/uma.h"
27#include "wx/mac/private/print.h"
28
29IMPLEMENT_CLASS(wxPrinterDC, wxDC)
30
31class wxNativePrinterDC
32{
33public :
34    wxNativePrinterDC() {}
35    virtual ~wxNativePrinterDC() {}
36    virtual bool StartDoc(  wxPrinterDC* dc , const wxString& message ) = 0;
37    virtual void EndDoc( wxPrinterDC* dc ) = 0;
38    virtual void StartPage( wxPrinterDC* dc ) = 0;
39    virtual void EndPage( wxPrinterDC* dc ) = 0;
40    virtual wxCoord GetMaxX() const = 0 ;
41    virtual wxCoord GetMaxY() const = 0 ;
42    // returns 0 in case of no Error, otherwise platform specific error codes
43    virtual wxUint32 GetStatus() const = 0 ;
44    bool Ok() { return GetStatus() == 0 ; }
45
46    static wxNativePrinterDC* Create(wxPrintData* data) ;
47} ;
48
49#if TARGET_CARBON
50
51class wxMacCarbonPrinterDC : public wxNativePrinterDC
52{
53public :
54    wxMacCarbonPrinterDC( wxPrintData* data ) ;
55    virtual ~wxMacCarbonPrinterDC() ;
56    virtual bool StartDoc(  wxPrinterDC* dc , const wxString& message ) ;
57    virtual void EndDoc( wxPrinterDC* dc ) ;
58    virtual void StartPage( wxPrinterDC* dc ) ;
59    virtual void EndPage( wxPrinterDC* dc ) ;
60    virtual wxCoord GetMaxX() const { return m_maxX ; }
61    virtual wxCoord GetMaxY() const { return m_maxY ; }
62    virtual wxUint32 GetStatus() const { return m_err ; }
63private :
64    GrafPtr m_macPrintFormerPort ;
65    wxCoord m_maxX ;
66    wxCoord m_maxY ;
67    OSStatus m_err ;
68} ;
69
70wxMacCarbonPrinterDC::wxMacCarbonPrinterDC( wxPrintData* data )
71{
72    ::GetPort( & m_macPrintFormerPort ) ;
73
74    m_err = noErr ;
75    wxMacCarbonPrintData *native = (wxMacCarbonPrintData*) data->m_nativePrintData ;
76
77    PMRect rPage;
78    m_err = PMGetAdjustedPageRect(native->m_macPageFormat, &rPage);
79    if ( m_err != noErr )
80        return;
81
82    m_maxX = wxCoord(rPage.right - rPage.left) ;
83    m_maxY = wxCoord(rPage.bottom - rPage.top);
84}
85
86wxMacCarbonPrinterDC::~wxMacCarbonPrinterDC()
87{
88    // nothing to release from print data, as wxPrinterDC has all data in its wxPrintData member
89    ::SetPort( m_macPrintFormerPort ) ;
90}
91
92wxNativePrinterDC* wxNativePrinterDC::Create(wxPrintData* data)
93{
94    return new wxMacCarbonPrinterDC(data) ;
95}
96
97bool wxMacCarbonPrinterDC::StartDoc(  wxPrinterDC* dc , const wxString& WXUNUSED(message)  )
98{
99    if ( m_err )
100        return false ;
101
102    wxMacCarbonPrintData *native = (wxMacCarbonPrintData*) dc->GetPrintData().m_nativePrintData ;
103
104    m_err = PMSessionBeginDocument(native->m_macPrintSession,
105              native->m_macPrintSettings,
106              native->m_macPageFormat);
107    if ( m_err != noErr )
108        return false;
109
110    PMRect rPage;
111    m_err = PMGetAdjustedPageRect(native->m_macPageFormat, &rPage);
112    if ( m_err != noErr )
113        return false;
114
115    m_maxX = (wxCoord)(rPage.right - rPage.left);
116    m_maxY = (wxCoord)(rPage.bottom - rPage.top);
117    return true ;
118}
119
120void wxMacCarbonPrinterDC::EndDoc( wxPrinterDC* dc )
121{
122    if ( m_err )
123        return ;
124
125    wxMacCarbonPrintData *native = (wxMacCarbonPrintData*) dc->GetPrintData().m_nativePrintData ;
126
127    m_err = PMSessionEndDocument(native->m_macPrintSession);
128}
129
130void wxMacCarbonPrinterDC::StartPage( wxPrinterDC* dc )
131{
132    if ( m_err )
133        return ;
134
135    wxMacCarbonPrintData *native = (wxMacCarbonPrintData*) dc->GetPrintData().m_nativePrintData ;
136
137    m_err = PMSessionBeginPage(native->m_macPrintSession,
138                 native->m_macPageFormat,
139                 nil);
140
141    if ( m_err == noErr )
142    {
143        m_err = PMSessionGetGraphicsContext(native->m_macPrintSession,
144                                            nil,
145                                            (void**) &dc->m_macPort );
146    }
147
148    if ( m_err != noErr )
149    {
150        PMSessionEndPage(native->m_macPrintSession);
151        PMSessionEndDocument(native->m_macPrintSession);
152    }
153    else
154    {
155        PMRect rPage;
156
157        m_err = PMGetAdjustedPageRect(native->m_macPageFormat, &rPage);
158        if ( !m_err )
159        {
160            dc->m_macLocalOrigin.x = (int) rPage.left;
161            dc->m_macLocalOrigin.y = (int) rPage.top;
162        }
163        // since this is a non-critical error, we set the flag back
164        m_err = noErr ;
165    }
166}
167
168void wxMacCarbonPrinterDC::EndPage( wxPrinterDC* dc )
169{
170    if ( m_err )
171        return ;
172
173    wxMacCarbonPrintData *native = (wxMacCarbonPrintData*) dc->GetPrintData().m_nativePrintData ;
174
175    m_err = PMSessionEndPage(native->m_macPrintSession);
176    if ( m_err != noErr )
177    {
178        PMSessionEndDocument(native->m_macPrintSession);
179    }
180}
181
182#else
183
184class wxMacClassicPrinterDC : public wxNativePrinterDC
185{
186public :
187    wxMacClassicPrinterDC( wxPrintData* data ) ;
188    virtual ~wxMacClassicPrinterDC() ;
189    virtual bool StartDoc(  wxPrinterDC* dc , const wxString& message ) ;
190    virtual void EndDoc( wxPrinterDC* dc ) ;
191    virtual void StartPage( wxPrinterDC* dc ) ;
192    virtual void EndPage( wxPrinterDC* dc ) ;
193    virtual wxCoord GetMaxX() const { return m_maxX ; }
194    virtual wxCoord GetMaxY() const { return m_maxY ; }
195    virtual wxUint32 GetStatus() const { return m_err ; }
196private :
197    GrafPtr m_macPrintFormerPort ;
198    TPPrPort m_macPrintingPort ;
199    OSErr m_err ;
200    long m_maxX ;
201    long m_maxY ;
202} ;
203
204wxNativePrinterDC* wxNativePrinterDC::Create(wxPrintData* data)
205{
206    return new wxMacClassicPrinterDC(data) ;
207}
208
209wxMacClassicPrinterDC::wxMacClassicPrinterDC(wxPrintData* data)
210{
211    ::GetPort( &m_macPrintFormerPort ) ;
212    m_err = noErr ;
213    ::UMAPrOpen() ;
214    m_err = PrError() ;
215    if ( m_err != noErr )
216        return;
217
218    wxMacClassicPrintData *native = (wxMacClassicPrintData*) data->m_nativePrintData ;
219
220    if ( ::PrValidate( native->m_macPrintSettings ) )
221    {
222        // the driver has changed in the mean time, should we pop up a page setup dialog ?
223        if ( !::PrStlDialog( native->m_macPrintSettings ) )
224        {
225            m_err = -1 ;
226            return;
227        }
228    }
229    m_err = PrError() ;
230
231    if ( m_err == noErr )
232    {
233        m_maxX = (**native->m_macPrintSettings).prInfo.rPage.right - (**native->m_macPrintSettings).prInfo.rPage.left ;
234        m_maxY = (**native->m_macPrintSettings).prInfo.rPage.bottom - (**native->m_macPrintSettings).prInfo.rPage.top ;
235    }
236}
237
238wxMacClassicPrinterDC::~wxMacClassicPrinterDC()
239{
240    ::UMAPrClose() ;
241    ::SetPort( LMGetWMgrPort() ) ;
242}
243
244bool wxMacClassicPrinterDC::StartDoc(  wxPrinterDC* dc , const wxString& WXUNUSED(message)  )
245{
246    if ( m_err )
247        return false ;
248
249    wxMacClassicPrintData *native = (wxMacClassicPrintData*) dc->GetPrintData().m_nativePrintData ;
250    m_macPrintingPort = ::PrOpenDoc( native->m_macPrintSettings , NULL , NULL ) ;
251    m_err = PrError() ;
252    if ( m_err )
253        return false ;
254
255    // sets current port
256    dc->m_macPort = (GrafPtr ) m_macPrintingPort ;
257    m_maxX = (**native->m_macPrintSettings).prInfo.rPage.right - (**native->m_macPrintSettings).prInfo.rPage.left ;
258    m_maxY = (**native->m_macPrintSettings).prInfo.rPage.bottom - (**native->m_macPrintSettings).prInfo.rPage.top ;
259    return true ;
260}
261
262void wxMacClassicPrinterDC::EndDoc( wxPrinterDC* dc )
263{
264    if ( m_err )
265        return ;
266
267    PrCloseDoc( m_macPrintingPort ) ;
268    m_err = PrError() ;
269}
270
271void wxMacClassicPrinterDC::StartPage( wxPrinterDC* dc )
272{
273    if ( m_err )
274        return ;
275
276    wxMacClassicPrintData *native = (wxMacClassicPrintData*) dc->GetPrintData().m_nativePrintData ;
277
278    PrOpenPage( m_macPrintingPort , NULL ) ;
279    dc->m_macLocalOrigin.x =  (**native->m_macPrintSettings).rPaper.left ;
280    dc->m_macLocalOrigin.y =  (**native->m_macPrintSettings).rPaper.top ;
281    // m_macPrintingPort is now the current port
282    Rect clip = { -32000 , -32000 , 32000 , 32000 } ;
283    ::ClipRect( &clip ) ;
284    m_err = PrError() ;
285    if ( m_err != noErr )
286        ::PrCloseDoc( m_macPrintingPort ) ;
287}
288
289void wxMacClassicPrinterDC::EndPage( wxPrinterDC* dc )
290{
291    if ( m_err )
292        return ;
293
294    PrClosePage( m_macPrintingPort ) ;
295    m_err = PrError() ;
296    if ( m_err != noErr )
297        ::PrCloseDoc( m_macPrintingPort  ) ;
298}
299
300#endif
301
302wxPrinterDC::wxPrinterDC(const wxPrintData& printdata)
303{
304    m_ok = false ;
305    m_printData = printdata ;
306    m_printData.ConvertToNative() ;
307    m_nativePrinterDC = wxNativePrinterDC::Create( &m_printData ) ;
308    if ( m_nativePrinterDC )
309    {
310        m_ok = m_nativePrinterDC->Ok() ;
311
312        if ( !m_ok )
313        {
314            wxString message ;
315            message.Printf( wxT("Print Error %u"), m_nativePrinterDC->GetStatus() ) ;
316            wxMessageDialog dialog( NULL , message , wxEmptyString, wxICON_HAND | wxOK) ;
317            dialog.ShowModal();
318        }
319    }
320}
321
322wxPrinterDC::~wxPrinterDC(void)
323{
324    delete m_nativePrinterDC ;
325}
326
327bool wxPrinterDC::StartDoc( const wxString& message )
328{
329    wxASSERT_MSG( Ok() , wxT("Called wxPrinterDC::StartDoc from an invalid object") ) ;
330
331    if ( !m_ok )
332        return false ;
333
334    if ( m_nativePrinterDC->StartDoc(this, message ) )
335    {
336        // in case we have to do additional things when successful
337    }
338    m_ok = m_nativePrinterDC->Ok() ;
339    if ( !m_ok )
340    {
341        wxString message ;
342        message.Printf( wxT("Print Error %u"), m_nativePrinterDC->GetStatus() ) ;
343        wxMessageDialog dialog( NULL , message , wxEmptyString, wxICON_HAND | wxOK) ;
344        dialog.ShowModal();
345    }
346
347    return m_ok ;
348}
349
350void wxPrinterDC::EndDoc(void)
351{
352    if ( !m_ok )
353        return ;
354
355    m_nativePrinterDC->EndDoc( this ) ;
356    m_ok = m_nativePrinterDC->Ok() ;
357
358    if ( !m_ok )
359    {
360        wxString message ;
361        message.Printf( wxT("Print Error %u"), m_nativePrinterDC->GetStatus() ) ;
362        wxMessageDialog dialog( NULL , message , wxEmptyString, wxICON_HAND | wxOK) ;
363        dialog.ShowModal();
364    }
365}
366
367void wxPrinterDC::StartPage(void)
368{
369    if ( !m_ok )
370        return ;
371
372    m_logicalFunction = wxCOPY;
373    //  m_textAlignment = wxALIGN_TOP_LEFT;
374    m_backgroundMode = wxTRANSPARENT;
375
376    m_textForegroundColour = *wxBLACK;
377    m_textBackgroundColour = *wxWHITE;
378    m_pen = *wxBLACK_PEN;
379    m_font = *wxNORMAL_FONT;
380    m_brush = *wxTRANSPARENT_BRUSH;
381    m_backgroundBrush = *wxWHITE_BRUSH;
382
383    m_macFontInstalled = false ;
384    m_macBrushInstalled = false ;
385    m_macPenInstalled = false ;
386
387    m_nativePrinterDC->StartPage(this) ;
388    m_ok = m_nativePrinterDC->Ok() ;
389
390}
391
392void wxPrinterDC::EndPage(void)
393{
394    if ( !m_ok )
395        return ;
396
397    m_nativePrinterDC->EndPage(this) ;
398    m_ok = m_nativePrinterDC->Ok() ;
399}
400
401wxRect wxPrinterDC::GetPaperRect()
402{
403    wxMacCarbonPrintData *native = (wxMacCarbonPrintData*) m_printData.GetNativeData() ;
404    OSStatus err = noErr ;
405    PMRect rPaper;
406    err = PMGetAdjustedPaperRect(native->m_macPageFormat, &rPaper);
407    if ( err != noErr )
408        return pageRect;
409    return wxRect(wxCoord(rPaper.left), wxCoord(rPaper.top),
410        wxCoord(rPaper.right - rPaper.left), wxCoord(rPaper.bottom - rPaper.top));
411}
412
413void wxPrinterDC::DoGetSize(int *width, int *height) const
414{
415    wxCHECK_RET( m_ok , _T("GetSize() doesn't work without a valid wxPrinterDC") );
416
417    if ( width )
418        * width = m_nativePrinterDC->GetMaxX() ;
419    if ( height )
420        * height = m_nativePrinterDC->GetMaxY() ;
421}
422