Huw Davies : gdi32: Fallback to StretchDIBits if the driver doesn' t support BitBlt.

Alexandre Julliard julliard at wine.codeweavers.com
Fri Feb 24 04:47:55 CST 2006


Module: wine
Branch: refs/heads/master
Commit: 66a05b2aec118946d75f159237a3c73df38f2486
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=66a05b2aec118946d75f159237a3c73df38f2486

Author: Huw Davies <huw at codeweavers.com>
Date:   Thu Feb 23 12:02:03 2006 +0000

gdi32: Fallback to StretchDIBits if the driver doesn't support BitBlt.

---

 dlls/gdi/bitblt.c |   63 +++++++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 56 insertions(+), 7 deletions(-)

diff --git a/dlls/gdi/bitblt.c b/dlls/gdi/bitblt.c
index d15b39a..221fc6d 100644
--- a/dlls/gdi/bitblt.c
+++ b/dlls/gdi/bitblt.c
@@ -55,19 +55,68 @@ BOOL WINAPI BitBlt( HDC hdcDst, INT xDst
     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 );
+
+        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;
 }
 




More information about the wine-cvs mailing list