gdi32: Handle a missing source alpha directly in the blend_rect primitive instead of modifying the source data.

This commit is contained in:
Alexandre Julliard 2012-10-10 17:19:42 +02:00
parent 76272e0773
commit 6e325afaa7
5 changed files with 24 additions and 24 deletions

View File

@ -158,7 +158,7 @@ void free_heap_bits( struct gdi_image_bits *bits )
} }
DWORD convert_bits( const BITMAPINFO *src_info, struct bitblt_coords *src, 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; void *ptr;
DWORD err; 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 ))) if (!(ptr = HeapAlloc( GetProcessHeap(), 0, dst_info->bmiHeader.biSizeImage )))
return ERROR_OUTOFMEMORY; 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 ); if (bits->free) bits->free( bits );
bits->ptr = ptr; bits->ptr = ptr;
bits->is_copy = TRUE; 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 ); 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 */ /* get rid of the fake destination table */
dst_info->bmiHeader.biClrUsed = dst_colors; 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 ); err = dst_dev->funcs->pBlendImage( dst_dev, dst_info, &bits, src, dst, func );
if (err == ERROR_BAD_FORMAT) 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 ); if (!err) err = dst_dev->funcs->pBlendImage( dst_dev, dst_info, &bits, src, dst, func );
} }

View File

@ -572,7 +572,7 @@ INT nulldrv_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst, INT he
dst_info->bmiHeader.biClrUsed = 1; 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 */ /* get rid of the fake 1-bpp table */
if (dst_info->bmiHeader.biClrUsed == 1) dst_info->bmiHeader.biClrUsed = 0; 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 ); err = put_image_into_bitmap( bitmap, clip, dst_info, &src_bits, &src, &dst );
if (err == ERROR_BAD_FORMAT) 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) err = put_image_into_bitmap( bitmap, clip, dst_info, &src_bits, &src, &dst );
} }
if(err) result = 0; 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 ); err = dev->funcs->pPutImage( dev, clip, dst_info, &src_bits, &src, &dst, SRCCOPY );
if (err == ERROR_BAD_FORMAT) 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) err = dev->funcs->pPutImage( dev, clip, dst_info, &src_bits, &src, &dst, SRCCOPY );
} }
if (err) lines = 0; if (err) lines = 0;
@ -1387,7 +1387,7 @@ INT WINAPI GetDIBits(
else else
dst_info->bmiHeader.biHeight = -src.height; 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 ); if (src_bits.free) src_bits.free( &src_bits );
ret = lines; ret = lines;
} }

View File

@ -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, 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; dib_info src_dib, dst_dib;
DWORD ret; DWORD ret;
@ -234,24 +234,12 @@ DWORD convert_bitmapinfo( const BITMAPINFO *src_info, void *src_bits, struct bit
} }
__ENDTRY __ENDTRY
/* We shared the color tables, so there's no need to free the dib_infos here */
if(!ret) return ERROR_BAD_FORMAT; if(!ret) return ERROR_BAD_FORMAT;
/* update coordinates, the destination rectangle is always stored at 0,0 */ /* update coordinates, the destination rectangle is always stored at 0,0 */
src->x -= src->visrect.left; src->x -= src->visrect.left;
src->y -= src->visrect.top; src->y -= src->visrect.top;
offset_rect( &src->visrect, -src->visrect.left, -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; return ERROR_SUCCESS;
} }

View File

@ -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); 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 ) static inline DWORD blend_argb( DWORD dst, DWORD src )
{ {
BYTE b = (BYTE)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++) for (x = 0; x < rc->right - rc->left; x++)
dst_ptr[x] = blend_argb_alpha( dst_ptr[x], src_ptr[x], blend.SourceConstantAlpha ); 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 (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++) for (x = 0; x < rc->right - rc->left; x++)
dst_ptr[x] = blend_argb_constant_alpha( dst_ptr[x], src_ptr[x], blend.SourceConstantAlpha ); 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, static void blend_rect_32(const dib_info *dst, const RECT *rc,

View File

@ -222,7 +222,7 @@ extern BOOL BIDI_Reorder( HDC hDC, LPCWSTR lpString, INT uCount, DWORD dwFlags,
/* bitblt.c */ /* bitblt.c */
extern DWORD convert_bits( const BITMAPINFO *src_info, struct bitblt_coords *src, 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 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, extern DWORD stretch_bits( const BITMAPINFO *src_info, struct bitblt_coords *src,
BITMAPINFO *dst_info, struct bitblt_coords *dst, 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 void get_ddb_bitmapinfo( BITMAPOBJ *bmp, BITMAPINFO *info ) DECLSPEC_HIDDEN;
extern BITMAPINFO *copy_packed_dib( const BITMAPINFO *src_info, UINT usage ) 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, 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, 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, const BITMAPINFO *dst_info, void *dst_bits, struct bitblt_coords *dst,