diff --git a/dlls/gdi32/dibdrv/dc.c b/dlls/gdi32/dibdrv/dc.c index a33c488d271..24ec66ae8ca 100644 --- a/dlls/gdi32/dibdrv/dc.c +++ b/dlls/gdi32/dibdrv/dc.c @@ -259,13 +259,11 @@ DWORD convert_bitmapinfo( const BITMAPINFO *src_info, void *src_bits, struct bit static void update_fg_colors( dibdrv_physdev *pdev ) { - pdev->pen_color = get_pixel_color( pdev, pdev->pen_colorref, TRUE ); pdev->text_color = get_pixel_color( pdev, GetTextColor( pdev->dev.hdc ), TRUE ); } 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 ); diff --git a/dlls/gdi32/dibdrv/dibdrv.h b/dlls/gdi32/dibdrv/dibdrv.h index b0966afaccf..4b02d29c10e 100644 --- a/dlls/gdi32/dibdrv/dibdrv.h +++ b/dlls/gdi32/dibdrv/dibdrv.h @@ -83,10 +83,11 @@ typedef struct dibdrv_physdev /* pen */ COLORREF pen_colorref; - DWORD pen_color, pen_and, pen_xor, pen_endcap, pen_join; + DWORD pen_endcap, pen_join; int pen_width; dash_pattern pen_pattern; dash_pos dash_pos; + rop_mask dash_masks[2]; BOOL (* pen_lines)(struct dibdrv_physdev *pdev, int num, POINT *pts, BOOL close); /* brush */ diff --git a/dlls/gdi32/dibdrv/objects.c b/dlls/gdi32/dibdrv/objects.c index 084d447e25b..6e316694c02 100644 --- a/dlls/gdi32/dibdrv/objects.c +++ b/dlls/gdi32/dibdrv/objects.c @@ -192,7 +192,7 @@ DWORD get_pixel_color( dibdrv_physdev *pdev, COLORREF color, BOOL mono_fixup ) * this makes pdev->bkgnd_color unusable. So here we take the inverse * of the relevant fg color (which is always set up correctly). */ -static inline void get_pen_bkgnd_masks(const dibdrv_physdev *pdev, DWORD *and, DWORD *xor) +static inline void get_pen_bkgnd_masks(dibdrv_physdev *pdev, DWORD *and, DWORD *xor) { if(pdev->dib.bit_count != 1 || GetBkMode(pdev->dev.hdc) == TRANSPARENT) { @@ -201,8 +201,8 @@ static inline void get_pen_bkgnd_masks(const dibdrv_physdev *pdev, DWORD *and, D } else { - DWORD color = ~pdev->pen_color; - if(pdev->pen_colorref == GetBkColor(pdev->dev.hdc)) color = pdev->pen_color; + DWORD color = get_pixel_color( pdev, pdev->pen_colorref, TRUE ); + if(pdev->pen_colorref != GetBkColor(pdev->dev.hdc)) color = !color; calc_and_xor_masks( GetROP2(pdev->dev.hdc), color, and, xor ); } } @@ -552,7 +552,7 @@ static void bres_line_with_bias(const POINT *start, const struct line_params *pa } } -static BOOL solid_pen_line(dibdrv_physdev *pdev, POINT *start, POINT *end) +static BOOL solid_pen_line(dibdrv_physdev *pdev, POINT *start, POINT *end, DWORD and, DWORD xor) { const WINEREGION *clip = get_wine_region(pdev->clip); @@ -573,7 +573,7 @@ static BOOL solid_pen_line(dibdrv_physdev *pdev, POINT *start, POINT *end) /* Optimize the unclipped case */ if(clip->rects[i].left <= rect.left && clip->rects[i].right >= rect.right) { - pdev->dib.funcs->solid_rects(&pdev->dib, 1, &rect, pdev->pen_and, pdev->pen_xor); + pdev->dib.funcs->solid_rects(&pdev->dib, 1, &rect, and, xor); break; } if(clip->rects[i].right > rect.left && clip->rects[i].left < rect.right) @@ -581,7 +581,7 @@ static BOOL solid_pen_line(dibdrv_physdev *pdev, POINT *start, POINT *end) RECT tmp = rect; tmp.left = max(rect.left, clip->rects[i].left); tmp.right = min(rect.right, clip->rects[i].right); - pdev->dib.funcs->solid_rects(&pdev->dib, 1, &tmp, pdev->pen_and, pdev->pen_xor); + pdev->dib.funcs->solid_rects(&pdev->dib, 1, &tmp, and, xor); } } } @@ -601,7 +601,7 @@ static BOOL solid_pen_line(dibdrv_physdev *pdev, POINT *start, POINT *end) if(clip->rects[i].top <= rect.top && clip->rects[i].bottom >= rect.bottom && clip->rects[i].left <= rect.left && clip->rects[i].right >= rect.right) { - pdev->dib.funcs->solid_rects(&pdev->dib, 1, &rect, pdev->pen_and, pdev->pen_xor); + pdev->dib.funcs->solid_rects(&pdev->dib, 1, &rect, and, xor); break; } if(clip->rects[i].top >= rect.bottom) break; @@ -611,7 +611,7 @@ static BOOL solid_pen_line(dibdrv_physdev *pdev, POINT *start, POINT *end) RECT tmp = rect; tmp.top = max(rect.top, clip->rects[i].top); tmp.bottom = min(rect.bottom, clip->rects[i].bottom); - pdev->dib.funcs->solid_rects(&pdev->dib, 1, &tmp, pdev->pen_and, pdev->pen_xor); + pdev->dib.funcs->solid_rects(&pdev->dib, 1, &tmp, and, xor); } } } @@ -668,8 +668,7 @@ static BOOL solid_pen_line(dibdrv_physdev *pdev, POINT *start, POINT *end) if (clipped_end.x == end->x && clipped_end.y == end->y) line_params.length--; - pdev->dib.funcs->solid_line( &pdev->dib, &clipped_start, &line_params, - pdev->pen_and, pdev->pen_xor ); + pdev->dib.funcs->solid_line( &pdev->dib, &clipped_start, &line_params, and, xor ); if(clip_status == 2) break; /* completely unclipped, so we can finish */ } @@ -683,13 +682,17 @@ static BOOL solid_pen_line(dibdrv_physdev *pdev, POINT *start, POINT *end) static BOOL solid_pen_lines(dibdrv_physdev *pdev, int num, POINT *pts, BOOL close) { int i; + DWORD color, and, xor; + + color = get_pixel_color( pdev, pdev->pen_colorref, TRUE ); + calc_and_xor_masks( GetROP2(pdev->dev.hdc), color, &and, &xor ); assert( num >= 2 ); for (i = 0; i < num - 1; i++) - if (!solid_pen_line( pdev, pts + i, pts + i + 1 )) + if (!solid_pen_line( pdev, pts + i, pts + i + 1, and, xor )) return FALSE; - if (close) return solid_pen_line( pdev, pts + num - 1, pts ); + if (close) return solid_pen_line( pdev, pts + num - 1, pts, and, xor ); return TRUE; } @@ -719,38 +722,23 @@ static inline void skip_dash(dibdrv_physdev *pdev, unsigned int skip) } } -static inline void get_dash_colors(const dibdrv_physdev *pdev, DWORD *and, DWORD *xor) -{ - if(pdev->dash_pos.mark) - { - *and = pdev->pen_and; - *xor = pdev->pen_xor; - } - else /* space */ - { - get_pen_bkgnd_masks( pdev, and, xor ); - } -} - static void dashed_pen_line_callback(dibdrv_physdev *pdev, INT x, INT y) { RECT rect; - DWORD and, xor; + rop_mask mask = pdev->dash_masks[pdev->dash_pos.mark]; - get_dash_colors(pdev, &and, &xor); skip_dash(pdev, 1); rect.left = x; rect.right = x + 1; rect.top = y; rect.bottom = y + 1; - pdev->dib.funcs->solid_rects(&pdev->dib, 1, &rect, and, xor); + pdev->dib.funcs->solid_rects(&pdev->dib, 1, &rect, mask.and, mask.xor); return; } static BOOL dashed_pen_line(dibdrv_physdev *pdev, POINT *start, POINT *end) { const WINEREGION *clip = get_wine_region(pdev->clip); - DWORD and, xor; int i, dash_len; RECT rect; const dash_pos start_pos = pdev->dash_pos; @@ -796,14 +784,14 @@ static BOOL dashed_pen_line(dibdrv_physdev *pdev, POINT *start, POINT *end) while(cur_x <= clipped_right) { - get_dash_colors(pdev, &and, &xor); + rop_mask mask = pdev->dash_masks[pdev->dash_pos.mark]; dash_len = pdev->dash_pos.left_in_dash; if(cur_x + dash_len > clipped_right + 1) dash_len = clipped_right - cur_x + 1; rect.left = cur_x; rect.right = cur_x + dash_len; - pdev->dib.funcs->solid_rects(&pdev->dib, 1, &rect, and, xor); + pdev->dib.funcs->solid_rects(&pdev->dib, 1, &rect, mask.and, mask.xor); cur_x += dash_len; skip_dash(pdev, dash_len); } @@ -816,14 +804,14 @@ static BOOL dashed_pen_line(dibdrv_physdev *pdev, POINT *start, POINT *end) while(cur_x >= clipped_left) { - get_dash_colors(pdev, &and, &xor); + rop_mask mask = pdev->dash_masks[pdev->dash_pos.mark]; dash_len = pdev->dash_pos.left_in_dash; if(cur_x - dash_len < clipped_left - 1) dash_len = cur_x - clipped_left + 1; rect.left = cur_x - dash_len + 1; rect.right = cur_x + 1; - pdev->dib.funcs->solid_rects(&pdev->dib, 1, &rect, and, xor); + pdev->dib.funcs->solid_rects(&pdev->dib, 1, &rect, mask.and, mask.xor); cur_x -= dash_len; skip_dash(pdev, dash_len); } @@ -873,14 +861,14 @@ static BOOL dashed_pen_line(dibdrv_physdev *pdev, POINT *start, POINT *end) while(cur_y <= clipped_bottom) { - get_dash_colors(pdev, &and, &xor); + rop_mask mask = pdev->dash_masks[pdev->dash_pos.mark]; dash_len = pdev->dash_pos.left_in_dash; if(cur_y + dash_len > clipped_bottom + 1) dash_len = clipped_bottom - cur_y + 1; rect.top = cur_y; rect.bottom = cur_y + dash_len; - pdev->dib.funcs->solid_rects(&pdev->dib, 1, &rect, and, xor); + pdev->dib.funcs->solid_rects(&pdev->dib, 1, &rect, mask.and, mask.xor); cur_y += dash_len; skip_dash(pdev, dash_len); } @@ -893,14 +881,14 @@ static BOOL dashed_pen_line(dibdrv_physdev *pdev, POINT *start, POINT *end) while(cur_y >= clipped_top) { - get_dash_colors(pdev, &and, &xor); + rop_mask mask = pdev->dash_masks[pdev->dash_pos.mark]; dash_len = pdev->dash_pos.left_in_dash; if(cur_y - dash_len < clipped_top - 1) dash_len = cur_y - clipped_top + 1; rect.top = cur_y - dash_len + 1; rect.bottom = cur_y + 1; - pdev->dib.funcs->solid_rects(&pdev->dib, 1, &rect, and, xor); + pdev->dib.funcs->solid_rects(&pdev->dib, 1, &rect, mask.and, mask.xor); cur_y -= dash_len; skip_dash(pdev, dash_len); } @@ -985,6 +973,12 @@ static BOOL dashed_pen_line(dibdrv_physdev *pdev, POINT *start, POINT *end) static BOOL dashed_pen_lines(dibdrv_physdev *pdev, int num, POINT *pts, BOOL close) { int i; + DWORD color; + + color = get_pixel_color( pdev, pdev->pen_colorref, TRUE ); + get_pen_bkgnd_masks( pdev, &pdev->dash_masks[0].and, &pdev->dash_masks[0].xor ); + calc_and_xor_masks( GetROP2(pdev->dev.hdc), color, + &pdev->dash_masks[1].and, &pdev->dash_masks[1].xor ); assert( num >= 2 ); for (i = 0; i < num - 1; i++) @@ -1282,9 +1276,9 @@ static BOOL wide_pen_lines(dibdrv_physdev *pdev, int num, POINT *pts, BOOL close const WINEREGION *data; rop_mask color; HRGN region; + DWORD pen_color = get_pixel_color( pdev, pdev->pen_colorref, TRUE ); - color.and = pdev->pen_and; - color.xor = pdev->pen_xor; + calc_and_xor_masks( GetROP2(pdev->dev.hdc), pen_color, &color.and, &color.xor ); region = get_wide_lines_region( pdev, num, pts, close ); @@ -1363,9 +1357,6 @@ HPEN dibdrv_SelectPen( PHYSDEV dev, HPEN hpen ) logpen.lopnColor = GetDCPenColor( dev->hdc ); pdev->pen_colorref = logpen.lopnColor; - pdev->pen_color = get_pixel_color( pdev, pdev->pen_colorref, TRUE ); - calc_and_xor_masks(GetROP2(dev->hdc), pdev->pen_color, &pdev->pen_and, &pdev->pen_xor); - pdev->pen_pattern = dash_patterns[PS_SOLID]; pdev->defer |= DEFER_PEN; @@ -1414,11 +1405,7 @@ COLORREF dibdrv_SetDCPenColor( PHYSDEV dev, COLORREF color ) dibdrv_physdev *pdev = get_dibdrv_pdev(dev); if (GetCurrentObject(dev->hdc, OBJ_PEN) == GetStockObject( DC_PEN )) - { pdev->pen_colorref = color; - pdev->pen_color = get_pixel_color( pdev, pdev->pen_colorref, TRUE ); - calc_and_xor_masks(GetROP2(dev->hdc), pdev->pen_color, &pdev->pen_and, &pdev->pen_xor); - } return next->funcs->pSetDCPenColor( next, color ); }