From 11f406f91fb3faceb6e07853dec9c90cd3e15066 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 21 Jul 2007 22:56:07 +0000 Subject: [PATCH] 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 --- include/wx/msw/bitmap.h | 25 ++++++++++--- src/msw/bitmap.cpp | 77 +++++++++++++++++++++++++---------------- 2 files changed, 68 insertions(+), 34 deletions(-) diff --git a/include/wx/msw/bitmap.h b/include/wx/msw/bitmap.h index ffde65f429..e0740f8832 100644 --- a/include/wx/msw/bitmap.h +++ b/include/wx/msw/bitmap.h @@ -30,6 +30,15 @@ class WXDLLIMPEXP_FWD_CORE wxMask; class WXDLLIMPEXP_FWD_CORE wxPalette; 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 // ---------------------------------------------------------------------------- @@ -80,7 +89,11 @@ public: // we must have this, otherwise icons are silently copied into bitmaps using // 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) { @@ -106,10 +119,12 @@ public: wxBitmap GetSubBitmap( const wxRect& rect ) const; // 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 - bool CopyFromCursor(const wxCursor& cursor); + bool CopyFromCursor(const wxCursor& cursor, + wxBitmapTransparency transp = wxBitmapTransparency_Auto); #if wxUSE_WXDIB // copies from a device independent bitmap @@ -175,7 +190,9 @@ protected: private: // 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) diff --git a/src/msw/bitmap.cpp b/src/msw/bitmap.cpp index 773ed64d57..b942d9d61f 100644 --- a/src/msw/bitmap.cpp +++ b/src/msw/bitmap.cpp @@ -289,9 +289,8 @@ wxObjectRefData *wxBitmap::CloneRefData(const wxObjectRefData *dataOrig) const return m_refData; } -#ifdef __WIN32__ - -bool wxBitmap::CopyFromIconOrCursor(const wxGDIImage& icon) +bool wxBitmap::CopyFromIconOrCursor(const wxGDIImage& icon, + wxBitmapTransparency transp) { #if !defined(__WXMICROWIN__) && !defined(__WXWINCE__) // it may be either HICON or HCURSOR @@ -317,31 +316,51 @@ bool wxBitmap::CopyFromIconOrCursor(const wxGDIImage& icon) refData->m_hBitmap = (WXHBITMAP)iconInfo.hbmColor; + switch ( transp ) + { + default: + wxFAIL_MSG( _T("unknown wxBitmapTransparency value") ); + + case wxBitmapTransparency_None: + // 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. - BITMAP bm; - if ( ::GetObject(iconInfo.hbmColor, sizeof(BITMAP), (LPVOID)&bm) - && bm.bmBitsPixel == 32) - { - wxDIB dib(iconInfo.hbmColor); - if (dib.IsOk()) - { - unsigned char* pixels = dib.GetData(); - for (int idx=0; idxm_hasAlpha = true; - break; + wxDIB dib(iconInfo.hbmColor); + if (dib.IsOk()) + { + 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 ) { // the mask returned by GetIconInfo() is inverted compared to the usual @@ -353,32 +372,30 @@ bool wxBitmap::CopyFromIconOrCursor(const wxGDIImage& icon) ::DeleteObject(iconInfo.hbmMask); return true; -#else +#else // __WXMICROWIN__ || __WXWINCE__ wxUnusedVar(icon); return false; -#endif +#endif // !__WXWINCE__/__WXWINCE__ } -#endif // Win32 - -bool wxBitmap::CopyFromCursor(const wxCursor& cursor) +bool wxBitmap::CopyFromCursor(const wxCursor& cursor, wxBitmapTransparency transp) { UnRef(); if ( !cursor.Ok() ) return false; - return CopyFromIconOrCursor(cursor); + return CopyFromIconOrCursor(cursor, transp); } -bool wxBitmap::CopyFromIcon(const wxIcon& icon) +bool wxBitmap::CopyFromIcon(const wxIcon& icon, wxBitmapTransparency transp) { UnRef(); if ( !icon.Ok() ) return false; - return CopyFromIconOrCursor(icon); + return CopyFromIconOrCursor(icon, transp); } #ifndef NEVER_USE_DIB -- 2.45.2