1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxMetaFile, wxMetaFileDC etc. These classes are optional.
4 // Author: Stefan Csomor
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
13 #pragma implementation "metafile.h"
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
30 #include "wx/metafile.h"
31 #include "wx/clipbrd.h"
33 #include "wx/mac/private.h"
38 extern bool wxClipboardIsOpen
;
40 IMPLEMENT_DYNAMIC_CLASS(wxMetafile
, wxObject
)
41 IMPLEMENT_ABSTRACT_CLASS(wxMetafileDC
, wxDC
)
43 class wxMetafileRefData
: public wxGDIRefData
45 friend class WXDLLEXPORT wxMetafile
;
47 wxMetafileRefData(void);
48 ~wxMetafileRefData(void);
52 #if wxMAC_USE_CORE_GRAPHICS
53 QDPictRef m_qdPictRef
;
60 * Currently, the only purpose for making a metafile is to put
61 * it on the clipboard.
64 wxMetafileRefData::wxMetafileRefData(void)
67 #if wxMAC_USE_CORE_GRAPHICS
72 wxMetafileRefData::~wxMetafileRefData(void)
76 KillPicture( (PicHandle
) m_metafile
) ;
78 #if wxMAC_USE_CORE_GRAPHICS
79 QDPictRelease( m_qdPictRef
) ;
85 wxMetaFile::wxMetaFile(const wxString
& file
)
87 m_refData
= new wxMetafileRefData
;
89 M_METAFILEDATA
->m_metafile
= 0;
90 wxASSERT_MSG( file
.IsEmpty() , wxT("no file based metafile support yet") ) ;
92 if (!file.IsNull() && (file.Cmp("") == 0))
93 M_METAFILEDATA->m_metafile = (WXHANDLE) GetMetaFile(file);
97 wxMetaFile::~wxMetaFile()
101 bool wxMetaFile::Ok() const
103 return (M_METAFILEDATA
&& (M_METAFILEDATA
->m_metafile
!= 0));
106 WXHMETAFILE
wxMetaFile::GetHMETAFILE() const
108 return (WXHMETAFILE
) M_METAFILEDATA
->m_metafile
;
111 bool wxMetaFile::SetClipboard(int width
, int height
)
113 #if wxUSE_DRAG_AND_DROP
114 //TODO finishi this port , we need the data obj first
118 bool alreadyOpen
=wxTheClipboard
->IsOpened() ;
121 wxTheClipboard
->Open();
122 wxTheClipboard
->Clear();
125 new wxMetafileDataObject( *this) ;
126 bool success
= wxTheClipboard
->SetData(data
);
128 wxTheClipboard
->Close();
129 return (bool) success
;
134 void wxMetafile::SetHMETAFILE(WXHMETAFILE mf
)
138 m_refData
= new wxMetafileRefData
;
140 M_METAFILEDATA
->m_metafile
= (PicHandle
) mf
;
141 #if wxMAC_USE_CORE_GRAPHICS
142 size_t sz
= GetHandleSize( (Handle
) M_METAFILEDATA
->m_metafile
) ;
143 wxMemoryBuffer
* membuf
= new wxMemoryBuffer( sz
) ;
144 void * data
= membuf
->GetWriteBuf(sz
) ;
145 memcpy( data
, *M_METAFILEDATA
->m_metafile
, sz
) ;
146 membuf
->UngetWriteBuf(sz
) ;
147 CGDataProviderRef provider
= CGDataProviderCreateWithData( membuf
, data
, sz
,
148 wxMacMemoryBufferReleaseProc
) ;
149 M_METAFILEDATA
->m_qdPictRef
= NULL
;
150 if ( provider
!= NULL
)
152 M_METAFILEDATA
->m_qdPictRef
= QDPictCreateWithProvider( provider
) ;
153 CGDataProviderRelease( provider
) ;
158 bool wxMetaFile::Play(wxDC
*dc
)
167 #if wxMAC_USE_CORE_GRAPHICS
168 QDPictRef cgPictRef
= M_METAFILEDATA
->m_qdPictRef
;
169 CGContextRef cg
= ((wxMacCGContext
*)(dc
->GetGraphicContext()))->GetNativeContext() ;
170 CGRect bounds
= QDPictGetBounds( cgPictRef
) ;
172 CGContextSaveGState(cg
);
173 CGContextTranslateCTM(cg
, 0 , bounds
.size
.width
);
174 CGContextScaleCTM(cg
, 1, -1);
175 QDPictDrawToCGContext( cg
, bounds
, cgPictRef
) ;
176 CGContextRestoreGState( cg
) ;
178 PicHandle pict
= (PicHandle
) GetHMETAFILE() ;
179 wxMacPortSetter
helper( dc
) ;
180 DrawPicture( pict
, &(**pict
).picFrame
) ;
186 wxSize
wxMetaFile::GetSize() const
188 wxSize size
= wxDefaultSize
;
191 PicHandle pict
= (PicHandle
) GetHMETAFILE() ;
192 Rect
&r
= (**pict
).picFrame
;
193 size
.x
= r
.right
- r
.left
;
194 size
.y
= r
.bottom
- r
.top
;
201 * Metafile device context
205 // New constructor that takes origin and extent. If you use this, don't
206 // give origin/extent arguments to wxMakeMetaFilePlaceable.
208 wxMetaFileDC::wxMetaFileDC(const wxString
& filename
,
209 int width
, int height
,
210 const wxString
& WXUNUSED(description
) )
212 wxASSERT_MSG( width
== 0 || height
== 0 , _T("no arbitration of metafilesize supported") ) ;
213 wxASSERT_MSG( filename
.IsEmpty() , _T("no file based metafile support yet")) ;
215 m_metaFile
= new wxMetaFile(filename
) ;
216 #if wxMAC_USE_CORE_GRAPHICS
218 Rect r
={0,0,height
,width
} ;
220 RectRgn( (RgnHandle
) m_macBoundaryClipRgn
, &r
) ;
221 CopyRgn( (RgnHandle
) m_macBoundaryClipRgn
, (RgnHandle
) m_macCurrentClipRgn
) ;
223 m_metaFile
->SetHMETAFILE( (WXHMETAFILE
) OpenPicture( &r
) ) ;
224 ::GetPort( (GrafPtr
*) &m_macPort
) ;
227 SetMapMode(wxMM_TEXT
);
230 wxMetaFileDC::~wxMetaFileDC()
234 void wxMetaFileDC::DoGetSize(int *width
, int *height
) const
236 wxCHECK_RET( m_metaFile
, _T("GetSize() doesn't work without a metafile") );
238 wxSize sz
= m_metaFile
->GetSize() ;
239 if (width
) (*width
) = sz
.x
;
240 if (height
) (*height
) = sz
.y
;
243 wxMetaFile
*wxMetaFileDC::Close()
250 size_t wxMetafileDataObject::GetDataSize() const
252 return GetHandleSize( (Handle
) (*((wxMetafile
*)&m_metafile
)).GetHMETAFILE() ) ;
255 bool wxMetafileDataObject::GetDataHere(void *buf
) const
257 memcpy( buf
, (*(PicHandle
)(*((wxMetafile
*)&m_metafile
)).GetHMETAFILE()) ,
258 GetHandleSize( (Handle
) (*((wxMetafile
*)&m_metafile
)).GetHMETAFILE() ) ) ;
262 bool wxMetafileDataObject::SetData(size_t len
, const void *buf
)
264 Handle handle
= NewHandle( len
) ;
265 SetHandleSize( handle
, len
) ;
266 memcpy( *handle
, buf
, len
) ;
267 m_metafile
.SetHMETAFILE( (WXHMETAFILE
) handle
) ;