From: Vadim Zeitlin Date: Sat, 14 Jun 2003 12:57:44 +0000 (+0000) Subject: implemented alpha support for raw bitmaps under Mac X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/1e74d03b7f4dec5b7f254192541f72182c7558b9 implemented alpha support for raw bitmaps under Mac git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@21145 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/include/wx/mac/bitmap.h b/include/wx/mac/bitmap.h index 0a0537bb6f..27a729ccc9 100644 --- a/include/wx/mac/bitmap.h +++ b/include/wx/mac/bitmap.h @@ -94,6 +94,7 @@ public: WXHBITMAP m_hBitmap; WXHICON m_hIcon ; wxMask * m_bitmapMask; // Optional mask + bool m_hasAlpha; }; #define M_BITMAPDATA ((wxBitmapRefData *)m_refData) @@ -199,7 +200,7 @@ public: 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); diff --git a/include/wx/rawbmp.h b/include/wx/rawbmp.h index 4edf2cd974..8e74712b0c 100644 --- a/include/wx/rawbmp.h +++ b/include/wx/rawbmp.h @@ -196,6 +196,8 @@ public: 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; } @@ -567,10 +569,9 @@ struct WXDLLEXPORT wxPixelDataOut // 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; }; diff --git a/src/mac/bitmap.cpp b/src/mac/bitmap.cpp index be836afd23..7ef70887d6 100644 --- a/src/mac/bitmap.cpp +++ b/src/mac/bitmap.cpp @@ -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 @@ -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() }; @@ -1366,14 +1366,55 @@ 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 ) @@ -1384,6 +1425,8 @@ void wxBitmap::UngetRawData(wxPixelDataBase& data) 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; } diff --git a/src/mac/carbon/bitmap.cpp b/src/mac/carbon/bitmap.cpp index be836afd23..7ef70887d6 100644 --- a/src/mac/carbon/bitmap.cpp +++ b/src/mac/carbon/bitmap.cpp @@ -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 @@ -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() }; @@ -1366,14 +1366,55 @@ 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 ) @@ -1384,6 +1425,8 @@ void wxBitmap::UngetRawData(wxPixelDataBase& data) 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; }