]> git.saurik.com Git - wxWidgets.git/blobdiff - src/mac/carbon/bitmap.cpp
GTK+ doesn't like slider with min=max values
[wxWidgets.git] / src / mac / carbon / bitmap.cpp
index 4c0a49334f344e01c6cc66a4d5ae1ee789a8ab05..3304fdacec1bf4dd1119891e506574a5fbd3c5c5 100644 (file)
 IMPLEMENT_DYNAMIC_CLASS(wxBitmap, wxGDIObject)
 IMPLEMENT_DYNAMIC_CLASS(wxMask, wxObject)
 
-#ifdef __DARWIN__
-    #include <ApplicationServices/ApplicationServices.h>
-#else
-    #include <PictUtils.h>
-#endif
+#include <ApplicationServices/ApplicationServices.h>
+#include <QuickTime/QuickTime.h>
 
 #include "wx/mac/uma.h"
 
@@ -46,10 +43,95 @@ IMPLEMENT_DYNAMIC_CLASS(wxMask, wxObject)
 // under Quartz then content is transformed into a CGImageRef representing the same data
 // which can be transferred to the GPU by the OS for fast rendering
 
-// we don't dare use premultiplied alpha yet
-#define wxMAC_USE_PREMULTIPLIED_ALPHA 0
+class WXDLLEXPORT wxBitmapRefData: public wxGDIRefData
+{
+    friend class WXDLLIMPEXP_FWD_CORE wxIcon;
+    friend class WXDLLIMPEXP_FWD_CORE wxCursor;
+public:
+    wxBitmapRefData(int width , int height , int depth);
+    wxBitmapRefData();
+    wxBitmapRefData(const wxBitmapRefData &tocopy);
+    
+    virtual ~wxBitmapRefData();
+    
+    void Free();
+    bool Ok() const { return IsOk(); }
+    bool IsOk() const { return m_ok; }
+    void SetOk( bool isOk) { m_ok = isOk; }
+    
+    void SetWidth( int width ) { m_width = width; }
+    void SetHeight( int height ) { m_height = height; }
+    void SetDepth( int depth ) { m_depth = depth; }
+    
+    int GetWidth() const { return m_width; }
+    int GetHeight() const { return m_height; }
+    int GetDepth() const { return m_depth; }
+    
+    void *GetRawAccess() const;
+    void *BeginRawAccess();
+    void EndRawAccess();
+    
+    bool HasAlpha() const { return m_hasAlpha; }
+    void UseAlpha( bool useAlpha );
+    
+public:
+#if wxUSE_PALETTE
+    wxPalette     m_bitmapPalette;
+#endif // wxUSE_PALETTE
+    
+    wxMask *      m_bitmapMask; // Optional mask
+    CGImageRef    CreateCGImage() const;
+    
+    // returns true if the bitmap has a size that
+    // can be natively transferred into a true icon
+    // if no is returned GetIconRef will still produce
+    // an icon but it will be generated via a PICT and
+    // rescaled to 16 x 16
+    bool          HasNativeSize();
+    
+    // caller should increase ref count if needed longer
+    // than the bitmap exists
+    IconRef       GetIconRef();
+    
+    // returns a Pict from the bitmap content
+    PicHandle     GetPictHandle();
+    
+    CGContextRef  GetBitmapContext() const;
+    
+    int           GetBytesPerRow() const { return m_bytesPerRow; }
+    private :
+    bool Create(int width , int height , int depth);
+    void Init();
+    
+    int           m_width;
+    int           m_height;
+    int           m_bytesPerRow;
+    int           m_depth;
+    bool          m_hasAlpha;
+    wxMemoryBuffer m_memBuf;
+    int           m_rawAccessCount;
+    bool          m_ok;
+    mutable CGImageRef    m_cgImageRef;
+    
+    IconRef       m_iconRef;
+    PicHandle     m_pictHandle;
+    
+    CGContextRef  m_hBitmap;
+};
+
 
