Vincent Povirk : gdiplus: Implement GdipTransformRegion.
Alexandre Julliard
julliard at winehq.org
Fri Oct 1 11:38:44 CDT 2010
Module: wine
Branch: master
Commit: 40d8876fc4ce90a07043b4b0b78d8b98c7a972f3
URL: http://source.winehq.org/git/wine.git/?a=commit;h=40d8876fc4ce90a07043b4b0b78d8b98c7a972f3
Author: Vincent Povirk <vincent at codeweavers.com>
Date: Thu Sep 30 14:39:27 2010 -0500
gdiplus: Implement GdipTransformRegion.
---
dlls/gdiplus/region.c | 59 ++++++++++++++++++++++-
dlls/gdiplus/tests/region.c | 108 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 165 insertions(+), 2 deletions(-)
diff --git a/dlls/gdiplus/region.c b/dlls/gdiplus/region.c
index decaaf9..9b8ed18 100644
--- a/dlls/gdiplus/region.c
+++ b/dlls/gdiplus/region.c
@@ -1248,11 +1248,66 @@ GpStatus WINGDIPAPI GdipSetInfinite(GpRegion *region)
return stat;
}
+/* Transforms GpRegion elements with given matrix */
+static GpStatus transform_region_element(region_element* element, GpMatrix *matrix)
+{
+ GpStatus stat;
+
+ switch(element->type)
+ {
+ case RegionDataEmptyRect:
+ case RegionDataInfiniteRect:
+ return Ok;
+ case RegionDataRect:
+ {
+ /* We can't transform a rectangle, so convert it to a path. */
+ GpRegion *new_region;
+ GpPath *path;
+
+ stat = GdipCreatePath(FillModeAlternate, &path);
+ if (stat == Ok)
+ {
+ stat = GdipAddPathRectangle(path,
+ element->elementdata.rect.X, element->elementdata.rect.Y,
+ element->elementdata.rect.Width, element->elementdata.rect.Height);
+
+ if (stat == Ok)
+ stat = GdipCreateRegionPath(path, &new_region);
+
+ GdipDeletePath(path);
+ }
+
+ if (stat == Ok)
+ {
+ /* Steal the element from the created region. */
+ memcpy(element, &new_region->node, sizeof(region_element));
+ HeapFree(GetProcessHeap(), 0, new_region);
+ }
+ else
+ return stat;
+ }
+ /* Fall-through to do the actual conversion. */
+ case RegionDataPath:
+ stat = GdipTransformMatrixPoints(matrix,
+ element->elementdata.pathdata.path->pathdata.Points,
+ element->elementdata.pathdata.path->pathdata.Count);
+ return stat;
+ default:
+ stat = transform_region_element(element->elementdata.combine.left, matrix);
+ if (stat == Ok)
+ stat = transform_region_element(element->elementdata.combine.right, matrix);
+ return stat;
+ }
+}
+
GpStatus WINGDIPAPI GdipTransformRegion(GpRegion *region, GpMatrix *matrix)
{
- FIXME("(%p, %p): stub\n", region, matrix);
+ TRACE("(%p, %p)\n", region, matrix);
- return NotImplemented;
+ if (!region || !matrix)
+ return InvalidParameter;
+
+ return transform_region_element(®ion->node, matrix);
}
/* Translates GpRegion elements with specified offsets */
diff --git a/dlls/gdiplus/tests/region.c b/dlls/gdiplus/tests/region.c
index efd2115..96ac40e 100644
--- a/dlls/gdiplus/tests/region.c
+++ b/dlls/gdiplus/tests/region.c
@@ -1123,6 +1123,113 @@ static void test_translate(void)
ReleaseDC(0, hdc);
}
+static void test_transform(void)
+{
+ GpRegion *region, *region2;
+ GpMatrix *matrix;
+ GpGraphics *graphics;
+ GpPath *path;
+ GpRectF rectf;
+ GpStatus status;
+ HDC hdc = GetDC(0);
+ BOOL res;
+
+ status = GdipCreateFromHDC(hdc, &graphics);
+ expect(Ok, status);
+
+ status = GdipCreatePath(FillModeAlternate, &path);
+ expect(Ok, status);
+
+ status = GdipCreateRegion(®ion);
+ expect(Ok, status);
+ status = GdipCreateRegion(®ion2);
+ expect(Ok, status);
+
+ status = GdipCreateMatrix(&matrix);
+ expect(Ok, status);
+ status = GdipScaleMatrix(matrix, 2.0, 3.0, MatrixOrderAppend);
+ expect(Ok, status);
+
+ /* NULL */
+ status = GdipTransformRegion(NULL, matrix);
+ expect(InvalidParameter, status);
+
+ status = GdipTransformRegion(region, NULL);
+ expect(InvalidParameter, status);
+
+ /* infinite */
+ status = GdipTransformRegion(region, matrix);
+ expect(Ok, status);
+
+ res = FALSE;
+ status = GdipIsEqualRegion(region, region2, graphics, &res);
+ expect(Ok, status);
+ ok(res, "Expected to be equal.\n");
+
+ /* empty */
+ status = GdipSetEmpty(region);
+ expect(Ok, status);
+ status = GdipTransformRegion(region, matrix);
+ expect(Ok, status);
+
+ status = GdipSetEmpty(region2);
+ expect(Ok, status);
+
+ res = FALSE;
+ status = GdipIsEqualRegion(region, region2, graphics, &res);
+ expect(Ok, status);
+ ok(res, "Expected to be equal.\n");
+
+ /* rect */
+ rectf.X = 10.0;
+ rectf.Y = 0.0;
+ rectf.Width = rectf.Height = 100.0;
+ status = GdipCombineRegionRect(region, &rectf, CombineModeReplace);
+ expect(Ok, status);
+ rectf.X = 20.0;
+ rectf.Y = 0.0;
+ rectf.Width = 200.0;
+ rectf.Height = 300.0;
+ status = GdipCombineRegionRect(region2, &rectf, CombineModeReplace);
+ expect(Ok, status);
+ status = GdipTransformRegion(region, matrix);
+ expect(Ok, status);
+ res = FALSE;
+ status = GdipIsEqualRegion(region, region2, graphics, &res);
+ expect(Ok, status);
+ ok(res, "Expected to be equal.\n");
+
+ /* path */
+ status = GdipAddPathEllipse(path, 0.0, 10.0, 100.0, 150.0);
+ expect(Ok, status);
+ status = GdipCombineRegionPath(region, path, CombineModeReplace);
+ expect(Ok, status);
+ status = GdipResetPath(path);
+ expect(Ok, status);
+ status = GdipAddPathEllipse(path, 0.0, 30.0, 200.0, 450.0);
+ expect(Ok, status);
+ status = GdipCombineRegionPath(region2, path, CombineModeReplace);
+ expect(Ok, status);
+ status = GdipTransformRegion(region, matrix);
+ expect(Ok, status);
+ res = FALSE;
+ status = GdipIsEqualRegion(region, region2, graphics, &res);
+ expect(Ok, status);
+ ok(res, "Expected to be equal.\n");
+
+ status = GdipDeleteRegion(region);
+ expect(Ok, status);
+ status = GdipDeleteRegion(region2);
+ expect(Ok, status);
+ status = GdipDeleteGraphics(graphics);
+ expect(Ok, status);
+ status = GdipDeletePath(path);
+ expect(Ok, status);
+ status = GdipDeleteMatrix(matrix);
+ expect(Ok, status);
+ ReleaseDC(0, hdc);
+}
+
static void test_getbounds(void)
{
GpRegion *region;
@@ -1634,6 +1741,7 @@ START_TEST(region)
test_gethrgn();
test_isequal();
test_translate();
+ test_transform();
test_getbounds();
test_isvisiblepoint();
test_isvisiblerect();
More information about the wine-cvs
mailing list