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