]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/mac/carbon/metafile.cpp
first stab at the selection iterator
[wxWidgets.git] / src / mac / carbon / metafile.cpp
... / ...
CommitLineData
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
32IMPLEMENT_DYNAMIC_CLASS(wxMetafile, wxObject)
33IMPLEMENT_ABSTRACT_CLASS(wxMetafileDC, wxDC)
34
35class wxMetafileRefData: public wxGDIRefData
36{
37 friend class WXDLLEXPORT wxMetafile;
38
39public:
40 wxMetafileRefData();
41 virtual ~wxMetafileRefData();
42
43private:
44 PicHandle m_metafile;
45
46#if wxMAC_USE_CORE_GRAPHICS
47 QDPictRef m_qdPictRef;
48#endif
49};
50
51
52extern bool wxClipboardIsOpen;
53
54
55wxMetafileRefData::wxMetafileRefData()
56{
57 m_metafile = NULL;
58
59#if wxMAC_USE_CORE_GRAPHICS
60 m_qdPictRef = NULL;
61#endif
62}
63
64wxMetafileRefData::~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
78wxMetaFile::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
91wxMetaFile::~wxMetaFile()
92{
93}
94
95bool wxMetaFile::Ok() const
96{
97 return (M_METAFILEDATA && (M_METAFILEDATA->m_metafile != NULL));
98}
99
100WXHMETAFILE wxMetaFile::GetHMETAFILE() const
101{
102 return (WXHMETAFILE) M_METAFILEDATA->m_metafile;
103}
104
105bool 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
130void 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
157bool 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
187wxSize 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
208wxMetaFileDC::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
234wxMetaFileDC::~wxMetaFileDC()
235{
236}
237
238void 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
249wxMetaFile *wxMetaFileDC::Close()
250{
251 ClosePicture();
252
253 return m_metaFile;
254}
255
256#if wxUSE_DATAOBJ
257size_t wxMetafileDataObject::GetDataSize() const
258{
259 return GetHandleSize( (Handle) (*((wxMetafile*)&m_metafile)).GetHMETAFILE() );
260}
261
262bool 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
273bool 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