]> git.saurik.com Git - wxWidgets.git/blob - src/mac/carbon/metafile.cpp
1ed5081a6b1eeb162f1468df2e2317e1a82ea95d
[wxWidgets.git] / src / mac / carbon / metafile.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/mac/carbon/metafile.cpp
3 // Purpose: wxMetaFile, wxMetaFileDC etc. These classes are optional.
4 // Author: Stefan Csomor
5 // Modified by:
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11 //
12 // Currently, the only purpose for making a metafile
13 // is to put it on the clipboard.
14
15
16 #include "wx/wxprec.h"
17
18 #if wxUSE_METAFILE
19
20 #ifndef WX_PRECOMP
21 #include "wx/utils.h"
22 #include "wx/app.h"
23 #endif
24
25 #include "wx/metafile.h"
26 #include "wx/clipbrd.h"
27 #include "wx/mac/private.h"
28
29 #include <stdio.h>
30 #include <string.h>
31
32 IMPLEMENT_DYNAMIC_CLASS(wxMetafile, wxObject)
33 IMPLEMENT_ABSTRACT_CLASS(wxMetafileDC, wxDC)
34
35 class wxMetafileRefData: public wxGDIRefData
36 {
37 friend class WXDLLEXPORT wxMetafile;
38
39 public:
40 wxMetafileRefData();
41 virtual ~wxMetafileRefData();
42
43 private:
44 PicHandle m_metafile;
45
46 #if wxMAC_USE_CORE_GRAPHICS
47 QDPictRef m_qdPictRef;
48 #endif
49 };
50
51 wxMetafileRefData::wxMetafileRefData()
52 {
53 m_metafile = NULL;
54
55 #if wxMAC_USE_CORE_GRAPHICS
56 m_qdPictRef = NULL;
57 #endif
58 }
59
60 wxMetafileRefData::~wxMetafileRefData()
61 {
62 if (m_metafile)
63 {
64 #ifndef __LP64__
65 KillPicture( (PicHandle)m_metafile );
66 m_metafile = NULL;
67
68 #if wxMAC_USE_CORE_GRAPHICS
69 QDPictRelease( m_qdPictRef );
70 m_qdPictRef = NULL;
71 #endif
72 #endif
73 }
74 }
75
76 wxMetaFile::wxMetaFile(const wxString& file)
77 {
78 m_refData = new wxMetafileRefData;
79
80 M_METAFILEDATA->m_metafile = NULL;
81 wxASSERT_MSG( file.empty(), wxT("no file-based metafile support yet") );
82
83 #if 0
84 if (!file.IsNull() && (file.Cmp("") == 0))
85 M_METAFILEDATA->m_metafile = (WXHANDLE) GetMetaFile( file );
86 #endif
87 }
88
89 wxMetaFile::~wxMetaFile()
90 {
91 }
92
93 bool wxMetaFile::IsOk() const
94 {
95 return (M_METAFILEDATA && (M_METAFILEDATA->m_metafile != NULL));
96 }
97
98 WXHMETAFILE wxMetaFile::GetHMETAFILE() const
99 {
100 return (WXHMETAFILE) M_METAFILEDATA->m_metafile;
101 }
102
103 bool wxMetaFile::SetClipboard(int width, int height)
104 {
105 bool success = true;
106
107 #if wxUSE_DRAG_AND_DROP
108 // TODO: to finish this port, we need the data object first
109 if (m_refData == NULL)
110 return false;
111
112 bool alreadyOpen = wxTheClipboard->IsOpened();
113 if (!alreadyOpen)
114 {
115 wxTheClipboard->Open();
116 wxTheClipboard->Clear();
117 }
118
119 wxDataObject *data = new wxMetafileDataObject( *this );
120 success = wxTheClipboard->SetData( data );
121 if (!alreadyOpen)
122 wxTheClipboard->Close();
123 #endif
124
125 return success;
126 }
127
128 void wxMetafile::SetHMETAFILE(WXHMETAFILE mf)
129 {
130 UnRef();
131
132 m_refData = new wxMetafileRefData;
133
134 M_METAFILEDATA->m_metafile = (PicHandle)mf;
135
136 #if wxMAC_USE_CORE_GRAPHICS
137 size_t sz = GetHandleSize( (Handle) M_METAFILEDATA->m_metafile );
138 wxMemoryBuffer* membuf = new wxMemoryBuffer( sz );
139 void *data = membuf->GetWriteBuf( sz );
140
141 memcpy( data, *M_METAFILEDATA->m_metafile, sz );
142 membuf->UngetWriteBuf( sz );
143 CGDataProviderRef provider = CGDataProviderCreateWithData(
144 membuf, data, sz, wxMacMemoryBufferReleaseProc );
145 M_METAFILEDATA->m_qdPictRef = NULL;
146
147 #ifndef __LP64__
148 if (provider != NULL)
149 {
150 M_METAFILEDATA->m_qdPictRef = QDPictCreateWithProvider( provider );
151 CGDataProviderRelease( provider );
152 }
153 #endif
154 #endif
155 }
156
157 bool wxMetaFile::Play(wxDC *dc)
158 {
159 if (!m_refData)
160 return false;
161
162 if (!dc->Ok())
163 return false;
164
165 {
166 #if wxMAC_USE_CORE_GRAPHICS
167 #ifndef __LP64__
168 QDPictRef cgPictRef = M_METAFILEDATA->m_qdPictRef;
169 CGContextRef cg = (CGContextRef) dc->GetGraphicContext()->GetNativeContext();
170 CGRect bounds = QDPictGetBounds( cgPictRef );
171
172 CGContextSaveGState( cg );
173 CGContextTranslateCTM( cg, 0, bounds.size.width );
174 CGContextScaleCTM( cg, 1, -1 );
175 QDPictDrawToCGContext( cg, bounds, cgPictRef );
176 CGContextRestoreGState( cg );
177 #endif
178 #else
179 PicHandle pict = (PicHandle)GetHMETAFILE();
180 wxMacPortSetter helper( dc );
181 Rect picFrame;
182 DrawPicture( pict, wxMacGetPictureBounds( pict, &picFrame ) );
183 #endif
184 }
185
186 return true;
187 }
188
189 wxSize wxMetaFile::GetSize() const
190 {
191 wxSize dataSize = wxDefaultSize;
192
193 if (Ok())
194 {
195 #ifndef __LP64__
196 PicHandle pict = (PicHandle)GetHMETAFILE();
197 Rect r;
198 wxMacGetPictureBounds( pict, &r );
199 dataSize.x = r.right - r.left;
200 dataSize.y = r.bottom - r.top;
201 #endif
202 }
203
204 return dataSize;
205 }
206
207 // Metafile device context
208
209 // New constructor that takes origin and extent. If you use this, don't
210 // give origin/extent arguments to wxMakeMetaFilePlaceable.
211
212 wxMetaFileDC::wxMetaFileDC(
213 const wxString& filename,
214 int width, int height,
215 const wxString& WXUNUSED(description) )
216 {
217 wxASSERT_MSG( width <= 0 || height <= 0, wxT("no arbitration of metafile size supported") );
218 wxASSERT_MSG( filename.empty(), wxT("no file based metafile support yet"));
219
220 m_metaFile = new wxMetaFile( filename );
221
222 #if wxMAC_USE_CORE_GRAPHICS
223 #else
224 Rect r = { 0, 0, height, width };
225
226 RectRgn( (RgnHandle)m_macBoundaryClipRgn, &r );
227 CopyRgn( (RgnHandle)m_macBoundaryClipRgn, (RgnHandle)m_macCurrentClipRgn );
228
229 m_metaFile->SetHMETAFILE( (WXHMETAFILE)OpenPicture( &r ) );
230 ::GetPort( (GrafPtr*)&m_macPort );
231
232 m_ok = true;
233 #endif
234
235 SetMapMode( wxMM_TEXT );
236 }
237
238 wxMetaFileDC::~wxMetaFileDC()
239 {
240 }
241
242 void wxMetaFileDC::DoGetSize(int *width, int *height) const
243 {
244 wxCHECK_RET( m_metaFile, wxT("GetSize() doesn't work without a metafile") );
245
246 wxSize sz = m_metaFile->GetSize();
247 if (width)
248 (*width) = sz.x;
249 if (height)
250 (*height) = sz.y;
251 }
252
253 wxMetaFile *wxMetaFileDC::Close()
254 {
255 #ifndef __LP64__
256 ClosePicture();
257 #endif
258 return m_metaFile;
259 }
260
261 #if wxUSE_DATAOBJ
262 size_t wxMetafileDataObject::GetDataSize() const
263 {
264 return GetHandleSize( (Handle) (*((wxMetafile*)&m_metafile)).GetHMETAFILE() );
265 }
266
267 bool wxMetafileDataObject::GetDataHere(void *buf) const
268 {
269 Handle pictH = (Handle)(*((wxMetafile*)&m_metafile)).GetHMETAFILE();
270 bool result = (pictH != NULL);
271
272 if (result)
273 memcpy( buf, *pictH, GetHandleSize( pictH ) );
274
275 return result;
276 }
277
278 bool wxMetafileDataObject::SetData(size_t len, const void *buf)
279 {
280 Handle handle = NewHandle( len );
281 SetHandleSize( handle, len );
282 memcpy( *handle, buf, len );
283 m_metafile.SetHMETAFILE( (WXHMETAFILE) handle );
284
285 return true;
286 }
287 #endif
288
289 #endif