diff --git "a/dll/win32/gdiplus/graphics.c" "b/dll/win32/gdiplus/graphics.c" index 199b20442b2..842efa6eb10 100644 --- "a/dll/win32/gdiplus/graphics.c" +++ "b/dll/win32/gdiplus/graphics.c" @@ -1053,75 +1053,6 @@ static ARGB resample_bitmap_pixel(GDIPCONST GpRect *src_rect, LPBYTE bits, UINT } } -static ARGB resample_bitmap_pixel_premult(GDIPCONST GpRect *src_rect, LPBYTE bits, UINT width, - UINT height, GpPointF *point, GDIPCONST GpImageAttributes *attributes, - InterpolationMode interpolation, PixelOffsetMode offset_mode) -{ - static int fixme; - - switch (interpolation) - { - default: - if (!fixme++) - FIXME("Unimplemented interpolation %i\n", interpolation); - /* fall-through */ - case InterpolationModeBilinear: - { - REAL leftxf, topyf; - INT leftx, rightx, topy, bottomy; - ARGB topleft, topright, bottomleft, bottomright; - ARGB top, bottom; - float x_offset; - - leftx = (INT)point->X; - leftxf = (REAL)leftx; - rightx = positive_ceilf(point->X); - topy = (INT)point->Y; - topyf = (REAL)topy; - bottomy = positive_ceilf(point->Y); - - if (leftx == rightx && topy == bottomy) - return sample_bitmap_pixel(src_rect, bits, width, height, - leftx, topy, attributes); - - topleft = sample_bitmap_pixel(src_rect, bits, width, height, - leftx, topy, attributes); - topright = sample_bitmap_pixel(src_rect, bits, width, height, - rightx, topy, attributes); - bottomleft = sample_bitmap_pixel(src_rect, bits, width, height, - leftx, bottomy, attributes); - bottomright = sample_bitmap_pixel(src_rect, bits, width, height, - rightx, bottomy, attributes); - - x_offset = point->X - leftxf; - top = blend_colors_premult(topleft, topright, x_offset); - bottom = blend_colors_premult(bottomleft, bottomright, x_offset); - - return blend_colors_premult(top, bottom, point->Y - topyf); - } - case InterpolationModeNearestNeighbor: - { - FLOAT pixel_offset; - switch (offset_mode) - { - default: - case PixelOffsetModeNone: - case PixelOffsetModeHighSpeed: - pixel_offset = 0.5; - break; - - case PixelOffsetModeHalf: - case PixelOffsetModeHighQuality: - pixel_offset = 0.0; - break; - } - return sample_bitmap_pixel(src_rect, bits, width, height, - floorf(point->X + pixel_offset), point->Y + pixel_offset, attributes); - } - - } -} - static REAL intersect_line_scanline(const GpPointF *p1, const GpPointF *p2, REAL y) { return (p1->X - p2->X) * (p2->Y - y) / (p2->Y - p1->Y) + p2->X; @@ -3144,7 +3075,7 @@ GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image BOOL do_resampling = FALSE; BOOL use_software = FALSE; - TRACE("graphics: %.2fx%.2f dpi, fmt %#x, scale %f, image: %.2fx%.2f dpi, fmt %#x, color %08x\n", + TRACE("graphics: %.2fx%.2f dpi, fmt %#x, scale %f, image: %.2fx%.2f dpi, fmt %#x, color %08lx\n", graphics->xres, graphics->yres, graphics->image && graphics->image->type == ImageTypeBitmap ? ((GpBitmap *)graphics->image)->format : 0, graphics->scale, image->xres, image->yres, bitmap->format, @@ -3166,14 +3097,10 @@ GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image GpRectF graphics_bounds; GpRect src_area; int i, x, y, src_stride, dst_stride; - GpMatrix dst_to_src; - REAL m11, m12, m21, m22, mdx, mdy; LPBYTE src_data, dst_data, dst_dyn_data=NULL; BitmapData lockeddata; InterpolationMode interpolation = graphics->interpolation; PixelOffsetMode offset_mode = graphics->pixeloffset; - GpPointF dst_to_src_points[3] = {{0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}}; - REAL x_dx, x_dy, y_dx, y_dy; static const GpImageAttributes defaultImageAttributes = {WrapModeClamp, 0, FALSE}; if (!imageAttributes) @@ -3201,18 +3128,6 @@ GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image if (IsRectEmpty(&dst_area)) return Ok; - m11 = (ptf[1].X - ptf[0].X) / srcwidth; - m21 = (ptf[2].X - ptf[0].X) / srcheight; - mdx = ptf[0].X - m11 * srcx - m21 * srcy; - m12 = (ptf[1].Y - ptf[0].Y) / srcwidth; - m22 = (ptf[2].Y - ptf[0].Y) / srcheight; - mdy = ptf[0].Y - m12 * srcx - m22 * srcy; - - GdipSetMatrixElements(&dst_to_src, m11, m12, m21, m22, mdx, mdy); - - stat = GdipInvertMatrix(&dst_to_src); - if (stat != Ok) return stat; - if (do_resampling) { get_bitmap_sample_size(interpolation, imageAttributes->wrap, @@ -3241,10 +3156,8 @@ GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image lockeddata.Scan0 = src_data; if (!do_resampling && bitmap->format == PixelFormat32bppPARGB) lockeddata.PixelFormat = apply_image_attributes(imageAttributes, NULL, 0, 0, 0, ColorAdjustTypeBitmap, bitmap->format); - else if (imageAttributes != &defaultImageAttributes) - lockeddata.PixelFormat = PixelFormat32bppARGB; else - lockeddata.PixelFormat = PixelFormat32bppPARGB; + lockeddata.PixelFormat = PixelFormat32bppARGB; stat = GdipBitmapLockBits(bitmap, &src_area, ImageLockModeRead|ImageLockModeUserInputBuf, lockeddata.PixelFormat, &lockeddata); @@ -3264,7 +3177,29 @@ GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image if (do_resampling) { - REAL delta_xx, delta_xy, delta_yx, delta_yy; + GpMatrix dst_to_src; + REAL m11, m12, m21, m22, mdx, mdy; + REAL x_dx, x_dy, y_dx, y_dy; + ARGB *dst_color; + GpPointF src_pointf_row, src_pointf; + + m11 = (ptf[1].X - ptf[0].X) / srcwidth; + m12 = (ptf[1].Y - ptf[0].Y) / srcwidth; + m21 = (ptf[2].X - ptf[0].X) / srcheight; + m22 = (ptf[2].Y - ptf[0].Y) / srcheight; + mdx = ptf[0].X - m11 * srcx - m21 * srcy; + mdy = ptf[0].Y - m12 * srcx - m22 * srcy; + + GdipSetMatrixElements(&dst_to_src, m11, m12, m21, m22, mdx, mdy); + + stat = GdipInvertMatrix(&dst_to_src); + if (stat != Ok) return stat; + + dst_stride = sizeof(ARGB) * (dst_area.right - dst_area.left); + x_dx = dst_to_src.matrix[0]; + x_dy = dst_to_src.matrix[1]; + y_dx = dst_to_src.matrix[2]; + y_dy = dst_to_src.matrix[3]; /* Transform the bits as needed to the destination. */ dst_data = dst_dyn_data = heap_alloc_zero(sizeof(ARGB) * (dst_area.right - dst_area.left) * (dst_area.bottom - dst_area.top)); @@ -3273,52 +3208,27 @@ GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image heap_free(src_data); return OutOfMemory; } + dst_color = (ARGB*)(dst_data); - dst_stride = sizeof(ARGB) * (dst_area.right - dst_area.left); - - GdipTransformMatrixPoints(&dst_to_src, dst_to_src_points, 3); + /* 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; + src_pointf_row.Y = dst_to_src.matrix[5] + + dst_area.left * x_dy + dst_area.top * y_dy; - x_dx = dst_to_src_points[1].X - dst_to_src_points[0].X; - x_dy = dst_to_src_points[1].Y - dst_to_src_points[0].Y; - y_dx = dst_to_src_points[2].X - dst_to_src_points[0].X; - y_dy = dst_to_src_points[2].Y - dst_to_src_points[0].Y; - - delta_yy = dst_area.top * y_dy; - delta_yx = dst_area.top * y_dx; - - for (y=dst_area.top; y= srcx && src_pointf.X < srcx + srcwidth && src_pointf.Y >= srcy && src_pointf.Y < srcy+srcheight) - { - if (lockeddata.PixelFormat != PixelFormat32bppPARGB) - *dst_color = resample_bitmap_pixel(&src_area, src_data, bitmap->width, bitmap->height, &src_pointf, - imageAttributes, interpolation, offset_mode); - else - *dst_color = resample_bitmap_pixel_premult(&src_area, src_data, bitmap->width, bitmap->height, &src_pointf, - imageAttributes, interpolation, offset_mode); - } - else - *dst_color = 0; - - delta_xx += x_dx; - delta_yx += y_dx; + if (src_pointf.X >= srcx && src_pointf.X < srcx + srcwidth && + src_pointf.Y >= srcy && src_pointf.Y < srcy + srcheight) + *dst_color = resample_bitmap_pixel(&src_area, src_data, bitmap->width, bitmap->height, &src_pointf, + imageAttributes, interpolation, offset_mode); + dst_color++; } - - delta_xy += x_dy; - delta_yy += y_dy; } } else