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 #if !USE_SHARED_LIBRARY 
  41 IMPLEMENT_DYNAMIC_CLASS(wxMetafile
, wxObject
) 
  42 IMPLEMENT_ABSTRACT_CLASS(wxMetafileDC
, wxDC
) 
  45 class wxMetafileRefData
: public wxGDIRefData
 
  47     friend class WXDLLEXPORT wxMetafile
; 
  49     wxMetafileRefData(void); 
  50     ~wxMetafileRefData(void); 
  54 #if wxMAC_USE_CORE_GRAPHICS 
  55     QDPictRef m_qdPictRef 
; 
  62  * Currently, the only purpose for making a metafile is to put 
  63  * it on the clipboard. 
  66 wxMetafileRefData::wxMetafileRefData(void) 
  69 #if wxMAC_USE_CORE_GRAPHICS 
  74 wxMetafileRefData::~wxMetafileRefData(void) 
  78         KillPicture( (PicHandle
) m_metafile 
) ; 
  80 #if wxMAC_USE_CORE_GRAPHICS 
  81         QDPictRelease( m_qdPictRef 
) ; 
  87 wxMetaFile::wxMetaFile(const wxString
& file
) 
  89     m_refData 
= new wxMetafileRefData
; 
  91     M_METAFILEDATA
->m_metafile 
= 0; 
  92     wxASSERT_MSG( file
.IsEmpty() , wxT("no file based metafile support yet") ) ; 
  94     if (!file.IsNull() && (file.Cmp("") == 0)) 
  95         M_METAFILEDATA->m_metafile = (WXHANDLE) GetMetaFile(file); 
  99 wxMetaFile::~wxMetaFile() 
 103 bool wxMetaFile::Ok() const  
 105     return (M_METAFILEDATA 
&& (M_METAFILEDATA
->m_metafile 
!= 0));  
 108 WXHMETAFILE 
wxMetaFile::GetHMETAFILE() const  
 110     return (WXHMETAFILE
) M_METAFILEDATA
->m_metafile
;  
 113 bool wxMetaFile::SetClipboard(int width
, int height
) 
 115 #if wxUSE_DRAG_AND_DROP 
 116     //TODO finishi this port , we need the data obj first 
 120     bool alreadyOpen
=wxTheClipboard
->IsOpened() ; 
 123         wxTheClipboard
->Open(); 
 124         wxTheClipboard
->Clear(); 
 127         new wxMetafileDataObject( *this) ; 
 128     bool success 
= wxTheClipboard
->SetData(data
); 
 130         wxTheClipboard
->Close(); 
 131     return (bool) success
; 
 136 void wxMetafile::SetHMETAFILE(WXHMETAFILE mf
) 
 140     m_refData 
= new wxMetafileRefData
; 
 142     M_METAFILEDATA
->m_metafile 
= (PicHandle
) mf
; 
 143 #if wxMAC_USE_CORE_GRAPHICS 
 144     size_t sz 
= GetHandleSize( (Handle
) M_METAFILEDATA
->m_metafile 
) ; 
 145     wxMemoryBuffer
* membuf 
= new wxMemoryBuffer( sz 
) ; 
 146     void * data 
= membuf
->GetWriteBuf(sz
) ; 
 147     memcpy( data 
, *M_METAFILEDATA
->m_metafile 
, sz 
) ; 
 148     membuf
->UngetWriteBuf(sz
) ; 
 149     CGDataProviderRef provider 
= CGDataProviderCreateWithData( membuf 
, data 
, sz 
, 
 150         wxMacMemoryBufferReleaseProc 
) ; 
 151     M_METAFILEDATA
->m_qdPictRef 
= NULL 
; 
 152     if ( provider 
!= NULL 
) 
 154         M_METAFILEDATA
->m_qdPictRef 
= QDPictCreateWithProvider( provider 
) ; 
 155         CGDataProviderRelease( provider 
) ; 
 160 bool wxMetaFile::Play(wxDC 
*dc
) 
 169 #if wxMAC_USE_CORE_GRAPHICS 
 170         QDPictRef cgPictRef 
