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

Huw D M Davies h.davies1 at physics.ox.ac.uk
Thu Feb 23 06:02:03 CST 2006


Here's a better version:

        Huw Davies <huw at codeweavers.com>
        gdi32: Fallback to StretchDIBits if the driver doesn't support BitBlt
-- 
Huw Davies
huw at codeweavers.com
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-patches mailing list