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