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