gdi32: Allow the PutImage entry point to optionally support stretching.
This commit is contained in:
parent
73dc9833b7
commit
97c30bdd6c
@ -167,10 +167,10 @@ BOOL nulldrv_StretchBlt( PHYSDEV dst_dev, struct bitblt_coords *dst,
|
|||||||
BITMAPINFO *src_info = (BITMAPINFO *)src_buffer;
|
BITMAPINFO *src_info = (BITMAPINFO *)src_buffer;
|
||||||
BITMAPINFO *dst_info = (BITMAPINFO *)dst_buffer;
|
BITMAPINFO *dst_info = (BITMAPINFO *)dst_buffer;
|
||||||
DWORD err;
|
DWORD err;
|
||||||
struct gdi_image_bits src_bits, dst_bits;
|
struct gdi_image_bits bits;
|
||||||
BITMAP bm;
|
BITMAP bm;
|
||||||
HBITMAP hbm;
|
HBITMAP hbm;
|
||||||
LPVOID bits;
|
LPVOID ptr;
|
||||||
INT lines;
|
INT lines;
|
||||||
|
|
||||||
/* make sure we have a real implementation for StretchDIBits */
|
/* make sure we have a real implementation for StretchDIBits */
|
||||||
@ -191,36 +191,31 @@ BOOL nulldrv_StretchBlt( PHYSDEV dst_dev, struct bitblt_coords *dst,
|
|||||||
src_info->bmiHeader.biClrUsed = 0;
|
src_info->bmiHeader.biClrUsed = 0;
|
||||||
src_info->bmiHeader.biClrImportant = 0;
|
src_info->bmiHeader.biClrImportant = 0;
|
||||||
|
|
||||||
if (!(bits = HeapAlloc(GetProcessHeap(), 0, bm.bmHeight * bm.bmWidth * 4)))
|
if (!(ptr = HeapAlloc(GetProcessHeap(), 0, bm.bmHeight * bm.bmWidth * 4)))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* Select out the src bitmap before calling GetDIBits */
|
/* Select out the src bitmap before calling GetDIBits */
|
||||||
hbm = SelectObject( src_dev->hdc, GetStockObject(DEFAULT_BITMAP) );
|
hbm = SelectObject( src_dev->hdc, GetStockObject(DEFAULT_BITMAP) );
|
||||||
lines = GetDIBits( src_dev->hdc, hbm, 0, bm.bmHeight, bits, src_info, DIB_RGB_COLORS );
|
lines = GetDIBits( src_dev->hdc, hbm, 0, bm.bmHeight, ptr, src_info, DIB_RGB_COLORS );
|
||||||
SelectObject( src_dev->hdc, hbm );
|
SelectObject( src_dev->hdc, hbm );
|
||||||
|
|
||||||
if (lines) lines = StretchDIBits( dst_dev->hdc, dst->log_x, dst->log_y, dst->log_width, dst->log_height,
|
if (lines) lines = StretchDIBits( dst_dev->hdc, dst->log_x, dst->log_y, dst->log_width, dst->log_height,
|
||||||
src->x, bm.bmHeight - src->height - src->y, src->width, src->height,
|
src->x, bm.bmHeight - src->height - src->y, src->width, src->height,
|
||||||
bits, src_info, DIB_RGB_COLORS, rop );
|
ptr, src_info, DIB_RGB_COLORS, rop );
|
||||||
HeapFree( GetProcessHeap(), 0, bits );
|
HeapFree( GetProcessHeap(), 0, ptr );
|
||||||
return (lines == src->height);
|
return (lines == src->height);
|
||||||
|
|
||||||
try_get_image:
|
try_get_image:
|
||||||
|
|
||||||
if (!(dc_src = get_dc_ptr( src_dev->hdc ))) return FALSE;
|
if (!(dc_src = get_dc_ptr( src_dev->hdc ))) return FALSE;
|
||||||
src_dev = GET_DC_PHYSDEV( dc_src, pGetImage );
|
src_dev = GET_DC_PHYSDEV( dc_src, pGetImage );
|
||||||
err = src_dev->funcs->pGetImage( src_dev, 0, src_info, &src_bits, src );
|
err = src_dev->funcs->pGetImage( src_dev, 0, src_info, &bits, src );
|
||||||
release_dc_ptr( dc_src );
|
release_dc_ptr( dc_src );
|
||||||
if (err) return FALSE;
|
if (err) return FALSE;
|
||||||
|
|
||||||
dst_dev = GET_DC_PHYSDEV( dc_dst, pPutImage );
|
dst_dev = GET_DC_PHYSDEV( dc_dst, pPutImage );
|
||||||
|
|
||||||
if ((src->width != dst->width) || (src->height != dst->height))
|
|
||||||
FIXME( "should stretch %dx%d -> %dx%d\n",
|
|
||||||
src->width, src->height, dst->width, dst->height );
|
|
||||||
|
|
||||||
memcpy( dst_info, src_info, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ));
|
memcpy( dst_info, src_info, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ));
|
||||||
err = dst_dev->funcs->pPutImage( dst_dev, 0, dst_info, &src_bits, src, dst, rop );
|
err = dst_dev->funcs->pPutImage( dst_dev, 0, dst_info, &bits, src, dst, rop );
|
||||||
if (err == ERROR_BAD_FORMAT)
|
if (err == ERROR_BAD_FORMAT)
|
||||||
{
|
{
|
||||||
/* 1-bpp source without a color table uses the destination DC colors */
|
/* 1-bpp source without a color table uses the destination DC colors */
|
||||||
@ -252,23 +247,32 @@ try_get_image:
|
|||||||
}
|
}
|
||||||
|
|
||||||
dst_info->bmiHeader.biWidth = src->visrect.right - src->visrect.left;
|
dst_info->bmiHeader.biWidth = src->visrect.right - src->visrect.left;
|
||||||
dst_bits.ptr = HeapAlloc( GetProcessHeap(), 0, get_dib_image_size( dst_info ));
|
if ((ptr = HeapAlloc( GetProcessHeap(), 0, get_dib_image_size( dst_info ))))
|
||||||
if (dst_bits.ptr)
|
|
||||||
{
|
{
|
||||||
dst_bits.is_copy = TRUE;
|
err = convert_bitmapinfo( src_info, bits.ptr, &src->visrect, dst_info, ptr );
|
||||||
dst_bits.offset = 0;
|
if (bits.free) bits.free( &bits );
|
||||||
dst_bits.free = free_heap_bits;
|
bits.ptr = ptr;
|
||||||
if (!(err = convert_bitmapinfo( src_info, src_bits.ptr, &src->visrect, dst_info, dst_bits.ptr )))
|
bits.is_copy = TRUE;
|
||||||
|
bits.offset = 0;
|
||||||
|
bits.free = free_heap_bits;
|
||||||
|
if (!err)
|
||||||
{
|
{
|
||||||
/* get rid of the fake 1-bpp table */
|
/* get rid of the fake 1-bpp table */
|
||||||
if (dst_info->bmiHeader.biClrUsed == 1) dst_info->bmiHeader.biClrUsed = 0;
|
if (dst_info->bmiHeader.biClrUsed == 1) dst_info->bmiHeader.biClrUsed = 0;
|
||||||
err = dst_dev->funcs->pPutImage( dst_dev, 0, dst_info, &dst_bits, src, dst, rop );
|
err = dst_dev->funcs->pPutImage( dst_dev, 0, dst_info, &bits, src, dst, rop );
|
||||||
}
|
}
|
||||||
if (dst_bits.free) dst_bits.free( &dst_bits );
|
|
||||||
}
|
}
|
||||||
else err = ERROR_OUTOFMEMORY;
|
else err = ERROR_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
if (src_bits.free) src_bits.free( &src_bits );
|
|
||||||
|
if (err == ERROR_TRANSFORM_NOT_SUPPORTED &&
|
||||||
|
((src->width != dst->width) || (src->height != dst->height)))
|
||||||
|
{
|
||||||
|
FIXME( "should stretch %dx%d -> %dx%d\n",
|
||||||
|
src->width, src->height, dst->width, dst->height );
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bits.free) bits.free( &bits );
|
||||||
return !err;
|
return !err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1898,6 +1898,7 @@ DWORD X11DRV_PutImage( PHYSDEV dev, HBITMAP hbitmap, BITMAPINFO *info, const str
|
|||||||
/* FIXME: could try to handle 1-bpp using XCopyPlane */
|
/* FIXME: could try to handle 1-bpp using XCopyPlane */
|
||||||
if (!matching_color_info( dev, color_shifts, info )) goto update_format;
|
if (!matching_color_info( dev, color_shifts, info )) goto update_format;
|
||||||
if (!bits) return ERROR_SUCCESS; /* just querying the format */
|
if (!bits) return ERROR_SUCCESS; /* just querying the format */
|
||||||
|
if ((src->width != dst->width) || (src->height != dst->height)) return ERROR_TRANSFORM_NOT_SUPPORTED;
|
||||||
|
|
||||||
wine_tsx11_lock();
|
wine_tsx11_lock();
|
||||||
image = XCreateImage( gdi_display, visual, depth, ZPixmap, 0, NULL,
|
image = XCreateImage( gdi_display, visual, depth, ZPixmap, 0, NULL,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user