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