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