gdiplus: Support regions of more than one rectangle in GdipCreateRegionHrgn.
This commit is contained in:
parent
cf5e2938a9
commit
9ec5f9ad6f
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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, ®ion);
|
status = GdipCreateRegionHrgn((HRGN)0xdeadbeef, ®ion);
|
||||||
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, ®ion);
|
status = GdipCreateRegionHrgn(hrgn, ®ion);
|
||||||
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);
|
||||||
|
|
Loading…
Reference in New Issue