gdiplus: Implement trivial case of GdipCreateRegionRgnData for empty and infinite regions.
This commit is contained in:
parent
79118f3543
commit
0a15e163db
|
@ -39,7 +39,8 @@
|
|||
#define MAX_DASHLEN (16) /* this is a limitation of gdi */
|
||||
#define INCH_HIMETRIC (2540)
|
||||
|
||||
#define VERSION_MAGIC 0xdbc01001
|
||||
#define VERSION_MAGIC 0xdbc01001
|
||||
#define VERSION_MAGIC2 0xdbc01002
|
||||
#define TENSION_CONST (0.3)
|
||||
|
||||
#define GIF_DISPOSE_UNSPECIFIED 0
|
||||
|
|
|
@ -522,15 +522,6 @@ GpStatus WINGDIPAPI GdipCreateRegionRectI(GDIPCONST GpRect *rect,
|
|||
return GdipCreateRegionRect(&rectf, region);
|
||||
}
|
||||
|
||||
GpStatus WINGDIPAPI GdipCreateRegionRgnData(GDIPCONST BYTE *data, INT size, GpRegion **region)
|
||||
{
|
||||
FIXME("(%p, %d, %p): stub\n", data, size, region);
|
||||
|
||||
*region = NULL;
|
||||
return NotImplemented;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* GdipCreateRegionHrgn [GDIPLUS.@]
|
||||
*/
|
||||
|
@ -787,6 +778,14 @@ static void write_element(const region_element* element, DWORD *buffer,
|
|||
}
|
||||
}
|
||||
|
||||
struct region_header
|
||||
{
|
||||
DWORD size;
|
||||
DWORD checksum;
|
||||
DWORD magic;
|
||||
DWORD num_children;
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* GdipGetRegionData [GDIPLUS.@]
|
||||
*
|
||||
|
@ -823,13 +822,7 @@ static void write_element(const region_element* element, DWORD *buffer,
|
|||
GpStatus WINGDIPAPI GdipGetRegionData(GpRegion *region, BYTE *buffer, UINT size,
|
||||
UINT *needed)
|
||||
{
|
||||
struct _region_header
|
||||
{
|
||||
DWORD size;
|
||||
DWORD checksum;
|
||||
DWORD magic;
|
||||
DWORD num_children;
|
||||
} *region_header;
|
||||
struct region_header *region_header;
|
||||
INT filled = 0;
|
||||
UINT required;
|
||||
GpStatus status;
|
||||
|
@ -847,7 +840,7 @@ GpStatus WINGDIPAPI GdipGetRegionData(GpRegion *region, BYTE *buffer, UINT size,
|
|||
return InsufficientBuffer;
|
||||
}
|
||||
|
||||
region_header = (struct _region_header *)buffer;
|
||||
region_header = (struct region_header *)buffer;
|
||||
region_header->size = sizeheader_size + get_element_size(®ion->node);
|
||||
region_header->checksum = 0;
|
||||
region_header->magic = VERSION_MAGIC;
|
||||
|
@ -863,6 +856,74 @@ GpStatus WINGDIPAPI GdipGetRegionData(GpRegion *region, BYTE *buffer, UINT size,
|
|||
return Ok;
|
||||
}
|
||||
|
||||
static inline GpStatus read_dword(DWORD **buffer, INT *size, DWORD *ret)
|
||||
{
|
||||
if (*size < sizeof(DWORD))
|
||||
return GenericError;
|
||||
|
||||
*ret = **buffer;
|
||||
(*buffer)++;
|
||||
(*size) -= sizeof(DWORD);
|
||||
return Ok;
|
||||
}
|
||||
|
||||
static GpStatus read_element(GpRegion *region, region_element *element, DWORD **buffer, INT *size)
|
||||
{
|
||||
GpStatus status;
|
||||
|
||||
status = read_dword(buffer, size, &element->type);
|
||||
if (status != Ok)
|
||||
return status;
|
||||
|
||||
switch (element->type)
|
||||
{
|
||||
case RegionDataInfiniteRect:
|
||||
case RegionDataEmptyRect:
|
||||
break;
|
||||
default:
|
||||
FIXME("region element type 0x%08x not supported\n", element->type);
|
||||
return NotImplemented;
|
||||
}
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* GdipCreateRegionRgnData [GDIPLUS.@]
|
||||
*/
|
||||
GpStatus WINGDIPAPI GdipCreateRegionRgnData(GDIPCONST BYTE *data, INT size, GpRegion **region)
|
||||
{
|
||||
struct region_header *region_header;
|
||||
DWORD *buffer = (DWORD*)data;
|
||||
GpStatus status;
|
||||
|
||||
TRACE("(%p, %d, %p)\n", data, size, region);
|
||||
|
||||
if (!data || size < sizeof(*region_header) || !region)
|
||||
return InvalidParameter;
|
||||
|
||||
region_header = (struct region_header *)buffer;
|
||||
if (region_header->magic != VERSION_MAGIC && region_header->magic != VERSION_MAGIC2)
|
||||
return InvalidParameter;
|
||||
|
||||
status = GdipCreateRegion(region);
|
||||
if (status != Ok)
|
||||
return status;
|
||||
|
||||
/* skip header */
|
||||
buffer += 4;
|
||||
size -= sizeof(*region_header);
|
||||
|
||||
status = read_element(*region, &(*region)->node, &buffer, &size);
|
||||
if (status != Ok)
|
||||
{
|
||||
GdipDeleteRegion(*region);
|
||||
*region = NULL;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* GdipGetRegionDataSize [GDIPLUS.@]
|
||||
*/
|
||||
|
@ -988,7 +1049,7 @@ static GpStatus get_region_hrgn(struct region_element *element, GpGraphics *grap
|
|||
case CombineModeIntersect:
|
||||
return get_region_hrgn(element->elementdata.combine.right, graphics, hrgn);
|
||||
case CombineModeXor: case CombineModeExclude:
|
||||
left = CreateRectRgn(-4194304, -4194304, 4194304, 4194304);
|
||||
left = CreateRectRgn(-(1 << 22), -(1 << 22), 1 << 22, 1 << 22);
|
||||
break;
|
||||
case CombineModeUnion: case CombineModeComplement:
|
||||
*hrgn = NULL;
|
||||
|
@ -1013,7 +1074,7 @@ static GpStatus get_region_hrgn(struct region_element *element, GpGraphics *grap
|
|||
*hrgn = left;
|
||||
return Ok;
|
||||
case CombineModeXor: case CombineModeComplement:
|
||||
right = CreateRectRgn(-4194304, -4194304, 4194304, 4194304);
|
||||
right = CreateRectRgn(-(1 << 22), -(1 << 22), 1 << 22, 1 << 22);
|
||||
break;
|
||||
case CombineModeUnion: case CombineModeExclude:
|
||||
DeleteObject(left);
|
||||
|
|
|
@ -2132,6 +2132,68 @@ static void test_excludeinfinite(void)
|
|||
GdipDeleteMatrix(identity);
|
||||
}
|
||||
|
||||
static void test_GdipCreateRegionRgnData(void)
|
||||
{
|
||||
GpGraphics *graphics = NULL;
|
||||
GpRegion *region, *region2;
|
||||
HDC hdc = GetDC(0);
|
||||
GpStatus status;
|
||||
BYTE buf[512];
|
||||
UINT needed;
|
||||
BOOL ret;
|
||||
|
||||
status = GdipCreateRegionRgnData(NULL, 0, NULL);
|
||||
ok(status == InvalidParameter, "status %d\n", status);
|
||||
|
||||
status = GdipCreateFromHDC(hdc, &graphics);
|
||||
ok(status == Ok, "status %d\n", status);
|
||||
|
||||
status = GdipCreateRegion(®ion);
|
||||
ok(status == Ok, "status %d\n", status);
|
||||
|
||||
/* infinite region */
|
||||
memset(buf, 0xee, sizeof(buf));
|
||||
needed = 0;
|
||||
status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed);
|
||||
ok(status == Ok, "status %d\n", status);
|
||||
expect(20, needed);
|
||||
|
||||
status = GdipCreateRegionRgnData(buf, needed, NULL);
|
||||
ok(status == InvalidParameter, "status %d\n", status);
|
||||
|
||||
status = GdipCreateRegionRgnData(buf, needed, ®ion2);
|
||||
ok(status == Ok, "status %d\n", status);
|
||||
|
||||
ret = FALSE;
|
||||
status = GdipIsInfiniteRegion(region2, graphics, &ret);
|
||||
ok(status == Ok, "status %d\n", status);
|
||||
ok(ret, "got %d\n", ret);
|
||||
GdipDeleteRegion(region2);
|
||||
|
||||
/* empty region */
|
||||
status = GdipSetEmpty(region);
|
||||
ok(status == Ok, "status %d\n", status);
|
||||
|
||||
memset(buf, 0xee, sizeof(buf));
|
||||
needed = 0;
|
||||
status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed);
|
||||
ok(status == Ok, "status %d\n", status);
|
||||
expect(20, needed);
|
||||
|
||||
status = GdipCreateRegionRgnData(buf, needed, ®ion2);
|
||||
ok(status == Ok, "status %d\n", status);
|
||||
|
||||
ret = FALSE;
|
||||
status = GdipIsEmptyRegion(region2, graphics, &ret);
|
||||
ok(status == Ok, "status %d\n", status);
|
||||
ok(ret, "got %d\n", ret);
|
||||
GdipDeleteRegion(region2);
|
||||
|
||||
GdipDeleteGraphics(graphics);
|
||||
GdipDeleteRegion(region);
|
||||
ReleaseDC(0, hdc);
|
||||
}
|
||||
|
||||
START_TEST(region)
|
||||
{
|
||||
struct GdiplusStartupInput gdiplusStartupInput;
|
||||
|
@ -2158,6 +2220,7 @@ START_TEST(region)
|
|||
test_isvisiblepoint();
|
||||
test_isvisiblerect();
|
||||
test_excludeinfinite();
|
||||
test_GdipCreateRegionRgnData();
|
||||
|
||||
GdiplusShutdown(gdiplusToken);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue