Module: wine Branch: master Commit: 399fd55f5c4e7668b286f92cf43253bf17deefdc URL: http://source.winehq.org/git/wine.git/?a=commit;h=399fd55f5c4e7668b286f92cf4...
Author: Vincent Povirk vincent@codeweavers.com Date: Wed Aug 30 12:32:17 2017 -0500
gdiplus: Account for gdi transform in SOFTWARE_GdipFillRegion.
Signed-off-by: Vincent Povirk vincent@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/gdiplus/gdiplus_private.h | 4 +++ dlls/gdiplus/graphics.c | 57 +++++++++++++++++++++++++++++++++++++++--- dlls/gdiplus/tests/graphics.c | 2 +- 3 files changed, 58 insertions(+), 5 deletions(-)
diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h index 9980afc..6bb7f88 100644 --- a/dlls/gdiplus/gdiplus_private.h +++ b/dlls/gdiplus/gdiplus_private.h @@ -81,6 +81,8 @@ extern REAL units_scale(GpUnit from, GpUnit to, REAL dpi) DECLSPEC_HIDDEN;
#define WineCoordinateSpaceGdiDevice ((GpCoordinateSpace)4)
+extern GpStatus gdi_transform_acquire(GpGraphics *graphics); +extern GpStatus gdi_transform_release(GpGraphics *graphics); extern GpStatus get_graphics_transform(GpGraphics *graphics, GpCoordinateSpace dst_space, GpCoordinateSpace src_space, GpMatrix *matrix) DECLSPEC_HIDDEN; extern GpStatus gdip_transform_points(GpGraphics *graphics, GpCoordinateSpace dst_space, @@ -258,6 +260,8 @@ struct GpGraphics{ struct list containers; GraphicsContainer contid; /* last-issued container ID */ INT origin_x, origin_y; + INT gdi_transform_acquire_count, gdi_transform_save; + GpMatrix gdi_transform; /* For giving the caller an HDC when we technically can't: */ HBITMAP temp_hbitmap; int temp_hbitmap_width; diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c index 3dbb457..7aa1dac 100644 --- a/dlls/gdiplus/graphics.c +++ b/dlls/gdiplus/graphics.c @@ -2039,7 +2039,7 @@ static GpStatus restore_container(GpGraphics* graphics, return Ok; }
-static GpStatus get_graphics_bounds(GpGraphics* graphics, GpRectF* rect) +static GpStatus get_graphics_device_bounds(GpGraphics* graphics, GpRectF* rect) { RECT wnd_rect; GpStatus stat=Ok; @@ -2083,7 +2083,14 @@ static GpStatus get_graphics_bounds(GpGraphics* graphics, GpRectF* rect) rect->Height = GetDeviceCaps(graphics->hdc, VERTRES); }
- if (graphics->hdc) + return stat; +} + +static GpStatus get_graphics_bounds(GpGraphics* graphics, GpRectF* rect) +{ + GpStatus stat = get_graphics_device_bounds(graphics, rect); + + if (stat == Ok && graphics->hdc) { GpPointF points[4], min_point, max_point; int i; @@ -4457,14 +4464,17 @@ static GpStatus SOFTWARE_GdipFillRegion(GpGraphics *graphics, GpBrush *brush, if (!brush_can_fill_pixels(brush)) return NotImplemented;
- stat = get_graphics_bounds(graphics, &graphics_bounds); + stat = gdi_transform_acquire(graphics); + + if (stat == Ok) + stat = get_graphics_device_bounds(graphics, &graphics_bounds);
if (stat == Ok) stat = GdipCloneRegion(region, &temp_region);
if (stat == Ok) { - stat = get_graphics_transform(graphics, CoordinateSpaceDevice, + stat = get_graphics_transform(graphics, WineCoordinateSpaceGdiDevice, CoordinateSpaceWorld, &world_to_device);
if (stat == Ok) @@ -4482,6 +4492,7 @@ static GpStatus SOFTWARE_GdipFillRegion(GpGraphics *graphics, GpBrush *brush, if (stat == Ok && GetRgnBox(hregion, &bound_rect) == NULLREGION) { DeleteObject(hregion); + gdi_transform_release(graphics); return Ok; }
@@ -4513,6 +4524,8 @@ static GpStatus SOFTWARE_GdipFillRegion(GpGraphics *graphics, GpBrush *brush, DeleteObject(hregion); }
+ gdi_transform_release(graphics); + return stat; }
@@ -6586,10 +6599,46 @@ static void get_gdi_transform(GpGraphics *graphics, GpMatrix *matrix) return; }
+ if (graphics->gdi_transform_acquire_count) + { + *matrix = graphics->gdi_transform; + return; + } + GetTransform(graphics->hdc, 0x204, &xform); GdipSetMatrixElements(matrix, xform.eM11, xform.eM12, xform.eM21, xform.eM22, xform.eDx, xform.eDy); }
+GpStatus gdi_transform_acquire(GpGraphics *graphics) +{ + if (graphics->gdi_transform_acquire_count == 0 && graphics->hdc) + { + get_gdi_transform(graphics, &graphics->gdi_transform); + graphics->gdi_transform_save = SaveDC(graphics->hdc); + SetGraphicsMode(graphics->hdc, GM_COMPATIBLE); + SetMapMode(graphics->hdc, MM_TEXT); + SetWindowOrgEx(graphics->hdc, 0, 0, NULL); + SetViewportOrgEx(graphics->hdc, 0, 0, NULL); + } + graphics->gdi_transform_acquire_count++; + return Ok; +} + +GpStatus gdi_transform_release(GpGraphics *graphics) +{ + if (graphics->gdi_transform_acquire_count <= 0) + { + ERR("called without matching gdi_transform_acquire"); + return GenericError; + } + if (graphics->gdi_transform_acquire_count == 1 && graphics->hdc) + { + RestoreDC(graphics->hdc, graphics->gdi_transform_save); + } + graphics->gdi_transform_acquire_count--; + return Ok; +} + GpStatus get_graphics_transform(GpGraphics *graphics, GpCoordinateSpace dst_space, GpCoordinateSpace src_space, GpMatrix *matrix) { diff --git a/dlls/gdiplus/tests/graphics.c b/dlls/gdiplus/tests/graphics.c index 5f45cc2..5416ebc 100644 --- a/dlls/gdiplus/tests/graphics.c +++ b/dlls/gdiplus/tests/graphics.c @@ -6361,7 +6361,7 @@ static void test_GdipFillRectanglesOnMemoryDCTextureBrush(void) color[4] = get_bitmap_pixel(width/2-1, height-1); color[5] = get_bitmap_pixel(width-1, height/2-1); } - todo_wine ok(is_blue_color(color[0]) && is_blue_color(color[1]) && is_blue_color(color[2]) && + ok(is_blue_color(color[0]) && is_blue_color(color[1]) && is_blue_color(color[2]) && color[3] == 0 && color[4] == 0 && color[5] == 0, "Expected GdipFillRectangleI take effect!\n" ); ReleaseBitmapPixelBuffer(pixel);