Vincent Povirk : gdiplus: Implement GdipGetRegionScansCount.

Alexandre Julliard julliard at winehq.org
Fri Oct 1 11:38:44 CDT 2010


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

Author: Vincent Povirk <vincent at codeweavers.com>
Date:   Thu Sep 30 14:59:04 2010 -0500

gdiplus: Implement GdipGetRegionScansCount.

---

 dlls/gdiplus/region.c       |   76 ++++++++++++++++++++++++++++++++++++++++--
 dlls/gdiplus/tests/region.c |   64 ++++++++++++++++++++++++++++++++++++
 include/gdiplusflat.h       |    1 +
 3 files changed, 137 insertions(+), 4 deletions(-)

diff --git a/dlls/gdiplus/region.c b/dlls/gdiplus/region.c
index 9b8ed18..2e895a8 100644
--- a/dlls/gdiplus/region.c
+++ b/dlls/gdiplus/region.c
@@ -1362,14 +1362,82 @@ GpStatus WINGDIPAPI GdipTranslateRegionI(GpRegion *region, INT dx, INT dy)
     return GdipTranslateRegion(region, (REAL)dx, (REAL)dy);
 }
 
+static GpStatus get_region_scans_data(GpRegion *region, GpMatrix *matrix, LPRGNDATA *data)
+{
+    GpRegion *region_copy;
+    GpStatus stat;
+    HRGN hrgn;
+    DWORD data_size;
+
+    stat = GdipCloneRegion(region, &region_copy);
+
+    if (stat == Ok)
+    {
+        stat = GdipTransformRegion(region_copy, matrix);
+
+        if (stat == Ok)
+            stat = GdipGetRegionHRgn(region_copy, NULL, &hrgn);
+
+        if (stat == Ok)
+        {
+            if (hrgn)
+            {
+                data_size = GetRegionData(hrgn, 0, NULL);
+
+                *data = GdipAlloc(data_size);
+
+                if (*data)
+                    GetRegionData(hrgn, data_size, *data);
+                else
+                    stat = OutOfMemory;
+
+                DeleteObject(hrgn);
+            }
+            else
+            {
+                data_size = sizeof(RGNDATAHEADER) + sizeof(RECT);
+
+                *data = GdipAlloc(data_size);
+
+                if (*data)
+                {
+                    (*data)->rdh.dwSize = sizeof(RGNDATAHEADER);
+                    (*data)->rdh.iType = RDH_RECTANGLES;
+                    (*data)->rdh.nCount = 1;
+                    (*data)->rdh.nRgnSize = sizeof(RECT);
+                    (*data)->rdh.rcBound.left = (*data)->rdh.rcBound.top = -0x400000;
+                    (*data)->rdh.rcBound.right = (*data)->rdh.rcBound.bottom = 0x400000;
+
+                    memcpy(&(*data)->Buffer, &(*data)->rdh.rcBound, sizeof(RECT));
+                }
+                else
+                    stat = OutOfMemory;
+            }
+        }
+
+        GdipDeleteRegion(region_copy);
+    }
+
+    return stat;
+}
+
 GpStatus WINGDIPAPI GdipGetRegionScansCount(GpRegion *region, UINT *count, GpMatrix *matrix)
 {
-    static int calls;
+    GpStatus stat;
+    LPRGNDATA data;
 
     TRACE("(%p, %p, %p)\n", region, count, matrix);
 
-    if (!(calls++))
-        FIXME("not implemented\n");
+    if (!region || !count || !matrix)
+        return InvalidParameter;
 
-    return NotImplemented;
+    stat = get_region_scans_data(region, matrix, &data);
+
+    if (stat == Ok)
+    {
+        *count = data->rdh.nCount;
+        GdipFree(data);
+    }
+
+    return stat;
 }
