]> git.saurik.com Git - wxWidgets.git/commitdiff
adding metafile and clipboard support
authorStefan Csomor <csomor@advancedconcepts.ch>
Sun, 13 Feb 2005 05:59:04 +0000 (05:59 +0000)
committerStefan Csomor <csomor@advancedconcepts.ch>
Sun, 13 Feb 2005 05:59:04 +0000 (05:59 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@31980 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/mac/carbon/bitmap.h
include/wx/mac/carbon/dc.h
include/wx/mac/carbon/metafile.h
include/wx/mac/carbon/private.h
src/mac/carbon/bitmap.cpp
src/mac/carbon/dataobj.cpp
src/mac/carbon/metafile.cpp

index d9d2db1f2ebe0292f2053ddab672daae7170d7cb..054249c602d4d6817d49e42a1ee8fdc122930125 100644 (file)
@@ -68,18 +68,18 @@ public:
     int GetBytesPerRow() const { return m_bytesPerRow ; }
     // renders/updates native representation when necessary 
     void RealizeNative() ;
-#if !wxMAC_USE_CORE_GRAPHICS
+
     WXHBITMAP GetHBITMAP() const ;
-#endif
+
 
 private:
     wxMemoryBuffer m_memBuf ;
     int m_bytesPerRow ;
     int m_width ;
     int m_height ;
-#if !wxMAC_USE_CORE_GRAPHICS
+
     WXHBITMAP m_maskBitmap ;
-#endif
+
 };
 
 class WXDLLEXPORT wxBitmapHandler: public wxBitmapHandlerBase
@@ -193,10 +193,8 @@ public:
     bool HasAlpha() const;
     void UseAlpha();
 
-#if !wxMAC_USE_CORE_GRAPHICS
     // returns the 'native' implementation, a GWorldPtr for the content and one for the mask 
     WXHBITMAP GetHBITMAP( WXHBITMAP * mask = NULL ) const;
-#endif
 
 #if wxMAC_USE_CORE_GRAPHICS
     // returns a CGImageRef which must released after usage with CGImageRelease
index 3a6437507f948d55c1e0ab636217187a4c5e56b4..b84d255a1f517e84d0d5dee78dbe65dce1f94fe9 100644 (file)
@@ -222,7 +222,9 @@ class WXDLLEXPORT wxDC: public wxDCBase
       else
         return (wxCoord)((double)(new_y) * m_scaleY - 0.5) * m_signY + m_deviceOriginY + m_macLocalOrigin.y ;
     }
-#if !wxMAC_USE_CORE_GRAPHICS
+#if wxMAC_USE_CORE_GRAPHICS
+    wxGraphicContext* GetGraphicContext() { return m_graphicContext ; }
+#else
     WXHRGN MacGetCurrentClipRgn() { return m_macCurrentClipRgn ; }
     static void MacSetupBackgroundForCurrentPort(const wxBrush& background ) ;
 #endif
index 2b528efeca862bfc71ffb87de0281b583e66fc86..8dff33be653a789522be5c488f946f509399c88e 100644 (file)
 #define wxMetaFileDC wxMetafileDC
 
 class WXDLLEXPORT wxMetafile;
-
-class WXDLLEXPORT wxMetafileRefData: public wxGDIRefData
-{
-    friend class WXDLLEXPORT wxMetafile;
-public:
-    wxMetafileRefData(void);
-    ~wxMetafileRefData(void);
-
-public:
-    WXHMETAFILE m_metafile;
-};
+class wxMetafileRefData ;
 
 #define M_METAFILEDATA ((wxMetafileRefData *)m_refData)
 
@@ -63,14 +53,14 @@ public:
     virtual bool SetClipboard(int width = 0, int height = 0);
 
     virtual bool Play(wxDC *dc);
-    inline bool Ok(void) const { return (M_METAFILEDATA && (M_METAFILEDATA->m_metafile != 0)); };
+    bool Ok() const ;
 
     wxSize GetSize() const;
     int GetWidth() const { return GetSize().x; }
     int GetHeight() const { return GetSize().y; }
 
     // Implementation
