]> git.saurik.com Git - wxWidgets.git/blob - src/mac/carbon/metafile.cpp
Move some things to wxBitmapBase to avoid much duplication.
[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
52 extern bool wxClipboardIsOpen;
53
54
55 wxMetafileRefData::wxMetafileRefData()
56 {
57 m_metafile = NULL;
58
59 #if wxMAC_USE_CORE_GRAPHICS
60 m_qdPictRef = NULL;
61 #endif
62 }
63
64 wxMetafileRefData::~wxMetafileRefData()
65 {
66 if (m_metafile)
67 {
68 KillPicture( (PicHandle)m_metafile );
69 m_metafile = NULL;
70
71 #if wxMAC_USE_CORE_GRAPHICS
72 QDPictRelease( m_qdPictRef );
73 m_qdPictRef = NULL;
74 #endif
75 }
76 }
77
78 wxMetaFile::wxMetaFile(const wxString& file)
79 {
80 m_refData = new wxMetafileRefData;
81
82 M_METAFILEDATA->m_metafile = NULL;
83 wxASSERT_MSG( file.empty(), wxT("no file-based metafile support yet") );
84
85 #if 0
86 if (!file.IsNull() && (file.Cmp("") == 0))
87 M_METAFILEDATA->m_metafile = (WXHANDLE) GetMetaFile( file );
88 #endif
89 }
90
91 wxMetaFile::~wxMetaFile()
92 {
93 }
94
95 bool wxMetaFile::Ok() const
96 {
97 return (M_METAFILEDATA && (M_METAFILEDATA->m_metafile != NULL));
98 }
99
100 WXHMETAFILE wxMetaFile::GetHMETAFILE() const
101 {
102 return (WXHMETAFILE) M_METAFILEDATA->m_metafile;
103 }
104
105 bool wxMetaFile::SetClipboard(int width, int height)
106 {
107 bool success = true;
108
109 #if wxUSE_DRAG_AND_DROP
110 // TODO: to finish this port, we need the data object first
111 if (m_refData == NULL)
112 return false;
113
114 bool alreadyOpen = wxTheClipboard->IsOpened();
115 if (!alreadyOpen)
116 {
117 wxTheClipboard->Open();
118 wxTheClipboard->Clear();
119 }
120
121 wxDataObject *data = new wxMetafileDataObject( *this );
122 success = wxTheClipboard->SetData( data );
123 if (!alreadyOpen)
124 wxTheClipboard->Close();
125 #endif
126
127 return success;
128 }
129
130 void wxMetafile::SetHMETAFILE(WXHMETAFILE mf)
131 {
132 UnRef();
133
134 m_refData = new wxMetafileRefData;
135
136 M_METAFILEDATA->m_metafile = (PicHandle)mf;
137
138 #if wxMAC_USE_CORE_GRAPHICS
139 size_t sz = GetHandleSize( (Handle) M_METAFILEDATA->m_metafile );
140 wxMemoryBuffer* membuf = new wxMemoryBuffer( sz );
141 void *data = membuf->GetWriteBuf( sz );
142
143 memcpy( data, *M_METAFILEDATA->m_metafile, sz );
144 membuf->UngetWriteBuf( sz );
145 CGDataProviderRef provider = CGDataProviderCreateWithData(
146 membuf, data, sz, wxMacMemoryBufferReleaseProc );
147 M_METAFILEDATA->m_qdPictRef = NULL;
148
149 if (provider != NULL)
150 {
151 M_METAFILEDATA->m_qdPictRef = QDPictCreateWithProvider( provider );
152 CGDataProviderRelease( provider );
153 }
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 QDPictRef cgPictRef = M_METAFILEDATA->m_qdPictRef;
168 CGContextRef cg = ((wxMacCGContext*)(dc->GetGraphicContext()))->GetNativeContext();
169 CGRect bounds = QDPictGetBounds( cgPictRef );
170
171 CGContextSaveGState( cg );
172 CGContextTranslateCTM( cg, 0, bounds.size.width );
173 CGContextScaleCTM( cg, 1, -1 );
174 QDPictDrawToCGContext( cg, bounds, cgPictRef );
175 CGContextRestoreGState( cg );
176 #else
177 PicHandle pict = (PicHandle)GetHMETAFILE();
178 wxMacPortSetter helper( dc );
179 Rect picFrame;
180 DrawPicture( pict, wxMacGetPictureBounds( pict, &picFrame ) );
181 #endif
182 }
183
184 return true;
185 }
186
187 wxSize wxMetaFile::GetSize() const
188 {
189 wxSize dataSize = wxDefaultSize;
190
191 if (Ok())
192 {
193 PicHandle pict = (PicHandle)GetHMETAFILE();
194 Rect r;
195 wxMacGetPictureBounds( pict, &r );
196 dataSize.x = r.right - r.left;
197 dataSize.y = r.bottom - r.top;
198 }
199
200 return dataSize;
201 }
202
203 // Metafile device context
204
205 // New constructor that takes origin and extent. If you use this, don't
206 // give origin/extent arguments to wxMakeMetaFilePlaceable.
207
208 wxMetaFileDC::wxMetaFileDC(
209 const wxString& filename,
210 int width, int height,
211 const wxString& WXUNUSED(description) )
212 {
213 wxASSERT_MSG( width <= 0 || height <= 0, wxT("no arbitration of metafile size supported") );
214 wxASSERT_MSG( filename.empty(), wxT("no file based metafile support yet"));
215
216 m_metaFile = new wxMetaFile( filename );
217
218 #if wxMAC_USE_CORE_GRAPHICS
219 #else
220 Rect r = { 0, 0, height, width };
221
222 RectRgn( (RgnHandle)m_macBoundaryClipRgn, &r );
223 CopyRgn( (RgnHandle)m_macBoundaryClipRgn, (RgnHandle)m_macCurrentClipRgn );
224
225 m_metaFile->SetHMETAFILE( (WXHMETAFILE)OpenPicture( &r ) );
226 ::GetPort( (GrafPtr*)&m_macPort );
227
228 m_ok = true;
229 #endif
230
231 SetMapMode( wxMM_TEXT );
232 }
233
234 wxMetaFileDC::~wxMetaFileDC()
235 {
236 }
237
238 void wxMetaFileDC::DoGetSize(int *width, int *height) const
239 {
240 wxCHECK_RET( m_metaFile, wxT("GetSize() doesn't work without a metafile") );
241
242 wxSize sz = m_metaFile->GetSize();
243 if (width)
244 (*width) = sz.x;
245 if (height)
246 (*height) = sz.y;
247 }
248
249 wxMetaFile *wxMetaFileDC::Close()
250 {
251 ClosePicture();
252
253 return m_metaFile;
254 }
255
256 #if wxUSE_DATAOBJ
257 size_t wxMetafileDataObject::GetDataSize() const
258 {
259 return GetHandleSize( (Handle) (*((wxMetafile*)&m_metafile)).GetHMETAFILE() );
260 }
261
262 bool wxMetafileDataObject::GetDataHere(void *buf) const
263 {
264 Handle pictH = (Handle)(*((wxMetafile*)&m_metafile)).GetHMETAFILE();
265 bool result = (pictH != NULL);
266
267 if (result)
268 memcpy( buf, *pictH, GetHandleSize( pictH ) );
269
270 return result;
271 }
272
273 bool wxMetafileDataObject::SetData(size_t len, const void *buf)
274 {
275 Handle handle = NewHandle( len );
276 SetHandleSize( handle, len );
277 memcpy( *handle, buf, len );
278 m_metafile.SetHMETAFILE( (WXHMETAFILE) handle );
279
280 return true;
281 }
282 #endif
283
284 #endif