Partial fix for issue 17982 (PatBlt cannot draw arbitrary parallelograms based on the world transform)

Alexander Almaleh sashoalm at gmail.com
Sun Jul 27 23:34:04 CDT 2014


I made a partial fix of this bug -
https://bugs.winehq.org/show_bug.cgi?id=17982, only for the PATCOPY rop.
It's based on the observation that the Polygon() function does
support arbitrary parallelograms, including when defined through the XFORM
matrix, so for PATCOPY we can just delegate the implementation to it (with
a NULL_PEN because PatBlt doesn't use a pen).

Is this patch acceptable? I have no idea if delegating to Polygon() will
hurt performance. If that is a concern, I can do it only in case the
physical coordinates after the world transform are not rectangular.

If it is, I will submit it to wine-patches, then.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.winehq.org/pipermail/wine-devel/attachments/20140728/826416b2/attachment.html>
-------------- next part --------------
commit 2df13e4fa12132d0ad8dcf614e0fa45357177f29
Author: Alexander Almaleh <sashoalm at gmail.com>
Date:   Sun Jul 27 22:51:43 2014 +0300

    Fix for issue 17982.

diff --git a/dlls/gdi32/bitblt.c b/dlls/gdi32/bitblt.c
index 762ca0f..5c81ad2 100644
--- a/dlls/gdi32/bitblt.c
+++ b/dlls/gdi32/bitblt.c
@@ -518,6 +518,21 @@ COLORREF nulldrv_GetPixel( PHYSDEV dev, INT x, INT y )
  */
 BOOL WINAPI PatBlt( HDC hdc, INT left, INT top, INT width, INT height, DWORD rop)
 {
+    // Fix for issue 17982.
+    // For PAT_COPY, we delegate the blitting operation to Polygon(),
+    // because it can handle rotation in the XFORM matrix.
+    if (rop == PATCOPY)
+    {
+        POINT p[4] = { left,top, left+width,top, left+width,top+height,
+            left,top+height };
+        // Polygon() uses the pen, but PatBlt() does not, so we select
+        // a NULL_PEN for the operation.
+        HGDIOBJ old = SelectObject(hdc, GetStockObject(NULL_PEN));
+        BOOL ret = Polygon(hdc, p, 4);
+        SelectObject(hdc, old);
+        return ret;
+    }
+
     DC * dc;
     BOOL ret = FALSE;
 


More information about the wine-devel mailing list