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

This commit is contained in:
Rein Klazes 2009-06-06 19:56:58 +02:00 committed by Alexandre Julliard
parent ad9036e1ff
commit d145f399ca
2 changed files with 63 additions and 5 deletions

View File

@ -1144,27 +1144,45 @@ BOOL WINAPI RectInRegion( HRGN hrgn, const RECT *rect )
{ {
RGNOBJ * obj; RGNOBJ * obj;
BOOL ret = FALSE; 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 ))) if ((obj = GDI_GetObjPtr( hrgn, OBJ_REGION )))
{ {
RECT *pCurRect, *pRectEnd; RECT *pCurRect, *pRectEnd;
/* this is (just) a useful optimization */ /* 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 + for (pCurRect = obj->rgn.rects, pRectEnd = pCurRect +
obj->rgn.numRects; pCurRect < pRectEnd; pCurRect++) obj->rgn.numRects; pCurRect < pRectEnd; pCurRect++)
{ {
if (pCurRect->bottom <= rect->top) if (pCurRect->bottom <= rc.top)
continue; /* not far enough down yet */ continue; /* not far enough down yet */
if (pCurRect->top >= rect->bottom) if (pCurRect->top >= rc.bottom)
break; /* too far down */ break; /* too far down */
if (pCurRect->right <= rect->left) if (pCurRect->right <= rc.left)
continue; /* not far enough over yet */ continue; /* not far enough over yet */
if (pCurRect->left >= rect->right) { if (pCurRect->left >= rc.right) {
continue; continue;
} }

View File

@ -266,9 +266,49 @@ static void test_GetCurrentObject(void)
DeleteDC(hdc); 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) START_TEST(gdiobj)
{ {
test_gdi_objects(); test_gdi_objects();
test_thread_objects(); test_thread_objects();
test_GetCurrentObject(); test_GetCurrentObject();
test_region();
} }