[PATCH 3/4] gdi32: Fix negative width/height handling in StretchBlt.

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


Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45971
Signed-off-by: Akihiro Sagawa <sagawa.aki at gmail.com>
---
 dlls/gdi32/bitblt.c       | 26 ++++++++++++++------------
 dlls/gdi32/tests/bitmap.c |  2 +-
 2 files changed, 15 insertions(+), 13 deletions(-)

diff --git a/dlls/gdi32/bitblt.c b/dlls/gdi32/bitblt.c
index c8d67cbada..6f5af649c6 100644
--- a/dlls/gdi32/bitblt.c
+++ b/dlls/gdi32/bitblt.c
@@ -57,12 +57,13 @@ BOOL intersect_vis_rectangles( struct bitblt_coords *dst, struct bitblt_coords *
     {
         /* map source rectangle into destination coordinates */
         rect = src->visrect;
-        offset_rect( &rect, -min( src->x, src->x + src->width + 1),
-                     -min( src->y, src->y + src->height + 1) );
-        rect.left   = dst->x + rect.left * dst->width / abs(src->width);
-        rect.top    = dst->y + rect.top * dst->height / abs(src->height);
-        rect.right  = dst->x + rect.right * dst->width / abs(src->width);
-        rect.bottom = dst->y + rect.bottom * dst->height / abs(src->height);
+        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;
         order_rect( &rect );
 
         /* avoid rounding errors */
@@ -74,12 +75,13 @@ BOOL intersect_vis_rectangles( struct bitblt_coords *dst, struct bitblt_coords *
 
         /* map destination rectangle back to source coordinates */
         rect = dst->visrect;
-        offset_rect( &rect, -min( dst->x, dst->x + dst->width + 1),
-                     -min( dst->y, dst->y + dst->height + 1) );
-        rect.left   = src->x + rect.left * src->width / abs(dst->width);
-        rect.top    = src->y + rect.top * src->height / abs(dst->height);
-        rect.right  = src->x + rect.right * src->width / abs(dst->width);
-        rect.bottom = src->y + rect.bottom * src->height / abs(dst->height);
+        offset_rect( &rect,
+                     -dst->x - (dst->width < 0 ? 1 : 0),
+                     -dst->y - (dst->height < 0 ? 1 : 0));
+        rect.left   = src->x + rect.left * src->width / dst->width;
+        rect.top    = src->y + rect.top * src->height / dst->height;
+        rect.right  = src->x + rect.right * src->width / dst->width;
+        rect.bottom = src->y + rect.bottom * src->height / dst->height;
         order_rect( &rect );
 
         /* avoid rounding errors */
diff --git a/dlls/gdi32/tests/bitmap.c b/dlls/gdi32/tests/bitmap.c
index ffe28a374d..420a6a7ad6 100644
--- a/dlls/gdi32/tests/bitmap.c
+++ b/dlls/gdi32/tests/bitmap.c
@@ -3256,7 +3256,7 @@ static void test_StretchBlt(void)
     memset( expected, 0, get_dib_image_size( &biDst ) );
     expected[17] = 0x76543210, expected[18] = 0xfedcba98;
     expected[32] = 0x0000cccc, expected[33] = 0x0000f0f0, expected[34] = 0x0000ff00;
-    todo_wine check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
+    check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
                              2, 2, -8, -8, 0, 0, 8, 8, expected, __LINE__);
 
     /* the source rectangle doesn't fit in the device area */
-- 
2.17.1





More information about the wine-devel mailing list