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