gdi32: Implement SelectBrush for solid brushes.

This commit is contained in:
Huw Davies 2011-04-11 10:00:28 +01:00 committed by Alexandre Julliard
parent bceb274c94
commit 44f530275a
5 changed files with 106 additions and 3 deletions

View file

@ -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 */

View file

@ -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);
}

View file

@ -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;

View file

@ -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 );
}

View file

@ -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
{