diff --git a/dlls/gdiplus/tests/region.c b/dlls/gdiplus/tests/region.c
index 96ac40e..9d48b25 100644
--- a/dlls/gdiplus/tests/region.c
+++ b/dlls/gdiplus/tests/region.c
@@ -1230,6 +1230,69 @@ static void test_transform(void)
     ReleaseDC(0, hdc);
 }
 
+static void test_scans(void)
+{
+    GpRegion *region;
+    GpMatrix *matrix;
+    GpRectF rectf;
+    GpStatus status;
+    ULONG count=80085;
+
+    status = GdipCreateRegion(&region);
+    expect(Ok, status);
+
+    status = GdipCreateMatrix(&matrix);
+    expect(Ok, status);
+
+    /* test NULL values */
+    status = GdipGetRegionScansCount(NULL, &count, matrix);
+    expect(InvalidParameter, status);
+
+    status = GdipGetRegionScansCount(region, NULL, matrix);
+    expect(InvalidParameter, status);
+
+    status = GdipGetRegionScansCount(region, &count, NULL);
+    expect(InvalidParameter, status);
+
+    /* infinite */
+    status = GdipGetRegionScansCount(region, &count, matrix);
+    expect(Ok, status);
+    expect(1, count);
+
+    /* empty */
+    status = GdipSetEmpty(region);
+    expect(Ok, status);
+
+    status = GdipGetRegionScansCount(region, &count, matrix);
+    expect(Ok, status);
+    expect(0, count);
+
+    /* single rectangle */
+    rectf.X = rectf.Y = 0.0;
+    rectf.Width = rectf.Height = 5.0;
+    status = GdipCombineRegionRect(region, &rectf, CombineModeReplace);
+    expect(Ok, status);
+
+    status = GdipGetRegionScansCount(region, &count, matrix);
+    expect(Ok, status);
+    expect(1, count);
+
+    /* two rectangles */
+    rectf.X = rectf.Y = 5.0;
+    rectf.Width = rectf.Height = 5.0;
+    status = GdipCombineRegionRect(region, &rectf, CombineModeUnion);
+    expect(Ok, status);
+
+    status = GdipGetRegionScansCount(region, &count, matrix);
+    expect(Ok, status);
+    expect(2, count);
+
+    status = GdipDeleteRegion(region);
+    expect(Ok, status);
+    status = GdipDeleteMatrix(matrix);
+    expect(Ok, status);
+}
+
 static void test_getbounds(void)
 {
     GpRegion *region;
@@ -1742,6 +1805,7 @@ START_TEST(region)
     test_isequal();
     test_translate();
     test_transform();
+    test_scans();
     test_getbounds();
     test_isvisiblepoint();
     test_isvisiblerect();
diff --git a/include/gdiplusflat.h b/include/gdiplusflat.h
index c361d10..76549e7 100644
--- a/include/gdiplusflat.h
+++ b/include/gdiplusflat.h
@@ -643,6 +643,7 @@ GpStatus WINGDIPAPI GdipGetRegionBoundsI(GpRegion *, GpGraphics *, GpRect *);
 GpStatus WINGDIPAPI GdipGetRegionData(GpRegion *, BYTE *, UINT, UINT *);
 GpStatus WINGDIPAPI GdipGetRegionDataSize(GpRegion *, UINT *);
 GpStatus WINGDIPAPI GdipGetRegionHRgn(GpRegion *, GpGraphics *, HRGN *);
+GpStatus WINGDIPAPI GdipGetRegionScansCount(GpRegion *, UINT *, GpMatrix *);
 GpStatus WINGDIPAPI GdipIsEmptyRegion(GpRegion *, GpGraphics *, BOOL *);
 GpStatus WINGDIPAPI GdipIsEqualRegion(GpRegion *, GpRegion *, GpGraphics *, BOOL *);
 GpStatus WINGDIPAPI GdipIsInfiniteRegion(GpRegion *, GpGraphics *, BOOL *);




More information about the wine-cvs mailing list