From 66a05b2aec118946d75f159237a3c73df38f2486 Mon Sep 17 00:00:00 2001 From: Huw Davies Date: Thu, 23 Feb 2006 12:02:03 +0000 Subject: [PATCH] gdi32: Fallback to StretchDIBits if the driver doesn't support BitBlt. --- dlls/gdi/bitblt.c | 65 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 57 insertions(+), 8 deletions(-) diff --git a/dlls/gdi/bitblt.c b/dlls/gdi/bitblt.c index d15b39a64ca..221fc6dfd67 100644 --- a/dlls/gdi/bitblt.c +++ b/dlls/gdi/bitblt.c @@ -55,19 +55,68 @@ BOOL WINAPI BitBlt( HDC hdcDst, INT xDst, INT yDst, INT width, BOOL ret = FALSE; DC *dcDst, *dcSrc; - if ((dcSrc = DC_GetDCUpdate( hdcSrc ))) GDI_ReleaseObj( hdcSrc ); - /* FIXME: there is a race condition here */ - if ((dcDst = DC_GetDCUpdate( hdcDst ))) + if ((dcDst = DC_GetDCUpdate( hdcDst )) && dcDst->funcs->pBitBlt) { - dcSrc = DC_GetDCPtr( hdcSrc ); + GDI_ReleaseObj( hdcDst ); + /* FIXME: there is a race condition here */ + dcSrc = DC_GetDCUpdate( hdcSrc ); + dcDst = DC_GetDCPtr( hdcDst ); TRACE("hdcSrc=%p %d,%d -> hdcDest=%p %d,%d %dx%d rop=%06lx\n", hdcSrc, xSrc, ySrc, hdcDst, xDst, yDst, width, height, rop); - if (dcDst->funcs->pBitBlt) - ret = dcDst->funcs->pBitBlt( dcDst->physDev, xDst, yDst, width, height, - dcSrc ? dcSrc->physDev : NULL, xSrc, ySrc, rop ); - if (dcSrc) GDI_ReleaseObj( hdcSrc ); + + ret = dcDst->funcs->pBitBlt( dcDst->physDev, xDst, yDst, width, height, + dcSrc ? dcSrc->physDev : NULL, xSrc, ySrc, rop ); + GDI_ReleaseObj( hdcDst ); + if (dcSrc) GDI_ReleaseObj( hdcSrc ); } + else if(dcDst && dcDst->funcs->pStretchDIBits) + { + BITMAP bm; + BITMAPINFOHEADER info_hdr; + HBITMAP hbm; + LPVOID bits; + INT lines; + + GDI_ReleaseObj( hdcDst ); + + if(GetObjectType( hdcSrc ) != OBJ_MEMDC) + { + FIXME("hdcSrc isn't a memory dc. Don't yet cope with this\n"); + 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, width, height, xSrc, ySrc, width, height, + bits, (BITMAPINFO*)&info_hdr, DIB_RGB_COLORS, rop); + + HeapFree(GetProcessHeap(), 0, bits); + return (lines == bm.bmHeight); + } + else if(dcDst) + GDI_ReleaseObj( hdcDst ); + return ret; }