[PATCH v3] gdi32/tests: Add tests for the advanced graphics mode
Ralf Habacker
ralf.habacker at freenet.de
Tue Feb 9 06:42:09 CST 2021
For each failing test an associated bitmap files is created in the current
directoy, which can then be inspected visually.
Signed-off-by: Ralf Habacker <ralf.habacker at freenet.de>
---
dlls/gdi32/tests/dib.c | 370 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 370 insertions(+)
diff --git a/dlls/gdi32/tests/dib.c b/dlls/gdi32/tests/dib.c
index bdc3d9ed55b..72b3633a611 100644
--- a/dlls/gdi32/tests/dib.c
+++ b/dlls/gdi32/tests/dib.c
@@ -3529,11 +3529,381 @@ static void test_simple_graphics(void)
DeleteDC(mem_dc);
}
+typedef struct {
+ const char *name;
+ double shearX;
+ double angle;
+ const char *sha1;
+} hash_table_entry;
+
+/* generated on Windows 10 */
+hash_table_entry hash_table[] = {
+ { "LineTo", 0.000000, 0.000000, "4fd2ef41c2dfe9e0373d5560e715adcb0996e1e8" },
+ { "Rectangle", 0.000000, 0.000000, "7dfd17a8b871745eb3a9835282c4cdea05a4fdf5" },
+ { "Ellipse", 0.000000, 0.000000, "7764ca19f379333b001015d2eaba1fdbc9610f91" },
+ { "Arc", 0.000000, 0.000000, "fea4743713de7fe8368f037b2d466746c6f2ac08" },
+ { "ArcTo", 0.000000, 0.000000, "9b852a42f2bfb034ba7cc5a7c5dee87ac95f3e1f" },
+ { "Chord", 0.000000, 0.000000, "221091b6ab38d14cfa6c55723846a91e90931786" },
+ { "Pie", 0.000000, 0.000000, "221091b6ab38d14cfa6c55723846a91e90931786" },
+ { "FillRect", 0.000000, 0.000000, "877e47e0f729ebf3d104952b43aecf3553a5cf56" },
+ { "LineTo", 0.000000, 30.000000, "5b114b9b7d5422dac77508cf561e9f46b779c63a" },
+ { "Rectangle", 0.000000, 30.000000, "71a1ba67b6c8b96bb0785734f6e59759167f311c" },
+ { "Ellipse", 0.000000, 30.000000, "095e6add22e8e850304152b009aad03070f5700c" },
+ { "Arc", 0.000000, 30.000000, "8c7f9bf14d68c263fd0be427628ad5a47af5ab92" },
+ { "ArcTo", 0.000000, 30.000000, "7d6b7c8589b6beee073cfc7f30ee7a66092630d0" },
+ { "Chord", 0.000000, 30.000000, "b182fa35ffc3b63d415c3024333799c6b4195aaa" },
+ { "Pie", 0.000000, 30.000000, "b182fa35ffc3b63d415c3024333799c6b4195aaa" },
+ { "FillRect", 0.000000, 30.000000, "79f54ab207afeb8fb7ccc64dd222cae3d43c0454" },
+ { "LineTo", 0.000000, 60.000000, "d59a48a4cc8b528ee23c598df4163ae451240582" },
+ { "Rectangle", 0.000000, 60.000000, "8f203b915de9942751c6c7dbe64eeff9617dce6e" },
+ { "Ellipse", 0.000000, 60.000000, "fdeba07d4e07787b9c014097123b19e173272564" },
+ { "Arc", 0.000000, 60.000000, "1fe918dc0349de6fb8b25c7dfb453e5039868f07" },
+ { "ArcTo", 0.000000, 60.000000, "490fef90e731d2745826167f851bfedfedb17c32" },
+ { "Chord", 0.000000, 60.000000, "76e4c30a8031f41f5a4c4eb3025306ca72856179" },
+ { "Pie", 0.000000, 60.000000, "76e4c30a8031f41f5a4c4eb3025306ca72856179" },
+ { "FillRect", 0.000000, 60.000000, "a7f00485c5ca9f772b1ea6df15bfbb191e088af4" },
+ { "LineTo", 0.000000, 90.000000, "d555e5a94fdb7cd438bf791bb5496660e6f5b3e4" },
+ { "Rectangle", 0.000000, 90.000000, "53f1de2c148917affcffe25901427de2528d1f33" },
+ { "Ellipse", 0.000000, 90.000000, "77f7068eff91ba547a277e7f1cf1c6b0c58feece" },
+ { "Arc", 0.000000, 90.000000, "0100a40d978d3468c3869efb28ee78b79e9ac28c" },
+ { "ArcTo", 0.000000, 90.000000, "fa33a4bf59af3fec4cf1af0caf740134e701587c" },
+ { "Chord", 0.000000, 90.000000, "5f51b144f123ac82d4ceb061a763af7718d0ad57" },
+ { "Pie", 0.000000, 90.000000, "5f51b144f123ac82d4ceb061a763af7718d0ad57" },
+ { "FillRect", 0.000000, 90.000000, "4c97c178892098154a78749576917f1974ae0642" },
+ { "LineTo", 0.000000, 120.000000, "ea59644b1f5908c44cb7cade4d474a2f714d6f2d" },
+ { "Rectangle", 0.000000, 120.000000, "758787fe602d117d65cc46301b24756f1e72c4eb" },
+ { "Ellipse", 0.000000, 120.000000, "47f873ebc9ca562bbf790ef338a22d4ef3849d91" },
+ { "Arc", 0.000000, 120.000000, "772a592aa7e9069900de5e6e4c13c7823e4531e4" },
+ { "ArcTo", 0.000000, 120.000000, "9785fdd2df63e702da0ce66a855744d82a4f7370" },
+ { "Chord", 0.000000, 120.000000, "72790e3be1f5d3df5578c7451345317d766ec303" },
+ { "Pie", 0.000000, 120.000000, "72790e3be1f5d3df5578c7451345317d766ec303" },
+ { "FillRect", 0.000000, 120.000000, "d14f7b3ab63bf89eb2d8e0deaf103c65ad7b79a3" },
+ { "LineTo", 0.000000, 150.000000, "371daccf7add2bce0de8b0ec20f1e5ac7379d4ca" },
+ { "Rectangle", 0.000000, 150.000000, "cb046a9299e337e6bdc270986a1006df81608650" },
+ { "Ellipse", 0.000000, 150.000000, "599a5bec049aeeb004bf1a2ccde88fc8729a2726" },
+ { "Arc", 0.000000, 150.000000, "3c58506a6700bd99235a0353a35dacc7249485f0" },
+ { "ArcTo", 0.000000, 150.000000, "f59ca59f92a63a97744761e1ec3717077d0f9442" },
+ { "Chord", 0.000000, 150.000000, "27d2c9dbe9675d70cb0c429802da9d2e44385de0" },
+ { "Pie", 0.000000, 150.000000, "27d2c9dbe9675d70cb0c429802da9d2e44385de0" },
+ { "FillRect", 0.000000, 150.000000, "a807bffafaa74d092a1f23131c09b72a79c9164b" },
+ { "LineTo", 0.100000, 0.000000, "baa3c953aa781a0ae454225c56fc8f9197a9e34e" },
+ { "Rectangle", 0.100000, 0.000000, "bc3eb8b8e43f53043cb906b94987702724c1d5db" },
+ { "Ellipse", 0.100000, 0.000000, "8ec7278136f64b773e4796c7bc189e68e24db2e6" },
+ { "Arc", 0.100000, 0.000000, "b339b7623a66268184bff55692e51308bbfa507c" },
+ { "ArcTo", 0.100000, 0.000000, "15aaf44926d59ecf1da6ceb2ce09f0963c7e5390" },
+ { "Chord", 0.100000, 0.000000, "a6c63982ac7344e63228c2c42d7143cdd7d8db39" },
+ { "Pie", 0.100000, 0.000000, "a6c63982ac7344e63228c2c42d7143cdd7d8db39" },
+ { "FillRect", 0.100000, 0.000000, "f67c061ce20cfc04f981df9741b6e3c24bae1ebf" },
+ { "LineTo", 0.100000, 30.000000, "5283bbbde19515586bd08d6008adedb1e391c946" },
+ { "Rectangle", 0.100000, 30.000000, "9f75a948bfdad207aeaf9854298b0fbfbe017fe9" },
+ { "Ellipse", 0.100000, 30.000000, "8c7a7b0c3f5c0fe5f42f25a4d78ff3525438e82b" },
+ { "Arc", 0.100000, 30.000000, "70895f509313460a6641c3f25582fc68c9ba5652" },
+ { "ArcTo", 0.100000, 30.000000, "f566a8ac08c9f9e36e77e16c9f952721d6822d6b" },
+ { "Chord", 0.100000, 30.000000, "fc3bdc578bbc8a33ca01acb52bcb4be866d98868" },
+ { "Pie", 0.100000, 30.000000, "fc3bdc578bbc8a33ca01acb52bcb4be866d98868" },
+ { "FillRect", 0.100000, 30.000000, "b4fbb4d12ee61e10289082ffaa4cd58ff9271ee2" },
+ { "LineTo", 0.100000, 60.000000, "3fa54cd80b94d7e61c677dcbaefb927612679c15" },
+ { "Rectangle", 0.100000, 60.000000, "6415184eeeeb985db2049e4bf8be869397db26cc" },
+ { "Ellipse", 0.100000, 60.000000, "007e094d6db47745d8436086a0a24e9da98b5137" },
+ { "Arc", 0.100000, 60.000000, "719b81e32e2672a0f3adcf4d095d68033d60f4c1" },
+ { "ArcTo", 0.100000, 60.000000, "266cdf1829837a92dc525fde5b281577f22f62d2" },
+ { "Chord", 0.100000, 60.000000, "0c56b384011f96bc309a4bc1cbed08fec51b9d5a" },
+ { "Pie", 0.100000, 60.000000, "0c56b384011f96bc309a4bc1cbed08fec51b9d5a" },
+ { "FillRect", 0.100000, 60.000000, "e203834924cac7929a998b8ee4914943b94b8f7b" },
+ { "LineTo", 0.100000, 90.000000, "b9877b0324c5d8d9e9a86e09c9176effd6af2e69" },
+ { "Rectangle", 0.100000, 90.000000, "c9ed79cce52372b0bef9960b0069ab09c5f15379" },
+ { "Ellipse", 0.100000, 90.000000, "0e3206af4e0a8793d020fbcfff5308d62d9a9bbd" },
+ { "Arc", 0.100000, 90.000000, "8f63bba05d73f7659bd5d6b0197f23fa2b936296" },
+ { "ArcTo", 0.100000, 90.000000, "22ca17fe3d517c2c0551e93e904a7a3aa1eb0a3a" },
+ { "Chord", 0.100000, 90.000000, "a6ac92337383b50cddee9353c8e5d0180ec0b179" },
+ { "Pie", 0.100000, 90.000000, "a6ac92337383b50cddee9353c8e5d0180ec0b179" },
+ { "FillRect", 0.100000, 90.000000, "99f4cbdb52964d928dba5df88f99718c630d8466" },
+ { "LineTo", 0.100000, 120.000000, "5a218e4533c11f0137813a483b83469e5bc9f272" },
+ { "Rectangle", 0.100000, 120.000000, "0630eb459f6c5634a96567537eb7add9c062f7ff" },
+ { "Ellipse", 0.100000, 120.000000, "9823b51b405b5ae7647f2fd33491397a06a13644" },
+ { "Arc", 0.100000, 120.000000, "f163d0fc823cb00dfca7e9d86ad316c3df5dc7b0" },
+ { "ArcTo", 0.100000, 120.000000, "8b4a52c051b4cd36841b68ed419d0981ac214c29" },
+ { "Chord", 0.100000, 120.000000, "d5c8ad44f3a4a7e37df1b58ce35565aa6fb81938" },
+ { "Pie", 0.100000, 120.000000, "d5c8ad44f3a4a7e37df1b58ce35565aa6fb81938" },
+ { "FillRect", 0.100000, 120.000000, "111163a546305f3dfff58f447bf763a1f8690064" },
+ { "LineTo", 0.100000, 150.000000, "837dba89923d94d1a8ce3bc8fe73e6a65b058299" },
+ { "Rectangle", 0.100000, 150.000000, "535fea9f81dc44394326f2e499926d9e4e5ef095" },
+ { "Ellipse", 0.100000, 150.000000, "5c2d6ba0dd1e81a32fbfa07652bfd21a3b5620f7" },
+ { "Arc", 0.100000, 150.000000, "fa40fec084b7c9a641a75e8c6ae2a9b74cb36adc" },
+ { "ArcTo", 0.100000, 150.000000, "7a0d70cef05dfeed94f74e5cfe16f70955c3fbf5" },
+ { "Chord", 0.100000, 150.000000, "ef0d60b2152b399c44bb4cb0b793799e9759c277" },
+ { "Pie", 0.100000, 150.000000, "ef0d60b2152b399c44bb4cb0b793799e9759c277" },
+ { "FillRect", 0.100000, 150.000000, "062ee355971a58a72746747c9fce17ef9bf24ecb" },
+ { NULL, 0.0, 0.0, NULL },
+};
+
+typedef struct {
+ HDC dc;
+ BITMAPINFO *bmi;
+ BYTE *bits;
+ HBITMAP dib;
+ char *hash_dib;
+ 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;
+}
+
+BOOL save_bitmap_to_file(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 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 );
+}
+
+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, "\"%s\", %3.1f, %2.1f", td->test_name, td->shearX, td->angle );
+ 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 );
+}
+
+const char *find_hash( test_data *td )
+{
+ hash_table_entry *p = hash_table;
+ for( ; p->name != NULL; p++ ) {
+ if ( strcmp( p->name, td->test_name ) != 0
+ || p->shearX != td->shearX
+ || p->angle != td->angle )
+ continue;
+ return p->sha1;
+ }
+ return NULL;
+}
+
+void check_hash( test_data *td )
+{
+ const char *hash;
+ if ( td->hash_dib )
+ HeapFree( GetProcessHeap(), 0, td->hash_dib );
+ td->hash_dib = hash_dib( td->dc, td->bmi, td->bits );
+ hash = find_hash( td );
+ if ( hash == NULL)
+ skip( "{ \"%s\", %lf, %lf, \"%s\" },\n",
+ td->test_name, td->shearX, td->angle, td->hash_dib );
+ else if( strcmp( td->hash_dib, hash ) != 0 ) {
+ ok( FALSE, "%s: expected hash %s got %s - image saved as '%s'\n",
+ td->hash_name, hash, td->hash_dib, td->save_path );
+
+ /* for debugging purpose */
+ save_bitmap_to_file( td->dib, td->save_path );
+ }
+}
+
+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 )
+{
+ int save = winetest_mute_threshold;
+ winetest_mute_threshold = 256;
+
+ td->bounds.left = 0;
+ td->bounds.top = 0;
+ td->bounds.right = 256;
+ td->bounds.bottom = 256;
+
+ trace("advanced - no shear\n");
+ 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 );
+ trace("advanced - with shear\n");
+ 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 );
+
+ winetest_mute_threshold = save;
+}
+
START_TEST(dib)
{
CryptAcquireContextW(&crypt_prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
test_simple_graphics();
+ test_advanced_graphics();
CryptReleaseContext(crypt_prov, 0);
}
--
2.26.2
More information about the wine-devel
mailing list