Rein Klazes : gdi32: Fix RectInRegion() if right < left or bottom < top.

Alexandre Julliard julliard at winehq.org
Mon Jun 8 09:44:46 CDT 2009


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

Author: Rein Klazes <wijn at online.nl>
Date:   Sat Jun  6 19:56:58 2009 +0200

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

---

 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..c1adc0f 100644
--- a/dlls/gdi32/tests/gdiobj.c
+++ b/dlls/gdi32/tests/gdiobj.c
@@ -266,9 +266,49 @@ static void test_GetCurrentObject(void)
     DeleteDC(hdc);
 }
 
+static void test_region(void)
+{
+    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();
 }




More information about the wine-cvs mailing list