From f1d5781eb78c23db3a4d3f0127d68a4abea9b198 Mon Sep 17 00:00:00 2001 From: Vincent Povirk Date: Thu, 30 Sep 2010 14:59:04 -0500 Subject: [PATCH 2/3] gdiplus: Implement GdipGetRegionScansCount. --- dlls/gdiplus/region.c | 77 ++++++++++++++++++++++++++++++++++++++++-- dlls/gdiplus/tests/region.c | 64 +++++++++++++++++++++++++++++++++++ include/gdiplusflat.h | 1 + 3 files changed, 138 insertions(+), 4 deletions(-) diff --git a/dlls/gdiplus/region.c b/dlls/gdiplus/region.c index 9b8ed18..69d78f2 100644 --- a/dlls/gdiplus/region.c +++ b/dlls/gdiplus/region.c @@ -1362,14 +1362,83 @@ 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, ®ion_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(®ion); + 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 *); -- 1.7.0.4