Huw Davies : gdi32: Implement PatBlt.

Alexandre Julliard julliard at winehq.org
Mon Apr 11 13:29:29 CDT 2011


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

Author: Huw Davies <huw at 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;
+}




More information about the wine-cvs mailing list