]> git.saurik.com Git - wxWidgets.git/blobdiff - src/mac/carbon/bitmap.cpp
Updated list of subprojects.
[wxWidgets.git] / src / mac / carbon / bitmap.cpp
index 9789fa598a07c9bdee9a80efb1753aeced524d96..42031fe4ab52db3709267ac7abaa5f6dc74986bb 100644 (file)
@@ -1,5 +1,5 @@
 /////////////////////////////////////////////////////////////////////////////
-// Name:        bitmap.cpp
+// Name:        src/mac/carbon/bitmap.cpp
 // Purpose:     wxBitmap
 // Author:      Stefan Csomor
 // Modified by:
 #include "wx/wxprec.h"
 
 #include "wx/bitmap.h"
-#include "wx/icon.h"
-#include "wx/log.h"
-#include "wx/image.h"
+
+#ifndef WX_PRECOMP
+    #include "wx/log.h"
+    #include "wx/dcmemory.h"
+    #include "wx/icon.h"
+    #include "wx/image.h"
+#endif
+
 #include "wx/metafile.h"
 #include "wx/xpmdecod.h"
 
@@ -22,7 +27,6 @@
 
 IMPLEMENT_DYNAMIC_CLASS(wxBitmap, wxGDIObject)
 IMPLEMENT_DYNAMIC_CLASS(wxMask, wxObject)
-IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler, wxObject)
 
 #ifdef __DARWIN__
     #include <ApplicationServices/ApplicationServices.h>
@@ -31,7 +35,6 @@ IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler, wxObject)
 #endif
 
 #include "wx/mac/uma.h"
-#include "wx/dcmemory.h"
 
 // Implementation Notes
 // --------------------
@@ -90,8 +93,10 @@ void wxMacCreateBitmapButton( ControlButtonContentInfo*info , const wxBitmap& bi
 #endif
         else
         {
+#ifndef __LP64__
             info->contentType = kControlContentPictHandle ;
             info->u.picture = bmap->GetPictHandle() ;
+#endif
         }
     }
 }
@@ -161,8 +166,8 @@ wxBitmapRefData::wxBitmapRefData( int w , int h , int d )
 
 bool wxBitmapRefData::Create( int w , int h , int d )
 {
-    m_width = w ;
-    m_height = ;
+    m_width = wxMax(1, w);
+    m_height = wxMax(1, h);
     m_depth = d ;
 
     m_bytesPerRow = w * 4 ;
@@ -173,10 +178,11 @@ bool wxBitmapRefData::Create( int w , int h , int d )
 
     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_ok = ( m_hBitmap != NULL ) ;
 
     return m_ok ;
@@ -201,9 +207,11 @@ void wxBitmapRefData::UseAlpha( bool use )
 
         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
@@ -212,7 +220,9 @@ void wxBitmapRefData::UseAlpha( bool use )
     }
     else
     {
+#ifndef __LP64__
         DisposeGWorld( m_hMaskBitmap ) ;
+#endif
         m_hMaskBitmap = NULL ;
         m_maskBytesPerRow = 0 ;
     }
@@ -367,6 +377,7 @@ IconRef wxBitmapRefData::GetIconRef()
                         *maskdest++ = 0xFF - *masksource++ ;
                         masksource++ ;
                         masksource++ ;
+                        masksource++ ;
                     }
                     else if ( hasAlpha )
                         *maskdest++ = a ;
@@ -391,9 +402,14 @@ IconRef wxBitmapRefData::GetIconRef()
             PicHandle pic = GetPictHandle() ;
             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 ) ;
@@ -402,8 +418,9 @@ IconRef wxBitmapRefData::GetIconRef()
         // we have to retain a reference, as Unregister will decrement it
         AcquireIconRef( m_iconRef ) ;
         UnregisterIconRef( 'WXNG' , (OSType) iconCounter ) ;
-        DisposeHandle( (Handle) iconFamily ) ;
         ++iconCounter ;
+#endif
+        DisposeHandle( (Handle) iconFamily ) ;
     }
 
     return m_iconRef ;
