From 7c4c233d12e4d8fe1b85d4429b692d7605ce1ca1 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 29 May 2012 14:29:40 +0200 Subject: [PATCH] gdi32: Add a helper function that implements PutImage on a bitmap. --- dlls/gdi32/bitmap.c | 5 +- dlls/gdi32/dib.c | 6 +- dlls/gdi32/dibdrv/bitblt.c | 125 ++++++++++++++++++------------------- dlls/gdi32/gdi_private.h | 4 +- 4 files changed, 68 insertions(+), 72 deletions(-) diff --git a/dlls/gdi32/bitmap.c b/dlls/gdi32/bitmap.c index a8e4b2b4f98..38bc172ae79 100644 --- a/dlls/gdi32/bitmap.c +++ b/dlls/gdi32/bitmap.c @@ -210,7 +210,6 @@ HBITMAP WINAPI CreateBitmapIndirect( const BITMAP *bmp ) bmpobj->dib.dsBm = bm; bmpobj->dib.dsBm.bmBits = NULL; - bmpobj->funcs = &dib_driver; if (!(hbitmap = alloc_gdi_handle( &bmpobj->header, OBJ_BITMAP, &bitmap_funcs ))) { @@ -393,14 +392,14 @@ LONG WINAPI SetBitmapBits( info->bmiHeader.biWidth = 0; info->bmiHeader.biHeight = 0; info->bmiHeader.biSizeImage = 0; - err = bmp->funcs->pPutImage( NULL, hbitmap, 0, info, NULL, NULL, NULL, SRCCOPY ); + err = put_image_into_bitmap( bmp, 0, info, NULL, NULL, NULL ); if (!err || err == ERROR_BAD_FORMAT) { info->bmiHeader.biWidth = bmp->dib.dsBm.bmWidth; info->bmiHeader.biHeight = -dst.height; info->bmiHeader.biSizeImage = dst.height * dst_stride; - err = bmp->funcs->pPutImage( NULL, hbitmap, clip, info, &src_bits, &src, &dst, SRCCOPY ); + err = put_image_into_bitmap( bmp, clip, info, &src_bits, &src, &dst ); } if (err) count = 0; diff --git a/dlls/gdi32/dib.c b/dlls/gdi32/dib.c index 5eaa48ce7d9..8f044de0d7c 100644 --- a/dlls/gdi32/dib.c +++ b/dlls/gdi32/dib.c @@ -733,11 +733,11 @@ INT WINAPI SetDIBits( HDC hdc, HBITMAP hbitmap, UINT startscan, copy_bitmapinfo( dst_info, src_info ); - err = bitmap->funcs->pPutImage( NULL, hbitmap, clip, dst_info, &src_bits, &src, &dst, 0 ); + 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 ); - if (!err) err = bitmap->funcs->pPutImage( NULL, hbitmap, clip, dst_info, &src_bits, &src, &dst, 0 ); + if (!err) err = put_image_into_bitmap( bitmap, clip, dst_info, &src_bits, &src, &dst ); } if(err) result = 0; @@ -1492,8 +1492,6 @@ HBITMAP WINAPI CreateDIBSection(HDC hdc, CONST BITMAPINFO *bmi, UINT usage, bmp->dib.dsBm.bmBitsPixel = info->bmiHeader.biBitCount; bmp->dib.dsBmih = info->bmiHeader; - bmp->funcs = &dib_driver; - if (info->bmiHeader.biBitCount <= 8) /* build the color table */ { if (usage == DIB_PAL_COLORS && !fill_color_table_from_pal_colors( info, hdc )) diff --git a/dlls/gdi32/dibdrv/bitblt.c b/dlls/gdi32/dibdrv/bitblt.c index a20bed52233..6d5e51a5bdf 100644 --- a/dlls/gdi32/dibdrv/bitblt.c +++ b/dlls/gdi32/dibdrv/bitblt.c @@ -466,7 +466,7 @@ static int get_overlap( const dib_info *dst, const RECT *dst_rect, return ret; } -static DWORD copy_rect( dib_info *dst, const RECT *dst_rect, const dib_info *src, const RECT *src_rect, +static void copy_rect( dib_info *dst, const RECT *dst_rect, const dib_info *src, const RECT *src_rect, const struct clipped_rects *clipped_rects, INT rop2 ) { POINT origin; @@ -495,7 +495,7 @@ static DWORD copy_rect( dib_info *dst, const RECT *dst_rect, const dib_info *src dst->funcs->solid_rects( dst, count, rects, and, xor ); /* fall through */ case R2_NOP: - return ERROR_SUCCESS; + return; } overlap = get_overlap( dst, dst_rect, src, src_rect ); @@ -550,7 +550,6 @@ static DWORD copy_rect( dib_info *dst, const RECT *dst_rect, const dib_info *src dst->funcs->copy_rect( dst, &rects[i], src, &origin, rop2, overlap ); } } - return ERROR_SUCCESS; } static DWORD blend_rect( dib_info *dst, const RECT *dst_rect, const dib_info *src, const RECT *src_rect, @@ -875,6 +874,9 @@ static BOOL matching_color_info( const dib_info *dib, const BITMAPINFO *info ) { const RGBQUAD *color_table = info->bmiColors; + if (info->bmiHeader.biPlanes != 1) return FALSE; + if (info->bmiHeader.biBitCount != dib->bit_count) return FALSE; + switch (info->bmiHeader.biBitCount) { case 1: @@ -919,6 +921,33 @@ static BOOL matching_color_info( const dib_info *dib, const BITMAPINFO *info ) return FALSE; } +DWORD put_image_into_bitmap( BITMAPOBJ *bmp, HRGN clip, BITMAPINFO *info, + const struct gdi_image_bits *bits, struct bitblt_coords *src, + struct bitblt_coords *dst ) +{ + struct clipped_rects clipped_rects; + dib_info dib, src_dib; + + if (!init_dib_info_from_bitmapobj( &dib, bmp )) return ERROR_OUTOFMEMORY; + if (!matching_color_info( &dib, info )) goto update_format; + if (!bits) return ERROR_SUCCESS; + if ((src->width != dst->width) || (src->height != dst->height)) return ERROR_TRANSFORM_NOT_SUPPORTED; + + init_dib_info_from_bitmapinfo( &src_dib, info, bits->ptr ); + src_dib.bits.is_copy = bits->is_copy; + + if (get_clipped_rects( &dib, &dst->visrect, clip, &clipped_rects )) + copy_rect( &dib, &dst->visrect, &src_dib, &src->visrect, &clipped_rects, R2_COPYPEN ); + + return ERROR_SUCCESS; + +update_format: + info->bmiHeader.biPlanes = 1; + info->bmiHeader.biBitCount = dib.bit_count; + set_color_info( &dib, info ); + return ERROR_BAD_FORMAT; +} + static inline BOOL rop_uses_pat(DWORD rop) { return ((rop >> 4) & 0x0f0000) != (rop & 0x0f0000); @@ -931,90 +960,58 @@ DWORD dibdrv_PutImage( PHYSDEV dev, HBITMAP hbitmap, HRGN clip, BITMAPINFO *info const struct gdi_image_bits *bits, struct bitblt_coords *src, struct bitblt_coords *dst, DWORD rop ) { - dib_info *dib = NULL, stand_alone; struct clipped_rects clipped_rects; - DWORD ret; + DWORD ret = ERROR_SUCCESS; dib_info src_dib; HRGN tmp_rgn = 0; - dibdrv_physdev *pdev = NULL; + dibdrv_physdev *pdev = get_dibdrv_pdev( dev ); TRACE( "%p %p %p\n", dev, hbitmap, info ); if (hbitmap) { + DWORD ret; BITMAPOBJ *bmp = GDI_GetObjPtr( hbitmap, OBJ_BITMAP ); - if (!bmp) return ERROR_INVALID_HANDLE; - if (!init_dib_info_from_bitmapobj( &stand_alone, bmp )) - { - ret = ERROR_OUTOFMEMORY; - goto done; - } - dib = &stand_alone; - rop = SRCCOPY; - } - else - { - pdev = get_dibdrv_pdev( dev ); - dib = &pdev->dib; + ret = put_image_into_bitmap( bmp, clip, info, bits, src, dst ); + GDI_ReleaseObj( hbitmap ); + return ret; } - if (info->bmiHeader.biPlanes != 1) goto update_format; - if (info->bmiHeader.biBitCount != dib->bit_count) goto update_format; - if (!matching_color_info( dib, info )) goto update_format; - if (!bits) - { - ret = ERROR_SUCCESS; - goto done; - } - if ((src->width != dst->width) || (src->height != dst->height)) - { - ret = ERROR_TRANSFORM_NOT_SUPPORTED; - goto done; - } + if (!matching_color_info( &pdev->dib, info )) goto update_format; + if (!bits) return ERROR_SUCCESS; + if ((src->width != dst->width) || (src->height != dst->height)) return ERROR_TRANSFORM_NOT_SUPPORTED; init_dib_info_from_bitmapinfo( &src_dib, info, bits->ptr ); src_dib.bits.is_copy = bits->is_copy; - if (!hbitmap) + if (clip && pdev->clip) { - if (clip && pdev->clip) + tmp_rgn = CreateRectRgn( 0, 0, 0, 0 ); + CombineRgn( tmp_rgn, clip, pdev->clip, RGN_AND ); + clip = tmp_rgn; + } + else if (!clip) clip = pdev->clip; + add_clipped_bounds( pdev, &dst->visrect, clip ); + + if (get_clipped_rects( &pdev->dib, &dst->visrect, clip, &clipped_rects )) + { + if (!rop_uses_pat( rop )) { - tmp_rgn = CreateRectRgn( 0, 0, 0, 0 ); - CombineRgn( tmp_rgn, clip, pdev->clip, RGN_AND ); - clip = tmp_rgn; + int rop2 = ((rop >> 16) & 0xf) + 1; + copy_rect( &pdev->dib, &dst->visrect, &src_dib, &src->visrect, &clipped_rects, rop2 ); } - else if (!clip) clip = pdev->clip; - add_clipped_bounds( pdev, &dst->visrect, clip ); + else + ret = execute_rop( pdev, &dst->visrect, &src_dib, &src->visrect, &clipped_rects, rop ); } - - if (!get_clipped_rects( dib, &dst->visrect, clip, &clipped_rects )) - { - ret = ERROR_SUCCESS; - goto done; - } - - if (!rop_uses_pat( rop )) - { - int rop2 = ((rop >> 16) & 0xf) + 1; - ret = copy_rect( dib, &dst->visrect, &src_dib, &src->visrect, &clipped_rects, rop2 ); - } - else - { - ret = execute_rop( pdev, &dst->visrect, &src_dib, &src->visrect, &clipped_rects, rop ); - } - goto done; + if (tmp_rgn) DeleteObject( tmp_rgn ); + return ret; update_format: info->bmiHeader.biPlanes = 1; - info->bmiHeader.biBitCount = dib->bit_count; - set_color_info( dib, info ); - ret = ERROR_BAD_FORMAT; - -done: - if (tmp_rgn) DeleteObject( tmp_rgn ); - if (hbitmap) GDI_ReleaseObj( hbitmap ); - return ret; + info->bmiHeader.biBitCount = pdev->dib.bit_count; + set_color_info( &pdev->dib, info ); + return ERROR_BAD_FORMAT; } /*********************************************************************** diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h index 029937e0d7f..43d2f0e8769 100644 --- a/dlls/gdi32/gdi_private.h +++ b/dlls/gdi32/gdi_private.h @@ -186,7 +186,6 @@ typedef struct tagBITMAPOBJ DIBSECTION dib; SIZE size; /* For SetBitmapDimension() */ RGBQUAD *color_table; /* DIB color table if <= 8bpp (always 1 << bpp in size) */ - const struct gdi_dc_funcs *funcs; /* DC function table */ } BITMAPOBJ; static inline BOOL is_bitmapobj_dib( const BITMAPOBJ *bmp ) @@ -271,6 +270,9 @@ extern BOOL render_aa_text_bitmapinfo( HDC hdc, BITMAPINFO *info, struct gdi_ima UINT aa_flags, LPCWSTR str, UINT count, const INT *dx ) DECLSPEC_HIDDEN; extern DWORD get_image_from_bitmap( BITMAPOBJ *bmp, BITMAPINFO *info, struct gdi_image_bits *bits, struct bitblt_coords *src ) DECLSPEC_HIDDEN; +extern DWORD put_image_into_bitmap( BITMAPOBJ *bmp, HRGN clip, BITMAPINFO *info, + const struct gdi_image_bits *bits, struct bitblt_coords *src, + struct bitblt_coords *dst ) DECLSPEC_HIDDEN; /* driver.c */ extern const struct gdi_dc_funcs null_driver DECLSPEC_HIDDEN;