[5/5] gdiplus: Account for gdi transform in SOFTWARE_GdipFillRegion.
Vincent Povirk
vincent at codeweavers.com
Wed Aug 30 12:32:17 CDT 2017
Signed-off-by: Vincent Povirk <vincent at codeweavers.com>
---
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);
--
2.7.4
More information about the wine-patches
mailing list