1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/mac/carbon/metafile.cpp
3 // Purpose: wxMetaFile, wxMetaFileDC etc. These classes are optional.
4 // Author: Stefan Csomor
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // Currently, the only purpose for making a metafile
13 // is to put it on the clipboard.
16 #include "wx/wxprec.h"
25 #include "wx/metafile.h"
26 #include "wx/clipbrd.h"
27 #include "wx/mac/private.h"
28 #include "wx/graphics.h"
33 IMPLEMENT_DYNAMIC_CLASS(wxMetafile
, wxObject
)
34 IMPLEMENT_ABSTRACT_CLASS(wxMetafileDC
, wxDC
)
36 class wxMetafileRefData
: public wxGDIRefData
38 friend class WXDLLEXPORT wxMetafile
;
42 virtual ~wxMetafileRefData();
47 #if wxMAC_USE_CORE_GRAPHICS
48 QDPictRef m_qdPictRef
;
52 wxMetafileRefData::wxMetafileRefData()
56 #if wxMAC_USE_CORE_GRAPHICS
61 wxMetafileRefData::~wxMetafileRefData()
66 KillPicture( (PicHandle
)m_metafile
);
69 #if wxMAC_USE_CORE_GRAPHICS
70 QDPictRelease( m_qdPictRef
);
77 wxMetaFile::wxMetaFile(const wxString
& file
)
79 m_refData
= new wxMetafileRefData
;
81 M_METAFILEDATA
->m_metafile
= NULL
;
82 wxASSERT_MSG( file
.empty(), wxT("no file-based metafile support yet") );
85 if (!file
.IsNull() && (file
.Cmp("") == 0))
86 M_METAFILEDATA
->m_metafile
= (WXHANDLE
) GetMetaFile( file
);
90 wxMetaFile::~wxMetaFile()
94 bool wxMetaFile::IsOk() const
96 return (M_METAFILEDATA
&& (M_METAFILEDATA
->m_metafile
!= NULL
));
99 WXHMETAFILE
wxMetaFile::GetHMETAFILE() const
101 return (WXHMETAFILE
) M_METAFILEDATA
->m_metafile
;
104 bool wxMetaFile::SetClipboard(int width
, int height
)
108 #if wxUSE_DRAG_AND_DROP
109 // TODO: to finish this port, we need the data object first
110 if (m_refData
== NULL
)
113 bool alreadyOpen
= wxTheClipboard
->IsOpened();
116 wxTheClipboard
->Open();
117 wxTheClipboard
->Clear();
120 wxDataObject
*data
= new wxMetafileDataObject( *this );
121 success
= wxTheClipboard
->SetData( data
);
123 wxTheClipboard
->Close();
129 void wxMetafile::SetHMETAFILE(WXHMETAFILE mf
)
133 m_refData
= new wxMetafileRefData
;
135 M_METAFILEDATA
->m_metafile
= (PicHandle
)mf
;
137 #if wxMAC_USE_CORE_GRAPHICS
138 size_t sz
= GetHandleSize( (Handle
) M_METAFILEDATA
->m_metafile
);
139 wxMemoryBuffer
* membuf
= new wxMemoryBuffer( sz
);
140 void *data
= membuf
->GetWriteBuf( sz
);
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
;
149 if (provider
!= NULL
)
151 M_METAFILEDATA
->m_qdPictRef
= QDPictCreateWithProvider( provider
);
152 CGDataProviderRelease( provider
);
158 bool wxMetaFile::Play(wxDC
*dc
)
167 #if wxMAC_USE_CORE_GRAPHICS
169 QDPictRef cgPictRef
= M_METAFILEDATA
->m_qdPictRef
;
170 CGContextRef cg
= (CGContextRef
) dc
->GetGraphicsContext()->GetNativeContext();
171 CGRect bounds
= QDPictGetBounds( cgPictRef
);
173 CGContextSaveGState( cg
);
174 CGContextTranslateCTM( cg
, 0, bounds
.size
.width
);
175 CGContextScaleCTM( cg
, 1, -1 );
176 QDPictDrawToCGContext( cg
, bounds
, cgPictRef
);
177 CGContextRestoreGState( cg
);
180 PicHandle pict
= (PicHandle
)GetHMETAFILE();
181 wxMacPortSetter
helper( dc
);
183 DrawPicture( pict
, wxMacGetPictureBounds( pict
, &picFrame
) );
190 wxSize
wxMetaFile::GetSize() const
192 wxSize dataSize
= wxDefaultSize
;
197 PicHandle pict
= (PicHandle
)GetHMETAFILE();
199 wxMacGetPictureBounds( pict
, &r
);
200 dataSize
.x
= r
.right
- r
.left
;
201 dataSize
.y
= r
.bottom
- r
.top
;
208 // Metafile device context
210 // New constructor that takes origin and extent. If you use this, don't
211 // give origin/extent arguments to wxMakeMetaFilePlaceable.
213 wxMetaFileDC::wxMetaFileDC(
214 const wxString
& filename
,
215 int width
, int height
,
216 const wxString
& WXUNUSED(description
) )
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"));
221 m_metaFile
= new wxMetaFile( filename
);
223 #if wxMAC_USE_CORE_GRAPHICS
225 Rect r
= { 0, 0, height
, width
};
227 RectRgn( (RgnHandle
)m_macBoundaryClipRgn
, &r
);
228 CopyRgn( (RgnHandle
)m_macBoundaryClipRgn
, (RgnHandle
)m_macCurrentClipRgn
);
230 m_metaFile
->SetHMETAFILE( (WXHMETAFILE
)OpenPicture( &r
) );
231 ::GetPort( (GrafPtr
*)&m_macPort
);
236 SetMapMode( wxMM_TEXT
);
239 wxMetaFileDC::~wxMetaFileDC()
243 void wxMetaFileDC::DoGetSize(int *width
, int *height
) const
245 wxCHECK_RET( m_metaFile
, wxT("GetSize() doesn't work without a metafile") );
247 wxSize sz
= m_metaFile
->GetSize();
254 wxMetaFile
*wxMetaFileDC::Close()
263 size_t wxMetafileDataObject::GetDataSize() const
265 return GetHandleSize( (Handle
) (*((wxMetafile
*)&m_metafile
)).GetHMETAFILE() );
268 bool wxMetafileDataObject::GetDataHere(void *buf
) const
270 Handle pictH
= (Handle
)(*((wxMetafile
*)&m_metafile
)).GetHMETAFILE();
271 bool result
= (pictH
!= NULL
);
274 memcpy( buf
, *pictH
, GetHandleSize( pictH
) );
279 bool wxMetafileDataObject::SetData(size_t len
, const void *buf
)
281 Handle handle
= NewHandle( len
);
282 SetHandleSize( handle
, len
);
283 memcpy( *handle
, buf
, len
);
284 m_metafile
.SetHMETAFILE( (WXHMETAFILE
) handle
);