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