[try 5][Gdiplus 1/6] Implement GdipCreateRegion and mark the tests todo_wine instead of skipping over them all.
Adam Petaccia
adam at tpetaccia.com
Thu Jul 24 18:01:21 CDT 2008
This patch also addresses some Valgrind warnings that will pop up once
everything is implemented. Also, be more descriptive when we fail some tests
by using the expect() macro.
Changelog:
(try5):
tests: Don't set buffer to 0, but 0xee.
(try4):
Merge with what was previous patch (test todo'ing)
Make region directly hold its node
Use lowercase struct names and members.
Move InitRegion to the top, and rename to init_region
Move enumeration to region.c, as its not public.
pathHeader->{pointCount,storageFlags} --> pathheader->{count, flags}
numOps --> num_children
Add const qualifier
(try3):
Fix a mistake which caused SetEmpty to be incorrectly filled out.
Remove a comment that should be added later.
---
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 1b806cd..620f822 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 fc53c86..d2997f4 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 6b1c5f0..e3ed8ec 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);
}
--
1.5.4.3
More information about the wine-patches
mailing list