From cdcdbe54956f18f86ba9162f7c9b7902a163f668 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Mon, 13 Sep 2004 19:37:03 +0000 Subject: [PATCH] Authors: Michael Kaufmann , Huw Davies CreateDIBitmap should return bitmaps at the depth of the supplied dc. Add a test to exercise this behaviour. --- dlls/gdi/dib.c | 91 ++++--------------------- dlls/gdi/enhmetafile.c | 96 +++++++++++++++++++++++---- dlls/gdi/tests/.cvsignore | 1 + dlls/gdi/tests/Makefile.in | 1 + dlls/gdi/tests/bitmap.c | 161 +++++++++++++++++++++++++++++++++++++++++++++ windows/cursoricon.c | 98 ++++++++++++++++++++++++--- 6 files changed, 351 insertions(+), 97 deletions(-) create mode 100644 dlls/gdi/tests/bitmap.c diff --git a/dlls/gdi/dib.c b/dlls/gdi/dib.c index 850bee96b9f..3fc382907aa 100644 --- a/dlls/gdi/dib.c +++ b/dlls/gdi/dib.c @@ -773,13 +773,15 @@ INT WINAPI GetDIBits( /*********************************************************************** * CreateDIBitmap (GDI32.@) + * + * Creates a DDB (device dependent bitmap) from a DIB. + * The DDB will have the same color depth as the reference DC. */ HBITMAP WINAPI CreateDIBitmap( HDC hdc, const BITMAPINFOHEADER *header, DWORD init, LPCVOID bits, const BITMAPINFO *data, UINT coloruse ) { HBITMAP handle; - BOOL fColor; DWORD width; int height; WORD bpp; @@ -789,91 +791,26 @@ HBITMAP WINAPI CreateDIBitmap( HDC hdc, const BITMAPINFOHEADER *header, if (DIB_GetBitmapInfo( header, &width, &height, &bpp, &compr ) == -1) return 0; if (height < 0) height = -height; - /* Check if we should create a monochrome or color bitmap. */ - /* We create a monochrome bitmap only if it has exactly 2 */ - /* colors, which are black followed by white, nothing else. */ - /* In all other cases, we create a color bitmap. */ - - if (bpp != 1) fColor = TRUE; - else if ((coloruse != DIB_RGB_COLORS) || !data) fColor = FALSE; + if (hdc == NULL) + handle = CreateBitmap( width, height, 1, 1, NULL ); else - { - if (data->bmiHeader.biSize == sizeof(BITMAPINFOHEADER)) - { - RGBQUAD *rgb = data->bmiColors; - DWORD col = RGB( rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue ); - - /* Check if the first color of the colormap is black */ - if ((col == RGB(0,0,0))) - { - rgb++; - col = RGB( rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue ); - /* If the second color is white, create a monochrome bitmap */ - fColor = (col != RGB(0xff,0xff,0xff)); - } - /* Note : If the first color of the colormap is white - followed by black, we have to create a color bitmap. - If we don't the white will be displayed in black later on!*/ - else fColor = TRUE; - } - else if (data->bmiHeader.biSize == sizeof(BITMAPCOREHEADER)) - { - RGBTRIPLE *rgb = ((BITMAPCOREINFO *)data)->bmciColors; - DWORD col = RGB( rgb->rgbtRed, rgb->rgbtGreen, rgb->rgbtBlue ); - if ((col == RGB(0,0,0))) - { - rgb++; - col = RGB( rgb->rgbtRed, rgb->rgbtGreen, rgb->rgbtBlue ); - fColor = (col != RGB(0xff,0xff,0xff)); - } - else fColor = TRUE; - } - else if (data->bmiHeader.biSize == sizeof(BITMAPV4HEADER)) - { /* FIXME: correct ? */ - RGBQUAD *rgb = data->bmiColors; - DWORD col = RGB( rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue ); - - /* Check if the first color of the colormap is black */ - if ((col == RGB(0,0,0))) - { - rgb++; - col = RGB( rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue ); - /* If the second color is white, create a monochrome bitmap */ - fColor = (col != RGB(0xff,0xff,0xff)); - } - /* Note : If the first color of the colormap is white - followed by black, we have to create a color bitmap. - If we don't the white will be displayed in black later on!*/ - else fColor = TRUE; - } - else - { - ERR("(%ld): wrong/unknown size for data\n", - data->bmiHeader.biSize ); - return 0; - } - } - - /* Now create the bitmap */ - - if (!(dc = DC_GetDCPtr( hdc ))) return 0; - - if (fColor) - handle = CreateBitmap( width, height, GetDeviceCaps( hdc, PLANES ), - GetDeviceCaps( hdc, BITSPIXEL ), NULL ); - else handle = CreateBitmap( width, height, 1, 1, NULL ); + handle = CreateCompatibleBitmap( hdc, width, height ); if (handle) { if (init == CBM_INIT) SetDIBits( hdc, handle, 0, height, bits, data, coloruse ); - else if (!BITMAP_SetOwnerDC( handle, dc )) + + else if (hdc && ((dc = DC_GetDCPtr( hdc )) != NULL) ) { - DeleteObject( handle ); - handle = 0; + if (!BITMAP_SetOwnerDC( handle, dc )) + { + DeleteObject( handle ); + handle = 0; + } + GDI_ReleaseObj( hdc ); } } - GDI_ReleaseObj( hdc ); return handle; } diff --git a/dlls/gdi/enhmetafile.c b/dlls/gdi/enhmetafile.c index 7a2e5690637..c242302bf96 100644 --- a/dlls/gdi/enhmetafile.c +++ b/dlls/gdi/enhmetafile.c @@ -196,6 +196,55 @@ static const char *get_emr_name(DWORD type) return NULL; } +/*********************************************************************** + * is_dib_monochrome + * + * Returns whether a DIB can be converted to a monochrome DDB. + * + * A DIB can be converted if its color table contains only black and + * white. Black must be the first color in the color table. + * + * Note : If the first color in the color table is white followed by + * black, we can't convert it to a monochrome DDB with + * SetDIBits, because black and white would be inverted. + */ +static BOOL is_dib_monochrome( const BITMAPINFO* info ) +{ + if (info->bmiHeader.biBitCount != 1) return FALSE; + + if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER)) + { + RGBTRIPLE *rgb = ((BITMAPCOREINFO *) info)->bmciColors; + + /* Check if the first color is black */ + if ((rgb->rgbtRed == 0) && (rgb->rgbtGreen == 0) && (rgb->rgbtBlue == 0)) + { + rgb++; + + /* Check if the second color is white */ + return ((rgb->rgbtRed == 0xff) && (rgb->rgbtGreen == 0xff) + && (rgb->rgbtBlue == 0xff)); + } + else return FALSE; + } + else /* assume BITMAPINFOHEADER */ + { + RGBQUAD *rgb = info->bmiColors; + + /* Check if the first color is black */ + if ((rgb->rgbRed == 0) && (rgb->rgbGreen == 0) && + (rgb->rgbBlue == 0) && (rgb->rgbReserved == 0)) + { + rgb++; + + /* Check if the second color is white */ + return ((rgb->rgbRed == 0xff) && (rgb->rgbGreen == 0xff) + && (rgb->rgbBlue == 0xff) && (rgb->rgbReserved == 0)); + } + else return FALSE; + } +} + /**************************************************************************** * EMF_Create_HENHMETAFILE */ @@ -1619,11 +1668,30 @@ BOOL WINAPI PlayEnhMetaFileRecord( case EMR_CREATEMONOBRUSH: { - PEMRCREATEMONOBRUSH pCreateMonoBrush = (PEMRCREATEMONOBRUSH)mr; - BITMAPINFO *pbi = (BITMAPINFO *)((BYTE *)mr + pCreateMonoBrush->offBmi); - HBITMAP hBmp = CreateDIBitmap(0, (BITMAPINFOHEADER *)pbi, CBM_INIT, - (BYTE *)mr + pCreateMonoBrush->offBits, pbi, pCreateMonoBrush->iUsage); + PEMRCREATEMONOBRUSH pCreateMonoBrush = (PEMRCREATEMONOBRUSH)mr; + BITMAPINFO *pbi = (BITMAPINFO *)((BYTE *)mr + pCreateMonoBrush->offBmi); + HBITMAP hBmp; + + /* Need to check if the bitmap is monochrome, and if the + two colors are really black and white */ + if (is_dib_monochrome(pbi)) + { + /* Top-down DIBs have a negative height */ + LONG height = pbi->bmiHeader.biHeight; + if (height < 0) height = -height; + + hBmp = CreateBitmap(pbi->bmiHeader.biWidth, height, 1, 1, NULL); + SetDIBits(hdc, hBmp, 0, pbi->bmiHeader.biHeight, + (BYTE *)mr + pCreateMonoBrush->offBits, pbi, pCreateMonoBrush->iUsage); + } + else + { + hBmp = CreateDIBitmap(hdc, (BITMAPINFOHEADER *)pbi, CBM_INIT, + (BYTE *)mr + pCreateMonoBrush->offBits, pbi, pCreateMonoBrush->iUsage); + } + (handletable->objectHandle)[pCreateMonoBrush->ihBrush] = CreatePatternBrush(hBmp); + /* CreatePatternBrush created a copy of the bitmap */ DeleteObject(hBmp); break; @@ -1652,7 +1720,7 @@ BOOL WINAPI PlayEnhMetaFileRecord( SelectObject(hdcSrc, hBrushOld); DeleteObject(hBrush); - hBmp = CreateDIBitmap(0, (BITMAPINFOHEADER *)pbi, CBM_INIT, + hBmp = CreateDIBitmap(hdc, (BITMAPINFOHEADER *)pbi, CBM_INIT, (BYTE *)mr + pBitBlt->offBitsSrc, pbi, pBitBlt->iUsageSrc); hBmpOld = SelectObject(hdcSrc, hBmp); @@ -1694,7 +1762,7 @@ BOOL WINAPI PlayEnhMetaFileRecord( SelectObject(hdcSrc, hBrushOld); DeleteObject(hBrush); - hBmp = CreateDIBitmap(0, (BITMAPINFOHEADER *)pbi, CBM_INIT, + hBmp = CreateDIBitmap(hdc, (BITMAPINFOHEADER *)pbi, CBM_INIT, (BYTE *)mr + pStretchBlt->offBitsSrc, pbi, pStretchBlt->iUsageSrc); hBmpOld = SelectObject(hdcSrc, hBmp); @@ -1728,11 +1796,13 @@ BOOL WINAPI PlayEnhMetaFileRecord( DeleteObject(hBrush); pbi = (BITMAPINFO *)((BYTE *)mr + pMaskBlt->offBmiMask); - hBmpMask = CreateDIBitmap(0, (BITMAPINFOHEADER *)pbi, CBM_INIT, - (BYTE *)mr + pMaskBlt->offBitsMask, pbi, pMaskBlt->iUsageMask); + hBmpMask = CreateBitmap(pbi->bmiHeader.biWidth, pbi->bmiHeader.biHeight, + 1, 1, NULL); + SetDIBits(hdc, hBmpMask, 0, pbi->bmiHeader.biHeight, + (BYTE *)mr + pMaskBlt->offBitsMask, pbi, pMaskBlt->iUsageMask); pbi = (BITMAPINFO *)((BYTE *)mr + pMaskBlt->offBmiSrc); - hBmp = CreateDIBitmap(0, (BITMAPINFOHEADER *)pbi, CBM_INIT, + hBmp = CreateDIBitmap(hdc, (BITMAPINFOHEADER *)pbi, CBM_INIT, (BYTE *)mr + pMaskBlt->offBitsSrc, pbi, pMaskBlt->iUsageSrc); hBmpOld = SelectObject(hdcSrc, hBmp); MaskBlt(hdc, @@ -1778,11 +1848,13 @@ BOOL WINAPI PlayEnhMetaFileRecord( DeleteObject(hBrush); pbi = (BITMAPINFO *)((BYTE *)mr + pPlgBlt->offBmiMask); - hBmpMask = CreateDIBitmap(0, (BITMAPINFOHEADER *)pbi, CBM_INIT, - (BYTE *)mr + pPlgBlt->offBitsMask, pbi, pPlgBlt->iUsageMask); + hBmpMask = CreateBitmap(pbi->bmiHeader.biWidth, pbi->bmiHeader.biHeight, + 1, 1, NULL); + SetDIBits(hdc, hBmpMask, 0, pbi->bmiHeader.biHeight, + (BYTE *)mr + pPlgBlt->offBitsMask, pbi, pPlgBlt->iUsageMask); pbi = (BITMAPINFO *)((BYTE *)mr + pPlgBlt->offBmiSrc); - hBmp = CreateDIBitmap(0, (BITMAPINFOHEADER *)pbi, CBM_INIT, + hBmp = CreateDIBitmap(hdc, (BITMAPINFOHEADER *)pbi, CBM_INIT, (BYTE *)mr + pPlgBlt->offBitsSrc, pbi, pPlgBlt->iUsageSrc); hBmpOld = SelectObject(hdcSrc, hBmp); PlgBlt(hdc, diff --git a/dlls/gdi/tests/.cvsignore b/dlls/gdi/tests/.cvsignore index 6f32d4c5db5..01a5204fe9a 100644 --- a/dlls/gdi/tests/.cvsignore +++ b/dlls/gdi/tests/.cvsignore @@ -1,4 +1,5 @@ Makefile +bitmap.ok gdiobj.ok generated.ok metafile.ok diff --git a/dlls/gdi/tests/Makefile.in b/dlls/gdi/tests/Makefile.in index 6891b565560..aad8a538161 100644 --- a/dlls/gdi/tests/Makefile.in +++ b/dlls/gdi/tests/Makefile.in @@ -6,6 +6,7 @@ TESTDLL = gdi32.dll IMPORTS = user32 gdi32 CTESTS = \ + bitmap.c \ gdiobj.c \ generated.c \ metafile.c diff --git a/dlls/gdi/tests/bitmap.c b/dlls/gdi/tests/bitmap.c new file mode 100644 index 00000000000..cd53d20f7c6 --- /dev/null +++ b/dlls/gdi/tests/bitmap.c @@ -0,0 +1,161 @@ +/* + * Unit test suite for bitmaps + * + * Copyright 2004 Huw Davies + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include + +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" + +#include "wine/test.h" + + +static void test_createdibitmap(void) +{ + HDC hdc, hdcmem; + BITMAPINFOHEADER bmih; + BITMAP bm; + HBITMAP hbm, hbm_colour, hbm_old; + INT screen_depth; + + hdc = GetDC(0); + screen_depth = GetDeviceCaps(hdc, BITSPIXEL); + memset(&bmih, 0, sizeof(bmih)); + bmih.biSize = sizeof(bmih); + bmih.biWidth = 10; + bmih.biHeight = 10; + bmih.biPlanes = 1; + bmih.biBitCount = 32; + bmih.biCompression = BI_RGB; + + /* First create an un-initialised bitmap. The depth of the bitmap + should match that of the hdc and not that supplied in bmih. + */ + + /* First try 32 bits */ + hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0); + ok(hbm != NULL, "CreateDIBitmap failed\n"); + ok(GetObject(hbm, sizeof(bm), &bm), "GetObject failed\n"); + + ok(bm.bmBitsPixel == screen_depth, "CreateDIBitmap created bitmap of incorrect depth %d != %d\n", bm.bmBitsPixel, screen_depth); + DeleteObject(hbm); + + /* Then 16 */ + bmih.biBitCount = 16; + hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0); + ok(hbm != NULL, "CreateDIBitmap failed\n"); + ok(GetObject(hbm, sizeof(bm), &bm), "GetObject failed\n"); + + ok(bm.bmBitsPixel == screen_depth, "CreateDIBitmap created bitmap of incorrect depth %d != %d\n", bm.bmBitsPixel, screen_depth); + DeleteObject(hbm); + + /* Then 1 */ + bmih.biBitCount = 1; + hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0); + ok(hbm != NULL, "CreateDIBitmap failed\n"); + ok(GetObject(hbm, sizeof(bm), &bm), "GetObject failed\n"); + + ok(bm.bmBitsPixel == screen_depth, "CreateDIBitmap created bitmap of incorrect depth %d != %d\n", bm.bmBitsPixel, screen_depth); + DeleteObject(hbm); + + /* Now with a monochrome dc we expect a monochrome bitmap */ + hdcmem = CreateCompatibleDC(hdc); + + /* First try 32 bits */ + bmih.biBitCount = 32; + hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0); + ok(hbm != NULL, "CreateDIBitmap failed\n"); + ok(GetObject(hbm, sizeof(bm), &bm), "GetObject failed\n"); + + ok(bm.bmBitsPixel == 1, "CreateDIBitmap created bitmap of incorrect depth %d != %d\n", bm.bmBitsPixel, 1); + DeleteObject(hbm); + + /* Then 16 */ + bmih.biBitCount = 16; + hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0); + ok(hbm != NULL, "CreateDIBitmap failed\n"); + ok(GetObject(hbm, sizeof(bm), &bm), "GetObject failed\n"); + + ok(bm.bmBitsPixel == 1, "CreateDIBitmap created bitmap of incorrect depth %d != %d\n", bm.bmBitsPixel, 1); + DeleteObject(hbm); + + /* Then 1 */ + bmih.biBitCount = 1; + hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0); + ok(hbm != NULL, "CreateDIBitmap failed\n"); + ok(GetObject(hbm, sizeof(bm), &bm), "GetObject failed\n"); + + ok(bm.bmBitsPixel == 1, "CreateDIBitmap created bitmap of incorrect depth %d != %d\n", bm.bmBitsPixel, 1); + DeleteObject(hbm); + + /* Now select a polychrome bitmap into the dc and we expect + screen_depth bitmaps again */ + hbm_colour = CreateCompatibleBitmap(hdc, 1, 1); + hbm_old = SelectObject(hdcmem, hbm_colour); + + /* First try 32 bits */ + bmih.biBitCount = 32; + hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0); + ok(hbm != NULL, "CreateDIBitmap failed\n"); + ok(GetObject(hbm, sizeof(bm), &bm), "GetObject failed\n"); + + ok(bm.bmBitsPixel == screen_depth, "CreateDIBitmap created bitmap of incorrect depth %d != %d\n", bm.bmBitsPixel, screen_depth); + DeleteObject(hbm); + + /* Then 16 */ + bmih.biBitCount = 16; + hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0); + ok(hbm != NULL, "CreateDIBitmap failed\n"); + ok(GetObject(hbm, sizeof(bm), &bm), "GetObject failed\n"); + + ok(bm.bmBitsPixel == screen_depth, "CreateDIBitmap created bitmap of incorrect depth %d != %d\n", bm.bmBitsPixel, screen_depth); + DeleteObject(hbm); + + /* Then 1 */ + bmih.biBitCount = 1; + hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0); + ok(hbm != NULL, "CreateDIBitmap failed\n"); + ok(GetObject(hbm, sizeof(bm), &bm), "GetObject failed\n"); + + ok(bm.bmBitsPixel == screen_depth, "CreateDIBitmap created bitmap of incorrect depth %d != %d\n", bm.bmBitsPixel, screen_depth); + DeleteObject(hbm); + + SelectObject(hdcmem, hbm_old); + DeleteObject(hbm_colour); + DeleteDC(hdcmem); + + /* If hdc == 0 then we get a 1 bpp bitmap */ + bmih.biBitCount = 32; + hbm = CreateDIBitmap(0, &bmih, 0, NULL, NULL, 0); + ok(hbm != NULL, "CreateDIBitmap failed\n"); + ok(GetObject(hbm, sizeof(bm), &bm), "GetObject failed\n"); + + ok(bm.bmBitsPixel == 1, "CreateDIBitmap created bitmap of incorrect depth %d != %d\n", bm.bmBitsPixel, 1); + DeleteObject(hbm); + + ReleaseDC(0, hdc); +} + +START_TEST(bitmap) +{ + test_createdibitmap(); +} diff --git a/windows/cursoricon.c b/windows/cursoricon.c index c5bc5f89d47..d1b45e43b85 100644 --- a/windows/cursoricon.c +++ b/windows/cursoricon.c @@ -224,6 +224,56 @@ static int bitmap_info_size( const BITMAPINFO * info, WORD coloruse ) } +/*********************************************************************** + * is_dib_monochrome + * + * Returns whether a DIB can be converted to a monochrome DDB. + * + * A DIB can be converted if its color table contains only black and + * white. Black must be the first color in the color table. + * + * Note : If the first color in the color table is white followed by + * black, we can't convert it to a monochrome DDB with + * SetDIBits, because black and white would be inverted. + */ +static BOOL is_dib_monochrome( const BITMAPINFO* info ) +{ + if (info->bmiHeader.biBitCount != 1) return FALSE; + + if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER)) + { + RGBTRIPLE *rgb = ((BITMAPCOREINFO *) info)->bmciColors; + + /* Check if the first color is black */ + if ((rgb->rgbtRed == 0) && (rgb->rgbtGreen == 0) && (rgb->rgbtBlue == 0)) + { + rgb++; + + /* Check if the second color is white */ + return ((rgb->rgbtRed == 0xff) && (rgb->rgbtGreen == 0xff) + && (rgb->rgbtBlue == 0xff)); + } + else return FALSE; + } + else /* assume BITMAPINFOHEADER */ + { + RGBQUAD *rgb = info->bmiColors; + + /* Check if the first color is black */ + if ((rgb->rgbRed == 0) && (rgb->rgbGreen == 0) && + (rgb->rgbBlue == 0) && (rgb->rgbReserved == 0)) + { + rgb++; + + /* Check if the second color is white */ + return ((rgb->rgbRed == 0xff) && (rgb->rgbGreen == 0xff) + && (rgb->rgbBlue == 0xff) && (rgb->rgbReserved == 0)); + } + else return FALSE; + } +} + + /********************************************************************** * CURSORICON_FindSharedIcon */ @@ -657,8 +707,17 @@ static HICON CURSORICON_CreateFromResource( HMODULE16 hModule, HGLOBAL16 hObj, L } if (!res) { DeleteObject(hXorBits); hXorBits = 0; } } - } else hXorBits = CreateDIBitmap( screen_dc, &pInfo->bmiHeader, - CBM_INIT, (char*)bmi + size, pInfo, DIB_RGB_COLORS ); + } else { + if (is_dib_monochrome(bmi)) { + hXorBits = CreateBitmap(width, height, 1, 1, NULL); + SetDIBits(screen_dc, hXorBits, 0, height, + (char*)bmi + size, pInfo, DIB_RGB_COLORS); + } + else + hXorBits = CreateDIBitmap(screen_dc, &pInfo->bmiHeader, + CBM_INIT, (char*)bmi + size, pInfo, DIB_RGB_COLORS); + } + if( hXorBits ) { char* xbits = (char *)bmi + size + @@ -700,9 +759,13 @@ static HICON CURSORICON_CreateFromResource( HMODULE16 hModule, HGLOBAL16 hObj, L } if (!res) { DeleteObject(hAndBits); hAndBits = 0; } } - } else hAndBits = CreateDIBitmap( screen_dc, &pInfo->bmiHeader, - CBM_INIT, xbits, pInfo, DIB_RGB_COLORS ); + } else { + hAndBits = CreateBitmap(width, height, 1, 1, NULL); + + if (hAndBits) SetDIBits(screen_dc, hAndBits, 0, height, + xbits, pInfo, DIB_RGB_COLORS); + } if( !hAndBits ) DeleteObject( hXorBits ); } HeapFree( GetProcessHeap(), 0, pInfo ); @@ -1170,7 +1233,7 @@ HICON WINAPI CreateIcon( iinfo.hbmColor = CreateDIBitmap( hdc, &bmi.bmiHeader, CBM_INIT, lpXORbits, &bmi, DIB_RGB_COLORS ); - + hIcon=CreateIconIndirect(&iinfo); DeleteObject(iinfo.hbmMask); DeleteObject(iinfo.hbmColor); @@ -1957,7 +2020,7 @@ static void DIB_FixColorsToLoadflags(BITMAPINFO * bmi, UINT loadflags, BYTE pix) /********************************************************************** * BITMAP_Load */ -static HBITMAP BITMAP_Load( HINSTANCE instance,LPCWSTR name, UINT loadflags ) +static HBITMAP BITMAP_Load( HINSTANCE instance, LPCWSTR name, UINT loadflags ) { HBITMAP hbitmap = 0; HRSRC hRsrc; @@ -1975,6 +2038,7 @@ static HBITMAP BITMAP_Load( HINSTANCE instance,LPCWSTR name, UINT loadflags ) if (HIWORD(name)) return 0; instance = user32_module; } + if (!(hRsrc = FindResourceW( instance, name, (LPWSTR)RT_BITMAP ))) return 0; if (!(handle = LoadResource( instance, hRsrc ))) return 0; @@ -1985,8 +2049,10 @@ static HBITMAP BITMAP_Load( HINSTANCE instance,LPCWSTR name, UINT loadflags ) if (!(ptr = map_fileW( name ))) return 0; info = (BITMAPINFO *)(ptr + sizeof(BITMAPFILEHEADER)); } + size = bitmap_info_size(info, DIB_RGB_COLORS); if ((hFix = GlobalAlloc(0, size))) fix_info=GlobalLock(hFix); + if (fix_info) { BYTE pix; @@ -1994,9 +2060,11 @@ static HBITMAP BITMAP_Load( HINSTANCE instance,LPCWSTR name, UINT loadflags ) pix = *((LPBYTE)info + size); DIB_FixColorsToLoadflags(fix_info, loadflags, pix); if (!screen_dc) screen_dc = CreateDCA( "DISPLAY", NULL, NULL, NULL ); + if (screen_dc) { char *bits = (char *)info + size; + if (loadflags & LR_CREATEDIBSECTION) { DIBSECTION dib; hbitmap = CreateDIBSection(screen_dc, fix_info, DIB_RGB_COLORS, NULL, 0, 0); @@ -2005,14 +2073,28 @@ static HBITMAP BITMAP_Load( HINSTANCE instance,LPCWSTR name, UINT loadflags ) DIB_RGB_COLORS); } else { - hbitmap = CreateDIBitmap( screen_dc, &fix_info->bmiHeader, CBM_INIT, - bits, fix_info, DIB_RGB_COLORS ); + /* If it's possible, create a monochrome bitmap */ + + LONG height = fix_info->bmiHeader.biHeight; + if (height < 0) height = -height; + + if (is_dib_monochrome(fix_info)) + hbitmap = CreateBitmap(fix_info->bmiHeader.biWidth, height, 1, 1, NULL); + else + hbitmap = CreateBitmap(fix_info->bmiHeader.biWidth, height, + GetDeviceCaps(screen_dc, PLANES), + GetDeviceCaps(screen_dc, BITSPIXEL), NULL); + + SetDIBits(screen_dc, hbitmap, 0, height, bits, info, DIB_RGB_COLORS); } } + GlobalUnlock(hFix); GlobalFree(hFix); } + if (loadflags & LR_LOADFROMFILE) UnmapViewOfFile( ptr ); + return hbitmap; } -- 2.11.4.GIT