[try7][Gdiplus 02/10] Implement GdipCreateRegionPath
Adam Petaccia
adam at tpetaccia.com
Mon Aug 4 12:56:33 CDT 2008
Changelog:
(try5):
Add some documentation
(try4):
region->node is no longer a pointer
Update to new naming scheme
(try3):
Plug some leaks that occurred on error.
---
dlls/gdiplus/region.c | 116 +++++++++++++++++++++++++++++++++++++++++-
dlls/gdiplus/tests/region.c | 33 +++----------
2 files changed, 120 insertions(+), 29 deletions(-)
diff --git a/dlls/gdiplus/region.c b/dlls/gdiplus/region.c
index fd4c7ba..48a9d00 100644
--- a/dlls/gdiplus/region.c
+++ b/dlls/gdiplus/region.c
@@ -214,12 +214,122 @@ GpStatus WINGDIPAPI GdipCreateRegion(GpRegion **region)
return init_region(*region, RegionDataInfiniteRect);
}
+/*****************************************************************************
+ * GdipCreateRegionPath [GDIPLUS.@]
+ *
+ * Creates a GpRegion from a GpPath
+ *
+ * PARAMS
+ * path [I] path to base the region on
+ * region [O] pointer to the newly allocated region
+ *
+ * RETURNS
+ * SUCCESS: Ok
+ * FAILURE: InvalidParameter
+ *
+ * NOTES
+ * If a path has no floating point points, its points will be stored as shorts
+ * (INTPATH)
+ *
+ * If a path is empty, it is considered to be an INTPATH
+ */
GpStatus WINGDIPAPI GdipCreateRegionPath(GpPath *path, GpRegion **region)
{
- FIXME("(%p, %p): stub\n", path, region);
+ region_element* element;
+ GpPoint *pointsi;
+ GpPointF *pointsf;
- *region = NULL;
- return NotImplemented;
+ GpStatus stat;
+ DWORD flags = FLAGS_INTPATH;
+ INT count, i;
+
+ TRACE("%p, %p\n", path, region);
+
+ if (!(path && region))
+ return InvalidParameter;
+
+ *region = GdipAlloc(sizeof(GpRegion));
+ if(!*region)
+ return OutOfMemory;
+ stat = init_region(*region, RegionDataPath);
+ if (stat != Ok)
+ {
+ GdipDeleteRegion(*region);
+ return stat;
+ }
+ element = &(*region)->node;
+ count = path->pathdata.Count;
+
+ /* Test to see if the path is an Integer path */
+ if (count)
+ {
+ pointsi = GdipAlloc(sizeof(GpPoint) * count);
+ pointsf = GdipAlloc(sizeof(GpPointF) * count);
+ if (!(pointsi && pointsf))
+ {
+ GdipFree(pointsi);
+ GdipFree(pointsf);
+ GdipDeleteRegion(*region);
+ return OutOfMemory;
+ }
+
+ stat = GdipGetPathPointsI(path, pointsi, count);
+ if (stat != Ok)
+ {
+ GdipDeleteRegion(*region);
+ return stat;
+ }
+ stat = GdipGetPathPoints(path, pointsf, count);
+ if (stat != Ok)
+ {
+ GdipDeleteRegion(*region);
+ return stat;
+ }
+
+ for (i = 0; i < count; i++)
+ {
+ if (!(pointsi[i].X == pointsf[i].X &&
+ pointsi[i].Y == pointsf[i].Y ))
+ {
+ flags = FLAGS_NOFLAGS;
+ break;
+ }
+ }
+ GdipFree(pointsi);
+ GdipFree(pointsf);
+ }
+
+ stat = GdipClonePath(path, &element->elementdata.pathdata.path);
+ if (stat != Ok)
+ {
+ GdipDeleteRegion(*region);
+ return stat;
+ }
+
+ /* 3 for headers, once again size doesn't count itself */
+ element->elementdata.pathdata.pathheader.size = ((sizeof(DWORD) * 3));
+ switch(flags)
+ {
+ /* Floats, sent out as floats */
+ case FLAGS_NOFLAGS:
+ element->elementdata.pathdata.pathheader.size +=
+ (sizeof(DWORD) * count * 2);
+ break;
+ /* INTs, sent out as packed shorts */
+ case FLAGS_INTPATH:
+ element->elementdata.pathdata.pathheader.size +=
+ (sizeof(DWORD) * count);
+ break;
+ default:
+ FIXME("Unhandled flags (%08x). Expect wrong results.\n", flags);
+ }
+ element->elementdata.pathdata.pathheader.size += get_pathtypes_size(path);
+ element->elementdata.pathdata.pathheader.magic = VERSION_MAGIC;
+ element->elementdata.pathdata.pathheader.count = count;
+ element->elementdata.pathdata.pathheader.flags = flags;
+ (*region)->header.size = sizeheader_size + get_element_size(element);
+
+ return Ok;
}
GpStatus WINGDIPAPI GdipCreateRegionRect(GDIPCONST GpRectF *rect, GpRegion **region)
diff --git a/dlls/gdiplus/tests/region.c b/dlls/gdiplus/tests/region.c
index 01991a2..17a4ba4 100644
--- a/dlls/gdiplus/tests/region.c
+++ b/dlls/gdiplus/tests/region.c
@@ -172,6 +172,7 @@ todo_wine
rect.Width = 22;
rect.Height = 55;
status = GdipCombineRegionRectI(region, &rect, CombineModeExclude);
+todo_wine
ok(status == Ok, "status %08x\n", status);
status = GdipGetRegionDataSize(region, &needed);
@@ -233,8 +234,6 @@ todo_wine
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);
@@ -247,11 +246,8 @@ todo_wine
expect(72, needed);
expect_dword(buf, 64);
trace("buf[1] = %08x\n", buf[1]);
-}
expect_magic((DWORD*)(buf + 2));
expect_dword(buf + 3, 0);
-todo_wine
-{
expect_dword(buf + 4, RGNDATA_PATH);
expect_dword(buf + 5, 0x00000030);
expect_magic((DWORD*)(buf + 6));
@@ -273,12 +269,16 @@ todo_wine
rect.Width = 10;
rect.Height = 20;
status = GdipCombineRegionRectI(region, &rect, CombineModeIntersect);
+todo_wine
ok(status == Ok, "status %08x\n", status);
status = GdipGetRegionDataSize(region, &needed);
ok(status == Ok, "status %08x\n", status);
+todo_wine
expect(96, needed);
status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed);
ok(status == Ok, "status %08x\n", status);
+todo_wine
+{
expect(96, needed);
expect_dword(buf, 88);
trace("buf[1] = %08x\n", buf[1]);
@@ -307,18 +307,16 @@ todo_wine
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);
/* Test an empty path */
status = GdipCreatePath(FillModeAlternate, &path);
expect(Ok, status);
-todo_wine
-{
status = GdipCreateRegionPath(path, ®ion);
expect(Ok, status);
status = GdipGetRegionDataSize(region, &needed);
@@ -329,11 +327,8 @@ todo_wine
expect(36, needed);
expect_dword(buf, 28);
trace("buf[1] = %08x\n", buf[1]);
-}
expect_magic((DWORD*)(buf + 2));
expect_dword(buf + 3, 0);
-todo_wine
-{
expect_dword(buf + 4, RGNDATA_PATH);
/* Second signature for pathdata */
@@ -344,7 +339,6 @@ todo_wine
status = GdipDeleteRegion(region);
expect(Ok, status);
-}
/* Test a simple triangle of INTs */
status = GdipAddPathLine(path, 5, 6, 7, 8);
@@ -353,8 +347,6 @@ todo_wine
expect(Ok, status);
status = GdipClosePathFigure(path);
expect(Ok, status);
-todo_wine
-{
status = GdipCreateRegionPath(path, ®ion);
expect(Ok, status);
status = GdipGetRegionDataSize(region, &needed);
@@ -364,12 +356,9 @@ todo_wine
expect(Ok, status);
expect(56, needed);
expect_dword(buf, 48);
-}
trace("buf[1] = %08x\n", buf[1]);
expect_magic((DWORD*)(buf + 2));
expect_dword(buf + 3 , 0);
-todo_wine
-{
expect_dword(buf + 4 , RGNDATA_PATH);
expect_dword(buf + 5, 32);
@@ -387,11 +376,10 @@ 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 */
@@ -402,8 +390,6 @@ todo_wine
status = GdipAddPathLine(path, 8.1, 1.6, 5.6, 6.2);
expect(Ok, status);
status = GdipCreateRegionPath(path, ®ion);
-todo_wine
-{
expect(Ok, status);
status = GdipGetRegionDataSize(region, &needed);
expect(Ok, status);
@@ -413,11 +399,8 @@ todo_wine
expect(72, needed);
expect_dword(buf, 64);
trace("buf[1] = %08x\n", buf[1]);
-}
expect_magic((DWORD*)(buf + 2));
expect_dword(buf + 3, 0);
-todo_wine
-{
expect_dword(buf + 4, RGNDATA_PATH);
expect_dword(buf + 5, 48);
@@ -432,12 +415,10 @@ 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