From 209578aeab623e43e2791fc7d87b47929bc12a3a Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Wed, 20 Jul 2011 16:04:28 +0200 Subject: [PATCH] wineps: Implement the PutImage entry point. --- dlls/wineps.drv/bitmap.c | 116 +++++++++++++++++++++++++++++++++++++++ dlls/wineps.drv/init.c | 2 +- dlls/wineps.drv/psdrv.h | 2 + 3 files changed, 119 insertions(+), 1 deletion(-) diff --git a/dlls/wineps.drv/bitmap.c b/dlls/wineps.drv/bitmap.c index cb4ea3048b..cac4841eec 100644 --- a/dlls/wineps.drv/bitmap.c +++ b/dlls/wineps.drv/bitmap.c @@ -177,6 +177,11 @@ static inline DWORD max_ascii85_size(DWORD size) return (size + 3) / 4 * 5; } +static void free_heap_bits( struct gdi_image_bits *bits ) +{ + HeapFree( GetProcessHeap(), 0, bits->ptr ); +} + /*************************************************************************** * PSDRV_WriteImageBits */ @@ -205,6 +210,117 @@ static void PSDRV_WriteImageBits( PHYSDEV dev, const BITMAPINFO *info, INT xDst, HeapFree(GetProcessHeap(), 0, ascii85); } +/*********************************************************************** + * PSDRV_PutImage + */ +DWORD PSDRV_PutImage( PHYSDEV dev, HBITMAP hbitmap, BITMAPINFO *info, const struct gdi_image_bits *bits, + struct bitblt_coords *src, struct bitblt_coords *dst, DWORD rop ) +{ + int src_stride, dst_stride, size, x, y, width, height, bit_offset; + int dst_x, dst_y, dst_width, dst_height; + unsigned char *src_ptr, *dst_ptr; + struct gdi_image_bits dst_bits; + + if (hbitmap) return ERROR_NOT_SUPPORTED; + + if (info->bmiHeader.biPlanes != 1) goto update_format; + if (info->bmiHeader.biCompression != BI_RGB) goto update_format; + if (info->bmiHeader.biBitCount == 16 || info->bmiHeader.biBitCount == 32) goto update_format; + if (!bits) return ERROR_SUCCESS; /* just querying the format */ + + TRACE( "bpp %u %s -> %s\n", info->bmiHeader.biBitCount, wine_dbgstr_rect(&src->visrect), + wine_dbgstr_rect(&dst->visrect) ); + + width = src->visrect.right - src->visrect.left; + height = src->visrect.bottom - src->visrect.top; + src_stride = get_dib_width_bytes( info->bmiHeader.biWidth, info->bmiHeader.biBitCount ); + dst_stride = (width * info->bmiHeader.biBitCount + 7) / 8; + + src_ptr = bits->ptr; + if (info->bmiHeader.biHeight > 0) + src_ptr += (info->bmiHeader.biHeight - src->visrect.bottom) * src_stride; + else + src_ptr += src->visrect.top * src_stride; + bit_offset = src->visrect.left * info->bmiHeader.biBitCount; + src_ptr += bit_offset / 8; + bit_offset &= 7; + if (bit_offset) FIXME( "pos %s not supported\n", wine_dbgstr_rect(&src->visrect) ); + size = height * dst_stride; + + if (src_stride != dst_stride || (info->bmiHeader.biBitCount == 24 && !bits->is_copy)) + { + if (!(dst_bits.ptr = HeapAlloc( GetProcessHeap(), 0, size ))) return ERROR_OUTOFMEMORY; + dst_bits.is_copy = TRUE; + dst_bits.free = free_heap_bits; + } + else + { + dst_bits.ptr = src_ptr; + dst_bits.is_copy = bits->is_copy; + dst_bits.free = NULL; + } + dst_ptr = dst_bits.ptr; + + switch (info->bmiHeader.biBitCount) + { + case 1: + case 4: + case 8: + if (src_stride != dst_stride) + for (y = 0; y < height; y++, src_ptr += src_stride, dst_ptr += dst_stride) + memcpy( dst_ptr, src_ptr, dst_stride ); + break; + case 24: + if (dst_ptr != src_ptr) + for (y = 0; y < height; y++, src_ptr += src_stride, dst_ptr += dst_stride) + for (x = 0; x < width; x++) + { + dst_ptr[x * 3] = src_ptr[x * 3 + 2]; + dst_ptr[x * 3 + 1] = src_ptr[x * 3 + 1]; + dst_ptr[x * 3 + 2] = src_ptr[x * 3]; + } + else /* swap R and B in place */ + for (y = 0; y < height; y++, src_ptr += src_stride, dst_ptr += dst_stride) + for (x = 0; x < width; x++) + { + unsigned char tmp = dst_ptr[x * 3]; + dst_ptr[x * 3] = dst_ptr[x * 3 + 2]; + dst_ptr[x * 3 + 2] = tmp; + } + break; + } + + dst_x = dst->visrect.left; + dst_y = dst->visrect.top, + dst_width = dst->visrect.right - dst->visrect.left; + dst_height = dst->visrect.bottom - dst->visrect.top; + if (src->width * dst->width < 0) + { + dst_x += dst_width; + dst_width = -dst_width; + } + if (src->height * dst->height < 0) + { + dst_y += dst_height; + dst_height = -dst_height; + } + + PSDRV_SetClip(dev); + PSDRV_WriteGSave(dev); + PSDRV_WriteImageBits( dev, info, dst_x, dst_y, dst_width, dst_height, + width, height, dst_bits.ptr, size ); + PSDRV_WriteGRestore(dev); + PSDRV_ResetClip(dev); + if (dst_bits.free) dst_bits.free( &dst_bits ); + return ERROR_SUCCESS; + +update_format: + info->bmiHeader.biPlanes = 1; + if (info->bmiHeader.biBitCount > 8) info->bmiHeader.biBitCount = 24; + info->bmiHeader.biCompression = BI_RGB; + return ERROR_BAD_FORMAT; +} + /*************************************************************************** * * PSDRV_StretchDIBits diff --git a/dlls/wineps.drv/init.c b/dlls/wineps.drv/init.c index a45cf86e24..e9b0a0447d 100644 --- a/dlls/wineps.drv/init.c +++ b/dlls/wineps.drv/init.c @@ -868,7 +868,7 @@ static const struct gdi_dc_funcs psdrv_funcs = PSDRV_Polygon, /* pPolygon */ PSDRV_Polyline, /* pPolyline */ NULL, /* pPolylineTo */ - NULL, /* pPutImage */ + PSDRV_PutImage, /* pPutImage */ NULL, /* pRealizeDefaultPalette */ NULL, /* pRealizePalette */ PSDRV_Rectangle, /* pRectangle */ diff --git a/dlls/wineps.drv/psdrv.h b/dlls/wineps.drv/psdrv.h index d228023db2..5be855dc4d 100644 --- a/dlls/wineps.drv/psdrv.h +++ b/dlls/wineps.drv/psdrv.h @@ -443,6 +443,8 @@ extern BOOL PSDRV_PolyPolygon( PHYSDEV dev, const POINT* pts, const INT* counts, extern BOOL PSDRV_PolyPolyline( PHYSDEV dev, const POINT* pts, const DWORD* counts, DWORD polylines ) DECLSPEC_HIDDEN; extern BOOL PSDRV_Polygon( PHYSDEV dev, const POINT* pt, INT count ) DECLSPEC_HIDDEN; extern BOOL PSDRV_Polyline( PHYSDEV dev, const POINT* pt, INT count ) DECLSPEC_HIDDEN; +extern DWORD PSDRV_PutImage( PHYSDEV dev, HBITMAP hbitmap, BITMAPINFO *info, const struct gdi_image_bits *bits, + struct bitblt_coords *src, struct bitblt_coords *dst, DWORD rop ) DECLSPEC_HIDDEN; extern BOOL PSDRV_Rectangle( PHYSDEV dev, INT left, INT top, INT right, INT bottom ) DECLSPEC_HIDDEN; extern BOOL PSDRV_RoundRect( PHYSDEV dev, INT left, INT top, INT right, INT bottom, INT ell_width, INT ell_height ) DECLSPEC_HIDDEN; -- 2.32.0.93.g670b81a890