Module: wine Branch: master Commit: d145f399cadb06a09a9468ff54efdccc68d2cc7c URL: http://source.winehq.org/git/wine.git/?a=commit;h=d145f399cadb06a09a9468ff54...
Author: Rein Klazes wijn@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(); }