gdiplus: Add write_region_data helper and use it in GdipGetRegionData.
Signed-off-by: Piotr Caban <piotr@codeweavers.com> Signed-off-by: Vincent Povirk <vincent@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
cb56d0ce2b
commit
4a02870296
|
@ -84,12 +84,17 @@ struct memory_buffer
|
|||
|
||||
struct region_header
|
||||
{
|
||||
DWORD size;
|
||||
DWORD checksum;
|
||||
DWORD magic;
|
||||
DWORD num_children;
|
||||
};
|
||||
|
||||
struct region_data_header
|
||||
{
|
||||
DWORD size;
|
||||
DWORD checksum;
|
||||
struct region_header header;
|
||||
};
|
||||
|
||||
struct path_header
|
||||
{
|
||||
DWORD size;
|
||||
|
@ -98,11 +103,6 @@ struct path_header
|
|||
DWORD flags;
|
||||
};
|
||||
|
||||
/* Header size as far as header->size is concerned. This doesn't include
|
||||
* header->size or header->checksum
|
||||
*/
|
||||
static const INT sizeheader_size = sizeof(DWORD) * 2;
|
||||
|
||||
typedef struct packed_point
|
||||
{
|
||||
short X;
|
||||
|
@ -699,6 +699,24 @@ static void write_element(const region_element* element, DWORD *buffer,
|
|||
}
|
||||
}
|
||||
|
||||
static DWORD write_region_data(const GpRegion *region, void *data)
|
||||
{
|
||||
struct region_header *header = data;
|
||||
INT filled = 0;
|
||||
DWORD size;
|
||||
|
||||
size = sizeof(struct region_header) + get_element_size(®ion->node);
|
||||
if (!data) return size;
|
||||
|
||||
header->magic = VERSION_MAGIC2;
|
||||
header->num_children = region->num_children;
|
||||
filled += 2;
|
||||
/* With few exceptions, everything written is DWORD aligned,
|
||||
* so use that as our base */
|
||||
write_element(®ion->node, (DWORD*)data, &filled);
|
||||
return size;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* GdipGetRegionData [GDIPLUS.@]
|
||||
*
|
||||
|
@ -735,36 +753,27 @@ static void write_element(const region_element* element, DWORD *buffer,
|
|||
GpStatus WINGDIPAPI GdipGetRegionData(GpRegion *region, BYTE *buffer, UINT size,
|
||||
UINT *needed)
|
||||
{
|
||||
struct region_header *region_header;
|
||||
INT filled = 0;
|
||||
struct region_data_header *region_data_header;
|
||||
UINT required;
|
||||
GpStatus status;
|
||||
|
||||
TRACE("%p, %p, %d, %p\n", region, buffer, size, needed);
|
||||
|
||||
if (!region || !buffer || !size)
|
||||
return InvalidParameter;
|
||||
|
||||
status = GdipGetRegionDataSize(region, &required);
|
||||
if (status != Ok) return status;
|
||||
required = FIELD_OFFSET(struct region_data_header, header) + write_region_data(region, NULL);
|
||||
if (size < required)
|
||||
{
|
||||
if (needed) *needed = size;
|
||||
return InsufficientBuffer;
|
||||
}
|
||||
|
||||
region_header = (struct region_header *)buffer;
|
||||
region_header->size = sizeheader_size + get_element_size(®ion->node);
|
||||
region_header->checksum = 0;
|
||||
region_header->magic = VERSION_MAGIC2;
|
||||
region_header->num_children = region->num_children;
|
||||
filled += 4;
|
||||
/* With few exceptions, everything written is DWORD aligned,
|
||||
* so use that as our base */
|
||||
write_element(®ion->node, (DWORD*)buffer, &filled);
|
||||
region_data_header = (struct region_data_header *)buffer;
|
||||
region_data_header->size = write_region_data(region, ®ion_data_header->header);
|
||||
region_data_header->checksum = 0;
|
||||
|
||||
if (needed)
|
||||
*needed = filled * sizeof(DWORD);
|
||||
*needed = required;
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
@ -960,7 +969,7 @@ static GpStatus read_element(struct memory_buffer *mbuf, GpRegion *region, regio
|
|||
*/
|
||||
GpStatus WINGDIPAPI GdipCreateRegionRgnData(GDIPCONST BYTE *data, INT size, GpRegion **region)
|
||||
{
|
||||
const struct region_header *region_header;
|
||||
const struct region_data_header *region_data_header;
|
||||
struct memory_buffer mbuf;
|
||||
GpStatus status;
|
||||
INT count;
|
||||
|
@ -972,8 +981,8 @@ GpStatus WINGDIPAPI GdipCreateRegionRgnData(GDIPCONST BYTE *data, INT size, GpRe
|
|||
|
||||
init_memory_buffer(&mbuf, data, size);
|
||||
|
||||
region_header = buffer_read(&mbuf, sizeof(*region_header));
|
||||
if (!region_header || !VALID_MAGIC(region_header->magic))
|
||||
region_data_header = buffer_read(&mbuf, sizeof(*region_data_header));
|
||||
if (!region_data_header || !VALID_MAGIC(region_data_header->header.magic))
|
||||
return InvalidParameter;
|
||||
|
||||
status = GdipCreateRegion(region);
|
||||
|
@ -1005,7 +1014,7 @@ GpStatus WINGDIPAPI GdipGetRegionDataSize(GpRegion *region, UINT *needed)
|
|||
return InvalidParameter;
|
||||
|
||||
/* header.size doesn't count header.size and header.checksum */
|
||||
*needed = sizeof(DWORD) * 2 + sizeheader_size + get_element_size(®ion->node);
|
||||
*needed = FIELD_OFFSET(struct region_data_header, header) + write_region_data(region, NULL);
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue