Nikolay Sivov : gdiplus: Implemented GdipCreateRegionHrgn for rectangular regions.

Alexandre Julliard julliard at winehq.org
Fri Jan 30 07:58:25 CST 2009


Module: wine
Branch: master
Commit: 67f9570332b20dcecd3d771e1f060eb6d50819ad
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=67f9570332b20dcecd3d771e1f060eb6d50819ad

Author: Nikolay Sivov <bunglehead at gmail.com>
Date:   Fri Jan 30 03:49:54 2009 +0300

gdiplus: 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, &region);
     expect(InvalidParameter, status);
     status = GdipCreateRegionHrgn((HRGN)0xdeadbeef, &region);
-    todo_wine expect(InvalidParameter, status);
+    expect(InvalidParameter, status);
+
+    /* empty rectangle */
+    hrgn = CreateRectRgn(0, 0, 0, 0);
+    status = GdipCreateRegionHrgn(hrgn, &region);
+    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, &region);
-    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);
 }




More information about the wine-cvs mailing list