[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, &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);
 }
-- 
1.5.6.5






More information about the wine-patches mailing list