Vincent Povirk : gdiplus: Account for gdi32 transform in GdipDrawImage.
Alexandre Julliard
julliard at winehq.org
Fri Sep 1 12:23:21 CDT 2017
Module: wine
Branch: master
Commit: 93e8507aeada4eef8550aad44e6d38c877e52ea3
URL: http://source.winehq.org/git/wine.git/?a=commit;h=93e8507aeada4eef8550aad44e6d38c877e52ea3
Author: Vincent Povirk <vincent at codeweavers.com>
Date: Thu Aug 31 14:14:06 2017 -0500
gdiplus: Account for gdi32 transform in GdipDrawImage.
Signed-off-by: Vincent Povirk <vincent at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/gdiplus/graphics.c | 49 +++++++++++++++++++------------------------------
1 file changed, 19 insertions(+), 30 deletions(-)
diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c
index a7da283..3ac9952 100644
--- a/dlls/gdiplus/graphics.c
+++ b/dlls/gdiplus/graphics.c
@@ -284,43 +284,23 @@ static void restore_dc(GpGraphics *graphics, INT state)
RestoreDC(graphics->hdc, state);
}
-/* This helper applies all the changes that the points listed in ptf need in
- * order to be drawn on the device context. In the end, this should include at
- * least:
- * -scaling by page unit
- * -applying world transformation
- * -converting from float to int
- * Native gdiplus uses gdi32 to do all this (via SetMapMode, SetViewportExtEx,
- * SetWindowExtEx, SetWorldTransform, etc.) but we cannot because we are using
- * gdi to draw, and these functions would irreparably mess with line widths.
- */
-static void transform_and_round_points(GpGraphics *graphics, POINT *pti,
- GpPointF *ptf, INT count)
+static void round_points(POINT *pti, GpPointF *ptf, INT count)
{
- REAL scale_x, scale_y;
- GpMatrix matrix;
int i;
- scale_x = units_to_pixels(1.0, graphics->unit, graphics->xres);
- scale_y = units_to_pixels(1.0, graphics->unit, graphics->yres);
-
- /* apply page scale */
- if(graphics->unit != UnitDisplay)
- {
- scale_x *= graphics->scale;
- scale_y *= graphics->scale;
- }
-
- matrix = graphics->worldtrans;
- GdipScaleMatrix(&matrix, scale_x, scale_y, MatrixOrderAppend);
- GdipTransformMatrixPoints(&matrix, ptf, count);
-
for(i = 0; i < count; i++){
pti[i].x = gdip_round(ptf[i].X);
pti[i].y = gdip_round(ptf[i].Y);
}
}
+static void transform_and_round_points(GpGraphics *graphics, POINT *pti,
+ GpPointF *ptf, INT count)
+{
+ gdip_transform_points(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, ptf, count);
+ round_points(pti, ptf, count);
+}
+
static void gdi_alpha_blend(GpGraphics *graphics, INT dst_x, INT dst_y, INT dst_width, INT dst_height,
HDC hdc, INT src_x, INT src_y, INT src_width, INT src_height)
{
@@ -2943,7 +2923,8 @@ GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image
ptf[3].Y = ptf[2].Y + ptf[1].Y - ptf[0].Y;
if (!srcwidth || !srcheight || (ptf[3].X == ptf[0].X && ptf[3].Y == ptf[0].Y))
return Ok;
- transform_and_round_points(graphics, pti, ptf, 4);
+ gdip_transform_points(graphics, WineCoordinateSpaceGdiDevice, CoordinateSpaceWorld, ptf, 4);
+ round_points(pti, ptf, 4);
TRACE("%s %s %s %s\n", wine_dbgstr_point(&pti[0]), wine_dbgstr_point(&pti[1]),
wine_dbgstr_point(&pti[2]), wine_dbgstr_point(&pti[3]));
@@ -3005,7 +2986,7 @@ GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image
if (dst_area.bottom < pti[i].y) dst_area.bottom = pti[i].y;
}
- stat = get_graphics_bounds(graphics, &graphics_bounds);
+ stat = get_graphics_device_bounds(graphics, &graphics_bounds);
if (stat != Ok) return stat;
if (graphics_bounds.X > dst_area.left) dst_area.left = floorf(graphics_bounds.X);
@@ -3121,10 +3102,14 @@ GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image
dst_stride = src_stride;
}
+ gdi_transform_acquire(graphics);
+
stat = alpha_blend_pixels(graphics, dst_area.left, dst_area.top,
dst_data, dst_area.right - dst_area.left, dst_area.bottom - dst_area.top, dst_stride,
lockeddata.PixelFormat);
+ gdi_transform_release(graphics);
+
heap_free(src_data);
heap_free(dst_dyn_data);
@@ -3208,6 +3193,8 @@ GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image
DeleteObject(hrgn);
}
+ gdi_transform_acquire(graphics);
+
if (bitmap->format & (PixelFormatAlpha|PixelFormatPAlpha))
{
gdi_alpha_blend(graphics, pti[0].x, pti[0].y, pti[1].x - pti[0].x, pti[2].y - pti[0].y,
@@ -3219,6 +3206,8 @@ GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image
hdc, srcx, srcy, srcwidth, srcheight, SRCCOPY);
}
+ gdi_transform_release(graphics);
+
RestoreDC(graphics->hdc, save_state);
if (temp_hdc)
More information about the wine-cvs
mailing list