ScrollDC should not clip output if a clipping rect is not specified
Dmitry Timoshkov
dmitry at baikal.ru
Fri Dec 16 08:17:29 CST 2005
Hello,
here is hopefully a correct version of the patch.
Changelog:
Rein Klazes <wijn at wanadoo.nl>
Add another set of ScrollDC tests.
Dmitry Timoshkov <dmitry at codeweavers.com>
Add a ScrollDC test with NULL clipping rect.
ScrollDC should not clip output if a clipping rect is not specified.
diff -up cvs/hq/wine/dlls/user/tests/win.c wine/dlls/user/tests/win.c
--- cvs/hq/wine/dlls/user/tests/win.c 2005-11-30 23:19:27.000000000 +0800
+++ wine/dlls/user/tests/win.c 2005-12-16 21:51:28.000000000 +0800
@@ -2923,6 +2923,60 @@ static void test_scroll(void)
DestroyWindow( hwnd);
}
+static void test_scrolldc( HWND parent)
+{
+ HDC hdc;
+ HRGN exprgn, tmprgn, hrgn;
+ RECT rc, rc2, rcu, cliprc;
+ HWND hwnd1;
+ COLORREF colr;
+
+ hrgn = CreateRectRgn(0,0,0,0);
+
+ hwnd1 = CreateWindowExA(0, "static", NULL,
+ WS_CHILD| WS_VISIBLE,
+ 25, 50, 100, 100, parent, 0, 0, NULL);
+ ShowWindow( parent, SW_SHOW);
+ UpdateWindow( parent);
+ GetClientRect( hwnd1, &rc);
+ hdc = GetDC( hwnd1);
+ /* paint the upper half of the window black */
+ rc2 = rc;
+ rc2.bottom = ( rc.top + rc.bottom) /2;
+ FillRect( hdc, &rc2, GetStockObject(BLACK_BRUSH));
+ /* clip region is the lower half */
+ cliprc=rc;
+ cliprc.top = (rc.top + rc.bottom) /2;
+ /* test whether scrolled pixels are properly clipped */
+ colr = GetPixel( hdc, (rc.left+rc.right)/2, ( rc.top + rc.bottom) /2 - 1);
+ ok ( colr == 0, "pixel should be black, color is %08lx\n", colr);
+ /* this scroll should not cause any visible changes */
+ ScrollDC( hdc, 5, -20, &rc, &cliprc, hrgn, &rcu);
+ colr = GetPixel( hdc, (rc.left+rc.right)/2, ( rc.top + rc.bottom) /2 - 1);
+ ok ( colr == 0, "pixel should be black, color is %08lx\n", colr);
+
+ ScrollDC( hdc, 20, -20, &rc, NULL, hrgn, &rcu);
+ /*FillRgn(hdc, hrgn, GetStockObject(WHITE_BRUSH));*/
+ trace("update rect: %ld,%ld - %ld,%ld\n",
+ rcu.left, rcu.top, rcu.right, rcu.bottom);
+ if (winetest_debug > 0) dump_region(hrgn);
+ SetRect(&rc2, 0, 0, 100, 100);
+ ok(EqualRect(&rcu, &rc2), "rects do not match (%ld,%ld-%ld,%ld) / (%ld,%ld-%ld,%ld)\n",
+ rcu.left, rcu.top, rcu.right, rcu.bottom, rc2.left, rc2.top, rc2.right, rc2.bottom);
+
+ exprgn = CreateRectRgn(0, 0, 20, 80);
+ tmprgn = CreateRectRgn(0, 80, 100, 100);
+ CombineRgn(exprgn, exprgn, tmprgn, RGN_OR);
+ if (winetest_debug > 0) dump_region(exprgn);
+ ok(EqualRgn(exprgn, hrgn), "wrong update region\n");
+
+ /* clean up */
+ DeleteObject(hrgn);
+ DeleteObject(exprgn);
+ DeleteObject(tmprgn);
+ DestroyWindow(hwnd1);
+}
+
static void test_params(void)
{
HWND hwnd;
@@ -3533,6 +3587,7 @@ START_TEST(win)
test_validatergn(hwndMain);
test_nccalcscroll( hwndMain);
test_scrollvalidate( hwndMain);
+ test_scrolldc( hwndMain);
test_scroll();
test_IsWindowUnicode();
test_vis_rgn(hwndMain);
diff -up cvs/hq/wine/dlls/x11drv/scroll.c wine/dlls/x11drv/scroll.c
--- cvs/hq/wine/dlls/x11drv/scroll.c 2005-12-14 11:52:43.000000000 +0800
+++ wine/dlls/x11drv/scroll.c 2005-12-16 21:49:27.000000000 +0800
@@ -110,7 +110,11 @@ BOOL X11DRV_ScrollDC( HDC hdc, INT dx, I
/* Then clip again to get the source rectangle that will remain in the
* clipping rect */
rcSrc = rcClip;
- IntersectRect( &rcSrc, &rcSrc, &rcClip);
+ if (lprcClip)
+ {
+ OffsetRect( &rcSrc, -dx, -dy);
+ IntersectRect( &rcSrc, &rcSrc, &rcClip);
+ }
/* now convert to device coordinates */
LPtoDP(hdc, (LPPOINT)&rcSrc, 2);
TRACE("source rect: %s\n", wine_dbgstr_rect(&rcSrc));
@@ -141,7 +145,7 @@ BOOL X11DRV_ScrollDC( HDC hdc, INT dx, I
TRACE("destination rect: %s\n", wine_dbgstr_rect(&rect));
BitBlt( hdc, rect.left, rect.top,
- rect.right - rect.left, rect.bottom -rect.top,
+ rect.right - rect.left, rect.bottom - rect.top,
hdc, rect.left - dx, rect.top - dy, SRCCOPY);
}
/* compute the update areas. This is the combined clip rectangle
@@ -181,6 +185,7 @@ BOOL X11DRV_ScrollDC( HDC hdc, INT dx, I
if( !hrgnUpdate)
DeleteObject( hrgn);
}
+ /* restore original clipping region */
SelectClipRgn( hdc, clipRgn);
DeleteObject( visrgn);
DeleteObject( DstRgn);
More information about the wine-patches
mailing list