gdi32: fix RectInRegion() if right < left or bottom < top.

Rein Klazes wijn at online.nl
Sat Jun 6 12:56:58 CDT 2009


fix for bug #10551
---
 dlls/gdi32/region.c       |   28 +++++++++++++++++++++++-----
 dlls/gdi32/tests/gdiobj.c |   40 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 63 insertions(+), 5 deletions(-)

diff --git a/dlls/gdi32/region.c b/dlls/gdi32/region.c
index f9d078c..f3c5e13 100644
--- a/dlls/gdi32/region.c
+++ b/dlls/gdi32/region.c
@@ -1144,27 +1144,45 @@ BOOL WINAPI RectInRegion( HRGN hrgn, const RECT *rect )
 {
     RGNOBJ * obj;
     BOOL ret = FALSE;
+    RECT rc;
+
+    /* swap the coordinates to make right >= left and bottom >= top */
+    /* (region building rectangles are normalized the same way) */
+    if( rect->top > rect->bottom) {
+        rc.top = rect->bottom;
+        rc.bottom = rect->top;
+    } else {
+        rc.top = rect->top;
+        rc.bottom = rect->bottom;
+    }
+    if( rect->right < rect->left) {
+        rc.right = rect->left;
+        rc.left = rect->right;
+    } else {
+        rc.right = rect->right;
+        rc.left = rect->left;
+    }
 
     if ((obj = GDI_GetObjPtr( hrgn, OBJ_REGION )))
     {
 	RECT *pCurRect, *pRectEnd;
 
     /* this is (just) a useful optimization */
-	if ((obj->rgn.numRects > 0) && EXTENTCHECK(&obj->rgn.extents, rect))
+	if ((obj->rgn.numRects > 0) && EXTENTCHECK(&obj->rgn.extents, &rc))
 	{
 	    for (pCurRect = obj->rgn.rects, pRectEnd = pCurRect +
 	     obj->rgn.numRects; pCurRect < pRectEnd; pCurRect++)
 	    {
-	        if (pCurRect->bottom <= rect->top)
+	        if (pCurRect->bottom <= rc.top)
 		    continue;             /* not far enough down yet */
 
-		if (pCurRect->top >= rect->bottom)
+		if (pCurRect->top >= rc.bottom)
 		    break;                /* too far down */
 
-		if (pCurRect->right <= rect->left)
+		if (pCurRect->right <= rc.left)
 		    continue;              /* not far enough over yet */
 
-		if (pCurRect->left >= rect->right) {
+		if (pCurRect->left >= rc.right) {
 		    continue;
 		}
 
diff --git a/dlls/gdi32/tests/gdiobj.c b/dlls/gdi32/tests/gdiobj.c
index 67a135e..c437000 100644
--- a/dlls/gdi32/tests/gdiobj.c
+++ b/dlls/gdi32/tests/gdiobj.c
@@ -266,9 +266,49 @@ static void test_GetCurrentObject(void)
     DeleteDC(hdc);
 }
 
+void test_region()
+{
+    HRGN hrgn = CreateRectRgn(10, 10, 20, 20);
+    RECT rc = { 5, 5, 15, 15 };
+    BOOL ret = RectInRegion( hrgn, &rc);
+    ok( ret, "RectInRegion should return TRUE\n");
+    /* swap left and right */
+    SetRect( &rc, 15, 5, 5, 15 );
+    ret = RectInRegion( hrgn, &rc);
+    ok( ret, "RectInRegion should return TRUE\n");
+    /* swap top and bottom */
+    SetRect( &rc, 5, 15, 15, 5 );
+    ret = RectInRegion( hrgn, &rc);
+    ok( ret, "RectInRegion should return TRUE\n");
+    /* swap both */
+    SetRect( &rc, 15, 15, 5, 5 );
+    ret = RectInRegion( hrgn, &rc);
+    ok( ret, "RectInRegion should return TRUE\n");
+    DeleteObject(hrgn);
+    /* swap left and right in the region */
+    hrgn = CreateRectRgn(20, 10, 10, 20);
+    SetRect( &rc, 5, 5, 15, 15 );
+    ret = RectInRegion( hrgn, &rc);
+    ok( ret, "RectInRegion should return TRUE\n");
+    /* swap left and right */
+    SetRect( &rc, 15, 5, 5, 15 );
+    ret = RectInRegion( hrgn, &rc);
+    ok( ret, "RectInRegion should return TRUE\n");
+    /* swap top and bottom */
+    SetRect( &rc, 5, 15, 15, 5 );
+    ret = RectInRegion( hrgn, &rc);
+    ok( ret, "RectInRegion should return TRUE\n");
+    /* swap both */
+    SetRect( &rc, 15, 15, 5, 5 );
+    ret = RectInRegion( hrgn, &rc);
+    ok( ret, "RectInRegion should return TRUE\n");
+    DeleteObject(hrgn);
+}
+
 START_TEST(gdiobj)
 {
     test_gdi_objects();
     test_thread_objects();
     test_GetCurrentObject();
+    test_region();
 }
-- 
1.6.3.1




More information about the wine-patches mailing list