[GDIPLUS_WINETEST] Sync with Wine Staging 2.16. CORE-13762

svn path=/trunk/; revision=75873
This commit is contained in:
Amine Khaldi 2017-09-17 12:34:24 +00:00
parent c6f32e4a5f
commit 73232b5227
12 changed files with 1420 additions and 86 deletions

View file

@ -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);
}

View file

@ -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;

View file

@ -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;

View file

@ -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 );

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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, &region);
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);
}

View file

@ -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;

View file

@ -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();

View file

@ -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, &region);
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;

View file

@ -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;