gdi32: Add null driver entry points for StretchBlt and AlphaBlend.

This commit is contained in:
Alexandre Julliard 2011-03-18 12:59:26 +01:00
parent 5ffbce6d3c
commit 3d34f01f3c
7 changed files with 110 additions and 101 deletions

View File

@ -40,6 +40,62 @@ static inline BOOL rop_uses_src( DWORD rop )
return ((rop >> 2) & 0x330000) != (rop & 0x330000);
}
/* nulldrv fallback implementation using StretchDIBits */
BOOL CDECL nulldrv_StretchBlt( PHYSDEV dst_dev, INT xDst, INT yDst, INT widthDst, INT heightDst,
PHYSDEV src_dev, INT xSrc, INT ySrc, INT widthSrc, INT heightSrc,
DWORD rop )
{
DC *dc = get_nulldrv_dc( dst_dev );
BITMAP bm;
BITMAPINFOHEADER info_hdr;
HBITMAP hbm;
LPVOID bits;
INT lines;
POINT pts[2];
/* make sure we have a real implementation for StretchDIBits */
if (GET_DC_PHYSDEV( dc, pStretchDIBits ) == dst_dev) return 0;
pts[0].x = xSrc;
pts[0].y = ySrc;
pts[1].x = xSrc + widthSrc;
pts[1].y = ySrc + heightSrc;
LPtoDP( src_dev->hdc, pts, 2 );
xSrc = pts[0].x;
ySrc = pts[0].y;
widthSrc = pts[1].x - pts[0].x;
heightSrc = pts[1].y - pts[0].y;
if (GetObjectType( src_dev->hdc ) != OBJ_MEMDC) return FALSE;
if (!GetObjectW( GetCurrentObject( src_dev->hdc, OBJ_BITMAP ), sizeof(bm), &bm )) return FALSE;
info_hdr.biSize = sizeof(info_hdr);
info_hdr.biWidth = bm.bmWidth;
info_hdr.biHeight = bm.bmHeight;
info_hdr.biPlanes = 1;
info_hdr.biBitCount = 32;
info_hdr.biCompression = BI_RGB;
info_hdr.biSizeImage = 0;
info_hdr.biXPelsPerMeter = 0;
info_hdr.biYPelsPerMeter = 0;
info_hdr.biClrUsed = 0;
info_hdr.biClrImportant = 0;
if (!(bits = HeapAlloc(GetProcessHeap(), 0, bm.bmHeight * bm.bmWidth * 4)))
return FALSE;
/* Select out the src bitmap before calling GetDIBits */
hbm = SelectObject( src_dev->hdc, GetStockObject(DEFAULT_BITMAP) );
lines = GetDIBits( src_dev->hdc, hbm, 0, bm.bmHeight, bits, (BITMAPINFO*)&info_hdr, DIB_RGB_COLORS );
SelectObject( src_dev->hdc, hbm );
if (lines) lines = StretchDIBits( dst_dev->hdc, xDst, yDst, widthDst, heightDst,
xSrc, bm.bmHeight - heightSrc - ySrc, widthSrc, heightSrc,
bits, (BITMAPINFO*)&info_hdr, DIB_RGB_COLORS, rop );
HeapFree( GetProcessHeap(), 0, bits );
return (lines == heightSrc);
}
/***********************************************************************
* PatBlt (GDI32.@)
*/
@ -89,76 +145,19 @@ BOOL WINAPI StretchBlt( HDC hdcDst, INT xDst, INT yDst, INT widthDst, INT height
hdcSrc, xSrc, ySrc, widthSrc, heightSrc,
hdcDst, xDst, yDst, widthDst, heightDst, rop );
if (!(dcDst = get_dc_ptr( hdcDst ))) return FALSE;
update_dc( dcDst );
if (dcDst->funcs->pStretchBlt)
if ((dcSrc = get_dc_ptr( hdcSrc )))
{
if ((dcSrc = get_dc_ptr( hdcSrc )))
{
update_dc( dcSrc );
ret = dcDst->funcs->pStretchBlt( dcDst->physDev, xDst, yDst, widthDst, heightDst,
dcSrc->physDev, xSrc, ySrc, widthSrc, heightSrc,
rop );
release_dc_ptr( dcSrc );
}
release_dc_ptr( dcDst );
PHYSDEV src_dev = GET_DC_PHYSDEV( dcSrc, pStretchBlt );
PHYSDEV dst_dev = GET_DC_PHYSDEV( dcDst, pStretchBlt );
update_dc( dcSrc );
update_dc( dcDst );
ret = dst_dev->funcs->pStretchBlt( dst_dev, xDst, yDst, widthDst, heightDst,
src_dev, xSrc, ySrc, widthSrc, heightSrc, rop );
release_dc_ptr( dcSrc );
}
else if (dcDst->funcs->pStretchDIBits)
{
BITMAP bm;
BITMAPINFOHEADER info_hdr;
HBITMAP hbm;
LPVOID bits;
INT lines;
POINT pts[2];
pts[0].x = xSrc;
pts[0].y = ySrc;
pts[1].x = xSrc + widthSrc;
pts[1].y = ySrc + heightSrc;
LPtoDP(hdcSrc, pts, 2);
xSrc = pts[0].x;
ySrc = pts[0].y;
widthSrc = pts[1].x - pts[0].x;
heightSrc = pts[1].y - pts[0].y;
release_dc_ptr( dcDst );
if(GetObjectType( hdcSrc ) != OBJ_MEMDC) return FALSE;
GetObjectW(GetCurrentObject(hdcSrc, OBJ_BITMAP), sizeof(bm), &bm);
info_hdr.biSize = sizeof(info_hdr);
info_hdr.biWidth = bm.bmWidth;
info_hdr.biHeight = bm.bmHeight;
info_hdr.biPlanes = 1;
info_hdr.biBitCount = 32;
info_hdr.biCompression = BI_RGB;
info_hdr.biSizeImage = 0;
info_hdr.biXPelsPerMeter = 0;
info_hdr.biYPelsPerMeter = 0;
info_hdr.biClrUsed = 0;
info_hdr.biClrImportant = 0;
if(!(bits = HeapAlloc(GetProcessHeap(), 0, bm.bmHeight * bm.bmWidth * 4)))
return FALSE;
/* Select out the src bitmap before calling GetDIBits */
hbm = SelectObject(hdcSrc, GetStockObject(DEFAULT_BITMAP));
GetDIBits(hdcSrc, hbm, 0, bm.bmHeight, bits, (BITMAPINFO*)&info_hdr, DIB_RGB_COLORS);
SelectObject(hdcSrc, hbm);
lines = StretchDIBits(hdcDst, xDst, yDst, widthDst, heightDst, xSrc, bm.bmHeight - heightSrc - ySrc,
widthSrc, heightSrc, bits, (BITMAPINFO*)&info_hdr, DIB_RGB_COLORS, rop);
HeapFree(GetProcessHeap(), 0, bits);
return (lines == heightSrc);
}
else release_dc_ptr( dcDst );
release_dc_ptr( dcDst );
return ret;
}
@ -456,22 +455,22 @@ BOOL WINAPI GdiAlphaBlend(HDC hdcDst, int xDst, int yDst, int widthDst, int heig
BOOL ret = FALSE;
DC *dcDst, *dcSrc;
TRACE( "%p %d,%d %dx%d -> %p %d,%d %dx%d op=%02x flags=%02x srcconstalpha=%02x alphafmt=%02x\n",
hdcSrc, xSrc, ySrc, widthSrc, heightSrc, hdcDst, xDst, yDst, widthDst, heightDst,
blendFunction.BlendOp, blendFunction.BlendFlags,
blendFunction.SourceConstantAlpha, blendFunction.AlphaFormat );
dcSrc = get_dc_ptr( hdcSrc );
if (!dcSrc) return FALSE;
if ((dcDst = get_dc_ptr( hdcDst )))
{
PHYSDEV src_dev = GET_DC_PHYSDEV( dcSrc, pAlphaBlend );
PHYSDEV dst_dev = GET_DC_PHYSDEV( dcDst, pAlphaBlend );
update_dc( dcSrc );
update_dc( dcDst );
TRACE("%p %d,%d %dx%d -> %p %d,%d %dx%d op=%02x flags=%02x srcconstalpha=%02x alphafmt=%02x\n",
hdcSrc, xSrc, ySrc, widthSrc, heightSrc,
hdcDst, xDst, yDst, widthDst, heightDst,
blendFunction.BlendOp, blendFunction.BlendFlags,
blendFunction.SourceConstantAlpha, blendFunction.AlphaFormat);
if (dcDst->funcs->pAlphaBlend)
ret = dcDst->funcs->pAlphaBlend( dcDst->physDev, xDst, yDst, widthDst, heightDst,
dcSrc->physDev, xSrc, ySrc, widthSrc, heightSrc,
blendFunction );
ret = dst_dev->funcs->pAlphaBlend( dst_dev, xDst, yDst, widthDst, heightDst,
src_dev, xSrc, ySrc, widthSrc, heightSrc, blendFunction );
release_dc_ptr( dcDst );
}
release_dc_ptr( dcSrc );

View File

@ -317,6 +317,13 @@ static INT CDECL nulldrv_AbortDoc( PHYSDEV dev )
return 0;
}
static BOOL CDECL nulldrv_AlphaBlend( PHYSDEV dst_dev, INT x_dst, INT y_dst, INT width_dst, INT height_dst,
PHYSDEV src_dev, INT x_src, INT y_src, INT width_src, INT height_src,
BLENDFUNCTION func)
{
return TRUE;
}
static BOOL CDECL nulldrv_Arc( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
INT xstart, INT ystart, INT xend, INT yend )
{
@ -788,7 +795,7 @@ const DC_FUNCTIONS null_driver =
{
nulldrv_AbortDoc, /* pAbortDoc */
nulldrv_AbortPath, /* pAbortPath */
NULL, /* pAlphaBlend */
nulldrv_AlphaBlend, /* pAlphaBlend */
nulldrv_AngleArc, /* pAngleArc */
nulldrv_Arc, /* pArc */
nulldrv_ArcTo, /* pArcTo */
@ -898,7 +905,7 @@ const DC_FUNCTIONS null_driver =
nulldrv_SetWorldTransform, /* pSetWorldTransform */
nulldrv_StartDoc, /* pStartDoc */
nulldrv_StartPage, /* pStartPage */
NULL, /* pStretchBlt */
nulldrv_StretchBlt, /* pStretchBlt */
nulldrv_StretchDIBits, /* pStretchDIBits */
nulldrv_StrokeAndFillPath, /* pStrokeAndFillPath */
nulldrv_StrokePath, /* pStrokePath */

View File

@ -77,10 +77,11 @@ BOOL CDECL EMFDRV_StretchBlt( PHYSDEV devDst, INT xDst, INT yDst, INT widthDst,
BITMAP BM;
WORD nBPP = 0;
LPBITMAPINFOHEADER lpBmiH;
EMFDRV_PDEVICE* physDevSrc = (EMFDRV_PDEVICE*)devSrc;
HBITMAP hBitmap = NULL;
DWORD emrType;
if (devSrc->funcs == devDst->funcs) return FALSE; /* can't use a metafile DC as source */
if (widthSrc == widthDst && heightSrc == heightDst)
{
emrType = EMR_BITBLT;
@ -92,7 +93,7 @@ BOOL CDECL EMFDRV_StretchBlt( PHYSDEV devDst, INT xDst, INT yDst, INT widthDst,
emrSize = sizeof(EMRSTRETCHBLT);
}
hBitmap = GetCurrentObject(physDevSrc->hdc, OBJ_BITMAP);
hBitmap = GetCurrentObject(devSrc->hdc, OBJ_BITMAP);
if(sizeof(BITMAP) != GetObjectW(hBitmap, sizeof(BITMAP), &BM))
return FALSE;
@ -122,8 +123,8 @@ BOOL CDECL EMFDRV_StretchBlt( PHYSDEV devDst, INT xDst, INT yDst, INT widthDst,
pEMR->dwRop = rop;
pEMR->xSrc = xSrc;
pEMR->ySrc = ySrc;
GetWorldTransform(physDevSrc->hdc, &pEMR->xformSrc);
pEMR->crBkColorSrc = GetBkColor(physDevSrc->hdc);
GetWorldTransform(devSrc->hdc, &pEMR->xformSrc);
pEMR->crBkColorSrc = GetBkColor(devSrc->hdc);
pEMR->iUsageSrc = DIB_RGB_COLORS;
pEMR->offBmiSrc = emrSize;
pEMR->offBitsSrc = emrSize + bmiSize;
@ -155,7 +156,7 @@ BOOL CDECL EMFDRV_StretchBlt( PHYSDEV devDst, INT xDst, INT yDst, INT widthDst,
lpBmiH->biClrImportant = 0;
/* Initialize bitmap bits */
if (GetDIBits(physDevSrc->hdc, hBitmap, 0, (UINT)lpBmiH->biHeight,
if (GetDIBits(devSrc->hdc, hBitmap, 0, (UINT)lpBmiH->biHeight,
(BYTE*)pEMR + pEMR->offBitsSrc,
(LPBITMAPINFO)lpBmiH, DIB_RGB_COLORS))
{

View File

@ -548,6 +548,8 @@ extern BOOL CDECL nulldrv_SetViewportOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt
extern BOOL CDECL nulldrv_SetWindowExtEx( PHYSDEV dev, INT cx, INT cy, SIZE *size ) DECLSPEC_HIDDEN;
extern BOOL CDECL nulldrv_SetWindowOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt ) DECLSPEC_HIDDEN;
extern BOOL CDECL nulldrv_SetWorldTransform( PHYSDEV dev, const XFORM *xform ) DECLSPEC_HIDDEN;
extern BOOL CDECL nulldrv_StretchBlt( PHYSDEV dst_dev, INT xDst, INT yDst, INT widthDst, INT heightDst,
PHYSDEV src_dev, INT xSrc, INT ySrc, INT widthSrc, INT heightSrc, DWORD rop ) DECLSPEC_HIDDEN;
extern INT CDECL nulldrv_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst, INT heightDst,
INT xSrc, INT ySrc, INT widthSrc, INT heightSrc, const void *bits,
const BITMAPINFO *info, UINT coloruse, DWORD rop ) DECLSPEC_HIDDEN;

View File

@ -51,16 +51,17 @@ BOOL CDECL MFDRV_StretchBlt( PHYSDEV devDst, INT xDst, INT yDst, INT widthDst,
DWORD len;
METARECORD *mr;
BITMAP BM;
METAFILEDRV_PDEVICE *physDevSrc = (METAFILEDRV_PDEVICE *)devSrc;
#ifdef STRETCH_VIA_DIB
LPBITMAPINFOHEADER lpBMI;
WORD nBPP;
#endif
HBITMAP hBitmap = GetCurrentObject(physDevSrc->hdc, OBJ_BITMAP);
HBITMAP hBitmap = GetCurrentObject(devSrc->hdc, OBJ_BITMAP);
if (devSrc->funcs == devDst->funcs) return FALSE; /* can't use a metafile DC as source */
if (GetObjectW(hBitmap, sizeof(BITMAP), &BM) != sizeof(BITMAP))
{
WARN("bad bitmap object %p passed for hdc %p\n", hBitmap, physDevSrc->hdc);
WARN("bad bitmap object %p passed for hdc %p\n", hBitmap, devSrc->hdc);
return FALSE;
}
#ifdef STRETCH_VIA_DIB
@ -81,14 +82,14 @@ BOOL CDECL MFDRV_StretchBlt( PHYSDEV devDst, INT xDst, INT yDst, INT widthDst,
lpBMI->biSizeImage = DIB_GetDIBWidthBytes(BM.bmWidth, nBPP) * lpBMI->biHeight;
lpBMI->biClrUsed = nBPP <= 8 ? 1 << nBPP : 0;
lpBMI->biCompression = BI_RGB;
lpBMI->biXPelsPerMeter = MulDiv(GetDeviceCaps(physDevSrc->hdc,LOGPIXELSX),3937,100);
lpBMI->biYPelsPerMeter = MulDiv(GetDeviceCaps(physDevSrc->hdc,LOGPIXELSY),3937,100);
lpBMI->biXPelsPerMeter = MulDiv(GetDeviceCaps(devSrc->hdc,LOGPIXELSX),3937,100);
lpBMI->biYPelsPerMeter = MulDiv(GetDeviceCaps(devSrc->hdc,LOGPIXELSY),3937,100);
lpBMI->biClrImportant = 0; /* 1 meter = 39.37 inch */
TRACE("MF_StretchBltViaDIB->len = %d rop=%x PixYPM=%d Caps=%d\n",
len,rop,lpBMI->biYPelsPerMeter,GetDeviceCaps(physDevSrc->hdc, LOGPIXELSY));
len,rop,lpBMI->biYPelsPerMeter,GetDeviceCaps(devSrc->hdc, LOGPIXELSY));
if (GetDIBits(physDevSrc->hdc, hBitmap, 0, (UINT)lpBMI->biHeight,
if (GetDIBits(devSrc->hdc, hBitmap, 0, (UINT)lpBMI->biHeight,
(LPSTR)lpBMI + bitmap_info_size( (BITMAPINFO *)lpBMI,
DIB_RGB_COLORS ),
(LPBITMAPINFO)lpBMI, DIB_RGB_COLORS))

View File

@ -1486,9 +1486,10 @@ BOOL CDECL X11DRV_PatBlt( X11DRV_PDEVICE *physDev, INT x, INT y, INT width, INT
* X11DRV_StretchBlt
*/
BOOL CDECL X11DRV_StretchBlt( X11DRV_PDEVICE *physDevDst, INT xDst, INT yDst, INT widthDst, INT heightDst,
X11DRV_PDEVICE *physDevSrc, INT xSrc, INT ySrc, INT widthSrc, INT heightSrc,
PHYSDEV src_dev, INT xSrc, INT ySrc, INT widthSrc, INT heightSrc,
DWORD rop )
{
X11DRV_PDEVICE *physDevSrc = (X11DRV_PDEVICE *)src_dev; /* FIXME: check that it's really an x11 dev */
BOOL usePat, useDst, destUsed, fStretch, fNullBrush;
struct bitblt_coords src, dst;
INT width, height;
@ -1504,7 +1505,7 @@ BOOL CDECL X11DRV_StretchBlt( X11DRV_PDEVICE *physDevDst, INT xDst, INT yDst, IN
src.y = ySrc;
src.width = widthSrc;
src.height = heightSrc;
src.layout = physDevSrc ? GetLayout( physDevSrc->hdc ) : 0;
src.layout = GetLayout( physDevSrc->hdc );
dst.x = xDst;
dst.y = yDst;
dst.width = widthDst;
@ -1685,9 +1686,10 @@ done:
* X11DRV_AlphaBlend
*/
BOOL CDECL X11DRV_AlphaBlend( X11DRV_PDEVICE *physDevDst, INT xDst, INT yDst, INT widthDst, INT heightDst,
X11DRV_PDEVICE *physDevSrc, INT xSrc, INT ySrc, INT widthSrc, INT heightSrc,
PHYSDEV src_dev, INT xSrc, INT ySrc, INT widthSrc, INT heightSrc,
BLENDFUNCTION blendfn )
{
X11DRV_PDEVICE *physDevSrc = (X11DRV_PDEVICE *)src_dev; /* FIXME: check that it's really an x11 dev */
struct bitblt_coords src, dst;
src.x = xSrc;

View File

@ -141,10 +141,15 @@ typedef UINT X_PHYSFONT;
struct xrender_info;
typedef struct gdi_physdev
{
void *reserved[3];
} *PHYSDEV;
/* X physical device */
typedef struct
{
void *reserved[3]; /* reserved for gdi */
struct gdi_physdev dev;
HDC hdc;
GC gc; /* X Window GC */
Drawable drawable;
@ -186,10 +191,6 @@ extern GC get_bitmap_gc(int depth);
/* Wine driver X11 functions */
extern BOOL CDECL X11DRV_AlphaBlend( X11DRV_PDEVICE *physDevDst, INT xDst, INT yDst,
INT widthDst, INT heightDst,
X11DRV_PDEVICE *physDevSrc, INT xSrc, INT ySrc,
INT widthSrc, INT heightSrc, BLENDFUNCTION blendfn );
extern BOOL CDECL X11DRV_EnumDeviceFonts( X11DRV_PDEVICE *physDev, LPLOGFONTW plf,
FONTENUMPROCW dfeproc, LPARAM lp );
extern LONG CDECL X11DRV_GetBitmapBits( HBITMAP hbitmap, void *bits, LONG count );
@ -198,10 +199,6 @@ extern BOOL CDECL X11DRV_GetCharWidth( X11DRV_PDEVICE *physDev, UINT firstChar,
extern BOOL CDECL X11DRV_GetTextExtentExPoint( X11DRV_PDEVICE *physDev, LPCWSTR str, INT count,
INT maxExt, LPINT lpnFit, LPINT alpDx, LPSIZE size );
extern BOOL CDECL X11DRV_GetTextMetrics(X11DRV_PDEVICE *physDev, TEXTMETRICW *metrics);
extern BOOL CDECL X11DRV_StretchBlt( X11DRV_PDEVICE *physDevDst, INT xDst, INT yDst,
INT widthDst, INT heightDst,
X11DRV_PDEVICE *physDevSrc, INT xSrc, INT ySrc,
INT widthSrc, INT heightSrc, DWORD rop );
extern BOOL CDECL X11DRV_LineTo( X11DRV_PDEVICE *physDev, INT x, INT y);
extern BOOL CDECL X11DRV_Arc( X11DRV_PDEVICE *physDev, INT left, INT top, INT right,
INT bottom, INT xstart, INT ystart, INT xend, INT yend );