gdi: StretchBlt fallback

Huw D M Davies h.davies1 at physics.ox.ac.uk
Fri Nov 25 08:20:05 CST 2005


The first step to get Picasa printing [#3387].  While it does indeed
now print, the output only consists of the blue component for some
reason...

        Huw Davies <huw at codeweavers.com>
        If the driver doesn't support StretchBlt try to use
        StretchDIBits instead.        
-- 
Huw Davies
huw at codeweavers.com
Index: dlls/gdi/bitblt.c
===================================================================
RCS file: /home/wine/wine/dlls/gdi/bitblt.c,v
retrieving revision 1.7
diff -u -p -r1.7 bitblt.c
--- dlls/gdi/bitblt.c	6 May 2005 15:44:32 -0000	1.7
+++ dlls/gdi/bitblt.c	25 Nov 2005 14:01:41 -0000
@@ -84,25 +84,68 @@ BOOL WINAPI StretchBlt( HDC hdcDst, INT 
     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->pStretchBlt)
     {
-        dcSrc = DC_GetDCPtr( hdcSrc );
-
-        TRACE("%p %d,%d %dx%d -> %p %d,%d %dx%d rop=%06lx\n",
-              hdcSrc, xSrc, ySrc, widthSrc, heightSrc,
-              hdcDst, xDst, yDst, widthDst, heightDst, rop );
+        GDI_ReleaseObj( hdcDst );
+        /* FIXME: there is a race condition here */
+        if ((dcSrc = DC_GetDCUpdate( hdcSrc )))
+        {
+            dcDst = DC_GetDCPtr( hdcDst );
+
+            TRACE("%p %d,%d %dx%d -> %p %d,%d %dx%d rop=%06lx\n",
+                  hdcSrc, xSrc, ySrc, widthSrc, heightSrc,
+                  hdcDst, xDst, yDst, widthDst, heightDst, rop );
+
+            ret = dcDst->funcs->pStretchBlt( dcDst->physDev, xDst, yDst, widthDst, heightDst,
+                                             dcSrc->physDev, xSrc, ySrc, widthSrc, heightSrc,
+                                             rop );
+            GDI_ReleaseObj( hdcDst );
+            GDI_ReleaseObj( hdcSrc );
+        }
+    }
+    else if(dcDst && dcDst->funcs->pStretchDIBits)
+    {
+        BITMAP bm;
+        BITMAPINFOHEADER info_hdr;
+        HBITMAP hbm;
+        LPVOID bits;
+        INT lines;
 
-	if (dcSrc) {
-	    if (dcDst->funcs->pStretchBlt)
-		ret = dcDst->funcs->pStretchBlt( dcDst->physDev, xDst, yDst, widthDst, heightDst,
-                                                 dcSrc->physDev, xSrc, ySrc, widthSrc, heightSrc,
-                                                 rop );
-	    GDI_ReleaseObj( hdcSrc );
-	}
         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, widthDst, heightDst, xSrc, ySrc, widthSrc, heightSrc,
+                              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