diff --git a/dlls/gdi32/bitmap.c b/dlls/gdi32/bitmap.c index 93bfe77ca20..bce5183c193 100644 --- a/dlls/gdi32/bitmap.c +++ b/dlls/gdi32/bitmap.c @@ -126,6 +126,81 @@ done: return ERROR_SUCCESS; } +DWORD nulldrv_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 ) +{ + BITMAPOBJ *bmp; + + if (!hbitmap) return ERROR_SUCCESS; + if (!(bmp = GDI_GetObjPtr( hbitmap, OBJ_BITMAP ))) return ERROR_INVALID_HANDLE; + + if (info->bmiHeader.biPlanes != 1) goto update_format; + if (info->bmiHeader.biBitCount != bmp->bitmap.bmBitsPixel) goto update_format; + /* FIXME: check color masks */ + + if (bits) + { + int i, width_bytes = get_dib_stride( info->bmiHeader.biWidth, info->bmiHeader.biBitCount ); + unsigned char *dst_bits, *src_bits; + + if ((src->width != dst->width) || (src->height != dst->height)) + { + GDI_ReleaseObj( hbitmap ); + return ERROR_TRANSFORM_NOT_SUPPORTED; + } + if (src->visrect.left > 0 || src->visrect.right < bmp->bitmap.bmWidth || + dst->visrect.left > 0 || dst->visrect.right < bmp->bitmap.bmWidth) + { + FIXME( "setting partial rows not supported\n" ); + GDI_ReleaseObj( hbitmap ); + return ERROR_NOT_SUPPORTED; + } + if (clip) + { + FIXME( "clip region not supported\n" ); + GDI_ReleaseObj( hbitmap ); + return ERROR_NOT_SUPPORTED; + } + + if (!bmp->bitmap.bmBits && + !(bmp->bitmap.bmBits = HeapAlloc( GetProcessHeap(), 0, + bmp->bitmap.bmHeight * bmp->bitmap.bmWidthBytes ))) + { + GDI_ReleaseObj( hbitmap ); + return ERROR_OUTOFMEMORY; + } + src_bits = bits->ptr; + if (info->bmiHeader.biHeight > 0) + { + src_bits += (info->bmiHeader.biHeight - 1 - src->visrect.top) * width_bytes; + width_bytes = -width_bytes; + } + else + src_bits += src->visrect.top * width_bytes; + + dst_bits = (unsigned char *)bmp->bitmap.bmBits + dst->visrect.top * bmp->bitmap.bmWidthBytes; + if (width_bytes != bmp->bitmap.bmWidthBytes) + { + for (i = 0; i < dst->visrect.bottom - dst->visrect.top; i++) + { + memcpy( dst_bits, src_bits, min( abs(width_bytes), bmp->bitmap.bmWidthBytes )); + src_bits += width_bytes; + dst_bits += bmp->bitmap.bmWidthBytes; + } + } + else memcpy( dst_bits, src_bits, width_bytes * (dst->visrect.bottom - dst->visrect.top) ); + } + GDI_ReleaseObj( hbitmap ); + return ERROR_SUCCESS; + +update_format: + info->bmiHeader.biPlanes = 1; + info->bmiHeader.biBitCount = bmp->bitmap.bmBitsPixel; + if (info->bmiHeader.biHeight > 0) info->bmiHeader.biHeight = -info->bmiHeader.biHeight; + return ERROR_BAD_FORMAT; +} + /****************************************************************************** * CreateBitmap [GDI32.@] diff --git a/dlls/gdi32/driver.c b/dlls/gdi32/driver.c index 290a30d172c..dc4a33b9385 100644 --- a/dlls/gdi32/driver.c +++ b/dlls/gdi32/driver.c @@ -421,13 +421,6 @@ static BOOL nulldrv_Polyline( PHYSDEV dev, const POINT *points, INT count ) return TRUE; } -static DWORD nulldrv_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 ) -{ - return ERROR_SUCCESS; -} - static UINT nulldrv_RealizeDefaultPalette( PHYSDEV dev ) { return 0; diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h index 4aeef70a298..ed5bb8a5f2e 100644 --- a/dlls/gdi32/gdi_private.h +++ b/dlls/gdi32/gdi_private.h @@ -493,6 +493,9 @@ extern BOOL nulldrv_PolyBezier( PHYSDEV dev, const POINT *points, DWORD count ) extern BOOL nulldrv_PolyBezierTo( PHYSDEV dev, const POINT *points, DWORD count ) DECLSPEC_HIDDEN; extern BOOL nulldrv_PolyDraw( PHYSDEV dev, const POINT *points, const BYTE *types, DWORD count ) DECLSPEC_HIDDEN; extern BOOL nulldrv_PolylineTo( PHYSDEV dev, const POINT *points, INT count ) DECLSPEC_HIDDEN; +extern DWORD nulldrv_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 ) DECLSPEC_HIDDEN; extern BOOL nulldrv_RestoreDC( PHYSDEV dev, INT level ) DECLSPEC_HIDDEN; extern INT nulldrv_SaveDC( PHYSDEV dev ) DECLSPEC_HIDDEN; extern BOOL nulldrv_ScaleViewportExtEx( PHYSDEV dev, INT x_num, INT x_denom, INT y_num, INT y_denom, SIZE *size ) DECLSPEC_HIDDEN;