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