gdi32: Pass the full bitblt_coords structure to the Get/PutImage entry points.

This commit is contained in:
Alexandre Julliard 2011-07-21 11:17:13 +02:00
parent c1dafc514a
commit 73dc9833b7
6 changed files with 56 additions and 47 deletions

View File

@ -209,7 +209,7 @@ try_get_image:
if (!(dc_src = get_dc_ptr( src_dev->hdc ))) return FALSE;
src_dev = GET_DC_PHYSDEV( dc_src, pGetImage );
err = src_dev->funcs->pGetImage( src_dev, 0, src_info, &src_bits, &src->visrect );
err = src_dev->funcs->pGetImage( src_dev, 0, src_info, &src_bits, src );
release_dc_ptr( dc_src );
if (err) return FALSE;
@ -220,11 +220,9 @@ try_get_image:
src->width, src->height, dst->width, dst->height );
memcpy( dst_info, src_info, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ));
err = dst_dev->funcs->pPutImage( dst_dev, 0, dst_info, &src_bits, &dst->visrect, rop );
err = dst_dev->funcs->pPutImage( dst_dev, 0, dst_info, &src_bits, src, dst, rop );
if (err == ERROR_BAD_FORMAT)
{
RECT src_rect = src->visrect;
/* 1-bpp source without a color table uses the destination DC colors */
if (src_info->bmiHeader.biBitCount == 1 && !src_info->bmiHeader.biClrUsed)
{
@ -253,19 +251,18 @@ try_get_image:
dst_info->bmiHeader.biClrUsed = 1;
}
offset_rect( &src_rect, src_bits.offset - src->visrect.left, -src->visrect.top );
dst_info->bmiHeader.biWidth = src_rect.right - src_rect.left;
dst_info->bmiHeader.biWidth = src->visrect.right - src->visrect.left;
dst_bits.ptr = HeapAlloc( GetProcessHeap(), 0, get_dib_image_size( dst_info ));
if (dst_bits.ptr)
{
dst_bits.is_copy = TRUE;
dst_bits.offset = 0;
dst_bits.free = free_heap_bits;
if (!(err = convert_bitmapinfo( src_info, src_bits.ptr, &src_rect, dst_info, dst_bits.ptr )))
if (!(err = convert_bitmapinfo( src_info, src_bits.ptr, &src->visrect, dst_info, dst_bits.ptr )))
{
/* get rid of the fake 1-bpp table */
if (dst_info->bmiHeader.biClrUsed == 1) dst_info->bmiHeader.biClrUsed = 0;
err = dst_dev->funcs->pPutImage( dst_dev, 0, dst_info, &dst_bits, &dst->visrect, rop );
err = dst_dev->funcs->pPutImage( dst_dev, 0, dst_info, &dst_bits, src, dst, rop );
}
if (dst_bits.free) dst_bits.free( &dst_bits );
}

View File

@ -693,10 +693,10 @@ INT WINAPI GetDIBits(
if (bits && lines)
{
PHYSDEV physdev;
RECT rect;
char src_bmibuf[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
BITMAPINFO *src_info = (BITMAPINFO *)src_bmibuf;
struct gdi_image_bits src_bits;
struct bitblt_coords src;
DWORD err;
/* FIXME: will need updating once the dib driver has pGetImage. */
@ -704,8 +704,8 @@ INT WINAPI GetDIBits(
if (!BITMAP_SetOwnerDC( hbitmap, physdev )) lines = 0;
rect.left = 0;
rect.right = min( width, bmp->bitmap.bmWidth );
src.visrect.left = 0;
src.visrect.right = min( width, bmp->bitmap.bmWidth );
if (startscan >= bmp->bitmap.bmHeight) /* constrain lines to within src bitmap */
lines = 0;
@ -715,10 +715,14 @@ INT WINAPI GetDIBits(
if (lines == 0) goto done;
rect.bottom = bmp->bitmap.bmHeight - startscan;
rect.top = rect.bottom - lines;
src.visrect.bottom = bmp->bitmap.bmHeight - startscan;
src.visrect.top = src.visrect.bottom - lines;
src.x = src.visrect.left;
src.y = src.visrect.top;
src.width = src.visrect.right - src.visrect.left;
src.height = src.visrect.bottom - src.visrect.top;
err = physdev->funcs->pGetImage( physdev, hbitmap, src_info, &src_bits, &rect );
err = physdev->funcs->pGetImage( physdev, hbitmap, src_info, &src_bits, &src );
if(err)
{
@ -734,14 +738,12 @@ INT WINAPI GetDIBits(
fill_default_color_table( src_info );
}
offset_rect( &rect, src_bits.offset, -rect.top );
if(dst_info->bmiHeader.biHeight > 0)
dst_info->bmiHeader.biHeight = lines;
else
dst_info->bmiHeader.biHeight = -lines;
convert_bitmapinfo( src_info, src_bits.ptr, &rect, dst_info, bits );
convert_bitmapinfo( src_info, src_bits.ptr, &src.visrect, dst_info, bits );
if (src_bits.free) src_bits.free( &src_bits );
}
else lines = abs(height);

View File

@ -348,7 +348,7 @@ static BOOL nulldrv_GetICMProfile( PHYSDEV dev, LPDWORD size, LPWSTR filename )
}
static DWORD nulldrv_GetImage( PHYSDEV dev, HBITMAP hbitmap, BITMAPINFO *info,
struct gdi_image_bits *bits, const RECT *rect )
struct gdi_image_bits *bits, struct bitblt_coords *src )
{
return ERROR_NOT_SUPPORTED;
}
@ -428,7 +428,8 @@ static BOOL nulldrv_Polyline( PHYSDEV dev, const POINT *points, INT count )
}
static DWORD nulldrv_PutImage( PHYSDEV dev, HBITMAP hbitmap, BITMAPINFO *info,
const struct gdi_image_bits *bits, const RECT *rect, DWORD rop )
const struct gdi_image_bits *bits, struct bitblt_coords *src,
struct bitblt_coords *dst, DWORD rop )
{
return ERROR_SUCCESS;
}

View File

@ -1711,7 +1711,7 @@ static BOOL matching_color_info( PHYSDEV dev, const ColorShifts *color_shifts, c
/* copy the image bits, fixing up alignment and byte swapping as necessary */
static DWORD copy_image_bits( BITMAPINFO *info, const ColorShifts *color_shifts, XImage *image,
const struct gdi_image_bits *src_bits, struct gdi_image_bits *dst_bits,
const int *mapping, unsigned int zeropad_mask )
struct bitblt_coords *coords, const int *mapping, unsigned int zeropad_mask )
{
#ifdef WORDS_BIGENDIAN
static const int client_byte_order = MSBFirst;
@ -1719,7 +1719,7 @@ static DWORD copy_image_bits( BITMAPINFO *info, const ColorShifts *color_shifts,
static const int client_byte_order = LSBFirst;
#endif
BOOL need_byteswap;
int x, y, height = abs(info->bmiHeader.biHeight);
int x, y, height = coords->visrect.bottom - coords->visrect.top;
int width_bytes = image->bytes_per_line;
int padding_pos;
unsigned char *src, *dst;
@ -1745,6 +1745,12 @@ static DWORD copy_image_bits( BITMAPINFO *info, const ColorShifts *color_shifts,
break;
}
src = src_bits->ptr;
if (info->bmiHeader.biHeight > 0)
src += (info->bmiHeader.biHeight - coords->visrect.bottom) * width_bytes;
else
src += coords->visrect.top * width_bytes;
if ((need_byteswap && !src_bits->is_copy) || /* need to swap bytes */
(zeropad_mask != ~0u && !src_bits->is_copy) || /* need to clear padding bytes */
(mapping && !src_bits->is_copy) || /* need to remap pixels */
@ -1762,14 +1768,13 @@ static DWORD copy_image_bits( BITMAPINFO *info, const ColorShifts *color_shifts,
else
{
/* swap bits in place */
dst_bits->ptr = src_bits->ptr;
dst_bits->ptr = src;
dst_bits->offset = src_bits->offset;
dst_bits->is_copy = src_bits->is_copy;
dst_bits->free = NULL;
if (!need_byteswap && zeropad_mask == ~0u && !mapping) return ERROR_SUCCESS; /* nothing to do */
}
src = src_bits->ptr;
dst = dst_bits->ptr;
padding_pos = width_bytes/sizeof(unsigned int) - 1;
@ -1859,7 +1864,7 @@ static DWORD copy_image_bits( BITMAPINFO *info, const ColorShifts *color_shifts,
* X11DRV_PutImage
*/
DWORD X11DRV_PutImage( PHYSDEV dev, HBITMAP hbitmap, BITMAPINFO *info, const struct gdi_image_bits *bits,
const RECT *rect, DWORD rop )
struct bitblt_coords *src, struct bitblt_coords *dst, DWORD rop )
{
X11DRV_PDEVICE *physdev;
X_PHYSBITMAP *bitmap;
@ -1896,7 +1901,7 @@ DWORD X11DRV_PutImage( PHYSDEV dev, HBITMAP hbitmap, BITMAPINFO *info, const str
wine_tsx11_lock();
image = XCreateImage( gdi_display, visual, depth, ZPixmap, 0, NULL,
info->bmiHeader.biWidth, abs(info->bmiHeader.biHeight), 32, 0 );
info->bmiHeader.biWidth, src->visrect.bottom - src->visrect.top, 32, 0 );
wine_tsx11_unlock();
if (!image) return ERROR_OUTOFMEMORY;
@ -1906,20 +1911,20 @@ DWORD X11DRV_PutImage( PHYSDEV dev, HBITMAP hbitmap, BITMAPINFO *info, const str
mapping = X11DRV_PALETTE_PaletteToXPixel;
}
ret = copy_image_bits( info, color_shifts, image, bits, &dst_bits, mapping, ~0u );
ret = copy_image_bits( info, color_shifts, image, bits, &dst_bits, src, mapping, ~0u );
if (!ret)
{
int width = rect->right - rect->left;
int height = rect->bottom - rect->top;
int width = dst->visrect.right - dst->visrect.left;
int height = dst->visrect.bottom - dst->visrect.top;
image->data = dst_bits.ptr;
if (bitmap)
{
X11DRV_DIB_Lock( bitmap, DIB_Status_GdiMod );
wine_tsx11_lock();
XPutImage( gdi_display, bitmap->pixmap, get_bitmap_gc(depth), image, dst_bits.offset, 0,
rect->left, rect->top, width, height );
XPutImage( gdi_display, bitmap->pixmap, get_bitmap_gc(depth), image, src->visrect.left, 0,
dst->visrect.left, dst->visrect.top, width, height );
wine_tsx11_unlock();
X11DRV_DIB_Unlock( bitmap, TRUE );
}
@ -1932,9 +1937,9 @@ DWORD X11DRV_PutImage( PHYSDEV dev, HBITMAP hbitmap, BITMAPINFO *info, const str
{
wine_tsx11_lock();
XSetFunction( gdi_display, physdev->gc, OP_ROP(*opcode) );
XPutImage( gdi_display, physdev->drawable, physdev->gc, image, dst_bits.offset, 0,
physdev->dc_rect.left + rect->left, physdev->dc_rect.top + rect->top,
width, height );
XPutImage( gdi_display, physdev->drawable, physdev->gc, image, src->visrect.left, 0,
physdev->dc_rect.left + dst->visrect.left,
physdev->dc_rect.top + dst->visrect.top, width, height );
wine_tsx11_unlock();
}
else
@ -1947,10 +1952,10 @@ DWORD X11DRV_PutImage( PHYSDEV dev, HBITMAP hbitmap, BITMAPINFO *info, const str
XSetSubwindowMode( gdi_display, gc, IncludeInferiors );
XSetGraphicsExposures( gdi_display, gc, False );
src_pixmap = XCreatePixmap( gdi_display, root_window, width, height, depth );
XPutImage( gdi_display, src_pixmap, gc, image, dst_bits.offset, 0, 0, 0, width, height );
XPutImage( gdi_display, src_pixmap, gc, image, src->visrect.left, 0, 0, 0, width, height );
wine_tsx11_unlock();
execute_rop( physdev, src_pixmap, gc, rect, rop );
execute_rop( physdev, src_pixmap, gc, &dst->visrect, rop );
wine_tsx11_lock();
XFreePixmap( gdi_display, src_pixmap );
@ -1981,7 +1986,7 @@ update_format:
* X11DRV_GetImage
*/
DWORD X11DRV_GetImage( PHYSDEV dev, HBITMAP hbitmap, BITMAPINFO *info,
struct gdi_image_bits *bits, const RECT *rect )
struct gdi_image_bits *bits, struct bitblt_coords *src )
{
X11DRV_PDEVICE *physdev;
X_PHYSBITMAP *bitmap;
@ -2023,12 +2028,16 @@ DWORD X11DRV_GetImage( PHYSDEV dev, HBITMAP hbitmap, BITMAPINFO *info,
FIXME( "depth %u bpp %u not supported yet\n", depth, format->bits_per_pixel );
return ERROR_BAD_FORMAT;
}
src_bits.offset = rect->left & (align - 1);
x = rect->left - src_bits.offset;
y = rect->top;
width = rect->right - x;
height = rect->bottom - rect->top;
src_bits.offset = src->visrect.left & (align - 1);
x = src->visrect.left - src_bits.offset;
y = src->visrect.top;
width = src->visrect.right - x;
height = src->visrect.bottom - src->visrect.top;
if (format->scanline_pad != 32) width = (width + (align - 1)) & ~(align - 1);
/* make the source rectangle relative to the returned bits */
src->x -= x;
src->y -= y;
OffsetRect( &src->visrect, -x, -y );
if (bitmap)
{
@ -2082,7 +2091,7 @@ DWORD X11DRV_GetImage( PHYSDEV dev, HBITMAP hbitmap, BITMAPINFO *info,
src_bits.ptr = image->data;
src_bits.is_copy = TRUE;
ret = copy_image_bits( info, color_shifts, image, &src_bits, bits, mapping,
ret = copy_image_bits( info, color_shifts, image, &src_bits, bits, src, mapping,
zeropad_masks[(width * image->bits_per_pixel) & 31] );
if (!ret && bits->ptr == image->data)

View File

@ -203,7 +203,7 @@ extern BOOL X11DRV_GetCharWidth( PHYSDEV dev, UINT firstChar, UINT lastChar, LPI
extern BOOL X11DRV_GetDeviceGammaRamp( PHYSDEV dev, LPVOID ramp ) DECLSPEC_HIDDEN;
extern BOOL X11DRV_GetICMProfile( PHYSDEV dev, LPDWORD size, LPWSTR filename ) DECLSPEC_HIDDEN;
extern DWORD X11DRV_GetImage( PHYSDEV dev, HBITMAP hbitmap, BITMAPINFO *info,
struct gdi_image_bits *bits, const RECT *rect ) DECLSPEC_HIDDEN;
struct gdi_image_bits *bits, struct bitblt_coords *src ) DECLSPEC_HIDDEN;
extern COLORREF X11DRV_GetNearestColor( PHYSDEV dev, COLORREF color ) DECLSPEC_HIDDEN;
extern COLORREF X11DRV_GetPixel( PHYSDEV dev, INT x, INT y) DECLSPEC_HIDDEN;
extern UINT X11DRV_GetSystemPaletteEntries( PHYSDEV dev, UINT start, UINT count, LPPALETTEENTRY entries ) DECLSPEC_HIDDEN;
@ -220,7 +220,7 @@ extern BOOL X11DRV_Polygon( PHYSDEV dev, const POINT* pt, INT count ) DECLSPEC_H
extern BOOL X11DRV_PolyPolygon( PHYSDEV dev, const POINT* pt, const INT* counts, UINT polygons) DECLSPEC_HIDDEN;
extern BOOL X11DRV_PolyPolyline( PHYSDEV dev, const POINT* pt, const DWORD* counts, DWORD polylines) DECLSPEC_HIDDEN;
extern DWORD X11DRV_PutImage( PHYSDEV dev, HBITMAP hbitmap, BITMAPINFO *info, const struct gdi_image_bits *bits,
const RECT *rect, DWORD rop ) DECLSPEC_HIDDEN;
struct bitblt_coords *src, struct bitblt_coords *dst, DWORD rop ) DECLSPEC_HIDDEN;
extern UINT X11DRV_RealizeDefaultPalette( PHYSDEV dev ) DECLSPEC_HIDDEN;
extern UINT X11DRV_RealizePalette( PHYSDEV dev, HPALETTE hpal, BOOL primary ) DECLSPEC_HIDDEN;
extern BOOL X11DRV_Rectangle(PHYSDEV dev, INT left, INT top, INT right, INT bottom) DECLSPEC_HIDDEN;

View File

@ -95,7 +95,7 @@ struct gdi_dc_funcs
INT (*pGetDeviceCaps)(PHYSDEV,INT);
BOOL (*pGetDeviceGammaRamp)(PHYSDEV,LPVOID);
BOOL (*pGetICMProfile)(PHYSDEV,LPDWORD,LPWSTR);
DWORD (*pGetImage)(PHYSDEV,HBITMAP,BITMAPINFO*,struct gdi_image_bits*,const RECT*);
DWORD (*pGetImage)(PHYSDEV,HBITMAP,BITMAPINFO*,struct gdi_image_bits*,struct bitblt_coords*);
COLORREF (*pGetNearestColor)(PHYSDEV,COLORREF);
COLORREF (*pGetPixel)(PHYSDEV,INT,INT);
INT (*pGetPixelFormat)(PHYSDEV);
@ -121,7 +121,7 @@ struct gdi_dc_funcs
BOOL (*pPolygon)(PHYSDEV,const POINT*,INT);
BOOL (*pPolyline)(PHYSDEV,const POINT*,INT);
BOOL (*pPolylineTo)(PHYSDEV,const POINT*,INT);
DWORD (*pPutImage)(PHYSDEV,HBITMAP,BITMAPINFO*,const struct gdi_image_bits*,const RECT*,DWORD);
DWORD (*pPutImage)(PHYSDEV,HBITMAP,BITMAPINFO*,const struct gdi_image_bits*,struct bitblt_coords*,struct bitblt_coords*,DWORD);
UINT (*pRealizeDefaultPalette)(PHYSDEV);
UINT (*pRealizePalette)(PHYSDEV,HPALETTE,BOOL);
BOOL (*pRectangle)(PHYSDEV,INT,INT,INT,INT);
@ -192,7 +192,7 @@ struct gdi_dc_funcs
};
/* increment this when you change the DC function table */
#define WINE_GDI_DRIVER_VERSION 4
#define WINE_GDI_DRIVER_VERSION 5
static inline PHYSDEV get_physdev_entry_point( PHYSDEV dev, size_t offset )
{