Alexandre Julliard : gdi32: PatBlt needs to bypass the brush for ROPs that don't make use of it.

Alexandre Julliard julliard at winehq.org
Thu Jul 19 13:23:42 CDT 2012


Module: wine
Branch: master
Commit: 7c9d35e575613e7e554ee7cb6bc1bc5e192e7209
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=7c9d35e575613e7e554ee7cb6bc1bc5e192e7209

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Thu Jul 19 15:36:33 2012 +0200

gdi32: PatBlt needs to bypass the brush for ROPs that don't make use of it.

---

 dlls/gdi32/dibdrv/dibdrv.h   |    1 -
 dlls/gdi32/dibdrv/graphics.c |   45 +++++++++++++++++++++++++++++++++++++----
 dlls/gdi32/dibdrv/objects.c  |   15 +++----------
 3 files changed, 44 insertions(+), 17 deletions(-)

diff --git a/dlls/gdi32/dibdrv/dibdrv.h b/dlls/gdi32/dibdrv/dibdrv.h
index cb94800..24202d0 100644
--- a/dlls/gdi32/dibdrv/dibdrv.h
+++ b/dlls/gdi32/dibdrv/dibdrv.h
@@ -241,7 +241,6 @@ extern void copy_dib_color_info(dib_info *dst, const dib_info *src) DECLSPEC_HID
 extern BOOL convert_dib(dib_info *dst, const dib_info *src) DECLSPEC_HIDDEN;
 extern COLORREF make_rgb_colorref( HDC hdc, dib_info *dib, COLORREF color, BOOL *got_pixel, DWORD *pixel ) DECLSPEC_HIDDEN;
 extern DWORD get_pixel_color(dibdrv_physdev *pdev, COLORREF color, BOOL mono_fixup) DECLSPEC_HIDDEN;