= M_METAFILEDATA
->m_qdPictRef 
; 
 171         CGContextRef cg 
= ((wxMacCGContext
*)(dc
->GetGraphicContext()))->GetNativeContext() ; 
 172         CGRect bounds 
= QDPictGetBounds( cgPictRef 
) ; 
 174         CGContextSaveGState(cg
);     
 175         CGContextTranslateCTM(cg
, 0 , bounds
.size
.width 
); 
 176         CGContextScaleCTM(cg
, 1, -1); 
 177         QDPictDrawToCGContext( cg 
, bounds 
, cgPictRef 
) ; 
 178         CGContextRestoreGState( cg 
) ; 
 180         PicHandle pict 
= (PicHandle
) GetHMETAFILE() ; 
 181         wxMacPortSetter 
helper( dc 
) ; 
 182         DrawPicture( pict 
, &(**pict
).picFrame 
) ; 
 188 wxSize 
wxMetaFile::GetSize() const 
 190     wxSize size 
= wxDefaultSize 
; 
 193         PicHandle pict 
= (PicHandle
) GetHMETAFILE() ; 
 194         Rect 
&r 
= (**pict
).picFrame 
; 
 195         size
.x 
= r
.right 
- r
.left 
; 
 196         size
.y 
= r
.bottom 
- r
.top 
; 
 203  * Metafile device context 
 207 // New constructor that takes origin and extent. If you use this, don't 
 208 // give origin/extent arguments to wxMakeMetaFilePlaceable. 
 210 wxMetaFileDC::wxMetaFileDC(const wxString
& filename 
, 
 211                     int width 
, int height 
, 
 212                     const wxString
& WXUNUSED(description
) ) 
 214     wxASSERT_MSG( width 
== 0 || height 
== 0 , _T("no arbitration of metafilesize supported") ) ; 
 215     wxASSERT_MSG( filename
.IsEmpty() , _T("no file based metafile support yet")) ; 
 217     m_metaFile 
= new wxMetaFile(filename
) ; 
 218 #if wxMAC_USE_CORE_GRAPHICS 
 220     Rect r
={0,0,height
,width
} ; 
 222     RectRgn( (RgnHandle
) m_macBoundaryClipRgn 
, &r 
) ; 
 223     CopyRgn( (RgnHandle
) m_macBoundaryClipRgn 
, (RgnHandle
) m_macCurrentClipRgn 
) ; 
 225     m_metaFile
->SetHMETAFILE( (WXHMETAFILE
) OpenPicture( &r 
) ) ; 
 226     ::GetPort( (GrafPtr
*) &m_macPort 
) ;     
 229     SetMapMode(wxMM_TEXT
);  
 232 wxMetaFileDC::~wxMetaFileDC() 
 236 void wxMetaFileDC::DoGetSize(int *width
, int *height
) const 
 238     wxCHECK_RET( m_metaFile 
, _T("GetSize() doesn't work without a metafile") ); 
 240     wxSize sz 
= m_metaFile
->GetSize() ; 
 241     if (width
) (*width
) = sz
.x
; 
 242     if (height
) (*height
) = sz
.y
; 
 245 wxMetaFile 
*wxMetaFileDC::Close() 
 252 size_t wxMetafileDataObject::GetDataSize() const 
 254     return GetHandleSize( (Handle
) (*((wxMetafile
*)&m_metafile
)).GetHMETAFILE() ) ; 
 257 bool wxMetafileDataObject::GetDataHere(void *buf
) const 
 259     memcpy( buf 
, (*(PicHandle
)(*((wxMetafile
*)&m_metafile
)).GetHMETAFILE()) , 
 260         GetHandleSize( (Handle
) (*((wxMetafile
*)&m_metafile
)).GetHMETAFILE() ) ) ; 
 264 bool wxMetafileDataObject::SetData(size_t len
, const void *buf
) 
 266     Handle handle 
= NewHandle( len 
) ; 
 267     SetHandleSize( handle 
, len 
) ; 
 268     memcpy( *handle 
, buf 
, len 
) ; 
 269     m_metafile
.SetHMETAFILE( (WXHMETAFILE
) handle 
) ;