-    inline WXHMETAFILE GetHMETAFILE() const { return M_METAFILEDATA->m_metafile; }
+    WXHMETAFILE GetHMETAFILE() const ;
     void SetHMETAFILE(WXHMETAFILE mf) ;
 
     // Operators
index 26b4452ce8acd78649866a017b802a8c4e554135..2ead7ca3f1ed07e1f9614f8cf94589504be0dc31 100644 (file)
@@ -354,6 +354,7 @@ CIconHandle     wxMacCreateCIcon(GWorldPtr image , GWorldPtr mask , short dstDep
 void                 wxMacSetColorTableEntry( CTabHandle newColors , int index , int red , int green ,  int blue ) ;
 CTabHandle         wxMacCreateColorTable( int numColors ) ;
 */
+PicHandle wxMacCreatePicHandle( const wxBitmap &bmp ) ;
 IconRef wxMacCreateIconRef(const wxBitmap& bmp) ;
 void wxMacCreateBitmapButton( ControlButtonContentInfo*info , const wxBitmap& bitmap , int forceType = 0 ) ;
 void wxMacReleaseBitmapButton( ControlButtonContentInfo*info ) ;
@@ -597,6 +598,7 @@ private:
 } ;
 
 CGColorSpaceRef wxMacGetGenericRGBColorSpace(void) ;
+void wxMacMemoryBufferReleaseProc(void *info, const void *data, size_t size) ;
 
 #endif // wxMAC_USE_CORE_GRAPHICS
 
@@ -638,10 +640,10 @@ public:
     wxMask *      m_bitmapMask; // Optional mask
 #if wxMAC_USE_CORE_GRAPHICS
     CGImageRef    CGImageCreate() const ;
-#else
+#endif
     GWorldPtr     GetHBITMAP(GWorldPtr * mask = NULL ) const ;
     void          UpdateAlphaMask() const ;
-#endif
+
 private :
     bool Create(int width , int height , int depth) ;
     void Init() ;
@@ -656,12 +658,11 @@ private :
     bool          m_ok;
 #if wxMAC_USE_CORE_GRAPHICS
     mutable CGImageRef    m_cgImageRef ;
-#else
+#endif
     GWorldPtr     m_hBitmap;
     GWorldPtr     m_hMaskBitmap ;
     wxMemoryBuffer m_maskMemBuf ;
     int            m_maskBytesPerRow ;
-#endif
 };
 
 #define M_BITMAPDATA ((wxBitmapRefData *)m_refData)
index d98e6fd2dda27893fb97e215588a3db00a17a0c4..89a0e4998cd0ce4dc77d3ede0e913b29a04fff6b 100644 (file)
@@ -49,7 +49,7 @@ IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler, wxObject )
 // we don't dare premultiplied alpha yet
 #define wxMAC_USE_PREMULTIPLIED_ALPHA 0
 
-IconRef wxMacCreateIconRef(const wxBitmap& bmp)
+IconFamilyHandle wxMacCreateIconFamily(const wxBitmap& bmp)
 {
     // setup the header properly
     
@@ -151,11 +151,16 @@ IconRef wxMacCreateIconRef(const wxBitmap& bmp)
     HUnlock( maskdata ) ;
     DisposeHandle( data ) ;
     DisposeHandle( maskdata ) ;
+    return iconFamily ;
+}
 
+IconRef wxMacCreateIconRef(const wxBitmap& bmp)
+{
+    IconFamilyHandle iconFamily = wxMacCreateIconFamily( bmp ) ;
     IconRef iconRef ;
     static int iconCounter = 2 ;
     
-    err = RegisterIconRefFromIconFamily( 'WXNG' , (OSType) iconCounter, iconFamily, &iconRef ) ;
+    OSStatus err = RegisterIconRefFromIconFamily( 'WXNG' , (OSType) iconCounter, iconFamily, &iconRef ) ;
     UInt16 owners ;
     err = GetIconRefOwners(iconRef , &owners ) ;
 
@@ -169,6 +174,44 @@ IconRef wxMacCreateIconRef(const wxBitmap& bmp)
     return iconRef ;
 }
 
