allow overriding automatic alpha detection during icon->bitmap conversions (slightly modified patch 1738168)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@47629 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2007-07-21 22:56:07 +00:00
parent 313d9977bb
commit 11f406f91f
2 changed files with 68 additions and 34 deletions

View File

@@ -30,6 +30,15 @@ class WXDLLIMPEXP_FWD_CORE wxMask;
class WXDLLIMPEXP_FWD_CORE wxPalette; class WXDLLIMPEXP_FWD_CORE wxPalette;
class WXDLLIMPEXP_FWD_CORE wxPixelDataBase; class WXDLLIMPEXP_FWD_CORE wxPixelDataBase;
// What kind of transparency should a bitmap copied from an icon or cursor
// have?
enum wxBitmapTransparency
{
wxBitmapTransparency_Auto, // default: copy alpha if the source has it
wxBitmapTransparency_None, // never create alpha
wxBitmapTransparency_Always // always use alpha
};
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxBitmap: a mono or colour bitmap // wxBitmap: a mono or colour bitmap
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -80,7 +89,11 @@ public:
// we must have this, otherwise icons are silently copied into bitmaps using // we must have this, otherwise icons are silently copied into bitmaps using
// the copy ctor but the resulting bitmap is invalid! // the copy ctor but the resulting bitmap is invalid!
wxBitmap(const wxIcon& icon) { CopyFromIcon(icon); } wxBitmap(const wxIcon& icon,
wxBitmapTransparency transp = wxBitmapTransparency_Auto)
{
CopyFromIcon(icon, transp);
}
wxBitmap& operator=(const wxIcon& icon) wxBitmap& operator=(const wxIcon& icon)
{ {
@@ -106,10 +119,12 @@ public:
wxBitmap GetSubBitmap( const wxRect& rect ) const; wxBitmap GetSubBitmap( const wxRect& rect ) const;
// copies the contents and mask of the given (colour) icon to the bitmap // copies the contents and mask of the given (colour) icon to the bitmap
bool CopyFromIcon(const wxIcon& icon); bool CopyFromIcon(const wxIcon& icon,
wxBitmapTransparency transp = wxBitmapTransparency_Auto);
// copies the contents and mask of the given cursor to the bitmap // copies the contents and mask of the given cursor to the bitmap
bool CopyFromCursor(const wxCursor& cursor); bool CopyFromCursor(const wxCursor& cursor,
wxBitmapTransparency transp = wxBitmapTransparency_Auto);
#if wxUSE_WXDIB #if wxUSE_WXDIB
// copies from a device independent bitmap // copies from a device independent bitmap
@@ -175,7 +190,9 @@ protected:
private: private:
// common part of CopyFromIcon/CopyFromCursor for Win32 // common part of CopyFromIcon/CopyFromCursor for Win32
bool CopyFromIconOrCursor(const wxGDIImage& icon); bool
CopyFromIconOrCursor(const wxGDIImage& icon,
wxBitmapTransparency transp = wxBitmapTransparency_Auto);
DECLARE_DYNAMIC_CLASS(wxBitmap) DECLARE_DYNAMIC_CLASS(wxBitmap)

View File

@@ -289,9 +289,8 @@ wxObjectRefData *wxBitmap::CloneRefData(const wxObjectRefData *dataOrig) const
return m_refData; return m_refData;
} }
#ifdef __WIN32__ bool wxBitmap::CopyFromIconOrCursor(const wxGDIImage& icon,
wxBitmapTransparency transp)
bool wxBitmap::CopyFromIconOrCursor(const wxGDIImage& icon)
{ {
#if !defined(__WXMICROWIN__) && !defined(__WXWINCE__) #if !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
// it may be either HICON or HCURSOR // it may be either HICON or HCURSOR
@@ -317,31 +316,51 @@ bool wxBitmap::CopyFromIconOrCursor(const wxGDIImage& icon)
refData->m_hBitmap = (WXHBITMAP)iconInfo.hbmColor; refData->m_hBitmap = (WXHBITMAP)iconInfo.hbmColor;
#if wxUSE_WXDIB switch ( transp )
// If the icon is 32 bits per pixel then it may have alpha channel data,
// although there are some icons that are 32 bpp but have no alpha... So
// convert to a DIB and manually check the 4th byte for each pixel.
BITMAP bm;
if ( ::GetObject(iconInfo.hbmColor, sizeof(BITMAP), (LPVOID)&bm)
&& bm.bmBitsPixel == 32)
{ {
wxDIB dib(iconInfo.hbmColor); default:
if (dib.IsOk()) wxFAIL_MSG( _T("unknown wxBitmapTransparency value") );
{
unsigned char* pixels = dib.GetData(); case wxBitmapTransparency_None:
for (int idx=0; idx<w*h*4; idx+=4) // nothing to do, refData->m_hasAlpha is false by default
break;
case wxBitmapTransparency_Auto:
#if wxUSE_WXDIB
// If the icon is 32 bits per pixel then it may have alpha channel
// data, although there are some icons that are 32 bpp but have no
// alpha... So convert to a DIB and manually check the 4th byte for
// each pixel.
{ {
if (pixels[idx+3] != 0) BITMAP bm;
if ( ::GetObject(iconInfo.hbmColor, sizeof(bm), &bm) &&
(bm.bmBitsPixel == 32) )
{ {
// If there is an alpha byte that is non-zero then set the wxDIB dib(iconInfo.hbmColor);
// alpha flag and bail out of the loop. if (dib.IsOk())
refData->m_hasAlpha = true; {
break; const unsigned char* pixels = dib.GetData();
for (int idx = 0; idx < w*h*4; idx+=4)
{
if (pixels[idx+3] != 0)
{
// If there is an alpha byte that is non-zero
// then set the alpha flag and stop checking
refData->m_hasAlpha = true;
break;
}
}
}
} }
} }
} break;
#endif // wxUSE_WXDIB
case wxBitmapTransparency_Always:
refData->m_hasAlpha = true;
break;
} }
#endif
if ( !refData->m_hasAlpha ) if ( !refData->m_hasAlpha )
{ {
// the mask returned by GetIconInfo() is inverted compared to the usual // the mask returned by GetIconInfo() is inverted compared to the usual
@@ -353,32 +372,30 @@ bool wxBitmap::CopyFromIconOrCursor(const wxGDIImage& icon)
::DeleteObject(iconInfo.hbmMask); ::DeleteObject(iconInfo.hbmMask);
return true; return true;
#else #else // __WXMICROWIN__ || __WXWINCE__
wxUnusedVar(icon); wxUnusedVar(icon);
return false; return false;
#endif #endif // !__WXWINCE__/__WXWINCE__
} }
#endif // Win32 bool wxBitmap::CopyFromCursor(const wxCursor& cursor, wxBitmapTransparency transp)
bool wxBitmap::CopyFromCursor(const wxCursor& cursor)
{ {
UnRef(); UnRef();
if ( !cursor.Ok() ) if ( !cursor.Ok() )
return false; return false;
return CopyFromIconOrCursor(cursor); return CopyFromIconOrCursor(cursor, transp);
} }
bool wxBitmap::CopyFromIcon(const wxIcon& icon) bool wxBitmap::CopyFromIcon(const wxIcon& icon, wxBitmapTransparency transp)
{ {
UnRef(); UnRef();
if ( !icon.Ok() ) if ( !icon.Ok() )
return false; return false;
return CopyFromIconOrCursor(icon); return CopyFromIconOrCursor(icon, transp);
} }
#ifndef NEVER_USE_DIB #ifndef NEVER_USE_DIB