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@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);
Hi,
While running your changed tests on Windows, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=43037
Your paranoid android.
=== debian9 (32 bit Wine report) ===
gdi32: bitmap.c:3699: Test succeeded inside todo block: GdiAlphaBlend failed err 3735928559
=== debian9 (build log) ===