wineps: Implement the PutImage entry point.
This commit is contained in:
parent
632391dbf4
commit
209578aeab
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue