Module: wine Branch: master Commit: 91ff1440184eb57fa7cdfc9b1ed998eeb32685d0 URL: http://source.winehq.org/git/wine.git/?a=commit;h=91ff1440184eb57fa7cdfc9b1e...
Author: Huw Davies huw@codeweavers.com Date: Mon Apr 11 10:07:12 2011 +0100
gdi32: Implement PatBlt.
---
dlls/gdi32/dibdrv/dc.c | 2 +- dlls/gdi32/dibdrv/dibdrv.h | 1 + dlls/gdi32/dibdrv/graphics.c | 70 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 1 deletions(-)
diff --git a/dlls/gdi32/dibdrv/dc.c b/dlls/gdi32/dibdrv/dc.c index 9c2aca4..d784c94 100644 --- a/dlls/gdi32/dibdrv/dc.c +++ b/dlls/gdi32/dibdrv/dc.c @@ -200,7 +200,7 @@ const DC_FUNCTIONS dib_driver = NULL, /* pOffsetViewportOrg */ NULL, /* pOffsetWindowOrg */ NULL, /* pPaintRgn */ - NULL, /* pPatBlt */ + dibdrv_PatBlt, /* pPatBlt */ NULL, /* pPie */ NULL, /* pPolyBezier */ NULL, /* pPolyBezierTo */ diff --git a/dlls/gdi32/dibdrv/dibdrv.h b/dlls/gdi32/dibdrv/dibdrv.h index e62536f..c6cdd62 100644 --- a/dlls/gdi32/dibdrv/dibdrv.h +++ b/dlls/gdi32/dibdrv/dibdrv.h @@ -19,6 +19,7 @@ */
extern BOOL CDECL dibdrv_LineTo( PHYSDEV dev, INT x, INT y ) DECLSPEC_HIDDEN; +extern BOOL CDECL dibdrv_PatBlt( PHYSDEV dev, INT x, INT y, INT width, INT height, DWORD rop ) DECLSPEC_HIDDEN; extern HBRUSH CDECL dibdrv_SelectBrush( PHYSDEV dev, HBRUSH hbrush ) DECLSPEC_HIDDEN; extern HPEN CDECL dibdrv_SelectPen( PHYSDEV dev, HPEN hpen ) DECLSPEC_HIDDEN; extern COLORREF CDECL dibdrv_SetDCBrushColor( PHYSDEV dev, COLORREF color ) DECLSPEC_HIDDEN; diff --git a/dlls/gdi32/dibdrv/graphics.c b/dlls/gdi32/dibdrv/graphics.c index 1b4ccb3..7d0f2e9 100644 --- a/dlls/gdi32/dibdrv/graphics.c +++ b/dlls/gdi32/dibdrv/graphics.c @@ -25,6 +25,37 @@
WINE_DEFAULT_DEBUG_CHANNEL(dib);
+static RECT get_device_rect( HDC hdc, int left, int top, int right, int bottom ) +{ + RECT rect; + + rect.left = left; + rect.top = top; + rect.right = right; + rect.bottom = bottom; + if (GetLayout( hdc ) & LAYOUT_RTL) + { + /* shift the rectangle so that the right border is included after mirroring */ + /* it would be more correct to do this after LPtoDP but that's not what Windows does */ + rect.left--; + rect.right--; + } + LPtoDP( hdc, (POINT *)&rect, 2 ); + if (rect.left > rect.right) + { + int tmp = rect.left; + rect.left = rect.right; + rect.right = tmp; + } + if (rect.top > rect.bottom) + { + int tmp = rect.top; + rect.top = rect.bottom; + rect.bottom = tmp; + } + return rect; +} + /*********************************************************************** * dibdrv_LineTo */ @@ -45,3 +76,42 @@ BOOL CDECL dibdrv_LineTo( PHYSDEV dev, INT x, INT y )
return TRUE; } + +/*********************************************************************** + * get_rop2_from_rop + * + * Returns the binary rop that is equivalent to the provided ternary rop + * if the src bits are ignored. + */ +static inline INT get_rop2_from_rop(INT rop) +{ + return (((rop >> 18) & 0x0c) | ((rop >> 16) & 0x03)) + 1; +} + +/*********************************************************************** + * dibdrv_PatBlt + */ +BOOL CDECL dibdrv_PatBlt( PHYSDEV dev, INT x, INT y, INT width, INT height, DWORD rop ) +{ + PHYSDEV next = GET_NEXT_PHYSDEV( dev, pPatBlt ); + dibdrv_physdev *pdev = get_dibdrv_pdev(dev); + INT rop2 = get_rop2_from_rop(rop); + RECT rect = get_device_rect( dev->hdc, x, y, x + width, y + height ); + BOOL done; + + TRACE("(%p, %d, %d, %d, %d, %06x)\n", dev, x, y, width, height, rop); + + if(defer_brush(pdev)) + return next->funcs->pPatBlt( next, x, y, width, height, rop ); + + update_brush_rop( pdev, rop2 ); + + done = pdev->brush_rects( pdev, 1, &rect ); + + update_brush_rop( pdev, GetROP2(dev->hdc) ); + + if(!done) + return next->funcs->pPatBlt( next, x, y, width, height, rop ); + + return TRUE; +}