From 73dc9833b700fe07f9dee1adfe4a18c7771054f3 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Thu, 21 Jul 2011 11:17:13 +0200 Subject: [PATCH] gdi32: Pass the full bitblt_coords structure to the Get/PutImage entry points. --- dlls/gdi32/bitblt.c | 13 ++++----- dlls/gdi32/dib.c | 20 +++++++------- dlls/gdi32/driver.c | 5 ++-- dlls/winex11.drv/bitblt.c | 55 +++++++++++++++++++++++---------------- dlls/winex11.drv/x11drv.h | 4 +-- include/wine/gdi_driver.h | 6 ++--- 6 files changed, 56 insertions(+), 47 deletions(-) diff --git a/dlls/gdi32/bitblt.c b/dlls/gdi32/bitblt.c index 0f266ec4ec0..2d81ad53d48 100644 --- a/dlls/gdi32/bitblt.c +++ b/dlls/gdi32/bitblt.c @@ -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 ); } diff --git a/dlls/gdi32/dib.c b/dlls/gdi32/dib.c index 181515111e0..7e5354bd69e 100644 --- a/dlls/gdi32/dib.c +++ b/dlls/gdi32/dib.c @@ -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); diff --git a/dlls/gdi32/driver.c b/dlls/gdi32/driver.c index 0c268399d55..71d15cd7a4d 100644 --- a/dlls/gdi32/driver.c +++ b/dlls/gdi32/driver.c @@ -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; } diff --git a/dlls/winex11.drv/bitblt.c b/dlls/winex11.drv/bitblt.c index c1dc6c4fbf0..015a3e07c4e 100644 --- a/dlls/winex11.drv/bitblt.c +++ b/dlls/winex11.drv/bitblt.c @@ -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) diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 1729546e2dd..1754b1b343f 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -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; diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h index 3a9685ce5d4..b4166bf1047 100644 --- a/include/wine/gdi_driver.h +++ b/include/wine/gdi_driver.h @@ -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 ) {