-extern BOOL brush_rect( dibdrv_physdev *pdev, dib_brush *brush, const RECT *rect, HRGN clip, INT rop ) DECLSPEC_HIDDEN;
 extern int get_clipped_rects( const dib_info *dib, const RECT *rc, HRGN clip, struct clipped_rects *clip_rects ) DECLSPEC_HIDDEN;
 extern void add_clipped_bounds( dibdrv_physdev *dev, const RECT *rect, HRGN clip ) DECLSPEC_HIDDEN;
 extern int clip_line(const POINT *start, const POINT *end, const RECT *clip,
diff --git a/dlls/gdi32/dibdrv/graphics.c b/dlls/gdi32/dibdrv/graphics.c
index 0237acf..846b08e 100644
--- a/dlls/gdi32/dibdrv/graphics.c
+++ b/dlls/gdi32/dibdrv/graphics.c
@@ -26,18 +26,30 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(dib);
 
+static BOOL brush_rect( dibdrv_physdev *pdev, dib_brush *brush, const RECT *rect, HRGN clip )
+{
+    struct clipped_rects clipped_rects;
+    BOOL ret;
+
+    if (!get_clipped_rects( &pdev->dib, rect, clip, &clipped_rects )) return TRUE;
+    ret = brush->rects( pdev, brush, &pdev->dib, clipped_rects.count, clipped_rects.rects,
+                        GetROP2( pdev->dev.hdc ));
+    free_clipped_rects( &clipped_rects );
+    return ret;
+}
+
 /* paint a region with the brush (note: the region can be modified) */
 static BOOL brush_region( dibdrv_physdev *pdev, HRGN region )
 {
     if (pdev->clip) CombineRgn( region, region, pdev->clip, RGN_AND );
-    return brush_rect( pdev, &pdev->brush, NULL, region, GetROP2( pdev->dev.hdc ));
+    return brush_rect( pdev, &pdev->brush, NULL, region );
 }
 
 /* paint a region with the pen (note: the region can be modified) */
 static BOOL pen_region( dibdrv_physdev *pdev, HRGN region )
 {
     if (pdev->clip) CombineRgn( region, region, pdev->clip, RGN_AND );
-    return brush_rect( pdev, &pdev->pen_brush, NULL, region, GetROP2( pdev->dev.hdc ));
+    return brush_rect( pdev, &pdev->pen_brush, NULL, region );
 }
 
 static RECT get_device_rect( HDC hdc, int left, int top, int right, int bottom, BOOL rtl_correction )
@@ -916,11 +928,34 @@ static inline INT get_rop2_from_rop(INT rop)
 BOOL dibdrv_PatBlt( PHYSDEV dev, struct bitblt_coords *dst, DWORD rop )
 {
     dibdrv_physdev *pdev = get_dibdrv_pdev(dev);
+    dib_brush *brush = &pdev->brush;
+    int rop2 = get_rop2_from_rop( rop );
+    struct clipped_rects clipped_rects;
+    DWORD and = 0, xor = 0;
+    BOOL ret = TRUE;
 
     TRACE("(%p, %d, %d, %d, %d, %06x)\n", dev, dst->x, dst->y, dst->width, dst->height, rop);
 
     add_clipped_bounds( pdev, &dst->visrect, 0 );
-    return brush_rect( pdev, &pdev->brush, &dst->visrect, pdev->clip, get_rop2_from_rop(rop) );
+    if (!get_clipped_rects( &pdev->dib, &dst->visrect, pdev->clip, &clipped_rects )) return TRUE;
+
+    switch (rop2)  /* shortcuts for rops that don't involve the brush */
+    {
+    case R2_NOT:   and = ~0u;
+        /* fall through */
+    case R2_WHITE: xor = ~0u;
+        /* fall through */
+    case R2_BLACK:
+        pdev->dib.funcs->solid_rects( &pdev->dib, clipped_rects.count, clipped_rects.rects, and, xor );
+        /* fall through */
+    case R2_NOP:
+        break;
+    default:
+        ret = brush->rects( pdev, brush, &pdev->dib, clipped_rects.count, clipped_rects.rects, rop2 );
+        break;
+    }
+    free_clipped_rects( &clipped_rects );
+    return ret;
 }
 
 /***********************************************************************
@@ -945,7 +980,7 @@ BOOL dibdrv_PaintRgn( PHYSDEV dev, HRGN rgn )
         rect = get_device_rect( dev->hdc, region->rects[i].left, region->rects[i].top,
                                 region->rects[i].right, region->rects[i].bottom, FALSE );
         add_bounds_rect( &bounds, &rect );
-        brush_rect( pdev, &pdev->brush, &rect, pdev->clip, GetROP2( dev->hdc ) );
+        brush_rect( pdev, &pdev->brush, &rect, pdev->clip );
     }
 
     release_wine_region( rgn );
@@ -1142,7 +1177,7 @@ BOOL dibdrv_Rectangle( PHYSDEV dev, INT left, INT top, INT right, INT bottom )
         rect.top    += (pdev->pen_width + 1) / 2;
         rect.right  -= pdev->pen_width / 2;
         rect.bottom -= pdev->pen_width / 2;
-        ret = brush_rect( pdev, &pdev->brush, &rect, pdev->clip, GetROP2(dev->hdc) );
+        ret = brush_rect( pdev, &pdev->brush, &rect, pdev->clip );
     }
     return ret;
 }
diff --git a/dlls/gdi32/dibdrv/objects.c b/dlls/gdi32/dibdrv/objects.c
index 35164e6..b3f058d 100644
--- a/dlls/gdi32/dibdrv/objects.c
+++ b/dlls/gdi32/dibdrv/objects.c
@@ -1991,6 +1991,10 @@ static BOOL pattern_brush(dibdrv_physdev *pdev, dib_brush *brush, dib_info *dib,
 static BOOL null_brush(dibdrv_physdev *pdev, dib_brush *brush, dib_info *dib,
                        int num, const RECT *rects, INT rop)
 {
+    if (rop == 1)
+    {
+        ERR("(%p, %s, BLACKNESS)\n", pdev, wine_dbgstr_rect(rects));
+    }
     return TRUE;
 }
 
@@ -2175,14 +2179,3 @@ COLORREF dibdrv_SetDCBrushColor( PHYSDEV dev, COLORREF color )
     }
     return color;
 }
-
-BOOL brush_rect(dibdrv_physdev *pdev, dib_brush *brush, const RECT *rect, HRGN clip, INT rop)
-{
-    struct clipped_rects clipped_rects;
-    BOOL ret;
-
-    if (!get_clipped_rects( &pdev->dib, rect, clip, &clipped_rects )) return TRUE;
-    ret = brush->rects( pdev, brush, &pdev->dib, clipped_rects.count, clipped_rects.rects, rop );
-    free_clipped_rects( &clipped_rects );
-    return ret;
-}




More information about the wine-cvs mailing list