gdi32: Calculate AND and XOR masks corresponding to the current pen colour and rop2.

This commit is contained in:
Huw Davies 2011-04-07 13:48:39 +01:00 committed by Alexandre Julliard
parent 15ef394159
commit d5d4603062
4 changed files with 85 additions and 2 deletions

View file

@ -128,6 +128,19 @@ static HBITMAP CDECL dibdrv_SelectBitmap( PHYSDEV dev, HBITMAP bitmap )
return next->funcs->pSelectBitmap( next, bitmap );
}
/***********************************************************************
* dibdrv_SetROP2
*/
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);
return next->funcs->pSetROP2( next, rop );
}
const DC_FUNCTIONS dib_driver =
{
NULL, /* pAbortDoc */
@ -228,7 +241,7 @@ const DC_FUNCTIONS dib_driver =
NULL, /* pSetPixel */
NULL, /* pSetPixelFormat */
NULL, /* pSetPolyFillMode */
NULL, /* pSetROP2 */
dibdrv_SetROP2, /* pSetROP2 */
NULL, /* pSetRelAbs */
NULL, /* pSetStretchBltMode */
NULL, /* pSetTextAlign */

View file

@ -35,3 +35,5 @@ typedef struct primitive_funcs
extern const primitive_funcs funcs_8888 DECLSPEC_HIDDEN;
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;

View file

@ -25,6 +25,70 @@
WINE_DEFAULT_DEBUG_CHANNEL(dib);
/*
*
* Decompose the 16 ROP2s into an expression of the form
*
* D = (D & A) ^ X
*
* Where A and X depend only on P (and so can be precomputed).
*
* A X
*
* R2_BLACK 0 0 0
* R2_NOTMERGEPEN ~(D | P) ~P ~P
* R2_MASKNOTPEN ~P & D ~P 0
* R2_NOTCOPYPEN ~P 0 ~P
* R2_MASKPENNOT P & ~D P P
* R2_NOT ~D 1 1
* R2_XORPEN P ^ D 1 P
* R2_NOTMASKPEN ~(P & D) P 1
* R2_MASKPEN P & D P 0
* R2_NOTXORPEN ~(P ^ D) 1 ~P
* R2_NOP D 1 0
* R2_MERGENOTPEN ~P | D P ~P
* R2_COPYPEN P 0 P
* R2_MERGEPENNOT P | ~D ~P 1
* R2_MERGEPEN P | D ~P P
* R2_WHITE 1 0 1
*
*/
/* A = (P & A1) | (~P & A2) */
#define ZERO {0, 0}
#define ONE {0xffffffff, 0xffffffff}
#define P {0xffffffff, 0}
#define NOT_P {0, 0xffffffff}
static const DWORD rop2_and_array[16][2] =
{
ZERO, NOT_P, NOT_P, ZERO,
P, ONE, ONE, P,
P, ONE, ONE, P,
ZERO, NOT_P, NOT_P, ZERO
};
/* X = (P & X1) | (~P & X2) */
static const DWORD rop2_xor_array[16][2] =
{
ZERO, NOT_P, ZERO, NOT_P,
P, ONE, P, ONE,
ZERO, NOT_P, ZERO, NOT_P,
P, ONE, P, ONE
};
#undef NOT_P
#undef P
#undef ONE
#undef ZERO
void calc_and_xor_masks(INT rop, DWORD color, DWORD *and, DWORD *xor)
{
/* NB The ROP2 codes start at one and the arrays are zero-based */
*and = (color & rop2_and_array[rop-1][0]) | ((~color) & rop2_and_array[rop-1][1]);
*xor = (color & rop2_xor_array[rop-1][0]) | ((~color) & rop2_xor_array[rop-1][1]);
}
/***********************************************************************
* dibdrv_SelectPen
*/
@ -60,6 +124,7 @@ HPEN CDECL dibdrv_SelectPen( PHYSDEV dev, HPEN hpen )
logpen.lopnColor = GetDCPenColor( dev->hdc );
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);
pdev->defer |= DEFER_PEN;
@ -86,7 +151,10 @@ COLORREF CDECL dibdrv_SetDCPenColor( PHYSDEV dev, COLORREF color )
dibdrv_physdev *pdev = get_dibdrv_pdev(dev);
if (GetCurrentObject(dev->hdc, OBJ_PEN) == GetStockObject( DC_PEN ))
{
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);
}
return next->funcs->pSetDCPenColor( next, color );
}

View file

@ -100,7 +100,7 @@ typedef struct dibdrv_physdev
DWORD defer;
/* pen */
DWORD pen_color;
DWORD pen_color, pen_and, pen_xor;
} dibdrv_physdev;
#define DEFER_FORMAT 1