+PicHandle wxMacCreatePicHandle( const wxBitmap &bmp )
+{
+    CGrafPtr        origPort = NULL ;
+    GDHandle        origDev = NULL ;
+    PicHandle       pict = NULL ;
+    GWorldPtr       wp = NULL ;
+    GWorldPtr       mask = NULL ;
+
+    GetGWorld( &origPort , &origDev ) ;
+
+    wp = (GWorldPtr) bmp.GetHBITMAP( (WXHBITMAP*) &mask ) ;
+
+    SetGWorld( wp , NULL ) ;
+    Rect portRect ;
+    GetPortBounds( wp , &portRect ) ;
+    pict = OpenPicture(&portRect);
+    
+    if(pict)
+    {
+        RGBColor       white = { 0xffff ,0xffff , 0xffff } ;
+        RGBColor       black = { 0x0000 ,0x0000 , 0x0000 } ;
+        RGBForeColor( &black ) ;
+        RGBBackColor( &white ) ;
+
+        LockPixels( GetGWorldPixMap( wp ) ) ;
+        CopyBits(GetPortBitMapForCopyBits(wp),
+                GetPortBitMapForCopyBits(wp),
+                &portRect,
+                &portRect,
+                srcCopy,NULL);
+        UnlockPixels( GetGWorldPixMap( wp ) ) ;
+        ClosePicture();
+    }
+    SetGWorld( origPort , origDev ) ;
+
+    return pict;
+}
+
 void wxMacCreateBitmapButton( ControlButtonContentInfo*info , const wxBitmap& bitmap , int forceType )
 {
     memset( info , 0 , sizeof(ControlButtonContentInfo) ) ;
@@ -219,11 +262,11 @@ void wxBitmapRefData::Init()
     m_bitmapMask = NULL ;
 #if wxMAC_USE_CORE_GRAPHICS
     m_cgImageRef = NULL ;
-#else
+#endif
     m_hBitmap = NULL ;
     m_hMaskBitmap = NULL;
     m_maskBytesPerRow = NULL ;
-#endif
+
     m_rawAccessCount = 0 ;
     m_hasAlpha = false;
 }
@@ -250,16 +293,14 @@ bool wxBitmapRefData::Create( int w , int h , int d )
     void*  data = m_memBuf.GetWriteBuf(size) ;
     memset( data ,  0 , size) ;
     m_memBuf.UngetWriteBuf(size) ;
-#if wxMAC_USE_CORE_GRAPHICS
-    m_ok = true ;
-#else
+
     m_hBitmap = NULL ;
     Rect rect = { 0 , 0 , m_height , m_width } ;
     verify_noerr( NewGWorldFromPtr( (GWorldPtr*) &m_hBitmap , k32ARGBPixelFormat , &rect , NULL , NULL , 0 ,
         (char*) data , m_bytesPerRow ) ) ; 
     wxASSERT_MSG( m_hBitmap , wxT("Unable to create GWorld context") ) ;
     m_ok = ( m_hBitmap != NULL ) ;
-#endif 
+
     return m_ok ;   
 }
 
@@ -269,7 +310,6 @@ void wxBitmapRefData::UseAlpha( bool use )
         return ;
         
     m_hasAlpha = use ;
-#if !wxMAC_USE_CORE_GRAPHICS
     if ( m_hasAlpha )
     {
         int width = GetWidth() ;
@@ -284,7 +324,9 @@ void wxBitmapRefData::UseAlpha( bool use )
             (char*) data , m_maskBytesPerRow ) ) ; 
         wxASSERT_MSG( m_hMaskBitmap , wxT("Unable to create GWorld context for alpha mask") ) ;
         m_maskMemBuf.UngetWriteBuf(size) ;
+#if !wxMAC_USE_CORE_GRAPHICS
         UpdateAlphaMask() ;
+#endif
     }
     else
     {
@@ -292,7 +334,6 @@ void wxBitmapRefData::UseAlpha( bool use )
         m_hMaskBitmap = NULL ;
         m_maskBytesPerRow = 0 ;
     }
