gdiplus: Support regions of more than one rectangle in GdipCreateRegionHrgn.

This commit is contained in:
Andrew Eikum 2009-08-24 16:49:31 -05:00 committed by Alexandre Julliard
parent cf5e2938a9
commit 9ec5f9ad6f
2 changed files with 46 additions and 36 deletions

View File

@ -579,51 +579,63 @@ GpStatus WINGDIPAPI GdipCreateRegionRgnData(GDIPCONST BYTE *data, INT size, GpRe
*/ */
GpStatus WINGDIPAPI GdipCreateRegionHrgn(HRGN hrgn, GpRegion **region) GpStatus WINGDIPAPI GdipCreateRegionHrgn(HRGN hrgn, GpRegion **region)
{ {
union {
RGNDATA data;
char buf[sizeof(RGNDATAHEADER) + sizeof(RECT)];
} rdata;
DWORD size; DWORD size;
GpRectF rectf; LPRGNDATA buf;
GpPath *path; LPRECT rect;
GpStatus stat; GpStatus stat;
GpPath* path;
GpRegion* local;
int i;
TRACE("(%p, %p)\n", hrgn, region); TRACE("(%p, %p)\n", hrgn, region);
if(!region || !(size = GetRegionData(hrgn, 0, NULL))) if(!region || !(size = GetRegionData(hrgn, 0, NULL)))
return InvalidParameter; return InvalidParameter;
if(size > sizeof(RGNDATAHEADER) + sizeof(RECT)){ buf = GdipAlloc(size);
FIXME("Only simple rect regions supported.\n"); if(!buf)
*region = NULL; return OutOfMemory;
return NotImplemented;
}
if(!GetRegionData(hrgn, sizeof(rdata), &rdata.data)) if(!GetRegionData(hrgn, size, buf)){
GdipFree(buf);
return GenericError; return GenericError;
}
/* return empty region */ if(buf->rdh.nCount == 0){
if(IsRectEmpty(&rdata.data.rdh.rcBound)){ if((stat = GdipCreateRegion(&local)) != Ok){
stat = GdipCreateRegion(region); GdipFree(buf);
if(stat == Ok) return stat;
GdipSetEmpty(*region); }
if((stat = GdipSetEmpty(local)) != Ok){
GdipFree(buf);
GdipDeleteRegion(local);
return stat;
}
*region = local;
GdipFree(buf);
return Ok;
}
if((stat = GdipCreatePath(FillModeAlternate, &path)) != Ok){
GdipFree(buf);
return stat; return stat;
} }
rectf.X = (REAL)rdata.data.rdh.rcBound.left; rect = (LPRECT)buf->Buffer;
rectf.Y = (REAL)rdata.data.rdh.rcBound.top; for(i = 0; i < buf->rdh.nCount; i++){
rectf.Width = (REAL)rdata.data.rdh.rcBound.right - rectf.X; if((stat = GdipAddPathRectangle(path, (REAL)rect->left, (REAL)rect->top,
rectf.Height = (REAL)rdata.data.rdh.rcBound.bottom - rectf.Y; (REAL)(rect->right - rect->left), (REAL)(rect->bottom - rect->top))) != Ok){
GdipFree(buf);
stat = GdipCreatePath(FillModeAlternate, &path); GdipDeletePath(path);
if(stat != Ok) return stat;
return stat; }
rect++;
GdipAddPathRectangle(path, rectf.X, rectf.Y, rectf.Width, rectf.Height); }
stat = GdipCreateRegionPath(path, region); stat = GdipCreateRegionPath(path, region);
GdipDeletePath(path);
GdipFree(buf);
GdipDeletePath(path);
return stat; return stat;
} }

View File

@ -704,7 +704,7 @@ static void test_combinereplace(void)
static void test_fromhrgn(void) static void test_fromhrgn(void)
{ {
GpStatus status; GpStatus status;
GpRegion *region; GpRegion *region = (GpRegion*)0xabcdef01;
HRGN hrgn; HRGN hrgn;
UINT needed; UINT needed;
DWORD buf[220]; DWORD buf[220];
@ -720,6 +720,7 @@ static void test_fromhrgn(void)
expect(InvalidParameter, status); expect(InvalidParameter, status);
status = GdipCreateRegionHrgn((HRGN)0xdeadbeef, &region); status = GdipCreateRegionHrgn((HRGN)0xdeadbeef, &region);
expect(InvalidParameter, status); expect(InvalidParameter, status);
ok(region == (GpRegion*)0xabcdef01, "Expected region not to be created\n");
/* empty rectangle */ /* empty rectangle */
hrgn = CreateRectRgn(0, 0, 0, 0); hrgn = CreateRectRgn(0, 0, 0, 0);
@ -788,21 +789,19 @@ static void test_fromhrgn(void)
/* ellipse */ /* ellipse */
hrgn = CreateEllipticRgn(0, 0, 100, 10); hrgn = CreateEllipticRgn(0, 0, 100, 10);
status = GdipCreateRegionHrgn(hrgn, &region); status = GdipCreateRegionHrgn(hrgn, &region);
todo_wine expect(Ok, status); expect(Ok, status);
status = GdipGetRegionDataSize(region, &needed); status = GdipGetRegionDataSize(region, &needed);
todo_wine{
expect(Ok, status); expect(Ok, status);
ok(needed == 216 || ok(needed == 216 ||
needed == 196, /* win98 */ needed == 196, /* win98 */
"Got %.8x\n", needed); "Got %.8x\n", needed);
}
status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &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 */ if(status == Ok && needed == 216) /* Don't try to test win98 layout */
{ {
todo_wine{
expect(Ok, status); expect(Ok, status);
expect(216, needed); expect(216, needed);
expect_dword(buf, 208); expect_dword(buf, 208);
@ -812,8 +811,7 @@ todo_wine{
expect_dword(buf + 5, 0x000000C0); expect_dword(buf + 5, 0x000000C0);
expect_magic((DWORD*)(buf + 6)); expect_magic((DWORD*)(buf + 6));
expect_dword(buf + 7, 0x00000024); expect_dword(buf + 7, 0x00000024);
expect_dword(buf + 8, 0x00006000); /* ?? */ todo_wine expect_dword(buf + 8, 0x00006000); /* ?? */
}
} }
GdipDeleteRegion(region); GdipDeleteRegion(region);