Module: wine Branch: master Commit: 9ec5f9ad6fb97deaa443ce68ce4ca67c4b2f7298 URL: http://source.winehq.org/git/wine.git/?a=commit;h=9ec5f9ad6fb97deaa443ce68ce...
Author: Andrew Eikum aeikum@codeweavers.com Date: Mon Aug 24 16:49:31 2009 -0500
gdiplus: Support regions of more than one rectangle in GdipCreateRegionHrgn.
---
dlls/gdiplus/region.c | 66 +++++++++++++++++++++++++----------------- dlls/gdiplus/tests/region.c | 14 ++++----- 2 files changed, 45 insertions(+), 35 deletions(-)
diff --git a/dlls/gdiplus/region.c b/dlls/gdiplus/region.c index 039e789..ce6b60d 100644 --- a/dlls/gdiplus/region.c +++ b/dlls/gdiplus/region.c @@ -579,51 +579,63 @@ GpStatus WINGDIPAPI GdipCreateRegionRgnData(GDIPCONST BYTE *data, INT size, GpRe */ GpStatus WINGDIPAPI GdipCreateRegionHrgn(HRGN hrgn, GpRegion **region) { - union { - RGNDATA data; - char buf[sizeof(RGNDATAHEADER) + sizeof(RECT)]; - } rdata; DWORD size; - GpRectF rectf; - GpPath *path; + LPRGNDATA buf; + LPRECT rect; GpStatus stat; + GpPath* path; + GpRegion* local; + int i;
TRACE("(%p, %p)\n", hrgn, region);
if(!region || !(size = GetRegionData(hrgn, 0, NULL))) return InvalidParameter;
- if(size > sizeof(RGNDATAHEADER) + sizeof(RECT)){ - FIXME("Only simple rect regions supported.\n"); - *region = NULL; - return NotImplemented; - } + buf = GdipAlloc(size); + if(!buf) + return OutOfMemory;
- if(!GetRegionData(hrgn, sizeof(rdata), &rdata.data)) + if(!GetRegionData(hrgn, size, buf)){ + GdipFree(buf); 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; + if(buf->rdh.nCount == 0){ + if((stat = GdipCreateRegion(&local)) != Ok){ + GdipFree(buf); + return stat; + } + if((stat = GdipSetEmpty(local)) != Ok){ + GdipFree(buf); + GdipDeleteRegion(local); + return stat; + } + *region = local; + GdipFree(buf); + return Ok; + }
- stat = GdipCreatePath(FillModeAlternate, &path); - if(stat != Ok) + if((stat = GdipCreatePath(FillModeAlternate, &path)) != Ok){ + GdipFree(buf); return stat; + }
- GdipAddPathRectangle(path, rectf.X, rectf.Y, rectf.Width, rectf.Height); + rect = (LPRECT)buf->Buffer; + for(i = 0; i < buf->rdh.nCount; i++){ + if((stat = GdipAddPathRectangle(path, (REAL)rect->left, (REAL)rect->top, + (REAL)(rect->right - rect->left), (REAL)(rect->bottom - rect->top))) != Ok){ + GdipFree(buf); + GdipDeletePath(path); + return stat; + } + rect++; + }
stat = GdipCreateRegionPath(path, region); - GdipDeletePath(path);
+ GdipFree(buf); + GdipDeletePath(path); return stat; }
diff --git a/dlls/gdiplus/tests/region.c b/dlls/gdiplus/tests/region.c index 8b1b04e..fddceb3 100644 --- a/dlls/gdiplus/tests/region.c +++ b/dlls/gdiplus/tests/region.c @@ -704,7 +704,7 @@ static void test_combinereplace(void) static void test_fromhrgn(void) { GpStatus status; - GpRegion *region; + GpRegion *region = (GpRegion*)0xabcdef01; HRGN hrgn; UINT needed; DWORD buf[220]; @@ -720,6 +720,7 @@ static void test_fromhrgn(void) expect(InvalidParameter, status); status = GdipCreateRegionHrgn((HRGN)0xdeadbeef, ®ion); expect(InvalidParameter, status); + ok(region == (GpRegion*)0xabcdef01, "Expected region not to be created\n");
/* empty rectangle */ hrgn = CreateRectRgn(0, 0, 0, 0); @@ -788,21 +789,19 @@ static void test_fromhrgn(void) /* ellipse */ hrgn = CreateEllipticRgn(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); ok(needed == 216 || needed == 196, /* win98 */ "Got %.8x\n", needed); -} + status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed); - todo_wine expect(Ok, status); + expect(Ok, status);
if(status == Ok && needed == 216) /* Don't try to test win98 layout */ { -todo_wine{ expect(Ok, status); expect(216, needed); expect_dword(buf, 208); @@ -812,8 +811,7 @@ todo_wine{ expect_dword(buf + 5, 0x000000C0); expect_magic((DWORD*)(buf + 6)); expect_dword(buf + 7, 0x00000024); - expect_dword(buf + 8, 0x00006000); /* ?? */ -} + todo_wine expect_dword(buf + 8, 0x00006000); /* ?? */ }
GdipDeleteRegion(region);