From: Bartosz Kosiorek gang65@poczta.onet.pl
--- dlls/gdiplus/graphics.c | 16 ++++++++++++++-- dlls/gdiplus/tests/image.c | 23 ++++++++++++++--------- 2 files changed, 28 insertions(+), 11 deletions(-)
diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c index 65b33cdc960..ec57199bd96 100644 --- a/dlls/gdiplus/graphics.c +++ b/dlls/gdiplus/graphics.c @@ -3217,6 +3217,7 @@ GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image GpMatrix dst_to_src; REAL m11, m12, m21, m22, mdx, mdy; REAL x_dx, x_dy, y_dx, y_dy; + REAL dst_pixel_offset; ARGB *dst_color; GpPointF src_pointf_row, src_pointf;
@@ -3247,12 +3248,23 @@ GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image } dst_color = (ARGB*)(dst_data);
+ if ((offset_mode == PixelOffsetModeHalf) || + (offset_mode == PixelOffsetModeHighQuality)) + { + // We are checking color in the middle of destination pixel, + // The pixel center is at (0.5, 0.5). + dst_pixel_offset = 0.5; + } + else + // The pixel center is at (0.0, 0.0). + dst_pixel_offset = 0.0; + /* Calculate top left point of transformed image. It would be used as reference point for adding */ src_pointf_row.X = dst_to_src.matrix[4] + - dst_area.left * x_dx + dst_area.top * y_dx; + (dst_area.left + dst_pixel_offset) * x_dx + (dst_area.top + dst_pixel_offset) * y_dx; src_pointf_row.Y = dst_to_src.matrix[5] + - dst_area.left * x_dy + dst_area.top * y_dy; + (dst_area.left + dst_pixel_offset) * x_dy + (dst_area.top + dst_pixel_offset) * y_dy;
for (y = dst_area.top; y < dst_area.bottom; y++, src_pointf_row.X += y_dx, src_pointf_row.Y += y_dy) diff --git a/dlls/gdiplus/tests/image.c b/dlls/gdiplus/tests/image.c index 4d93e28d951..5e53768cfc7 100644 --- a/dlls/gdiplus/tests/image.c +++ b/dlls/gdiplus/tests/image.c @@ -4618,8 +4618,10 @@ static void test_DrawImage(void) match = memcmp(white_2x2, black_2x2, sizeof(black_2x2)) == 0; ok(match, "data should match\n"); if (!match) - trace("%s\n", dbgstr_hexdata(white_2x2, sizeof(white_2x2))); - + { + trace("Expected: %s\n", dbgstr_hexdata(black_2x2, sizeof(black_2x2))); + trace("Got: %s\n", dbgstr_hexdata(white_2x2, sizeof(white_2x2))); + } status = GdipDeleteGraphics(graphics); expect(Ok, status); status = GdipDisposeImage(u1.image); @@ -4708,7 +4710,10 @@ static void test_GdipDrawImagePointRect(void) match = memcmp(white_2x2, black_2x2, sizeof(black_2x2)) == 0; ok(match, "data should match\n"); if (!match) - trace("%s\n", dbgstr_hexdata(white_2x2, sizeof(white_2x2))); + { + trace("Expected: %s\n", dbgstr_hexdata(black_2x2, sizeof(black_2x2))); + trace("Got: %s\n", dbgstr_hexdata(white_2x2, sizeof(white_2x2))); + }
status = GdipDeleteGraphics(graphics); expect(Ok, status); @@ -4884,18 +4889,18 @@ static void test_DrawImage_scale(void) /* TODO There are missing left pixel column of image*/ { 0.8, InterpolationModeNearestNeighbor, PixelOffsetModeHalf, image_080 }, /* 14 */ { 1.0, InterpolationModeNearestNeighbor, PixelOffsetModeHalf, image_100 }, - { 1.2, InterpolationModeNearestNeighbor, PixelOffsetModeHalf, image_120_half, 0, TRUE }, + { 1.2, InterpolationModeNearestNeighbor, PixelOffsetModeHalf, image_120_half }, { 1.5, InterpolationModeNearestNeighbor, PixelOffsetModeHalf, image_150_half, 0, TRUE }, - { 1.8, InterpolationModeNearestNeighbor, PixelOffsetModeHalf, image_180_half, 0, TRUE }, - { 2.0, InterpolationModeNearestNeighbor, PixelOffsetModeHalf, image_200_half, 0, TRUE }, + { 1.8, InterpolationModeNearestNeighbor, PixelOffsetModeHalf, image_180_half }, + { 2.0, InterpolationModeNearestNeighbor, PixelOffsetModeHalf, image_200_half }, { 2.5, InterpolationModeNearestNeighbor, PixelOffsetModeHalf, image_250_half, 0, TRUE },
{ 0.8, InterpolationModeNearestNeighbor, PixelOffsetModeHighQuality, image_080 }, /* 21 */ { 1.0, InterpolationModeNearestNeighbor, PixelOffsetModeHighQuality, image_100 }, - { 1.2, InterpolationModeNearestNeighbor, PixelOffsetModeHighQuality, image_120_half, 0, TRUE }, + { 1.2, InterpolationModeNearestNeighbor, PixelOffsetModeHighQuality, image_120_half }, { 1.5, InterpolationModeNearestNeighbor, PixelOffsetModeHighQuality, image_150_half, 0, TRUE }, - { 1.8, InterpolationModeNearestNeighbor, PixelOffsetModeHighQuality, image_180_half, 0, TRUE }, - { 2.0, InterpolationModeNearestNeighbor, PixelOffsetModeHighQuality, image_200_half, 0, TRUE }, + { 1.8, InterpolationModeNearestNeighbor, PixelOffsetModeHighQuality, image_180_half }, + { 2.0, InterpolationModeNearestNeighbor, PixelOffsetModeHighQuality, image_200_half }, { 2.5, InterpolationModeNearestNeighbor, PixelOffsetModeHighQuality, image_250_half, 0, TRUE },
/* The bilinear interpolation results are little bit different than on Windows */