[Gdiplus 4/5] Partially Implement GdipGetRegionBounds

Adam Petaccia adam at tpetaccia.com
Sat Aug 16 22:28:23 CDT 2008


---
 dlls/gdiplus/region.c       |   77 +++++++++++++++++++++++++++++++++++++++++-
 dlls/gdiplus/tests/region.c |   15 ++------
 2 files changed, 79 insertions(+), 13 deletions(-)

diff --git a/dlls/gdiplus/region.c b/dlls/gdiplus/region.c
index 5527834..3e0a1b4 100644
--- a/dlls/gdiplus/region.c
+++ b/dlls/gdiplus/region.c
@@ -576,9 +576,82 @@ GpStatus WINGDIPAPI GdipDeleteRegion(GpRegion *region)
     return Ok;
 }
 
-GpStatus WINGDIPAPI GdipGetRegionBounds(GpRegion *region, GpGraphics *graphics, GpRectF *rect)
+/*******************************************************************************
+ * GdipGetRegionBounds [GDIPLUS.@]
+ *
+ * Gets the bounding rectangle for the region
+ *
+ * PARAMS
+ *  region      [I] source region
+ *  graphics    [I] current graphics context
+ *  rect        [O] the resulting bounding rectangle
+ *
+ * RETURNS
+ *  SUCCESS: Ok
+ *  FAILURE: Another GpStatus element
+ */
+GpStatus WINGDIPAPI GdipGetRegionBounds(GpRegion *region, GpGraphics *graphics,
+        GpRectF *rect)
 {
-    FIXME("(%p, %p, %p): stub\n", region, graphics, rect);
+    if (!(region && graphics && rect))
+        return InvalidParameter;
+
+    TRACE("%p, %p, %p\n", region, graphics, rect);
+
+    switch(region->node.type)
+    {
+        case RegionDataRect:
+            rect->X = region->node.elementdata.rect.X;
+            rect->Y = region->node.elementdata.rect.Y;
+            rect->Width = region->node.elementdata.rect.Width;
+            rect->Height = region->node.elementdata.rect.Height;
+
+            return Ok;
+        case RegionDataPath:
+        {
+            GpPointF *allPoints;
+            FLOAT mostLeft, mostRight, mostHigh, mostLow;
+            INT pointCount, i;
+
+            GdipGetPointCount(region->node.elementdata.pathdata.path,
+                    &pointCount);
+            allPoints = GdipAlloc(sizeof(GpPointF) * pointCount);
+            if (!allPoints)
+                return OutOfMemory;
+            GdipGetPathPoints(region->node.elementdata.pathdata.path,
+                    allPoints, pointCount);
+
+            mostRight = mostLeft = allPoints[0].X;
+            mostHigh  = mostLow  = allPoints[0].Y;
+            for (i = 1; i < pointCount; i++)
+            {
+                if(allPoints[i].X < mostLeft)
+                    mostLeft  = allPoints[i].X;
+                else if (allPoints[i].X > mostRight)
+                    mostRight = allPoints[i].X;
+
+                if(allPoints[i].Y < mostLow)
+                    mostLow   = allPoints[i].Y;
+                else if (allPoints[i].Y > mostHigh)
+                    mostHigh  = allPoints[i].Y;
+            }
+            rect->X = mostLeft;
+            rect->Width = mostRight - mostLeft;
+            rect->Y = mostLow;
+            rect->Height = mostHigh - mostLow;
+
+            return Ok;
+        }
+        case RegionDataEmptyRect:
+            rect->X = 0;
+            rect->Width = 0;
+            rect->Y = 0;
+            rect->Height = 0;
+            return Ok;
+        case RegionDataInfiniteRect:
+        default:
+            FIXME("Unhandled type: %08x\n", region->node.type);
+    }
 
     return NotImplemented;
 }
diff --git a/dlls/gdiplus/tests/region.c b/dlls/gdiplus/tests/region.c
index 7850dc0..7d99fcf 100644
--- a/dlls/gdiplus/tests/region.c
+++ b/dlls/gdiplus/tests/region.c
@@ -540,11 +540,10 @@ todo_wine {
 
     /* Are equivalent Rectangles and Paths "equal"? (yes, they are) */
     GdipCreateRegionPath(path, &region2);
-todo_wine {
     GdipIsEqualRegion(region, region2, graphics, &equals);
     expect(Ok, stat);
+todo_wine
     expect(TRUE, equals);
-}
 
     stat = GdipDeleteRegion(region2);
     expect(Ok, stat);
@@ -558,9 +557,12 @@ todo_wine {
     expect(Ok, stat);
     stat = GdipCreateRegionPath(path, &region2);
     expect(Ok, stat);
+todo_wine
+{
     stat = GdipIsEqualRegion(region, region2, graphics, &equals);
     expect(Ok, stat);
     expect(FALSE, equals);
+}
 
     GdipDeletePath(path);
     GdipDeleteRegion(region);
@@ -591,14 +593,11 @@ static void test_regionbounds(void)
 
     /* Clear the rect to make sure what we get isn't stale data */
     memset(&rect, 0xee, sizeof(RectF));
-todo_wine
-{
     stat = GdipGetRegionBounds(region, graphics, &rect);
     ok(rect.X == 5, "Expected 5 for X, got %f\n", rect.X);
     ok(rect.Y == 7, "Expected 7 for Y, got %f\n", rect.Y);
     ok(rect.Width == 10, "Expected a width of 10, got %f\n", rect.Width);
     ok(rect.Height == 20, "Expected a height of 20, got %f\n", rect.Height);
-}
     stat = GdipDeleteRegion(region);
     expect(Ok, stat);
 
@@ -613,29 +612,23 @@ todo_wine
 
     stat = GdipCreateRegionPath(path, &region);
     expect(Ok, stat);
-todo_wine
-{
     stat = GdipGetRegionBounds(region, graphics, &rect);
     expect(Ok, stat);
     ok(rect.X == 1, "Expected 1 for X, got %f\n", rect.X);
     ok(rect.Y == 1, "Expected 1 for Y, got %f\n", rect.Y);
     ok(rect.Width == 8, "Expected 8 for Width, got %f\n", rect.Width);
     ok(rect.Height == 3, "Expected 3 for Height, got %f\n", rect.Height);
-}
 
     GdipDeletePath(path);
 
     stat = GdipSetEmpty(region);
     expect(Ok, stat);
-todo_wine
-{
     stat = GdipGetRegionBounds(region, graphics, &rect);
     expect(Ok, stat);
     ok(rect.X == 0, "Expected 0 for X, got %f\n", rect.X);
     ok(rect.Y == 0, "Expected 0 for Y, got %f\n", rect.Y);
     ok(rect.Width == 0, "Expected 0 for Width, got %f\n", rect.Width);
     ok(rect.Height == 0, "Expected 0 for Height, got %f\n", rect.Height);
-}
 
     GdipDeleteGraphics(graphics);
     GdipDeleteRegion(region);
-- 
1.5.4.3




More information about the wine-patches mailing list