-#endif
 }
 
 void *wxBitmapRefData::GetRawAccess() const
@@ -330,9 +371,11 @@ void wxBitmapRefData::EndRawAccess()
 
 
 #if wxMAC_USE_CORE_GRAPHICS
-static void FreeImageMemoryBufferInstance(void *info, const void *data, size_t size)
+void wxMacMemoryBufferReleaseProc(void *info, const void *data, size_t size)
 {
-    delete ((wxMemoryBuffer*)info) ;
+    wxMemoryBuffer* membuf = (wxMemoryBuffer*) info ;
+    wxASSERT( data == membuf->GetData() ) ;
+    delete membuf ;
 }
 
 CGImageRef wxBitmapRefData::CGImageCreate() const
@@ -381,7 +424,8 @@ CGImageRef wxBitmapRefData::CGImageCreate() const
         }
         CGColorSpaceRef colorSpace = wxMacGetGenericRGBColorSpace();
        CGDataProviderRef dataProvider = 
-           CGDataProviderCreateWithData( membuf , (const void *)membuf->GetData() , imageSize, FreeImageMemoryBufferInstance );
+           CGDataProviderCreateWithData( membuf , (const void *)membuf->GetData() , imageSize, 
+               wxMacMemoryBufferReleaseProc );
         image = 
            ::CGImageCreate( w, h, 8 , 32 , 4 * m_width , colorSpace, alphaInfo , 
                        dataProvider, NULL , false , kCGRenderingIntentDefault );
@@ -402,7 +446,6 @@ CGImageRef wxBitmapRefData::CGImageCreate() const
 }
 #endif
 
-#if !wxMAC_USE_CORE_GRAPHICS
 GWorldPtr wxBitmapRefData::GetHBITMAP(GWorldPtr* mask) const
 {
     wxCHECK_MSG( Ok(), NULL, wxT("invalid bitmap") );
@@ -413,8 +456,14 @@ GWorldPtr wxBitmapRefData::GetHBITMAP(GWorldPtr* mask) const
             *mask = (GWorldPtr) m_bitmapMask->GetHBITMAP() ;        
         else if ( m_hasAlpha )
         {
+#if !wxMAC_USE_CORE_GRAPHICS
             if ( m_rawAccessCount > 0 )
                 UpdateAlphaMask() ;
+#else
+            // this structure is not kept in synch when using CG, so if someone
+            // is really accessing the Graphports, we have to sync it
+            UpdateAlphaMask() ;
+#endif
             *mask = m_hMaskBitmap ;
         }
     }
@@ -442,8 +491,6 @@ void wxBitmapRefData::UpdateAlphaMask() const
     }
 }
 
-#endif
-
 void wxBitmapRefData::Free()
 {
     wxASSERT_MSG( m_rawAccessCount == 0 , wxT("Bitmap still selected when destroyed") ) ;
@@ -454,7 +501,7 @@ void wxBitmapRefData::Free()
         CGImageRelease( m_cgImageRef ) ;
         m_cgImageRef = NULL ;
     }
-#else
+#endif
     if ( m_hBitmap )
     {
         DisposeGWorld( MAC_WXHBITMAP(m_hBitmap) ) ;
@@ -465,7 +512,6 @@ void wxBitmapRefData::Free()
         DisposeGWorld( MAC_WXHBITMAP(m_hMaskBitmap) ) ;
         m_hMaskBitmap = NULL ;
     }
