From 89d31e42fc64bf78d9390c55baa4fc8ec54539e2 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Wed, 8 Mar 2017 21:03:59 +0100 Subject: [PATCH] gdi32: Fix color conversion when blitting to 1-bpp by matching pixels instead of color values. Signed-off-by: Alexandre Julliard --- dlls/gdi32/bitblt.c | 12 ++---- dlls/gdi32/dib.c | 14 +++---- dlls/gdi32/dibdrv/primitives.c | 68 ++++++++++++++++--------------- dlls/gdi32/tests/dib.c | 74 ++++++++++++++++++++++++++++++++++ 4 files changed, 118 insertions(+), 50 deletions(-) diff --git a/dlls/gdi32/bitblt.c b/dlls/gdi32/bitblt.c index 8c2e815515..a17d248ff1 100644 --- a/dlls/gdi32/bitblt.c +++ b/dlls/gdi32/bitblt.c @@ -286,16 +286,10 @@ BOOL nulldrv_StretchBlt( PHYSDEV dst_dev, struct bitblt_coords *dst, if (src_info->bmiHeader.biBitCount == 1 && !src_info->bmiHeader.biClrUsed) get_mono_dc_colors( dc_dst, src_info, 2 ); + /* 1-bpp destination without a color table requires a fake 1-entry table + * that contains only the background color */ if (dst_info->bmiHeader.biBitCount == 1 && !dst_colors) - { - /* 1-bpp destination without a color table requires a fake 1-entry table - * that contains only the background color; except with a 1-bpp source, - * in which case it uses the source colors */ - if (src_info->bmiHeader.biBitCount > 1) - get_mono_dc_colors( dc_src, dst_info, 1 ); - else - get_mono_dc_colors( dc_src, dst_info, 2 ); - } + get_mono_dc_colors( dc_src, dst_info, 1 ); if (!(err = convert_bits( src_info, src, dst_info, &bits ))) { diff --git a/dlls/gdi32/dib.c b/dlls/gdi32/dib.c index a85bf6f278..2eb0e91aa3 100644 --- a/dlls/gdi32/dib.c +++ b/dlls/gdi32/dib.c @@ -577,17 +577,13 @@ INT nulldrv_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst, INT he DWORD dst_colors = dst_info->bmiHeader.biClrUsed; /* 1-bpp destination without a color table requires a fake 1-entry table - * that contains only the background color; except with a 1-bpp source, - * in which case it uses the source colors */ + * that contains only the background color. There is no source DC to get + * it from, so the background is hardcoded to the default color. */ if (dst_info->bmiHeader.biBitCount == 1 && !dst_colors) { - if (src_info->bmiHeader.biBitCount > 1) - get_mono_dc_colors( dc, dst_info, 1 ); - else - { - memcpy( dst_info->bmiColors, src_info->bmiColors, 2 * sizeof(dst_info->bmiColors[0]) ); - dst_info->bmiHeader.biClrUsed = 2; - } + static const RGBQUAD default_bg = { 255, 255, 255 }; + dst_info->bmiColors[0] = default_bg; + dst_info->bmiHeader.biClrUsed = 1; } if (!(err = convert_bits( src_info, &src, dst_info, &src_bits ))) diff --git a/dlls/gdi32/dibdrv/primitives.c b/dlls/gdi32/dibdrv/primitives.c index cb4210f038..a47e31c89c 100644 --- a/dlls/gdi32/dibdrv/primitives.c +++ b/dlls/gdi32/dibdrv/primitives.c @@ -2111,14 +2111,6 @@ static DWORD rgb_to_pixel_colortable(const dib_info *dib, BYTE r, BYTE g, BYTE b int i, best_index = 0; DWORD diff, best_diff = 0xffffffff; - /* special case for conversion to 1-bpp without a color table: - * we get a 1-entry table containing the background color - */ - if (dib->bit_count == 1 && size == 1) - return (r == color_table[0].rgbRed && - g == color_table[0].rgbGreen && - b == color_table[0].rgbBlue); - for(i = 0; i < size; i++) { const RGBQUAD *cur = color_table + i; @@ -2141,14 +2133,17 @@ static DWORD rgb_to_pixel_colortable(const dib_info *dib, BYTE r, BYTE g, BYTE b return best_index; } -static DWORD rgb_to_pixel_mono(const dib_info *dib, BOOL dither, int x, int y, BYTE r, BYTE g, BYTE b) +static DWORD rgb_to_pixel_mono(const dib_info *dib, BOOL dither, int x, int y, + DWORD src_pixel, DWORD bg_pixel, BYTE r, BYTE g, BYTE b) { DWORD ret; - if (!dither) - ret = rgb_to_pixel_colortable( dib, r, g, b ); - else + if (dither) ret = ((30 * r + 59 * g + 11 * b) / 100 + bayer_16x16[y % 16][x % 16]) > 255; + else if (dib->color_table_size == 1) + ret = (src_pixel == bg_pixel); + else + ret = rgb_to_pixel_colortable( dib, r, g, b ); return ret ? 0xff : 0; } @@ -4184,6 +4179,7 @@ static void convert_to_1(dib_info *dst, const dib_info *src, const RECT *src_rec { BYTE *dst_start = get_pixel_ptr_1(dst, 0, 0), *dst_pixel, dst_val; INT x, y, pad_size = ((dst->width + 31) & ~31) / 8 - (src_rect->right - src_rect->left + 7) / 8; + RGBQUAD rgb, bg_entry = *get_dib_color_table( dst ); /* entry 0 is the background color */ DWORD src_val; int bit_pos; @@ -4192,6 +4188,7 @@ static void convert_to_1(dib_info *dst, const dib_info *src, const RECT *src_rec case 32: { DWORD *src_start = get_pixel_ptr_32(src, src_rect->left, src_rect->top), *src_pixel; + DWORD bg_pixel = rgbquad_to_pixel_masks(src, bg_entry); if(src->funcs == &funcs_8888) { @@ -4202,8 +4199,8 @@ static void convert_to_1(dib_info *dst, const dib_info *src, const RECT *src_rec for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++) { src_val = *src_pixel++; - dst_val = rgb_to_pixel_mono(dst, dither, x, y, src_val >> 16, src_val >> 8, src_val); - + dst_val = rgb_to_pixel_mono(dst, dither, x, y, src_val, bg_pixel, + src_val >> 16, src_val >> 8, src_val); if(bit_pos == 0) *dst_pixel = 0; *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]); @@ -4231,7 +4228,7 @@ static void convert_to_1(dib_info *dst, const dib_info *src, const RECT *src_rec for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++) { src_val = *src_pixel++; - dst_val = rgb_to_pixel_mono(dst, dither, x, y, + dst_val = rgb_to_pixel_mono(dst, dither, x, y, src_val, bg_pixel, src_val >> src->red_shift, src_val >> src->green_shift, src_val >> src->blue_shift); @@ -4263,7 +4260,7 @@ static void convert_to_1(dib_info *dst, const dib_info *src, const RECT *src_rec for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++) { src_val = *src_pixel++; - dst_val = rgb_to_pixel_mono(dst, dither, x, y, + dst_val = rgb_to_pixel_mono(dst, dither, x, y, src_val, bg_pixel, get_field(src_val, src->red_shift, src->red_len), get_field(src_val, src->green_shift, src->green_len), get_field(src_val, src->blue_shift, src->blue_len)); @@ -4292,6 +4289,7 @@ static void convert_to_1(dib_info *dst, const dib_info *src, const RECT *src_rec case 24: { BYTE *src_start = get_pixel_ptr_24(src, src_rect->left, src_rect->top), *src_pixel; + DWORD bg_pixel = RGB( bg_entry.rgbRed, bg_entry.rgbGreen, bg_entry.rgbBlue ); for(y = src_rect->top; y < src_rect->bottom; y++) { @@ -4299,7 +4297,8 @@ static void convert_to_1(dib_info *dst, const dib_info *src, const RECT *src_rec src_pixel = src_start; for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++, src_pixel += 3) { - dst_val = rgb_to_pixel_mono(dst, dither, x, y, src_pixel[2], src_pixel[1], src_pixel[0]); + dst_val = rgb_to_pixel_mono(dst, dither, x, y, RGB(src_pixel[2], src_pixel[1], src_pixel[0]), + bg_pixel, src_pixel[2], src_pixel[1], src_pixel[0]); if(bit_pos == 0) *dst_pixel = 0; *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]); @@ -4324,6 +4323,8 @@ static void convert_to_1(dib_info *dst, const dib_info *src, const RECT *src_rec case 16: { WORD *src_start = get_pixel_ptr_16(src, src_rect->left, src_rect->top), *src_pixel; + DWORD bg_pixel = rgbquad_to_pixel_masks(src, bg_entry); + if(src->funcs == &funcs_555) { for(y = src_rect->top; y < src_rect->bottom; y++) @@ -4333,7 +4334,7 @@ static void convert_to_1(dib_info *dst, const dib_info *src, const RECT *src_rec for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++) { src_val = *src_pixel++; - dst_val = rgb_to_pixel_mono(dst, dither, x, y, + dst_val = rgb_to_pixel_mono(dst, dither, x, y, src_val, bg_pixel, ((src_val >> 7) & 0xf8) | ((src_val >> 12) & 0x07), ((src_val >> 2) & 0xf8) | ((src_val >> 7) & 0x07), ((src_val << 3) & 0xf8) | ((src_val >> 2) & 0x07)); @@ -4365,7 +4366,7 @@ static void convert_to_1(dib_info *dst, const dib_info *src, const RECT *src_rec for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++) { src_val = *src_pixel++; - dst_val = rgb_to_pixel_mono(dst, dither, x, y, + dst_val = rgb_to_pixel_mono(dst, dither, x, y, src_val, bg_pixel, (((src_val >> src->red_shift) << 3) & 0xf8) | (((src_val >> src->red_shift) >> 2) & 0x07), (((src_val >> src->green_shift) << 3) & 0xf8) | @@ -4399,7 +4400,7 @@ static void convert_to_1(dib_info *dst, const dib_info *src, const RECT *src_rec for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++) { src_val = *src_pixel++; - dst_val = rgb_to_pixel_mono(dst, dither, x, y, + dst_val = rgb_to_pixel_mono(dst, dither, x, y, src_val, bg_pixel, (((src_val >> src->red_shift) << 3) & 0xf8) | (((src_val >> src->red_shift) >> 2) & 0x07), (((src_val >> src->green_shift) << 2) & 0xfc) | @@ -4433,7 +4434,7 @@ static void convert_to_1(dib_info *dst, const dib_info *src, const RECT *src_rec for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++) { src_val = *src_pixel++; - dst_val = rgb_to_pixel_mono(dst, dither, x, y, + dst_val = rgb_to_pixel_mono(dst, dither, x, y, src_val, bg_pixel, get_field(src_val, src->red_shift, src->red_len), get_field(src_val, src->green_shift, src->green_len), get_field(src_val, src->blue_shift, src->blue_len)); @@ -4462,6 +4463,7 @@ static void convert_to_1(dib_info *dst, const dib_info *src, const RECT *src_rec { const RGBQUAD *color_table = get_dib_color_table( src ); BYTE *src_start = get_pixel_ptr_8(src, src_rect->left, src_rect->top), *src_pixel; + DWORD bg_pixel = rgbquad_to_pixel_colortable( src, bg_entry ); for(y = src_rect->top; y < src_rect->bottom; y++) { @@ -4469,8 +4471,10 @@ static void convert_to_1(dib_info *dst, const dib_info *src, const RECT *src_rec src_pixel = src_start; for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++) { - RGBQUAD rgb = color_table[*src_pixel++]; - dst_val = rgb_to_pixel_mono(dst, dither, x, y, rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue); + BYTE src_val = *src_pixel++; + rgb = color_table[src_val]; + dst_val = rgb_to_pixel_mono(dst, dither, x, y, src_val, bg_pixel, + rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue); if(bit_pos == 0) *dst_pixel = 0; *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]); @@ -4496,6 +4500,7 @@ static void convert_to_1(dib_info *dst, const dib_info *src, const RECT *src_rec { const RGBQUAD *color_table = get_dib_color_table( src ); BYTE *src_start = get_pixel_ptr_4(src, src_rect->left, src_rect->top), *src_pixel; + DWORD bg_pixel = rgbquad_to_pixel_colortable( src, bg_entry ); for(y = src_rect->top; y < src_rect->bottom; y++) { @@ -4504,12 +4509,10 @@ static void convert_to_1(dib_info *dst, const dib_info *src, const RECT *src_rec src_pixel = src_start; for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++, pos++) { - RGBQUAD rgb; - if (pos & 1) - rgb = color_table[*src_pixel++ & 0xf]; - else - rgb = color_table[*src_pixel >> 4]; - dst_val = rgb_to_pixel_mono(dst, dither, x, y, rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue); + src_val = (pos & 1) ? *src_pixel++ & 0xf : *src_pixel >> 4; + rgb = color_table[src_val]; + dst_val = rgb_to_pixel_mono(dst, dither, x, y, src_val, bg_pixel, + rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue); if(bit_pos == 0) *dst_pixel = 0; *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]); @@ -4540,17 +4543,18 @@ static void convert_to_1(dib_info *dst, const dib_info *src, const RECT *src_rec { const RGBQUAD *color_table = get_dib_color_table( src ); BYTE *src_start = get_pixel_ptr_1(src, src_rect->left, src_rect->top); + DWORD bg_pixel = rgbquad_to_pixel_colortable(src, bg_entry); + for(y = src_rect->top; y < src_rect->bottom; y++) { int pos = (src->rect.left + src_rect->left) & 7; dst_pixel = dst_start; for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++, pos++) { - RGBQUAD rgb; src_val = (src_start[pos / 8] & pixel_masks_1[pos % 8]) ? 1 : 0; rgb = color_table[src_val]; - dst_val = rgb_to_pixel_mono(dst, dither, x, y, rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue); - + dst_val = rgb_to_pixel_mono(dst, dither, x, y, src_val, bg_pixel, + rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue); if(bit_pos == 0) *dst_pixel = 0; *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]); diff --git a/dlls/gdi32/tests/dib.c b/dlls/gdi32/tests/dib.c index bf3e77c4c6..999913f751 100644 --- a/dlls/gdi32/tests/dib.c +++ b/dlls/gdi32/tests/dib.c @@ -131,6 +131,7 @@ static const char *sha1_graphics_a8r8g8b8[] = "d7e34fa02db7ad52327f80389bd1ba1b72b6c692", "d7dd4700f49808541bba99244b7eb5840e0a2439", "00b4e9b243a36a7210a48bcb7c2d410d9cd8c8c7", + "8eb1f99d21a84153e88e7958707049d517ab7641", "af99228aa4cfbd1f61bd824db046144a3c6c2ed7", "568f87f0194ca19b69a5b2bcdef795d89c5721ce", "a37810f46dee8741fe5adbb3f1f2e87012ffc929", @@ -205,6 +206,7 @@ static const char *sha1_graphics_a8r8g8b8_bitfields[] = "d7e34fa02db7ad52327f80389bd1ba1b72b6c692", "d7dd4700f49808541bba99244b7eb5840e0a2439", "00b4e9b243a36a7210a48bcb7c2d410d9cd8c8c7", + "8eb1f99d21a84153e88e7958707049d517ab7641", "af99228aa4cfbd1f61bd824db046144a3c6c2ed7", "568f87f0194ca19b69a5b2bcdef795d89c5721ce", "a37810f46dee8741fe5adbb3f1f2e87012ffc929", @@ -279,6 +281,7 @@ static const char *sha1_graphics_a8b8g8r8[] = "eac5d164b83edf2cf85bac242686f9f617ec1fa4", "86c84cc8306975edecc6d4a89a8aff29f59b55a7", "698d6393e97539806351368f95be478c6fbc62b0", + "c272d1e0342e6089a0182dc42b37e47889116a9b", "af99228aa4cfbd1f61bd824db046144a3c6c2ed7", "25675c30adfe24d6cae60793b156dfdaa36ac3ba", "849d4abf4b690128a5f70e9b8ac78f20c437de06", @@ -353,6 +356,7 @@ static const char *sha1_graphics_r10g10b10[] = "5a713a91fd471fd331bd13b0868c994aa2ffe2b2", "fc0c32afb719295f28bcfef22803bef94f798e20", "bb2a421bab95f9b5420704ef44c0f3214a0b5a11", + "7735098af7535d8c57266190a13f92d8869e8529", "36f6db4fbe2a1630a7597d3a446f2902755c96ef", "d3f08946300e1700865042aed121870e292d1095", "4782df8e24127e66a434b4e839adebf2dbb223fb", @@ -427,6 +431,7 @@ static const char *sha1_graphics_r6g6b6[] = "8ad5cd520cd628b76d2e5a3f318ae1bbb6b4c994", "49341c297a887186bd47d7465d827ab3147f05e3", "514c07281ef6702c35e68b230e897303a8cdec81", + "4b41865829b50b2e29beda51b055bd1f908a649c", "325279e76367200d3fd7194d81c09fd139988ece", "c3def160a1e847605ff0fc7edd30397fa90635a0", "2b3e87e0b705b03c7c08f403409ab82cce095ba1", @@ -501,6 +506,7 @@ static const char *sha1_graphics_24[] = "5578c80048520732557abf3a3a3fa22c85015d7d", "b25ba91487ec945410deb2b51bc1156890c032a8", "4c8c936372755f95051f1159b7ff65a484e1a555", + "bf55d4bdb26ae0f358bd67ef01932563519aab98", "d347ca5c6c4b6a61389247c3b6f61564033e8c25", "ee315634ed92da3a32c2675ecd1b369471c60936", "099c688a920f606655b485e8f0a433dc811bc976", @@ -579,6 +585,7 @@ static const char *sha1_graphics_r5g5b5[] = "8f447a3820c83662086dfa836da2205b0130fd5f", "3772003c7fb420003512d0c437b3659d96d89ce4", "2ebf37d81da3f11434652d06bf65d55e96b090aa", + "ace2c60bd76b11a002bee852686e8783f102eba1", "dab47c9dc149e570045d699598b14a613bf319b3", "2daca4d26a086ed34894693be0b0374402232809", "904f1d82159bcf5485f323bd12b859dc5e83f8eb", @@ -652,6 +659,7 @@ static const char *sha1_graphics_r4g4b4[] = "104e85bad287a62dfe25f0e78280179f18bac765", "f0acb3cfcda62e95bee5f7bc8830ffeb3dd7e5a7", "fde993dfce1551ef220f5a07ce4acd66e8524ac5", + "a80f3df0aea1e1b30d9833039157bca658218f48", "07b10c3f191d0a93e5e5694aae37dcad407e10f5", "f7900e60347029876ba55e8f0c4c02e89deb36b6", "f373a5f37b82e7523c64c08eb509b6191e49b173", @@ -731,6 +739,7 @@ static const char *sha1_graphics_8_color[] = "abd2fff80f74b311072ecdb91ce9ceba268fa6e9", "9ae38bb94c7b4c0c6dfebbee23d1de4db9b77488", "8269b32b4a34440f1fa37927308debc7eb85f3fa", + "65b2c868790806be7ab4aaa6114d445c42a31f98", "678979a45126a76eb629992cd64734862f53a555", "2f7ba8803604c032cb1a1228bc021f0f1c03e245", "52e7c2f8b01592898c13f1e7633881e350244209", @@ -814,6 +823,7 @@ static const char *sha1_graphics_8_grayscale[] = "115c90df05b1ff754dbdfe2a712ef126034d952d", "fb63bbb2f944fb63ed2d7399f07b168740c1034b", "ae45f0d463ff916f3cb630103969fd49e8d09ef4", + "2becf041f83d22ac072fef5e0efd9bc1572796fd", "3685c9ae95118a83db3569832c29753276fa1264", "09640bad951c33e7d70a1fced83b1869f65b3fc5", "5eb00252664ec39e61359adb1dade4906a87a248", @@ -892,6 +902,7 @@ static const char *sha1_graphics_8[] = "5a1d8f9ea978b820edbc5c9e1c6f1cac022620ad", "31e667c2dbb81dcf81d01cb88f794e88ddb90ff2", "c404446958788fac00ee1eff571d682bc21dd7ac", + "95060f3dc9e6d01ada42f09a871b69f0699cb77c", "465d9cd0a77ab4fcf035aa67544b2a26269e0b09", "600d6b2713d5e4c0d90c02660245ed26c7ae3033", "0025a440866a404523a8a20e79a8891e45a2ff56", @@ -965,6 +976,7 @@ static const char *sha1_graphics_4[] = "c644f460937107214a88d5eb9e846d27abd8c874", "df5feb905a31c288008cf5e82d73ac818a160d82", "4f9658dde0432a711a4d783c1b5aa3365fb7d54b", + "09438163dcbede3890a0e6d8e614c97a06759380", "d8af3868c66c7d6dac35ec8ee0317b38a6910bb1", "ec8e2aebfb4a1c28ebcd0e053b9e4d8638b50951", "ccf8d11b1e81895e9781f17c227c821228d8714b", @@ -1038,6 +1050,7 @@ static const char *sha1_graphics_4_grayscale[] = "30c256a783c4874261667bb31307eb282ab9470e", "f8681c09f1abfc38d31e47622cb8798cd896a00e", "0ba7e5d68419702605739acb52fcc01c96cb63d4", + "f8d2f196ba8a16f54acb934e61a759ab7d3f2f05", "b5ee51cfc73acb59a2f6124509ea236f8fc7f9f7", "d374d4d92c940ae42a9b42c14d744341b68a8c14", "06a6a224be0f5cdc51ac4704f9f57fc1f3813d6f", @@ -1129,6 +1142,7 @@ static const char *sha1_graphics_1[] = "41a417c1f25f2619301afa44bfcde85198985792", "23366004515f3bc46796ea505d748f8d0f97fbe1", "ba682eb15c0ddffb942e6086e0ccad2353ed7241", + "58273e1fbf961ff2c772d57160d60170e258d3fe", "88763f8e8fcf4f78fa864325791a9dd35a0bd279", "013cee26bac8f815eadad4bfc012d9b5d01c3b7f", "44a28536466dc895feb824b23dfd4a47c6948af8", @@ -1204,6 +1218,7 @@ static const RECT graphics_bounds[] = { 10, 10, 356, 356 }, { 100, 100, 356, 356 }, { 0, 0, 260, 39 }, + { 0, 0, 16, 16 }, { 10, 10, 416, 26 }, { 10, 8, 60, 104 }, { 0, 10, 511, 306 }, @@ -2465,6 +2480,65 @@ static void draw_graphics(HDC hdc, const BITMAPINFO *bmi, BYTE *bits) compare_hash_broken_todo(hdc, bmi, bits, "BitBlt src 1-bpp ddb SRCCOPY", 0, bmi->bmiHeader.biBitCount <= 8 /* todo: DIBINDEX for indexed formats */ ); + DeleteObject( bmp ); + + /* blitting to 1-bpp ddb dest */ + + bmp = CreateBitmap( 16, 16, 1, 1, ddb_brush_bits ); + DeleteObject( SelectObject( src_dc, bmp ) ); + + for (y = 0; y < 16; y++) + for (x = 0; x < 16; x++) + SetPixel( hdc, x, y, RGB( 16 * x, 16 * y, 8 * (x + y)) ); + PatBlt( hdc, 15, 15, 1, 1, WHITENESS ); + /* source colors are ignored */ + SetTextColor( src_dc, 0xbeef ); + SetBkColor( src_dc, RGB( 16 * 2, 16 * 3, 8 * (2 + 3) )); + /* destination text color is also ignored */ + SetTextColor( hdc, 0xbedead ); + + i = 16; + SetBkColor( hdc, 0xffffff ); + BitBlt( src_dc, 0, 0, 16, 16, hdc, 0, 0, SRCCOPY ); + GetBitmapBits( bmp, 32, bits + get_stride(bmi) * i++ ); + StretchDIBits( src_dc, 0, 0, 16, 16, 0, + bmi->bmiHeader.biHeight - 16, 16, 16, bits, bmi, DIB_RGB_COLORS, SRCCOPY ); + GetBitmapBits( bmp, 32, bits + get_stride(bmi) * i++ ); + SetBkColor( hdc, 0 ); + BitBlt( src_dc, 0, 0, 16, 16, hdc, 0, 0, SRCCOPY ); + GetBitmapBits( bmp, 32, bits + get_stride(bmi) * i++ ); + StretchDIBits( src_dc, 0, 0, 16, 16, 0, + bmi->bmiHeader.biHeight - 16, 16, 16, bits, bmi, DIB_RGB_COLORS, SRCCOPY ); + GetBitmapBits( bmp, 32, bits + get_stride(bmi) * i++ ); + SetBkColor( hdc, RGB( 16 * 2, 16 * 3, 8 * (2 + 3) )); + BitBlt( src_dc, 0, 0, 16, 16, hdc, 0, 0, SRCCOPY ); + GetBitmapBits( bmp, 32, bits + get_stride(bmi) * i++ ); + StretchDIBits( src_dc, 0, 0, 16, 16, 0, + bmi->bmiHeader.biHeight - 16, 16, 16, bits, bmi, DIB_RGB_COLORS, SRCCOPY ); + GetBitmapBits( bmp, 32, bits + get_stride(bmi) * i++ ); + SetBkColor( hdc, RGB( 16 * 13, 16 * 14, 8 * (13 + 14) )); + BitBlt( src_dc, 0, 0, 16, 16, hdc, 0, 0, SRCCOPY ); + GetBitmapBits( bmp, 32, bits + get_stride(bmi) * i++ ); + StretchDIBits( src_dc, 0, 0, 16, 16, 0, + bmi->bmiHeader.biHeight - 16, 16, 16, bits, bmi, DIB_RGB_COLORS, SRCCOPY ); + GetBitmapBits( bmp, 32, bits + get_stride(bmi) * i++ ); + SetBkColor( hdc, PALETTEINDEX( 1 )); + BitBlt( src_dc, 0, 0, 16, 16, hdc, 0, 0, SRCCOPY ); + GetBitmapBits( bmp, 32, bits + get_stride(bmi) * i++ ); + StretchDIBits( src_dc, 0, 0, 16, 16, 0, + bmi->bmiHeader.biHeight - 16, 16, 16, bits, bmi, DIB_RGB_COLORS, SRCCOPY ); + GetBitmapBits( bmp, 32, bits + get_stride(bmi) * i++ ); + SetBkColor( hdc, DIBINDEX( 2 )); + BitBlt( src_dc, 0, 0, 16, 16, hdc, 0, 0, SRCCOPY ); + GetBitmapBits( bmp, 32, bits + get_stride(bmi) * i++ ); + StretchDIBits( src_dc, 0, 0, 16, 16, 0, + bmi->bmiHeader.biHeight - 16, 16, 16, bits, bmi, DIB_RGB_COLORS, SRCCOPY ); + GetBitmapBits( bmp, 32, bits + get_stride(bmi) * i++ ); + SetTextColor( hdc, old_text ); + SetBkColor( hdc, old_bkgnd ); + compare_hash_broken_todo(hdc, bmi, bits, "BitBlt dst 1-bpp ddb", 0, + bmi->bmiHeader.biBitCount <= 8 /* todo: DIBINDEX for indexed formats */ ); + DeleteDC( src_dc ); DeleteObject( bmp );