Andrew Eikum : gdiplus: Support regions of more than one rectangle in GdipCreateRegionHrgn.
Alexandre Julliard
julliard at winehq.org
Tue Aug 25 08:44:03 CDT 2009
Module: wine
Branch: master
Commit: 9ec5f9ad6fb97deaa443ce68ce4ca67c4b2f7298
URL: http://source.winehq.org/git/wine.git/?a=commit;h=9ec5f9ad6fb97deaa443ce68ce4ca67c4b2f7298
Author: Andrew Eikum <aeikum at 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);
More information about the wine-cvs
mailing list