diff --git a/dlls/gdiplus/region.c b/dlls/gdiplus/region.c index 3d95723b529..fc53c86b212 100644 --- a/dlls/gdiplus/region.c +++ b/dlls/gdiplus/region.c @@ -32,8 +32,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(gdiplus); /********************************************************** * - * Data returned by GdipGetRegionData (for rectangle based regions) - * looks something like this: + * Data returned by GdipGetRegionData looks something like this: * * struct region_data_header * { @@ -43,7 +42,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(gdiplus); * DWORD num_ops; number of combining ops * 2 * }; * - * Then follows a sequence of combining ops and RECTFs. + * Then follows a sequence of combining ops and region elements. + * + * A region element is either a RECTF or some path data. * * Combining ops are just stored as their CombineMode value. * @@ -51,19 +52,24 @@ WINE_DEFAULT_DEBUG_CHANNEL(gdiplus); * stored as 0x10000002 (with no following RECTF) and an infinite rect * is stored as 0x10000003 (again with no following RECTF). * - * The combining ops are stored in the reverse order to the RECTFs and in the - * reverse order to which the region was constructed. + * Path data is preceded by the DWORD 0x10000001. Then follows a + * DWORD size and then size bytes of data. * - * When two or more complex regions (ie those with more than one rect) - * are combined, the combining op for the two regions comes first, - * then the combining ops for the rects in region 1, followed by the - * rects for region 1, then follows the combining ops for region 2 and - * finally region 2's rects. Presumably you're supposed to use the - * 0x10000000 rect header to find the end of the op list (the count of - * the rects in each region is not stored). + * The combining ops are stored in the reverse order to the region + * elements and in the reverse order to which the region was + * constructed. * - * When a simple region (1 rect) is combined, it's treated as if a single rect - * is being combined. + * When two or more complex regions (ie those with more than one + * element) are combined, the combining op for the two regions comes + * first, then the combining ops for the region elements in region 1, + * followed by the region elements for region 1, then follows the + * combining ops for region 2 and finally region 2's region elements. + * Presumably you're supposed to use the 0x1000000x header to find the + * end of the op list (the count of the elements in each region is not + * stored). + * + * When a simple region (1 element) is combined, it's treated as if a + * single rect/path is being combined. * */ diff --git a/dlls/gdiplus/tests/region.c b/dlls/gdiplus/tests/region.c index 166df2d17d9..dfdba26444a 100644 --- a/dlls/gdiplus/tests/region.c +++ b/dlls/gdiplus/tests/region.c @@ -34,13 +34,14 @@ static inline void expect_float(DWORD *value, FLOAT expected) ok(valuef == expected, "expected %f got %f\n", expected, valuef); } -static void test_create_rgn(void) +static void test_getregiondata(void) { GpStatus status; GpRegion *region, *region2; UINT needed; DWORD buf[100]; GpRect rect; + GpPath *path; status = GdipCreateRegion(®ion); todo_wine @@ -201,6 +202,82 @@ todo_wine status = GdipDeleteRegion(region); ok(status == Ok, "status %08x\n", status); + /* Try some paths */ + + status = GdipCreatePath(FillModeAlternate, &path); + ok(status == Ok, "status %08x\n", status); + GdipAddPathRectangle(path, 12.5, 13.0, 14.0, 15.0); + + status = GdipCreateRegionPath(path, ®ion); + ok(status == Ok, "status %08x\n", status); + status = GdipGetRegionDataSize(region, &needed); + ok(status == Ok, "status %08x\n", status); + ok(needed == 72, "got %d\n", needed); + status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed); + ok(status == Ok, "status %08x\n", status); + ok(needed == 72, "got %d\n", needed); + expect_dword(buf, 64); + trace("buf[1] = %08x\n", buf[1]); + expect_dword(buf + 2, 0xdbc01001); + expect_dword(buf + 3, 0); + expect_dword(buf + 4, 0x10000001); + expect_dword(buf + 5, 0x00000030); + expect_dword(buf + 6, 0xdbc01001); + expect_dword(buf + 7, 0x00000004); + expect_dword(buf + 8, 0x00000000); + expect_float(buf + 9, 12.5); + expect_float(buf + 10, 13.0); + expect_float(buf + 11, 26.5); + expect_float(buf + 12, 13.0); + expect_float(buf + 13, 26.5); + expect_float(buf + 14, 28.0); + expect_float(buf + 15, 12.5); + expect_float(buf + 16, 28.0); + expect_dword(buf + 17, 0x81010100); + + + rect.X = 50; + rect.Y = 30; + rect.Width = 10; + rect.Height = 20; + status = GdipCombineRegionRectI(region, &rect, CombineModeIntersect); + ok(status == Ok, "status %08x\n", status); + status = GdipGetRegionDataSize(region, &needed); + ok(status == Ok, "status %08x\n", status); + ok(needed == 96, "got %d\n", needed); + status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed); + ok(status == Ok, "status %08x\n", status); + ok(needed == 96, "got %d\n", needed); + expect_dword(buf, 88); + trace("buf[1] = %08x\n", buf[1]); + expect_dword(buf + 2, 0xdbc01001); + expect_dword(buf + 3, 2); + expect_dword(buf + 4, CombineModeIntersect); + expect_dword(buf + 5, 0x10000001); + expect_dword(buf + 6, 0x00000030); + expect_dword(buf + 7, 0xdbc01001); + expect_dword(buf + 8, 0x00000004); + expect_dword(buf + 9, 0x00000000); + expect_float(buf + 10, 12.5); + expect_float(buf + 11, 13.0); + expect_float(buf + 12, 26.5); + expect_float(buf + 13, 13.0); + expect_float(buf + 14, 26.5); + expect_float(buf + 15, 28.0); + expect_float(buf + 16, 12.5); + expect_float(buf + 17, 28.0); + expect_dword(buf + 18, 0x81010100); + expect_dword(buf + 19, 0x10000000); + expect_float(buf + 20, 50.0); + expect_float(buf + 21, 30.0); + expect_float(buf + 22, 10.0); + expect_float(buf + 23, 20.0); + + status = GdipDeleteRegion(region); + ok(status == Ok, "status %08x\n", status); + status = GdipDeletePath(path); + ok(status == Ok, "status %08x\n", status); + } START_TEST(region) @@ -215,7 +292,7 @@ START_TEST(region) GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); - test_create_rgn(); + test_getregiondata(); GdiplusShutdown(gdiplusToken);