From 889bc31197e3a4c4ea9da7ae0c311ac7f317fc6b Mon Sep 17 00:00:00 2001 From: Adam Petaccia Date: Thu, 24 Jul 2008 19:01:21 -0400 Subject: [PATCH] gdiplus: Implement GdipCreateRegion and mark the tests todo_wine instead of skipping over them all. --- dlls/gdiplus/gdiplus_private.h | 38 ++++++++++++++++++++++++ dlls/gdiplus/region.c | 60 ++++++++++++++++++++++++++++++++++++-- dlls/gdiplus/tests/region.c | 66 ++++++++++++++++++++++++++---------------- 3 files changed, 136 insertions(+), 28 deletions(-) diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h index 1b806cdd69c..620f82269bc 100644 --- a/dlls/gdiplus/gdiplus_private.h +++ b/dlls/gdiplus/gdiplus_private.h @@ -37,6 +37,8 @@ #define MAX_DASHLEN (16) /* this is a limitation of gdi */ #define INCH_HIMETRIC (2540) +#define VERSION_MAGIC 0xdbc01001 + COLORREF ARGB2COLORREF(ARGB color); extern INT arc2polybezier(GpPointF * points, REAL x1, REAL y1, REAL x2, REAL y2, REAL startAngle, REAL sweepAngle); @@ -199,4 +201,40 @@ struct GpFontFamily{ WCHAR FamilyName[LF_FACESIZE]; }; +typedef struct region_element +{ + DWORD type; /* Rectangle, Path, SpecialRectangle, or CombineMode */ + union + { + GpRectF rect; + struct + { + GpPath* path; + struct + { + DWORD size; + DWORD magic; + DWORD count; + DWORD flags; + } pathheader; + } pathdata; + struct + { + struct region_element *left; /* the original region */ + struct region_element *right; /* what *left was combined with */ + } combine; + } elementdata; +} region_element; + +struct GpRegion{ + struct + { + DWORD size; + DWORD checksum; + DWORD magic; + DWORD num_children; + } header; + region_element node; +}; + #endif diff --git a/dlls/gdiplus/region.c b/dlls/gdiplus/region.c index fc53c86b212..d2997f478d9 100644 --- a/dlls/gdiplus/region.c +++ b/dlls/gdiplus/region.c @@ -73,6 +73,54 @@ WINE_DEFAULT_DEBUG_CHANNEL(gdiplus); * */ +typedef enum RegionType +{ + RegionDataRect = 0x10000000, + RegionDataPath = 0x10000001, + RegionDataEmptyRect = 0x10000002, + RegionDataInfiniteRect = 0x10000003, +} RegionType; + +/* Header size as far as header->size is concerned. This doesn't include + * header->size or header->checksum + */ +static const INT sizeheader_size = sizeof(DWORD) * 2; + +static inline INT get_element_size(const region_element* element) +{ + INT needed = sizeof(DWORD); /* DWORD for the type */ + switch(element->type) + { + case RegionDataRect: + return needed + sizeof(GpRect); + case RegionDataPath: + needed += element->elementdata.pathdata.pathheader.size; + needed += sizeof(DWORD); /* Extra DWORD for pathheader.size */ + return needed; + case RegionDataEmptyRect: + case RegionDataInfiniteRect: + return needed; + default: + needed += get_element_size(element->elementdata.combine.left); + needed += get_element_size(element->elementdata.combine.right); + return needed; + } + + return 0; +} + +/* Does not check parameters, caller must do that */ +static inline GpStatus init_region(GpRegion* region, const RegionType type) +{ + region->node.type = type; + region->header.checksum = 0xdeadbeef; + region->header.magic = VERSION_MAGIC; + region->header.num_children = 0; + region->header.size = sizeheader_size + get_element_size(®ion->node); + + return Ok; +} + GpStatus WINGDIPAPI GdipCloneRegion(GpRegion *region, GpRegion **clone) { FIXME("(%p %p): stub\n", region, clone); @@ -110,10 +158,16 @@ GpStatus WINGDIPAPI GdipCombineRegionRegion(GpRegion *region1, GpRegion *region2 GpStatus WINGDIPAPI GdipCreateRegion(GpRegion **region) { - FIXME("(%p): stub\n", region); + if(!region) + return InvalidParameter; - *region = NULL; - return NotImplemented; + TRACE("%p\n", region); + + *region = GdipAlloc(sizeof(GpRegion)); + if(!*region) + return OutOfMemory; + + return init_region(*region, RegionDataInfiniteRect); } GpStatus WINGDIPAPI GdipCreateRegionPath(GpPath *path, GpRegion **region) diff --git a/dlls/gdiplus/tests/region.c b/dlls/gdiplus/tests/region.c index 6b1c5f04ee2..e3ed8ec1416 100644 --- a/dlls/gdiplus/tests/region.c +++ b/dlls/gdiplus/tests/region.c @@ -62,18 +62,19 @@ static void test_getregiondata(void) GpRect rect; GpPath *path; + memset(buf, 0xee, sizeof(buf)); + status = GdipCreateRegion(®ion); -todo_wine ok(status == Ok, "status %08x\n", status); - if(status != Ok) return; - +todo_wine +{ status = GdipGetRegionDataSize(region, &needed); ok(status == Ok, "status %08x\n", status); - ok(needed == 20, "got %d\n", needed); + expect(20, needed); status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed); ok(status == Ok, "status %08x\n", status); - ok(needed == 20, "got %d\n", needed); + expect(20, needed); expect_dword(buf, 12); trace("buf[1] = %08x\n", buf[1]); expect_magic((DWORD*)(buf + 2)); @@ -84,10 +85,10 @@ todo_wine ok(status == Ok, "status %08x\n", status); status = GdipGetRegionDataSize(region, &needed); ok(status == Ok, "status %08x\n", status); - ok(needed == 20, "got %d\n", needed); + expect(20, needed); status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed); ok(status == Ok, "status %08x\n", status); - ok(needed == 20, "got %d\n", needed); + expect(20, needed); expect_dword(buf, 12); trace("buf[1] = %08x\n", buf[1]); expect_magic((DWORD*)(buf + 2)); @@ -98,10 +99,10 @@ todo_wine ok(status == Ok, "status %08x\n", status); status = GdipGetRegionDataSize(region, &needed); ok(status == Ok, "status %08x\n", status); - ok(needed == 20, "got %d\n", needed); + expect(20, needed); status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed); ok(status == Ok, "status %08x\n", status); - ok(needed == 20, "got %d\n", needed); + expect(20, needed); expect_dword(buf, 12); trace("buf[1] = %08x\n", buf[1]); expect_magic((DWORD*)(buf + 2)); @@ -119,10 +120,10 @@ todo_wine ok(status == Ok, "status %08x\n", status); status = GdipGetRegionDataSize(region, &needed); ok(status == Ok, "status %08x\n", status); - ok(needed == 36, "got %d\n", needed); + expect(36, needed); status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed); ok(status == Ok, "status %08x\n", status); - ok(needed == 36, "got %d\n", needed); + expect(36, needed); expect_dword(buf, 28); trace("buf[1] = %08x\n", buf[1]); expect_magic((DWORD*)(buf + 2)); @@ -171,10 +172,10 @@ todo_wine status = GdipGetRegionDataSize(region, &needed); ok(status == Ok, "status %08x\n", status); - ok(needed == 156, "got %d\n", needed); + expect(156, needed); status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed); ok(status == Ok, "status %08x\n", status); - ok(needed == 156, "got %d\n", needed); + expect(156, needed); expect_dword(buf, 148); trace("buf[1] = %08x\n", buf[1]); expect_magic((DWORD*)(buf + 2)); @@ -220,21 +221,24 @@ todo_wine ok(status == Ok, "status %08x\n", status); status = GdipDeleteRegion(region); ok(status == Ok, "status %08x\n", status); +} /* Try some paths */ status = GdipCreatePath(FillModeAlternate, &path); ok(status == Ok, "status %08x\n", status); +todo_wine +{ 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); + expect(72, needed); status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed); ok(status == Ok, "status %08x\n", status); - ok(needed == 72, "got %d\n", needed); + expect(72, needed); expect_dword(buf, 64); trace("buf[1] = %08x\n", buf[1]); expect_magic((DWORD*)(buf + 2)); @@ -263,10 +267,10 @@ todo_wine 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); + expect(96, needed); status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed); ok(status == Ok, "status %08x\n", status); - ok(needed == 96, "got %d\n", needed); + expect(96, needed); expect_dword(buf, 88); trace("buf[1] = %08x\n", buf[1]); expect_magic((DWORD*)(buf + 2)); @@ -294,20 +298,23 @@ todo_wine status = GdipDeleteRegion(region); ok(status == Ok, "status %08x\n", status); +} status = GdipDeletePath(path); ok(status == Ok, "status %08x\n", status); /* Test an empty path */ status = GdipCreatePath(FillModeAlternate, &path); expect(Ok, status); +todo_wine +{ status = GdipCreateRegionPath(path, ®ion); expect(Ok, status); status = GdipGetRegionDataSize(region, &needed); expect(Ok, status); - ok(needed == 36, "got %d\n", needed); + expect(36, needed); status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed); expect(Ok, status); - ok(needed == 36, "got %d\n", needed); + expect(36, needed); expect_dword(buf, 28); trace("buf[1] = %08x\n", buf[1]); expect_magic((DWORD*)(buf + 2)); @@ -322,23 +329,25 @@ todo_wine status = GdipDeleteRegion(region); expect(Ok, status); +} /* Test a simple triangle of INTs */ status = GdipAddPathLine(path, 5, 6, 7, 8); expect(Ok, status); - status = GdipAddPathLine(path, 7, 8, 8, 1); - expect(Ok, status); status = GdipAddPathLine(path, 8, 1, 5, 6); expect(Ok, status); status = GdipClosePathFigure(path); expect(Ok, status); +todo_wine +{ status = GdipCreateRegionPath(path, ®ion); expect(Ok, status); status = GdipGetRegionDataSize(region, &needed); expect(Ok, status); - ok(needed == 56, "Expected 56, got %d\n", needed); + expect(56, needed); status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed); expect(Ok, status); + expect(56, needed); expect_dword(buf, 48); trace("buf[1] = %08x\n", buf[1]); expect_magic((DWORD*)(buf + 2)); @@ -360,9 +369,11 @@ todo_wine expect(5, point[3].X); /* buf + 12 */ expect(6, point[3].Y); expect_dword(buf + 13, 0x81010100); /* 0x01010100 if we don't close the path */ +} status = GdipDeletePath(path); expect(Ok, status); status = GdipDeleteRegion(region); +todo_wine expect(Ok, status); /* Test a floating-point triangle */ @@ -370,17 +381,18 @@ todo_wine expect(Ok, status); status = GdipAddPathLine(path, 5.6, 6.2, 7.2, 8.9); expect(Ok, status); - status = GdipAddPathLine(path, 7.2, 8.9, 8.1, 1.6); - expect(Ok, status); status = GdipAddPathLine(path, 8.1, 1.6, 5.6, 6.2); expect(Ok, status); +todo_wine +{ status = GdipCreateRegionPath(path, ®ion); expect(Ok, status); status = GdipGetRegionDataSize(region, &needed); expect(Ok, status); - ok(needed == 72, "Expected 72, got %d\n", needed); + expect(72, needed); status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed); expect(Ok, status); + expect(72, needed); expect_dword(buf, 64); trace("buf[1] = %08x\n", buf[1]); expect_magic((DWORD*)(buf + 2)); @@ -399,8 +411,12 @@ todo_wine expect_float(buf + 14, 1.6); expect_float(buf + 15, 5.6); expect_float(buf + 16, 6.2); +} + status = GdipDeletePath(path); + expect(Ok, status); status = GdipDeleteRegion(region); +todo_wine expect(Ok, status); } -- 2.11.4.GIT