There is no need to offset the source rectangle in the reverse
direction before scrolling
Rein Klazes
wijn at wanadoo.nl
Wed Dec 14 07:15:25 CST 2005
On Tue, 13 Dec 2005 23:53:07 +0800, you wrote:
>Changelog:
> Dmitry Timoshkov <dmitry at codeweavers.com>
> There is no need to offset the source rectangle in the reverse
> direction before scrolling.
>
>--- cvs/hq/wine/dlls/x11drv/scroll.c 2005-11-22 12:41:07.000000000 +0800
>+++ wine/dlls/x11drv/scroll.c 2005-12-13 23:42:15.000000000 +0800
> /* Then clip again to get the source rectangle that will remain in the
> * clipping rect */
> rcSrc = rcClip;
>- OffsetRect( &rcSrc, -dx, -dy);
> IntersectRect( &rcSrc, &rcSrc, &rcClip);
In the first place: with this change the IntersectRect call is a no-op
I doubt you understand the reason for "to offset the source rectangle
in the reverse direction":
Scrolling should only occur in the clipping rectangle. When you talk
about the *destination* pixels, a clipping with the cliprect is needed.
Here we are talking about the *source* pixels, from destination to
source is indeed reverse. *that* is what is happening here.
If you are not convinced: the change is wrong and clipping fails. I have
added a test to confirm that. The test also gives a nice visual idea
what goes wrong, just add a Sleep() or two to get the picture.
Changelog:
dlls/x11drv : scroll.c
dlls/user/tests : win.c
Restore the previous change to X11DRV_ScrollDC. With a regression test
to confirm it was wrong.
Rein.
-------------- next part --------------
--- wine/dlls/x11drv/scroll.c 2005-12-14 13:32:28.000000000 +0100
+++ mywine/dlls/x11drv/scroll.c 2005-12-14 13:53:49.000000000 +0100
@@ -94,22 +94,19 @@ BOOL X11DRV_ScrollDC( HDC hdc, INT dx, I
* rect are scrolled. So first combine Scroll and Clipping rectangles,
* if available */
if( lprcScroll)
- {
if( lprcClip)
IntersectRect( &rcClip, lprcClip, lprcScroll);
else
rcClip = *lprcScroll;
- }
else
- {
if( lprcClip)
rcClip = *lprcClip;
else
GetClipBox( hdc, &rcClip);
- }
/* Then clip again to get the source rectangle that will remain in the
* clipping rect */
rcSrc = rcClip;
+ OffsetRect( &rcSrc, -dx, -dy);
IntersectRect( &rcSrc, &rcSrc, &rcClip);
/* now convert to device coordinates */
LPtoDP(hdc, (LPPOINT)&rcSrc, 2);
--- wine/dlls/user/tests/win.c 2005-11-30 18:21:30.000000000 +0100
+++ mywine/dlls/user/tests/win.c 2005-12-14 13:47:25.000000000 +0100
@@ -2923,6 +2923,43 @@ static void test_scroll(void)
DestroyWindow( hwnd);
}
+void test_scrolldc( HWND parent)
+{
+ HDC hdc;
+ HRGN hrgn=CreateRectRgn(0,0,0,0);
+ RECT rc, rc2, rcu, cliprc;
+ HWND hwnd1;
+ COLORREF colr;
+
+ hwnd1 = CreateWindowExA(0, "static", NULL,
+ WS_CHILD| WS_VISIBLE | WS_BORDER ,
+ 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);
+
+ /* clean up */
+ DeleteObject( hrgn);
+ DestroyWindow( hwnd1);
+}
+
+
+
static void test_params(void)
{
HWND hwnd;
@@ -3533,6 +3570,7 @@ START_TEST(win)
test_validatergn(hwndMain);
test_nccalcscroll( hwndMain);
test_scrollvalidate( hwndMain);
+ test_scrolldc( hwndMain);
test_scroll();
test_IsWindowUnicode();
test_vis_rgn(hwndMain);
More information about the wine-patches
mailing list