Piotr Caban : gdiplus: Add write_region_data helper and use it in GdipGetRegionData.

Alexandre Julliard julliard at winehq.org
Sat Aug 12 07:19:31 CDT 2017


Module: wine
Branch: master
Commit: 4a02870296227172f11e9d4cfdc1788fd0e905ff
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=4a02870296227172f11e9d4cfdc1788fd0e905ff

Author: Piotr Caban <piotr at 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 at codeweavers.com>
Signed-off-by: Vincent Povirk <vincent at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at 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(&region->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(&region->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(&region->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(&region->node, (DWORD*)buffer, &filled);
+    region_data_header = (struct region_data_header *)buffer;
+    region_data_header->size = write_region_data(region, &region_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(&region->node);
+    *needed = FIELD_OFFSET(struct region_data_header, header) + write_region_data(region, NULL);
 
     return Ok;
 }




More information about the wine-cvs mailing list