@@ -413,6 +430,7 @@ PicHandle wxBitmapRefData::GetPictHandle()
 {
     if ( m_pictHandle == NULL )
     {
+#ifndef __LP64__
         CGrafPtr origPort = NULL ;
         GDHandle origDev = NULL ;
         GWorldPtr wp = NULL ;
@@ -482,6 +500,7 @@ PicHandle wxBitmapRefData::GetPictHandle()
         SetGWorld( origPort , origDev ) ;
         if ( clipRgn )
             DisposeRgn( clipRgn ) ;
+#endif
     }
 
     return m_pictHandle ;
@@ -522,7 +541,7 @@ CGImageRef wxBitmapRefData::CGImageCreate() const
             for ( int y = 0 ; y < h ; ++y , sourcemaskstart += maskrowbytes)
             {
                 unsigned char *sourcemask = sourcemaskstart ;
-                for ( int x = 0 ; x < w ; ++x , sourcemask+=3 , destalpha += 4 )
+                for ( int x = 0 ; x < w ; ++x , sourcemask += 4 , destalpha += 4 )
                 {
                     *destalpha = 0xFF - *sourcemask ;
                 }
@@ -541,16 +560,38 @@ CGImageRef wxBitmapRefData::CGImageCreate() const
 
             membuf = new wxMemoryBuffer( m_memBuf ) ;
         }
-
-        CGColorSpaceRef colorSpace = wxMacGetGenericRGBColorSpace();
-        CGDataProviderRef dataProvider =
-            CGDataProviderCreateWithData(
-                membuf , (const void *)membuf->GetData() , imageSize,
-                wxMacMemoryBufferReleaseProc );
-        image =
+        
+        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 );
+        }
         CGDataProviderRelease( dataProvider);
     }
     else
@@ -642,6 +683,7 @@ void wxBitmapRefData::Free()
         m_iconRef = NULL ;
     }
 
+#ifndef __LP64__
     if ( m_pictHandle )
     {
         KillPicture( m_pictHandle ) ;
@@ -659,7 +701,7 @@ void wxBitmapRefData::Free()
         DisposeGWorld( MAC_WXHBITMAP(m_hMaskBitmap) ) ;
         m_hMaskBitmap = NULL ;
     }
-
+#endif
     if (m_bitmapMask)
     {
         delete m_bitmapMask;
@@ -831,7 +873,7 @@ wxBitmap::wxBitmap(int w, int h, int d)
     (void)Create(w, h, d);
 }
 
-wxBitmap::wxBitmap(void *data, wxBitmapType type, int width, int height, int depth)
+wxBitmap::wxBitmap(const void* data, wxBitmapType type, int width, int height, int depth)
 {
     (void) Create(data, type, width, height, depth);
 }
@@ -841,16 +883,6 @@ wxBitmap::wxBitmap(const wxString& filename, wxBitmapType type)
     LoadFile(filename, type);
 }
 
-wxBitmap::wxBitmap(const char **bits)
-{
-    (void) CreateFromXpm(bits);
-}
-
-wxBitmap::wxBitmap(char **bits)
-{
-    (void) CreateFromXpm((const char **)bits);
-}
-
 void * wxBitmap::GetRawAccess() const
 {
     wxCHECK_MSG( Ok() , NULL , wxT("invalid bitmap") ) ;
@@ -872,24 +904,6 @@ void wxBitmap::EndRawAccess()
     M_BITMAPDATA->EndRawAccess() ;
 }
 
