Fixes MaskBlt EMF playback.
From: Piotr Caban piotr@codeweavers.com
--- dlls/gdi32/tests/bitmap.c | 8 +++++++- dlls/win32u/dib.c | 20 ++++++++++++++++++-- dlls/win32u/ntgdi_private.h | 3 +++ 3 files changed, 28 insertions(+), 3 deletions(-)
diff --git a/dlls/gdi32/tests/bitmap.c b/dlls/gdi32/tests/bitmap.c index d3074286ee6..e9b93d15fce 100644 --- a/dlls/gdi32/tests/bitmap.c +++ b/dlls/gdi32/tests/bitmap.c @@ -915,7 +915,7 @@ static void test_dib_formats(void) char data[2048]; /* 2 x 2 pixels, max 64 bits-per-pixel, max 64 planes */ void *bits; int planes, bpp, compr, format; - HBITMAP hdib, hbmp; + HBITMAP hdib, hbmp, hbmp_mono; HDC hdc, memdc; UINT ret; BOOL format_ok, expect_ok; @@ -924,6 +924,7 @@ static void test_dib_formats(void) hdc = GetDC( 0 ); memdc = CreateCompatibleDC( 0 ); hbmp = CreateCompatibleBitmap( hdc, 10, 10 ); + hbmp_mono = CreateBitmap( 10, 10, 1, 1, NULL );
memset( data, 0xaa, sizeof(data) );
@@ -1203,6 +1204,8 @@ static void test_dib_formats(void) DeleteObject( hdib ); ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_PAL_COLORS+1); ok( !ret, "SetDIBits succeeded with DIB_PAL_COLORS+1\n" ); + ret = SetDIBits(hdc, hbmp_mono, 0, 1, data, bi, DIB_PAL_COLORS+1); + ok( ret, "SetDIBits failed with DIB_PAL_COLORS+1\n" ); ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_PAL_COLORS+1 ); ok( ret, "SetDIBitsToDevice failed with DIB_PAL_COLORS+1\n" ); ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_PAL_COLORS+1, SRCCOPY ); @@ -1227,6 +1230,8 @@ static void test_dib_formats(void) DeleteObject( hdib ); ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_PAL_COLORS+2); ok( !ret, "SetDIBits succeeded with DIB_PAL_COLORS+2\n" ); + ret = SetDIBits(hdc, hbmp_mono, 0, 1, data, bi, DIB_PAL_COLORS+2); + ok( !ret, "SetDIBits succeeded with DIB_PAL_COLORS+2\n" ); ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_PAL_COLORS+2 ); ok( !ret, "SetDIBitsToDevice succeeded with DIB_PAL_COLORS+2\n" ); ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_PAL_COLORS+2, SRCCOPY ); @@ -1285,6 +1290,7 @@ static void test_dib_formats(void)
DeleteDC( memdc ); DeleteObject( hbmp ); + DeleteObject( hbmp_mono ); ReleaseDC( 0, hdc ); HeapFree( GetProcessHeap(), 0, bi ); } diff --git a/dlls/win32u/dib.c b/dlls/win32u/dib.c index ccbb7d6db33..64f96b268c9 100644 --- a/dlls/win32u/dib.c +++ b/dlls/win32u/dib.c @@ -205,9 +205,11 @@ static BOOL bitmapinfo_from_user_bitmapinfo( BITMAPINFO *dst, const BITMAPINFO * { void *src_colors;
- if (coloruse > DIB_PAL_COLORS + 1) return FALSE; /* FIXME: handle DIB_PAL_COLORS+1 format */ + if (coloruse > DIB_PAL_INDICES) return FALSE; if (!bitmapinfoheader_from_user_bitmapinfo( &dst->bmiHeader, &info->bmiHeader )) return FALSE; if (!is_valid_dib_format( &dst->bmiHeader, allow_compression )) return FALSE; + if (coloruse == DIB_PAL_INDICES && (dst->bmiHeader.biBitCount != 1 || + dst->bmiHeader.biCompression != BI_RGB)) return FALSE;
src_colors = (char *)info + info->bmiHeader.biSize;
@@ -230,6 +232,18 @@ static BOOL bitmapinfo_from_user_bitmapinfo( BITMAPINFO *dst, const BITMAPINFO * memcpy( dst->bmiColors, src_colors, colors * sizeof(WORD) ); max_colors = colors; } + else if (coloruse == DIB_PAL_INDICES) + { + dst->bmiColors[0].rgbRed = 0; + dst->bmiColors[0].rgbGreen = 0; + dst->bmiColors[0].rgbBlue = 0; + dst->bmiColors[0].rgbReserved = 0; + dst->bmiColors[1].rgbRed = 0xff; + dst->bmiColors[1].rgbGreen = 0xff; + dst->bmiColors[1].rgbBlue = 0xff; + dst->bmiColors[1].rgbReserved = 0; + colors = max_colors; + } else if (info->bmiHeader.biSize != sizeof(BITMAPCOREHEADER)) { memcpy( dst->bmiColors, src_colors, colors * sizeof(RGBQUAD) ); @@ -675,7 +689,7 @@ INT WINAPI SetDIBits( HDC hdc, HBITMAP hbitmap, UINT startscan, INT src_to_dst_offset; HRGN clip = 0;
- if (!bitmapinfo_from_user_bitmapinfo( src_info, info, coloruse, TRUE ) || coloruse > DIB_PAL_COLORS) + if (!bitmapinfo_from_user_bitmapinfo( src_info, info, coloruse, TRUE )) { RtlSetLastWin32Error( ERROR_INVALID_PARAMETER ); return 0; @@ -699,6 +713,8 @@ INT WINAPI SetDIBits( HDC hdc, HBITMAP hbitmap, UINT startscan,
if (!(bitmap = GDI_GetObjPtr( hbitmap, NTGDI_OBJ_BITMAP ))) return 0;
+ if (coloruse == DIB_PAL_INDICES && bitmap->dib.dsBm.bmBitsPixel != 1) return 0; + if (src_info->bmiHeader.biCompression == BI_RLE4 || src_info->bmiHeader.biCompression == BI_RLE8) { if (lines == 0) goto done; diff --git a/dlls/win32u/ntgdi_private.h b/dlls/win32u/ntgdi_private.h index 93be59c9d7e..cd714f8ec0d 100644 --- a/dlls/win32u/ntgdi_private.h +++ b/dlls/win32u/ntgdi_private.h @@ -28,6 +28,9 @@ /* extra stock object: default 1x1 bitmap for memory DCs */ #define DEFAULT_BITMAP (STOCK_LAST+1)
+/* Undocumented value for DIB's color use: indicates a mono DIB w/o pal entries */ +#define DIB_PAL_INDICES 2 + struct gdi_obj_funcs { INT (*pGetObjectW)( HGDIOBJ handle, INT count, LPVOID buffer );
From: Piotr Caban piotr@codeweavers.com
--- dlls/gdi32/emfdc.c | 6 +++--- dlls/gdi32/enhmetafile.c | 2 +- dlls/gdi32/gdi_private.h | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/dlls/gdi32/emfdc.c b/dlls/gdi32/emfdc.c index 45587503330..bf35450cfb3 100644 --- a/dlls/gdi32/emfdc.c +++ b/dlls/gdi32/emfdc.c @@ -451,7 +451,7 @@ static DWORD emfdc_create_brush( struct emf *emf, HBRUSH brush ) * FIXME: It may be that the DIB functions themselves accept this value. */ emr->emr.iType = EMR_CREATEMONOBRUSH; - usage = DIB_PAL_MONO; + usage = DIB_PAL_INDICES; emr->cbBmi = sizeof( BITMAPINFOHEADER ); } else @@ -1617,7 +1617,7 @@ BOOL EMFDC_MaskBlt( DC_ATTR *dc_attr, INT x_dst, INT y_dst, INT width_dst, INT h emr->cbBitsSrc = src_info.bmiHeader.biSizeImage; emr->xMask = x_mask; emr->yMask = y_mask; - emr->iUsageMask = DIB_PAL_MONO; + emr->iUsageMask = DIB_PAL_INDICES; emr->offBmiMask = mask_info_size ? emr->offBitsSrc + emr->cbBitsSrc : 0; emr->cbBmiMask = mask_info_size; emr->offBitsMask = emr->offBmiMask + emr->cbBmiMask; @@ -1720,7 +1720,7 @@ BOOL EMFDC_PlgBlt( DC_ATTR *dc_attr, const POINT *points, HDC hdc_src, INT x_src emr->cbBitsSrc = src_info.bmiHeader.biSizeImage; emr->xMask = x_mask; emr->yMask = y_mask; - emr->iUsageMask = DIB_PAL_MONO; + emr->iUsageMask = DIB_PAL_INDICES; emr->offBmiMask = mask_info_size ? emr->offBitsSrc + emr->cbBitsSrc : 0; emr->cbBmiMask = mask_info_size; emr->offBitsMask = emr->offBmiMask + emr->cbBmiMask; diff --git a/dlls/gdi32/enhmetafile.c b/dlls/gdi32/enhmetafile.c index 178f7b0e132..da9c68df4af 100644 --- a/dlls/gdi32/enhmetafile.c +++ b/dlls/gdi32/enhmetafile.c @@ -1858,7 +1858,7 @@ BOOL WINAPI PlayEnhMetaFileRecord(
/* Need to check if the bitmap is monochrome, and if the two colors are really black and white */ - if (pCreateMonoBrush->iUsage == DIB_PAL_MONO) + if (pCreateMonoBrush->iUsage == DIB_PAL_INDICES) { BITMAP bm;
diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h index 79f1975d96f..da4c951eb00 100644 --- a/dlls/gdi32/gdi_private.h +++ b/dlls/gdi32/gdi_private.h @@ -53,7 +53,7 @@ static inline DWORD gdi_handle_type( HGDIOBJ obj ) #define MFVERSION 0x300
/* Undocumented value for DIB's iUsage: Indicates a mono DIB w/o pal entries */ -#define DIB_PAL_MONO 2 +#define DIB_PAL_INDICES 2
/* Format of comment record added by GetWinMetaFileBits */ #include <pshpack2.h>
From: Piotr Caban piotr@codeweavers.com
--- dlls/gdi32/enhmetafile.c | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-)
diff --git a/dlls/gdi32/enhmetafile.c b/dlls/gdi32/enhmetafile.c index da9c68df4af..adbc9b296e7 100644 --- a/dlls/gdi32/enhmetafile.c +++ b/dlls/gdi32/enhmetafile.c @@ -1858,23 +1858,7 @@ BOOL WINAPI PlayEnhMetaFileRecord(
/* Need to check if the bitmap is monochrome, and if the two colors are really black and white */ - if (pCreateMonoBrush->iUsage == DIB_PAL_INDICES) - { - BITMAP bm; - - /* Undocumented iUsage indicates a mono bitmap with no palette table, - * aligned to 32 rather than 16 bits. - */ - bm.bmType = 0; - bm.bmWidth = pbi->bmiHeader.biWidth; - bm.bmHeight = abs(pbi->bmiHeader.biHeight); - bm.bmWidthBytes = 4 * ((pbi->bmiHeader.biWidth + 31) / 32); - bm.bmPlanes = pbi->bmiHeader.biPlanes; - bm.bmBitsPixel = pbi->bmiHeader.biBitCount; - bm.bmBits = (BYTE *)mr + pCreateMonoBrush->offBits; - hBmp = CreateBitmapIndirect(&bm); - } - else if (is_dib_monochrome(pbi)) + if (is_dib_monochrome(pbi)) { /* Top-down DIBs have a negative height */ LONG height = pbi->bmiHeader.biHeight;
This merge request was approved by Huw Davies.