From c5f41f89f33a630289bc752684f84857d3d6cf03 Mon Sep 17 00:00:00 2001 From: Huw Davies Date: Thu, 2 Jun 2011 12:22:02 +0100 Subject: [PATCH] gdi32: Update pixel colours when the colour table changes. --- dlls/gdi32/dibdrv/dc.c | 38 ++++++++++++++++++++++++++++++++----- dlls/gdi32/dibdrv/objects.c | 4 ++++ dlls/gdi32/gdi_private.h | 2 ++ 3 files changed, 39 insertions(+), 5 deletions(-) diff --git a/dlls/gdi32/dibdrv/dc.c b/dlls/gdi32/dibdrv/dc.c index 8bdb60dd968..6a384800c26 100644 --- a/dlls/gdi32/dibdrv/dc.c +++ b/dlls/gdi32/dibdrv/dc.c @@ -357,6 +357,37 @@ static void CDECL dibdrv_SetDeviceClipping( PHYSDEV dev, HRGN vis_rgn, HRGN clip return next->funcs->pSetDeviceClipping( next, vis_rgn, clip_rgn); } +static void update_masks( dibdrv_physdev *pdev, INT rop ) +{ + calc_and_xor_masks( rop, pdev->pen_color, &pdev->pen_and, &pdev->pen_xor ); + update_brush_rop( pdev, rop ); + if( GetBkMode( pdev->dev.hdc ) == OPAQUE ) + calc_and_xor_masks( rop, pdev->bkgnd_color, &pdev->bkgnd_and, &pdev->bkgnd_xor ); +} + +/*********************************************************************** + * dibdrv_SetDIBColorTable + */ +static UINT CDECL dibdrv_SetDIBColorTable( PHYSDEV dev, UINT pos, UINT count, const RGBQUAD *colors ) +{ + PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetDIBColorTable ); + dibdrv_physdev *pdev = get_dibdrv_pdev(dev); + TRACE("(%p, %d, %d, %p)\n", dev, pos, count, colors); + + if( pdev->dib.color_table && pos < pdev->dib.color_table_size ) + { + if( pos + count > pdev->dib.color_table_size ) count = pdev->dib.color_table_size - pos; + memcpy( pdev->dib.color_table + pos, colors, count * sizeof(RGBQUAD) ); + + pdev->pen_color = pdev->dib.funcs->colorref_to_pixel( &pdev->dib, pdev->pen_colorref ); + pdev->brush_color = pdev->dib.funcs->colorref_to_pixel( &pdev->dib, pdev->brush_colorref ); + pdev->bkgnd_color = pdev->dib.funcs->colorref_to_pixel( &pdev->dib, GetBkColor( dev->hdc ) ); + + update_masks( pdev, GetROP2( dev->hdc ) ); + } + return next->funcs->pSetDIBColorTable( next, pos, count, colors ); +} + /*********************************************************************** * dibdrv_SetROP2 */ @@ -365,10 +396,7 @@ static INT CDECL dibdrv_SetROP2( PHYSDEV dev, INT rop ) PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetROP2 ); 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); - if( GetBkMode(dev->hdc) == OPAQUE ) - calc_and_xor_masks(rop, pdev->bkgnd_color, &pdev->bkgnd_and, &pdev->bkgnd_xor); + update_masks( pdev, rop ); return next->funcs->pSetROP2( next, rop ); } @@ -462,7 +490,7 @@ const DC_FUNCTIONS dib_driver = dibdrv_SetBkMode, /* pSetBkMode */ dibdrv_SetDCBrushColor, /* pSetDCBrushColor */ dibdrv_SetDCPenColor, /* pSetDCPenColor */ - NULL, /* pSetDIBColorTable */ + dibdrv_SetDIBColorTable, /* pSetDIBColorTable */ NULL, /* pSetDIBits */ NULL, /* pSetDIBitsToDevice */ dibdrv_SetDeviceClipping, /* pSetDeviceClipping */ diff --git a/dlls/gdi32/dibdrv/objects.c b/dlls/gdi32/dibdrv/objects.c index ce6e7104c6b..381cc39eced 100644 --- a/dlls/gdi32/dibdrv/objects.c +++ b/dlls/gdi32/dibdrv/objects.c @@ -868,6 +868,7 @@ HPEN CDECL dibdrv_SelectPen( PHYSDEV dev, HPEN hpen ) if (hpen == GetStockObject( DC_PEN )) logpen.lopnColor = GetDCPenColor( dev->hdc ); + pdev->pen_colorref = logpen.lopnColor; pdev->pen_color = pdev->dib.funcs->colorref_to_pixel(&pdev->dib, logpen.lopnColor); calc_and_xor_masks(GetROP2(dev->hdc), pdev->pen_color, &pdev->pen_and, &pdev->pen_xor); @@ -919,6 +920,7 @@ COLORREF CDECL dibdrv_SetDCPenColor( PHYSDEV dev, COLORREF color ) if (GetCurrentObject(dev->hdc, OBJ_PEN) == GetStockObject( DC_PEN )) { + pdev->pen_colorref = color; pdev->pen_color = pdev->dib.funcs->colorref_to_pixel(&pdev->dib, color); calc_and_xor_masks(GetROP2(dev->hdc), pdev->pen_color, &pdev->pen_and, &pdev->pen_xor); } @@ -1102,6 +1104,7 @@ HBRUSH CDECL dibdrv_SelectBrush( PHYSDEV dev, HBRUSH hbrush ) switch(logbrush.lbStyle) { case BS_SOLID: + pdev->brush_colorref = logbrush.lbColor; 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; @@ -1152,6 +1155,7 @@ COLORREF CDECL dibdrv_SetDCBrushColor( PHYSDEV dev, COLORREF color ) if (GetCurrentObject(dev->hdc, OBJ_BRUSH) == GetStockObject( DC_BRUSH )) { + pdev->brush_colorref = color; 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); } diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h index 9a188eef34e..7d1240b1197 100644 --- a/dlls/gdi32/gdi_private.h +++ b/dlls/gdi32/gdi_private.h @@ -118,6 +118,7 @@ typedef struct dibdrv_physdev DWORD defer; /* pen */ + COLORREF pen_colorref; DWORD pen_color, pen_and, pen_xor; dash_pattern pen_pattern; dash_pos dash_pos; @@ -126,6 +127,7 @@ typedef struct dibdrv_physdev /* brush */ UINT brush_style; INT brush_rop; /* PatBlt, for example, can override the DC's rop2 */ + COLORREF brush_colorref; DWORD brush_color, brush_and, brush_xor; dib_info brush_dib; void *brush_and_bits, *brush_xor_bits;