gdiplus: Avoid GdipCloneMatrix calls for the the graphics transformation matrix.

Dmitry Timoshkov dmitry at baikal.ru
Tue Nov 6 21:36:26 CST 2012


---
 dlls/gdiplus/font.c            |   9 ++-
 dlls/gdiplus/gdiplus_private.h |  10 ++--
 dlls/gdiplus/graphics.c        | 126 +++++++++++++----------------------------
 3 files changed, 49 insertions(+), 96 deletions(-)

diff --git a/dlls/gdiplus/font.c b/dlls/gdiplus/font.c
index f6a5d1c..6e31331 100644
--- a/dlls/gdiplus/font.c
+++ b/dlls/gdiplus/font.c
@@ -455,7 +455,7 @@ GpStatus WINGDIPAPI GdipGetLogFontA(GpFont *font, GpGraphics *graphics,
 GpStatus WINGDIPAPI GdipGetLogFontW(GpFont *font, GpGraphics *graphics, LOGFONTW *lf)
 {
     REAL angle, rel_height, height;
-    GpMatrix *matrix;
+    GpMatrix matrix;
     GpPointF pt[3];
 
     TRACE("(%p, %p, %p)\n", font, graphics, lf);
@@ -463,13 +463,13 @@ GpStatus WINGDIPAPI GdipGetLogFontW(GpFont *font, GpGraphics *graphics, LOGFONTW
     if (!font || !graphics || !lf)
         return InvalidParameter;
 
-    GdipCloneMatrix(graphics->worldtrans, &matrix);
+    matrix = graphics->worldtrans;
 
     if (font->unit == UnitPixel)
     {
         height = units_to_pixels(font->emSize, graphics->unit, graphics->yres);
         if (graphics->unit != UnitDisplay)
-            GdipScaleMatrix(matrix, graphics->scale, graphics->scale, MatrixOrderAppend);
+            GdipScaleMatrix(&matrix, graphics->scale, graphics->scale, MatrixOrderAppend);
     }
     else
     {
@@ -485,11 +485,10 @@ GpStatus WINGDIPAPI GdipGetLogFontW(GpFont *font, GpGraphics *graphics, LOGFONTW
     pt[1].Y = 0.0;
     pt[2].X = 0.0;
     pt[2].Y = 1.0;
-    GdipTransformMatrixPoints(matrix, pt, 3);
+    GdipTransformMatrixPoints(&matrix, pt, 3);
     angle = -gdiplus_atan2((pt[1].Y - pt[0].Y), (pt[1].X - pt[0].X));
     rel_height = sqrt((pt[2].Y - pt[0].Y) * (pt[2].Y - pt[0].Y)+
                       (pt[2].X - pt[0].X) * (pt[2].X - pt[0].X));
-    GdipDeleteMatrix(matrix);
 
     lf->lfHeight = -gdip_round(height * rel_height);
     lf->lfWidth = 0;
diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h
index 13a63e6..96eec0b 100644
--- a/dlls/gdiplus/gdiplus_private.h
+++ b/dlls/gdiplus/gdiplus_private.h
@@ -125,6 +125,10 @@ extern GpStatus convert_pixels(INT width, INT height,
     INT dst_stride, BYTE *dst_bits, PixelFormat dst_format,
     INT src_stride, const BYTE *src_bits, PixelFormat src_format, ColorPalette *palette) DECLSPEC_HIDDEN;
 
+struct GpMatrix{
+    REAL matrix[6];
+};
+
 struct GpPen{
     UINT style;
     GpUnit unit;
@@ -158,7 +162,7 @@ struct GpGraphics{
     GpUnit unit;    /* page unit */
     REAL scale;     /* page scale */
     REAL xres, yres;
-    GpMatrix * worldtrans; /* world transform */
+    GpMatrix worldtrans; /* world transform */
     BOOL busy;      /* hdc handle obtained by GdipGetDC */
     GpRegion *clip;
     UINT textcontrast; /* not used yet. get/set only */
@@ -240,10 +244,6 @@ struct GpPath{
     INT datalen; /* size of the arrays in pathdata */
 };
 
-struct GpMatrix{
-    REAL matrix[6];
-};
-
 struct GpPathIterator{
     GpPathData pathdata;
     INT subpath_pos;    /* for NextSubpath methods */
diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c
index f364a64..2175faa 100644
--- a/dlls/gdiplus/graphics.c
+++ b/dlls/gdiplus/graphics.c
@@ -255,7 +255,7 @@ static INT prepare_dc(GpGraphics *graphics, GpPen *pen)
         pt[0].Y = 0.0;
         pt[1].X = 1.0;
         pt[1].Y = 1.0;
-        GdipTransformMatrixPoints(graphics->worldtrans, pt, 2);
+        GdipTransformMatrixPoints(&graphics->worldtrans, pt, 2);
         width = sqrt((pt[1].X - pt[0].X) * (pt[1].X - pt[0].X) +
                      (pt[1].Y - pt[0].Y) * (pt[1].Y - pt[0].Y)) / sqrt(2.0);
 
@@ -296,7 +296,7 @@ static void restore_dc(GpGraphics *graphics, INT state)
 }
 
 static GpStatus get_graphics_transform(GpGraphics *graphics, GpCoordinateSpace dst_space,
-        GpCoordinateSpace src_space, GpMatrix **matrix);
+        GpCoordinateSpace src_space, GpMatrix *matrix);
 
 /* 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
@@ -325,7 +325,7 @@ static void transform_and_round_points(GpGraphics *graphics, POINT *pti,
         scale_y *= graphics->scale;
     }
 
-    matrix = *graphics->worldtrans;
+    matrix = graphics->worldtrans;
     GdipScaleMatrix(&matrix, scale_x, scale_y, MatrixOrderAppend);
     GdipTransformMatrixPoints(&matrix, ptf, count);
 
@@ -1204,7 +1204,7 @@ static GpStatus brush_fill_pixels(GpGraphics *graphics, GpBrush *brush,
     {
         GpPathGradient *fill = (GpPathGradient*)brush;
         GpPath *flat_path;
-        GpMatrix *world_to_device;
+        GpMatrix world_to_device;
         GpStatus stat;
         int i, figure_start=0;
         GpPointF start_point, end_point, center_point;
@@ -1263,18 +1263,16 @@ static GpStatus brush_fill_pixels(GpGraphics *graphics, GpBrush *brush,
             CoordinateSpaceWorld, &world_to_device);
         if (stat == Ok)
         {
-            stat = GdipTransformPath(flat_path, world_to_device);
+            stat = GdipTransformPath(flat_path, &world_to_device);
 
             if (stat == Ok)
             {
                 center_point = fill->center;
-                stat = GdipTransformMatrixPoints(world_to_device, &center_point, 1);
+                stat = GdipTransformMatrixPoints(&world_to_device, &center_point, 1);
             }
 
             if (stat == Ok)
                 stat = GdipFlattenPath(flat_path, NULL, 0.5);
-
-            GdipDeleteMatrix(world_to_device);
         }
 
         if (stat != Ok)
@@ -1987,7 +1985,7 @@ typedef struct _GraphicsContainerItem {
     GpUnit unit;
     PixelOffsetMode pixeloffset;
     UINT textcontrast;
-    GpMatrix* worldtrans;
+    GpMatrix worldtrans;
     GpRegion* clip;
     INT origin_x, origin_y;
 } GraphicsContainerItem;
@@ -2013,17 +2011,10 @@ static GpStatus init_container(GraphicsContainerItem** container,
     (*container)->pixeloffset = graphics->pixeloffset;
     (*container)->origin_x = graphics->origin_x;
     (*container)->origin_y = graphics->origin_y;
-
-    sts = GdipCloneMatrix(graphics->worldtrans, &(*container)->worldtrans);
-    if(sts != Ok){
-        GdipFree(*container);
-        *container = NULL;
-        return sts;
-    }
+    (*container)->worldtrans = graphics->worldtrans;
 
     sts = GdipCloneRegion(graphics->clip, &(*container)->clip);
     if(sts != Ok){
-        GdipDeleteMatrix((*container)->worldtrans);
         GdipFree(*container);
         *container = NULL;
         return sts;
@@ -2032,8 +2023,8 @@ static GpStatus init_container(GraphicsContainerItem** container,
     return Ok;
 }
 
-static void delete_container(GraphicsContainerItem* container){
-    GdipDeleteMatrix(container->worldtrans);
+static void delete_container(GraphicsContainerItem* container)
+{
     GdipDeleteRegion(container->clip);
     GdipFree(container);
 }
@@ -2041,21 +2032,12 @@ static void delete_container(GraphicsContainerItem* container){
 static GpStatus restore_container(GpGraphics* graphics,
         GDIPCONST GraphicsContainerItem* container){
     GpStatus sts;
-    GpMatrix *newTrans;
     GpRegion *newClip;
 
-    sts = GdipCloneMatrix(container->worldtrans, &newTrans);
-    if(sts != Ok)
-        return sts;
-
     sts = GdipCloneRegion(container->clip, &newClip);
-    if(sts != Ok){
-        GdipDeleteMatrix(newTrans);
-        return sts;
-    }
+    if(sts != Ok) return sts;
 
-    GdipDeleteMatrix(graphics->worldtrans);
-    graphics->worldtrans = newTrans;
+    graphics->worldtrans = container->worldtrans;
 
     GdipDeleteRegion(graphics->clip);
     graphics->clip = newClip;
@@ -2249,13 +2231,9 @@ GpStatus WINGDIPAPI GdipCreateFromHDC2(HDC hdc, HANDLE hDevice, GpGraphics **gra
     *graphics = GdipAlloc(sizeof(GpGraphics));
     if(!*graphics)  return OutOfMemory;
 
-    if((retval = GdipCreateMatrix(&(*graphics)->worldtrans)) != Ok){
-        GdipFree(*graphics);
-        return retval;
-    }
+    GdipSetMatrixElements(&(*graphics)->worldtrans, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
 
     if((retval = GdipCreateRegion(&(*graphics)->clip)) != Ok){
-        GdipFree((*graphics)->worldtrans);
         GdipFree(*graphics);
         return retval;
     }
@@ -2289,13 +2267,9 @@ GpStatus graphics_from_image(GpImage *image, GpGraphics **graphics)
     *graphics = GdipAlloc(sizeof(GpGraphics));
     if(!*graphics)  return OutOfMemory;
 
-    if((retval = GdipCreateMatrix(&(*graphics)->worldtrans)) != Ok){
-        GdipFree(*graphics);
-        return retval;
-    }
+    GdipSetMatrixElements(&(*graphics)->worldtrans, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
 
     if((retval = GdipCreateRegion(&(*graphics)->clip)) != Ok){
-        GdipFree((*graphics)->worldtrans);
         GdipFree(*graphics);
         return retval;
     }
@@ -2514,7 +2488,6 @@ GpStatus WINGDIPAPI GdipDeleteGraphics(GpGraphics *graphics)
     }
 
     GdipDeleteRegion(graphics->clip);
-    GdipDeleteMatrix(graphics->worldtrans);
     GdipFree(graphics);
 
     return Ok;
@@ -4279,7 +4252,7 @@ static GpStatus SOFTWARE_GdipFillRegion(GpGraphics *graphics, GpBrush *brush,
 {
     GpStatus stat;
     GpRegion *temp_region;
-    GpMatrix *world_to_device;
+    GpMatrix world_to_device;
     GpRectF graphics_bounds;
     DWORD *pixel_data;
     HRGN hregion;
@@ -4300,11 +4273,7 @@ static GpStatus SOFTWARE_GdipFillRegion(GpGraphics *graphics, GpBrush *brush,
             CoordinateSpaceWorld, &world_to_device);
 
         if (stat == Ok)
-        {
-            stat = GdipTransformRegion(temp_region, world_to_device);
-
-            GdipDeleteMatrix(world_to_device);
-        }
+            stat = GdipTransformRegion(temp_region, &world_to_device);
 
         if (stat == Ok)
             stat = GdipCombineRegionRect(temp_region, &graphics_bounds, CombineModeIntersect);
@@ -4649,7 +4618,7 @@ GpStatus WINGDIPAPI GdipGetWorldTransform(GpGraphics *graphics, GpMatrix *matrix
     if(graphics->busy)
         return ObjectBusy;
 
-    *matrix = *graphics->worldtrans;
+    *matrix = graphics->worldtrans;
     return Ok;
 }
 
@@ -5425,14 +5394,7 @@ GpStatus WINGDIPAPI GdipResetWorldTransform(GpGraphics *graphics)
     if(graphics->busy)
         return ObjectBusy;
 
-    graphics->worldtrans->matrix[0] = 1.0;
-    graphics->worldtrans->matrix[1] = 0.0;
-    graphics->worldtrans->matrix[2] = 0.0;
-    graphics->worldtrans->matrix[3] = 1.0;
-    graphics->worldtrans->matrix[4] = 0.0;
-    graphics->worldtrans->matrix[5] = 0.0;
-
-    return Ok;
+    return GdipSetMatrixElements(&graphics->worldtrans, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
 }
 
 GpStatus WINGDIPAPI GdipRestoreGraphics(GpGraphics *graphics, GraphicsState state)
@@ -5451,7 +5413,7 @@ GpStatus WINGDIPAPI GdipRotateWorldTransform(GpGraphics *graphics, REAL angle,
     if(graphics->busy)
         return ObjectBusy;
 
-    return GdipRotateMatrix(graphics->worldtrans, angle, order);
+    return GdipRotateMatrix(&graphics->worldtrans, angle, order);
 }
 
 GpStatus WINGDIPAPI GdipSaveGraphics(GpGraphics *graphics, GraphicsState *state)
@@ -5546,7 +5508,7 @@ GpStatus WINGDIPAPI GdipScaleWorldTransform(GpGraphics *graphics, REAL sx,
     if(graphics->busy)
         return ObjectBusy;
 
-    return GdipScaleMatrix(graphics->worldtrans, sx, sy, order);
+    return GdipScaleMatrix(&graphics->worldtrans, sx, sy, order);
 }
 
 GpStatus WINGDIPAPI GdipSetClipGraphics(GpGraphics *graphics, GpGraphics *srcgraphics,
@@ -5751,8 +5713,9 @@ GpStatus WINGDIPAPI GdipSetWorldTransform(GpGraphics *graphics, GpMatrix *matrix
           matrix->matrix[0], matrix->matrix[1], matrix->matrix[2],
           matrix->matrix[3], matrix->matrix[4], matrix->matrix[5]);
 
-    GdipDeleteMatrix(graphics->worldtrans);
-    return GdipCloneMatrix(matrix, &graphics->worldtrans);
+    graphics->worldtrans = *matrix;
+
+    return Ok;
 }
 
 GpStatus WINGDIPAPI GdipTranslateWorldTransform(GpGraphics *graphics, REAL dx,
@@ -5766,7 +5729,7 @@ GpStatus WINGDIPAPI GdipTranslateWorldTransform(GpGraphics *graphics, REAL dx,
     if(graphics->busy)
         return ObjectBusy;
 
-    return GdipTranslateMatrix(graphics->worldtrans, dx, dy, order);
+    return GdipTranslateMatrix(&graphics->worldtrans, dx, dy, order);
 }
 
 /*****************************************************************************
@@ -5968,11 +5931,11 @@ GpStatus WINGDIPAPI GdipMultiplyWorldTransform(GpGraphics *graphics, GDIPCONST G
     if(graphics->busy)
         return ObjectBusy;
 
-    m = *(graphics->worldtrans);
+    m = graphics->worldtrans;
 
     ret = GdipMultiplyMatrix(&m, matrix, order);
     if(ret == Ok)
-        *(graphics->worldtrans) = m;
+        graphics->worldtrans = m;
 
     return ret;
 }
@@ -6132,12 +6095,14 @@ GpStatus WINGDIPAPI GdipGetClip(GpGraphics *graphics, GpRegion *region)
 }
 
 static GpStatus get_graphics_transform(GpGraphics *graphics, GpCoordinateSpace dst_space,
-        GpCoordinateSpace src_space, GpMatrix **matrix)
+        GpCoordinateSpace src_space, GpMatrix *matrix)
 {
-    GpStatus stat = GdipCreateMatrix(matrix);
+    GpStatus stat = Ok;
     REAL scale_x, scale_y;
 
-    if (dst_space != src_space && stat == Ok)
+    GdipSetMatrixElements(matrix, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
+
+    if (dst_space != src_space)
     {
         scale_x = units_to_pixels(1.0, graphics->unit, graphics->xres);
         scale_y = units_to_pixels(1.0, graphics->unit, graphics->yres);
@@ -6152,12 +6117,12 @@ static GpStatus get_graphics_transform(GpGraphics *graphics, GpCoordinateSpace d
         switch (src_space)
         {
         case CoordinateSpaceWorld:
-            GdipMultiplyMatrix(*matrix, graphics->worldtrans, MatrixOrderAppend);
+            GdipMultiplyMatrix(matrix, &graphics->worldtrans, MatrixOrderAppend);
             break;
         case CoordinateSpacePage:
             break;
         case CoordinateSpaceDevice:
-            GdipScaleMatrix(*matrix, 1.0/scale_x, 1.0/scale_y, MatrixOrderAppend);
+            GdipScaleMatrix(matrix, 1.0/scale_x, 1.0/scale_y, MatrixOrderAppend);
             break;
         }
 
@@ -6166,21 +6131,16 @@ static GpStatus get_graphics_transform(GpGraphics *graphics, GpCoordinateSpace d
         {
         case CoordinateSpaceWorld:
             {
-                GpMatrix *inverted_transform;
-                stat = GdipCloneMatrix(graphics->worldtrans, &inverted_transform);
+                GpMatrix inverted_transform = graphics->worldtrans;
+                stat = GdipInvertMatrix(&inverted_transform);
                 if (stat == Ok)
-                {
-                    stat = GdipInvertMatrix(inverted_transform);
-                    if (stat == Ok)
-                        GdipMultiplyMatrix(*matrix, inverted_transform, MatrixOrderAppend);
-                    GdipDeleteMatrix(inverted_transform);
-                }
+                    GdipMultiplyMatrix(matrix, &inverted_transform, MatrixOrderAppend);
                 break;
             }
         case CoordinateSpacePage:
             break;
         case CoordinateSpaceDevice:
-            GdipScaleMatrix(*matrix, scale_x, scale_y, MatrixOrderAppend);
+            GdipScaleMatrix(matrix, scale_x, scale_y, MatrixOrderAppend);
             break;
         }
     }
@@ -6190,7 +6150,7 @@ static GpStatus get_graphics_transform(GpGraphics *graphics, GpCoordinateSpace d
 GpStatus WINGDIPAPI GdipTransformPoints(GpGraphics *graphics, GpCoordinateSpace dst_space,
                                         GpCoordinateSpace src_space, GpPointF *points, INT count)
 {
-    GpMatrix *matrix;
+    GpMatrix matrix;
     GpStatus stat;
 
     if(!graphics || !points || count <= 0)
@@ -6204,15 +6164,9 @@ GpStatus WINGDIPAPI GdipTransformPoints(GpGraphics *graphics, GpCoordinateSpace
     if (src_space == dst_space) return Ok;
 
     stat = get_graphics_transform(graphics, dst_space, src_space, &matrix);
+    if (stat != Ok) return stat;
 
-    if (stat == Ok)
-    {
-        stat = GdipTransformMatrixPoints(matrix, points, count);
-
-        GdipDeleteMatrix(matrix);
-    }
-
-    return stat;
+    return GdipTransformMatrixPoints(&matrix, points, count);
 }
 
 GpStatus WINGDIPAPI GdipTransformPointsI(GpGraphics *graphics, GpCoordinateSpace dst_space,
-- 
1.7.12.4




More information about the wine-patches mailing list