From 3d34f01f3c1dc461446d6c2894b2c88705dd8a58 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Fri, 18 Mar 2011 12:59:26 +0100 Subject: [PATCH] gdi32: Add null driver entry points for StretchBlt and AlphaBlend. --- dlls/gdi32/bitblt.c | 149 +++++++++++++++++------------------ dlls/gdi32/driver.c | 11 ++- dlls/gdi32/enhmfdrv/bitblt.c | 11 +-- dlls/gdi32/gdi_private.h | 2 + dlls/gdi32/mfdrv/bitblt.c | 15 ++-- dlls/winex11.drv/bitblt.c | 8 +- dlls/winex11.drv/x11drv.h | 15 ++-- 7 files changed, 110 insertions(+), 101 deletions(-) diff --git a/dlls/gdi32/bitblt.c b/dlls/gdi32/bitblt.c index daf29cd25bb..6c556d7acbf 100644 --- a/dlls/gdi32/bitblt.c +++ b/dlls/gdi32/bitblt.c @@ -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 ); diff --git a/dlls/gdi32/driver.c b/dlls/gdi32/driver.c index d2059060c35..bdbb318c4bc 100644 --- a/dlls/gdi32/driver.c +++ b/dlls/gdi32/driver.c @@ -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 */ diff --git a/dlls/gdi32/enhmfdrv/bitblt.c b/dlls/gdi32/enhmfdrv/bitblt.c index 377efad763f..bb773556218 100644 --- a/dlls/gdi32/enhmfdrv/bitblt.c +++ b/dlls/gdi32/enhmfdrv/bitblt.c @@ -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)) { diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h index 44a7eba9f0b..5fff65c4e92 100644 --- a/dlls/gdi32/gdi_private.h +++ b/dlls/gdi32/gdi_private.h @@ -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; diff --git a/dlls/gdi32/mfdrv/bitblt.c b/dlls/gdi32/mfdrv/bitblt.c index c09148f12ee..0a8a9005c90 100644 --- a/dlls/gdi32/mfdrv/bitblt.c +++ b/dlls/gdi32/mfdrv/bitblt.c @@ -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)) diff --git a/dlls/winex11.drv/bitblt.c b/dlls/winex11.drv/bitblt.c index 47515b6216d..6348165200c 100644 --- a/dlls/winex11.drv/bitblt.c +++ b/dlls/winex11.drv/bitblt.c @@ -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; diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 6048096c78d..e51a6146295 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -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 );