mirror of
git://source.winehq.org/git/wine.git
synced 2024-11-05 18:01:34 +00:00
gdi32: Calculate AND and XOR masks corresponding to the current pen colour and rop2.
This commit is contained in:
parent
15ef394159
commit
d5d4603062
4 changed files with 85 additions and 2 deletions
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue