Module: wine Branch: master Commit: 4a02870296227172f11e9d4cfdc1788fd0e905ff URL: http://source.winehq.org/git/wine.git/?a=commit;h=4a02870296227172f11e9d4cfd...
Author: Piotr Caban piotr@codeweavers.com Date: Thu Aug 10 20:56:12 2017 +0200
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
---
dlls/gdiplus/region.c | 61 +++++++++++++++++++++++++++++---------------------- 1 file changed, 35 insertions(+), 26 deletions(-)
diff --git a/dlls/gdiplus/region.c b/dlls/gdiplus/region.c index 74c02c2..d133afa 100644 --- a/dlls/gdiplus/region.c +++ b/dlls/gdiplus/region.c @@ -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; }