]> git.saurik.com Git - wxWidgets.git/commitdiff
implemented alpha support for raw bitmaps under Mac
authorVadim Zeitlin <vadim@wxwidgets.org>
Sat, 14 Jun 2003 12:57:44 +0000 (12:57 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sat, 14 Jun 2003 12:57:44 +0000 (12:57 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@21145 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/mac/bitmap.h
include/wx/rawbmp.h
src/mac/bitmap.cpp
src/mac/carbon/bitmap.cpp

index 0a0537bb6f50724f0248d08c732943fd07e2cba8..27a729ccc975b2e3375bf26592aadd28dcfae925 100644 (file)
@@ -94,6 +94,7 @@ public:
   WXHBITMAP     m_hBitmap;
   WXHICON       m_hIcon ;
   wxMask *      m_bitmapMask; // Optional mask
   WXHBITMAP     m_hBitmap;
   WXHICON       m_hIcon ;
   wxMask *      m_bitmapMask; // Optional mask
+  bool          m_hasAlpha;
 };
 
 #define M_BITMAPDATA ((wxBitmapRefData *)m_refData)
 };
 
 #define M_BITMAPDATA ((wxBitmapRefData *)m_refData)
@@ -199,7 +200,7 @@ public:
 
   static void InitStandardHandlers();
 
 
   static void InitStandardHandlers();
 
-    // raw bitmap access support functions
+    // raw bitmap access support functions, for internal use only
     void *GetRawData(wxPixelDataBase& data, int bpp);
     void UngetRawData(wxPixelDataBase& data);
 
     void *GetRawData(wxPixelDataBase& data, int bpp);
     void UngetRawData(wxPixelDataBase& data);
 
index 4edf2cd9740069893d77a27e0d88af37658b01a0..8e74712b0c839076c313b9c0e12f3300c8a5920c 100644 (file)
@@ -196,6 +196,8 @@ public:
     int GetWidth() const { return m_width; }
     int GetHeight() const { return m_height; }
 
     int GetWidth() const { return m_width; }
     int GetHeight() const { return m_height; }
 
+    wxSize GetSize() const { return wxSize(m_width, m_height); }
+
     // the distance between two rows
     int GetRowStride() const { return m_stride; }
 
     // the distance between two rows
     int GetRowStride() const { return m_stride; }
 
@@ -567,10 +569,9 @@ struct WXDLLEXPORT wxPixelDataOut<wxBitmap>
 
         // private: -- see comment in the beginning of the file
 
 
         // private: -- see comment in the beginning of the file
 
-            // NB: for efficiency reasons this class must *not* have any other
-            //     fields, otherwise it won't be put into a CPU register (as it
-            //     should inside the inner loops) by some compilers, notably
-            //     gcc
+            // for efficiency reasons this class should not have any other
+            // fields, otherwise it won't be put into a CPU register (as it
+            // should inside the inner loops) by some compilers, notably gcc
             ChannelType *m_ptr;
         };
 
             ChannelType *m_ptr;
         };
 
index be836afd232c72d0276dfc421425175f8785188b..7ef70887d623c316d3b79f42610d43c03c3ee2e1 100644 (file)
@@ -366,6 +366,7 @@ wxBitmapRefData::wxBitmapRefData()
     m_hPict = NULL ;
     m_hIcon = NULL ;
     m_bitmapType = kMacBitmapTypeUnknownType ;
     m_hPict = NULL ;
     m_hIcon = NULL ;
     m_bitmapType = kMacBitmapTypeUnknownType ;
+    m_hasAlpha = false;
 }
 
 // TODO move this to a public function of Bitmap Ref
 }
 
 // TODO move this to a public function of Bitmap Ref
@@ -1051,8 +1052,7 @@ void wxBitmap::SetMask(wxMask *mask)
         m_refData = new wxBitmapRefData;
 
     // Remove existing mask if there is one.
         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 ;
 }
 
     M_BITMAPDATA->m_bitmapMask = mask ;
 }
@@ -1150,7 +1150,7 @@ bool wxMask::Create(const wxBitmap& bitmap)
 
    wxCHECK_MSG( bitmap.Ok(), false, wxT("Invalid 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() };
 
    m_maskBitmap = wxMacCreateGWorld(bitmap.GetWidth(), bitmap.GetHeight(), bitmap.GetDepth() );
    Rect rect = { 0,0, bitmap.GetHeight(), bitmap.GetWidth() };
 
@@ -1366,14 +1366,55 @@ void *wxBitmap::GetRawData(wxPixelDataBase& data, int bpp)
    data.m_height = GetHeight();
    data.m_stride = (*hPixMap)->rowBytes & 0x7fff;
 
    data.m_height = GetHeight();
    data.m_stride = (*hPixMap)->rowBytes & 0x7fff;
 
+   M_BITMAPDATA->m_hasAlpha = false;
+
    return GetPixBaseAddr(hPixMap);
 }
 
    return GetPixBaseAddr(hPixMap);
 }
 
-void wxBitmap::UngetRawData(wxPixelDataBase& data)
+void wxBitmap::UngetRawData(wxPixelDataBase& dataBase)
 {
     if ( !Ok() )
         return;
 
 {
     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 )
     GWorldPtr gworld = MAC_WXHBITMAP(M_BITMAPDATA->m_hBitmap);
     PixMapHandle hPixMap = GetGWorldPixMap(gworld);
     if ( hPixMap )
@@ -1384,6 +1425,8 @@ void wxBitmap::UngetRawData(wxPixelDataBase& data)
 
 void wxBitmap::UseAlpha()
 {
 
 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;
 }
 
 }
 
index be836afd232c72d0276dfc421425175f8785188b..7ef70887d623c316d3b79f42610d43c03c3ee2e1 100644 (file)
@@ -366,6 +366,7 @@ wxBitmapRefData::wxBitmapRefData()
     m_hPict = NULL ;
     m_hIcon = NULL ;
     m_bitmapType = kMacBitmapTypeUnknownType ;
     m_hPict = NULL ;
     m_hIcon = NULL ;
     m_bitmapType = kMacBitmapTypeUnknownType ;
+    m_hasAlpha = false;
 }
 
 // TODO move this to a public function of Bitmap Ref
 }
 
 // TODO move this to a public function of Bitmap Ref
@@ -1051,8 +1052,7 @@ void wxBitmap::SetMask(wxMask *mask)
         m_refData = new wxBitmapRefData;
 
     // Remove existing mask if there is one.
         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 ;
 }
 
     M_BITMAPDATA->m_bitmapMask = mask ;
 }
@@ -1150,7 +1150,7 @@ bool wxMask::Create(const wxBitmap& bitmap)
 
    wxCHECK_MSG( bitmap.Ok(), false, wxT("Invalid 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() };
 
    m_maskBitmap = wxMacCreateGWorld(bitmap.GetWidth(), bitmap.GetHeight(), bitmap.GetDepth() );
    Rect rect = { 0,0, bitmap.GetHeight(), bitmap.GetWidth() };
 
@@ -1366,14 +1366,55 @@ void *wxBitmap::GetRawData(wxPixelDataBase& data, int bpp)
    data.m_height = GetHeight();
    data.m_stride = (*hPixMap)->rowBytes & 0x7fff;
 
    data.m_height = GetHeight();
    data.m_stride = (*hPixMap)->rowBytes & 0x7fff;
 
+   M_BITMAPDATA->m_hasAlpha = false;
+
    return GetPixBaseAddr(hPixMap);
 }
 
    return GetPixBaseAddr(hPixMap);
 }
 
-void wxBitmap::UngetRawData(wxPixelDataBase& data)
+void wxBitmap::UngetRawData(wxPixelDataBase& dataBase)
 {
     if ( !Ok() )
         return;
 
 {
     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 )
     GWorldPtr gworld = MAC_WXHBITMAP(M_BITMAPDATA->m_hBitmap);
     PixMapHandle hPixMap = GetGWorldPixMap(gworld);
     if ( hPixMap )
@@ -1384,6 +1425,8 @@ void wxBitmap::UngetRawData(wxPixelDataBase& data)
 
 void wxBitmap::UseAlpha()
 {
 
 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;
 }
 
 }