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