Huw Davies : gdi32: Implement SelectBrush for solid brushes.

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


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

Author: Huw Davies <huw at codeweavers.com>
Date:   Mon Apr 11 10:00:28 2011 +0100

gdi32: Implement SelectBrush for solid brushes.

---

 dlls/gdi32/dibdrv/dc.c       |    5 ++-
 dlls/gdi32/dibdrv/dibdrv.h   |   13 +++++++
 dlls/gdi32/dibdrv/graphics.c |    2 +-
 dlls/gdi32/dibdrv/objects.c  |   83 ++++++++++++++++++++++++++++++++++++++++++
 dlls/gdi32/gdi_private.h     |    6 +++
 5 files changed, 106 insertions(+), 3 deletions(-)

diff --git a/dlls/gdi32/dibdrv/dc.c b/dlls/gdi32/dibdrv/dc.c
index 78248dd..9c2aca4 100644
--- a/dlls/gdi32/dibdrv/dc.c
+++ b/dlls/gdi32/dibdrv/dc.c
@@ -137,6 +137,7 @@ static INT CDECL dibdrv_SetROP2( PHYSDEV dev, INT rop )
     dibdrv_physdev *pdev = get_dibdrv_pdev(dev);
 
     calc_and_xor_masks(rop, pdev->pen_color, &pdev->pen_and, &pdev->pen_xor);
+    update_brush_rop(pdev, rop);
 
     return next->funcs->pSetROP2( next, rop );
 }
@@ -219,7 +220,7 @@ const DC_FUNCTIONS dib_driver =
     NULL,                               /* pScaleViewportExt */
     NULL,                               /* pScaleWindowExt */
     dibdrv_SelectBitmap,                /* pSelectBitmap */
-    NULL,                               /* pSelectBrush */
+    dibdrv_SelectBrush,                 /* pSelectBrush */
     NULL,                               /* pSelectClipPath */
     NULL,                               /* pSelectFont */
     NULL,                               /* pSelectPalette */
@@ -228,7 +229,7 @@ const DC_FUNCTIONS dib_driver =
     NULL,                               /* pSetBitmapBits */
     NULL,                               /* pSetBkColor */
     NULL,                               /* pSetBkMode */
-    NULL,                               /* pSetDCBrushColor */
+    dibdrv_SetDCBrushColor,             /* pSetDCBrushColor */
     dibdrv_SetDCPenColor,               /* pSetDCPenColor */
     NULL,                               /* pSetDIBColorTable */
     NULL,                               /* pSetDIBits */
diff --git a/dlls/gdi32/dibdrv/dibdrv.h b/dlls/gdi32/dibdrv/dibdrv.h
index b7408ac..e62536f 100644
--- a/dlls/gdi32/dibdrv/dibdrv.h
+++ b/dlls/gdi32/dibdrv/dibdrv.h
@@ -19,7 +19,9 @@
  */
 
 extern BOOL     CDECL dibdrv_LineTo( PHYSDEV dev, INT x, INT y ) 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;
 extern COLORREF CDECL dibdrv_SetDCPenColor( PHYSDEV dev, COLORREF color ) DECLSPEC_HIDDEN;
 
 static inline dibdrv_physdev *get_dibdrv_pdev( PHYSDEV dev )
@@ -43,3 +45,14 @@ extern const primitive_funcs funcs_32   DECLSPEC_HIDDEN;
 extern const primitive_funcs funcs_null DECLSPEC_HIDDEN;
 
 extern void calc_and_xor_masks(INT rop, DWORD color, DWORD *and, DWORD *xor) DECLSPEC_HIDDEN;
+extern void update_brush_rop( dibdrv_physdev *pdev, INT rop ) DECLSPEC_HIDDEN;
+
+static inline BOOL defer_pen(dibdrv_physdev *pdev)
+{
+    return pdev->defer & (DEFER_FORMAT | DEFER_PEN);
+}
+
+static inline BOOL defer_brush(dibdrv_physdev *pdev)
+{
+    return pdev->defer & (DEFER_FORMAT | DEFER_BRUSH);
+}
diff --git a/dlls/gdi32/dibdrv/graphics.c b/dlls/gdi32/dibdrv/graphics.c
index 1e0de2f..1b4ccb3 100644
--- a/dlls/gdi32/dibdrv/graphics.c
+++ b/dlls/gdi32/dibdrv/graphics.c
@@ -40,7 +40,7 @@ BOOL CDECL dibdrv_LineTo( PHYSDEV dev, INT x, INT y )
 
     LPtoDP(dev->hdc, pts, 2);
 
-    if(pdev->defer || !pdev->pen_line(pdev, pts, pts + 1))
+    if(defer_pen(pdev) || !pdev->pen_line(pdev, pts, pts + 1))
         return next->funcs->pLineTo( next, x, y );
 
     return TRUE;
diff --git a/dlls/gdi32/dibdrv/objects.c b/dlls/gdi32/dibdrv/objects.c
index a26785a..4ebeee1 100644
--- a/dlls/gdi32/dibdrv/objects.c
+++ b/dlls/gdi32/dibdrv/objects.c
@@ -207,3 +207,86 @@ COLORREF CDECL dibdrv_SetDCPenColor( PHYSDEV dev, COLORREF color )
 
     return next->funcs->pSetDCPenColor( next, color );
 }
+
+/**********************************************************************
+ *             solid_brush
+ *
+ * Fill a number of rectangles with the solid brush
+ * FIXME: Should we insist l < r && t < b?  Currently we assume this.
+ */
+static BOOL solid_brush(dibdrv_physdev *pdev, int num, RECT *rects)
+{
+    int i;
+    DC *dc = get_dibdrv_dc( &pdev->dev );
+
+    if(get_clip_region(dc)) return FALSE;
+
+    for(i = 0; i < num; i++) /* simple clip to extents */
+    {
+        if(rects[i].left   < dc->vis_rect.left)   rects[i].left   = dc->vis_rect.left;
+        if(rects[i].top    < dc->vis_rect.top)    rects[i].top    = dc->vis_rect.top;
+        if(rects[i].right  > dc->vis_rect.right)  rects[i].right  = dc->vis_rect.right;
+        if(rects[i].bottom > dc->vis_rect.bottom) rects[i].bottom = dc->vis_rect.bottom;
+    }
+
+    pdev->dib.funcs->solid_rects(&pdev->dib, num, rects, pdev->brush_and, pdev->brush_xor);
+    return TRUE;
+}
+
+void update_brush_rop( dibdrv_physdev *pdev, INT rop )
+{
+    if(pdev->brush_style == BS_SOLID)
+        calc_and_xor_masks(rop, pdev->brush_color, &pdev->brush_and, &pdev->brush_xor);
+}
+
+/***********************************************************************
+ *           dibdrv_SelectBrush
+ */
+HBRUSH CDECL dibdrv_SelectBrush( PHYSDEV dev, HBRUSH hbrush )
+{
+    PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSelectBrush );
+    dibdrv_physdev *pdev = get_dibdrv_pdev(dev);
+    LOGBRUSH logbrush;
+
+    TRACE("(%p, %p)\n", dev, hbrush);
+
+    if (!GetObjectW( hbrush, sizeof(logbrush), &logbrush )) return 0;
+
+    if (hbrush == GetStockObject( DC_BRUSH ))
+        logbrush.lbColor = GetDCBrushColor( dev->hdc );
+
+    pdev->brush_style = logbrush.lbStyle;
+
+    pdev->defer |= DEFER_BRUSH;
+
+    switch(logbrush.lbStyle)
+    {
+    case BS_SOLID:
+        pdev->brush_color = pdev->dib.funcs->colorref_to_pixel(&pdev->dib, logbrush.lbColor);
+        calc_and_xor_masks(GetROP2(dev->hdc), pdev->brush_color, &pdev->brush_and, &pdev->brush_xor);
+        pdev->brush_rects = solid_brush;
+        pdev->defer &= ~DEFER_BRUSH;
+        break;
+    default:
+        break;
+    }
+
+    return next->funcs->pSelectBrush( next, hbrush );
+}
+
+/***********************************************************************
+ *           dibdrv_SetDCBrushColor
+ */
+COLORREF CDECL dibdrv_SetDCBrushColor( PHYSDEV dev, COLORREF color )
+{
+    PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetDCBrushColor );
+    dibdrv_physdev *pdev = get_dibdrv_pdev(dev);
+
+    if (GetCurrentObject(dev->hdc, OBJ_BRUSH) == GetStockObject( DC_BRUSH ))
+    {
+        pdev->brush_color = pdev->dib.funcs->colorref_to_pixel(&pdev->dib, color);
+        calc_and_xor_masks(GetROP2(dev->hdc), pdev->brush_color, &pdev->brush_and, &pdev->brush_xor);
+    }
+
+    return next->funcs->pSetDCBrushColor( next, color );
+}
diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h
index fc86b32..91f4acb 100644
--- a/dlls/gdi32/gdi_private.h
+++ b/dlls/gdi32/gdi_private.h
@@ -102,10 +102,16 @@ typedef struct dibdrv_physdev
     /* pen */
     DWORD pen_color, pen_and, pen_xor;
     BOOL   (* pen_line)(struct dibdrv_physdev *pdev, POINT *start, POINT *end);
+
+    /* brush */
+    UINT brush_style;
+    DWORD brush_color, brush_and, brush_xor;
+    BOOL   (* brush_rects)(struct dibdrv_physdev *pdev, int num, RECT *rects);
 } dibdrv_physdev;
 
 #define DEFER_FORMAT     1
 #define DEFER_PEN        2
+#define DEFER_BRUSH      4
 
 typedef struct tagDC_FUNCS
 {




More information about the wine-cvs mailing list