From: Amine Khaldi Date: Sun, 17 Sep 2017 12:34:24 +0000 (+0000) Subject: [GDIPLUS_WINETEST] Sync with Wine Staging 2.16. CORE-13762 X-Git-Tag: 0.4.8-dev~366 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=73232b5227d72fead31e2db4442840feeee7121f [GDIPLUS_WINETEST] Sync with Wine Staging 2.16. CORE-13762 svn path=/trunk/; revision=75873 --- diff --git a/rostests/winetests/gdiplus/brush.c b/rostests/winetests/gdiplus/brush.c index 939c327cf50..759090bdbfc 100644 --- a/rostests/winetests/gdiplus/brush.c +++ b/rostests/winetests/gdiplus/brush.c @@ -32,6 +32,8 @@ #define expect(expected, got) ok(got == expected, "Expected %.8x, got %.8x\n", expected, got) #define expectf(expected, got) ok(fabs(expected - got) < 0.0001, "Expected %.2f, got %.2f\n", expected, got) +static HWND hwnd; + static void test_constructor_destructor(void) { GpStatus status; @@ -179,12 +181,17 @@ static void test_transform(void) { GpStatus status; GpTexture *texture; + GpLineGradient *line; GpGraphics *graphics = NULL; GpBitmap *bitmap; HDC hdc = GetDC(0); GpMatrix *m, *m1; BOOL res; + GpPointF start, end; + GpRectF rectf; + REAL elements[6]; + /* GpTexture */ status = GdipCreateMatrix2(2.0, 0.0, 0.0, 0.0, 0.0, 0.0, &m); expect(Ok, status); @@ -238,6 +245,245 @@ static void test_transform(void) expect(Ok, status); status = GdipDeleteGraphics(graphics); expect(Ok, status); + + + + status = GdipCreateFromHWND(hwnd, &graphics); + expect(Ok, status); + + /* GpLineGradient */ + /* create with vertical gradient line */ + start.X = start.Y = end.X = 0.0; + end.Y = 100.0; + + status = GdipCreateLineBrush(&start, &end, (ARGB)0xffff0000, 0xff00ff00, WrapModeTile, &line); + expect(Ok, status); + + status = GdipCreateMatrix2(1.0, 0.0, 0.0, 1.0, 0.0, 0.0, &m); + expect(Ok, status); + + /* NULL arguments */ + status = GdipResetLineTransform(NULL); + expect(InvalidParameter, status); + status = GdipSetLineTransform(NULL, m); + expect(InvalidParameter, status); + status = GdipSetLineTransform(line, NULL); + expect(InvalidParameter, status); + status = GdipGetLineTransform(NULL, m); + expect(InvalidParameter, status); + status = GdipGetLineTransform(line, NULL); + expect(InvalidParameter, status); + status = GdipScaleLineTransform(NULL, 1, 1, MatrixOrderPrepend); + expect(InvalidParameter, status); + status = GdipMultiplyLineTransform(NULL, m, MatrixOrderPrepend); + expect(InvalidParameter, status); + status = GdipTranslateLineTransform(NULL, 0, 0, MatrixOrderPrepend); + expect(InvalidParameter, status); + + /* initial transform */ + status = GdipGetLineTransform(line, m); + expect(Ok, status); + + status = GdipGetMatrixElements(m, elements); + expect(Ok, status); + expectf(0.0, elements[0]); + expectf(1.0, elements[1]); + expectf(-1.0, elements[2]); + expectf(0.0, elements[3]); + expectf(50.0, elements[4]); + expectf(50.0, elements[5]); + + status = GdipGetLineRect(line, &rectf); + expect(Ok, status); + expectf(-50.0, rectf.X); + expectf(0.0, rectf.Y); + expectf(100.0, rectf.Width); + expectf(100.0, rectf.Height); + + status = GdipFillRectangle(graphics, (GpBrush*)line, 0, 0, 200, 200); + expect(Ok, status); + + /* manually set transform */ + GdipSetMatrixElements(m, 2.0, 0.0, 0.0, 4.0, 0.0, 0.0); + + status = GdipSetLineTransform(line, m); + expect(Ok, status); + + status = GdipGetLineTransform(line, m); + expect(Ok, status); + + status = GdipGetMatrixElements(m, elements); + expect(Ok, status); + expectf(2.0, elements[0]); + expectf(0.0, elements[1]); + expectf(0.0, elements[2]); + expectf(4.0, elements[3]); + expectf(0.0, elements[4]); + expectf(0.0, elements[5]); + + status = GdipGetLineRect(line, &rectf); + expect(Ok, status); + expectf(-50.0, rectf.X); + expectf(0.0, rectf.Y); + expectf(100.0, rectf.Width); + expectf(100.0, rectf.Height); + + status = GdipFillRectangle(graphics, (GpBrush*)line, 200, 0, 200, 200); + expect(Ok, status); + + /* scale transform */ + status = GdipScaleLineTransform(line, 4.0, 0.5, MatrixOrderAppend); + expect(Ok, status); + + status = GdipGetLineTransform(line, m); + expect(Ok, status); + + status = GdipGetMatrixElements(m, elements); + expect(Ok, status); + expectf(8.0, elements[0]); + expectf(0.0, elements[1]); + expectf(0.0, elements[2]); + expectf(2.0, elements[3]); + expectf(0.0, elements[4]); + expectf(0.0, elements[5]); + + status = GdipGetLineRect(line, &rectf); + expect(Ok, status); + expectf(-50.0, rectf.X); + expectf(0.0, rectf.Y); + expectf(100.0, rectf.Width); + expectf(100.0, rectf.Height); + + status = GdipFillRectangle(graphics, (GpBrush*)line, 400, 0, 200, 200); + expect(Ok, status); + + /* translate transform */ + status = GdipTranslateLineTransform(line, 10.0, -20.0, MatrixOrderAppend); + expect(Ok, status); + + status = GdipGetLineTransform(line, m); + expect(Ok, status); + + status = GdipGetMatrixElements(m, elements); + expect(Ok, status); + expectf(8.0, elements[0]); + expectf(0.0, elements[1]); + expectf(0.0, elements[2]); + expectf(2.0, elements[3]); + expectf(10.0, elements[4]); + expectf(-20.0, elements[5]); + + status = GdipGetLineRect(line, &rectf); + expect(Ok, status); + expectf(-50.0, rectf.X); + expectf(0.0, rectf.Y); + expectf(100.0, rectf.Width); + expectf(100.0, rectf.Height); + + status = GdipFillRectangle(graphics, (GpBrush*)line, 0, 200, 200, 200); + expect(Ok, status); + + /* multiply transform */ + GdipSetMatrixElements(m, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0); + GdipRotateMatrix(m, 45.0, MatrixOrderAppend); + GdipScaleMatrix(m, 0.25, 0.5, MatrixOrderAppend); + + status = GdipMultiplyLineTransform(line, m, MatrixOrderAppend); + expect(Ok, status); + + /* NULL transform does nothing */ + status = GdipMultiplyLineTransform(line, NULL, MatrixOrderAppend); + expect(Ok, status); + + status = GdipGetLineTransform(line, m); + expect(Ok, status); + + status = GdipGetMatrixElements(m, elements); + expect(Ok, status); + expectf(1.414214, elements[0]); + expectf(2.828427, elements[1]); + expectf(-0.353553, elements[2]); + expectf(0.707107, elements[3]); + expectf(5.303300, elements[4]); + expectf(-3.535534, elements[5]); + + status = GdipGetLineRect(line, &rectf); + expect(Ok, status); + expectf(-50.0, rectf.X); + expectf(0.0, rectf.Y); + expectf(100.0, rectf.Width); + expectf(100.0, rectf.Height); + + status = GdipFillRectangle(graphics, (GpBrush*)line, 200, 200, 200, 200); + expect(Ok, status); + + /* reset transform sets to identity */ + status = GdipResetLineTransform(line); + expect(Ok, status); + + status = GdipGetLineTransform(line, m); + expect(Ok, status); + + status = GdipGetMatrixElements(m, elements); + expect(Ok, status); + expectf(1.0, elements[0]); + expectf(0.0, elements[1]); + expectf(0.0, elements[2]); + expectf(1.0, elements[3]); + expectf(0.0, elements[4]); + expectf(0.0, elements[5]); + + status = GdipGetLineRect(line, &rectf); + expect(Ok, status); + expectf(-50.0, rectf.X); + expectf(0.0, rectf.Y); + expectf(100.0, rectf.Width); + expectf(100.0, rectf.Height); + + status = GdipFillRectangle(graphics, (GpBrush*)line, 400, 200, 200, 200); + expect(Ok, status); + + GdipDeleteBrush((GpBrush*)line); + + /* passing negative Width/Height to LinearGradientModeHorizontal */ + rectf.X = rectf.Y = 10.0; + rectf.Width = rectf.Height = -100.0; + status = GdipCreateLineBrushFromRect(&rectf, (ARGB)0xffff0000, 0xff00ff00, + LinearGradientModeHorizontal, WrapModeTile, &line); + expect(Ok, status); + memset(&rectf, 0, sizeof(GpRectF)); + status = GdipGetLineRect(line, &rectf); + expect(Ok, status); + expectf(10.0, rectf.X); + expectf(10.0, rectf.Y); + expectf(-100.0, rectf.Width); + expectf(-100.0, rectf.Height); + status = GdipGetLineTransform(line, m); + expect(Ok, status); + status = GdipGetMatrixElements(m, elements); + expect(Ok,status); + expectf(1.0, elements[0]); + expectf(0.0, elements[1]); + expectf(0.0, elements[2]); + expectf(1.0, elements[3]); + expectf(0.0, elements[4]); + expectf(0.0, elements[5]); + status = GdipFillRectangle(graphics, (GpBrush*)line, 0, 400, 200, 200); + expect(Ok, status); + status = GdipDeleteBrush((GpBrush*)line); + expect(Ok,status); + + if(0){ + /* enable to visually compare with Windows */ + MSG msg; + while(GetMessageW(&msg, hwnd, 0, 0) > 0){ + TranslateMessage(&msg); + DispatchMessageW(&msg); + } + } + + GdipDeleteMatrix(m); + GdipDeleteGraphics(graphics); ReleaseDC(0, hdc); } @@ -313,20 +559,18 @@ static void test_gradientgetrect(void) expectf(99.0, rectf.Width); expectf(99.0, rectf.Height); status = GdipGetLineTransform(brush, transform); - todo_wine expect(Ok, status); - if (status == Ok) - { - status = GdipGetMatrixElements(transform, elements); - expect(Ok, status); - expectf(1.0, elements[0]); - expectf(1.0, elements[1]); - expectf(-1.0, elements[2]); - expectf(1.0, elements[3]); - expectf(50.50, elements[4]); - expectf(-50.50, elements[5]); - } + expect(Ok, status); + status = GdipGetMatrixElements(transform, elements); + expect(Ok, status); + expectf(1.0, elements[0]); + expectf(1.0, elements[1]); + expectf(-1.0, elements[2]); + expectf(1.0, elements[3]); + expectf(50.50, elements[4]); + expectf(-50.50, elements[5]); status = GdipDeleteBrush((GpBrush*)brush); expect(Ok, status); + /* vertical gradient */ pt1.X = pt1.Y = pt2.X = 0.0; pt2.Y = 10.0; @@ -340,20 +584,18 @@ static void test_gradientgetrect(void) expectf(10.0, rectf.Width); expectf(10.0, rectf.Height); status = GdipGetLineTransform(brush, transform); - todo_wine expect(Ok, status); - if (status == Ok) - { - status = GdipGetMatrixElements(transform, elements); - expect(Ok, status); - expectf(0.0, elements[0]); - expectf(1.0, elements[1]); - expectf(-1.0, elements[2]); - expectf(0.0, elements[3]); - expectf(5.0, elements[4]); - expectf(5.0, elements[5]); - } + expect(Ok, status); + status = GdipGetMatrixElements(transform, elements); + expect(Ok, status); + expectf(0.0, elements[0]); + expectf(1.0, elements[1]); + expectf(-1.0, elements[2]); + expectf(0.0, elements[3]); + expectf(5.0, elements[4]); + expectf(5.0, elements[5]); status = GdipDeleteBrush((GpBrush*)brush); expect(Ok, status); + /* horizontal gradient */ pt1.X = pt1.Y = pt2.Y = 0.0; pt2.X = 10.0; @@ -367,20 +609,18 @@ static void test_gradientgetrect(void) expectf(10.0, rectf.Width); expectf(10.0, rectf.Height); status = GdipGetLineTransform(brush, transform); - todo_wine expect(Ok, status); - if (status == Ok) - { - status = GdipGetMatrixElements(transform, elements); - expect(Ok, status); - expectf(1.0, elements[0]); - expectf(0.0, elements[1]); - expectf(0.0, elements[2]); - expectf(1.0, elements[3]); - expectf(0.0, elements[4]); - expectf(0.0, elements[5]); - } + expect(Ok, status); + status = GdipGetMatrixElements(transform, elements); + expect(Ok, status); + expectf(1.0, elements[0]); + expectf(0.0, elements[1]); + expectf(0.0, elements[2]); + expectf(1.0, elements[3]); + expectf(0.0, elements[4]); + expectf(0.0, elements[5]); status = GdipDeleteBrush((GpBrush*)brush); expect(Ok, status); + /* slope = -1 */ pt1.X = pt1.Y = 0.0; pt2.X = 20.0; @@ -395,20 +635,18 @@ static void test_gradientgetrect(void) expectf(20.0, rectf.Width); expectf(20.0, rectf.Height); status = GdipGetLineTransform(brush, transform); - todo_wine expect(Ok, status); - if (status == Ok) - { - status = GdipGetMatrixElements(transform, elements); - expect(Ok, status); - expectf(1.0, elements[0]); - expectf(-1.0, elements[1]); - expectf(1.0, elements[2]); - expectf(1.0, elements[3]); - expectf(10.0, elements[4]); - expectf(10.0, elements[5]); - } + expect(Ok, status); + status = GdipGetMatrixElements(transform, elements); + expect(Ok, status); + expectf(1.0, elements[0]); + expectf(-1.0, elements[1]); + expectf(1.0, elements[2]); + expectf(1.0, elements[3]); + expectf(10.0, elements[4]); + expectf(10.0, elements[5]); status = GdipDeleteBrush((GpBrush*)brush); expect(Ok, status); + /* slope = 1/100 */ pt1.X = pt1.Y = 0.0; pt2.X = 100.0; @@ -423,20 +661,18 @@ static void test_gradientgetrect(void) expectf(100.0, rectf.Width); expectf(1.0, rectf.Height); status = GdipGetLineTransform(brush, transform); - todo_wine expect(Ok, status); - if (status == Ok) - { - status = GdipGetMatrixElements(transform, elements); - expect(Ok,status); - expectf(1.0, elements[0]); - expectf(0.01, elements[1]); - expectf(-0.02, elements[2]); - /* expectf(2.0, elements[3]); */ - expectf(0.01, elements[4]); - /* expectf(-1.0, elements[5]); */ - } + expect(Ok, status); + status = GdipGetMatrixElements(transform, elements); + expect(Ok,status); + expectf(1.0, elements[0]); + expectf(0.01, elements[1]); + expectf(-0.02, elements[2]); + /* expectf(2.0, elements[3]); */ + expectf(0.01, elements[4]); + /* expectf(-1.0, elements[5]); */ status = GdipDeleteBrush((GpBrush*)brush); expect(Ok,status); + /* zero height rect */ rectf.X = rectf.Y = 10.0; rectf.Width = 100.0; @@ -444,6 +680,7 @@ static void test_gradientgetrect(void) status = GdipCreateLineBrushFromRect(&rectf, 0, 0, LinearGradientModeVertical, WrapModeTile, &brush); expect(OutOfMemory, status); + /* zero width rect */ rectf.X = rectf.Y = 10.0; rectf.Width = 0.0; @@ -451,6 +688,7 @@ static void test_gradientgetrect(void) status = GdipCreateLineBrushFromRect(&rectf, 0, 0, LinearGradientModeHorizontal, WrapModeTile, &brush); expect(OutOfMemory, status); + /* from rect with LinearGradientModeHorizontal */ rectf.X = rectf.Y = 10.0; rectf.Width = rectf.Height = 100.0; @@ -465,20 +703,18 @@ static void test_gradientgetrect(void) expectf(100.0, rectf.Width); expectf(100.0, rectf.Height); status = GdipGetLineTransform(brush, transform); - todo_wine expect(Ok, status); - if (status == Ok) - { - status = GdipGetMatrixElements(transform, elements); - expect(Ok,status); - expectf(1.0, elements[0]); - expectf(0.0, elements[1]); - expectf(0.0, elements[2]); - expectf(1.0, elements[3]); - expectf(0.0, elements[4]); - expectf(0.0, elements[5]); - } + expect(Ok, status); + status = GdipGetMatrixElements(transform, elements); + expect(Ok,status); + expectf(1.0, elements[0]); + expectf(0.0, elements[1]); + expectf(0.0, elements[2]); + expectf(1.0, elements[3]); + expectf(0.0, elements[4]); + expectf(0.0, elements[5]); status = GdipDeleteBrush((GpBrush*)brush); expect(Ok,status); + /* passing negative Width/Height to LinearGradientModeHorizontal */ rectf.X = rectf.Y = 10.0; rectf.Width = rectf.Height = -100.0; @@ -493,21 +729,45 @@ static void test_gradientgetrect(void) expectf(-100.0, rectf.Width); expectf(-100.0, rectf.Height); status = GdipGetLineTransform(brush, transform); - todo_wine expect(Ok, status); - if (status == Ok) - { - status = GdipGetMatrixElements(transform, elements); - expect(Ok,status); - expectf(1.0, elements[0]); - expectf(0.0, elements[1]); - expectf(0.0, elements[2]); - expectf(1.0, elements[3]); - expectf(0.0, elements[4]); - expectf(0.0, elements[5]); - } + expect(Ok, status); + status = GdipGetMatrixElements(transform, elements); + expect(Ok,status); + expectf(1.0, elements[0]); + expectf(0.0, elements[1]); + expectf(0.0, elements[2]); + expectf(1.0, elements[3]); + expectf(0.0, elements[4]); + expectf(0.0, elements[5]); status = GdipDeleteBrush((GpBrush*)brush); expect(Ok,status); + /* reverse gradient line as immediately previous */ + pt1.X = 10.0; + pt1.Y = 10.0; + pt2.X = -90.0; + pt2.Y = 10.0; + status = GdipCreateLineBrush(&pt1, &pt2, 0, 0, WrapModeTile, &brush); + expect(Ok, status); + memset(&rectf, 0, sizeof(GpRectF)); + status = GdipGetLineRect(brush, &rectf); + expect(Ok, status); + expectf(-90.0, rectf.X); + expectf(-40.0, rectf.Y); + expectf(100.0, rectf.Width); + expectf(100.0, rectf.Height); + status = GdipGetLineTransform(brush, transform); + expect(Ok, status); + status = GdipGetMatrixElements(transform, elements); + expect(Ok, status); + expectf(-1.0, elements[0]); + expectf(0.0, elements[1]); + expectf(0.0, elements[2]); + expectf(-1.0, elements[3]); + expectf(-80.0, elements[4]); + expectf(20.0, elements[5]); + status = GdipDeleteBrush((GpBrush*)brush); + expect(Ok, status); + GdipDeleteMatrix(transform); } @@ -1278,6 +1538,27 @@ START_TEST(brush) { struct GdiplusStartupInput gdiplusStartupInput; ULONG_PTR gdiplusToken; + HMODULE hmsvcrt; + int (CDECL * _controlfp_s)(unsigned int *cur, unsigned int newval, unsigned int mask); + WNDCLASSA class; + + /* Enable all FP exceptions except _EM_INEXACT, which gdi32 can trigger */ + hmsvcrt = LoadLibraryA("msvcrt"); + _controlfp_s = (void*)GetProcAddress(hmsvcrt, "_controlfp_s"); + if (_controlfp_s) _controlfp_s(0, 0, 0x0008001e); + + memset( &class, 0, sizeof(class) ); + class.lpszClassName = "gdiplus_test"; + class.style = CS_HREDRAW | CS_VREDRAW; + class.lpfnWndProc = DefWindowProcA; + class.hInstance = GetModuleHandleA(0); + class.hIcon = LoadIconA(0, (LPCSTR)IDI_APPLICATION); + class.hCursor = LoadCursorA(0, (LPCSTR)IDC_ARROW); + class.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); + RegisterClassA( &class ); + hwnd = CreateWindowA( "gdiplus_test", "graphics test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, + CW_USEDEFAULT, CW_USEDEFAULT, 800, 600, 0, 0, GetModuleHandleA(0), 0 ); + ok(hwnd != NULL, "Expected window to be created\n"); gdiplusStartupInput.GdiplusVersion = 1; gdiplusStartupInput.DebugEventCallback = NULL; @@ -1304,4 +1585,5 @@ START_TEST(brush) test_pathgradientblend(); GdiplusShutdown(gdiplusToken); + DestroyWindow(hwnd); } diff --git a/rostests/winetests/gdiplus/customlinecap.c b/rostests/winetests/gdiplus/customlinecap.c index c5dad1fbfdc..b406eccda9d 100644 --- a/rostests/winetests/gdiplus/customlinecap.c +++ b/rostests/winetests/gdiplus/customlinecap.c @@ -321,6 +321,13 @@ START_TEST(customlinecap) { struct GdiplusStartupInput gdiplusStartupInput; ULONG_PTR gdiplusToken; + HMODULE hmsvcrt; + int (CDECL * _controlfp_s)(unsigned int *cur, unsigned int newval, unsigned int mask); + + /* Enable all FP exceptions except _EM_INEXACT, which gdi32 can trigger */ + hmsvcrt = LoadLibraryA("msvcrt"); + _controlfp_s = (void*)GetProcAddress(hmsvcrt, "_controlfp_s"); + if (_controlfp_s) _controlfp_s(0, 0, 0x0008001e); gdiplusStartupInput.GdiplusVersion = 1; gdiplusStartupInput.DebugEventCallback = NULL; diff --git a/rostests/winetests/gdiplus/font.c b/rostests/winetests/gdiplus/font.c index 19405f7d939..f31a5ee4b82 100644 --- a/rostests/winetests/gdiplus/font.c +++ b/rostests/winetests/gdiplus/font.c @@ -1121,6 +1121,13 @@ START_TEST(font) { struct GdiplusStartupInput gdiplusStartupInput; ULONG_PTR gdiplusToken; + HMODULE hmsvcrt; + int (CDECL * _controlfp_s)(unsigned int *cur, unsigned int newval, unsigned int mask); + + /* Enable all FP exceptions except _EM_INEXACT, which gdi32 can trigger */ + hmsvcrt = LoadLibraryA("msvcrt"); + _controlfp_s = (void*)GetProcAddress(hmsvcrt, "_controlfp_s"); + if (_controlfp_s) _controlfp_s(0, 0, 0x0008001e); gdiplusStartupInput.GdiplusVersion = 1; gdiplusStartupInput.DebugEventCallback = NULL; diff --git a/rostests/winetests/gdiplus/graphics.c b/rostests/winetests/gdiplus/graphics.c index 1ba522ea78a..33fee40d16d 100644 --- a/rostests/winetests/gdiplus/graphics.c +++ b/rostests/winetests/gdiplus/graphics.c @@ -35,6 +35,8 @@ #define expectf_(expected, got, precision) ok(fabs((expected) - (got)) <= (precision), "Expected %f, got %f\n", (expected), (got)) #define expectf(expected, got) expectf_((expected), (got), 0.001) +static GpStatus (WINAPI *pGdipGraphicsSetAbort)(GpGraphics*,GdiplusAbort*); + static const REAL mm_per_inch = 25.4; static const REAL point_per_inch = 72.0; static HWND hwnd; @@ -1872,6 +1874,15 @@ static void test_transformpoints(void) status = GdipTransformPoints(graphics, CoordinateSpacePage, CoordinateSpaceWorld, ptf, -1); expect(InvalidParameter, status); + status = GdipTransformPoints(graphics, CoordinateSpaceDevice+1, CoordinateSpaceWorld, ptf, 2); + expect(InvalidParameter, status); + status = GdipTransformPoints(graphics, -1, CoordinateSpaceWorld, ptf, 2); + expect(InvalidParameter, status); + status = GdipTransformPoints(graphics, CoordinateSpaceDevice, CoordinateSpaceDevice+1, ptf, 2); + expect(InvalidParameter, status); + status = GdipTransformPoints(graphics, CoordinateSpaceDevice, -1, ptf, 2); + expect(InvalidParameter, status); + ptf[0].X = 1.0; ptf[0].Y = 0.0; ptf[1].X = 0.0; @@ -4954,6 +4965,16 @@ static void test_clipping(void) ok(rect.X == 100.0 && rect.Y == 100.0 && rect.Width == 100.0 && rect.Height == 100.0, "expected 100.0,100.0-100.0,100.0, got %.2f,%.2f-%.2f,%.2f\n", rect.X, rect.Y, rect.Width, rect.Height); + /* Clip region does not account for changes to gdi32 transform */ + SetViewportOrgEx(hdc, 10, 10, NULL); + + status = GdipGetClipBounds(graphics, &rect); + expect(Ok, status); + ok(rect.X == 100.0 && rect.Y == 100.0 && rect.Width == 100.0 && rect.Height == 100.0, + "expected 100.0,100.0-100.0,100.0, got %.2f,%.2f-%.2f,%.2f\n", rect.X, rect.Y, rect.Width, rect.Height); + + SetViewportOrgEx(hdc, 0, 0, NULL); + status = GdipSetEmpty(region); expect(Ok, status); status = GdipGetClip(graphics, region); @@ -6155,11 +6176,380 @@ static void test_container_rects(void) ReleaseDC(hwnd, hdc); } +static void test_GdipGraphicsSetAbort(void) +{ + HDC hdc; + GpStatus status; + GpGraphics *graphics; + + if (!pGdipGraphicsSetAbort) + { + win_skip("GdipGraphicsSetAbort() is not supported.\n"); + return; + } + + hdc = GetDC(hwnd); + + status = GdipCreateFromHDC(hdc, &graphics); + expect(Ok, status); + + status = pGdipGraphicsSetAbort(NULL, NULL); + expect(InvalidParameter, status); + + status = pGdipGraphicsSetAbort(graphics, NULL); + expect(Ok, status); + + GdipDeleteGraphics(graphics); + + ReleaseDC(hwnd, hdc); +} + +#define BLUE_COLOR (0xff0000ff) +#define is_blue_color(color) ( ((color) & 0x00ffffff) == 0xff ) +#define get_bitmap_pixel(x,y) pixel[(y)*(width) + (x)] +static DWORD* GetBitmapPixelBuffer(HDC hdc, HBITMAP hbmp, int width, int height) +{ + BITMAPINFOHEADER bi; + UINT lines = 0; + DWORD *buffer = (DWORD *)GdipAlloc(width*height*4); + + bi.biSize = sizeof(BITMAPINFOHEADER); + bi.biWidth = width; + bi.biHeight = -height; /*very Important, set negative, indicating a top-down DIB*/ + bi.biPlanes = 1; + bi.biBitCount = 32; + bi.biCompression = BI_RGB; + bi.biSizeImage = 0; + bi.biXPelsPerMeter = 0; + bi.biYPelsPerMeter = 0; + bi.biClrUsed = 0; + bi.biClrImportant = 0; + + lines = GetDIBits(hdc, hbmp, 0, height, buffer, (BITMAPINFO *)&bi, DIB_RGB_COLORS); + ok(lines == height, "Expected GetDIBits:%p,%d->%d,%d\n", buffer, height, lines, GetLastError()); + + return buffer; +} + +static void ReleaseBitmapPixelBuffer(DWORD* buffer) +{ + if (buffer) GdipFree(buffer); +} + +static void test_GdipFillRectanglesOnMemoryDCSolidBrush(void) +{ + ARGB color[6] = {0,0,0,0,0,0}; + POINT pt = {0,0}; + RECT rect = {100, 100, 180, 180}; + UINT width = rect.right - rect.left; + UINT height = rect.bottom - rect.top; + GpStatus status = 0; + GpSolidFill *brush = NULL; + GpGraphics *graphics = NULL; + HDC dc = GetDC( hwnd); + HDC hdc = CreateCompatibleDC(dc); + HBITMAP bmp = CreateCompatibleBitmap(dc, width, height); + HGDIOBJ old = SelectObject(hdc, bmp); + DWORD* pixel = NULL; + + /*Change the window origin is the key test point*/ + SetWindowOrgEx(hdc, rect.left, rect.top, &pt); + + status = GdipCreateSolidFill(BLUE_COLOR, &brush); + expect(Ok, status); + + status = GdipCreateFromHDC(hdc, &graphics); + expect(Ok, status); + + status = GdipSetClipRectI(graphics, rect.left+width/2, rect.top+height/2, + width, height, CombineModeReplace); + expect(Ok, status); + + status = GdipFillRectangleI(graphics, (GpBrush*)brush, 0, 0, rect.right, rect.bottom); + expect(Ok, status); + + GdipDeleteBrush((GpBrush*)brush); + GdipDeleteGraphics(graphics); + + pixel = GetBitmapPixelBuffer(hdc, bmp, width, height); + if (pixel) + { + color[0] = get_bitmap_pixel(width/2, height/2); + color[1] = get_bitmap_pixel(width/2+1, height/2); + color[2] = get_bitmap_pixel(width/2, height/2+1); + color[3] = get_bitmap_pixel(width/2-1, height/2-1); + color[4] = get_bitmap_pixel(width/2-1, height-1); + color[5] = get_bitmap_pixel(width-1, height/2-1); + } + + ok(is_blue_color(color[0]) && is_blue_color(color[1]) && is_blue_color(color[2]) && + color[3] == 0 && color[4] == 0 && color[5] == 0, + "Expected GdipFillRectangleI take effect!\n" ); + ReleaseBitmapPixelBuffer(pixel); + + SelectObject(hdc, old); + DeleteObject(bmp); + DeleteDC(hdc); + ReleaseDC(hwnd, dc); +} + +static void test_GdipFillRectanglesOnMemoryDCTextureBrush(void) +{ + ARGB color[6] = {0,0,0,0,0,0}; + POINT pt = {0,0}; + RECT rect = {100, 100, 180, 180}; + UINT width = rect.right - rect.left; + UINT height = rect.bottom - rect.top; + GpStatus status = 0; + union + { + GpBitmap *bitmap; + GpImage *image; + } src_img; + GpTexture *brush = NULL; + GpGraphics *graphics = NULL; + HDC dc = GetDC( hwnd); + HDC hdc = CreateCompatibleDC(dc); + HBITMAP bmp = CreateCompatibleBitmap(dc, width, height); + HGDIOBJ old = SelectObject(hdc, bmp); + + UINT x = 0; + UINT y = 0; + UINT src_img_width = width/2; + UINT src_img_height = height/2; + BYTE *src_img_data = GdipAlloc(src_img_width*src_img_height*4); + DWORD *pixel = (DWORD *)src_img_data; + ok(pixel != NULL, "Expected src_img_data is valid\n"); + + /*Change the window origin is the key test point*/ + SetWindowOrgEx(hdc, rect.left, rect.top, &pt); + + /*build a blue solid image!*/ + for(y = 0; y < src_img_height; ++y) + { + for(x = 0; x < src_img_width; ++x) + { + pixel[x] = BLUE_COLOR; + } + + pixel += src_img_width; + } + + status = GdipCreateBitmapFromScan0(src_img_width, src_img_height, src_img_width*4, + PixelFormat32bppARGB, src_img_data, &src_img.bitmap); + expect(Ok, status); + + status = GdipCreateTexture(src_img.image, 0, &brush); + expect(Ok, status); + + status = GdipCreateFromHDC(hdc, &graphics); + expect(Ok, status); + + status = GdipSetClipRectI(graphics, rect.left+width/2, rect.top+height/2, + width, height, CombineModeReplace); + expect(Ok, status); + + status = GdipFillRectangleI(graphics, (GpBrush*)brush, 0, 0, rect.right, rect.bottom); + expect(Ok, status); + + GdipDisposeImage(src_img.image); + GdipDeleteBrush((GpBrush*)brush); + GdipDeleteGraphics(graphics); + GdipFree(src_img_data); + + pixel = GetBitmapPixelBuffer(hdc, bmp, width, height); + if (pixel) + { + color[0] = get_bitmap_pixel(width/2, height/2); + color[1] = get_bitmap_pixel(width/2+1, height/2); + color[2] = get_bitmap_pixel(width/2, height/2+1); + color[3] = get_bitmap_pixel(width/2-1, height/2-1); + color[4] = get_bitmap_pixel(width/2-1, height-1); + color[5] = get_bitmap_pixel(width-1, height/2-1); + } + ok(is_blue_color(color[0]) && is_blue_color(color[1]) && is_blue_color(color[2]) && + color[3] == 0 && color[4] == 0 && color[5] == 0, + "Expected GdipFillRectangleI take effect!\n" ); + ReleaseBitmapPixelBuffer(pixel); + + SelectObject(hdc, old); + DeleteObject(bmp); + DeleteDC(hdc); + ReleaseDC(hwnd, dc); +} + +static void test_GdipFillRectanglesOnBitmapTextureBrush(void) +{ + ARGB color[6] = {0,0,0,0,0,0}; + UINT x = 0; + UINT y = 0; + RECT rect = {100, 100, 180, 180}; + UINT width = rect.right - rect.left; + UINT height = rect.bottom - rect.top; + UINT src_img_width = width/2; + UINT src_img_height = height/2; + + GpStatus status = 0; + union + { + GpBitmap *bitmap; + GpImage *image; + } src_img; + union + { + GpBitmap *bitmap; + GpImage *image; + } dst_img; + + GpTexture *brush = NULL; + GpGraphics *graphics = NULL; + BYTE *src_img_data = GdipAlloc(src_img_width*src_img_height*4); + DWORD *pixel = (DWORD *)src_img_data; + ok(pixel != NULL, "Expected src_img_data is valid\n"); + + status = GdipCreateBitmapFromScan0(width, height, width*4, + PixelFormat32bppARGB, NULL, &dst_img.bitmap); + expect(Ok, status); + + /*build a blue solid image!*/ + for(y = 0; y < src_img_height; ++y) + { + for(x = 0; x < src_img_width; ++x) + { + pixel[x] = BLUE_COLOR; + } + + pixel += src_img_width; + } + + status = GdipCreateBitmapFromScan0(src_img_width, src_img_height, src_img_width*4, + PixelFormat32bppARGB, src_img_data, &src_img.bitmap); + expect(Ok, status); + + status = GdipCreateTexture(src_img.image, 0, &brush); + expect(Ok, status); + + status = GdipGetImageGraphicsContext(dst_img.image, &graphics); + expect(Ok, status); + + status = GdipSetClipRectI(graphics, 0, 0, width, height, CombineModeReplace); + expect(Ok, status); + + status = GdipFillRectangleI(graphics, (GpBrush*)brush, 0, 0, width/2, height/2); + expect(Ok, status); + + GdipDeleteBrush((GpBrush*)brush); + GdipDeleteGraphics(graphics); + + GdipBitmapGetPixel(dst_img.bitmap, 0, 0, &color[0]); + GdipBitmapGetPixel(dst_img.bitmap, 0, 1, &color[1]); + GdipBitmapGetPixel(dst_img.bitmap, 1, 0, &color[2]); + GdipBitmapGetPixel(dst_img.bitmap, width/2, 0, &color[3]); + GdipBitmapGetPixel(dst_img.bitmap, width/2, height/2, &color[4]); + GdipBitmapGetPixel(dst_img.bitmap, 0, height/2, &color[5]); + + ok(is_blue_color(color[0]) && is_blue_color(color[1]) && is_blue_color(color[2]) && + color[3] == 0 && color[4] == 0 && color[5] == 0, + "Expected GdipFillRectangleI take effect!\n" ); + + GdipDisposeImage(src_img.image); + GdipDisposeImage(dst_img.image); + GdipFree(src_img_data); +} + +static void test_GdipDrawImagePointsRectOnMemoryDC(void) +{ + ARGB color[6] = {0,0,0,0,0,0}; + POINT pt = {0,0}; + RECT rect = {100, 100, 180, 180}; + UINT width = rect.right - rect.left; + UINT height = rect.bottom - rect.top; + GpStatus status = 0; + union + { + GpBitmap *bitmap; + GpImage *image; + } src_img; + GpGraphics *graphics = NULL; + HDC dc = GetDC( hwnd); + HDC hdc = CreateCompatibleDC(dc); + HBITMAP bmp = CreateCompatibleBitmap(dc, width, height); + HGDIOBJ old = SelectObject(hdc, bmp); + + UINT x = 0; + UINT y = 0; + UINT src_img_width = width/2; + UINT src_img_height = height/2; + BYTE *src_img_data = GdipAlloc(src_img_width*src_img_height*4); + DWORD *pixel = (DWORD *)src_img_data; + ok(pixel != NULL, "Expected src_img_data is valid\n"); + + /*Change the window origin is the key test point*/ + SetWindowOrgEx(hdc, rect.left, rect.top, &pt); + + /*build a blue solid image!*/ + for(y = 0; y < src_img_height; ++y) + { + for(x = 0; x < src_img_width; ++x) + { + pixel[x] = BLUE_COLOR; + } + + pixel += src_img_width; + } + + status = GdipCreateBitmapFromScan0(src_img_width, src_img_height, src_img_width*4, + PixelFormat32bppARGB, src_img_data, &src_img.bitmap); + expect(Ok, status); + + status = GdipCreateFromHDC(hdc, &graphics); + expect(Ok, status); + + status = GdipDrawImageRectRectI(graphics, src_img.image, + rect.left+width/2, rect.top+height/2, width/2, height/2, + 0, 0, src_img_width, src_img_height, UnitPixel, NULL, NULL, NULL); + expect(Ok, status); + + GdipDisposeImage(src_img.image); + GdipDeleteGraphics(graphics); + GdipFree(src_img_data); + + pixel = GetBitmapPixelBuffer(hdc, bmp, width, height); + if (pixel) + { + color[0] = get_bitmap_pixel(width/2, height/2); + color[1] = get_bitmap_pixel(width/2+1, height/2); + color[2] = get_bitmap_pixel(width/2, height/2+1); + color[3] = get_bitmap_pixel(width/2-1, height/2-1); + color[4] = get_bitmap_pixel(width/2-1, height-1); + color[5] = get_bitmap_pixel(width-1, height/2-1); + } + ok(is_blue_color(color[0]) && is_blue_color(color[1]) && is_blue_color(color[2]) && + color[3] == 0 && color[4] == 0 && color[5] == 0, + "Expected GdipDrawImageRectRectI take effect!\n" ); + ReleaseBitmapPixelBuffer(pixel); + + SelectObject(hdc, old); + DeleteObject(bmp); + DeleteDC(hdc); + ReleaseDC(hwnd, dc); +} + START_TEST(graphics) { struct GdiplusStartupInput gdiplusStartupInput; ULONG_PTR gdiplusToken; WNDCLASSA class; + HMODULE gdiplus_mod = GetModuleHandleA("gdiplus.dll"); + HMODULE hmsvcrt; + int (CDECL * _controlfp_s)(unsigned int *cur, unsigned int newval, unsigned int mask); + + /* Enable all FP exceptions except _EM_INEXACT, which gdi32 can trigger */ + hmsvcrt = LoadLibraryA("msvcrt"); + _controlfp_s = (void*)GetProcAddress(hmsvcrt, "_controlfp_s"); + if (_controlfp_s) _controlfp_s(0, 0, 0x0008001e); + + pGdipGraphicsSetAbort = (void*)GetProcAddress(gdiplus_mod, "GdipGraphicsSetAbort"); memset( &class, 0, sizeof(class) ); class.lpszClassName = "gdiplus_test"; @@ -6228,7 +6618,12 @@ START_TEST(graphics) test_bitmapfromgraphics(); test_GdipFillRectangles(); test_GdipGetVisibleClipBounds_memoryDC(); + test_GdipFillRectanglesOnMemoryDCSolidBrush(); + test_GdipFillRectanglesOnMemoryDCTextureBrush(); + test_GdipFillRectanglesOnBitmapTextureBrush(); + test_GdipDrawImagePointsRectOnMemoryDC(); test_container_rects(); + test_GdipGraphicsSetAbort(); GdiplusShutdown(gdiplusToken); DestroyWindow( hwnd ); diff --git a/rostests/winetests/gdiplus/graphicspath.c b/rostests/winetests/gdiplus/graphicspath.c index 25aea41b0bb..6206096db83 100644 --- a/rostests/winetests/gdiplus/graphicspath.c +++ b/rostests/winetests/gdiplus/graphicspath.c @@ -1071,6 +1071,17 @@ static path_test_t widenline_wide_path[] = { {5.0, 20.0, PathPointTypeLine|PathPointTypeCloseSubpath, 0, 0} /*3*/ }; +static path_test_t widenline_dash_path[] = { + {5.0, 0.0, PathPointTypeStart, 0, 0}, /*0*/ + {35.0, 0.0, PathPointTypeLine, 0, 0}, /*1*/ + {35.0, 10.0, PathPointTypeLine, 0, 0}, /*2*/ + {5.0, 10.0, PathPointTypeLine|PathPointTypeCloseSubpath, 0, 0}, /*3*/ + {45.0, 0.0, PathPointTypeStart, 0, 0}, /*4*/ + {50.0, 0.0, PathPointTypeLine, 0, 0}, /*5*/ + {50.0, 10.0, PathPointTypeLine, 0, 0}, /*6*/ + {45.0, 10.0, PathPointTypeLine|PathPointTypeCloseSubpath, 0, 0}, /*7*/ + }; + static void test_widen(void) { GpStatus status; @@ -1145,6 +1156,22 @@ static void test_widen(void) status = GdipScaleMatrix(m, 1.0, 0.5, MatrixOrderAppend); expect(Ok, status); + /* dashed line */ + status = GdipResetPath(path); + expect(Ok, status); + status = GdipAddPathLine(path, 5.0, 5.0, 50.0, 5.0); + expect(Ok, status); + + status = GdipSetPenDashStyle(pen, DashStyleDash); + expect(Ok, status); + + status = GdipWidenPath(path, pen, m, 1.0); + expect(Ok, status); + ok_path(path, widenline_dash_path, sizeof(widenline_dash_path)/sizeof(path_test_t), FALSE); + + status = GdipSetPenDashStyle(pen, DashStyleSolid); + expect(Ok, status); + /* pen width in UnitWorld */ GdipDeletePen(pen); status = GdipCreatePen1(0xffffffff, 10.0, UnitWorld, &pen); @@ -1308,6 +1335,13 @@ START_TEST(graphicspath) { struct GdiplusStartupInput gdiplusStartupInput; ULONG_PTR gdiplusToken; + HMODULE hmsvcrt; + int (CDECL * _controlfp_s)(unsigned int *cur, unsigned int newval, unsigned int mask); + + /* Enable all FP exceptions except _EM_INEXACT, which gdi32 can trigger */ + hmsvcrt = LoadLibraryA("msvcrt"); + _controlfp_s = (void*)GetProcAddress(hmsvcrt, "_controlfp_s"); + if (_controlfp_s) _controlfp_s(0, 0, 0x0008001e); gdiplusStartupInput.GdiplusVersion = 1; gdiplusStartupInput.DebugEventCallback = NULL; diff --git a/rostests/winetests/gdiplus/image.c b/rostests/winetests/gdiplus/image.c index 268cdea3cd4..a332ddf71f8 100644 --- a/rostests/winetests/gdiplus/image.c +++ b/rostests/winetests/gdiplus/image.c @@ -5376,6 +5376,13 @@ START_TEST(image) HMODULE mod = GetModuleHandleA("gdiplus.dll"); struct GdiplusStartupInput gdiplusStartupInput; ULONG_PTR gdiplusToken; + HMODULE hmsvcrt; + int (CDECL * _controlfp_s)(unsigned int *cur, unsigned int newval, unsigned int mask); + + /* Enable all FP exceptions except _EM_INEXACT, which gdi32 can trigger */ + hmsvcrt = LoadLibraryA("msvcrt"); + _controlfp_s = (void*)GetProcAddress(hmsvcrt, "_controlfp_s"); + if (_controlfp_s) _controlfp_s(0, 0, 0x0008001e); gdiplusStartupInput.GdiplusVersion = 1; gdiplusStartupInput.DebugEventCallback = NULL; diff --git a/rostests/winetests/gdiplus/matrix.c b/rostests/winetests/gdiplus/matrix.c index be82f185a44..e1e61aa2a1f 100644 --- a/rostests/winetests/gdiplus/matrix.c +++ b/rostests/winetests/gdiplus/matrix.c @@ -34,6 +34,22 @@ #define expect(expected, got) ok(got == expected, "Expected %.8x, got %.8x\n", expected, got) #define expectf(expected, got) ok(fabs(expected - got) < 0.0001, "Expected %.2f, got %.2f\n", expected, got) +static BOOL compare_float(float f, float g, unsigned int ulps) +{ + int x = *(int *)&f; + int y = *(int *)&g; + + if (x < 0) + x = INT_MIN - x; + if (y < 0) + y = INT_MIN - y; + + if (abs(x - y) > ulps) + return FALSE; + + return TRUE; +} + static void test_constructor_destructor(void) { GpStatus status; @@ -135,6 +151,7 @@ static void test_invert(void) GpMatrix *matrix = NULL; GpMatrix *inverted = NULL; BOOL equal = FALSE; + REAL elems[6]; /* NULL */ status = GdipInvertMatrix(NULL); @@ -154,6 +171,18 @@ static void test_invert(void) GdipIsMatrixEqual(matrix, inverted, &equal); expect(TRUE, equal); + GdipCreateMatrix2(0.0006, 0, 0, 0.0006, 400, 400, &matrix); + status = GdipInvertMatrix(matrix); + expect(Ok, status); + status = GdipGetMatrixElements(matrix, elems); + expect(Ok, status); + ok(compare_float(elems[0], 1666.666504, 1), "elems[0] = %.10g\n", elems[0]); + ok(compare_float(elems[1], 0, 0), "elems[1] = %.10g\n", elems[1]); + ok(compare_float(elems[2], 0, 0), "elems[2] = %.10g\n", elems[2]); + ok(compare_float(elems[3], 1666.666504, 1), "elems[3] = %.10g\n", elems[3]); + ok(compare_float(elems[4], -666666.6875, 1), "elems[4] = %.10g\n", elems[4]); + ok(compare_float(elems[5], -666666.6875, 1), "elems[5] = %.10g\n", elems[5]); + GdipDeleteMatrix(inverted); GdipDeleteMatrix(matrix); } @@ -350,6 +379,13 @@ START_TEST(matrix) { struct GdiplusStartupInput gdiplusStartupInput; ULONG_PTR gdiplusToken; + HMODULE hmsvcrt; + int (CDECL * _controlfp_s)(unsigned int *cur, unsigned int newval, unsigned int mask); + + /* Enable all FP exceptions except _EM_INEXACT, which gdi32 can trigger */ + hmsvcrt = LoadLibraryA("msvcrt"); + _controlfp_s = (void*)GetProcAddress(hmsvcrt, "_controlfp_s"); + if (_controlfp_s) _controlfp_s(0, 0, 0x0008001e); gdiplusStartupInput.GdiplusVersion = 1; gdiplusStartupInput.DebugEventCallback = NULL; diff --git a/rostests/winetests/gdiplus/metafile.c b/rostests/winetests/gdiplus/metafile.c index b5351ef2339..123576729a5 100644 --- a/rostests/winetests/gdiplus/metafile.c +++ b/rostests/winetests/gdiplus/metafile.c @@ -69,6 +69,39 @@ typedef struct EmfPlusRecordHeader DWORD DataSize; } EmfPlusRecordHeader; +typedef enum +{ + ObjectTypeInvalid, + ObjectTypeBrush, + ObjectTypePen, + ObjectTypePath, + ObjectTypeRegion, + ObjectTypeImage, + ObjectTypeFont, + ObjectTypeStringFormat, + ObjectTypeImageAttributes, + ObjectTypeCustomLineCap, +} ObjectType; + +typedef enum +{ + ImageDataTypeUnknown, + ImageDataTypeBitmap, + ImageDataTypeMetafile, +} ImageDataType; + +typedef struct +{ + EmfPlusRecordHeader Header; + /* EmfPlusImage */ + DWORD Version; + ImageDataType Type; + /* EmfPlusMetafile */ + DWORD MetafileType; + DWORD MetafileDataSize; + BYTE MetafileData[1]; +} MetafileImageObject; + static int CALLBACK enum_emf_proc(HDC hDC, HANDLETABLE *lpHTable, const ENHMETARECORD *lpEMFR, int nObj, LPARAM lpData) { @@ -102,14 +135,30 @@ static int CALLBACK enum_emf_proc(HDC hDC, HANDLETABLE *lpHTable, const ENHMETAR actual.record_type = record->Type; check_record(state->count, state->desc, &state->expected[state->count], &actual); - state->count++; + + if (state->expected[state->count-1].todo && state->expected[state->count-1].record_type != actual.record_type) + continue; } else { ok(0, "%s: Unexpected EMF+ 0x%x record\n", state->desc, record->Type); } + if ((record->Flags >> 8) == ObjectTypeImage && record->Type == EmfPlusRecordTypeObject) + { + const MetafileImageObject *image = (const MetafileImageObject*)record; + + if (image->Type == ImageDataTypeMetafile) + { + HENHMETAFILE hemf = SetEnhMetaFileBits(image->MetafileDataSize, image->MetafileData); + ok(hemf != NULL, "%s: SetEnhMetaFileBits failed\n", state->desc); + + EnumEnhMetaFile(0, hemf, enum_emf_proc, state, NULL); + DeleteEnhMetaFile(hemf); + } + } + offset += record->Size; } @@ -645,6 +694,26 @@ static const emfplus_record emfonly_records[] = { {0} }; +static const emfplus_record emfonly_draw_records[] = { + {0, EMR_HEADER}, + {1, EMR_SAVEDC}, + {1, EMR_SETICMMODE}, + {1, EMR_SETMITERLIMIT}, + {1, EMR_MODIFYWORLDTRANSFORM}, + {1, EMR_EXTCREATEPEN}, + {1, EMR_SELECTOBJECT}, + {1, EMR_SELECTOBJECT}, + {1, EMR_POLYLINE16}, + {1, EMR_SELECTOBJECT}, + {1, EMR_SELECTOBJECT}, + {1, EMR_MODIFYWORLDTRANSFORM}, + {1, EMR_DELETEOBJECT}, + {1, EMR_SETMITERLIMIT}, + {1, EMR_RESTOREDC}, + {0, EMR_EOF}, + {1} +}; + static void test_emfonly(void) { GpStatus stat; @@ -663,6 +732,7 @@ static void test_emfonly(void) HBRUSH hbrush, holdbrush; GpBitmap *bitmap; ARGB color; + GpPen *pen; hdc = CreateCompatibleDC(0); @@ -905,6 +975,35 @@ static void test_emfonly(void) stat = GdipDisposeImage((GpImage*)metafile); expect(Ok, stat); + + /* test drawing to metafile with gdi+ functions */ + hdc = CreateCompatibleDC(0); + + stat = GdipRecordMetafile(hdc, EmfTypeEmfOnly, &frame, MetafileFrameUnitPixel, description, &metafile); + expect(Ok, stat); + + DeleteDC(hdc); + + if (stat != Ok) + return; + + stat = GdipGetImageGraphicsContext((GpImage*)metafile, &graphics); + expect(Ok, stat); + + stat = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen); + expect(Ok, stat); + stat = GdipDrawLineI(graphics, pen, 0, 0, 10, 10); + todo_wine expect(Ok, stat); + GdipDeletePen(pen); + + stat = GdipDeleteGraphics(graphics); + expect(Ok, stat); + + check_metafile(metafile, emfonly_draw_records, "emfonly draw metafile", dst_points, &frame, UnitPixel); + sync_metafile(&metafile, "emfonly_draw.emf"); + + stat = GdipDisposeImage((GpImage*)metafile); + expect(Ok, stat); } static const emfplus_record fillrect_records[] = { @@ -2060,6 +2159,8 @@ static const emfplus_record clipping_records[] = { {0, EmfPlusRecordTypeRestore}, {0, EmfPlusRecordTypeSetClipRect}, {0, EmfPlusRecordTypeFillRects}, + {0, EmfPlusRecordTypeObject, 1}, + {0, EmfPlusRecordTypeSetClipRegion, 1}, {0, EmfPlusRecordTypeEndOfFile}, {0, EMR_EOF}, {0} @@ -2071,7 +2172,9 @@ static void test_clipping(void) GpMetafile *metafile; GpGraphics *graphics; GpBitmap *bitmap; + GpRegion *region; GpBrush *brush; + GpRectF rect; ARGB color; HDC hdc; static const GpRectF frame = {0.0, 0.0, 100.0, 100.0}; @@ -2095,9 +2198,23 @@ static void test_clipping(void) stat = GdipSaveGraphics(graphics, &state); expect(Ok, stat); + stat = GdipGetVisibleClipBounds(graphics, &rect); + expect(Ok, stat); + ok(rect.X == -0x400000, "rect.X = %f\n", rect.X); + ok(rect.Y == -0x400000, "rect.Y = %f\n", rect.Y); + ok(rect.Width == 0x800000, "rect.Width = %f\n", rect.Width); + ok(rect.Height == 0x800000, "rect.Height = %f\n", rect.Height); + stat = GdipSetClipRect(graphics, 30, 30, 10, 10, CombineModeReplace); expect(Ok, stat); + stat = GdipGetVisibleClipBounds(graphics, &rect); + expect(Ok, stat); + ok(rect.X == 30, "rect.X = %f\n", rect.X); + ok(rect.Y == 30, "rect.Y = %f\n", rect.Y); + ok(rect.Width == 10, "rect.Width = %f\n", rect.Width); + ok(rect.Height == 10, "rect.Height = %f\n", rect.Height); + stat = GdipCreateSolidFill((ARGB)0xff000000, (GpSolidFill**)&brush); expect(Ok, stat); @@ -2122,6 +2239,15 @@ static void test_clipping(void) stat = GdipDeleteBrush(brush); expect(Ok, stat); + stat = GdipCreateRegionRect(&rect, ®ion); + expect(Ok, stat); + + stat = GdipSetClipRegion(graphics, region, CombineModeIntersect); + expect(Ok, stat); + + stat = GdipDeleteRegion(region); + expect(Ok, stat); + stat = GdipDeleteGraphics(graphics); expect(Ok, stat); @@ -2277,12 +2403,389 @@ static void test_gditransform(void) expect(Ok, stat); } +static const emfplus_record draw_image_bitmap_records[] = { + {0, EMR_HEADER}, + {0, EmfPlusRecordTypeHeader}, + {0, EmfPlusRecordTypeObject}, + {0, EmfPlusRecordTypeObject}, + {0, EmfPlusRecordTypeDrawImagePoints}, + {1, EMR_SAVEDC}, + {1, EMR_SETICMMODE}, + {1, EMR_BITBLT}, + {1, EMR_RESTOREDC}, + {0, EmfPlusRecordTypeEndOfFile}, + {0, EMR_EOF}, + {0} +}; + +static const emfplus_record draw_image_metafile_records[] = { + {0, EMR_HEADER}, + {0, EmfPlusRecordTypeHeader}, + {0, EmfPlusRecordTypeObject}, + /* metafile object */ + {0, EMR_HEADER}, + {0, EmfPlusRecordTypeHeader}, + {0, EmfPlusRecordTypeObject}, + {0, EmfPlusRecordTypeObject}, + {0, EmfPlusRecordTypeDrawImagePoints}, + {1, EMR_SAVEDC}, + {1, EMR_SETICMMODE}, + {1, EMR_BITBLT}, + {1, EMR_RESTOREDC}, + {0, EmfPlusRecordTypeEndOfFile}, + {0, EMR_EOF}, + /* end of metafile object */ + {0, EmfPlusRecordTypeDrawImagePoints}, + {1, EMR_SAVEDC}, + {1, EMR_SETICMMODE}, + {1, EMR_BITBLT}, + {1, EMR_RESTOREDC}, + {0, EmfPlusRecordTypeEndOfFile}, + {0, EMR_EOF}, + {0} +}; + +static void test_drawimage(void) +{ + static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0}; + static const GpPointF dst_points[3] = {{10.0,10.0},{85.0,15.0},{10.0,80.0}}; + static const GpRectF frame = {0.0, 0.0, 100.0, 100.0}; + const ColorMatrix double_red = {{ + {2.0,0.0,0.0,0.0,0.0}, + {0.0,1.0,0.0,0.0,0.0}, + {0.0,0.0,1.0,0.0,0.0}, + {0.0,0.0,0.0,1.0,0.0}, + {0.0,0.0,0.0,0.0,1.0}}}; + + GpImageAttributes *imageattr; + GpMetafile *metafile; + GpGraphics *graphics; + HENHMETAFILE hemf; + GpStatus stat; + BITMAPINFO info; + BYTE buff[400]; + GpImage *image; + HDC hdc; + + hdc = CreateCompatibleDC(0); + stat = GdipRecordMetafile(hdc, EmfTypeEmfPlusOnly, &frame, MetafileFrameUnitPixel, description, &metafile); + expect(Ok, stat); + + stat = GdipGetImageGraphicsContext((GpImage*)metafile, &graphics); + expect(Ok, stat); + + memset(&info, 0, sizeof(info)); + info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + info.bmiHeader.biWidth = 10; + info.bmiHeader.biHeight = 10; + info.bmiHeader.biPlanes = 1; + info.bmiHeader.biBitCount = 32; + info.bmiHeader.biCompression = BI_RGB; + memset(buff, 0x80, sizeof(buff)); + stat = GdipCreateBitmapFromGdiDib(&info, buff, (GpBitmap**)&image); + expect(Ok, stat); + + stat = GdipCreateImageAttributes(&imageattr); + expect(Ok, stat); + + stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault, + TRUE, &double_red, NULL, ColorMatrixFlagsDefault); + expect(Ok, stat); + + stat = GdipDrawImagePointsRect(graphics, image, dst_points, 3, + 0.0, 0.0, 10.0, 10.0, UnitPixel, imageattr, NULL, NULL); + GdipDisposeImageAttributes(imageattr); + expect(Ok, stat); + + GdipDisposeImage(image); + + stat = GdipDeleteGraphics(graphics); + expect(Ok, stat); + sync_metafile(&metafile, "draw_image_bitmap.emf"); + + stat = GdipGetHemfFromMetafile(metafile, &hemf); + expect(Ok, stat); + + check_emfplus(hemf, draw_image_bitmap_records, "draw image bitmap"); + + /* test drawing metafile */ + stat = GdipRecordMetafile(hdc, EmfTypeEmfPlusOnly, &frame, MetafileFrameUnitPixel, description, &metafile); + expect(Ok, stat); + + stat = GdipGetImageGraphicsContext((GpImage*)metafile, &graphics); + expect(Ok, stat); + + stat = GdipCreateMetafileFromEmf(hemf, TRUE, (GpMetafile**)&image); + expect(Ok, stat); + + stat = GdipDrawImagePointsRect(graphics, image, dst_points, 3, + 0.0, 0.0, 100.0, 100.0, UnitPixel, NULL, NULL, NULL); + expect(Ok, stat); + + GdipDisposeImage(image); + + stat = GdipDeleteGraphics(graphics); + expect(Ok, stat); + sync_metafile(&metafile, "draw_image_metafile.emf"); + + stat = GdipGetHemfFromMetafile(metafile, &hemf); + expect(Ok, stat); + + if (GetProcAddress(GetModuleHandleA("gdiplus.dll"), "GdipConvertToEmfPlus")) + { + check_emfplus(hemf, draw_image_metafile_records, "draw image metafile"); + } + else + { + win_skip("draw image metafile records tests skipped\n"); + } + DeleteEnhMetaFile(hemf); + + DeleteDC(hdc); + stat = GdipDisposeImage((GpImage*)metafile); + expect(Ok, stat); +} + +static const emfplus_record properties_records[] = { + {0, EMR_HEADER}, + {0, EmfPlusRecordTypeHeader}, + {0, EmfPlusRecordTypeSetTextRenderingHint}, + {0, EmfPlusRecordTypeSetPixelOffsetMode}, + {0, EmfPlusRecordTypeSetAntiAliasMode}, + {0, EmfPlusRecordTypeSetCompositingMode}, + {0, EmfPlusRecordTypeSetCompositingQuality}, + {0, EmfPlusRecordTypeSetInterpolationMode}, + {0, EmfPlusRecordTypeEndOfFile}, + {0, EMR_EOF}, + {0} +}; + +static void test_properties(void) +{ + static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0}; + static const GpRectF frame = {0.0, 0.0, 100.0, 100.0}; + + GpMetafile *metafile; + GpGraphics *graphics; + HENHMETAFILE hemf; + GpStatus stat; + HDC hdc; + + hdc = CreateCompatibleDC(0); + stat = GdipRecordMetafile(hdc, EmfTypeEmfPlusOnly, &frame, MetafileFrameUnitPixel, description, &metafile); + expect(Ok, stat); + DeleteDC(hdc); + + stat = GdipGetImageGraphicsContext((GpImage*)metafile, &graphics); + expect(Ok, stat); + + stat = GdipSetTextRenderingHint(graphics, TextRenderingHintSystemDefault); + expect(Ok, stat); + stat = GdipSetTextRenderingHint(graphics, TextRenderingHintAntiAlias); + expect(Ok, stat); + + stat = GdipSetPixelOffsetMode(graphics, PixelOffsetModeHighQuality); + expect(Ok, stat); + stat = GdipSetPixelOffsetMode(graphics, PixelOffsetModeHighQuality); + expect(Ok, stat); + + stat = GdipSetSmoothingMode(graphics, SmoothingModeAntiAlias); + expect(Ok, stat); + stat = GdipSetSmoothingMode(graphics, SmoothingModeAntiAlias); + expect(Ok, stat); + + stat = GdipSetCompositingMode(graphics, CompositingModeSourceOver); + expect(Ok, stat); + stat = GdipSetCompositingMode(graphics, CompositingModeSourceCopy); + expect(Ok, stat); + + stat = GdipSetCompositingQuality(graphics, CompositingQualityHighQuality); + expect(Ok, stat); + stat = GdipSetCompositingQuality(graphics, CompositingQualityHighQuality); + expect(Ok, stat); + + stat = GdipSetInterpolationMode(graphics, InterpolationModeDefault); + expect(Ok, stat); + stat = GdipSetInterpolationMode(graphics, InterpolationModeHighQuality); + expect(Ok, stat); + + stat = GdipDeleteGraphics(graphics); + expect(Ok, stat); + sync_metafile(&metafile, "properties.emf"); + + stat = GdipGetHemfFromMetafile(metafile, &hemf); + expect(Ok, stat); + + check_emfplus(hemf, properties_records, "properties"); + DeleteEnhMetaFile(hemf); + + stat = GdipDisposeImage((GpImage*)metafile); + expect(Ok, stat); +} + +static const emfplus_record draw_path_records[] = { + {0, EMR_HEADER}, + {0, EmfPlusRecordTypeHeader}, + {0, EmfPlusRecordTypeObject}, + {0, EmfPlusRecordTypeObject}, + {0, EmfPlusRecordTypeDrawPath}, + {1, EMR_SAVEDC}, + {1, EMR_SETICMMODE}, + {1, EMR_BITBLT}, + {1, EMR_RESTOREDC}, + {0, EmfPlusRecordTypeEndOfFile}, + {0, EMR_EOF}, + {0} +}; + +static void test_drawpath(void) +{ + static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0}; + static const GpRectF frame = {0.0, 0.0, 100.0, 100.0}; + + GpMetafile *metafile; + GpGraphics *graphics; + HENHMETAFILE hemf; + GpStatus stat; + GpPath *path; + GpPen *pen; + HDC hdc; + + hdc = CreateCompatibleDC(0); + stat = GdipRecordMetafile(hdc, EmfTypeEmfPlusOnly, &frame, MetafileFrameUnitPixel, description, &metafile); + expect(Ok, stat); + DeleteDC(hdc); + + stat = GdipGetImageGraphicsContext((GpImage*)metafile, &graphics); + expect(Ok, stat); + + stat = GdipCreatePath(FillModeAlternate, &path); + expect(Ok, stat); + stat = GdipAddPathLine(path, 5, 5, 30, 30); + expect(Ok, stat); + + stat = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen); + expect(Ok, stat); + + stat = GdipDrawPath(graphics, pen, path); + expect(Ok, stat); + + stat = GdipDeletePen(pen); + expect(Ok, stat); + stat = GdipDeletePath(path); + expect(Ok, stat); + + stat = GdipDeleteGraphics(graphics); + expect(Ok, stat); + sync_metafile(&metafile, "draw_path.emf"); + + stat = GdipGetHemfFromMetafile(metafile, &hemf); + expect(Ok, stat); + + check_emfplus(hemf, draw_path_records, "draw path"); + DeleteEnhMetaFile(hemf); + + stat = GdipDisposeImage((GpImage*)metafile); + expect(Ok, stat); +} + +static const emfplus_record fill_path_records[] = { + {0, EMR_HEADER}, + {0, EmfPlusRecordTypeHeader}, + {0, EmfPlusRecordTypeObject}, + {0, EmfPlusRecordTypeFillPath}, + {1, EMR_SAVEDC}, + {1, EMR_SETICMMODE}, + {1, EMR_BITBLT}, + {1, EMR_RESTOREDC}, + {0, EmfPlusRecordTypeEndOfFile}, + {0, EMR_EOF}, + {0} +}; + +static void test_fillpath(void) +{ + static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0}; + static const GpRectF frame = {0.0, 0.0, 100.0, 100.0}; + static const WCHAR winetestemfW[] = {'w','i','n','e','t','e','s','t','.','e','m','f',0}; + + GpMetafile *metafile; + GpGraphics *graphics; + GpSolidFill *brush; + HENHMETAFILE hemf; + GpStatus stat; + GpPath *path; + HDC hdc; + + hdc = CreateCompatibleDC(0); + stat = GdipRecordMetafile(hdc, EmfTypeEmfPlusOnly, &frame, MetafileFrameUnitPixel, description, &metafile); + expect(Ok, stat); + DeleteDC(hdc); + + stat = GdipGetImageGraphicsContext((GpImage*)metafile, &graphics); + expect(Ok, stat); + + stat = GdipCreatePath(FillModeAlternate, &path); + expect(Ok, stat); + stat = GdipAddPathLine(path, 5, 5, 30, 30); + expect(Ok, stat); + stat = GdipAddPathLine(path, 30, 30, 5, 30); + expect(Ok, stat); + + stat = GdipCreateSolidFill(0xffaabbcc, &brush); + expect(Ok, stat); + + stat = GdipFillPath(graphics, (GpBrush*)brush, path); + expect(Ok, stat); + + stat = GdipDeleteBrush((GpBrush*)brush); + expect(Ok, stat); + stat = GdipDeletePath(path); + expect(Ok, stat); + + stat = GdipDeleteGraphics(graphics); + expect(Ok, stat); + sync_metafile(&metafile, "fill_path.emf"); + + stat = GdipGetHemfFromMetafile(metafile, &hemf); + expect(Ok, stat); + + check_emfplus(hemf, fill_path_records, "fill path"); + + /* write to disk */ + DeleteEnhMetaFile(CopyEnhMetaFileW(hemf, winetestemfW)); + + DeleteEnhMetaFile(hemf); + + stat = GdipDisposeImage((GpImage*)metafile); + expect(Ok, stat); + + /* should succeed when given path to an EMF */ + stat = GdipCreateMetafileFromWmfFile(winetestemfW, NULL, &metafile); + expect(Ok, stat); + + stat = GdipDisposeImage((GpImage*)metafile); + expect(Ok, stat); + + DeleteFileW(winetestemfW); + + stat = GdipCreateMetafileFromWmfFile(winetestemfW, NULL, &metafile); + expect(GenericError, stat); +} + START_TEST(metafile) { struct GdiplusStartupInput gdiplusStartupInput; ULONG_PTR gdiplusToken; int myARGC; char **myARGV; + HMODULE hmsvcrt; + int (CDECL * _controlfp_s)(unsigned int *cur, unsigned int newval, unsigned int mask); + + /* Enable all FP exceptions except _EM_INEXACT, which gdi32 can trigger */ + hmsvcrt = LoadLibraryA("msvcrt"); + _controlfp_s = (void*)GetProcAddress(hmsvcrt, "_controlfp_s"); + if (_controlfp_s) _controlfp_s(0, 0, 0x0008001e); gdiplusStartupInput.GdiplusVersion = 1; gdiplusStartupInput.DebugEventCallback = NULL; @@ -2314,6 +2817,10 @@ START_TEST(metafile) test_containers(); test_clipping(); test_gditransform(); + test_drawimage(); + test_properties(); + test_drawpath(); + test_fillpath(); GdiplusShutdown(gdiplusToken); } diff --git a/rostests/winetests/gdiplus/pathiterator.c b/rostests/winetests/gdiplus/pathiterator.c index 137f332259b..cf6d10028b8 100644 --- a/rostests/winetests/gdiplus/pathiterator.c +++ b/rostests/winetests/gdiplus/pathiterator.c @@ -565,6 +565,13 @@ START_TEST(pathiterator) { struct GdiplusStartupInput gdiplusStartupInput; ULONG_PTR gdiplusToken; + HMODULE hmsvcrt; + int (CDECL * _controlfp_s)(unsigned int *cur, unsigned int newval, unsigned int mask); + + /* Enable all FP exceptions except _EM_INEXACT, which gdi32 can trigger */ + hmsvcrt = LoadLibraryA("msvcrt"); + _controlfp_s = (void*)GetProcAddress(hmsvcrt, "_controlfp_s"); + if (_controlfp_s) _controlfp_s(0, 0, 0x0008001e); gdiplusStartupInput.GdiplusVersion = 1; gdiplusStartupInput.DebugEventCallback = NULL; diff --git a/rostests/winetests/gdiplus/pen.c b/rostests/winetests/gdiplus/pen.c index a8ee9da1b43..39833caec00 100644 --- a/rostests/winetests/gdiplus/pen.c +++ b/rostests/winetests/gdiplus/pen.c @@ -461,6 +461,13 @@ START_TEST(pen) { struct GdiplusStartupInput gdiplusStartupInput; ULONG_PTR gdiplusToken; + HMODULE hmsvcrt; + int (CDECL * _controlfp_s)(unsigned int *cur, unsigned int newval, unsigned int mask); + + /* Enable all FP exceptions except _EM_INEXACT, which gdi32 can trigger */ + hmsvcrt = LoadLibraryA("msvcrt"); + _controlfp_s = (void*)GetProcAddress(hmsvcrt, "_controlfp_s"); + if (_controlfp_s) _controlfp_s(0, 0, 0x0008001e); test_startup(); diff --git a/rostests/winetests/gdiplus/region.c b/rostests/winetests/gdiplus/region.c index b09c55c8637..878c00089b1 100644 --- a/rostests/winetests/gdiplus/region.c +++ b/rostests/winetests/gdiplus/region.c @@ -42,7 +42,7 @@ #define expectf_(expected, got, precision) ok(fabs((expected) - (got)) < (precision), "Expected %f, got %f\n", (expected), (got)) #define expectf(expected, got) expectf_((expected), (got), 0.001) -#define expect_magic(value) ok(*(value) == RGNDATA_MAGIC || *(value) == RGNDATA_MAGIC2, "Expected a known magic value, got %8x\n", *(value)) +#define expect_magic(value) ok(broken(*(value) == RGNDATA_MAGIC) || *(value) == RGNDATA_MAGIC2, "Expected a known magic value, got %8x\n", *(value)) #define expect_dword(value, expected) expect((expected), *(value)) #define expect_float(value, expected) expectf((expected), *(FLOAT *)(value)) @@ -1123,6 +1123,8 @@ static void test_gethrgn(void) GpGraphics *graphics; HRGN hrgn; HDC hdc=GetDC(0); + INT rgntype; + RECT rgnbox; static const RECT empty_rect = {0,0,0,0}; static const RECT test_rect = {10, 11, 20, 21}; static const GpRectF test_rectF = {10.0, 11.0, 10.0, 10.0}; @@ -1243,6 +1245,35 @@ static void test_gethrgn(void) ok(status == Ok, "status %08x\n", status); status = GdipDeleteGraphics(graphics); ok(status == Ok, "status %08x\n", status); + + /* test with gdi32 transform */ + SetViewportOrgEx(hdc, 10, 10, NULL); + + status = GdipCreateFromHDC(hdc, &graphics); + expect(Ok, status); + + status = GdipCreateRegionRect(&test_rectF, ®ion); + expect(Ok, status); + + status = GdipGetRegionHRgn(region, graphics, &hrgn); + expect(Ok, status); + + rgntype = GetRgnBox(hrgn, &rgnbox); + DeleteObject(hrgn); + + expect(SIMPLEREGION, rgntype); + expect(20, rgnbox.left); + expect(21, rgnbox.top); + expect(30, rgnbox.right); + expect(31, rgnbox.bottom); + + status = GdipDeleteRegion(region); + expect(Ok, status); + status = GdipDeleteGraphics(graphics); + expect(Ok, status); + + SetViewportOrgEx(hdc, 0, 0, NULL); + ReleaseDC(0, hdc); } @@ -2267,6 +2298,13 @@ START_TEST(region) { struct GdiplusStartupInput gdiplusStartupInput; ULONG_PTR gdiplusToken; + HMODULE hmsvcrt; + int (CDECL * _controlfp_s)(unsigned int *cur, unsigned int newval, unsigned int mask); + + /* Enable all FP exceptions except _EM_INEXACT, which gdi32 can trigger */ + hmsvcrt = LoadLibraryA("msvcrt"); + _controlfp_s = (void*)GetProcAddress(hmsvcrt, "_controlfp_s"); + if (_controlfp_s) _controlfp_s(0, 0, 0x0008001e); gdiplusStartupInput.GdiplusVersion = 1; gdiplusStartupInput.DebugEventCallback = NULL; diff --git a/rostests/winetests/gdiplus/stringformat.c b/rostests/winetests/gdiplus/stringformat.c index 0135d6e4393..b06726f3683 100644 --- a/rostests/winetests/gdiplus/stringformat.c +++ b/rostests/winetests/gdiplus/stringformat.c @@ -444,6 +444,13 @@ START_TEST(stringformat) { struct GdiplusStartupInput gdiplusStartupInput; ULONG_PTR gdiplusToken; + HMODULE hmsvcrt; + int (CDECL * _controlfp_s)(unsigned int *cur, unsigned int newval, unsigned int mask); + + /* Enable all FP exceptions except _EM_INEXACT, which gdi32 can trigger */ + hmsvcrt = LoadLibraryA("msvcrt"); + _controlfp_s = (void*)GetProcAddress(hmsvcrt, "_controlfp_s"); + if (_controlfp_s) _controlfp_s(0, 0, 0x0008001e); gdiplusStartupInput.GdiplusVersion = 1; gdiplusStartupInput.DebugEventCallback = NULL;