-#if wxUSE_BMPBUTTON
+#define wxMAC_USE_PREMULTIPLIED_ALPHA 1
+static const int kBestByteAlignement = 16;
+static const int kMaskBytesPerPixel = 1;
+
+static int GetBestBytesPerRow( int rawBytes )
+{
+    return (((rawBytes)+kBestByteAlignement-1) & ~(kBestByteAlignement-1) );
+}
+
+#if wxUSE_GUI
+
+// this is used for more controls than just the wxBitmap button, also for notebooks etc
 
 void wxMacCreateBitmapButton( ControlButtonContentInfo*info , const wxBitmap& bitmap , int forceType )
 {
@@ -60,7 +142,12 @@ void wxMacCreateBitmapButton( ControlButtonContentInfo*info , const wxBitmap& bi
         if ( bmap == NULL )
             return ;
 
-        if ( ( bmap->HasNativeSize() && forceType == 0 ) || forceType == kControlContentIconRef )
+        if ( forceType == 0  )
+        {
+            forceType = kControlContentCGImageRef;
+        }
+
+        if ( forceType == kControlContentIconRef )
         {
             wxBitmap scaleBmp ;
             wxBitmapRefData* bmp = bmap ;
@@ -84,13 +171,11 @@ void wxMacCreateBitmapButton( ControlButtonContentInfo*info , const wxBitmap& bi
             info->u.iconRef = bmp->GetIconRef() ;
             AcquireIconRef( info->u.iconRef ) ;
         }
-#if defined( __WXMAC_OSX__ ) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2
         else if ( forceType == kControlContentCGImageRef )
         {
             info->contentType = kControlContentCGImageRef ;
-            info->u.imageRef = (CGImageRef) bmap->CGImageCreate() ;
+            info->u.imageRef = (CGImageRef) bmap->CreateCGImage() ;
         }
-#endif
         else
         {
 #ifndef __LP64__
@@ -101,6 +186,14 @@ void wxMacCreateBitmapButton( ControlButtonContentInfo*info , const wxBitmap& bi
     }
 }
 
+CGImageRef wxMacCreateCGImageFromBitmap( const wxBitmap& bitmap )
+{
+    wxBitmapRefData * bmap = bitmap.GetBitmapData() ;
+    if ( bmap == NULL )
+        return NULL ;
+    return (CGImageRef) bmap->CreateCGImage();
+}
+
 void wxMacReleaseBitmapButton( ControlButtonContentInfo*info )
 {
     if ( info->contentType == kControlContentIconRef )
@@ -115,12 +208,10 @@ void wxMacReleaseBitmapButton( ControlButtonContentInfo*info )
     {
         // owned by the bitmap, no release here
     }
-#if defined( __WXMAC_OSX__ ) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2
     else if ( info->contentType == kControlContentCGImageRef )
     {
         CGImageRelease( info->u.imageRef ) ;
     }
-#endif
     else
     {
         wxFAIL_MSG(wxT("Unexpected bitmap type") ) ;
@@ -136,23 +227,35 @@ void wxBitmapRefData::Init()
     m_width = 0 ;
     m_height = 0 ;
     m_depth = 0 ;
+    m_bytesPerRow = 0;
     m_ok = false ;
     m_bitmapMask = NULL ;
-
-#ifdef __WXMAC_OSX__
     m_cgImageRef = NULL ;
-#endif
 
     m_iconRef = NULL ;
     m_pictHandle = NULL ;
     m_hBitmap = NULL ;
-    m_hMaskBitmap = NULL;
-    m_maskBytesPerRow = 0 ;
 
     m_rawAccessCount = 0 ;
     m_hasAlpha = false;
 }
 
+wxBitmapRefData::wxBitmapRefData(const wxBitmapRefData &tocopy)
+{
+    Init();
+    Create(tocopy.m_width, tocopy.m_height, tocopy.m_depth); 
+    
+    if (tocopy.m_bitmapMask)
+        m_bitmapMask = new wxMask(*tocopy.m_bitmapMask);
+    else if (tocopy.m_hasAlpha)
+        UseAlpha(true);
+
+    unsigned char* dest = (unsigned char*)GetRawAccess();
+    unsigned char* source = (unsigned char*)tocopy.GetRawAccess();
+    size_t numbytes = m_bytesPerRow * m_height;
+    memcpy( dest, source, numbytes );
+}
+
 wxBitmapRefData::wxBitmapRefData()
 {
     Init() ;
@@ -170,19 +273,18 @@ bool wxBitmapRefData::Create( int w , int h , int d )
     m_height = wxMax(1, h);
     m_depth = d ;
 
-    m_bytesPerRow = w * 4 ;
+    m_bytesPerRow = GetBestBytesPerRow( w * 4 ) ;
     size_t size = m_bytesPerRow * h ;
     void* data = m_memBuf.GetWriteBuf( size ) ;
     memset( data , 0 , size ) ;
     m_memBuf.UngetWriteBuf( size ) ;
 
     m_hBitmap = NULL ;
-    Rect rect = { 0 , 0 , m_height , m_width } ;
-#ifndef __LP64__
-    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") ) ;
-#endif
+    m_hBitmap = CGBitmapContextCreate((char*) data, m_width, m_height, 8, m_bytesPerRow, wxMacGetGenericRGBColorSpace(), kCGImageAlphaNoneSkipFirst );
+    wxASSERT_MSG( m_hBitmap , wxT("Unable to create CGBitmapContext context") ) ;
+    CGContextTranslateCTM( m_hBitmap, 0,  m_height );
+    CGContextScaleCTM( m_hBitmap, 1, -1 );
+
     m_ok = ( m_hBitmap != NULL ) ;
 
     return m_ok ;
@@ -194,38 +296,12 @@ void wxBitmapRefData::UseAlpha( bool use )
         return ;
 
     m_hasAlpha = use ;
-    if ( m_hasAlpha )
-    {
-        wxASSERT( m_hMaskBitmap == NULL ) ;
-
-        int width = GetWidth() ;
-        int height = GetHeight() ;
-        m_maskBytesPerRow = ( width * 4 + 3 ) & 0xFFFFFFC ;
-        size_t size = height * m_maskBytesPerRow ;
-        unsigned char * data = (unsigned char * ) m_maskMemBuf.GetWriteBuf( size ) ;
-        wxASSERT( data != NULL ) ;
-
-        memset( data , 0 , size ) ;
-        Rect rect = { 0 , 0 , height , width } ;
-#ifndef __LP64__
-        verify_noerr( NewGWorldFromPtr( (GWorldPtr*) &m_hMaskBitmap , k32ARGBPixelFormat , &rect , NULL , NULL , 0 ,
-            (char*) data , m_maskBytesPerRow ) ) ;
-        wxASSERT_MSG( m_hMaskBitmap , wxT("Unable to create GWorld context for alpha mask") ) ;
-#endif
-        m_maskMemBuf.UngetWriteBuf(size) ;
 
-#if !wxMAC_USE_CORE_GRAPHICS
-        UpdateAlphaMask() ;
-#endif
-    }
-    else
-    {
-#ifndef __LP64__
-        DisposeGWorld( m_hMaskBitmap ) ;
-#endif
-        m_hMaskBitmap = NULL ;
-        m_maskBytesPerRow = 0 ;
-    }
+    CGContextRelease( m_hBitmap );
+    m_hBitmap = CGBitmapContextCreate((char*) m_memBuf.GetData(), m_width, m_height, 8, m_bytesPerRow, wxMacGetGenericRGBColorSpace(), m_hasAlpha ? kCGImageAlphaPremultipliedFirst : kCGImageAlphaNoneSkipFirst );
+    wxASSERT_MSG( m_hBitmap , wxT("Unable to create CGBitmapContext context") ) ;
+    CGContextTranslateCTM( m_hBitmap, 0,  m_height );
+    CGContextScaleCTM( m_hBitmap, 1, -1 );
 }
 
 void *wxBitmapRefData::GetRawAccess() const
@@ -243,7 +319,6 @@ void *wxBitmapRefData::BeginRawAccess()
 
     ++m_rawAccessCount ;
 
-#ifdef __WXMAC_OSX__
     // we must destroy an existing cached image, as
     // the bitmap data may change now
     if ( m_cgImageRef )
@@ -251,7 +326,6 @@ void *wxBitmapRefData::BeginRawAccess()
         CGImageRelease( m_cgImageRef ) ;
         m_cgImageRef = NULL ;
     }
-#endif
 
     return m_memBuf.GetData() ;
 }
@@ -262,10 +336,6 @@ void wxBitmapRefData::EndRawAccess()
     wxASSERT( m_rawAccessCount == 1 ) ;
 
     --m_rawAccessCount ;
-
-#if !wxMAC_USE_CORE_GRAPHICS
-    UpdateAlphaMask() ;
-#endif
 }
 
 bool wxBitmapRefData::HasNativeSize()
@@ -283,16 +353,7 @@ IconRef wxBitmapRefData::GetIconRef()
     {
         // Create Icon Family Handle
 
-        IconFamilyHandle iconFamily = NULL ;
-
-#ifdef WORDS_BIGENDIAN
-        iconFamily = (IconFamilyHandle) NewHandle( 8 ) ;
-        (**iconFamily).resourceType = kIconFamilyType ;
-        (**iconFamily).resourceSize = sizeof(OSType) + sizeof(Size);
-#else
-        // test this solution on big endian as well
-        iconFamily = (IconFamilyHandle) NewHandle( 0 ) ;
-#endif
+        IconFamilyHandle iconFamily = (IconFamilyHandle) NewHandle( 0 );
 
         int w = GetWidth() ;
         int h = GetHeight() ;
@@ -304,23 +365,59 @@ IconRef wxBitmapRefData::GetIconRef()
         switch (sz)
         {
             case 128:
-                dataType = kThumbnail32BitData ;
-                maskType = kThumbnail8BitMask ;
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+                if ( UMAGetSystemVersion() >= 0x1050 )
+                {
+                    dataType = kIconServices128PixelDataARGB ;
+                }
+                else
+#endif
+                {
+                    dataType = kThumbnail32BitData ;
+                    maskType = kThumbnail8BitMask ;
+                }
                 break;
 
             case 48:
-                dataType = kHuge32BitData ;
-                maskType = kHuge8BitMask ;
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+                if ( UMAGetSystemVersion() >= 0x1050 )
+                {
+                    dataType = kIconServices48PixelDataARGB ;
+                }
+                else
+#endif
+                {
+                    dataType = kHuge32BitData ;
+                    maskType = kHuge8BitMask ;
+                }
                 break;
 
             case 32:
-                dataType = kLarge32BitData ;
-                maskType = kLarge8BitMask ;
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+                if ( UMAGetSystemVersion() >= 0x1050 )
+                {
+                    dataType = kIconServices32PixelDataARGB ;
+                }
+                else
+#endif
+                {
+                    dataType = kLarge32BitData ;
+                    maskType = kLarge8BitMask ;
+                }
                 break;
 
             case 16:
-                dataType = kSmall32BitData ;
-                maskType = kSmall8BitMask ;
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+                if ( UMAGetSystemVersion() >= 0x1050 )
+                {
+                    dataType = kIconServices16PixelDataARGB ;
+                }
+                else
+#endif
+                {
+                    dataType = kSmall32BitData ;
+                    maskType = kSmall8BitMask ;
+                }
                 break;
 
             default:
@@ -329,73 +426,131 @@ IconRef wxBitmapRefData::GetIconRef()
 
         if ( dataType != 0 )
         {
-            // setup the header properly
-
-            Handle data = NULL ;
-            Handle maskdata = NULL ;
-            unsigned char * maskptr = NULL ;
-            unsigned char * ptr = NULL ;
-            size_t datasize, masksize ;
-
-            datasize = sz * sz * 4 ;
-            data = NewHandle( datasize ) ;
-            HLock( data ) ;
-            ptr = (unsigned char*) *data ;
-            memset( ptr , 0, datasize ) ;
-
-            masksize = sz * sz ;
-            maskdata = NewHandle( masksize ) ;
-            HLock( maskdata ) ;
-            maskptr = (unsigned char*) *maskdata ;
-            memset( maskptr , 0 , masksize ) ;
-
-            bool hasAlpha = HasAlpha() ;
-            wxMask *mask = m_bitmapMask ;
-            unsigned char * source = (unsigned char*) GetRawAccess() ;
-            unsigned char * masksource = mask ? (unsigned char*) mask->GetRawAccess() : NULL ;
-
-            for ( int y = 0 ; y < h ; ++y )
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+            if (  maskType == 0 && UMAGetSystemVersion() >= 0x1050 )
             {
-                unsigned char * dest = ptr + y * sz * 4 ;
-                unsigned char * maskdest = maskptr + y * sz ;
-                unsigned char a, r, g, b;
-
-                for ( int x = 0 ; x < w ; ++x )
+                size_t datasize = sz * sz * 4 ;
+                Handle data = NewHandle( datasize ) ;
+                HLock( data ) ;
+                unsigned char* ptr = (unsigned char*) *data ;
+                memset( ptr, 0, datasize );
+                bool hasAlpha = HasAlpha() ;
+                wxMask *mask = m_bitmapMask ;
+                unsigned char * sourcePtr = (unsigned char*) GetRawAccess() ;
+                unsigned char * masksourcePtr = mask ? (unsigned char*) mask->GetRawAccess() : NULL ;
+
+                for ( int y = 0 ; y < h ; ++y, sourcePtr += m_bytesPerRow , masksourcePtr += mask ? mask->GetBytesPerRow() : 0 )
                 {
-                    a = *source ++ ;
-                    r = *source ++ ;
-                    g = *source ++ ;
-                    b = *source ++ ;
+                    unsigned char * source = sourcePtr;
+                    unsigned char * masksource = masksourcePtr;
+                    unsigned char * dest = ptr + y * sz * 4 ;
+                    unsigned char a, r, g, b;
 
-                    *dest++ = 0 ;
-                    *dest++ = r ;
-                    *dest++ = g ;
-                    *dest++ = b ;
+                    for ( int x = 0 ; x < w ; ++x )
+                    {
+                        a = *source ++ ;
+                        r = *source ++ ;
+                        g = *source ++ ;
+                        b = *source ++ ;
+
+                        if ( mask )
+                        {
+                            a = 0xFF - *masksource++ ;
+                        }
+                        else if ( !hasAlpha )
+                            a = 0xFF ;
+                        else
+                        {
+#if wxMAC_USE_PREMULTIPLIED_ALPHA
+                            // this must be non-premultiplied data
+                            if ( a != 0xFF && a!= 0 )
+                            {
+                                r = r * 255 / a;
+                                g = g * 255 / a;
+                                b = b * 255 / a;
+                            }
+#endif
+                        }
+                        *dest++ = a ;
+                        *dest++ = r ;
+                        *dest++ = g ;
+                        *dest++ = b ;
 
-                    if ( mask )
+                     }
+                }
+                HUnlock( data );
+                OSStatus err = SetIconFamilyData( iconFamily, dataType , data );
+                wxASSERT_MSG( err == noErr , wxT("Error when adding bitmap") );
+                DisposeHandle( data );
+            }
+            else
+#endif
+            {
+                // setup the header properly
+                
+                Handle data = NULL ;
+                Handle maskdata = NULL ;
+                unsigned char * maskptr = NULL ;
+                unsigned char * ptr = NULL ;
+                size_t datasize, masksize ;
+                
+                datasize = sz * sz * 4 ;
+                data = NewHandle( datasize ) ;
+                HLock( data ) ;
+                ptr = (unsigned char*) *data ;
+                memset( ptr , 0, datasize ) ;
+                
+                masksize = sz * sz ;
+                maskdata = NewHandle( masksize ) ;
+                HLock( maskdata ) ;
+                maskptr = (unsigned char*) *maskdata ;
+                memset( maskptr , 0 , masksize ) ;
+                
+                bool hasAlpha = HasAlpha() ;
+                wxMask *mask = m_bitmapMask ;
+                unsigned char * sourcePtr = (unsigned char*) GetRawAccess() ;
+                unsigned char * masksourcePtr = mask ? (unsigned char*) mask->GetRawAccess() : NULL ;
+                
+                for ( int y = 0 ; y < h ; ++y, sourcePtr += m_bytesPerRow , masksourcePtr += mask ? mask->GetBytesPerRow() : 0 )
+                {
+                    unsigned char * source = sourcePtr;
+                    unsigned char * masksource = masksourcePtr;
+                    unsigned char * dest = ptr + y * sz * 4 ;
+                    unsigned char * maskdest = maskptr + y * sz ;
+                    unsigned char a, r, g, b;
+                    
+                    for ( int x = 0 ; x < w ; ++x )
                     {
-                        *maskdest++ = 0xFF - *masksource++ ;
-                        masksource++ ;
-                        masksource++ ;
-                        masksource++ ;
+                        a = *source ++ ;
+                        r = *source ++ ;
+                        g = *source ++ ;
+                        b = *source ++ ;
+                        
+                        *dest++ = 0 ;
+                        *dest++ = r ;
+                        *dest++ = g ;
+                        *dest++ = b ;
+                        
+                        if ( mask )
+                            *maskdest++ = 0xFF - *masksource++ ;
+                        else if ( hasAlpha )
+                            *maskdest++ = a ;
+                        else
+                            *maskdest++ = 0xFF ;
                     }
-                    else if ( hasAlpha )
-                        *maskdest++ = a ;
-                    else
-                        *maskdest++ = 0xFF ;
                 }
+                
+                OSStatus err = SetIconFamilyData( iconFamily, dataType , data ) ;
+                wxASSERT_MSG( err == noErr , wxT("Error when adding bitmap") ) ;
+                
+                err = SetIconFamilyData( iconFamily, maskType , maskdata ) ;
+                wxASSERT_MSG( err == noErr , wxT("Error when adding mask") ) ;
+                
+                HUnlock( data ) ;
+                HUnlock( maskdata ) ;
+                DisposeHandle( data ) ;
+                DisposeHandle( maskdata ) ;
             }
-
-            OSStatus err = SetIconFamilyData( iconFamily, dataType , data ) ;
-            wxASSERT_MSG( err == noErr , wxT("Error when adding bitmap") ) ;
-
-            err = SetIconFamilyData( iconFamily, maskType , maskdata ) ;
-            wxASSERT_MSG( err == noErr , wxT("Error when adding mask") ) ;
-
-            HUnlock( data ) ;
-            HUnlock( maskdata ) ;
-            DisposeHandle( data ) ;
-            DisposeHandle( maskdata ) ;
         }
         else
         {
@@ -403,23 +558,12 @@ IconRef wxBitmapRefData::GetIconRef()
             SetIconFamilyData( iconFamily, 'PICT' , (Handle) pic ) ;
         }
         // transform into IconRef
-#if defined( __WXMAC_OSX__ ) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2
+
         // cleaner version existing from 10.3 upwards
         HLock((Handle) iconFamily);
         OSStatus err = GetIconRefFromIconFamilyPtr( *iconFamily, GetHandleSize((Handle) iconFamily), &m_iconRef );
         HUnlock((Handle) iconFamily);
         wxASSERT_MSG( err == noErr , wxT("Error when constructing icon ref") );
-#else
-        static int iconCounter = 2 ;
-
-        OSStatus err = RegisterIconRefFromIconFamily( 'WXNG' , (OSType) iconCounter, iconFamily, &m_iconRef ) ;
-        wxASSERT_MSG( err == noErr , wxT("Error when adding bitmap") ) ;
-
-        // we have to retain a reference, as Unregister will decrement it
-        AcquireIconRef( m_iconRef ) ;
-        UnregisterIconRef( 'WXNG' , (OSType) iconCounter ) ;
-        ++iconCounter ;
-#endif
         DisposeHandle( (Handle) iconFamily ) ;
     }
 
@@ -431,168 +575,133 @@ PicHandle wxBitmapRefData::GetPictHandle()
     if ( m_pictHandle == NULL )
     {
 #ifndef __LP64__
-        CGrafPtr origPort = NULL ;
-        GDHandle origDev = NULL ;
-        GWorldPtr wp = NULL ;
-        GWorldPtr mask = NULL ;
-        int height = GetHeight() ;
-        int width = GetWidth() ;
-
-        Rect rect = { 0 , 0 , height , width } ;
-        RgnHandle clipRgn = NULL ;
-
-        GetGWorld( &origPort , &origDev ) ;
-        wp = GetHBITMAP( &mask ) ;
-
-        if ( mask )
-        {
-            GWorldPtr monoworld ;
-            clipRgn = NewRgn() ;
-            OSStatus err = NewGWorld( &monoworld , 1 , &rect , NULL , NULL , 0 ) ;
-            verify_noerr(err) ;
-            LockPixels( GetGWorldPixMap( monoworld ) ) ;
-            LockPixels( GetGWorldPixMap( mask ) ) ;
-            SetGWorld( monoworld , NULL ) ;
-
-            RGBColor white = { 0xffff , 0xffff , 0xffff } ;
-            RGBColor black = { 0x0000 , 0x0000 , 0x0000 } ;
-            RGBForeColor( &black ) ;
-            RGBBackColor( &white ) ;
-
-            CopyBits(GetPortBitMapForCopyBits(mask),
-                    GetPortBitMapForCopyBits(monoworld),
-                    &rect,
-                    &rect,
-                    srcCopy, NULL);
-            BitMapToRegion( clipRgn , (BitMap*) *GetGWorldPixMap( monoworld ) ) ;
-
-            UnlockPixels( GetGWorldPixMap( monoworld ) ) ;
-            UnlockPixels( GetGWorldPixMap( mask ) ) ;
-            DisposeGWorld( monoworld ) ;
-        }
-
-        SetGWorld( wp , NULL ) ;
-        Rect portRect ;
-        GetPortBounds( wp , &portRect ) ;
-        m_pictHandle = OpenPicture(&portRect);
-
-        if (m_pictHandle)
+        GraphicsExportComponent exporter = 0;
+        OSStatus err = OpenADefaultComponent(GraphicsExporterComponentType, kQTFileTypePicture, &exporter);
+        if (noErr == err)
         {
-            RGBColor white = { 0xffff , 0xffff , 0xffff } ;
-            RGBColor black = { 0x0000 , 0x0000 , 0x0000 } ;
-
-            RGBForeColor( &black ) ;
-            RGBBackColor( &white ) ;
-
-            if ( clipRgn )
-                SetClip( clipRgn ) ;
-
-            LockPixels( GetGWorldPixMap( wp ) ) ;
-            CopyBits(GetPortBitMapForCopyBits(wp),
-                    GetPortBitMapForCopyBits(wp),
-                    &portRect,
-                    &portRect,
-                    srcCopy,clipRgn);
-            UnlockPixels( GetGWorldPixMap( wp ) ) ;
-            ClosePicture();
+            m_pictHandle = (PicHandle) NewHandle(0);
+            if ( m_pictHandle )
+            {
+                // QT does not correctly export the mask
+                // TODO if we get around to it create a synthetic PICT with the CopyBits and Mask commands
+                CGImageRef imageRef = CreateCGImage();
+                err = GraphicsExportSetInputCGImage( exporter, imageRef );
+                err = GraphicsExportSetOutputHandle(exporter, (Handle)m_pictHandle);
+                err = GraphicsExportDoExport(exporter, NULL);
+                CGImageRelease( imageRef );
+
+                               size_t handleSize = GetHandleSize( (Handle) m_pictHandle );
+                               // the 512 bytes header is only needed for pict files, but not in memory
+                               if ( handleSize >= 512 )
+                               {
+                                       memmove( *m_pictHandle , (char*)(*m_pictHandle)+512, handleSize - 512 );
+                                       SetHandleSize( (Handle) m_pictHandle, handleSize - 512 );
+                               }
+            }
+            CloseComponent( exporter );
         }
-
-        SetGWorld( origPort , origDev ) ;
-        if ( clipRgn )
-            DisposeRgn( clipRgn ) ;
 #endif
     }
 
     return m_pictHandle ;
 }
 
-#ifdef __WXMAC_OSX__
-void wxMacMemoryBufferReleaseProc(void *info, const void *data, size_t size)
-{
-    wxMemoryBuffer* membuf = (wxMemoryBuffer*) info ;
-
-    wxASSERT( data == membuf->GetData() ) ;
-
-    delete membuf ;
-}
-
-CGImageRef wxBitmapRefData::CGImageCreate() const
+CGImageRef wxBitmapRefData::CreateCGImage() const
 {
     wxASSERT( m_ok ) ;
     wxASSERT( m_rawAccessCount >= 0 ) ;
     CGImageRef image ;
     if ( m_rawAccessCount > 0 || m_cgImageRef == NULL )
     {
-        size_t imageSize = m_width * m_height * 4 ;
-        void * dataBuffer = m_memBuf.GetData() ;
-        int w = m_width ;
-        int h = m_height ;
-        CGImageAlphaInfo alphaInfo = kCGImageAlphaNoneSkipFirst ;
-        wxMemoryBuffer* membuf = NULL ;
-
-        if ( m_bitmapMask )
+        if ( m_depth != 1 && m_bitmapMask == NULL )
         {
-            alphaInfo = kCGImageAlphaFirst ;
-            membuf = new wxMemoryBuffer( imageSize ) ;
-            memcpy( membuf->GetData() , dataBuffer , imageSize ) ;
-            unsigned char *sourcemaskstart = (unsigned char *) m_bitmapMask->GetRawAccess() ;
-            int maskrowbytes = m_bitmapMask->GetBytesPerRow() ;
-            unsigned char *destalpha = (unsigned char *) membuf->GetData() ;
-            for ( int y = 0 ; y < h ; ++y , sourcemaskstart += maskrowbytes)
+            if ( m_bitmapMask )
             {
-                unsigned char *sourcemask = sourcemaskstart ;
-                for ( int x = 0 ; x < w ; ++x , sourcemask += 4 , destalpha += 4 )
-                {
-                    *destalpha = 0xFF - *sourcemask ;
-                }
+                CGImageRef tempImage = CGBitmapContextCreateImage( m_hBitmap );
+                CGImageRef tempMask = CGBitmapContextCreateImage((CGContextRef) m_bitmapMask->GetHBITMAP() );
+                image = CGImageCreateWithMask( tempImage, tempMask );
+                CGImageRelease(tempMask);
+                CGImageRelease(tempImage);
             }
+            else
+                image = CGBitmapContextCreateImage( m_hBitmap );
         }
         else
         {
-            if ( m_hasAlpha )
+            size_t imageSize = m_height * m_bytesPerRow ;
+            void * dataBuffer = m_memBuf.GetData() ;
+            int w = m_width ;
+            int h = m_height ;
+            CGImageAlphaInfo alphaInfo = kCGImageAlphaNoneSkipFirst ;
+            wxMemoryBuffer membuf;
+            
+            if ( m_bitmapMask )
+            {
+                alphaInfo = kCGImageAlphaFirst ;
+                unsigned char *destalphastart = (unsigned char*) membuf.GetWriteBuf( imageSize ) ;
+                memcpy( destalphastart , dataBuffer , imageSize ) ;
+                unsigned char *sourcemaskstart = (unsigned char *) m_bitmapMask->GetRawAccess() ;
+                int maskrowbytes = m_bitmapMask->GetBytesPerRow() ;
+                for ( int y = 0 ; y < h ; ++y , destalphastart += m_bytesPerRow, sourcemaskstart += maskrowbytes)
+                {
+                    unsigned char *sourcemask = sourcemaskstart ;
+                    unsigned char *destalpha = destalphastart ;
+                    for ( int x = 0 ; x < w ; ++x , sourcemask += kMaskBytesPerPixel , destalpha += 4 )
+                    {
+                        *destalpha = 0xFF - *sourcemask ;
+                    }
+                }
+                membuf.UngetWriteBuf( imageSize );
+            }
+            else
             {
+                if ( m_hasAlpha )
+                {
 #if wxMAC_USE_PREMULTIPLIED_ALPHA
-                alphaInfo = kCGImageAlphaPremultipliedFirst ;
+                    alphaInfo = kCGImageAlphaPremultipliedFirst ;
 #else
-                alphaInfo = kCGImageAlphaFirst ;
+                    alphaInfo = kCGImageAlphaFirst ;
 #endif
+                }
+                
+                membuf = m_memBuf;
             }
-
-            membuf = new wxMemoryBuffer( m_memBuf ) ;
-        }
-        
-        CGDataProviderRef dataProvider = NULL ;
-        if ( m_depth == 1 )
-        {
-            wxMemoryBuffer* maskBuf = new wxMemoryBuffer( m_width * m_height );
-            unsigned char * maskBufData = (unsigned char *) maskBuf->GetData();
-            unsigned char * bufData = (unsigned char *) membuf->GetData() ;
-            // copy one color component
-            for( int i = 0 ; i < m_width * m_height ; ++i )
-                maskBufData[i] = bufData[i*4+3];
-            dataProvider =
-                CGDataProviderCreateWithData(
-                    maskBuf , (const void *) maskBufData , m_width * m_height,
-                    wxMacMemoryBufferReleaseProc );
-            // as we are now passing the mask buffer to the data provider, we have
-            // to release the membuf ourselves
-            delete membuf ;
-
-            image = ::CGImageMaskCreate( w, h, 8, 8, m_width , dataProvider, NULL, false );
-        }
-        else
-        {
-            CGColorSpaceRef colorSpace = wxMacGetGenericRGBColorSpace();
-            dataProvider =
-                CGDataProviderCreateWithData(
-                    membuf , (const void *)membuf->GetData() , imageSize,
-                    wxMacMemoryBufferReleaseProc );
-            image =
-            ::CGImageCreate(
-                w, h, 8 , 32 , 4 * m_width , colorSpace, alphaInfo ,
-                dataProvider, NULL , false , kCGRenderingIntentDefault );
+            
+            CGDataProviderRef dataProvider = NULL ;
+            if ( m_depth == 1 )
+            {
+                // TODO CHECK ALIGNMENT
+                wxMemoryBuffer maskBuf;
+                unsigned char * maskBufData = (unsigned char*) maskBuf.GetWriteBuf( m_width * m_height );
+                unsigned char * bufData = (unsigned char *) membuf.GetData() ;
+                // copy one color component
+                size_t i = 0;
+                for( int y = 0 ; y < m_height ; bufData+= m_bytesPerRow, ++y )
+                {
+                    unsigned char *bufDataIter = bufData+3;
+                    for ( int x = 0 ; x < m_width ; bufDataIter += 4, ++x, ++i )
+                    {
+                        maskBufData[i] = *bufDataIter;
+                    }
+                }
+                maskBuf.UngetWriteBuf( m_width * m_height );
+                
+                dataProvider =
+                    wxMacCGDataProviderCreateWithMemoryBuffer( maskBuf );
+                
+                image = ::CGImageMaskCreate( w, h, 8, 8, m_width , dataProvider, NULL, false );
+            }
+            else
+            {
+                CGColorSpaceRef colorSpace = wxMacGetGenericRGBColorSpace();
+                dataProvider = wxMacCGDataProviderCreateWithMemoryBuffer( membuf );
+                image =
+                    ::CGImageCreate(
+                                    w, h, 8 , 32 , m_bytesPerRow , colorSpace, alphaInfo ,
+                                    dataProvider, NULL , false , kCGRenderingIntentDefault );
+            }
+            CGDataProviderRelease( dataProvider);
         }
-        CGDataProviderRelease( dataProvider);
     }
     else
     {
@@ -609,73 +718,21 @@ CGImageRef wxBitmapRefData::CGImageCreate() const
 
     return image ;
 }
-#endif
-
-GWorldPtr wxBitmapRefData::GetHBITMAP(GWorldPtr* mask) const
-{
-    wxCHECK_MSG( Ok(), NULL, wxT("invalid bitmap") );
-    if ( mask )
-    {
-        *mask = NULL ;
-        if ( m_bitmapMask )
-        {
-            *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 something
-            // is really accessing the GrafPorts, we have to sync it
-            UpdateAlphaMask() ;
-#endif
-
-            *mask = m_hMaskBitmap ;
-        }
-    }
-
-    return m_hBitmap ;
-}
 
-void wxBitmapRefData::UpdateAlphaMask() const
+CGContextRef wxBitmapRefData::GetBitmapContext() const
 {
-    if ( m_hasAlpha )
-    {
-        unsigned char *sourcemask = (unsigned char *) GetRawAccess() ;
-        unsigned char *destalphabase = (unsigned char *) m_maskMemBuf.GetData() ;
-
-        int h = GetHeight() ;
-        int w = GetWidth() ;
-
-        for ( int y = 0 ; y < h ; ++y , destalphabase += m_maskBytesPerRow )
-        {
-            unsigned char* destalpha = destalphabase ;
-
-            for ( int x = 0 ; x < w ; ++x , sourcemask += 4 )
-            {
-                // we must have 24 bit depth for non quartz smooth alpha
-                *destalpha++ = 255 ;
-                *destalpha++ = 255  - *sourcemask ;
-                *destalpha++ = 255  - *sourcemask ;
-                *destalpha++ = 255  - *sourcemask ;
-            }
-        }
-    }
+    return m_hBitmap;
 }
 
 void wxBitmapRefData::Free()
 {
     wxASSERT_MSG( m_rawAccessCount == 0 , wxT("Bitmap still selected when destroyed") ) ;
 
-#ifdef __WXMAC_OSX__
     if ( m_cgImageRef )
     {
         CGImageRelease( m_cgImageRef ) ;
         m_cgImageRef = NULL ;
     }
-#endif
 
     if ( m_iconRef )
     {
@@ -689,19 +746,14 @@ void wxBitmapRefData::Free()
         KillPicture( m_pictHandle ) ;
         m_pictHandle = NULL ;
     }
+#endif
 
     if ( m_hBitmap )
     {
-        DisposeGWorld( MAC_WXHBITMAP(m_hBitmap) ) ;
+        CGContextRelease(m_hBitmap);
         m_hBitmap = NULL ;
     }
 
-    if ( m_hMaskBitmap )
-    {
-        DisposeGWorld( MAC_WXHBITMAP(m_hMaskBitmap) ) ;
-        m_hMaskBitmap = NULL ;
-    }
-#endif
     if (m_bitmapMask)
     {
         delete m_bitmapMask;
@@ -784,11 +836,18 @@ bool wxBitmap::CopyFromIcon(const wxIcon& icon)
             {
                 for ( int x = 0 ; x < w ; ++x )
                 {
-                    *destination++ = *sourcemask++ ;
+                    unsigned char a = *sourcemask++;
+                    *destination++ = a;
                     source++ ;
+#if wxMAC_USE_PREMULTIPLIED_ALPHA
+                    *destination++ = ( (*source++) * a + 127 ) / 255;
+                    *destination++ = ( (*source++) * a + 127 ) / 255;
+                    *destination++ = ( (*source++) * a + 127 ) / 255;
+#else                    
                     *destination++ = *source++ ;
                     *destination++ = *source++ ;
                     *destination++ = *source++ ;
+#endif
                 }
             }
 
@@ -831,10 +890,11 @@ wxBitmap::wxBitmap(const char bits[], int the_width, int the_height, int no_bits
             linesize += sizeof(unsigned char);
 
         unsigned char* linestart = (unsigned char*) bits ;
-        unsigned char* destination = (unsigned char*) BeginRawAccess() ;
+        unsigned char* destptr = (unsigned char*) BeginRawAccess() ;
 
-        for ( int y = 0 ; y < the_height ; ++y , linestart += linesize )
+        for ( int y = 0 ; y < the_height ; ++y , linestart += linesize, destptr += M_BITMAPDATA->GetBytesPerRow() )
         {
+            unsigned char* destination = destptr;
             int index, bit, mask;
 
             for ( int x = 0 ; x < the_width ; ++x )
@@ -883,6 +943,16 @@ wxBitmap::wxBitmap(const wxString& filename, wxBitmapType type)
     LoadFile(filename, type);
 }
 
+wxObjectRefData* wxBitmap::CreateRefData() const
+{
+    return new wxBitmapRefData;
+}
+
+wxObjectRefData* wxBitmap::CloneRefData(const wxObjectRefData* data) const
+{
+    return new wxBitmapRefData(*wx_static_cast(const wxBitmapRefData *, data));
+}
+
 void * wxBitmap::GetRawAccess() const
 {
     wxCHECK_MSG( Ok() , NULL , wxT("invalid bitmap") ) ;
@@ -904,14 +974,26 @@ void wxBitmap::EndRawAccess()
     M_BITMAPDATA->EndRawAccess() ;
 }
 
-#ifdef __WXMAC_OSX__
-WXCGIMAGEREF wxBitmap::CGImageCreate() const
+CGImageRef wxBitmap::CreateCGImage() const
 {
     wxCHECK_MSG( Ok(), NULL , wxT("invalid bitmap") ) ;
 
-    return M_BITMAPDATA->CGImageCreate() ;
+    return M_BITMAPDATA->CreateCGImage() ;
+}
+
+IconRef wxBitmap::GetIconRef() const
+{
+    wxCHECK_MSG( Ok(), NULL , wxT("invalid bitmap") ) ;
+    
+    return M_BITMAPDATA->GetIconRef() ;
+}
+
+IconRef wxBitmap::CreateIconRef() const
+{
+    IconRef icon = GetIconRef();
+    verify_noerr( AcquireIconRef(icon) );
+    return icon;
 }
-#endif
 
 wxBitmap wxBitmap::GetSubBitmap(const wxRect &rect) const
 {
@@ -924,7 +1006,6 @@ wxBitmap wxBitmap::GetSubBitmap(const wxRect &rect) const
     wxBitmap ret( rect.width, rect.height, GetDepth() );
     wxASSERT_MSG( ret.Ok(), wxT("GetSubBitmap error") );
 
-    int sourcewidth = GetWidth() ;
     int destwidth = rect.width ;
     int destheight = rect.height ;
 
@@ -933,8 +1014,8 @@ wxBitmap wxBitmap::GetSubBitmap(const wxRect &rect) const
         unsigned char *destdata = (unsigned char*) ret.BeginRawAccess() ;
         wxASSERT( (sourcedata != NULL) && (destdata != NULL) ) ;
 
-        int sourcelinesize = sourcewidth * 4 ;
-        int destlinesize = destwidth * 4 ;
+        int sourcelinesize = GetBitmapData()->GetBytesPerRow() ;
+        int destlinesize = ret.GetBitmapData()->GetBytesPerRow() ;
         unsigned char *source = sourcedata + rect.x * 4 + rect.y * sourcelinesize ;
         unsigned char *dest = destdata ;
 
@@ -949,7 +1030,7 @@ wxBitmap wxBitmap::GetSubBitmap(const wxRect &rect) const
     if ( M_BITMAPDATA->m_bitmapMask )
     {
         wxMemoryBuffer maskbuf ;
-        int rowBytes = ( destwidth * 4 + 3 ) & 0xFFFFFFC ;
+        int rowBytes = GetBestBytesPerRow( destwidth * kMaskBytesPerPixel );
         size_t maskbufsize = rowBytes * destheight ;
 
         int sourcelinesize = M_BITMAPDATA->m_bitmapMask->GetBytesPerRow() ;
@@ -959,7 +1040,7 @@ wxBitmap wxBitmap::GetSubBitmap(const wxRect &rect) const
         unsigned char *destdata = (unsigned char * ) maskbuf.GetWriteBuf( maskbufsize ) ;
         wxASSERT( (source != NULL) && (destdata != NULL) ) ;
 
-        source += rect.x * 4 + rect.y * sourcelinesize ;
+        source += rect.x * kMaskBytesPerPixel + rect.y * sourcelinesize ;
         unsigned char *dest = destdata ;
 
         for (int yy = 0; yy < destheight; ++yy, source += sourcelinesize , dest += destlinesize)
@@ -1041,17 +1122,17 @@ bool wxBitmap::Create(const void* data, wxBitmapType type, int width, int height
 wxBitmap::wxBitmap(const wxImage& image, int depth)
 {
     wxCHECK_RET( image.Ok(), wxT("invalid image") );
-
+    
     // width and height of the device-dependent bitmap
     int width = image.GetWidth();
     int height = image.GetHeight();
-
+    
     m_refData = new wxBitmapRefData( width , height , depth ) ;
-
+    
     // Create picture
-
+    
     bool hasAlpha = false ;
-
+    
     if ( image.HasMask() )
     {
         // takes precedence, don't mix with alpha info
@@ -1060,44 +1141,47 @@ wxBitmap::wxBitmap(const wxImage& image, int depth)
     {
         hasAlpha = image.HasAlpha() ;
     }
-
+    
     if ( hasAlpha )
         UseAlpha() ;
-
-    unsigned char* destination = (unsigned char*) BeginRawAccess() ;
+    
+    unsigned char* destinationstart = (unsigned char*) BeginRawAccess() ;
     register unsigned char* data = image.GetData();
-    const unsigned char *alpha = hasAlpha ? image.GetAlpha() : NULL ;
-
-    for (int y = 0; y < height; y++)
+    if ( destinationstart != NULL && data != NULL )
     {
-        for (int x = 0; x < width; x++)
+        const unsigned char *alpha = hasAlpha ? image.GetAlpha() : NULL ;
+        for (int y = 0; y < height; destinationstart += M_BITMAPDATA->GetBytesPerRow(), y++)
         {
-            if ( hasAlpha )
+            unsigned char * destination = destinationstart;
+            for (int x = 0; x < width; x++)
             {
-                const unsigned char a = *alpha++;
-                *destination++ = a ;
-
+                if ( hasAlpha )
+                {
+                    const unsigned char a = *alpha++;
+                    *destination++ = a ;
+                    
 #if wxMAC_USE_PREMULTIPLIED_ALPHA
-                *destination++ = ((*data++) * a + 127) / 255 ;
-                *destination++ = ((*data++) * a + 127) / 255 ;
-                *destination++ = ((*data++) * a + 127) / 255 ;
+                    *destination++ = ((*data++) * a + 127) / 255 ;
+                    *destination++ = ((*data++) * a + 127) / 255 ;
+                    *destination++ = ((*data++) * a + 127) / 255 ;
 #else
-                *destination++ = *data++ ;
-                *destination++ = *data++ ;
-                *destination++ = *data++ ;
+                    *destination++ = *data++ ;
+                    *destination++ = *data++ ;
+                    *destination++ = *data++ ;
 #endif
-            }
-            else
-            {
-                *destination++ = 0xFF ;
-                *destination++ = *data++ ;
-                *destination++ = *data++ ;
-                *destination++ = *data++ ;
+                }
+                else
+                {
+                    *destination++ = 0xFF ;
+                    *destination++ = *data++ ;
+                    *destination++ = *data++ ;
+                    *destination++ = *data++ ;
+                }
             }
         }
+        
+        EndRawAccess() ;
     }
-
-    EndRawAccess() ;
     if ( image.HasMask() )
         SetMask( new wxMask( *this , wxColour( image.GetMaskRed() , image.GetMaskGreen() , image.GetMaskBlue() ) ) ) ;
 }
@@ -1116,7 +1200,7 @@ wxImage wxBitmap::ConvertToImage() const
     unsigned char *data = image.GetData();
     wxCHECK_MSG( data, wxNullImage, wxT("Could not allocate data for image") );
 
-    unsigned char* source = (unsigned char*) GetRawAccess() ;
+    unsigned char* sourcestart = (unsigned char*) GetRawAccess() ;
 
     bool hasAlpha = false ;
     bool hasMask = false ;
@@ -1150,9 +1234,10 @@ wxImage wxBitmap::ConvertToImage() const
     static const int MASK_BLUE = 3;
     static const int MASK_BLUE_REPLACEMENT = 2;
 
-    for (int yy = 0; yy < height; yy++ , mask += maskBytesPerRow )
+    for (int yy = 0; yy < height; yy++ , sourcestart += M_BITMAPDATA->GetBytesPerRow() , mask += maskBytesPerRow )
     {
         unsigned char * maskp = mask ;
+        unsigned char * source = sourcestart;
         unsigned char a, r, g, b;
         long color;
 
@@ -1180,13 +1265,20 @@ wxImage wxBitmap::ConvertToImage() const
                 }
                 else if ( r == MASK_RED && g == MASK_GREEN && b == MASK_BLUE )
                     b = MASK_BLUE_REPLACEMENT ;
-
-                maskp++ ;
-                maskp++ ;
-                maskp++ ;
             }
             else if ( hasAlpha )
+            {
                 *alpha++ = a ;
+#if wxMAC_USE_PREMULTIPLIED_ALPHA
+                // this must be non-premultiplied data
+                if ( a != 0xFF && a!= 0 )
+                {
+                    r = r * 255 / a;
+                    g = g * 255 / a;
+                    b = b * 255 / a;
+                }
+#endif
+            }
 
             data[index    ] = r ;
             data[index + 1] = g ;
@@ -1254,17 +1346,6 @@ int wxBitmap::GetDepth() const
    return M_BITMAPDATA->GetDepth();
 }
 
-#if WXWIN_COMPATIBILITY_2_4
-int wxBitmap::GetQuality() const
-{
-    return 0;
-}
-
-void wxBitmap::SetQuality(int WXUNUSED(quality))
-{
-}
-#endif
-
 wxMask *wxBitmap::GetMask() const
 {
    wxCHECK_MSG( Ok(), (wxMask *) NULL, wxT("invalid bitmap") );
@@ -1329,7 +1410,9 @@ void wxBitmap::SetMask(wxMask *mask)
 
 WXHBITMAP wxBitmap::GetHBITMAP(WXHBITMAP* mask) const
 {
-    return WXHBITMAP(M_BITMAPDATA->GetHBITMAP((GWorldPtr*)mask));
+    wxUnusedVar(mask);
+
+    return WXHBITMAP(M_BITMAPDATA->GetBitmapContext());
 }
 
 // ----------------------------------------------------------------------------
@@ -1341,6 +1424,22 @@ wxMask::wxMask()
     Init() ;
 }
 
+wxMask::wxMask(const wxMask &tocopy)
+{
+    Init();
+
+    m_bytesPerRow = tocopy.m_bytesPerRow;
+    m_width = tocopy.m_width;
+    m_height = tocopy.m_height;
+
+    size_t size = m_bytesPerRow * m_height;
+    unsigned char* dest = (unsigned char*)m_memBuf.GetWriteBuf( size );
+    unsigned char* source = (unsigned char*)tocopy.m_memBuf.GetData();
+    memcpy( dest, source, size );
+    m_memBuf.UngetWriteBuf( size ) ;
+    RealizeNative() ;
+}
+
 // Construct a mask from a bitmap and a colour indicating
 // the transparent area
 wxMask::wxMask( const wxBitmap& bitmap, const wxColour& colour )
@@ -1366,13 +1465,11 @@ wxMask::wxMask( const wxMemoryBuffer& data, int width , int height , int bytesPe
 
 wxMask::~wxMask()
 {
-#ifndef __LP64__
     if ( m_maskBitmap )
     {
-        DisposeGWorld( (GWorldPtr)m_maskBitmap ) ;
+        CGContextRelease( (CGContextRef) m_maskBitmap );
         m_maskBitmap = NULL ;
     }
-#endif
 }
 
 void wxMask::Init()
@@ -1391,20 +1488,21 @@ void *wxMask::GetRawAccess() const
 
 void wxMask::RealizeNative()
 {
-#ifndef __LP64__
     if ( m_maskBitmap )
     {
-       DisposeGWorld( (GWorldPtr)m_maskBitmap ) ;
+        CGContextRelease( (CGContextRef) m_maskBitmap );
        m_maskBitmap = NULL ;
     }
 
-    Rect rect = { 0 , 0 , m_height , m_width } ;
-
-    OSStatus err = NewGWorldFromPtr(
-        (GWorldPtr*) &m_maskBitmap , k32ARGBPixelFormat , &rect , NULL , NULL , 0 ,
-        (char*) m_memBuf.GetData() , m_bytesPerRow ) ;
-    verify_noerr( err ) ;
-#endif
+    CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceGray();
+    // from MouseTracking sample :
+    // Ironically, due to a bug in CGImageCreateWithMask, you cannot use 
+    // CGColorSpaceCreateWithName(kCGColorSpaceGenericGray) at this point!
+    
+    m_maskBitmap = CGBitmapContextCreate((char*) m_memBuf.GetData(), m_width, m_height, 8, m_bytesPerRow, colorspace, 
+        kCGImageAlphaNone );
+    CGColorSpaceRelease( colorspace );
+    wxASSERT_MSG( m_maskBitmap , wxT("Unable to create CGBitmapContext context") ) ;
 }
 
 // Create a mask from a mono bitmap (copies the bitmap).
@@ -1428,7 +1526,7 @@ bool wxMask::Create(const wxBitmap& bitmap)
 {
     m_width = bitmap.GetWidth() ;
     m_height = bitmap.GetHeight() ;
-    m_bytesPerRow = ( m_width * 4 + 3 ) & 0xFFFFFFC ;
+    m_bytesPerRow = GetBestBytesPerRow( m_width * kMaskBytesPerPixel ) ;
 
     size_t size = m_bytesPerRow * m_height ;
     unsigned char * destdatabase = (unsigned char*) m_memBuf.GetWriteBuf( size ) ;
@@ -1450,19 +1548,9 @@ bool wxMask::Create(const wxBitmap& bitmap)
             b = *srcdata++ ;
 
             if ( ( r + g + b ) > 0x10 )
-            {
-                *destdata++ = 0xFF ;
                 *destdata++ = 0xFF ;
-                *destdata++ = 0xFF ;
-                *destdata++ = 0xFF ;
-            }
             else
-            {
                 *destdata++ = 0x00 ;
-                *destdata++ = 0x00 ;
-                *destdata++ = 0x00 ;
-                *destdata++ = 0x00 ;
-            }
         }
     }
 
@@ -1478,17 +1566,19 @@ bool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour)
 {
     m_width = bitmap.GetWidth() ;
     m_height = bitmap.GetHeight() ;
-    m_bytesPerRow = ( m_width * 4 + 3 ) & 0xFFFFFFC ;
+    m_bytesPerRow = GetBestBytesPerRow( m_width * kMaskBytesPerPixel ) ;
 
     size_t size = m_bytesPerRow * m_height ;
     unsigned char * destdatabase = (unsigned char*) m_memBuf.GetWriteBuf( size ) ;
     wxASSERT( destdatabase != NULL ) ;
 
     memset( destdatabase , 0 , size ) ;
-    unsigned char * srcdata = (unsigned char*) bitmap.GetRawAccess() ;
+    unsigned char * srcdatabase = (unsigned char*) bitmap.GetRawAccess() ;
+    size_t sourceBytesRow = bitmap.GetBitmapData()->GetBytesPerRow();
 
-    for ( int y = 0 ; y < m_height ; ++y , destdatabase += m_bytesPerRow)
+    for ( int y = 0 ; y < m_height ; ++y , srcdatabase+= sourceBytesRow, destdatabase += m_bytesPerRow)
     {
+        unsigned char *srcdata = srcdatabase ;
         unsigned char *destdata = destdatabase ;
         unsigned char r, g, b;
 
@@ -1500,19 +1590,9 @@ bool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour)
             b = *srcdata++ ;
 
             if ( colour == wxColour( r , g , b ) )
-            {
-                *destdata++ = 0xFF ;
-                *destdata++ = 0xFF ;
                 *destdata++ = 0xFF ;
-                *destdata++ = 0xFF ;
-            }
             else
-            {
-                *destdata++ = 0x00 ;
                 *destdata++ = 0x00 ;
-                *destdata++ = 0x00 ;
-                *destdata++ = 0x00 ;
-            }
         }
     }
 
@@ -1537,6 +1617,8 @@ IMPLEMENT_ABSTRACT_CLASS(wxBitmapHandler, wxBitmapHandlerBase)
 // Standard Handlers
 // ----------------------------------------------------------------------------
 
+#ifndef __LP64__
+
 class WXDLLEXPORT wxPICTResourceHandler: public wxBitmapHandler
 {
     DECLARE_DYNAMIC_CLASS(wxPICTResourceHandler)
@@ -1556,8 +1638,11 @@ public:
 IMPLEMENT_DYNAMIC_CLASS(wxPICTResourceHandler, wxBitmapHandler)
 
 
-bool wxPICTResourceHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
-          int desiredWidth, int desiredHeight)
+bool wxPICTResourceHandler::LoadFile(wxBitmap *bitmap,
+                                     const wxString& name,
+                                     long WXUNUSED(flags),
+                                     int WXUNUSED(desiredWidth),
+                                     int WXUNUSED(desiredHeight))
 {
 #if wxUSE_METAFILE
     Str255 theName ;
@@ -1568,7 +1653,7 @@ bool wxPICTResourceHandler::LoadFile(wxBitmap *bitmap, const wxString& name, lon
     {
         wxMetafile mf ;
 
-        mf.SetHMETAFILE( (WXHMETAFILE) thePict ) ;
+        mf.SetPICT( thePict ) ;
         bitmap->Create( mf.GetWidth() , mf.GetHeight() ) ;
         wxMemoryDC dc ;
         dc.SelectObject( *bitmap ) ;
@@ -1581,10 +1666,13 @@ bool wxPICTResourceHandler::LoadFile(wxBitmap *bitmap, const wxString& name, lon
 
     return false ;
 }
+#endif
 
 void wxBitmap::InitStandardHandlers()
 {
+#ifndef __LP64__
     AddHandler( new wxPICTResourceHandler ) ;
+#endif
     AddHandler( new wxICONResourceHandler ) ;
 }
 
@@ -1592,7 +1680,7 @@ void wxBitmap::InitStandardHandlers()
 // raw bitmap access support
 // ----------------------------------------------------------------------------
 
-void *wxBitmap::GetRawData(wxPixelDataBase& data, int bpp)
+void *wxBitmap::GetRawData(wxPixelDataBase& data, int WXUNUSED(bpp))
 {
     if ( !Ok() )
         // no bitmap, no data (raw or otherwise)
@@ -1600,12 +1688,12 @@ void *wxBitmap::GetRawData(wxPixelDataBase& data, int bpp)
 
     data.m_width = GetWidth() ;
     data.m_height = GetHeight() ;
-    data.m_stride = GetWidth() * 4 ;
+    data.m_stride = GetBitmapData()->GetBytesPerRow() ;
 
     return BeginRawAccess() ;
 }
 
-void wxBitmap::UngetRawData(wxPixelDataBase& dataBase)
+void wxBitmap::UngetRawData(wxPixelDataBase& WXUNUSED(dataBase))
 {
     EndRawAccess() ;
 }