[1/2] gdiplus: Implemented GdipCreateRegionHrgn for rectangular regions
Nikolay Sivov
bunglehead at gmail.com
Thu Jan 29 18:57:22 CST 2009
Changelog:
- Implemented GdipCreateRegionHrgn for rectangular regions with tests
>From f0aaf9c92c952bf443533b814a942ac30676664a Mon Sep 17 00:00:00 2001
From: Nikolay Sivov <bunglehead at gmail.com>
Date: Fri, 30 Jan 2009 03:49:54 +0300
Subject: Implemented GdipCreateRegionHrgn for rectangular regions
---
dlls/gdiplus/region.c | 51 +++++++++++++++++++++++++++++++++++++++---
dlls/gdiplus/tests/region.c | 49 +++++++++++++++++++++++++++++++----------
2 files changed, 84 insertions(+), 16 deletions(-)
diff --git a/dlls/gdiplus/region.c b/dlls/gdiplus/region.c
index 89b107f..e4cc7d8 100644
--- a/dlls/gdiplus/region.c
+++ b/dlls/gdiplus/region.c
@@ -567,15 +567,58 @@ GpStatus WINGDIPAPI GdipCreateRegionRgnData(GDIPCONST BYTE *data, INT size, GpRe
return NotImplemented;
}
+
+/******************************************************************************
+ * GdipCreateRegionHrgn [GDIPLUS.@]
+ */
GpStatus WINGDIPAPI GdipCreateRegionHrgn(HRGN hrgn, GpRegion **region)
{
- FIXME("(%p, %p): stub\n", hrgn, region);
+ union {
+ RGNDATA data;
+ char buf[sizeof(RGNDATAHEADER) + sizeof(RECT)];
+ } rdata;
+ DWORD size;
+ GpRectF rectf;
+ GpPath *path;
+ GpStatus stat;
+
+ TRACE("(%p, %p)\n", hrgn, region);
- if(!hrgn || !region)
+ if(!region || !(size = GetRegionData(hrgn, 0, NULL)))
return InvalidParameter;
- *region = NULL;
- return NotImplemented;
+ if(size > sizeof(RGNDATAHEADER) + sizeof(RECT)){
+ FIXME("Only simple rect regions supported.\n");
+ *region = NULL;
+ return NotImplemented;
+ }
+
+ if(!GetRegionData(hrgn, sizeof(rdata), &rdata.data))
+ return GenericError;
+
+ /* return empty region */
+ if(IsRectEmpty(&rdata.data.rdh.rcBound)){
+ stat = GdipCreateRegion(region);
+ if(stat == Ok)
+ GdipSetEmpty(*region);
+ return stat;
+ }
+
+ rectf.X = (REAL)rdata.data.rdh.rcBound.left;
+ rectf.Y = (REAL)rdata.data.rdh.rcBound.top;
+ rectf.Width = (REAL)rdata.data.rdh.rcBound.right - rectf.X;
+ rectf.Height = (REAL)rdata.data.rdh.rcBound.bottom - rectf.Y;
+
+ stat = GdipCreatePath(FillModeAlternate, &path);
+ if(stat != Ok)
+ return stat;
+
+ GdipAddPathRectangle(path, rectf.X, rectf.Y, rectf.Width, rectf.Height);
+
+ stat = GdipCreateRegionPath(path, region);
+ GdipDeletePath(path);
+
+ return stat;
}
GpStatus WINGDIPAPI GdipDeleteRegion(GpRegion *region)
diff --git a/dlls/gdiplus/tests/region.c b/dlls/gdiplus/tests/region.c
index 9ac0e9a..784b1b9 100644
--- a/dlls/gdiplus/tests/region.c
+++ b/dlls/gdiplus/tests/region.c
@@ -709,6 +709,9 @@ static void test_fromhrgn(void)
UINT needed;
DWORD buf[220];
RegionDataPoint *point;
+ GpGraphics *graphics = NULL;
+ HDC hdc;
+ BOOL res;
/* NULL */
status = GdipCreateRegionHrgn(NULL, NULL);
@@ -716,24 +719,42 @@ static void test_fromhrgn(void)
status = GdipCreateRegionHrgn(NULL, ®ion);
expect(InvalidParameter, status);
status = GdipCreateRegionHrgn((HRGN)0xdeadbeef, ®ion);
- todo_wine expect(InvalidParameter, status);
+ expect(InvalidParameter, status);
+
+ /* empty rectangle */
+ hrgn = CreateRectRgn(0, 0, 0, 0);
+ status = GdipCreateRegionHrgn(hrgn, ®ion);
+ expect(Ok, status);
+ if(status == Ok) {
+
+ hdc = GetDC(0);
+ status = GdipCreateFromHDC(hdc, &graphics);
+ expect(Ok, status);
+ res = FALSE;
+ status = GdipIsEmptyRegion(region, graphics, &res);
+ expect(Ok, status);
+ expect(TRUE, res);
+ GdipDeleteGraphics(graphics);
+ ReleaseDC(0, hdc);
+ GdipDeleteRegion(region);
+
+ }
+ DeleteObject(hrgn);
/* rectangle */
hrgn = CreateRectRgn(0, 0, 100, 10);
status = GdipCreateRegionHrgn(hrgn, ®ion);
- todo_wine expect(Ok, status);
+ expect(Ok, status);
status = GdipGetRegionDataSize(region, &needed);
-todo_wine{
expect(Ok, status);
expect(56, needed);
-}
status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed);
- todo_wine expect(Ok, status);
+ expect(Ok, status);
if(status == Ok){
-todo_wine{
+
expect(56, needed);
expect_dword(buf, 48);
expect_magic((DWORD*)(buf + 2));
@@ -742,25 +763,23 @@ todo_wine{
expect_dword(buf + 5, 0x00000020);
expect_magic((DWORD*)(buf + 6));
expect_dword(buf + 7, 0x00000004);
- expect_dword(buf + 8, 0x00006000); /* ?? */
-}
+ todo_wine expect_dword(buf + 8, 0x00006000); /* ?? */
+
point = (RegionDataPoint*)buf + 9;
expect(0, point[0].X);
expect(0, point[0].Y);
-todo_wine{
expect(100,point[1].X); /* buf + 10 */
expect(0, point[1].Y);
expect(100,point[2].X); /* buf + 11 */
expect(10, point[2].Y);
-}
+
expect(0, point[3].X); /* buf + 12 */
-todo_wine{
expect(10, point[3].Y);
expect_dword(buf + 13, 0x81010100); /* closed */
-}
+
}
GdipDeleteRegion(region);
@@ -777,6 +796,10 @@ todo_wine{
expect(216, needed);
}
status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed);
+ todo_wine expect(Ok, status);
+
+ if(status == Ok)
+ {
todo_wine{
expect(Ok, status);
expect(216, needed);
@@ -789,6 +812,8 @@ todo_wine{
expect_dword(buf + 7, 0x00000024);
expect_dword(buf + 8, 0x00006000); /* ?? */
}
+ }
+
GdipDeleteRegion(region);
DeleteObject(hrgn);
}
--
1.5.6.5
More information about the wine-patches
mailing list