diff --git a/dlls/gdiplus/tests/graphicspath.c b/dlls/gdiplus/tests/graphicspath.c index 8dd9adf0a5d..f7cfedbde86 100644 --- a/dlls/gdiplus/tests/graphicspath.c +++ b/dlls/gdiplus/tests/graphicspath.c @@ -21,8 +21,116 @@ #include "windows.h" #include "gdiplus.h" #include "wine/test.h" +#include "math.h" #define expect(expected, got) ok(got == expected, "Expected %.8x, got %.8x\n", expected, got) +#define POINT_TYPE_MAX_LEN (75) + +static void stringify_point_type(PathPointType type, char * name) +{ + *name = '\0'; + + switch(type & PathPointTypePathTypeMask){ + case PathPointTypeStart: + strcat(name, "PathPointTypeStart"); + break; + case PathPointTypeLine: + strcat(name, "PathPointTypeLine"); + break; + case PathPointTypeBezier: + strcat(name, "PathPointTypeBezier"); + break; + default: + strcat(name, "Unknown type"); + return; + } + + type &= ~PathPointTypePathTypeMask; + if(type & ~((PathPointTypePathMarker | PathPointTypeCloseSubpath))){ + *name = '\0'; + strcat(name, "Unknown type"); + return; + } + + if(type & PathPointTypePathMarker) + strcat(name, " | PathPointTypePathMarker"); + if(type & PathPointTypeCloseSubpath) + strcat(name, " | PathPointTypeCloseSubpath"); +} + +/* this helper structure and function modeled after gdi path.c test */ +typedef struct +{ + REAL X, Y; + BYTE type; + + /* How many extra entries before this one only on wine + * but not on native? */ + int wine_only_entries_preceding; + + /* 0 - This entry matches on wine. + * 1 - This entry corresponds to a single entry on wine that does not match the native entry. + * 2 - This entry is currently skipped on wine but present on native. */ + int todo; +} path_test_t; + +static void ok_path(GpPath* path, const path_test_t *expected, INT expected_size, BOOL todo_size) +{ + BYTE * types; + INT size, idx = 0, eidx = 0, numskip; + GpPointF * points; + char ename[POINT_TYPE_MAX_LEN], name[POINT_TYPE_MAX_LEN]; + + if(GdipGetPointCount(path, &size) != Ok){ + skip("Cannot perform path comparisons due to failure to retrieve path.\n"); + return; + } + + if(todo_size) todo_wine + ok(size == expected_size, "Path size %d does not match expected size %d\n", + size, expected_size); + else + ok(size == expected_size, "Path size %d does not match expected size %d\n", + size, expected_size); + + points = HeapAlloc(GetProcessHeap(), 0, size * sizeof(GpPointF)); + types = HeapAlloc(GetProcessHeap(), 0, size); + + if(GdipGetPathPoints(path, points, size) != Ok || GdipGetPathTypes(path, types, size) != Ok){ + skip("Cannot perform path comparisons due to failure to retrieve path.\n"); + goto end; + } + + numskip = expected_size ? expected[eidx].wine_only_entries_preceding : 0; + while (idx < size && eidx < expected_size){ + /* We allow a few pixels fudge in matching X and Y coordinates to account for imprecision in + * floating point to integer conversion */ + BOOL match = (types[idx] == expected[eidx].type) && + fabs(points[idx].X - expected[eidx].X) <= 2.0 && + fabs(points[idx].Y - expected[eidx].Y) <= 2.0; + + stringify_point_type(expected[eidx].type, ename); + stringify_point_type(types[idx], name); + + if (expected[eidx].todo || numskip) todo_wine + ok(match, "Expected #%d: %s (%.1f,%.1f) but got %s (%.1f,%.1f)\n", eidx, + ename, expected[eidx].X, expected[eidx].Y, + name, points[idx].X, points[idx].Y); + else + ok(match, "Expected #%d: %s (%.1f,%.1f) but got %s (%.1f,%.1f)\n", eidx, + ename, expected[eidx].X, expected[eidx].Y, + name, points[idx].X, points[idx].Y); + + if (match || expected[eidx].todo != 2) + idx++; + if (match || !numskip--) + numskip = expected[++eidx].wine_only_entries_preceding; + } + +end: + HeapFree(GetProcessHeap(), 0, types); + HeapFree(GetProcessHeap(), 0, points); +} static void test_constructor_destructor(void) { @@ -40,6 +148,43 @@ static void test_constructor_destructor(void) expect(Ok, status); } +static path_test_t line2_path[] = { + {0.0, 50.0, PathPointTypeStart, 0, 0}, /*0*/ + {5.0, 45.0, PathPointTypeLine, 0, 0}, /*1*/ + {0.0, 40.0, PathPointTypeLine, 0, 0}, /*2*/ + {15.0, 35.0, PathPointTypeLine, 0, 0}, /*3*/ + {0.0, 30.0, PathPointTypeLine, 0, 0}, /*4*/ + {25.0, 25.0, PathPointTypeLine | PathPointTypeCloseSubpath, 0, 0}, /*5*/ + {0.0, 20.0, PathPointTypeStart, 0, 0}, /*6*/ + {35.0, 15.0, PathPointTypeLine, 0, 0}, /*7*/ + {0.0, 10.0, PathPointTypeLine, 0, 0} /*8*/ + }; + +static void test_line2(void) +{ + GpStatus status; + GpPath* path; + int i; + GpPointF line2_points[9]; + + for(i = 0; i < 9; i ++){ + line2_points[i].X = i * 5.0 * (REAL)(i % 2); + line2_points[i].Y = 50.0 - i * 5.0; + } + + GdipCreatePath(FillModeAlternate, &path); + status = GdipAddPathLine2(path, line2_points, 3); + expect(Ok, status); + status = GdipAddPathLine2(path, &(line2_points[3]), 3); + expect(Ok, status); + status = GdipClosePathFigure(path); + expect(Ok, status); + status = GdipAddPathLine2(path, &(line2_points[6]), 3); + expect(Ok, status); + + ok_path(path, line2_path, sizeof(line2_path)/sizeof(path_test_t), FALSE); +} + START_TEST(graphicspath) { struct GdiplusStartupInput gdiplusStartupInput; @@ -53,6 +198,7 @@ START_TEST(graphicspath) GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); test_constructor_destructor(); + test_line2(); GdiplusShutdown(gdiplusToken); }