[try7][Gdiplus 05/10] Implement GdipCloneRegion
Adam Petaccia
adam at tpetaccia.com
Mon Aug 4 12:56:45 CDT 2008
Changelog:
(try4):
Move further up the patch series, others will depend on this now.
Deal with the fact that region->node isn't a pointer
Update to new naming scheme
Apply const qualifier
(try2):
Check *element2 for not NULL; clean up better in case of failure.
---
dlls/gdiplus/region.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 68 insertions(+), 3 deletions(-)
diff --git a/dlls/gdiplus/region.c b/dlls/gdiplus/region.c
index 43a4cf7..43efc77 100644
--- a/dlls/gdiplus/region.c
+++ b/dlls/gdiplus/region.c
@@ -162,15 +162,80 @@ static inline void delete_element(region_element* element)
}
}
+static inline GpStatus clone_element(const region_element* element,
+ region_element** element2)
+{
+ GpStatus stat;
+
+ *element2 = GdipAlloc(sizeof(region_element));
+ if (!*element2)
+ return OutOfMemory;
+
+ (*element2)->type = element->type;
+
+ switch (element->type)
+ {
+ case RegionDataRect:
+ memcpy(&(*element2)->elementdata.rect,
+ &element->elementdata.rect, sizeof(GpRectF));
+ break;
+ case RegionDataEmptyRect:
+ case RegionDataInfiniteRect:
+ break;
+ case RegionDataPath:
+ memcpy(&(*element2)->elementdata.pathdata.pathheader,
+ &element->elementdata.pathdata.pathheader, sizeof(DWORD)*4);
+ stat = GdipClonePath(element->elementdata.pathdata.path,
+ &(*element2)->elementdata.pathdata.path);
+ if (stat != Ok) goto clone_out;
+ break;
+ default:
+ stat = clone_element(element->elementdata.combine.left,
+ &(*element2)->elementdata.combine.left);
+ if (stat != Ok) goto clone_out;
+ stat = clone_element(element->elementdata.combine.right,
+ &(*element2)->elementdata.combine.right);
+ if (stat != Ok) goto clone_out;
+ break;
+ }
+
+ return Ok;
+
+clone_out:
+ delete_element(*element2);
+ *element2 = NULL;
+ return stat;
+}
+
/*****************************************************************************
* GdipCloneRegion [GDIPLUS.@]
+ *
+ * Creates a deep copy of the region
+ *
+ * PARAMS
+ * region [I] source region
+ * clone [O] resulting clone
+ *
+ * RETURNS
+ * SUCCESS: Ok
+ * FAILURE: InvalidParameter or OutOfMemory
*/
GpStatus WINGDIPAPI GdipCloneRegion(GpRegion *region, GpRegion **clone)
{
- FIXME("(%p %p): stub\n", region, clone);
+ region_element *element;
- *clone = NULL;
- return NotImplemented;
+ TRACE("%p %p\n", region, clone);
+
+ if (!(region && clone))
+ return InvalidParameter;
+
+ *clone = GdipAlloc(sizeof(GpRegion));
+ if (!*clone)
+ return OutOfMemory;
+ element = &(*clone)->node;
+
+ memcpy(&(*clone)->header, ®ion->header, sizeof(DWORD) * 4);
+ return clone_element(®ion->node, &element);
}
GpStatus WINGDIPAPI GdipCombineRegionPath(GpRegion *region, GpPath *path, CombineMode mode)
--
1.5.4.3
More information about the wine-patches
mailing list