Alexandre Julliard : wineps: Implement the PutImage entry point.
Alexandre Julliard
julliard at winehq.org
Thu Jul 21 10:50:51 CDT 2011
Module: wine
Branch: master
Commit: 209578aeab623e43e2791fc7d87b47929bc12a3a
URL: http://source.winehq.org/git/wine.git/?a=commit;h=209578aeab623e43e2791fc7d87b47929bc12a3a
Author: Alexandre Julliard <julliard at winehq.org>
Date: Wed Jul 20 16:04:28 2011 +0200
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 deletions(-)
diff --git a/dlls/wineps.drv/bitmap.c b/dlls/wineps.drv/bitmap.c
index cb4ea30..cac4841 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 a45cf86..e9b0a04 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 d228023..5be855d 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;
More information about the wine-cvs
mailing list