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
|
struct region_header
|
||||||
{
|
{
|
||||||
DWORD size;
|
|
||||||
DWORD checksum;
|
|
||||||
DWORD magic;
|
DWORD magic;
|
||||||
DWORD num_children;
|
DWORD num_children;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct region_data_header
|
||||||
|
{
|
||||||
|
DWORD size;
|
||||||
|
DWORD checksum;
|
||||||
|
struct region_header header;
|
||||||
|
};
|
||||||
|
|
||||||
struct path_header
|
struct path_header
|
||||||
{
|
{
|
||||||
DWORD size;
|
DWORD size;
|
||||||
|
@ -98,11 +103,6 @@ struct path_header
|
||||||
DWORD flags;
|
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
|
typedef struct packed_point
|
||||||
{
|
{
|
||||||
short X;
|
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.@]
|
* 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,
|
GpStatus WINGDIPAPI GdipGetRegionData(GpRegion *region, BYTE *buffer, UINT size,
|
||||||
UINT *needed)
|
UINT *needed)
|
||||||
{
|
{
|
||||||
struct region_header *region_header;
|
struct region_data_header *region_data_header;
|
||||||
INT filled = 0;
|
|
||||||
UINT required;
|
UINT required;
|
||||||
GpStatus status;
|
|
||||||
|
|
||||||
TRACE("%p, %p, %d, %p\n", region, buffer, size, needed);
|
TRACE("%p, %p, %d, %p\n", region, buffer, size, needed);
|
||||||
|
|
||||||
if (!region || !buffer || !size)
|
if (!region || !buffer || !size)
|
||||||
return InvalidParameter;
|
return InvalidParameter;
|
||||||
|
|
||||||
status = GdipGetRegionDataSize(region, &required);
|
required = FIELD_OFFSET(struct region_data_header, header) + write_region_data(region, NULL);
|
||||||
if (status != Ok) return status;
|
|
||||||
if (size < required)
|
if (size < required)
|
||||||
{
|
{
|
||||||
if (needed) *needed = size;
|
if (needed) *needed = size;
|
||||||
return InsufficientBuffer;
|
return InsufficientBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
region_header = (struct region_header *)buffer;
|
region_data_header = (struct region_data_header *)buffer;
|
||||||
region_header->size = sizeheader_size + get_element_size(®ion->node);
|
region_data_header->size = write_region_data(region, ®ion_data_header->header);
|
||||||
region_header->checksum = 0;
|
region_data_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);
|
|
||||||
|
|
||||||
if (needed)
|
if (needed)
|
||||||
*needed = filled * sizeof(DWORD);
|
*needed = required;
|
||||||
|
|
||||||
return Ok;
|
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)
|
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;
|
struct memory_buffer mbuf;
|
||||||
GpStatus status;
|
GpStatus status;
|
||||||
INT count;
|
INT count;
|
||||||
|
@ -972,8 +981,8 @@ GpStatus WINGDIPAPI GdipCreateRegionRgnData(GDIPCONST BYTE *data, INT size, GpRe
|
||||||
|
|
||||||
init_memory_buffer(&mbuf, data, size);
|
init_memory_buffer(&mbuf, data, size);
|
||||||
|
|
||||||
region_header = buffer_read(&mbuf, sizeof(*region_header));
|
region_data_header = buffer_read(&mbuf, sizeof(*region_data_header));
|
||||||
if (!region_header || !VALID_MAGIC(region_header->magic))
|
if (!region_data_header || !VALID_MAGIC(region_data_header->header.magic))
|
||||||
return InvalidParameter;
|
return InvalidParameter;
|
||||||
|
|
||||||
status = GdipCreateRegion(region);
|
status = GdipCreateRegion(region);
|
||||||
|
@ -1005,7 +1014,7 @@ GpStatus WINGDIPAPI GdipGetRegionDataSize(GpRegion *region, UINT *needed)
|
||||||
return InvalidParameter;
|
return InvalidParameter;
|
||||||
|
|
||||||
/* header.size doesn't count header.size and header.checksum */
|
/* 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;
|
return Ok;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue