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