[PATCH 4/4] gdi32: Adjust destination coordinates in some special cases.

Akihiro Sagawa sagawa.aki at gmail.com
Thu Oct 11 10:35:39 CDT 2018


When the source rectangle needs to flip and it doesn't fit in the source
device area, the destination image is flipped but the destination area
isn't flipped.

Signed-off-by: Akihiro Sagawa <sagawa.aki at gmail.com>
---
 dlls/gdi32/bitblt.c       | 26 ++++++++++++++++++++++----
 dlls/gdi32/tests/bitmap.c |  4 ++--
 2 files changed, 24 insertions(+), 6 deletions(-)

diff --git a/dlls/gdi32/bitblt.c b/dlls/gdi32/bitblt.c
index 6f5af649c6..abca82245a 100644
--- a/dlls/gdi32/bitblt.c
+++ b/dlls/gdi32/bitblt.c
@@ -60,12 +60,30 @@ BOOL intersect_vis_rectangles( struct bitblt_coords *dst, struct bitblt_coords *
         offset_rect( &rect,
                      -src->x - (src->width < 0 ? 1 : 0),
                      -src->y - (src->height < 0 ? 1 : 0));
-        rect.left   = dst->x + rect.left * dst->width / src->width;
-        rect.top    = dst->y + rect.top * dst->height / src->height;
-        rect.right  = dst->x + rect.right * dst->width / src->width;
-        rect.bottom = dst->y + rect.bottom * dst->height / src->height;
+        rect.left   = rect.left * dst->width / src->width;
+        rect.top    = rect.top * dst->height / src->height;
+        rect.right  = rect.right * dst->width / src->width;
+        rect.bottom = rect.bottom * dst->height / src->height;
         order_rect( &rect );
 
+        /* when the source rectangle needs to flip and it doesn't fit in the source device
+           area, the destination area isn't flipped. So, adjust destination coordinates */
+        if (src->width < 0 && dst->width > 0 &&
+            (src->x + src->width + 1 < src->visrect.left || src->x > src->visrect.right))
+            dst->x += (dst->width - rect.right) - rect.left;
+        else if (src->width > 0 && dst->width < 0 &&
+                 (src->x < src->visrect.left || src->x + src->width > src->visrect.right))
+            dst->x -= rect.right - (dst->width - rect.left);
+
+        if (src->height < 0 && dst->height > 0 &&
+            (src->y + src->height + 1 < src->visrect.top || src->y > src->visrect.bottom))
+            dst->y += (dst->height - rect.bottom) - rect.top;
+        else if (src->height > 0 && dst->height < 0 &&
+                 (src->y < src->visrect.top || src->y + src->height > src->visrect.bottom))
+            dst->y -= rect.bottom - (dst->height - rect.top);
+
+        offset_rect( &rect, dst->x, dst->y );
+
         /* avoid rounding errors */
         rect.left--;
         rect.top--;
diff --git a/dlls/gdi32/tests/bitmap.c b/dlls/gdi32/tests/bitmap.c
index 420a6a7ad6..df04a8b0e3 100644
--- a/dlls/gdi32/tests/bitmap.c
+++ b/dlls/gdi32/tests/bitmap.c
@@ -3263,13 +3263,13 @@ static void test_StretchBlt(void)
     memset( expected, 0, get_dib_image_size( &biDst ) );
     expected[102] = 0x76543210, expected[103] = 0xfedcba98;
     expected[117] = 0x0000cccc, expected[118] = 0x0000f0f0, expected[119] = 0x0000ff00;
-    todo_wine check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
+    check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
                              0, 0, 8, 8, 2, 2, -8, -8, expected, __LINE__);
 
     memset( expected, 0, get_dib_image_size( &biDst ) );
     expected[85] = 0x76543210, expected[86] = 0xfedcba98;
     expected[99] = 0x0000aaaa, expected[100] = 0x0000cccc, expected[101] = 0x0000f0f0, expected[102] = 0x0000ff00;
-    todo_wine check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
+    check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
                              8, 8, -18, -18, 0, 0, 18, 18, expected, __LINE__);
 
     SelectObject(hdcDst, oldDst);
-- 
2.17.1




More information about the wine-devel mailing list