]> git.saurik.com Git - wxWidgets.git/blobdiff - src/mac/carbon/bitmap.cpp
compositing and transition changes
[wxWidgets.git] / src / mac / carbon / bitmap.cpp
index 7d2223a0e298dccf2766d20921eac56893d498e6..84b1bae5c183f31d850e1291b5caa07608c6d69b 100644 (file)
@@ -366,6 +366,7 @@ wxBitmapRefData::wxBitmapRefData()
     m_hPict = NULL ;
     m_hIcon = NULL ;
     m_bitmapType = kMacBitmapTypeUnknownType ;
+    m_hasAlpha = false;
 }
 
 // TODO move this to a public function of Bitmap Ref
@@ -444,7 +445,7 @@ wxBitmap::wxBitmap(const char bits[], int the_width, int the_height, int no_bits
     if ( no_bits == 1 )
     {
         M_BITMAPDATA->m_bitmapType = kMacBitmapTypeGrafWorld ;
-        MAC_WXHBITMAP(M_BITMAPDATA->m_hBitmap) = wxMacCreateGWorld( the_width , the_height , no_bits ) ;
+        M_BITMAPDATA->m_hBitmap = wxMacCreateGWorld( the_width , the_height , no_bits ) ;
         M_BITMAPDATA->m_ok = (MAC_WXHBITMAP(M_BITMAPDATA->m_hBitmap) != NULL ) ;
 
         CGrafPtr    origPort ;
@@ -1051,8 +1052,7 @@ void wxBitmap::SetMask(wxMask *mask)
         m_refData = new wxBitmapRefData;
 
     // Remove existing mask if there is one.
-    if (M_BITMAPDATA->m_bitmapMask)
-        delete M_BITMAPDATA->m_bitmapMask;
+    delete M_BITMAPDATA->m_bitmapMask;
 
     M_BITMAPDATA->m_bitmapMask = mask ;
 }
@@ -1150,7 +1150,7 @@ bool wxMask::Create(const wxBitmap& bitmap)
 
    wxCHECK_MSG( bitmap.Ok(), false, wxT("Invalid bitmap"));
 
-    m_depth = bitmap.GetDepth() ;
+   m_depth = bitmap.GetDepth() ;
    m_maskBitmap = wxMacCreateGWorld(bitmap.GetWidth(), bitmap.GetHeight(), bitmap.GetDepth() );
    Rect rect = { 0,0, bitmap.GetHeight(), bitmap.GetWidth() };
 
@@ -1349,14 +1349,11 @@ void *wxBitmap::GetRawData(wxPixelDataBase& data, int bpp)
 
    GWorldPtr gworld = MAC_WXHBITMAP(M_BITMAPDATA->m_hBitmap);
    PixMapHandle hPixMap = GetGWorldPixMap(gworld);
-   wxCHECK_MSG( hPixMap, NULL, _T("failed to get PixMap from GWorld?") );
+   wxCHECK_MSG( hPixMap && *hPixMap, NULL,
+                    _T("GetRawData(): failed to get PixMap from GWorld?") );
 
-   if ( (*hPixMap)->pixelSize != bpp )
-   {
-       wxFAIL_MSG( _T("bpp mismatch in GetRawData()") );
-
-       return NULL;
-   }
+   wxCHECK_MSG( (*hPixMap)->pixelSize == bpp, NULL,
+                    _T("GetRawData(): pixel format mismatch") );
 
    if ( !LockPixels(hPixMap) )
    {
@@ -1369,22 +1366,67 @@ void *wxBitmap::GetRawData(wxPixelDataBase& data, int bpp)
    data.m_height = GetHeight();
    data.m_stride = (*hPixMap)->rowBytes & 0x7fff;
 
+   M_BITMAPDATA->m_hasAlpha = false;
+
    return GetPixBaseAddr(hPixMap);
 }
 
-void wxBitmap::UngetRawData(wxPixelDataBase& data)
+void wxBitmap::UngetRawData(wxPixelDataBase& dataBase)
 {
     if ( !Ok() )
         return;
 
+    if ( M_BITMAPDATA->m_hasAlpha )
+    {
+        wxAlphaPixelData& data = (wxAlphaPixelData&)dataBase;
+
+        int w = data.GetWidth(),
+            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,
+                                       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));
+    }
+
     GWorldPtr gworld = MAC_WXHBITMAP(M_BITMAPDATA->m_hBitmap);
     PixMapHandle hPixMap = GetGWorldPixMap(gworld);
     if ( hPixMap )
+    {
         UnlockPixels(hPixMap);
+    }
 }
 
 void wxBitmap::UseAlpha()
 {
-    // nothing to do here so far
+    // remember that we are using alpha channel, we'll need to create a proper
+    // mask in UngetRawData()
+    M_BITMAPDATA->m_hasAlpha = true;
 }