-#endif
 
     if (m_bitmapMask)
     {
@@ -485,14 +531,49 @@ bool wxBitmap::CopyFromIcon(const wxIcon& icon)
     int h = icon.GetHeight() ;
     Create( icon.GetWidth() , icon.GetHeight() ) ;
 
-    if ( w == h && w == 32 )
+    if ( w == h && ( w == 16 || w == 32 || w == 48 || w == 128 ) )
     {
         IconFamilyHandle iconFamily = NULL ;
         Handle imagehandle = NewHandle(0) ;
         Handle maskhandle = NewHandle(0) ;
-        OSStatus err = ( IconRefToIconFamily( MAC_WXHICON(icon.GetHICON()) , kSelectorLarge32Bit | kSelectorLarge8BitMask , &iconFamily ) ) ;
-        err =( GetIconFamilyData( iconFamily , kLarge32BitData , imagehandle ) ) ;
-        err =( GetIconFamilyData( iconFamily , kLarge8BitMask , maskhandle ) ) ;
+        
+        OSType maskType ;
+        OSType dataType ;
+        IconSelectorValue selector ;    
+        if ( w == 128 )
+        {
+            dataType = kThumbnail32BitData ;
+            maskType = kThumbnail8BitMask ;
+            selector = kSelectorAllAvailableData ;
+        }
+        else if ( w == 48 )
+        {
+            dataType = kHuge32BitData ;
+            maskType = kHuge8BitMask ;
+            selector = kSelectorHuge32Bit | kSelectorHuge8BitMask ;
+        }
+        else if ( w == 32 )
+        {
+            dataType = kLarge32BitData ;
+            maskType = kLarge8BitMask ;
+            selector = kSelectorLarge32Bit | kSelectorLarge8BitMask ;
+        }
+        else if ( w == 16 )
+        {
+            dataType = kSmall32BitData ;
+            maskType = kSmall8BitMask ;
+            selector = kSelectorSmall32Bit | kSelectorSmall8BitMask ;
+        }
+        else
+        {
+            wxFAIL_MSG(wxT("Illegal icon size for conversion") ) ;
+        }
+
+
+        OSStatus err = ( IconRefToIconFamily( MAC_WXHICON(icon.GetHICON()) , selector , &iconFamily ) ) ;
+        
+        err =( GetIconFamilyData( iconFamily , dataType , imagehandle ) ) ;
+        err =( GetIconFamilyData( iconFamily , maskType , maskhandle ) ) ;
         wxASSERT( GetHandleSize( imagehandle ) == w * 4 * h ) ;
         wxASSERT( GetHandleSize( maskhandle ) == w * h ) ;
         UseAlpha() ;
@@ -1024,12 +1105,10 @@ void wxBitmap::SetMask(wxMask *mask)
     M_BITMAPDATA->m_bitmapMask = mask ;
 }
 
-#if !wxMAC_USE_CORE_GRAPHICS
 WXHBITMAP wxBitmap::GetHBITMAP(WXHBITMAP* mask) const
 {
     return WXHBITMAP(M_BITMAPDATA->GetHBITMAP((GWorldPtr*)mask));
 }
-#endif
 
 // ----------------------------------------------------------------------------
 // wxMask
@@ -1064,22 +1143,17 @@ wxMask::wxMask(const wxMemoryBuffer& data, int width , int height , int bytesPer
 
 wxMask::~wxMask()
 {
-#if !wxMAC_USE_CORE_GRAPHICS
     if ( m_maskBitmap )
     {
         DisposeGWorld( (GWorldPtr) m_maskBitmap ) ;
         m_maskBitmap = NULL ;
     }
-#endif
 }
 
 void wxMask::Init() 
 {
     m_width = m_height = m_bytesPerRow = 0 ;
-#if !wxMAC_USE_CORE_GRAPHICS
     m_maskBitmap = NULL ;
-#endif
-    
 }
 
 void *wxMask::GetRawAccess() const
@@ -1089,7 +1163,6 @@ void *wxMask::GetRawAccess() const
 
 void wxMask::RealizeNative() 
 {
-#if !wxMAC_USE_CORE_GRAPHICS
     if ( m_maskBitmap )
     {
        DisposeGWorld(  (GWorldPtr) m_maskBitmap ) ;
@@ -1098,7 +1171,6 @@ void wxMask::RealizeNative()
     Rect rect = { 0 , 0 , m_height , m_width } ;
     verify_noerr( NewGWorldFromPtr( (GWorldPtr*) &m_maskBitmap , k8IndexedGrayPixelFormat , &rect , NULL , NULL , 0 ,
         (char*) m_memBuf.GetData() , m_bytesPerRow ) ) ; 
-#endif
 }
 
 // Create a mask from a mono bitmap (copies the bitmap).
@@ -1175,12 +1247,10 @@ bool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour)
     return TRUE;
 }
 
-#if !wxMAC_USE_CORE_GRAPHICS
 WXHBITMAP wxMask::GetHBITMAP() const
 {
     return m_maskBitmap ;
 }
-#endif
 
 // ----------------------------------------------------------------------------
 // wxBitmapHandler
index 234f49899a5f533a1c87a60a2b6d4213742bb6b3..4865f6f5acd7d3ce15a92b9ef1890830bcd23fef 100644 (file)
@@ -32,6 +32,7 @@
 #include "wx/dataobj.h"
 #include "wx/mstream.h"
 #include "wx/image.h"
+#include "wx/metafile.h"
 #include "wx/mac/private.h"
 #include <Scrap.h>
 
@@ -250,9 +251,8 @@ wxBitmapDataObject::wxBitmapDataObject(
     Init();
     if ( m_bitmap.Ok() )
     {
-    /*
-        m_pictHandle = m_bitmap.GetBitmapData()->GetPict( &m_pictCreated ) ;
-    */
+        m_pictHandle = wxMacCreatePicHandle( rBitmap ) ;
+        m_pictCreated = true ;
     }
 }
 
@@ -269,9 +269,8 @@ void wxBitmapDataObject::SetBitmap(
     wxBitmapDataObjectBase::SetBitmap(rBitmap);
     if ( m_bitmap.Ok() )
     {
-    /*
-        m_pictHandle = m_bitmap.GetBitmapData()->GetPict( &m_pictCreated ) ;
-    */
+        m_pictHandle = wxMacCreatePicHandle( rBitmap ) ;
+        m_pictCreated = true ;
     }
 }
 
@@ -320,10 +319,14 @@ bool wxBitmapDataObject::SetData(
     // ownership is transferred to the bitmap
     m_pictCreated = false ;
     Rect frame = (**picHandle).picFrame ;
-    /*
-    m_bitmap.GetBitmapData()->SetPict( (WXHMETAFILE) picHandle ) ;
-    m_bitmap.SetWidth( frame.right - frame.left ) ;
-    m_bitmap.SetHeight( frame.bottom - frame.top ) ;
-    */
+    
+    wxMetafile mf ;
+    mf.SetHMETAFILE( (WXHMETAFILE) m_pictHandle ) ;
+    wxMemoryDC mdc ;
+    m_bitmap.Create( frame.right - frame.left ,frame.bottom - frame.top ) ;
+    mdc.SelectObject(m_bitmap ) ;
+    mf.Play( &mdc ) ;
+    mdc.SelectObject( wxNullBitmap ) ;
+    
     return m_bitmap.Ok();
 }
index 354e4e5b1f471455b334026bce0fb9c4a9595752..adb8b49a4970fce432087c10213dec7c94f64f9a 100644 (file)
@@ -42,6 +42,21 @@ IMPLEMENT_DYNAMIC_CLASS(wxMetafile, wxObject)
 IMPLEMENT_ABSTRACT_CLASS(wxMetafileDC, wxDC)
 #endif
 
+class wxMetafileRefData: public wxGDIRefData
+{
+    friend class WXDLLEXPORT wxMetafile;
+public:
+    wxMetafileRefData(void);
+    ~wxMetafileRefData(void);
+
+private:
+    PicHandle m_metafile;
+#if wxMAC_USE_CORE_GRAPHICS
+    QDPictRef m_qdPictRef ;
+#endif
+};
+
+
 /*
  * Metafiles
  * Currently, the only purpose for making a metafile is to put
@@ -51,6 +66,9 @@ IMPLEMENT_ABSTRACT_CLASS(wxMetafileDC, wxDC)
 wxMetafileRefData::wxMetafileRefData(void)
 {
     m_metafile = 0;
+#if wxMAC_USE_CORE_GRAPHICS
+    m_qdPictRef = NULL ;
+#endif
 }
 
 wxMetafileRefData::~wxMetafileRefData(void)
@@ -59,6 +77,10 @@ wxMetafileRefData::~wxMetafileRefData(void)
     {
         KillPicture( (PicHandle) m_metafile ) ;
         m_metafile = 0;
+#if wxMAC_USE_CORE_GRAPHICS
+        QDPictRelease( m_qdPictRef ) ;
+        m_qdPictRef = NULL ;
+#endif
     }
 }
 
@@ -66,7 +88,6 @@ wxMetaFile::wxMetaFile(const wxString& file)
 {
     m_refData = new wxMetafileRefData;
 
-
     M_METAFILEDATA->m_metafile = 0;
     wxASSERT_MSG( file.IsEmpty() , wxT("no file based metafile support yet") ) ;
 /*
@@ -79,6 +100,16 @@ wxMetaFile::~wxMetaFile()
 {
 }
 
+bool wxMetaFile::Ok() const 
+{ 
+    return (M_METAFILEDATA && (M_METAFILEDATA->m_metafile != 0)); 
+}
+
+WXHMETAFILE wxMetaFile::GetHMETAFILE() const 
+{ 
+    return (WXHMETAFILE) M_METAFILEDATA->m_metafile; 
+}
+
 bool wxMetaFile::SetClipboard(int width, int height)
 {
 #if wxUSE_DRAG_AND_DROP
@@ -104,12 +135,26 @@ bool wxMetaFile::SetClipboard(int width, int height)
 
 void wxMetafile::SetHMETAFILE(WXHMETAFILE mf)
 {
-    if (!m_refData)
-        m_refData = new wxMetafileRefData;
-    if ( M_METAFILEDATA->m_metafile )
-        KillPicture( (PicHandle) M_METAFILEDATA->m_metafile ) ;
+    UnRef() ;
+    
+    m_refData = new wxMetafileRefData;
 
-    M_METAFILEDATA->m_metafile = mf;
+    M_METAFILEDATA->m_metafile = (PicHandle) mf;
+#if wxMAC_USE_CORE_GRAPHICS
+    size_t sz = GetHandleSize( (Handle) M_METAFILEDATA->m_metafile ) ;
+    wxMemoryBuffer* membuf = new wxMemoryBuffer( sz ) ;
+    void * data = membuf->GetWriteBuf(sz) ;
+    memcpy( data , *M_METAFILEDATA->m_metafile , sz ) ;
+    membuf->UngetWriteBuf(sz) ;
+    CGDataProviderRef provider = CGDataProviderCreateWithData( membuf , data , sz ,
+        wxMacMemoryBufferReleaseProc ) ;
+    M_METAFILEDATA->m_qdPictRef = NULL ;
+    if ( provider != NULL )
+    {
+        M_METAFILEDATA->m_qdPictRef = QDPictCreateWithProvider( provider ) ;
+        CGDataProviderRelease( provider ) ;
+    }
+#endif
 }
 
 bool wxMetaFile::Play(wxDC *dc)
@@ -121,10 +166,19 @@ bool wxMetaFile::Play(wxDC *dc)
         return FALSE;
         
     {
+        PicHandle pict = (PicHandle) GetHMETAFILE() ;
 #if wxMAC_USE_CORE_GRAPHICS
+        QDPictRef cgPictRef = M_METAFILEDATA->m_qdPictRef ;
+        CGContextRef cg = dynamic_cast<wxMacCGContext*>(dc->GetGraphicContext())->GetNativeContext() ;
+        CGRect bounds = QDPictGetBounds( cgPictRef ) ;
+
+        CGContextSaveGState(cg);    
+        CGContextTranslateCTM(cg, 0 , bounds.size.width );
+        CGContextScaleCTM(cg, 1, -1);
+        QDPictDrawToCGContext( cg , bounds , cgPictRef ) ;
+        CGContextRestoreGState( cg ) ;
 #else
         wxMacPortSetter helper( dc ) ;
-        PicHandle pict = (PicHandle) GetHMETAFILE() ;
         DrawPicture( pict , &(**pict).picFrame ) ;
 #endif
     }