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

Huw D M Davies h.davies1 at physics.ox.ac.uk
Wed Feb 22 09:36:29 CST 2006


        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..15d9e7b 100644
--- a/dlls/gdi/bitblt.c
+++ b/dlls/gdi/bitblt.c
@@ -55,19 +55,66 @@ 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 );
-        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)
+        GDI_ReleaseObj( hdcDst );
+        /* FIXME: there is a race condition here */
+        if ((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);
+
             ret = dcDst->funcs->pBitBlt( dcDst->physDev, xDst, yDst, width, height,
                                          dcSrc ? dcSrc->physDev : NULL, xSrc, ySrc, rop );
-        if (dcSrc) GDI_ReleaseObj( hdcSrc );
+
+            GDI_ReleaseObj( hdcDst );
+            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) 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