user32: Using DIB APIs to convert a DDB to monochrome is wrong,
do it differently
Dmitry Timoshkov
dmitry at codeweavers.com
Tue Jan 23 02:46:53 CST 2007
[1/2] user32: Using DIB APIs to convert a DDB to monochrome is wrong, do it differently
MSDN states that bitmaps and bitmap data passed to cursor-icon APIs are
in DDB format, so it's not appropriate to use DIB APIs for them, since
it introduces an alignment conflict: 2-bytes for DDBs vs. 4-bytes for DIBs.
This patch fixes a regression in the QIP application reported by Kirill Smirnov
and also works for the app I'm working on.
Changelog:
user32: Using DIB APIs to convert a DDB to monochrome is wrong, do it differently.
---
dlls/user32/cursoricon.c | 40 +++++++++++++++++++++++++++-------------
1 files changed, 27 insertions(+), 13 deletions(-)
diff --git a/dlls/user32/cursoricon.c b/dlls/user32/cursoricon.c
index 26adfde..a5e0d00 100644
--- a/dlls/user32/cursoricon.c
+++ b/dlls/user32/cursoricon.c
@@ -1846,8 +1846,6 @@ HICON WINAPI CreateIconIndirect(PICONINFO iconinfo)
sizeof(CURSORICONINFO) + sizeXor + sizeAnd );
if (hObj)
{
- HDC hdc;
- BITMAPINFO bi;
CURSORICONINFO *info;
info = (CURSORICONINFO *)GlobalLock16( hObj );
@@ -1884,18 +1882,34 @@ HICON WINAPI CreateIconIndirect(PICONINFO iconinfo)
/* Transfer the bitmap bits to the CURSORICONINFO structure */
/* Some apps pass a color bitmap as a mask, convert it to b/w */
- hdc = GetDC( 0 );
- memset(&bi, 0, sizeof(bi) );
- bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bi.bmiHeader.biWidth = bmpAnd.bmWidth;
- bi.bmiHeader.biHeight = bmpAnd.bmHeight;
- bi.bmiHeader.biPlanes = 1;
- bi.bmiHeader.biBitCount = 1;
- bi.bmiHeader.biCompression = BI_RGB;
- bi.bmiHeader.biSizeImage = sizeAnd;
- GetDIBits( hdc, iconinfo->hbmMask, 0, bmpAnd.bmHeight, (char*)(info + 1), &bi, DIB_RGB_COLORS );
- ReleaseDC( 0, hdc );
+ if (bmpAnd.bmBitsPixel == 1)
+ {
+ GetBitmapBits( iconinfo->hbmMask, sizeAnd, (char*)(info + 1) );
+ }
+ else
+ {
+ HDC hdc, hdc_mem;
+ HBITMAP hbmp_old, hbmp_mem_old, hbmp_mono;
+
+ hdc = GetDC( 0 );
+ hdc_mem = CreateCompatibleDC( hdc );
+ hbmp_mono = CreateBitmap( bmpAnd.bmWidth, bmpAnd.bmHeight, 1, 1, NULL );
+
+ hbmp_old = SelectObject( hdc, iconinfo->hbmMask );
+ hbmp_mem_old = SelectObject( hdc_mem, hbmp_mono );
+
+ BitBlt( hdc_mem, 0, 0, bmpAnd.bmWidth, bmpAnd.bmHeight, hdc, 0, 0, SRCCOPY );
+
+ SelectObject( hdc, hbmp_old );
+ SelectObject( hdc_mem, hbmp_mem_old );
+
+ DeleteDC( hdc_mem );
+ ReleaseDC( 0, hdc );
+
+ GetBitmapBits( hbmp_mono, sizeAnd, (char*)(info + 1) );
+ DeleteObject( hbmp_mono );
+ }
if (iconinfo->hbmColor) GetBitmapBits( iconinfo->hbmColor, sizeXor, (char*)(info + 1) + sizeAnd );
GlobalUnlock16( hObj );
}
--
1.4.4.4
More information about the wine-patches
mailing list