]> git.saurik.com Git - wxWidgets.git/commitdiff
Add bitmaps in non-premultiplied format to wxImageList in wxMSW.
authorVadim Zeitlin <vadim@wxwidgets.org>
Sat, 30 Oct 2010 23:50:55 +0000 (23:50 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sat, 30 Oct 2010 23:50:55 +0000 (23:50 +0000)
ImageList_Draw() applies pre-multiplication to the bitmap itself (as can be
seen by experimenting with this or reading WINE sources for it) and so the
image list must store bitmaps with data in non-pre-multiplied format to avoid
doing it twice.

Do it by converting wxBitmaps passed to wxImageList::Add() and Replace() to
wxImage and then to non-pre-multiplied DIBs. This is obviously very
inefficient but at least results in correct appearance of images drawn by
wxImageList so it's a step forward.

Closes #9050.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@65960 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

src/msw/imaglist.cpp

index 4820d044b6114bf5c4eec55a4e19440e9bc98ebc..087d6dddba41c65d6978719eccb42fbb10d25fe8 100644 (file)
@@ -40,6 +40,7 @@
 #include "wx/imaglist.h"
 #include "wx/dc.h"
 #include "wx/msw/dc.h"
+#include "wx/msw/dib.h"
 #include "wx/msw/private.h"
 
 // ----------------------------------------------------------------------------
@@ -139,9 +140,28 @@ bool wxImageList::GetSize(int WXUNUSED(index), int &width, int &height) const
 // 'bitmap' and 'mask'.
 int wxImageList::Add(const wxBitmap& bitmap, const wxBitmap& mask)
 {
+    HBITMAP hbmp;
+
+#if wxUSE_WXDIB && wxUSE_IMAGE
+    // wxBitmap normally stores alpha in pre-multiplied format but
+    // ImageList_Draw() does pre-multiplication internally so we need to undo
+    // the pre-multiplication here. Converting back and forth like this is, of
+    // course, very inefficient but it's better than wrong appearance so we do
+    // this for now until a better way can be found.
+    AutoHBITMAP hbmpRelease;
+    if ( bitmap.HasAlpha() )
+    {
+        hbmp = wxDIB(bitmap.ConvertToImage(),
+                     wxDIB::PixelFormat_NotPreMultiplied).Detach();
+        hbmpRelease.Init(hbmp);
+    }
+    else
+#endif // wxUSE_WXDIB && wxUSE_IMAGE
+        hbmp = GetHbitmapOf(bitmap);
+
     HBITMAP hbmpMask = GetMaskForImage(bitmap, mask);
 
-    int index = ImageList_Add(GetHImageList(), GetHbitmapOf(bitmap), hbmpMask);
+    int index = ImageList_Add(GetHImageList(), hbmp, hbmpMask);
     if ( index == -1 )
     {
         wxLogError(_("Couldn't add an image to the image list."));
@@ -157,8 +177,23 @@ int wxImageList::Add(const wxBitmap& bitmap, const wxBitmap& mask)
 // 'bitmap'.
 int wxImageList::Add(const wxBitmap& bitmap, const wxColour& maskColour)
 {
+    HBITMAP hbmp;
+
+#if wxUSE_WXDIB && wxUSE_IMAGE
+    // See the comment in overloaded Add() above.
+    AutoHBITMAP hbmpRelease;
+    if ( bitmap.HasAlpha() )
+    {
+        hbmp = wxDIB(bitmap.ConvertToImage(),
+                     wxDIB::PixelFormat_NotPreMultiplied).Detach();
+        hbmpRelease.Init(hbmp);
+    }
+    else
+#endif // wxUSE_WXDIB && wxUSE_IMAGE
+        hbmp = GetHbitmapOf(bitmap);
+
     int index = ImageList_AddMasked(GetHImageList(),
-                                    GetHbitmapOf(bitmap),
+                                    hbmp,
                                     wxColourToRGB(maskColour));
     if ( index == -1 )
     {
@@ -184,12 +219,27 @@ int wxImageList::Add(const wxIcon& icon)
 // Note that wxImageList creates new bitmaps, so you may delete
 // 'bitmap' and 'mask'.
 bool wxImageList::Replace(int index,
-                          const wxBitmap& bitmap, const wxBitmap& mask)
+                          const wxBitmap& bitmap,
+                          const wxBitmap& mask)
 {
+    HBITMAP hbmp;
+
+#if wxUSE_WXDIB && wxUSE_IMAGE
+    // See the comment in Add() above.
+    AutoHBITMAP hbmpRelease;
+    if ( bitmap.HasAlpha() )
+    {
+        hbmp = wxDIB(bitmap.ConvertToImage(),
+                     wxDIB::PixelFormat_NotPreMultiplied).Detach();
+        hbmpRelease.Init(hbmp);
+    }
+    else
+#endif // wxUSE_WXDIB && wxUSE_IMAGE
+        hbmp = GetHbitmapOf(bitmap);
+
     HBITMAP hbmpMask = GetMaskForImage(bitmap, mask);
 
-    bool ok = ImageList_Replace(GetHImageList(), index,
-                                GetHbitmapOf(bitmap), hbmpMask) != 0;
+    bool ok = ImageList_Replace(GetHImageList(), index, hbmp, hbmpMask) != 0;
     if ( !ok )
     {
         wxLogLastError(wxT("ImageList_Replace()"));