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 #include "wx/wxprec.h"
25 #include "wx/metafile.h"
26 #include "wx/clipbrd.h"
27 #include "wx/mac/private.h"
32 IMPLEMENT_DYNAMIC_CLASS(wxMetafile
, wxObject
)
33 IMPLEMENT_ABSTRACT_CLASS(wxMetafileDC
, wxDC
)
35 class wxMetafileRefData
: public wxGDIRefData
37 friend class WXDLLEXPORT wxMetafile
;
46 #if wxMAC_USE_CORE_GRAPHICS
47 QDPictRef m_qdPictRef
;
51 extern bool wxClipboardIsOpen
;
55 // Currently, the only purpose for making a metafile
56 // is to put it on the clipboard.
58 wxMetafileRefData::wxMetafileRefData()
62 #if wxMAC_USE_CORE_GRAPHICS
67 wxMetafileRefData::~wxMetafileRefData()
71 KillPicture( (PicHandle
)m_metafile
);
74 #if wxMAC_USE_CORE_GRAPHICS
75 QDPictRelease( m_qdPictRef
);
81 wxMetaFile::wxMetaFile(const wxString
& file
)
83 m_refData
= new wxMetafileRefData
;
85 M_METAFILEDATA
->m_metafile
= 0;
86 wxASSERT_MSG( file
.empty(), wxT("no file based metafile support yet") );
89 if (!file
.IsNull() && (file
.Cmp("") == 0))
90 M_METAFILEDATA
->m_metafile
= (WXHANDLE
) GetMetaFile( file
);
94 wxMetaFile::~wxMetaFile()
98 bool wxMetaFile::Ok() const
100 return (M_METAFILEDATA
&& (M_METAFILEDATA
->m_metafile
!= 0));
103 WXHMETAFILE
wxMetaFile::GetHMETAFILE() const
105 return (WXHMETAFILE
) M_METAFILEDATA
->m_metafile
;
108 bool wxMetaFile::SetClipboard(int width
, int height
)
112 #if wxUSE_DRAG_AND_DROP
113 // TODO: to finish this port, we need the data obj first
117 bool alreadyOpen
= wxTheClipboard
->IsOpened();
120 wxTheClipboard
->Open();
121 wxTheClipboard
->Clear();
124 wxDataObject
*data
= new wxMetafileDataObject( *this );
125 success
= wxTheClipboard
->SetData( data
);
127 wxTheClipboard
->Close();
133 void wxMetafile::SetHMETAFILE(WXHMETAFILE mf
)
137 m_refData
= new wxMetafileRefData
;
139 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(
148 membuf
, data
, sz
, wxMacMemoryBufferReleaseProc
);
149 M_METAFILEDATA
->m_qdPictRef
= NULL
;
151 if ( provider
!= NULL
)
153 M_METAFILEDATA
->m_qdPictRef
= QDPictCreateWithProvider( provider
);
154 CGDataProviderRelease( provider
);
159 bool wxMetaFile::Play(wxDC
*dc
)
168 #if wxMAC_USE_CORE_GRAPHICS
169 QDPictRef cgPictRef
= M_METAFILEDATA
->m_qdPictRef
;
170 CGContextRef cg
= ((wxMacCGContext
*)(dc
->GetGraphicContext()))->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
);
179 PicHandle pict
= (PicHandle
) GetHMETAFILE();
180 wxMacPortSetter
helper( dc
);
181 DrawPicture( pict
, &(**pict
).picFrame
);
188 wxSize
wxMetaFile::GetSize() const
190 wxSize size
= wxDefaultSize
;
194 PicHandle pict
= (PicHandle
) GetHMETAFILE() ;
195 Rect
&r
= (**pict
).picFrame
;
196 size
.x
= r
.right
- r
.left
;
197 size
.y
= r
.bottom
- r
.top
;
203 // 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 , wxT("no arbitration of metafilesize supported") );
213 wxASSERT_MSG( filename
.empty() , wxT("no file based metafile support yet"));
215 m_metaFile
= new wxMetaFile( filename
);
217 #if wxMAC_USE_CORE_GRAPHICS
219 Rect r
= { 0, 0, height
, width
};
221 RectRgn( (RgnHandle
) m_macBoundaryClipRgn
, &r
);
222 CopyRgn( (RgnHandle
) m_macBoundaryClipRgn
, (RgnHandle
) m_macCurrentClipRgn
);
224 m_metaFile
->SetHMETAFILE( (WXHMETAFILE
) OpenPicture( &r
) );
225 ::GetPort( (GrafPtr
*) &m_macPort
);
230 SetMapMode( wxMM_TEXT
);
233 wxMetaFileDC::~wxMetaFileDC()
237 void wxMetaFileDC::DoGetSize(int *width
, int *height
) const
239 wxCHECK_RET( m_metaFile
, wxT("GetSize() doesn't work without a metafile") );
241 wxSize sz
= m_metaFile
->GetSize() ;
248 wxMetaFile
*wxMetaFileDC::Close()
256 size_t wxMetafileDataObject::GetDataSize() const
258 return GetHandleSize( (Handle
) (*((wxMetafile
*)&m_metafile
)).GetHMETAFILE() );
261 bool wxMetafileDataObject::GetDataHere(void *buf
) const
263 memcpy( buf
, (*(PicHandle
)(*((wxMetafile
*)&m_metafile
)).GetHMETAFILE()) ,
264 GetHandleSize( (Handle
) (*((wxMetafile
*)&m_metafile
)).GetHMETAFILE() ) );
269 bool wxMetafileDataObject::SetData(size_t len
, const void *buf
)
271 Handle handle
= NewHandle( len
);
272 SetHandleSize( handle
, len
);
273 memcpy( *handle
, buf
, len
);
274 m_metafile
.SetHMETAFILE( (WXHMETAFILE
) handle
);