-bool wxBitmap::CreateFromXpm(const char **bits)
-{
-#if wxUSE_IMAGE
-    wxCHECK_MSG( bits != NULL, false, wxT("invalid bitmap data") )
-
-    wxXPMDecoder decoder;
-    wxImage img = decoder.ReadData(bits);
-    wxCHECK_MSG( img.Ok(), false, wxT("invalid bitmap data") )
-
-    *this = wxBitmap(img);
-
-    return true;
-#else
-
-    return false;
-#endif
-}
-
 #ifdef __WXMAC_OSX__
 WXCGIMAGEREF wxBitmap::CGImageCreate() const
 {
@@ -935,7 +949,7 @@ wxBitmap wxBitmap::GetSubBitmap(const wxRect &rect) const
     if ( M_BITMAPDATA->m_bitmapMask )
     {
         wxMemoryBuffer maskbuf ;
-        int rowBytes = ( destwidth + 3 ) & 0xFFFFFFC ;
+        int rowBytes = ( destwidth * 4 + 3 ) & 0xFFFFFFC ;
         size_t maskbufsize = rowBytes * destheight ;
 
         int sourcelinesize = M_BITMAPDATA->m_bitmapMask->GetBytesPerRow() ;
@@ -945,13 +959,12 @@ wxBitmap wxBitmap::GetSubBitmap(const wxRect &rect) const
         unsigned char *destdata = (unsigned char * ) maskbuf.GetWriteBuf( maskbufsize ) ;
         wxASSERT( (source != NULL) && (destdata != NULL) ) ;
 
-        source += rect.x * 3 + rect.y * sourcelinesize ;
+        source += rect.x * 4 + rect.y * sourcelinesize ;
         unsigned char *dest = destdata ;
 
         for (int yy = 0; yy < destheight; ++yy, source += sourcelinesize , dest += destlinesize)
         {
-            for (int xx = 0; xx < destlinesize; xx++ )
-                *(dest+xx) = 0xFF - *(source+xx*3) ;
+            memcpy( dest , source , destlinesize ) ;
         }
 
         maskbuf.UngetWriteBuf( maskbufsize ) ;
@@ -1005,7 +1018,7 @@ bool wxBitmap::LoadFile(const wxString& filename, wxBitmapType type)
     return false;
 }
 
-bool wxBitmap::Create(void *data, wxBitmapType type, int width, int height, int depth)
+bool wxBitmap::Create(const void* data, wxBitmapType type, int width, int height, int depth)
 {
     UnRef();
 
@@ -1027,7 +1040,7 @@ bool wxBitmap::Create(void *data, wxBitmapType type, int width, int height, int
 
 wxBitmap::wxBitmap(const wxImage& image, int depth)
 {
-    wxCHECK_RET( image.Ok(), wxT("invalid image") )
+    wxCHECK_RET( image.Ok(), wxT("invalid image") );
 
     // width and height of the device-dependent bitmap
     int width = image.GetWidth();
@@ -1146,11 +1159,17 @@ wxImage wxBitmap::ConvertToImage() const
         for (int xx = 0; xx < width; xx++)
         {
             color = *((long*) source) ;
+#ifdef WORDS_BIGENDIAN
             a = ((color&0xFF000000) >> 24) ;
             r = ((color&0x00FF0000) >> 16) ;
             g = ((color&0x0000FF00) >> 8) ;
             b = (color&0x000000FF);
-
+#else
+            b = ((color&0xFF000000) >> 24) ;
+            g = ((color&0x00FF0000) >> 16) ;
+            r = ((color&0x0000FF00) >> 8) ;
+            a = (color&0x000000FF);
+#endif
             if ( hasMask )
             {
                 if ( *maskp++ == 0xFF )
@@ -1164,6 +1183,7 @@ wxImage wxBitmap::ConvertToImage() const
 
                 maskp++ ;
                 maskp++ ;
+                maskp++ ;
             }
             else if ( hasAlpha )
                 *alpha++ = a ;
@@ -1208,7 +1228,7 @@ bool wxBitmap::SaveFile( const wxString& filename,
     return success;
 }
 
-bool wxBitmap::Ok() const
+bool wxBitmap::IsOk() const
 {
    return (M_BITMAPDATA && M_BITMAPDATA->Ok());
 }
@@ -1349,6 +1369,7 @@ wxMask::wxMask( const wxBitmap& bitmap )
 }
 
 // Construct a mask from a mono bitmap (copies the bitmap).
+
 wxMask::wxMask( const wxMemoryBuffer& data, int width , int height , int bytesPerRow )
 {
     Init() ;
@@ -1357,11 +1378,13 @@ wxMask::wxMask( const wxMemoryBuffer& data, int width , int height , int bytesPe
 
 wxMask::~wxMask()
 {
+#ifndef __LP64__
     if ( m_maskBitmap )
     {
         DisposeGWorld( (GWorldPtr)m_maskBitmap ) ;
         m_maskBitmap = NULL ;
     }
+#endif
 }
 
 void wxMask::Init()
@@ -1380,6 +1403,7 @@ void *wxMask::GetRawAccess() const
 
 void wxMask::RealizeNative()
 {
+#ifndef __LP64__
     if ( m_maskBitmap )
     {
        DisposeGWorld( (GWorldPtr)m_maskBitmap ) ;
@@ -1389,12 +1413,14 @@ void wxMask::RealizeNative()
     Rect rect = { 0 , 0 , m_height , m_width } ;
 
     OSStatus err = NewGWorldFromPtr(
-        (GWorldPtr*) &m_maskBitmap , k24RGBPixelFormat , &rect , NULL , NULL , 0 ,
+        (GWorldPtr*) &m_maskBitmap , k32ARGBPixelFormat , &rect , NULL , NULL , 0 ,
         (char*) m_memBuf.GetData() , m_bytesPerRow ) ;
     verify_noerr( err ) ;
+#endif
 }
 
 // Create a mask from a mono bitmap (copies the bitmap).
+
 bool wxMask::Create(const wxMemoryBuffer& data,int width , int height , int bytesPerRow)
 {
     m_memBuf = data ;
@@ -1414,7 +1440,7 @@ bool wxMask::Create(const wxBitmap& bitmap)
 {
     m_width = bitmap.GetWidth() ;
     m_height = bitmap.GetHeight() ;
-    m_bytesPerRow = ( m_width * 3 + 3 ) & 0xFFFFFFC ;
+    m_bytesPerRow = ( m_width * 4 + 3 ) & 0xFFFFFFC ;
 
     size_t size = m_bytesPerRow * m_height ;
     unsigned char * destdatabase = (unsigned char*) m_memBuf.GetWriteBuf( size ) ;
@@ -1440,12 +1466,14 @@ bool wxMask::Create(const wxBitmap& bitmap)
                 *destdata++ = 0xFF ;
                 *destdata++ = 0xFF ;
                 *destdata++ = 0xFF ;
+                *destdata++ = 0xFF ;
             }
             else
             {
                 *destdata++ = 0x00 ;
                 *destdata++ = 0x00 ;
                 *destdata++ = 0x00 ;
+                *destdata++ = 0x00 ;
             }
         }
     }
@@ -1462,7 +1490,7 @@ bool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour)
 {
     m_width = bitmap.GetWidth() ;
     m_height = bitmap.GetHeight() ;
-    m_bytesPerRow = ( m_width * 3 + 3 ) & 0xFFFFFFC ;
+    m_bytesPerRow = ( m_width * 4 + 3 ) & 0xFFFFFFC ;
 
     size_t size = m_bytesPerRow * m_height ;
     unsigned char * destdatabase = (unsigned char*) m_memBuf.GetWriteBuf( size ) ;
@@ -1488,12 +1516,14 @@ bool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour)
                 *destdata++ = 0xFF ;
                 *destdata++ = 0xFF ;
                 *destdata++ = 0xFF ;
+                *destdata++ = 0xFF ;
             }
             else
             {
                 *destdata++ = 0x00 ;
                 *destdata++ = 0x00 ;
                 *destdata++ = 0x00 ;
+                *destdata++ = 0x00 ;
             }
         }
     }
@@ -1513,25 +1543,7 @@ WXHBITMAP wxMask::GetHBITMAP() const
 // wxBitmapHandler
 // ----------------------------------------------------------------------------
 
-wxBitmapHandler::~wxBitmapHandler()
-{
-}
-
-bool wxBitmapHandler::Create(wxBitmap *bitmap, void *data, long type, int width, int height, int depth)
-{
-    return false;
-}
-
-bool wxBitmapHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
-        int desiredWidth, int desiredHeight)
-{
-    return false;
-}
-
-bool wxBitmapHandler::SaveFile(const wxBitmap *bitmap, const wxString& name, int type, const wxPalette *palette)
-{
-    return false;
-}
+IMPLEMENT_ABSTRACT_CLASS(wxBitmapHandler, wxBitmapHandlerBase)
 
 // ----------------------------------------------------------------------------
 // Standard Handlers
@@ -1602,53 +1614,12 @@ void *wxBitmap::GetRawData(wxPixelDataBase& data, int bpp)
     data.m_height = GetHeight() ;
     data.m_stride = GetWidth() * 4 ;
 
-    return GetRawAccess() ;
+    return BeginRawAccess() ;
 }
 
 void wxBitmap::UngetRawData(wxPixelDataBase& dataBase)
 {
-    if ( !Ok() )
-        return;
-
-    // TODO: if we have some information about the API we should check
-    // this code looks strange...
-
-    if ( !M_BITMAPDATA->HasAlpha() )
-        return;
-
-    wxAlphaPixelData& data = (wxAlphaPixelData&)dataBase;
-    int w = data.GetWidth();
-    int h = data.GetHeight();
-
-    wxBitmap bmpMask( GetWidth(), GetHeight(), 32 );
-    wxAlphaPixelData dataMask( bmpMask, data.GetOrigin(), wxSize( w, h ) );
-    wxAlphaPixelData::Iterator pMask( dataMask ), p( data );
-
-    for ( int y = 0; y < h; y++ )
-    {
-        wxAlphaPixelData::Iterator rowStartMask = pMask;
-        wxAlphaPixelData::Iterator rowStart = p;
-
-        for ( int x = 0; x < w; x++ )
-        {
-            const wxAlphaPixelData::Iterator::ChannelType alpha = p.Alpha();
-
-            pMask.Red() = alpha;
-            pMask.Green() = alpha;
-            pMask.Blue() = alpha;
-
-            ++p;
-            ++pMask;
-        }
-
-        p = rowStart;
-        p.OffsetY( data, 1 );
-
-        pMask = rowStartMask;
-        pMask.OffsetY( dataMask, 1 );
-    }
-
-    SetMask( new wxMask( bmpMask ) );
+    EndRawAccess() ;
 }
 
 void wxBitmap::UseAlpha()