scrolldc: better fix for clipping problem
Rein Klazes
wijn at wanadoo.nl
Sun Dec 18 09:51:00 CST 2005
Hi,
Looking at the problem with clip rect==NULL, it turns out that there is
general problem with clip rect > scroll rect.
Here is a fix for that general case with a test.
Changelog:
dlls/x11drv : scroll.c
dlls/user/tests : win.c
Do not use the scroll rectangle for clipping in ScrollDC. With a
conformance test.
Rein.
-------------- next part --------------
--- wine/dlls/x11drv/scroll.c 2005-12-18 14:48:41.000000000 +0100
+++ mywine/dlls/x11drv/scroll.c 2005-12-18 15:58:09.000000000 +0100
@@ -91,34 +91,21 @@ BOOL X11DRV_ScrollDC( HDC hdc, INT dx, I
} else
CombineRgn( visrgn, visrgn, clipRgn, RGN_AND);
/* only those pixels in the scroll rectangle that remain in the clipping
- * rect are scrolled. So first combine Scroll and Clipping rectangles,
- * if available */
- if( lprcScroll)
- {
- if( lprcClip)
- IntersectRect( &rcClip, lprcClip, lprcScroll);
- else
- rcClip = *lprcScroll;
- }
+ * rect are scrolled. */
+ if( lprcClip)
+ rcClip = *lprcClip;
else
- {
- if( lprcClip)
- rcClip = *lprcClip;
- else
- GetClipBox( hdc, &rcClip);
- }
- /* Then clip again to get the source rectangle that will remain in the
- * clipping rect */
+ GetClipBox( hdc, &rcClip);
rcSrc = rcClip;
- if (lprcClip)
- {
- OffsetRect( &rcSrc, -dx, -dy);
- IntersectRect( &rcSrc, &rcSrc, &rcClip);
- }
+ OffsetRect( &rcClip, -dx, -dy);
+ IntersectRect( &rcSrc, &rcSrc, &rcClip);
+ /* if an scroll rectangle is specified, only the pixels within that
+ * rectangle are scrolled */
+ if( lprcScroll)
+ IntersectRect( &rcSrc, &rcSrc, lprcScroll);
/* now convert to device coordinates */
LPtoDP(hdc, (LPPOINT)&rcSrc, 2);
TRACE("source rect: %s\n", wine_dbgstr_rect(&rcSrc));
-
/* also dx and dy */
SetRect(&offset, 0, 0, dx, dy);
LPtoDP(hdc, (LPPOINT)&offset, 2);
@@ -160,6 +147,17 @@ BOOL X11DRV_ScrollDC( HDC hdc, INT dx, I
code = X11DRV_END_EXPOSURES;
ExtEscape( hdc, X11DRV_ESCAPE, sizeof(code), (LPSTR)&code,
sizeof(ExpRgn), (LPSTR)&ExpRgn );
+ /* Intersect clip and scroll rectangles, allowing NULL values */
+ if( lprcScroll)
+ if( lprcClip)
+ IntersectRect( &rcClip, lprcClip, lprcScroll);
+ else
+ rcClip = *lprcScroll;
+ else
+ if( lprcClip)
+ rcClip = *lprcClip;
+ else
+ GetClipBox( hdc, &rcClip);
/* Convert the combined clip rectangle to device coordinates */
LPtoDP(hdc, (LPPOINT)&rcClip, 2);
if( hrgn )
--- wine/dlls/user/tests/win.c 2005-12-18 14:48:29.000000000 +0100
+++ mywine/dlls/user/tests/win.c 2005-12-18 15:57:17.000000000 +0100
@@ -2954,7 +2954,7 @@ static void test_scrolldc( HWND parent)
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);
-
+ /* test with NULL clip rect */
ScrollDC( hdc, 20, -20, &rc, NULL, hrgn, &rcu);
/*FillRgn(hdc, hrgn, GetStockObject(WHITE_BRUSH));*/
trace("update rect: %ld,%ld - %ld,%ld\n",
@@ -2969,6 +2969,21 @@ static void test_scrolldc( HWND parent)
CombineRgn(exprgn, exprgn, tmprgn, RGN_OR);
if (winetest_debug > 0) dump_region(exprgn);
ok(EqualRgn(exprgn, hrgn), "wrong update region\n");
+ /* test clip rect > scroll rect */
+ FillRect( hdc, &rc, GetStockObject(WHITE_BRUSH));
+ rc2=rc;
+ InflateRect( &rc2, -(rc.right-rc.left)/4, -(rc.bottom-rc.top)/4);
+ FillRect( hdc, &rc2, GetStockObject(BLACK_BRUSH));
+ ScrollDC( hdc, 10, 10, &rc2, &rc, hrgn, &rcu);
+ SetRectRgn( exprgn, 25, 25, 75, 35);
+ SetRectRgn( tmprgn, 25, 35, 35, 75);
+ CombineRgn(exprgn, exprgn, tmprgn, RGN_OR);
+ ok(EqualRgn(exprgn, hrgn), "wrong update region\n");
+ colr = GetPixel( hdc, 80, 80);
+ ok ( colr == 0, "pixel should be black, color is %08lx\n", colr);
+ trace("update rect: %ld,%ld - %ld,%ld\n",
+ rcu.left, rcu.top, rcu.right, rcu.bottom);
+ if (winetest_debug > 0) dump_region(hrgn);
/* clean up */
DeleteObject(hrgn);
More information about the wine-patches
mailing list