gdiplus: Use StretchBlt instead of GdiAlphaBlend if device doesn't support alpha blending. Resend.

Dmitry Timoshkov dmitry at baikal.ru
Fri Apr 13 00:03:49 CDT 2012


This patch makes printing of PNG and other images work from applications
which use gdiplus for that.

Printer drivers can't support transparency or alpha blending in any way.
This patch was tested with wide range of images (some mixed with other
graphics and text), and output matches what native gdiplus does.
---
 dlls/gdiplus/graphics.c |   63 ++++++++++++++++++++++++-----------------------
 1 file changed, 32 insertions(+), 31 deletions(-)

diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c
index 2c6c4b2..0845579 100644
--- a/dlls/gdiplus/graphics.c
+++ b/dlls/gdiplus/graphics.c
@@ -340,6 +340,30 @@ static void transform_and_round_points(GpGraphics *graphics, POINT *pti,
     }
 }
 
+static void gdi_alpha_blend(GpGraphics *graphics, INT dst_x, INT dst_y, INT dst_width, INT dst_height,
+                            HDC hdc, INT src_x, INT src_y, INT src_width, INT src_height)
+{
+    if (GetDeviceCaps(graphics->hdc, SHADEBLENDCAPS) == SB_NONE)
+    {
+        TRACE("alpha blending not supported by device, fallback to StretchBlt\n");
+
+        StretchBlt(graphics->hdc, dst_x, dst_y, dst_width, dst_height,
+                   hdc, src_x, src_y, src_width, src_height, SRCCOPY);
+    }
+    else
+    {
+        BLENDFUNCTION bf;
+
+        bf.BlendOp = AC_SRC_OVER;
+        bf.BlendFlags = 0;
+        bf.SourceConstantAlpha = 255;
+        bf.AlphaFormat = AC_SRC_ALPHA;
+
+        GdiAlphaBlend(graphics->hdc, dst_x, dst_y, dst_width, dst_height,
+                      hdc, src_x, src_y, src_width, src_height, bf);
+    }
+}
+
 /* Draw non-premultiplied ARGB data to the given graphics object */
 static GpStatus alpha_blend_pixels(GpGraphics *graphics, INT dst_x, INT dst_y,
     const BYTE *src, INT src_width, INT src_height, INT src_stride)
@@ -370,10 +394,9 @@ static GpStatus alpha_blend_pixels(GpGraphics *graphics, INT dst_x, INT dst_y,
     else
     {
         HDC hdc;
-        HBITMAP hbitmap, old_hbm=NULL;
+        HBITMAP hbitmap;
         BITMAPINFOHEADER bih;
         BYTE *temp_bits;
-        BLENDFUNCTION bf;
 
         hdc = CreateCompatibleDC(0);
 
@@ -395,17 +418,9 @@ static GpStatus alpha_blend_pixels(GpGraphics *graphics, INT dst_x, INT dst_y,
         convert_32bppARGB_to_32bppPARGB(src_width, src_height, temp_bits,
             4 * src_width, src, src_stride);
 
-        old_hbm = SelectObject(hdc, hbitmap);
-
-        bf.BlendOp = AC_SRC_OVER;
-        bf.BlendFlags = 0;
-        bf.SourceConstantAlpha = 255;
-        bf.AlphaFormat = AC_SRC_ALPHA;
-
-        GdiAlphaBlend(graphics->hdc, dst_x, dst_y, src_width, src_height,
-            hdc, 0, 0, src_width, src_height, bf);
-
-        SelectObject(hdc, old_hbm);
+        SelectObject(hdc, hbitmap);
+        gdi_alpha_blend(graphics, dst_x, dst_y, src_width, src_height,
+                        hdc, 0, 0, src_width, src_height);
         DeleteDC(hdc);
         DeleteObject(hbitmap);
 
@@ -918,19 +933,12 @@ static void brush_fill_path(GpGraphics *graphics, GpBrush* brush)
             if (GetClipBox(graphics->hdc, &rc) != NULLREGION)
             {
                 HDC hdc = CreateCompatibleDC(NULL);
-                BLENDFUNCTION bf;
 
                 if (!hdc) break;
 
                 SelectObject(hdc, bmp);
-
-                bf.BlendOp = AC_SRC_OVER;
-                bf.BlendFlags = 0;
-                bf.SourceConstantAlpha = 255;
-                bf.AlphaFormat = AC_SRC_ALPHA;
-
-                GdiAlphaBlend(graphics->hdc, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, hdc, 0, 0, 1, 1, bf);
-
+                gdi_alpha_blend(graphics, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top,
+                                hdc, 0, 0, 1, 1);
                 DeleteDC(hdc);
             }
 
@@ -3288,15 +3296,8 @@ GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image
 
             if (bitmap->format & (PixelFormatAlpha|PixelFormatPAlpha))
             {
-                BLENDFUNCTION bf;
-
-                bf.BlendOp = AC_SRC_OVER;
-                bf.BlendFlags = 0;
-                bf.SourceConstantAlpha = 255;
-                bf.AlphaFormat = AC_SRC_ALPHA;
-
-                GdiAlphaBlend(graphics->hdc, pti[0].x, pti[0].y, pti[1].x-pti[0].x, pti[2].y-pti[0].y,
-                    hdc, srcx, srcy, srcwidth, srcheight, bf);
+                gdi_alpha_blend(graphics, pti[0].x, pti[0].y, pti[1].x - pti[0].x, pti[2].y - pti[0].y,
+                                hdc, srcx, srcy, srcwidth, srcheight);
             }
             else
             {
-- 
1.7.9.4




More information about the wine-patches mailing list