This is used to avoid code duplication for adding an 'advanced' gdi32 test.
Signed-off-by: Ralf Habacker ralf.habacker@freenet.de --- dlls/gdi32/tests/Makefile.in | 1 + dlls/gdi32/tests/dib.c | 338 +--------------------------- dlls/gdi32/tests/misc.c | 425 +++++++++++++++++++++++++++++++++++ dlls/gdi32/tests/misc.h | 31 +++ 4 files changed, 460 insertions(+), 335 deletions(-) create mode 100644 dlls/gdi32/tests/misc.c create mode 100644 dlls/gdi32/tests/misc.h
diff --git a/dlls/gdi32/tests/Makefile.in b/dlls/gdi32/tests/Makefile.in index 876f6a376a2..ad8f0ce8bad 100644 --- a/dlls/gdi32/tests/Makefile.in +++ b/dlls/gdi32/tests/Makefile.in @@ -14,6 +14,7 @@ C_SRCS = \ icm.c \ mapping.c \ metafile.c \ + misc.c \ palette.c \ path.c \ pen.c diff --git a/dlls/gdi32/tests/dib.c b/dlls/gdi32/tests/dib.c index bdc3d9ed55b..96ac0b69271 100644 --- a/dlls/gdi32/tests/dib.c +++ b/dlls/gdi32/tests/dib.c @@ -31,7 +31,9 @@
#include "wine/test.h"
-static HCRYPTPROV crypt_prov; +#include "misc.h" + +static const char *dst_format;
static const DWORD rop3[256] = { @@ -1263,217 +1265,6 @@ static const char *sha1_graphics_1_ddb_inverted[] = NULL };
-static const RECT graphics_bounds[] = -{ - { 0, 0, 0, 0 }, - { 10, 3, 219, 101 }, - { 100, 100, 301, 301 }, - { 0, 0, 201, 201 }, - { 10, 10, 110, 320 }, - { 10, 99, 300, 200 }, - { 99, 12, 201, 200 }, - { 90, 110, 300, 200 }, - { 90, 90, 210, 200 }, - { 10, 99, 300, 200 }, - { 10, 99, 300, 200 }, - { 99, 12, 201, 200 }, - { 99, 11, 201, 200 }, - { 90, 110, 300, 200 }, - { 90, 110, 300, 200 }, - { 10, 10, 365, 405 }, - { 10, 10, 365, 405 }, - { 10, 10, 365, 405 }, - { 10, 10, 365, 405 }, - { 10, 10, 365, 405 }, - { 10, 10, 365, 405 }, - { 10, 10, 365, 405 }, - { 10, 10, 365, 405 }, - { 10, 10, 350, 251 }, - { 10, 10, 300, 200 }, - { 300, 10, 9, 260 }, - { 10, 10, 435, 405 }, - { 10, 10, 120, 120 }, - { 10, 10, 110, 110 }, - { 10, 10, 120, 110 }, - { 10, 10, 110, 120 }, - { 10, 10, 120, 120 }, - { 10, 10, 110, 110 }, - { 10, 10, 120, 110 }, - { 10, 10, 110, 120 }, - { 0, 4, 356, 356 }, - { 100, 100, 356, 356 }, - { 50, 50, 306, 306 }, - { 100, 100, 356, 356 }, - { 100, 100, 356, 356 }, - { 100, 100, 356, 356 }, - { 100, 100, 356, 356 }, - { 100, 100, 356, 356 }, - { 100, 100, 356, 356 }, - { 100, 100, 356, 356 }, - { 100, 100, 356, 356 }, - { 100, 100, 356, 356 }, - { 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, 0, 512, 512 }, - { 0, 10, 511, 306 }, - { 0, 0, 512, 336 }, - { 1, 1, 300, 512 }, - { 0, 0, 500, 512 }, - { 5, 5, 206, 206 }, - { 45, 45, 256, 256 }, - { 86, 86, 215, 215 }, - { 45, 45, 256, 256 }, - { 8, 0, 392, 231 }, - { 8, 0, 392, 231 }, - { 0, 0, 60, 20 }, - { 0, 0, 512, 512 }, - { -1, -1, -1, -1 } /* the end */ -}; - -static const char **current_sha1; -static const RECT *current_bounds; -static const char *dst_format; - -static inline DWORD get_stride(const BITMAPINFO *bmi) -{ - return ((bmi->bmiHeader.biBitCount * bmi->bmiHeader.biWidth + 31) >> 3) & ~3; -} - -static inline DWORD get_dib_size(const BITMAPINFO *bmi) -{ - return get_stride(bmi) * abs(bmi->bmiHeader.biHeight); -} - -static void reset_bits( HDC hdc, const BITMAPINFO *bmi, BYTE *bits ) -{ - DWORD size = get_dib_size( bmi ); - if (bits) memset( bits, 0xcc, size ); - else - { - void *ddb_bits = HeapAlloc( GetProcessHeap(), 0, size ); - memset( ddb_bits, 0xcc, size ); - SetBitmapBits( GetCurrentObject(hdc, OBJ_BITMAP), size, ddb_bits ); - HeapFree( GetProcessHeap(), 0, ddb_bits ); - } -} - -static char *hash_dib(HDC hdc, const BITMAPINFO *bmi, const void *bits) -{ - DWORD dib_size = get_dib_size(bmi); - HCRYPTHASH hash; - char *buf; - BYTE hash_buf[20]; - DWORD hash_size = sizeof(hash_buf); - int i; - static const char *hex = "0123456789abcdef"; - - if(!crypt_prov) return NULL; - - if(!CryptCreateHash(crypt_prov, CALG_SHA1, 0, 0, &hash)) return NULL; - - if (!bits) - { - void *ddb_bits = HeapAlloc( GetProcessHeap(), 0, dib_size ); - GetBitmapBits( GetCurrentObject(hdc, OBJ_BITMAP), dib_size, ddb_bits ); - CryptHashData(hash, ddb_bits, dib_size, 0); - HeapFree( GetProcessHeap(), 0, ddb_bits ); - } - else CryptHashData(hash, bits, dib_size, 0); - - CryptGetHashParam(hash, HP_HASHVAL, NULL, &hash_size, 0); - if(hash_size != sizeof(hash_buf)) return NULL; - - CryptGetHashParam(hash, HP_HASHVAL, hash_buf, &hash_size, 0); - CryptDestroyHash(hash); - - buf = HeapAlloc(GetProcessHeap(), 0, hash_size * 2 + 1); - - for(i = 0; i < hash_size; i++) - { - buf[i * 2] = hex[hash_buf[i] >> 4]; - buf[i * 2 + 1] = hex[hash_buf[i] & 0xf]; - } - buf[i * 2] = '\0'; - - return buf; -} - -static void reset_bounds( HDC hdc ) -{ - current_bounds = graphics_bounds; - SetBoundsRect( hdc, NULL, DCB_RESET | DCB_ENABLE ); -} - -static void compare_bounds( HDC hdc, const char *info ) -{ - RECT rect; - - GetBoundsRect( hdc, &rect, DCB_RESET ); - - if (current_bounds->left == -1 && - current_bounds->top == -1 && - current_bounds->right == -1 && - current_bounds->bottom == -1) - { - ok( 0, "missing bounds, got %s,\n", wine_dbgstr_rect( &rect )); - return; - } - - ok( EqualRect( current_bounds, &rect ), "%s: %s: expected bounds %s got %s\n", dst_format, info, - wine_dbgstr_rect( current_bounds ), wine_dbgstr_rect( &rect )); - current_bounds++; -} - -static void compare_hash_broken_todo(HDC hdc, const BITMAPINFO *bmi, BYTE *bits, const char *info, int num_broken, BOOL todo) -{ - char *hash = hash_dib(hdc, bmi, bits); - BOOL ok_cond; - int i; - - /* reset the bits for the next test */ - reset_bits( hdc, bmi, bits ); - - if(!hash) - { - skip("SHA1 hashing unavailable on this platform\n"); - return; - } - - for(i = 0; i <= num_broken; i++) - { - if(current_sha1[i] == NULL) - { - ok(current_sha1[i] != NULL, "missing hash, got "%s",\n", hash); - HeapFree(GetProcessHeap(), 0, hash); - return; - } - } - - ok_cond = !strcmp(hash, *current_sha1); - - for(i = 1; i <= num_broken; i++) - ok_cond = ok_cond || broken( !strcmp(hash, current_sha1[i]) ); - - todo_wine_if(todo) - ok( ok_cond, "%s: %s: expected hash %s got %s\n", - dst_format, info, *current_sha1, hash ); - - current_sha1 += num_broken + 1; - - HeapFree(GetProcessHeap(), 0, hash); - - compare_bounds( hdc, info ); -} - -static void compare_hash(HDC hdc, const BITMAPINFO *bmi, BYTE *bits, const char *info) -{ - compare_hash_broken_todo(hdc, bmi, bits, info, 0, FALSE); -} - static const RECT bias_check[] = { {100, 100, 200, 150}, @@ -1621,129 +1412,6 @@ static const DWORD four_by_four_data[16] = { 0x000000, 0xff0000, 0x00ff00, 0x000 static const DWORD ddb_brush_bits[8] = { 0x11112222, 0x33334444, 0x55556666, 0x77778888, 0xaaaaaaaa, 0x00000000, 0x98765432, 0xabcdef00 };
-static const RGBQUAD default_palette_1[2] = -{ - { 0x00, 0x00, 0x00 }, { 0xff, 0xff, 0xff } -}; - -static const RGBQUAD default_palette_4[16] = -{ - { 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x80 }, { 0x00, 0x80, 0x00 }, { 0x00, 0x80, 0x80 }, - { 0x80, 0x00, 0x00 }, { 0x80, 0x00, 0x80 }, { 0x80, 0x80, 0x00 }, { 0x80, 0x80, 0x80 }, - { 0xc0, 0xc0, 0xc0 }, { 0x00, 0x00, 0xff }, { 0x00, 0xff, 0x00 }, { 0x00, 0xff, 0xff }, - { 0xff, 0x00, 0x00 }, { 0xff, 0x00, 0xff }, { 0xff, 0xff, 0x00 }, { 0xff, 0xff, 0xff }, -}; - -static const RGBQUAD default_palette_8[256] = -{ - { 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x80 }, { 0x00, 0x80, 0x00 }, { 0x00, 0x80, 0x80 }, - { 0x80, 0x00, 0x00 }, { 0x80, 0x00, 0x80 }, { 0x80, 0x80, 0x00 }, { 0xc0, 0xc0, 0xc0 }, - { 0xc0, 0xdc, 0xc0 }, { 0xf0, 0xca, 0xa6 }, { 0x00, 0x20, 0x40 }, { 0x00, 0x20, 0x60 }, - { 0x00, 0x20, 0x80 }, { 0x00, 0x20, 0xa0 }, { 0x00, 0x20, 0xc0 }, { 0x00, 0x20, 0xe0 }, - { 0x00, 0x40, 0x00 }, { 0x00, 0x40, 0x20 }, { 0x00, 0x40, 0x40 }, { 0x00, 0x40, 0x60 }, - { 0x00, 0x40, 0x80 }, { 0x00, 0x40, 0xa0 }, { 0x00, 0x40, 0xc0 }, { 0x00, 0x40, 0xe0 }, - { 0x00, 0x60, 0x00 }, { 0x00, 0x60, 0x20 }, { 0x00, 0x60, 0x40 }, { 0x00, 0x60, 0x60 }, - { 0x00, 0x60, 0x80 }, { 0x00, 0x60, 0xa0 }, { 0x00, 0x60, 0xc0 }, { 0x00, 0x60, 0xe0 }, - { 0x00, 0x80, 0x00 }, { 0x00, 0x80, 0x20 }, { 0x00, 0x80, 0x40 }, { 0x00, 0x80, 0x60 }, - { 0x00, 0x80, 0x80 }, { 0x00, 0x80, 0xa0 }, { 0x00, 0x80, 0xc0 }, { 0x00, 0x80, 0xe0 }, - { 0x00, 0xa0, 0x00 }, { 0x00, 0xa0, 0x20 }, { 0x00, 0xa0, 0x40 }, { 0x00, 0xa0, 0x60 }, - { 0x00, 0xa0, 0x80 }, { 0x00, 0xa0, 0xa0 }, { 0x00, 0xa0, 0xc0 }, { 0x00, 0xa0, 0xe0 }, - { 0x00, 0xc0, 0x00 }, { 0x00, 0xc0, 0x20 }, { 0x00, 0xc0, 0x40 }, { 0x00, 0xc0, 0x60 }, - { 0x00, 0xc0, 0x80 }, { 0x00, 0xc0, 0xa0 }, { 0x00, 0xc0, 0xc0 }, { 0x00, 0xc0, 0xe0 }, - { 0x00, 0xe0, 0x00 }, { 0x00, 0xe0, 0x20 }, { 0x00, 0xe0, 0x40 }, { 0x00, 0xe0, 0x60 }, - { 0x00, 0xe0, 0x80 }, { 0x00, 0xe0, 0xa0 }, { 0x00, 0xe0, 0xc0 }, { 0x00, 0xe0, 0xe0 }, - { 0x40, 0x00, 0x00 }, { 0x40, 0x00, 0x20 }, { 0x40, 0x00, 0x40 }, { 0x40, 0x00, 0x60 }, - { 0x40, 0x00, 0x80 }, { 0x40, 0x00, 0xa0 }, { 0x40, 0x00, 0xc0 }, { 0x40, 0x00, 0xe0 }, - { 0x40, 0x20, 0x00 }, { 0x40, 0x20, 0x20 }, { 0x40, 0x20, 0x40 }, { 0x40, 0x20, 0x60 }, - { 0x40, 0x20, 0x80 }, { 0x40, 0x20, 0xa0 }, { 0x40, 0x20, 0xc0 }, { 0x40, 0x20, 0xe0 }, - { 0x40, 0x40, 0x00 }, { 0x40, 0x40, 0x20 }, { 0x40, 0x40, 0x40 }, { 0x40, 0x40, 0x60 }, - { 0x40, 0x40, 0x80 }, { 0x40, 0x40, 0xa0 }, { 0x40, 0x40, 0xc0 }, { 0x40, 0x40, 0xe0 }, - { 0x40, 0x60, 0x00 }, { 0x40, 0x60, 0x20 }, { 0x40, 0x60, 0x40 }, { 0x40, 0x60, 0x60 }, - { 0x40, 0x60, 0x80 }, { 0x40, 0x60, 0xa0 }, { 0x40, 0x60, 0xc0 }, { 0x40, 0x60, 0xe0 }, - { 0x40, 0x80, 0x00 }, { 0x40, 0x80, 0x20 }, { 0x40, 0x80, 0x40 }, { 0x40, 0x80, 0x60 }, - { 0x40, 0x80, 0x80 }, { 0x40, 0x80, 0xa0 }, { 0x40, 0x80, 0xc0 }, { 0x40, 0x80, 0xe0 }, - { 0x40, 0xa0, 0x00 }, { 0x40, 0xa0, 0x20 }, { 0x40, 0xa0, 0x40 }, { 0x40, 0xa0, 0x60 }, - { 0x40, 0xa0, 0x80 }, { 0x40, 0xa0, 0xa0 }, { 0x40, 0xa0, 0xc0 }, { 0x40, 0xa0, 0xe0 }, - { 0x40, 0xc0, 0x00 }, { 0x40, 0xc0, 0x20 }, { 0x40, 0xc0, 0x40 }, { 0x40, 0xc0, 0x60 }, - { 0x40, 0xc0, 0x80 }, { 0x40, 0xc0, 0xa0 }, { 0x40, 0xc0, 0xc0 }, { 0x40, 0xc0, 0xe0 }, - { 0x40, 0xe0, 0x00 }, { 0x40, 0xe0, 0x20 }, { 0x40, 0xe0, 0x40 }, { 0x40, 0xe0, 0x60 }, - { 0x40, 0xe0, 0x80 }, { 0x40, 0xe0, 0xa0 }, { 0x40, 0xe0, 0xc0 }, { 0x40, 0xe0, 0xe0 }, - { 0x80, 0x00, 0x00 }, { 0x80, 0x00, 0x20 }, { 0x80, 0x00, 0x40 }, { 0x80, 0x00, 0x60 }, - { 0x80, 0x00, 0x80 }, { 0x80, 0x00, 0xa0 }, { 0x80, 0x00, 0xc0 }, { 0x80, 0x00, 0xe0 }, - { 0x80, 0x20, 0x00 }, { 0x80, 0x20, 0x20 }, { 0x80, 0x20, 0x40 }, { 0x80, 0x20, 0x60 }, - { 0x80, 0x20, 0x80 }, { 0x80, 0x20, 0xa0 }, { 0x80, 0x20, 0xc0 }, { 0x80, 0x20, 0xe0 }, - { 0x80, 0x40, 0x00 }, { 0x80, 0x40, 0x20 }, { 0x80, 0x40, 0x40 }, { 0x80, 0x40, 0x60 }, - { 0x80, 0x40, 0x80 }, { 0x80, 0x40, 0xa0 }, { 0x80, 0x40, 0xc0 }, { 0x80, 0x40, 0xe0 }, - { 0x80, 0x60, 0x00 }, { 0x80, 0x60, 0x20 }, { 0x80, 0x60, 0x40 }, { 0x80, 0x60, 0x60 }, - { 0x80, 0x60, 0x80 }, { 0x80, 0x60, 0xa0 }, { 0x80, 0x60, 0xc0 }, { 0x80, 0x60, 0xe0 }, - { 0x80, 0x80, 0x00 }, { 0x80, 0x80, 0x20 }, { 0x80, 0x80, 0x40 }, { 0x80, 0x80, 0x60 }, - { 0x80, 0x80, 0x80 }, { 0x80, 0x80, 0xa0 }, { 0x80, 0x80, 0xc0 }, { 0x80, 0x80, 0xe0 }, - { 0x80, 0xa0, 0x00 }, { 0x80, 0xa0, 0x20 }, { 0x80, 0xa0, 0x40 }, { 0x80, 0xa0, 0x60 }, - { 0x80, 0xa0, 0x80 }, { 0x80, 0xa0, 0xa0 }, { 0x80, 0xa0, 0xc0 }, { 0x80, 0xa0, 0xe0 }, - { 0x80, 0xc0, 0x00 }, { 0x80, 0xc0, 0x20 }, { 0x80, 0xc0, 0x40 }, { 0x80, 0xc0, 0x60 }, - { 0x80, 0xc0, 0x80 }, { 0x80, 0xc0, 0xa0 }, { 0x80, 0xc0, 0xc0 }, { 0x80, 0xc0, 0xe0 }, - { 0x80, 0xe0, 0x00 }, { 0x80, 0xe0, 0x20 }, { 0x80, 0xe0, 0x40 }, { 0x80, 0xe0, 0x60 }, - { 0x80, 0xe0, 0x80 }, { 0x80, 0xe0, 0xa0 }, { 0x80, 0xe0, 0xc0 }, { 0x80, 0xe0, 0xe0 }, - { 0xc0, 0x00, 0x00 }, { 0xc0, 0x00, 0x20 }, { 0xc0, 0x00, 0x40 }, { 0xc0, 0x00, 0x60 }, - { 0xc0, 0x00, 0x80 }, { 0xc0, 0x00, 0xa0 }, { 0xc0, 0x00, 0xc0 }, { 0xc0, 0x00, 0xe0 }, - { 0xc0, 0x20, 0x00 }, { 0xc0, 0x20, 0x20 }, { 0xc0, 0x20, 0x40 }, { 0xc0, 0x20, 0x60 }, - { 0xc0, 0x20, 0x80 }, { 0xc0, 0x20, 0xa0 }, { 0xc0, 0x20, 0xc0 }, { 0xc0, 0x20, 0xe0 }, - { 0xc0, 0x40, 0x00 }, { 0xc0, 0x40, 0x20 }, { 0xc0, 0x40, 0x40 }, { 0xc0, 0x40, 0x60 }, - { 0xc0, 0x40, 0x80 }, { 0xc0, 0x40, 0xa0 }, { 0xc0, 0x40, 0xc0 }, { 0xc0, 0x40, 0xe0 }, - { 0xc0, 0x60, 0x00 }, { 0xc0, 0x60, 0x20 }, { 0xc0, 0x60, 0x40 }, { 0xc0, 0x60, 0x60 }, - { 0xc0, 0x60, 0x80 }, { 0xc0, 0x60, 0xa0 }, { 0xc0, 0x60, 0xc0 }, { 0xc0, 0x60, 0xe0 }, - { 0xc0, 0x80, 0x00 }, { 0xc0, 0x80, 0x20 }, { 0xc0, 0x80, 0x40 }, { 0xc0, 0x80, 0x60 }, - { 0xc0, 0x80, 0x80 }, { 0xc0, 0x80, 0xa0 }, { 0xc0, 0x80, 0xc0 }, { 0xc0, 0x80, 0xe0 }, - { 0xc0, 0xa0, 0x00 }, { 0xc0, 0xa0, 0x20 }, { 0xc0, 0xa0, 0x40 }, { 0xc0, 0xa0, 0x60 }, - { 0xc0, 0xa0, 0x80 }, { 0xc0, 0xa0, 0xa0 }, { 0xc0, 0xa0, 0xc0 }, { 0xc0, 0xa0, 0xe0 }, - { 0xc0, 0xc0, 0x00 }, { 0xc0, 0xc0, 0x20 }, { 0xc0, 0xc0, 0x40 }, { 0xc0, 0xc0, 0x60 }, - { 0xc0, 0xc0, 0x80 }, { 0xc0, 0xc0, 0xa0 }, { 0xf0, 0xfb, 0xff }, { 0xa4, 0xa0, 0xa0 }, - { 0x80, 0x80, 0x80 }, { 0x00, 0x00, 0xff }, { 0x00, 0xff, 0x00 }, { 0x00, 0xff, 0xff }, - { 0xff, 0x00, 0x00 }, { 0xff, 0x00, 0xff }, { 0xff, 0xff, 0x00 }, { 0xff, 0xff, 0xff } -}; - -static HPALETTE create_default_palette( int bpp ) -{ - char pal_buffer[sizeof(LOGPALETTE) + 255 * sizeof(PALETTEENTRY)]; - LOGPALETTE *pal = (LOGPALETTE *)pal_buffer; - PALETTEENTRY *entries = pal->palPalEntry; - int i; - - pal->palVersion = 0x300; - pal->palNumEntries = 1 << bpp; - switch (bpp) - { - case 1: - for (i = 0; i < 2; i++) - { - entries[i].peRed = default_palette_1[i].rgbRed; - entries[i].peGreen = default_palette_1[i].rgbGreen; - entries[i].peBlue = default_palette_1[i].rgbBlue; - entries[i].peFlags = 0; - } - break; - case 4: - for (i = 0; i < 16; i++) - { - entries[i].peRed = default_palette_4[i].rgbRed; - entries[i].peGreen = default_palette_4[i].rgbGreen; - entries[i].peBlue = default_palette_4[i].rgbBlue; - entries[i].peFlags = 0; - } - break; - case 8: - for (i = 0; i < 256; i++) - { - entries[i].peRed = default_palette_8[i].rgbRed; - entries[i].peGreen = default_palette_8[i].rgbGreen; - entries[i].peBlue = default_palette_8[i].rgbBlue; - entries[i].peFlags = 0; - } - break; - } - return CreatePalette( pal ); -} - static inline void solid_patblt( HDC hdc, int x, int y, int width, int height, COLORREF color ) { HBRUSH brush = CreateSolidBrush( color ); diff --git a/dlls/gdi32/tests/misc.c b/dlls/gdi32/tests/misc.c new file mode 100644 index 00000000000..828be2745a0 --- /dev/null +++ b/dlls/gdi32/tests/misc.c @@ -0,0 +1,425 @@ + + +#include <stdarg.h> +#include <stdio.h> +#include <math.h> + +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" +#include "wincrypt.h" +#include "mmsystem.h" /* DIBINDEX */ + +#include "wine/test.h" +#include "misc.h" + +const char **current_sha1; +const RECT *current_bounds; +const char *dst_format; +HCRYPTPROV crypt_prov; + +static const RECT graphics_bounds[] = +{ + { 0, 0, 0, 0 }, + { 10, 3, 219, 101 }, + { 100, 100, 301, 301 }, + { 0, 0, 201, 201 }, + { 10, 10, 110, 320 }, + { 10, 99, 300, 200 }, + { 99, 12, 201, 200 }, + { 90, 110, 300, 200 }, + { 90, 90, 210, 200 }, + { 10, 99, 300, 200 }, + { 10, 99, 300, 200 }, + { 99, 12, 201, 200 }, + { 99, 11, 201, 200 }, + { 90, 110, 300, 200 }, + { 90, 110, 300, 200 }, + { 10, 10, 365, 405 }, + { 10, 10, 365, 405 }, + { 10, 10, 365, 405 }, + { 10, 10, 365, 405 }, + { 10, 10, 365, 405 }, + { 10, 10, 365, 405 }, + { 10, 10, 365, 405 }, + { 10, 10, 365, 405 }, + { 10, 10, 350, 251 }, + { 10, 10, 300, 200 }, + { 300, 10, 9, 260 }, + { 10, 10, 435, 405 }, + { 10, 10, 120, 120 }, + { 10, 10, 110, 110 }, + { 10, 10, 120, 110 }, + { 10, 10, 110, 120 }, + { 10, 10, 120, 120 }, + { 10, 10, 110, 110 }, + { 10, 10, 120, 110 }, + { 10, 10, 110, 120 }, + { 0, 4, 356, 356 }, + { 100, 100, 356, 356 }, + { 50, 50, 306, 306 }, + { 100, 100, 356, 356 }, + { 100, 100, 356, 356 }, + { 100, 100, 356, 356 }, + { 100, 100, 356, 356 }, + { 100, 100, 356, 356 }, + { 100, 100, 356, 356 }, + { 100, 100, 356, 356 }, + { 100, 100, 356, 356 }, + { 100, 100, 356, 356 }, + { 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, 0, 512, 512 }, + { 0, 10, 511, 306 }, + { 0, 0, 512, 336 }, + { 1, 1, 300, 512 }, + { 0, 0, 500, 512 }, + { 5, 5, 206, 206 }, + { 45, 45, 256, 256 }, + { 86, 86, 215, 215 }, + { 45, 45, 256, 256 }, + { 8, 0, 392, 231 }, + { 8, 0, 392, 231 }, + { 0, 0, 60, 20 }, + { 0, 0, 512, 512 }, + { -1, -1, -1, -1 } /* the end */ +}; + +static const RGBQUAD default_palette_1[2] = +{ + { 0x00, 0x00, 0x00 }, { 0xff, 0xff, 0xff } +}; + +static const RGBQUAD default_palette_4[16] = +{ + { 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x80 }, { 0x00, 0x80, 0x00 }, { 0x00, 0x80, 0x80 }, + { 0x80, 0x00, 0x00 }, { 0x80, 0x00, 0x80 }, { 0x80, 0x80, 0x00 }, { 0x80, 0x80, 0x80 }, + { 0xc0, 0xc0, 0xc0 }, { 0x00, 0x00, 0xff }, { 0x00, 0xff, 0x00 }, { 0x00, 0xff, 0xff }, + { 0xff, 0x00, 0x00 }, { 0xff, 0x00, 0xff }, { 0xff, 0xff, 0x00 }, { 0xff, 0xff, 0xff }, +}; + +static const RGBQUAD default_palette_8[256] = +{ + { 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x80 }, { 0x00, 0x80, 0x00 }, { 0x00, 0x80, 0x80 }, + { 0x80, 0x00, 0x00 }, { 0x80, 0x00, 0x80 }, { 0x80, 0x80, 0x00 }, { 0xc0, 0xc0, 0xc0 }, + { 0xc0, 0xdc, 0xc0 }, { 0xf0, 0xca, 0xa6 }, { 0x00, 0x20, 0x40 }, { 0x00, 0x20, 0x60 }, + { 0x00, 0x20, 0x80 }, { 0x00, 0x20, 0xa0 }, { 0x00, 0x20, 0xc0 }, { 0x00, 0x20, 0xe0 }, + { 0x00, 0x40, 0x00 }, { 0x00, 0x40, 0x20 }, { 0x00, 0x40, 0x40 }, { 0x00, 0x40, 0x60 }, + { 0x00, 0x40, 0x80 }, { 0x00, 0x40, 0xa0 }, { 0x00, 0x40, 0xc0 }, { 0x00, 0x40, 0xe0 }, + { 0x00, 0x60, 0x00 }, { 0x00, 0x60, 0x20 }, { 0x00, 0x60, 0x40 }, { 0x00, 0x60, 0x60 }, + { 0x00, 0x60, 0x80 }, { 0x00, 0x60, 0xa0 }, { 0x00, 0x60, 0xc0 }, { 0x00, 0x60, 0xe0 }, + { 0x00, 0x80, 0x00 }, { 0x00, 0x80, 0x20 }, { 0x00, 0x80, 0x40 }, { 0x00, 0x80, 0x60 }, + { 0x00, 0x80, 0x80 }, { 0x00, 0x80, 0xa0 }, { 0x00, 0x80, 0xc0 }, { 0x00, 0x80, 0xe0 }, + { 0x00, 0xa0, 0x00 }, { 0x00, 0xa0, 0x20 }, { 0x00, 0xa0, 0x40 }, { 0x00, 0xa0, 0x60 }, + { 0x00, 0xa0, 0x80 }, { 0x00, 0xa0, 0xa0 }, { 0x00, 0xa0, 0xc0 }, { 0x00, 0xa0, 0xe0 }, + { 0x00, 0xc0, 0x00 }, { 0x00, 0xc0, 0x20 }, { 0x00, 0xc0, 0x40 }, { 0x00, 0xc0, 0x60 }, + { 0x00, 0xc0, 0x80 }, { 0x00, 0xc0, 0xa0 }, { 0x00, 0xc0, 0xc0 }, { 0x00, 0xc0, 0xe0 }, + { 0x00, 0xe0, 0x00 }, { 0x00, 0xe0, 0x20 }, { 0x00, 0xe0, 0x40 }, { 0x00, 0xe0, 0x60 }, + { 0x00, 0xe0, 0x80 }, { 0x00, 0xe0, 0xa0 }, { 0x00, 0xe0, 0xc0 }, { 0x00, 0xe0, 0xe0 }, + { 0x40, 0x00, 0x00 }, { 0x40, 0x00, 0x20 }, { 0x40, 0x00, 0x40 }, { 0x40, 0x00, 0x60 }, + { 0x40, 0x00, 0x80 }, { 0x40, 0x00, 0xa0 }, { 0x40, 0x00, 0xc0 }, { 0x40, 0x00, 0xe0 }, + { 0x40, 0x20, 0x00 }, { 0x40, 0x20, 0x20 }, { 0x40, 0x20, 0x40 }, { 0x40, 0x20, 0x60 }, + { 0x40, 0x20, 0x80 }, { 0x40, 0x20, 0xa0 }, { 0x40, 0x20, 0xc0 }, { 0x40, 0x20, 0xe0 }, + { 0x40, 0x40, 0x00 }, { 0x40, 0x40, 0x20 }, { 0x40, 0x40, 0x40 }, { 0x40, 0x40, 0x60 }, + { 0x40, 0x40, 0x80 }, { 0x40, 0x40, 0xa0 }, { 0x40, 0x40, 0xc0 }, { 0x40, 0x40, 0xe0 }, + { 0x40, 0x60, 0x00 }, { 0x40, 0x60, 0x20 }, { 0x40, 0x60, 0x40 }, { 0x40, 0x60, 0x60 }, + { 0x40, 0x60, 0x80 }, { 0x40, 0x60, 0xa0 }, { 0x40, 0x60, 0xc0 }, { 0x40, 0x60, 0xe0 }, + { 0x40, 0x80, 0x00 }, { 0x40, 0x80, 0x20 }, { 0x40, 0x80, 0x40 }, { 0x40, 0x80, 0x60 }, + { 0x40, 0x80, 0x80 }, { 0x40, 0x80, 0xa0 }, { 0x40, 0x80, 0xc0 }, { 0x40, 0x80, 0xe0 }, + { 0x40, 0xa0, 0x00 }, { 0x40, 0xa0, 0x20 }, { 0x40, 0xa0, 0x40 }, { 0x40, 0xa0, 0x60 }, + { 0x40, 0xa0, 0x80 }, { 0x40, 0xa0, 0xa0 }, { 0x40, 0xa0, 0xc0 }, { 0x40, 0xa0, 0xe0 }, + { 0x40, 0xc0, 0x00 }, { 0x40, 0xc0, 0x20 }, { 0x40, 0xc0, 0x40 }, { 0x40, 0xc0, 0x60 }, + { 0x40, 0xc0, 0x80 }, { 0x40, 0xc0, 0xa0 }, { 0x40, 0xc0, 0xc0 }, { 0x40, 0xc0, 0xe0 }, + { 0x40, 0xe0, 0x00 }, { 0x40, 0xe0, 0x20 }, { 0x40, 0xe0, 0x40 }, { 0x40, 0xe0, 0x60 }, + { 0x40, 0xe0, 0x80 }, { 0x40, 0xe0, 0xa0 }, { 0x40, 0xe0, 0xc0 }, { 0x40, 0xe0, 0xe0 }, + { 0x80, 0x00, 0x00 }, { 0x80, 0x00, 0x20 }, { 0x80, 0x00, 0x40 }, { 0x80, 0x00, 0x60 }, + { 0x80, 0x00, 0x80 }, { 0x80, 0x00, 0xa0 }, { 0x80, 0x00, 0xc0 }, { 0x80, 0x00, 0xe0 }, + { 0x80, 0x20, 0x00 }, { 0x80, 0x20, 0x20 }, { 0x80, 0x20, 0x40 }, { 0x80, 0x20, 0x60 }, + { 0x80, 0x20, 0x80 }, { 0x80, 0x20, 0xa0 }, { 0x80, 0x20, 0xc0 }, { 0x80, 0x20, 0xe0 }, + { 0x80, 0x40, 0x00 }, { 0x80, 0x40, 0x20 }, { 0x80, 0x40, 0x40 }, { 0x80, 0x40, 0x60 }, + { 0x80, 0x40, 0x80 }, { 0x80, 0x40, 0xa0 }, { 0x80, 0x40, 0xc0 }, { 0x80, 0x40, 0xe0 }, + { 0x80, 0x60, 0x00 }, { 0x80, 0x60, 0x20 }, { 0x80, 0x60, 0x40 }, { 0x80, 0x60, 0x60 }, + { 0x80, 0x60, 0x80 }, { 0x80, 0x60, 0xa0 }, { 0x80, 0x60, 0xc0 }, { 0x80, 0x60, 0xe0 }, + { 0x80, 0x80, 0x00 }, { 0x80, 0x80, 0x20 }, { 0x80, 0x80, 0x40 }, { 0x80, 0x80, 0x60 }, + { 0x80, 0x80, 0x80 }, { 0x80, 0x80, 0xa0 }, { 0x80, 0x80, 0xc0 }, { 0x80, 0x80, 0xe0 }, + { 0x80, 0xa0, 0x00 }, { 0x80, 0xa0, 0x20 }, { 0x80, 0xa0, 0x40 }, { 0x80, 0xa0, 0x60 }, + { 0x80, 0xa0, 0x80 }, { 0x80, 0xa0, 0xa0 }, { 0x80, 0xa0, 0xc0 }, { 0x80, 0xa0, 0xe0 }, + { 0x80, 0xc0, 0x00 }, { 0x80, 0xc0, 0x20 }, { 0x80, 0xc0, 0x40 }, { 0x80, 0xc0, 0x60 }, + { 0x80, 0xc0, 0x80 }, { 0x80, 0xc0, 0xa0 }, { 0x80, 0xc0, 0xc0 }, { 0x80, 0xc0, 0xe0 }, + { 0x80, 0xe0, 0x00 }, { 0x80, 0xe0, 0x20 }, { 0x80, 0xe0, 0x40 }, { 0x80, 0xe0, 0x60 }, + { 0x80, 0xe0, 0x80 }, { 0x80, 0xe0, 0xa0 }, { 0x80, 0xe0, 0xc0 }, { 0x80, 0xe0, 0xe0 }, + { 0xc0, 0x00, 0x00 }, { 0xc0, 0x00, 0x20 }, { 0xc0, 0x00, 0x40 }, { 0xc0, 0x00, 0x60 }, + { 0xc0, 0x00, 0x80 }, { 0xc0, 0x00, 0xa0 }, { 0xc0, 0x00, 0xc0 }, { 0xc0, 0x00, 0xe0 }, + { 0xc0, 0x20, 0x00 }, { 0xc0, 0x20, 0x20 }, { 0xc0, 0x20, 0x40 }, { 0xc0, 0x20, 0x60 }, + { 0xc0, 0x20, 0x80 }, { 0xc0, 0x20, 0xa0 }, { 0xc0, 0x20, 0xc0 }, { 0xc0, 0x20, 0xe0 }, + { 0xc0, 0x40, 0x00 }, { 0xc0, 0x40, 0x20 }, { 0xc0, 0x40, 0x40 }, { 0xc0, 0x40, 0x60 }, + { 0xc0, 0x40, 0x80 }, { 0xc0, 0x40, 0xa0 }, { 0xc0, 0x40, 0xc0 }, { 0xc0, 0x40, 0xe0 }, + { 0xc0, 0x60, 0x00 }, { 0xc0, 0x60, 0x20 }, { 0xc0, 0x60, 0x40 }, { 0xc0, 0x60, 0x60 }, + { 0xc0, 0x60, 0x80 }, { 0xc0, 0x60, 0xa0 }, { 0xc0, 0x60, 0xc0 }, { 0xc0, 0x60, 0xe0 }, + { 0xc0, 0x80, 0x00 }, { 0xc0, 0x80, 0x20 }, { 0xc0, 0x80, 0x40 }, { 0xc0, 0x80, 0x60 }, + { 0xc0, 0x80, 0x80 }, { 0xc0, 0x80, 0xa0 }, { 0xc0, 0x80, 0xc0 }, { 0xc0, 0x80, 0xe0 }, + { 0xc0, 0xa0, 0x00 }, { 0xc0, 0xa0, 0x20 }, { 0xc0, 0xa0, 0x40 }, { 0xc0, 0xa0, 0x60 }, + { 0xc0, 0xa0, 0x80 }, { 0xc0, 0xa0, 0xa0 }, { 0xc0, 0xa0, 0xc0 }, { 0xc0, 0xa0, 0xe0 }, + { 0xc0, 0xc0, 0x00 }, { 0xc0, 0xc0, 0x20 }, { 0xc0, 0xc0, 0x40 }, { 0xc0, 0xc0, 0x60 }, + { 0xc0, 0xc0, 0x80 }, { 0xc0, 0xc0, 0xa0 }, { 0xf0, 0xfb, 0xff }, { 0xa4, 0xa0, 0xa0 }, + { 0x80, 0x80, 0x80 }, { 0x00, 0x00, 0xff }, { 0x00, 0xff, 0x00 }, { 0x00, 0xff, 0xff }, + { 0xff, 0x00, 0x00 }, { 0xff, 0x00, 0xff }, { 0xff, 0xff, 0x00 }, { 0xff, 0xff, 0xff } +}; + +HPALETTE create_default_palette( int bpp ) +{ + char pal_buffer[sizeof(LOGPALETTE) + 255 * sizeof(PALETTEENTRY)]; + LOGPALETTE *pal = (LOGPALETTE *)pal_buffer; + PALETTEENTRY *entries = pal->palPalEntry; + int i; + + pal->palVersion = 0x300; + pal->palNumEntries = 1 << bpp; + switch (bpp) + { + case 1: + for (i = 0; i < 2; i++) + { + entries[i].peRed = default_palette_1[i].rgbRed; + entries[i].peGreen = default_palette_1[i].rgbGreen; + entries[i].peBlue = default_palette_1[i].rgbBlue; + entries[i].peFlags = 0; + } + break; + case 4: + for (i = 0; i < 16; i++) + { + entries[i].peRed = default_palette_4[i].rgbRed; + entries[i].peGreen = default_palette_4[i].rgbGreen; + entries[i].peBlue = default_palette_4[i].rgbBlue; + entries[i].peFlags = 0; + } + break; + case 8: + for (i = 0; i < 256; i++) + { + entries[i].peRed = default_palette_8[i].rgbRed; + entries[i].peGreen = default_palette_8[i].rgbGreen; + entries[i].peBlue = default_palette_8[i].rgbBlue; + entries[i].peFlags = 0; + } + break; + } + return CreatePalette( pal ); +} + +void reset_bits( HDC hdc, const BITMAPINFO *bmi, BYTE *bits ) +{ + DWORD size = get_dib_size( bmi ); + if (bits) memset( bits, 0xcc, size ); + else + { + void *ddb_bits = HeapAlloc( GetProcessHeap(), 0, size ); + memset( ddb_bits, 0xcc, size ); + SetBitmapBits( GetCurrentObject(hdc, OBJ_BITMAP), size, ddb_bits ); + HeapFree( GetProcessHeap(), 0, ddb_bits ); + } +} + +char *hash_dib(HDC hdc, const BITMAPINFO *bmi, const void *bits) +{ + DWORD dib_size = get_dib_size(bmi); + HCRYPTHASH hash; + char *buf; + BYTE hash_buf[20]; + DWORD hash_size = sizeof(hash_buf); + int i; + static const char *hex = "0123456789abcdef"; + + if(!crypt_prov) return NULL; + + if(!CryptCreateHash(crypt_prov, CALG_SHA1, 0, 0, &hash)) return NULL; + + if (!bits) + { + void *ddb_bits = HeapAlloc( GetProcessHeap(), 0, dib_size ); + GetBitmapBits( GetCurrentObject(hdc, OBJ_BITMAP), dib_size, ddb_bits ); + CryptHashData(hash, ddb_bits, dib_size, 0); + HeapFree( GetProcessHeap(), 0, ddb_bits ); + } + else CryptHashData(hash, bits, dib_size, 0); + + CryptGetHashParam(hash, HP_HASHVAL, NULL, &hash_size, 0); + if(hash_size != sizeof(hash_buf)) return NULL; + + CryptGetHashParam(hash, HP_HASHVAL, hash_buf, &hash_size, 0); + CryptDestroyHash(hash); + + buf = HeapAlloc(GetProcessHeap(), 0, hash_size * 2 + 1); + + for(i = 0; i < hash_size; i++) + { + buf[i * 2] = hex[hash_buf[i] >> 4]; + buf[i * 2 + 1] = hex[hash_buf[i] & 0xf]; + } + buf[i * 2] = '\0'; + + return buf; +} + +void reset_bounds( HDC hdc ) +{ + current_bounds = graphics_bounds; + SetBoundsRect( hdc, NULL, DCB_RESET | DCB_ENABLE ); +} + +void compare_bounds( HDC hdc, const char *info ) +{ + RECT rect; + + GetBoundsRect( hdc, &rect, DCB_RESET ); + + if (current_bounds->left == -1 && + current_bounds->top == -1 && + current_bounds->right == -1 && + current_bounds->bottom == -1) + { + ok( 0, "missing bounds, got %s,\n", wine_dbgstr_rect( &rect )); + return; + } + + ok( EqualRect( current_bounds, &rect ), "%s: %s: expected bounds %s got %s\n", dst_format, info, + wine_dbgstr_rect( current_bounds ), wine_dbgstr_rect( &rect )); + current_bounds++; +} + +void compare_hash_broken_todo(HDC hdc, const BITMAPINFO *bmi, BYTE *bits, const char *info, int num_broken, BOOL todo) +{ + char *hash = hash_dib(hdc, bmi, bits); + BOOL ok_cond; + int i; + + /* reset the bits for the next test */ + reset_bits( hdc, bmi, bits ); + + if(!hash) + { + skip("SHA1 hashing unavailable on this platform\n"); + return; + } + + for(i = 0; i <= num_broken; i++) + { + if(current_sha1[i] == NULL) + { + ok(current_sha1[i] != NULL, "missing hash, got "%s",\n", hash); + HeapFree(GetProcessHeap(), 0, hash); + return; + } + } + + ok_cond = !strcmp(hash, *current_sha1); + + for(i = 1; i <= num_broken; i++) + ok_cond = ok_cond || broken( !strcmp(hash, current_sha1[i]) ); + + todo_wine_if(todo) + ok( ok_cond, "%s: %s: expected hash %s got %s\n", + dst_format, info, *current_sha1, hash ); + + current_sha1 += num_broken + 1; + + HeapFree(GetProcessHeap(), 0, hash); + + compare_bounds( hdc, info ); +} + +void compare_hash(HDC hdc, const BITMAPINFO *bmi, BYTE *bits, const char *info) +{ + compare_hash_broken_todo(hdc, bmi, bits, info, 0, FALSE); +} + +BOOL SaveHBITMAPToFile(HBITMAP hBitmap, LPSTR lpszFileName) +{ + HDC hDC; + int iBits; + WORD wBitCount; + DWORD dwPaletteSize = 0, dwBmBitsSize = 0, dwDIBSize = 0, dwWritten = 0; + BITMAP Bitmap0; + BITMAPFILEHEADER bmfHdr; + BITMAPINFOHEADER bi; + LPBITMAPINFOHEADER lpbi; + HANDLE fh, hDib, hPal, hOldPal2 = NULL; + hDC = CreateDCA("DISPLAY", NULL, NULL, NULL); + iBits = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES); + DeleteDC(hDC); + if (iBits <= 1) + wBitCount = 1; + else if (iBits <= 4) + wBitCount = 4; + else if (iBits <= 8) + wBitCount = 8; + else + wBitCount = 24; + GetObjectA(hBitmap, sizeof(Bitmap0), (LPSTR)&Bitmap0); + bi.biSize = sizeof(BITMAPINFOHEADER); + bi.biWidth = Bitmap0.bmWidth; + bi.biHeight = -Bitmap0.bmHeight; + bi.biPlanes = 1; + bi.biBitCount = wBitCount; + bi.biCompression = BI_RGB; + bi.biSizeImage = 0; + bi.biXPelsPerMeter = 0; + bi.biYPelsPerMeter = 0; + bi.biClrImportant = 0; + bi.biClrUsed = 256; + dwBmBitsSize = ((Bitmap0.bmWidth * wBitCount + 31) & ~31) / 8 + * Bitmap0.bmHeight; + hDib = GlobalAlloc(GHND, dwBmBitsSize + dwPaletteSize + sizeof(BITMAPINFOHEADER)); + lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib); + *lpbi = bi; + + hPal = GetStockObject(DEFAULT_PALETTE); + if (hPal) + { + hDC = GetDC(NULL); + hOldPal2 = SelectPalette(hDC, (HPALETTE)hPal, FALSE); + RealizePalette(hDC); + } + + + GetDIBits(hDC, hBitmap, 0, (UINT)Bitmap0.bmHeight, (LPSTR)lpbi + sizeof(BITMAPINFOHEADER) + + dwPaletteSize, (BITMAPINFO *)lpbi, DIB_RGB_COLORS); + + if (hOldPal2) + { + SelectPalette(hDC, (HPALETTE)hOldPal2, TRUE); + RealizePalette(hDC); + ReleaseDC(NULL, hDC); + } + + fh = CreateFileA(lpszFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); + + if (fh == INVALID_HANDLE_VALUE) + return FALSE; + + bmfHdr.bfType = 0x4D42; // "BM" + dwDIBSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwPaletteSize + dwBmBitsSize; + bmfHdr.bfSize = dwDIBSize; + bmfHdr.bfReserved1 = 0; + bmfHdr.bfReserved2 = 0; + bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER) + dwPaletteSize; + + WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL); + + WriteFile(fh, (LPSTR)lpbi, dwDIBSize, &dwWritten, NULL); + GlobalUnlock(hDib); + GlobalFree(hDib); + CloseHandle(fh); + return TRUE; +} + +void func_misc() +{ +} diff --git a/dlls/gdi32/tests/misc.h b/dlls/gdi32/tests/misc.h new file mode 100644 index 00000000000..719a360d23d --- /dev/null +++ b/dlls/gdi32/tests/misc.h @@ -0,0 +1,31 @@ + +#ifndef MISC_H +#define MISC_H + +#include "windef.h" + +extern const char **current_sha1; +extern const RECT *current_bounds; +extern HCRYPTPROV crypt_prov; + +HPALETTE create_default_palette( int bpp ); + +static inline DWORD get_stride(const BITMAPINFO *bmi) +{ + return ((bmi->bmiHeader.biBitCount * bmi->bmiHeader.biWidth + 31) >> 3) & ~3; +} + +static inline DWORD get_dib_size(const BITMAPINFO *bmi) +{ + return get_stride(bmi) * abs(bmi->bmiHeader.biHeight); +} + +void reset_bits( HDC hdc, const BITMAPINFO *bmi, BYTE *bits ); +char *hash_dib(HDC hdc, const BITMAPINFO *bmi, const void *bits); +void reset_bounds( HDC hdc ); +void compare_bounds( HDC hdc, const char *info ); +void compare_hash_broken_todo(HDC hdc, const BITMAPINFO *bmi, BYTE *bits, const char *info, int num_broken, BOOL todo); +void compare_hash(HDC hdc, const BITMAPINFO *bmi, BYTE *bits, const char *info); + +BOOL SaveHBITMAPToFile(HBITMAP hBitmap, LPSTR lpszFileName); +#endif
Because drawing simple lines already gives different results than a native Windows, the comparison of hashes does not work anymore.
Therefore, the advanced test creates bitmap files for each processed test, which can then be compared visually.
Signed-off-by: Ralf Habacker ralf.habacker@freenet.de --- dlls/gdi32/tests/Makefile.in | 1 + dlls/gdi32/tests/advanced.c | 186 +++++++++++++++++++++++++++++++++++ 2 files changed, 187 insertions(+) create mode 100644 dlls/gdi32/tests/advanced.c
diff --git a/dlls/gdi32/tests/Makefile.in b/dlls/gdi32/tests/Makefile.in index ad8f0ce8bad..2cdb1e42e4c 100644 --- a/dlls/gdi32/tests/Makefile.in +++ b/dlls/gdi32/tests/Makefile.in @@ -2,6 +2,7 @@ TESTDLL = gdi32.dll IMPORTS = user32 gdi32 advapi32
C_SRCS = \ + advanced.c \ bitmap.c \ brush.c \ clipping.c \ diff --git a/dlls/gdi32/tests/advanced.c b/dlls/gdi32/tests/advanced.c new file mode 100644 index 00000000000..2810d2076d1 --- /dev/null +++ b/dlls/gdi32/tests/advanced.c @@ -0,0 +1,186 @@ +#include <stdarg.h> +#include <stdio.h> +#include <math.h> + +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" +#include "wincrypt.h" +#include "mmsystem.h" /* DIBINDEX */ + +#include "wine/test.h" +#include "misc.h" + +/* Comparing hashes does not work because drawing simple lines is already different from native win32 */ +/* #define WITH_HASH */ + +typedef struct { + HDC dc; + BITMAPINFO *bmi; + BYTE *bits; + HBITMAP dib; +#ifdef WITH_HASH + char *hash_dib; +#endif + char test_name[1024]; + char save_path[MAX_PATH]; + char hash_name[1024]; + RECT bounds; + double angle; + double shearX; +} test_data; + +static test_data _test_data; +test_data *td = &_test_data; + +double radians ( double d ) +{ + return d * M_PI / 180; +} + +void set_transform( HDC dc, RECT *bounds, double angle ) +{ + XFORM xf; + double r = radians( angle ); + xf.eM11 = cos( r ) + sin( r ) * td->shearX; + xf.eM22 = cos( r ); + xf.eM12 = -sin( r ); + xf.eM21 = sin( r ) + cos( r ) * td->shearX; + xf.eDx = ( bounds->right - bounds->left ) / 4; + xf.eDy = ( bounds->bottom - bounds->top ) / 4; + SetWorldTransform( dc, &xf ); +} + +BOOL save_bitmap( test_data *td ) +{ + return SaveHBITMAPToFile( td->dib, td->save_path ); +} + +void init( test_data *td, const char *test_name ) +{ + sprintf( td->test_name, "%s", test_name ); + sprintf( td->save_path, "%s-%3.1f-%2.1f.bmp", td->test_name, td->shearX, td->angle ); + sprintf( td->hash_name, "sha1_advanced_%s_%3.1f_%2.1f", td->test_name, td->shearX, td->angle ); + trace( "%s\n", td->test_name ); + reset_bits( td->dc, td->bmi, td->bits ); + MoveToEx( td->dc, -5, 0, NULL ); + LineTo( td->dc, 5, 0 ); + MoveToEx( td->dc, 0, 5, NULL ); + LineTo( td->dc, 0, -5 ); +} + +void check_hash( test_data *td ) +{ +#ifdef WITH_HASH + if ( td->hash_dib ) + HeapFree( GetProcessHeap(), 0, td->hash_dib ); + td->hash_dib = hash_dib( td->dc, td->bmi, td->bits ); + printf( "const char *%s = "%s";\n", td->hash_name, td->hash_dib ); +#endif + // instead we dump the display to a file for visual inspection + save_bitmap( td ); +} + +static void test_gdi( double angle, double shearX ) +{ + char bmibuf[sizeof( BITMAPINFO ) + 256 * sizeof( RGBQUAD )]; + HBITMAP orig_bm; + HPALETTE default_palette, old_hpal; + RECT r; + + td->bmi = ( BITMAPINFO * )bmibuf; + td->dc = CreateCompatibleDC( NULL ); + td->angle = angle; + td->shearX = shearX; + + SetGraphicsMode( td->dc, GM_ADVANCED ); + set_transform( td->dc, &td->bounds, td->angle ); + + memset( td->bmi, 0, sizeof( bmibuf )); + td->bmi->bmiHeader.biSize = sizeof( td->bmi->bmiHeader ); + td->bmi->bmiHeader.biHeight = td->bounds.right; + td->bmi->bmiHeader.biWidth = td->bounds.bottom; + td->bmi->bmiHeader.biBitCount = 32; + td->bmi->bmiHeader.biPlanes = 1; + td->bmi->bmiHeader.biCompression = BI_RGB; + + td->dib = CreateDIBSection( 0, td->bmi, DIB_RGB_COLORS, ( void** )&( td->bits ), NULL, 0 ); + orig_bm = SelectObject( td->dc, td->dib ); + + default_palette = create_default_palette( 8 ); + old_hpal = SelectPalette( td->dc, default_palette, FALSE ); + + current_bounds = &td->bounds; + SetBoundsRect( td->dc, &td->bounds, DCB_SET ); + + SetRect( &r, 0, 0, 128, 128 ); + + init( td, "LineTo" ); + MoveToEx( td->dc, r.left, r.top, NULL ); + LineTo( td->dc, r.right, r.bottom ); + check_hash( td ); + + init( td, "Rectangle" ); + ok( Rectangle( td->dc, r.left, r.top, r.right, r.bottom ), td->test_name ); + check_hash( td ); + + init( td, "Ellipse" ); + ok( Ellipse( td->dc, r.left, r.top, r.right, r.bottom ), td->test_name ); + check_hash( td ); + + init( td, "Arc" ); + ok( Arc( td->dc, r.left, r.top, r.right, r.bottom, r.left+10, r.top, r.right-10, r.bottom ), td->test_name ); + check_hash( td ); + + init( td, "ArcTo" ); + ok( ArcTo( td->dc, r.left, r.top, r.right, r.bottom, r.left+10, r.top, r.right-10, r.bottom ), td->test_name ); + check_hash( td ); + + init( td, "Chord" ); + ok( Chord( td->dc, r.left, r.top, r.right, r.bottom, r.left+10, r.top, r.right-10, r.bottom ), td->test_name ); + check_hash( td ); + + init( td, "Pie" ); + ok( Pie( td->dc, r.left, r.top, r.right, r.bottom, r.left+10, r.top, r.right-10, r.bottom ), td->test_name ); + check_hash( td ); + + init( td, "FillRect" ); + ok( FillRect( td->dc, &r, GetStockObject( WHITE_BRUSH )), td->test_name ); + check_hash( td ); + + SelectObject( td->dc, orig_bm ); + DeleteObject( td->dib ); + SelectPalette( td->dc, old_hpal, FALSE ); + DeleteDC( td->dc ); +} + +static void test_advanced_graphics( void ) +{ + td->bounds.left = 0; + td->bounds.top = 0; + td->bounds.right = 256; + td->bounds.bottom = 256; + + test_gdi( 0, 0.0 ); + test_gdi( 30, 0.0 ); + test_gdi( 60, 0.0 ); + test_gdi( 90, 0.0 ); + test_gdi( 120, 0.0 ); + test_gdi( 150, 0.0 ); + test_gdi( 0, 0.1 ); + test_gdi( 30, 0.1 ); + test_gdi( 60, 0.1 ); + test_gdi( 90, 0.1 ); + test_gdi( 120, 0.1 ); + test_gdi( 150, 0.1 ); +} + +START_TEST( advanced ) +{ + CryptAcquireContextW( &crypt_prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT ); + + test_advanced_graphics(); + + CryptReleaseContext( crypt_prov, 0 ); +}
Ralf Habacker ralf.habacker@freenet.de writes:
This is used to avoid code duplication for adding an 'advanced' gdi32 test.
That doesn't seem necessary. You can simply add the new test to dib.c.
Am 08.02.21 um 12:23 schrieb Alexandre Julliard:
Ralf Habacker ralf.habacker@freenet.de writes:
This is used to avoid code duplication for adding an 'advanced' gdi32 test.
That doesn't seem necessary. You can simply add the new test to dib.c.
Adding the new tests to dib.c with
START_TEST( advanced ) { CryptAcquireContextW( &crypt_prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT );
test_advanced_graphics();
CryptReleaseContext( crypt_prov, 0 ); }
at the end does not add the new test 'advanced' to the list of available tests.
$ ~/src/wine-build/dlls/gdi32/tests> wine ./gdi32_test.exe Valid test names: bitmap brush clipping dc dib driver font gdiobj generated icm mapping metafile palette path pen
It looks that it is recommended to place each START_TEST() macro into a separate file as it was done with all present tests.
bitmap.c:5938:START_TEST(bitmap) brush.c:364:START_TEST(brush) clipping.c:557:START_TEST(clipping) dc.c:1675:START_TEST(dc) dib.c:3200:START_TEST(dib) driver.c:792:START_TEST(driver) font.c:7723:START_TEST(font) gdiobj.c:365:START_TEST(gdiobj) generated.c:13563:START_TEST(generated) icm.c:305:START_TEST(icm) mapping.c:713:START_TEST(mapping) metafile.c:4303:START_TEST(metafile) palette.c:328:START_TEST(palette) path.c:1922:START_TEST(path) pen.c:690:START_TEST(pen)
Regards Ralf
On 2/8/21 6:21 AM, Ralf Habacker wrote:
Am 08.02.21 um 12:23 schrieb Alexandre Julliard:
Ralf Habacker ralf.habacker@freenet.de writes:
This is used to avoid code duplication for adding an 'advanced' gdi32 test.
That doesn't seem necessary. You can simply add the new test to dib.c.
Adding the new tests to dib.c with
START_TEST( advanced ) { CryptAcquireContextW( &crypt_prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT );
test_advanced_graphics(); CryptReleaseContext( crypt_prov, 0 );
}
at the end does not add the new test 'advanced' to the list of available tests.
$ ~/src/wine-build/dlls/gdi32/tests> wine ./gdi32_test.exe Valid test names: bitmap brush clipping dc dib driver font gdiobj generated icm mapping metafile palette path pen
It looks that it is recommended to place each START_TEST() macro into a separate file as it was done with all present tests.
bitmap.c:5938:START_TEST(bitmap) brush.c:364:START_TEST(brush) clipping.c:557:START_TEST(clipping) dc.c:1675:START_TEST(dc) dib.c:3200:START_TEST(dib) driver.c:792:START_TEST(driver) font.c:7723:START_TEST(font) gdiobj.c:365:START_TEST(gdiobj) generated.c:13563:START_TEST(generated) icm.c:305:START_TEST(icm) mapping.c:713:START_TEST(mapping) metafile.c:4303:START_TEST(metafile) palette.c:328:START_TEST(palette) path.c:1922:START_TEST(path) pen.c:690:START_TEST(pen)
The point is that it's not worth adding a new test unit; you can just run your new tests as part of the "dib" test unit.
Regards Ralf