From 6e325afaa78f2037521e899838be91fa1dc35a16 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Wed, 10 Oct 2012 17:19:42 +0200 Subject: [PATCH] gdi32: Handle a missing source alpha directly in the blend_rect primitive instead of modifying the source data. --- dlls/gdi32/bitblt.c | 8 ++++---- dlls/gdi32/dib.c | 8 ++++---- dlls/gdi32/dibdrv/dc.c | 14 +------------- dlls/gdi32/dibdrv/primitives.c | 14 +++++++++++++- dlls/gdi32/gdi_private.h | 4 ++-- 5 files changed, 24 insertions(+), 24 deletions(-) diff --git a/dlls/gdi32/bitblt.c b/dlls/gdi32/bitblt.c index ea6d8a79279..4750d1b1e3f 100644 --- a/dlls/gdi32/bitblt.c +++ b/dlls/gdi32/bitblt.c @@ -158,7 +158,7 @@ void free_heap_bits( struct gdi_image_bits *bits ) } DWORD convert_bits( const BITMAPINFO *src_info, struct bitblt_coords *src, - BITMAPINFO *dst_info, struct gdi_image_bits *bits, BOOL add_alpha ) + BITMAPINFO *dst_info, struct gdi_image_bits *bits ) { void *ptr; DWORD err; @@ -172,7 +172,7 @@ DWORD convert_bits( const BITMAPINFO *src_info, struct bitblt_coords *src, if (!(ptr = HeapAlloc( GetProcessHeap(), 0, dst_info->bmiHeader.biSizeImage ))) return ERROR_OUTOFMEMORY; - err = convert_bitmapinfo( src_info, bits->ptr, src, dst_info, ptr, add_alpha ); + err = convert_bitmapinfo( src_info, bits->ptr, src, dst_info, ptr ); if (bits->free) bits->free( bits ); bits->ptr = ptr; bits->is_copy = TRUE; @@ -287,7 +287,7 @@ BOOL nulldrv_StretchBlt( PHYSDEV dst_dev, struct bitblt_coords *dst, get_mono_dc_colors( src_dev->hdc, dst_info, 2 ); } - if (!(err = convert_bits( src_info, src, dst_info, &bits, FALSE ))) + if (!(err = convert_bits( src_info, src, dst_info, &bits ))) { /* get rid of the fake destination table */ dst_info->bmiHeader.biClrUsed = dst_colors; @@ -330,7 +330,7 @@ BOOL nulldrv_AlphaBlend( PHYSDEV dst_dev, struct bitblt_coords *dst, err = dst_dev->funcs->pBlendImage( dst_dev, dst_info, &bits, src, dst, func ); if (err == ERROR_BAD_FORMAT) { - err = convert_bits( src_info, src, dst_info, &bits, TRUE ); + err = convert_bits( src_info, src, dst_info, &bits ); if (!err) err = dst_dev->funcs->pBlendImage( dst_dev, dst_info, &bits, src, dst, func ); } diff --git a/dlls/gdi32/dib.c b/dlls/gdi32/dib.c index 91cfae79d0a..eed57e8c2db 100644 --- a/dlls/gdi32/dib.c +++ b/dlls/gdi32/dib.c @@ -572,7 +572,7 @@ INT nulldrv_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst, INT he dst_info->bmiHeader.biClrUsed = 1; } - if (!(err = convert_bits( src_info, &src, dst_info, &src_bits, FALSE ))) + if (!(err = convert_bits( src_info, &src, dst_info, &src_bits ))) { /* get rid of the fake 1-bpp table */ if (dst_info->bmiHeader.biClrUsed == 1) dst_info->bmiHeader.biClrUsed = 0; @@ -738,7 +738,7 @@ INT WINAPI SetDIBits( HDC hdc, HBITMAP hbitmap, UINT startscan, err = put_image_into_bitmap( bitmap, clip, dst_info, &src_bits, &src, &dst ); if (err == ERROR_BAD_FORMAT) { - err = convert_bits( src_info, &src, dst_info, &src_bits, FALSE ); + err = convert_bits( src_info, &src, dst_info, &src_bits ); if (!err) err = put_image_into_bitmap( bitmap, clip, dst_info, &src_bits, &src, &dst ); } if(err) result = 0; @@ -855,7 +855,7 @@ INT nulldrv_SetDIBitsToDevice( PHYSDEV dev, INT x_dst, INT y_dst, DWORD cx, DWOR err = dev->funcs->pPutImage( dev, clip, dst_info, &src_bits, &src, &dst, SRCCOPY ); if (err == ERROR_BAD_FORMAT) { - err = convert_bits( src_info, &src, dst_info, &src_bits, FALSE ); + err = convert_bits( src_info, &src, dst_info, &src_bits ); if (!err) err = dev->funcs->pPutImage( dev, clip, dst_info, &src_bits, &src, &dst, SRCCOPY ); } if (err) lines = 0; @@ -1387,7 +1387,7 @@ INT WINAPI GetDIBits( else dst_info->bmiHeader.biHeight = -src.height; - convert_bitmapinfo( src_info, src_bits.ptr, &src, dst_info, bits, FALSE ); + convert_bitmapinfo( src_info, src_bits.ptr, &src, dst_info, bits ); if (src_bits.free) src_bits.free( &src_bits ); ret = lines; } diff --git a/dlls/gdi32/dibdrv/dc.c b/dlls/gdi32/dibdrv/dc.c index 0e68f806cee..0b6013d0170 100644 --- a/dlls/gdi32/dibdrv/dc.c +++ b/dlls/gdi32/dibdrv/dc.c @@ -214,7 +214,7 @@ void copy_dib_color_info(dib_info *dst, const dib_info *src) } DWORD convert_bitmapinfo( const BITMAPINFO *src_info, void *src_bits, struct bitblt_coords *src, - const BITMAPINFO *dst_info, void *dst_bits, BOOL add_alpha ) + const BITMAPINFO *dst_info, void *dst_bits ) { dib_info src_dib, dst_dib; DWORD ret; @@ -234,24 +234,12 @@ DWORD convert_bitmapinfo( const BITMAPINFO *src_info, void *src_bits, struct bit } __ENDTRY - /* We shared the color tables, so there's no need to free the dib_infos here */ if(!ret) return ERROR_BAD_FORMAT; /* update coordinates, the destination rectangle is always stored at 0,0 */ src->x -= src->visrect.left; src->y -= src->visrect.top; offset_rect( &src->visrect, -src->visrect.left, -src->visrect.top ); - - if (add_alpha && dst_dib.funcs == &funcs_8888 && src_dib.funcs != &funcs_8888) - { - DWORD *pixel = dst_dib.bits.ptr; - int x, y; - - for (y = src->visrect.top; y < src->visrect.bottom; y++, pixel += dst_dib.stride / 4) - for (x = src->visrect.left; x < src->visrect.right; x++) - pixel[x] |= 0xff000000; - } - return ERROR_SUCCESS; } diff --git a/dlls/gdi32/dibdrv/primitives.c b/dlls/gdi32/dibdrv/primitives.c index 07dd1d51c0a..6feb8195429 100644 --- a/dlls/gdi32/dibdrv/primitives.c +++ b/dlls/gdi32/dibdrv/primitives.c @@ -3838,6 +3838,14 @@ static inline DWORD blend_argb_constant_alpha( DWORD dst, DWORD src, DWORD alpha blend_color( dst >> 24, src >> 24, alpha ) << 24); } +static inline DWORD blend_argb_no_src_alpha( DWORD dst, DWORD src, DWORD alpha ) +{ + return (blend_color( dst, src, alpha ) | + blend_color( dst >> 8, src >> 8, alpha ) << 8 | + blend_color( dst >> 16, src >> 16, alpha ) << 16 | + blend_color( dst >> 24, 255, alpha ) << 24); +} + static inline DWORD blend_argb( DWORD dst, DWORD src ) { BYTE b = (BYTE)src; @@ -3898,10 +3906,14 @@ static void blend_rect_8888(const dib_info *dst, const RECT *rc, for (x = 0; x < rc->right - rc->left; x++) dst_ptr[x] = blend_argb_alpha( dst_ptr[x], src_ptr[x], blend.SourceConstantAlpha ); } - else + else if (src->compression == BI_RGB) for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride / 4, src_ptr += src->stride / 4) for (x = 0; x < rc->right - rc->left; x++) dst_ptr[x] = blend_argb_constant_alpha( dst_ptr[x], src_ptr[x], blend.SourceConstantAlpha ); + else + for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride / 4, src_ptr += src->stride / 4) + for (x = 0; x < rc->right - rc->left; x++) + dst_ptr[x] = blend_argb_no_src_alpha( dst_ptr[x], src_ptr[x], blend.SourceConstantAlpha ); } static void blend_rect_32(const dib_info *dst, const RECT *rc, diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h index 29d4286f30d..5b79526e858 100644 --- a/dlls/gdi32/gdi_private.h +++ b/dlls/gdi32/gdi_private.h @@ -222,7 +222,7 @@ extern BOOL BIDI_Reorder( HDC hDC, LPCWSTR lpString, INT uCount, DWORD dwFlags, /* bitblt.c */ extern DWORD convert_bits( const BITMAPINFO *src_info, struct bitblt_coords *src, - BITMAPINFO *dst_info, struct gdi_image_bits *bits, BOOL add_alpha ) DECLSPEC_HIDDEN; + BITMAPINFO *dst_info, struct gdi_image_bits *bits ) DECLSPEC_HIDDEN; extern BOOL intersect_vis_rectangles( struct bitblt_coords *dst, struct bitblt_coords *src ) DECLSPEC_HIDDEN; extern DWORD stretch_bits( const BITMAPINFO *src_info, struct bitblt_coords *src, BITMAPINFO *dst_info, struct bitblt_coords *dst, @@ -264,7 +264,7 @@ extern void fill_default_color_table( BITMAPINFO *info ) DECLSPEC_HIDDEN; extern void get_ddb_bitmapinfo( BITMAPOBJ *bmp, BITMAPINFO *info ) DECLSPEC_HIDDEN; extern BITMAPINFO *copy_packed_dib( const BITMAPINFO *src_info, UINT usage ) DECLSPEC_HIDDEN; extern DWORD convert_bitmapinfo( const BITMAPINFO *src_info, void *src_bits, struct bitblt_coords *src, - const BITMAPINFO *dst_info, void *dst_bits, BOOL add_alpha ) DECLSPEC_HIDDEN; + const BITMAPINFO *dst_info, void *dst_bits ) DECLSPEC_HIDDEN; extern DWORD stretch_bitmapinfo( const BITMAPINFO *src_info, void *src_bits, struct bitblt_coords *src, const BITMAPINFO *dst_info, void *dst_bits, struct bitblt_coords *dst,