From bb3a1bdcacdd06ed8af19755a95617acc99e1c27 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Mon, 25 Jul 2011 15:26:39 +0200 Subject: [PATCH] gdi32: Implement GetImage in the null driver. --- dlls/gdi32/bitmap.c | 58 ++++++++++++++++++++++++++++++++++++++++ dlls/gdi32/driver.c | 6 ----- dlls/gdi32/gdi_private.h | 1 + 3 files changed, 59 insertions(+), 6 deletions(-) diff --git a/dlls/gdi32/bitmap.c b/dlls/gdi32/bitmap.c index e0df88de492..620e75c65fe 100644 --- a/dlls/gdi32/bitmap.c +++ b/dlls/gdi32/bitmap.c @@ -79,6 +79,64 @@ LONG nulldrv_SetBitmapBits( HBITMAP bitmap, const void *bits, LONG size ) return size; } +DWORD nulldrv_GetImage( PHYSDEV dev, HBITMAP hbitmap, BITMAPINFO *info, + struct gdi_image_bits *bits, struct bitblt_coords *src ) +{ + BITMAPOBJ *bmp; + int height, width_bytes; + + if (!hbitmap) return ERROR_NOT_SUPPORTED; + if (!(bmp = GDI_GetObjPtr( hbitmap, OBJ_BITMAP ))) return ERROR_INVALID_HANDLE; + + info->bmiHeader.biSize = sizeof(info->bmiHeader); + info->bmiHeader.biPlanes = 1; + info->bmiHeader.biBitCount = bmp->bitmap.bmBitsPixel; + info->bmiHeader.biCompression = BI_RGB; + info->bmiHeader.biXPelsPerMeter = 0; + info->bmiHeader.biYPelsPerMeter = 0; + info->bmiHeader.biClrUsed = 0; + info->bmiHeader.biClrImportant = 0; + if (!bits) goto done; + + height = src->visrect.bottom - src->visrect.top; + width_bytes = get_dib_stride( bmp->bitmap.bmWidth, bmp->bitmap.bmBitsPixel ); + info->bmiHeader.biWidth = bmp->bitmap.bmWidth; + info->bmiHeader.biHeight = -height; + info->bmiHeader.biSizeImage = height * width_bytes; + + /* make the source rectangle relative to the returned bits */ + src->y -= src->visrect.top; + offset_rect( &src->visrect, 0, -src->visrect.top ); + + if (bmp->bitmap.bmBits && bmp->bitmap.bmWidthBytes == width_bytes) + { + bits->ptr = (char *)bmp->bitmap.bmBits + src->visrect.top * width_bytes; + bits->is_copy = FALSE; + bits->free = NULL; + } + else + { + bits->ptr = HeapAlloc( GetProcessHeap(), 0, info->bmiHeader.biSizeImage ); + bits->is_copy = TRUE; + bits->free = free_heap_bits; + if (bmp->bitmap.bmBits) + { + /* fixup the line alignment */ + char *src = bmp->bitmap.bmBits, *dst = bits->ptr; + for ( ; height > 0; height--, src += bmp->bitmap.bmWidthBytes, dst += width_bytes) + { + memcpy( dst, src, bmp->bitmap.bmWidthBytes ); + memset( dst + bmp->bitmap.bmWidthBytes, 0, width_bytes - bmp->bitmap.bmWidthBytes ); + } + } + else memset( bits->ptr, 0, info->bmiHeader.biSizeImage ); + } +done: + GDI_ReleaseObj( hbitmap ); + return ERROR_SUCCESS; +} + + /*********************************************************************** * BITMAP_GetWidthBytes * diff --git a/dlls/gdi32/driver.c b/dlls/gdi32/driver.c index 7ef76d80337..4a65b8dcf60 100644 --- a/dlls/gdi32/driver.c +++ b/dlls/gdi32/driver.c @@ -347,12 +347,6 @@ static BOOL nulldrv_GetICMProfile( PHYSDEV dev, LPDWORD size, LPWSTR filename ) return FALSE; } -static DWORD nulldrv_GetImage( PHYSDEV dev, HBITMAP hbitmap, BITMAPINFO *info, - struct gdi_image_bits *bits, struct bitblt_coords *src ) -{ - return ERROR_NOT_SUPPORTED; -} - static COLORREF nulldrv_GetPixel( PHYSDEV dev, INT x, INT y ) { return 0; diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h index 0744a445f3e..bdd9606493f 100644 --- a/dlls/gdi32/gdi_private.h +++ b/dlls/gdi32/gdi_private.h @@ -482,6 +482,7 @@ extern BOOL nulldrv_FillRgn( PHYSDEV dev, HRGN rgn, HBRUSH brush ) DECLSPEC_HIDD extern BOOL nulldrv_FlattenPath( PHYSDEV dev ) DECLSPEC_HIDDEN; extern BOOL nulldrv_FrameRgn( PHYSDEV dev, HRGN rgn, HBRUSH brush, INT width, INT height ) DECLSPEC_HIDDEN; extern LONG nulldrv_GetBitmapBits( HBITMAP bitmap, void *bits, LONG size ) DECLSPEC_HIDDEN; +extern DWORD nulldrv_GetImage( PHYSDEV dev, HBITMAP hbitmap, BITMAPINFO *info, struct gdi_image_bits *bits, struct bitblt_coords *src ) DECLSPEC_HIDDEN; extern COLORREF nulldrv_GetNearestColor( PHYSDEV dev, COLORREF color ) DECLSPEC_HIDDEN; extern INT nulldrv_IntersectClipRect( PHYSDEV dev, INT left, INT top, INT right, INT bottom ) DECLSPEC_HIDDEN; extern BOOL nulldrv_InvertRgn( PHYSDEV dev, HRGN rgn ) DECLSPEC_HIDDEN;