Authors: Michael Kaufmann <hallo@michael-kaufmann.ch>, Huw Davies <huw@codeweavers.com>
CreateDIBitmap should return bitmaps at the depth of the supplied dc. Add a test to exercise this behaviour.
This commit is contained in:
parent
37f2cc8274
commit
cdcdbe5495
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
Makefile
|
||||
bitmap.ok
|
||||
gdiobj.ok
|
||||
generated.ok
|
||||
metafile.ok
|
||||
|
|
|
@ -6,6 +6,7 @@ TESTDLL = gdi32.dll
|
|||
IMPORTS = user32 gdi32
|
||||
|
||||
CTESTS = \
|
||||
bitmap.c \
|
||||
gdiobj.c \
|
||||
generated.c \
|
||||
metafile.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 <stdarg.h>
|
||||
#include <assert.h>
|
||||
|
||||
#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();
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue