* Matrix.cs: Rewrote to use GDI+ implementation, doing all the
authorDuncan Mak <duncan@mono-cvs.ximian.com>
Sat, 22 Nov 2003 23:32:56 +0000 (23:32 -0000)
committerDuncan Mak <duncan@mono-cvs.ximian.com>
Sat, 22 Nov 2003 23:32:56 +0000 (23:32 -0000)
math in unmanaged code instead of doing it in C#.

* gdipFunctions.cs
(GdipResetWorldTransform, GdipSetWorldTransform):
(GdipGetWorldTransform, GdipScaleWorldTransform): Imported.

* Graphics.cs: Remove unnecessary TODO, and reformatted the code.
(transform): Removed this field. Always use the
matrix associated in the GpGraphics ptr.
(DrawBeziers): Implemented.
(DrawLine): Don't need to manually invoke the transform now.
(MultiplyTransform, ResetTransform):
(ScaleTransform, TranslateTransform): Use GDI+ implementation.
(Transform): Instead of storing a Matrix in managed code, use
equivalent GDI+ functions.

* matrix.c (GdipCreateMatrix3, GdipCreateMatrix3I): Implemented.
(GdipCloneMatrix): Fixed.
(GdipShearMatrix, set_shear): Implemented.

* graphics.c:
(GdipGetWorldTransform, GdipMultiplyWorldTransform): Implemented.
(GdipRotatePenTransform, GdipTranslatePenTransform): Use GDI+
functions instead.

* gdip.h
(GdipRotatePenTransform, GdipTranslatePenTransform): Fix
signature.
(GdipCreateMatrix3, GdipCreateMatrix3I): Use const appropriately.

svn path=/trunk/mcs/; revision=20344

mcs/class/System.Drawing/System.Drawing.Drawing2D/ChangeLog
mcs/class/System.Drawing/System.Drawing.Drawing2D/Matrix.cs
mcs/class/System.Drawing/System.Drawing/ChangeLog
mcs/class/System.Drawing/System.Drawing/Graphics.cs
mcs/class/System.Drawing/System.Drawing/gdipFunctions.cs
mcs/class/System.Drawing/gdiplus/ChangeLog
mcs/class/System.Drawing/gdiplus/gdip.h
mcs/class/System.Drawing/gdiplus/graphics.c
mcs/class/System.Drawing/gdiplus/matrix.c
mcs/class/System.Drawing/gdiplus/pen.c

index bc4c285028c81853eaa5ffbbbf7286151c30809a..dc67c84467f0be8b233f22de94d2b3a24a60734b 100644 (file)
@@ -1,7 +1,12 @@
-2003-11-04  Miguel de Icaza  <miguel@ximian.com>\r
-\r
-       * GraphicsPathIterator.cs: Do not make this protected.\r
-\r
+2003-11-22  Duncan Mak  <duncan@ximian.com>
+
+       * Matrix.cs: Rewrote to use GDI+ implementation, doing all the
+       math in unmanaged code instead of doing it in C#.
+
+2003-11-04  Miguel de Icaza  <miguel@ximian.com>
+
+       * GraphicsPathIterator.cs: Do not make this protected.
+
 2003-11-13  Andreas Nahr <ClassDevelopment@A-SoftTech.com>
 
        * QualityMode.cs: Fixed typo
index a3b4ddccaeca25d1fcdc8655e3af7452c9a43955..d12587ab975b7276a13207fc15e0f96accafa242 100644 (file)
@@ -4,6 +4,7 @@
 // Author:\r
 //   Stefan Maierhofer <sm@cg.tuwien.ac.at>\r
 //   Dennis Hayes (dennish@Raytek.com)\r
+//   Duncan Mak (duncan@ximian.com)\r
 //\r
 // (C) Ximian, Inc.  http://www.ximian.com\r
 //\r
@@ -14,441 +15,251 @@ using System.Runtime.InteropServices;
 \r
 namespace System.Drawing.Drawing2D\r
 {\r
-    public sealed class Matrix : MarshalByRefObject, IDisposable\r
-    {\r
-        // initialize to identity\r
-        private float[] m = {1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f};\r
-        \r
-        // constructors\r
-        public Matrix() { }\r
-        \r
-        /* TODO: depends on System.Drawing.Drawing2D.Rectangle\r
-        public Matrix(Rectangle rect , Point[] plgpts)\r
-        {\r
-            // TODO\r
-        }\r
-        */\r
-        \r
-        /* TODO: depends on System.Drawing.Drawing2D.RectangleF\r
-        public Matrix(RectangleF rect , PointF[] pa)\r
-        {\r
-            // TODO\r
-        }\r
-        */\r
-        public Matrix(float m11, float m12, \r
-                      float m21, float m22, \r
-                      float dx, float dy)\r
-        {\r
-            m[0] = m11; m[1] = m12;\r
-            m[2] = m21; m[3] = m22;\r
-            m[4] = dx; m[5] = dy;\r
-        }\r
-        \r
-        // properties\r
-        public float[] Elements\r
-        {\r
-            get { return m; }\r
-        }\r
-        \r
-        public bool IsIdentity\r
-        {\r
-            get \r
-            {\r
-                if ( (m[0] == 1.0f) && (m[1] == 0.0f) &&\r
-                     (m[2] == 0.0f) && (m[3] == 1.0f) &&\r
-                     (m[4] == 0.0f) && (m[5] == 0.0f) )\r
-                    return true;\r
-                else \r
-                    return false;\r
-            }\r
-        }\r
-        \r
-        public bool IsInvertible\r
-        {\r
-            get \r
-            { \r
-                // matrix M is invertible if det(M) != 0\r
-                float det = m[0] * m[3] - m[2] * m[1];\r
-                if (det != 0.0f) return true;\r
-                else return false;\r
-            }\r
-        }\r
-        \r
-        public float OffsetX\r
+        public  sealed class Matrix : MarshalByRefObject, IDisposable\r
         {\r
-            get { return m[4]; }\r
-        }\r
-        \r
-        public float OffsetY\r
-        {\r
-            get { return m[5]; }\r
-        }\r
-        \r
-        // methods\r
-        public Matrix Clone()\r
-        {\r
-            return new Matrix(m[0], m[1], m[2], m[3], m[4], m[5]);\r
-        }\r
-        \r
-        public void Dispose() { }\r
-        \r
-        public override bool Equals(object obj)\r
-        {\r
-            if (obj is Matrix)\r
-            {\r
-                float[] a = ((Matrix)obj).Elements;\r
-                if ( m[0] == a[0] && m[1] == a[1] &&\r
-                     m[2] == a[2] && m[3] == a[3] &&\r
-                     m[4] == a[4] && m[5] == a[5] ) \r
-                    return true;\r
-                else \r
-                    return false;\r
-            }\r
-            else\r
-            {\r
-                return false;\r
-            }\r
-        }\r
+                internal IntPtr nativeMatrix;\r
+                \r
+                // constructors\r
+                Matrix (IntPtr ptr)\r
+                {\r
+                        nativeMatrix = ptr;\r
+                }\r
+                \r
+                public Matrix ()\r
+                {\r
+                        Status s = GDIPlus.GdipCreateMatrix (out nativeMatrix);\r
+                }\r
         \r
-        ~Matrix() {}\r
+                public Matrix (Rectangle rect , Point[] plgpts)\r
+                {\r
+                        GpRect rectangle = new GpRect (rect);\r
+\r
+                        GDIPlus.GdipCreateMatrix3I (rectangle, plgpts, out nativeMatrix);\r
+                }\r
         \r
-        [StructLayout(LayoutKind.Explicit)]\r
-        internal struct BitConverter \r
-        {\r
-            [FieldOffset(0)] public float f;\r
-            [FieldOffset(0)] public int i;\r
-        }\r
+                public Matrix (RectangleF rect , PointF[] pa)\r
+                {\r
+                        GpRectF rectangle = new GpRectF (rect);\r
+\r
+                        GDIPlus.GdipCreateMatrix3 (rectangle, pa, out nativeMatrix);\r
+                }\r
+\r
+                public Matrix (float m11, float m12, float m21, float m22, float dx, float dy)\r
+                {\r
+                        GDIPlus.GdipCreateMatrix2 (m11, m12, m21, m22, dx, dy, out nativeMatrix);\r
+                }\r
         \r
-        public override int GetHashCode()\r
-        {\r
-            BitConverter b;\r
-            // compiler is not smart\r
-            b.i = 0;\r
-            int h = 0;\r
-            for (int i = 0; i < 6; i++) \r
-            {\r
-                b.f = m[i];\r
-                h ^= b.i >> i;\r
-            }\r
-            return h;\r
-        }\r
+                // properties\r
+                public float[] Elements {\r
+                        get {\r
+                                IntPtr tmp = Marshal.AllocHGlobal (8 * 6);\r
+\r
+                                Status s = GDIPlus.GdipGetMatrixElements (nativeMatrix, tmp);\r
+\r
+                                float [] retval = new float [6];\r
+\r
+                                Marshal.Copy (tmp, retval, 0, 6);\r
+\r
+                                Marshal.FreeHGlobal (tmp);\r
+                                return retval;\r
+                        }\r
+                }\r
+        \r
+                public bool IsIdentity {\r
+                        get {\r
+                                bool retval;\r
+                                GDIPlus.GdipIsMatrixIdentity (nativeMatrix, out retval);\r
+\r
+                                return retval;\r
+                        }\r
+                }\r
+        \r
+                public bool IsInvertible {\r
+                        get {\r
+                                bool retval;\r
+                                GDIPlus.GdipIsMatrixInvertible (nativeMatrix, out retval);\r
+\r
+                                return retval;\r
+                        }\r
+                }\r
+        \r
+                public float OffsetX {\r
+                        get {\r
+                                return this.Elements [4];\r
+                        }\r
+                }\r
+        \r
+                public float OffsetY {\r
+                        get {\r
+                                return this.Elements [5];\r
+                        }\r
+                }\r
+\r
+                public Matrix Clone()\r
+                {\r
+                        IntPtr retval;\r
+                        Status s = GDIPlus.GdipCloneMatrix (nativeMatrix, out retval);\r
+                        return new Matrix (retval);\r
+                }\r
+                \r
         \r
-        public void Invert()\r
-        {\r
-            float det = m[0] * m[3] - m[2] * m[1];\r
-            if (det != 0.0f)    // if invertible\r
-            {\r
-                float[] r = \r
+                public void Dispose ()\r
                 {\r
-                    m[3] / det, \r
-                    -m[1] / det,\r
-                    -m[2] / det,\r
-                     m[0] / det,\r
-                    (-m[3] * m[4] + m[1] * m[5]) / det,\r
-                    (m[2] * m[4] - m[0] * m[5]) / det\r
-                };\r
-                m = r;\r
-            }\r
-        }\r
+                        GDIPlus.GdipDeleteMatrix (nativeMatrix); \r
+                }                       \r
         \r
-        public void Multiply(Matrix matrix)\r
-        {\r
-            Multiply(matrix, MatrixOrder.Prepend);\r
-        }\r
+                public override bool Equals (object obj)\r
+                {\r
+                        Matrix m = obj as Matrix;\r
+\r
+                        if (m != null) {\r
+                                bool retval;\r
+                                GDIPlus.GdipIsMatrixEqual (nativeMatrix, m.nativeMatrix, out retval);\r
+\r
+                                return retval;\r
+\r
+                        } else\r
+                                return false;\r
+                }\r
         \r
-        public void Multiply(Matrix matrix, MatrixOrder order)\r
-        {\r
-            switch (order)\r
-            {\r
-                case MatrixOrder.Prepend:\r
-                    // this = matrix * this\r
-                    float[] p = matrix.Elements;\r
-                    float[] r0 = \r
-                    {\r
-                        p[0] * m[0] + p[1] * m[2],\r
-                        p[0] * m[1] + p[1] * m[3],\r
-                        p[2] * m[0] + p[3] * m[2],\r
-                        p[2] * m[1] + p[3] * m[3],\r
-                        p[4] * m[0] + p[5] * m[2] + m[4],\r
-                        p[4] * m[1] + p[5] * m[3] + m[5]\r
-                    };\r
-                    m = r0;\r
-                    break;\r
-                case MatrixOrder.Append:\r
-                    // this = this * matrix\r
-                    float[] a = matrix.Elements;\r
-                    float[] r1 = \r
-                    {\r
-                        m[0] * a[0] + m[1] * a[2],\r
-                        m[0] * a[1] + m[1] * a[3],\r
-                        m[2] * a[0] + m[3] * a[2],\r
-                        m[2] * a[1] + m[3] * a[3],\r
-                        m[4] * a[0] + m[5] * a[2] + a[4],\r
-                        m[4] * a[1] + m[5] * a[3] + a[5]\r
-                    };\r
-                    m = r1;\r
-                    break;\r
-            }\r
-        }\r
+                ~Matrix()\r
+                {\r
+                        Dispose ();\r
+                }\r
+                \r
+                public override int GetHashCode ()\r
+                {\r
+                        return base.GetHashCode ();\r
+                }\r
         \r
-        public void Reset()\r
-        {\r
-            m[0] = 1.0f; m[1] = 0.0f;\r
-            m[2] = 0.0f; m[3] = 1.0f;\r
-            m[4] = 0.0f; m[5] = 0.0f;\r
-        }\r
+                public void Invert ()\r
+                {\r
+                        GDIPlus.GdipInvertMatrix (nativeMatrix);\r
+                }\r
         \r
-        public void Rotate(float angle)\r
-        {\r
-            Rotate(angle, MatrixOrder.Prepend);\r
-        }\r
+                public void Multiply (Matrix matrix)\r
+                {\r
+                        Multiply (matrix, MatrixOrder.Prepend);\r
+                }\r
         \r
-        public void Rotate(float angle, MatrixOrder order)\r
-        {\r
-            angle *= (float)(Math.PI / 180.0);  // degrees to randians\r
-            float cos = (float)Math.Cos(angle);\r
-            float sin = (float)Math.Sin(angle);\r
-            switch (order)\r
-            {\r
-                case MatrixOrder.Prepend:\r
-                    // this = rotation * this\r
-                    float[] r0 = \r
-                    {\r
-                         cos * m[0] + sin * m[2],\r
-                         cos * m[1] + sin * m[3],\r
-                        -sin * m[0] + cos * m[2],\r
-                        -sin * m[1] + cos * m[3],\r
-                        m[4],\r
-                        m[5]\r
-                    };\r
-                    m = r0;\r
-                    break;\r
-                case MatrixOrder.Append:\r
-                    // this = this * rotation\r
-                    float[] r1 = \r
-                    {\r
-                        m[0] * cos + m[1] * -sin,\r
-                        m[0] * sin + m[1] *  cos,\r
-                        m[2] * cos + m[3] * -sin,\r
-                        m[2] * sin + m[3] *  cos,\r
-                        m[4] * cos + m[5] * -sin,\r
-                        m[4] * sin + m[5] *  cos\r
-                    };\r
-                    m = r1;\r
-                    break;\r
-            }\r
-        }\r
+                public void Multiply (Matrix matrix, MatrixOrder order)\r
+                {\r
+                        GDIPlus.GdipMultiplyMatrix (nativeMatrix, matrix.nativeMatrix, order);\r
+                }\r
         \r
-        public void RotateAt(float angle, PointF point)\r
-        {\r
-            RotateAt(angle, point, MatrixOrder.Prepend);\r
-        }\r
+                public void Reset()\r
+                {\r
+                        GDIPlus.GdipSetMatrixElements (nativeMatrix, 1, 0, 0, 1, 0, 0);\r
+                }\r
+\r
+                public override string ToString ()\r
+                {\r
+                        System.Text.StringBuilder sb = new System.Text.StringBuilder ();\r
+                        sb.Append ("(");\r
+                        sb.Append (Elements [0] + " ");\r
+                        sb.Append (Elements [1] + " ");\r
+                        sb.Append (Elements [2] + " ");\r
+                        sb.Append (Elements [3] + " ");\r
+                        sb.Append (Elements [4] + " ");\r
+                        sb.Append (Elements [5] + ")");                        \r
+                        return sb.ToString ();\r
+                }\r
+        \r
+                public void Rotate (float angle)\r
+                {\r
+                        Rotate (angle, MatrixOrder.Prepend);\r
+                }\r
         \r
-        public void RotateAt(float angle, PointF point, MatrixOrder order)\r
-        {\r
-            angle *= (float)(Math.PI / 180.0);  // degrees to randians\r
-            float cos = (float)Math.Cos(angle);\r
-            float sin = (float)Math.Sin(angle);\r
-            float e4 = -point.X * cos + point.Y * sin + point.X;\r
-            float e5 = -point.X * sin - point.Y * cos + point.Y;\r
-            switch (order)\r
-            {\r
-                case MatrixOrder.Prepend:\r
-                    // this = rotation * this\r
-                    float[] r0 = \r
-                    {\r
-                        cos * m[0] + sin * m[2],\r
-                        cos * m[1] + sin * m[3],\r
-                        -sin * m[0] + cos * m[2],\r
-                        -sin * m[1] + cos * m[3],\r
-                        e4 * m[0] + e5 * m[2] + m[4],\r
-                        e4 * m[1] + e5 * m[3] + m[5]\r
-                    };\r
-                    m = r0;\r
-                    break;\r
-                case MatrixOrder.Append:\r
-                    // this = this * rotation\r
-                    float[] r1 = \r
-                    {\r
-                        m[0] * cos + m[1] * -sin,\r
-                        m[0] * sin + m[1] * cos,\r
-                        m[2] * cos + m[3] * -sin,\r
-                        m[2] * sin + m[3] * cos,\r
-                        m[4] * cos + m[5] * -sin + e4,\r
-                        m[4] * sin + m[5] * cos + e5\r
-                    };\r
-                    m = r1;\r
-                    break;\r
-            }\r
-        }\r
+                public void Rotate (float angle, MatrixOrder order)\r
+                {\r
+                        GDIPlus.GdipRotateMatrix (nativeMatrix, angle, order);\r
+                }\r
         \r
-        public void Scale(float scaleX, float scaleY)\r
-        {\r
-            Scale(scaleX, scaleY, MatrixOrder.Prepend);\r
-        }\r
+                public void RotateAt (float angle, PointF point)\r
+                {\r
+                        RotateAt (angle, point, MatrixOrder.Prepend);\r
+                }\r
         \r
-        public void Scale(float scaleX, float scaleY, MatrixOrder order)\r
-        {\r
-            switch (order)\r
-            {\r
-                case MatrixOrder.Prepend:\r
-                    // this = scale * this\r
-                    m[0] *= scaleX; m[1] *= scaleX;\r
-                    m[2] *= scaleY; m[3] *= scaleY;\r
-                    break;\r
-                case MatrixOrder.Append:\r
-                    // this = this * scale\r
-                    m[0] *= scaleX; m[1] *= scaleY;\r
-                    m[2] *= scaleX; m[3] *= scaleY;\r
-                    m[4] *= scaleX; m[5] *= scaleY;\r
-                    break;\r
-            }\r
-        }\r
+                public void RotateAt (float angle, PointF point, MatrixOrder order)\r
+                {\r
+                        angle *= (float) (Math.PI / 180.0);  // degrees to radians\r
+                        float cos = (float) Math.Cos (angle);\r
+                        float sin = (float) Math.Sin (angle);\r
+                        float e4 = -point.X * cos + point.Y * sin + point.X;\r
+                        float e5 = -point.X * sin - point.Y * cos + point.Y;\r
+                        float[] m = this.Elements;\r
+\r
+                        if (order == MatrixOrder.Prepend)\r
+                                GDIPlus.GdipSetMatrixElements (nativeMatrix,\r
+                                                cos * m[0] + sin * m[2],\r
+                                                cos * m[1] + sin * m[3],\r
+                                                -sin * m[0] + cos * m[2],\r
+                                                -sin * m[1] + cos * m[3],\r
+                                                e4 * m[0] + e5 * m[2] + m[4],\r
+                                                e4 * m[1] + e5 * m[3] + m[5]);\r
+                        else\r
+                                GDIPlus.GdipSetMatrixElements (nativeMatrix,\r
+                                                m[0] * cos + m[1] * -sin,\r
+                                                m[0] * sin + m[1] * cos,\r
+                                                m[2] * cos + m[3] * -sin,\r
+                                                m[2] * sin + m[3] * cos,\r
+                                                m[4] * cos + m[5] * -sin + e4,\r
+                                                m[4] * sin + m[5] * cos + e5);\r
+                }\r
+        \r
+                public void Scale (float scaleX, float scaleY)\r
+                {\r
+                        Scale (scaleX, scaleY, MatrixOrder.Prepend);\r
+                }\r
         \r
-        public void Shear(float shearX, float shearY)\r
-        {\r
-            Shear(shearX, shearY, MatrixOrder.Prepend);\r
-        }\r
+                public void Scale (float scaleX, float scaleY, MatrixOrder order)\r
+                {\r
+                        GDIPlus.GdipScaleMatrix (nativeMatrix, scaleX, scaleY, order);\r
+                }\r
         \r
-        // LAMESPEC: quote from beta 2 sdk docs: "[To be supplied!]"\r
-        //\r
-        // assuming transformation matrix:\r
-        //\r
-        //      (1       shearY  0)\r
-        //      (shearX  1       0)\r
-        //      (0       0       1)\r
-        //\r
-        public void Shear(float shearX, float shearY, MatrixOrder order)\r
-        {\r
-            switch (order)\r
-            {\r
-                case MatrixOrder.Prepend:\r
-                    // this = shear * this\r
-                    float[] r0 = \r
-                    {\r
-                        m[0] + shearY * m[2],\r
-                        m[1] + shearY * m[3],\r
-                        shearX * m[0] + m[2],\r
-                        shearX * m[1] + m[3],\r
-                        m[4],\r
-                        m[5]\r
-                    };\r
-                    m = r0;\r
-                    break;\r
-                case MatrixOrder.Append:\r
-                    // this = this * shear\r
-                    float[] r1 = \r
-                    {\r
-                        m[0] + m[1] * shearX,\r
-                        m[0] * shearY + m[1],\r
-                        m[2] + m[3] * shearX,\r
-                        m[2] * shearY + m[3],\r
-                        m[4] + m[5] * shearX ,\r
-                        m[4] * shearY + m[5]\r
-                    };\r
-                    m = r1;\r
-                    break;\r
-            }\r
-        }\r
+                public void Shear (float shearX, float shearY)\r
+                {\r
+                        Shear (shearX, shearY, MatrixOrder.Prepend);\r
+                }\r
         \r
-        public void TransformPoints(Point[] pts)\r
-        {\r
-            for (int i = 0; i < pts.Length; i++)\r
-            {\r
-                float x = (float)pts[i].X;\r
-                float y = (float)pts[i].Y;\r
-                pts[i].X = (int)(x * m[0] + y * m[2] + m[4]);\r
-                pts[i].Y = (int)(x * m[1] + y * m[3] + m[5]);\r
-            }\r
-        }\r
+                public void Shear (float shearX, float shearY, MatrixOrder order)\r
+                {\r
+                        GDIPlus.GdipShearMatrix (nativeMatrix, shearX, shearY, order);\r
+                }\r
         \r
-        public void TransformPoints(PointF[] pts)\r
-        {\r
-            for (int i = 0; i < pts.Length; i++)\r
-            {\r
-                float x = pts[i].X;\r
-                float y = pts[i].Y;\r
-                pts[i].X = x * m[0] + y * m[2] + m[4];\r
-                pts[i].Y = x * m[1] + y * m[3] + m[5];\r
-            }\r
-        }\r
+                public void TransformPoints (Point[] pts)\r
+                {\r
+                        GDIPlus.GdipTransformMatrixPointsI (nativeMatrix, pts, pts.Length);\r
+                }\r
         \r
-        public void TransformVectors(Point[] pts)\r
-        {\r
-            for (int i = 0; i < pts.Length; i++)\r
-            {\r
-                float x = (float)pts[i].X;\r
-                float y = (float)pts[i].Y;\r
-                pts[i].X = (int)(x * m[0] + y * m[2]);\r
-                pts[i].Y = (int)(x * m[1] + y * m[3]);\r
-            }\r
-        }\r
+                public void TransformPoints (PointF[] pts)\r
+                {\r
+                        GDIPlus.GdipTransformMatrixPoints (nativeMatrix, pts, pts.Length);\r
+                }\r
         \r
-        public void TransformVectors(PointF[] pts)\r
-        {\r
-            for (int i = 0; i < pts.Length; i++)\r
-            {\r
-                float x = pts[i].X;\r
-                float y = pts[i].Y;\r
-                pts[i].X = x * m[0] + y * m[2];\r
-                pts[i].Y = x * m[1] + y * m[3];\r
-            }\r
-        }\r
+                public void TransformVectors (Point[] pts)\r
+                {\r
+                        GDIPlus.GdipVectorTransformMatrixPointsI (nativeMatrix, pts, pts.Length);\r
+                }\r
         \r
-        public void Translate(float offsetX, float offsetY)\r
-        {\r
-            Translate(offsetX, offsetY, MatrixOrder.Prepend);\r
-        }\r
+                public void TransformVectors (PointF[] pts)\r
+                {\r
+                        GDIPlus.GdipVectorTransformMatrixPoints (nativeMatrix, pts, pts.Length);                        \r
+                }\r
         \r
-        public void Translate(float offsetX, float offsetY, MatrixOrder order)\r
-        {\r
-            switch (order)\r
-            {\r
-                case MatrixOrder.Prepend:\r
-                    // this = translation * this\r
-                    m[4] = offsetX * m[0] + offsetY * m[2] + m[4];\r
-                    m[5] = offsetX * m[1] + offsetY * m[3] + m[5];\r
-                    break;\r
-                case MatrixOrder.Append:\r
-                    // this = this * translation\r
-                    m[4] += offsetX;\r
-                    m[5] += offsetY;\r
-                    break;\r
-            }\r
-        }\r
+                public void Translate (float offsetX, float offsetY)\r
+                {\r
+                        Translate (offsetX, offsetY, MatrixOrder.Prepend);\r
+                }\r
         \r
-        // LAMESPEC: quote from beta 2 sdk docs: "[To be supplied!]"\r
-//     [MonoTODO]    \r
-       public void VectorTransformPoints(Point[] pts)\r
-        {\r
-            // TODO\r
-        }\r
+                public void Translate (float offsetX, float offsetY, MatrixOrder order)\r
+                {\r
+                        GDIPlus.GdipTranslateMatrix (nativeMatrix, offsetX, offsetY, order);\r
+                }\r
         \r
-        // some simple test (TODO: remove)\r
-        /*\r
-        public static void Main()\r
-        {\r
-            PointF[] p = {new PointF(1.0f, 2.0f)};\r
-            Console.WriteLine("(" + p[0].X + " " + p[0].Y + ")");\r
-            Matrix m = new Matrix();\r
-            \r
-            m.Translate(1.0f, 1.0f); \r
-            m.Scale(2.0f, 2.0f); \r
-            m.Rotate(180.0f);\r
-            \r
-            m.TransformPoints(p);\r
-            Console.WriteLine("(" + p[0].X + " " + p[0].Y + ")");\r
-            m.Invert();\r
-            m.TransformPoints(p);\r
-            Console.WriteLine("(" + p[0].X + " " + p[0].Y + ")");\r
-            \r
-            Matrix a = new Matrix(1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f);\r
-            Matrix b = new Matrix(2.0f, 0.0f, 0.0f, 2.0f, 0.0f, 0.0f);\r
-            \r
-            Console.WriteLine("h(a) = " + a.GetHashCode());\r
-            Console.WriteLine("h(b) = " + b.GetHashCode());\r
+                public void VectorTransformPoints (Point[] pts)\r
+                {\r
+                        TransformVectors (pts);\r
+                }\r
         }\r
-        */\r
-        \r
-    }\r
 }\r
index 437d1931f36fb12cca51fe3c495da364d9825849..85d627f51ccb51358be3796db67cf6330a855c09 100644 (file)
@@ -1,3 +1,19 @@
+2003-11-22  Duncan Mak  <duncan@ximian.com>
+
+       * gdipFunctions.cs
+       (GdipResetWorldTransform, GdipSetWorldTransform):
+       (GdipGetWorldTransform, GdipScaleWorldTransform): Imported.
+
+       * Graphics.cs: Remove unnecessary TODO, and reformatted the code.
+       (transform): Removed this field. Always use the
+       matrix associated in the GpGraphics ptr.
+       (DrawBeziers): Implemented.
+       (DrawLine): Don't need to manually invoke the transform now.
+       (MultiplyTransform, ResetTransform): 
+       (ScaleTransform, TranslateTransform): Use GDI+ implementation.
+       (Transform): Instead of storing a Matrix in managed code, use
+       equivalent GDI+ functions.
+
 2003-11-21  Gonzalo Paniagua Javier <gonzalo@ximian.com>
 
        * SizeConverter.cs: fixed class signature and implemented some methods.
index 82efcdd5b33b4e901f88463a40b60f42425fc7e9..a158c4a14e8dc857055522b42f49a6a7815f4079 100755 (executable)
@@ -18,9 +18,7 @@ namespace System.Drawing
        [ComVisible(false)]
        public sealed class Graphics : MarshalByRefObject, IDisposable
        {
-               internal IntPtr nativeObject;
-               
-               internal Matrix transform = new Matrix();
+               internal IntPtr nativeObject;
                
                public delegate bool EnumerateMetafileProc (EmfPlusRecordType recordType,
                                                            int flags,
@@ -110,16 +108,44 @@ namespace System.Drawing
                         GDIPlus.GdipDrawBezier (nativeObject, pen.nativeObject, x1, y1, x2, y2, x3, y3, x4, y4);
                }
 
-               [MonoTODO]
+                [MonoTODO]
                public void DrawBeziers (Pen pen, Point [] points)
                {
-                       throw new NotImplementedException ();
+                        int length = points.Length;
+
+                        if (length < 3)
+                                return;
+
+                       for (int i = 0; i < length; i += 3) {
+                                Point p1 = points [i];
+                                Point p2 = points [i + 1];
+                                Point p3 = points [i + 2];
+                                Point p4 = points [i + 3];
+
+                                GDIPlus.GdipDrawBezier (nativeObject, pen.nativeObject,
+                                                        p1.X, p1.Y, p2.X, p2.Y, 
+                                                        p3.X, p3.Y, p4.X, p4.Y);
+                        }
                }
 
-               [MonoTODO]
+                [MonoTODO]
                public void DrawBeziers (Pen pen, PointF [] points)
                {
-                       throw new NotImplementedException ();
+                       int length = points.Length;
+
+                        if (length < 3)
+                                return;
+
+                       for (int i = 0; i < length; i += 3) {
+                                PointF p1 = points [i];
+                                PointF p2 = points [i + 1];
+                                PointF p3 = points [i + 2];
+                                PointF p4 = points [i + 3];
+
+                                GDIPlus.GdipDrawBezier (nativeObject, pen.nativeObject,
+                                                        p1.X, p1.Y, p2.X, p2.Y, 
+                                                        p3.X, p3.Y, p4.X, p4.Y);
+                        }
                }
 
                [MonoTODO]
@@ -188,13 +214,11 @@ namespace System.Drawing
                        throw new NotImplementedException ();
                }
 
-               [MonoTODO]
                public void DrawEllipse (Pen pen, Rectangle rect)
                {
                        DrawEllipse (pen, rect.X, rect.Y, rect.Width, rect.Height);
                }
 
-               [MonoTODO]
                public void DrawEllipse (Pen pen, RectangleF rect)
                {
                        DrawEllipse (pen, rect.X, rect.Y, rect.Width, rect.Height);
@@ -432,32 +456,20 @@ namespace System.Drawing
                        throw new NotImplementedException ();
                }
 
-               [MonoTODO]
                public void DrawLine (Pen pen, PointF pt1, PointF pt2)
                {
-                       PointF[] pts = new PointF[2];
-                       pts[0] = pt1;
-                       pts[1] = pt2;
-                       transform.TransformPoints(pts);
-
                         GDIPlus.GdipDrawLine (
                                 nativeObject, pen.nativeObject,
-                                pts [0].X, pts [0].Y,
-                                pts [1].X, pts [1].Y);
+                                pt1.X, pt1.Y,
+                                pt2.X, pt2.Y);
                }
 
-               [MonoTODO]
                public void DrawLine (Pen pen, Point pt1, Point pt2)
                {
-                       Point[] pts = new Point[2];
-                       pts[0] = pt1;
-                       pts[1] = pt2;
-                       transform.TransformPoints(pts);
-
                         GDIPlus.GdipDrawLine (
                                 nativeObject, pen.nativeObject,
-                                pts [0].X, pts [0].Y,
-                                pts [1].X, pts [1].Y);
+                                pt1.X, pt1.Y,
+                                pt2.X, pt2.Y);
                 }
 
                public void DrawLine (Pen pen, int x1, int y1, int x2, int y2)
@@ -515,7 +527,6 @@ namespace System.Drawing
                        GDIPlus.GdipDrawPolygonI (nativeObject, pen.nativeObject, points, points.Length);
                }
 
-               [MonoTODO]
                public void DrawPolygon (Pen pen, PointF [] points)
                {
                        GDIPlus.GdipDrawPolygon (nativeObject, pen.nativeObject, points, points.Length);
@@ -541,20 +552,16 @@ namespace System.Drawing
                        GDIPlus.GdipDrawRectangleI (nativeObject, pen.nativeObject, x, y, width, height);
                }
 
-               [MonoTODO]
                public void DrawRectangles (Pen pen, RectangleF [] rects)
                {
-                       foreach( RectangleF rc in rects) {
-                               DrawRectangle(pen, rc.Left, rc.Top, rc.Width, rc.Height);
-                       }
+                       foreach (RectangleF rc in rects)
+                               DrawRectangle (pen, rc.Left, rc.Top, rc.Width, rc.Height);
                }
 
-               [MonoTODO]
                public void DrawRectangles (Pen pen, Rectangle [] rects)
                {
-                       foreach( RectangleF rc in rects) {
+                       foreach (RectangleF rc in rects)
                                DrawRectangle(pen, rc.Left, rc.Top, rc.Width, rc.Height);
-                       }
                }
 
                [MonoTODO("Ignores the font")]
@@ -947,48 +954,36 @@ namespace System.Drawing
                        GDIPlus.GdipFillPolygon (nativeObject, brush.nativeObject, points, points.Length, fillMode);
                }
 
-               [MonoTODO]
                public void FillRectangle (Brush brush, RectangleF rect)
                {
-                   FillRectangle( brush, rect.Left, rect.Top, rect.Width, rect.Height);
+                        FillRectangle (brush, rect.Left, rect.Top, rect.Width, rect.Height);
                }
 
-               [MonoTODO]
                public void FillRectangle (Brush brush, Rectangle rect)
                {
-                   FillRectangle( brush, rect.Left, rect.Top, rect.Width, rect.Height);
+                        FillRectangle (brush, rect.Left, rect.Top, rect.Width, rect.Height);
                }
 
-               [MonoTODO]
                public void FillRectangle (Brush brush, int x, int y, int width, int height)
                {
                        GDIPlus.GdipFillRectangle (nativeObject, brush.nativeObject, (float)x, (float)y, (float)width, (float)height);
                }
 
-               [MonoTODO]
                public void FillRectangle (Brush brush, float x, float y, float width, float height)
                {
                        GDIPlus.GdipFillRectangle (nativeObject, brush.nativeObject, x, y, width, height);
                }
 
-               [MonoTODO]
                public void FillRectangles (Brush brush, Rectangle [] rects)
                {
-                   if(rects != null) {
-                               foreach( Rectangle rc in rects) {
-                                   FillRectangle(brush, rc);
-                               }
-                   }
+                        foreach (Rectangle rc in rects)
+                                FillRectangle(brush, rc);
                }
 
-               [MonoTODO]
                public void FillRectangles (Brush brush, RectangleF [] rects)
                {
-                   if(rects != null) {
-                       foreach( RectangleF rc in rects) {
-                           FillRectangle(brush, rc);
-                       }
-                   }
+                       foreach (RectangleF rc in rects)
+                                FillRectangle(brush, rc);
                }
 
                [MonoTODO]
@@ -1194,7 +1189,7 @@ namespace System.Drawing
 
                public void MultiplyTransform (Matrix matrix, MatrixOrder order)
                {
-                       // GDIPlus.GdipMultiplyWorldTransform (nativeObject, matrix.nativeMatrix, order);
+                       GDIPlus.GdipMultiplyWorldTransform (nativeObject, matrix.nativeMatrix, order);
                }
 
                [MonoTODO]
@@ -1215,16 +1210,15 @@ namespace System.Drawing
                        throw new NotImplementedException ();
                }
 
-               [MonoTODO]
                public void ResetTransform ()
                {
-                       throw new NotImplementedException ();
+                       GDIPlus.GdipResetWorldTransform (nativeObject);
                }
 
                [MonoTODO]
                public void Restore (GraphicsState gstate)
                {
-                       transform = gstate.matrix.Clone();
+                       Transform = gstate.matrix.Clone();
                        GDIPlus.GdipRestoreGraphics (nativeObject, gstate.nativeState);
                }
 
@@ -1238,7 +1232,7 @@ namespace System.Drawing
                public void RotateTransform (float angle, MatrixOrder order)
                {
                        //transform.Rotate(angle, order);
-                       GDIPlus.GdipRotateWorldTransform (nativeObject, angle, order);
+                       // GDIPlus.GdipRotateWorldTransform (nativeObject, angle, order);
                }
 
                [MonoTODO]
@@ -1246,21 +1240,19 @@ namespace System.Drawing
                {
                        //return implementation.Save();
                        GraphicsState state = new GraphicsState();
-                       state.matrix = transform.Clone();
+                       state.matrix = Transform.Clone();
                        GDIPlus.GdipSaveGraphics (nativeObject, out state.nativeState);
                        return state;
                }
 
-               [MonoTODO]
                public void ScaleTransform (float sx, float sy)
                {
-                       throw new NotImplementedException ();
+                       ScaleTransform (sx, sy, MatrixOrder.Prepend);
                }
 
-               [MonoTODO]
                public void ScaleTransform (float sx, float sy, MatrixOrder order)
                {
-                       throw new NotImplementedException ();
+                        GDIPlus.GdipScaleWorldTransform (nativeObject, sx, sy, order);
                }
 
                [MonoTODO]
@@ -1341,10 +1333,9 @@ namespace System.Drawing
                        throw new NotImplementedException ();
                }
 
-               [MonoTODO]
                public void TranslateTransform (float dx, float dy)
                {
-                       TranslateTransform(dx, dy, MatrixOrder.Prepend);
+                       TranslateTransform (dx, dy, MatrixOrder.Prepend);
                }
 
                [MonoTODO]
@@ -1354,8 +1345,7 @@ namespace System.Drawing
                        GDIPlus.GdipTranslateWorldTransform (nativeObject, dx, dy, order);
                }
 
-               public Region Clip
-               {
+               public Region Clip {
                        get {
                                throw new NotImplementedException ();
                        }
@@ -1364,15 +1354,13 @@ namespace System.Drawing
                        }
                }
 
-               public RectangleF ClipBounds
-               {
+               public RectangleF ClipBounds {
                        get {
                                throw new NotImplementedException ();
                        }
                }
 
-               public CompositingMode CompositingMode
-               {
+               public CompositingMode CompositingMode {
                        get {
                                throw new NotImplementedException ();
                        }
@@ -1381,8 +1369,8 @@ namespace System.Drawing
                        }
 
                }
-               public CompositingQuality CompositingQuality
-               {
+
+               public CompositingQuality CompositingQuality {
                        get {
                                throw new NotImplementedException ();
                        }
@@ -1391,22 +1379,19 @@ namespace System.Drawing
                        }
                }
 
-               public float DpiX
-               {
+               public float DpiX {
                        get {
                                throw new NotImplementedException ();
                        }
                }
 
-               public float DpiY
-               {
+               public float DpiY {
                        get {
                                throw new NotImplementedException ();
                        }
                }
 
-               public InterpolationMode InterpolationMode
-               {
+               public InterpolationMode InterpolationMode {
                        get {
                                throw new NotImplementedException ();
                        }
@@ -1415,22 +1400,19 @@ namespace System.Drawing
                        }
                }
 
-               public bool IsClipEmpty
-               {
+               public bool IsClipEmpty {
                        get {
                                throw new NotImplementedException ();
                        }
                }
 
-               public bool IsVisibleClipEmpty
-               {
+               public bool IsVisibleClipEmpty {
                        get {
                                throw new NotImplementedException ();
                        }
                }
 
-               public float PageScale
-               {
+               public float PageScale {
                        get {
                                throw new NotImplementedException ();
                        }
@@ -1439,8 +1421,7 @@ namespace System.Drawing
                        }
                }
 
-               public GraphicsUnit PageUnit
-               {
+               public GraphicsUnit PageUnit {
                        get {
                                throw new NotImplementedException ();
                        }
@@ -1449,8 +1430,7 @@ namespace System.Drawing
                        }
                }
 
-               public PixelOffsetMode PixelOffsetMode
-               {
+               public PixelOffsetMode PixelOffsetMode {
                        get {
                                throw new NotImplementedException ();
                        }
@@ -1502,10 +1482,13 @@ namespace System.Drawing
 
                public Matrix Transform {
                        get {
-                                return transform;
+                                Matrix matrix = new Matrix ();
+                                GDIPlus.GdipGetWorldTransform (nativeObject, matrix.nativeMatrix);
+
+                                return matrix;
                        }
                        set {
-                               transform = value.Clone();
+                                GDIPlus.GdipSetWorldTransform (nativeObject, value.nativeMatrix);
                        }
                }
 
index a4ca3659a3f626141a52744961378719c3548f9e..581a67e940fe89ac75eca3b998f526d5d5a527d3 100644 (file)
@@ -122,8 +122,14 @@ namespace System.Drawing {
                static internal extern Status GdipSetRenderingOrigin (IntPtr graphics, int x, int y);
                [DllImport("gdiplus.dll")]
                internal static extern Status GdipCloneBitmapAreaI (int x, int y, int width, int height, PixelFormat format, IntPtr original, out int bitmap);
-
-                
+               [DllImport("gdiplus.dll")]
+               internal static extern Status GdipResetWorldTransform (IntPtr graphics);
+               [DllImport("gdiplus.dll")]
+               internal static extern Status GdipSetWorldTransform (IntPtr graphics, IntPtr matrix);
+               [DllImport("gdiplus.dll")]
+               internal static extern Status GdipGetWorldTransform (IntPtr graphics, IntPtr matrix);
+               [DllImport("gdiplus.dll")]
+               internal static extern Status GdipScaleWorldTransform (IntPtr graphics, float sx, float sy, MatrixOrder order);
                
                // Pen functions
                [DllImport("gdiplus.dll")]
index d0f06956cba74c11171ffc0dafc0f785e401200c..468f9f6eb58bf79e3a377a7285414c995d5c214a 100644 (file)
@@ -1,8 +1,35 @@
+2003-11-22  Duncan Mak  <duncan@ximian.com>
+
+       * matrix.c (GdipCreateMatrix3, GdipCreateMatrix3I): Implemented.
+       (GdipCloneMatrix): Fixed.
+       (GdipShearMatrix, set_shear): Implemented.
+       
+       * graphics.c:
+       (GdipGetWorldTransform, GdipMultiplyWorldTransform): Implemented.
+       (GdipRotatePenTransform, GdipTranslatePenTransform): Use GDI+
+       functions instead.
+
+       * gdip.h
+       (GdipRotatePenTransform, GdipTranslatePenTransform): Fix
+       signature.
+       (GdipCreateMatrix3, GdipCreateMatrix3I): Use const appropriately.
+       
+2003-11-17  Duncan Mak  <duncan@ximian.com>
+
+       * matrix.c (matrix_equals): New helper function help test matrix
+       equality.
+       (GdipIsMatrixIdentity, GdipIsMatrixEqual): Use matrix_equals.
+       (GdipGetMatrixElements): Don't malloc here, because the caller
+       should hand us an allocated array.
+
 2003-11-16  Duncan Mak  <duncan@ximian.com>
 
+       * matrix.c (GdipCreateMatrix2, GdipCreateMatrix3) 
+       (GdipCreateMatrix3I): Implemented.
+
        * pen.c (GdipResetPenTransform):
        (GdipMultiplyPenTransform, GdipTranslatePenTransform):
-       (GdipScalePenTransform, GdipRotatePenTransform): Implemented..
+       (GdipScalePenTransform, GdipRotatePenTransform): Implemented.
 
        * matrix.c (set_translate, set_scale, set_rotate): Helper
        functions copied from Cairo. We are doing this because you can
@@ -21,8 +48,7 @@
        (GdipSetMatrixElements, GdipGetMatrixElements):
        (GdipIsMatrixInvertible): Implemented.
 
-       * matrix.c (GdipIsMatrixIdentity, GdipIsMatrixEqual): Implemented,
-       but pending commit for cairo_matrix_equals to Cairo.
+       * matrix.c (GdipIsMatrixIdentity, GdipIsMatrixEqual): Implemented.
 
 2003-11-14  Duncan Mak  <duncan@ximian.com>    
 
index 0e3ae7cfffcf210c22dd24b6ccace6e1b45ba5d7..202b7adfe1342567c63e639f3410cc9e9b9eebb5 100644 (file)
@@ -279,8 +279,8 @@ GpStatus GdipGetDC (GpGraphics *graphics, int *hDC);
 GpStatus GdipReleaseDC (GpGraphics *graphics, int hDC);
 GpStatus GdipRestoreGraphics (GpGraphics *graphics, unsigned int graphicsState);
 GpStatus GdipSaveGraphics(GpGraphics *graphics, unsigned int * state);
-GpStatus GdipRotateWorldTransform (GpGraphics *graphics, float angle, int order);
-GpStatus GdipTranslateWorldTransform (GpGraphics *graphics, float dx, float dy, int order);
+GpStatus GdipRotateWorldTransform (GpGraphics *graphics, float angle, GpMatrixOrder order);
+GpStatus GdipTranslateWorldTransform (GpGraphics *graphics, float dx, float dy, GpMatrixOrder order);
 GpStatus GdipDrawBezier (GpGraphics *graphics, GpPen *pen, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4);
 GpStatus GdipDrawBezierI (GpGraphics *graphics, GpPen *pen, int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4);
 GpStatus GdipDrawBeziers (GpGraphics *graphics, GpPen *pen, GpPointF *points, int count);
@@ -329,8 +329,8 @@ GpStatus GdipDrawString (GpGraphics *graphics, const char *string, int len, void
 /* Matrix */
 GpStatus GdipCreateMatrix (GpMatrix **matrix);
 GpStatus GdipCreateMatrix2 (float m11, float m12, float m21, float m22, float dx, float dy, GpMatrix **matrix);
-GpStatus GdipCreateMatrix3 (GpRectF *rect, GpPointF *dstplg, GpMatrix **matrix);
-GpStatus GdipCreateMatrix3I (GpRect *rect, GpPoint *dstplg, GpMatrix **matrix);
+GpStatus GdipCreateMatrix3 (const GpRectF *rect, const GpPointF *dstplg, GpMatrix **matrix);
+GpStatus GdipCreateMatrix3I (const GpRect *rect, const GpPoint *dstplg, GpMatrix **matrix);
 GpStatus GdipCloneMatrix (GpMatrix *matrix, GpMatrix **cloneMatrix);
 GpStatus GdipDeleteMatrix (GpMatrix *matrix);
 GpStatus GdipSetMatrixElements (GpMatrix *matrix, float m11, float m12, float m21, float m22, float dx, float dy);
index 5455051870dc7ca8b2d25cb1d27d779520d2e8b9..6072ad11d40d240afc84d7c6efeb22107f7ac363 100644 (file)
@@ -281,25 +281,73 @@ GdipSaveGraphics(GpGraphics *graphics, unsigned int *state)
        }
        return Ok;
 }
+GpStatus
+GdipResetWorldTransform (GpGraphics *graphics)
+{
+        GpStatus s = cairo_matrix_set_identity (graphics->copy_of_ctm);
+
+        if (s != Ok)
+                return s;
+        else {
+                cairo_set_matrix (graphics->ct, graphics->copy_of_ctm);
+                return Ok;
+        }
+}
+
+GpStatus
+GdipSetWorldTransform (GpGraphics *graphics, GpMatrix *matrix)
+{
+        graphics->copy_of_ctm = matrix;
+        cairo_set_matrix (graphics->ct, graphics->copy_of_ctm);
+        return Ok;
+}
 
 GpStatus 
-GdipRotateWorldTransform (GpGraphics *graphics, float angle, int order)
+GdipGetWorldTransform (GpGraphics *graphics, GpMatrix *matrix)
 {
-       cairo_matrix_t *mtx = cairo_matrix_create ();
-       cairo_matrix_rotate (mtx, angle * DEGTORAD);
-       cairo_matrix_multiply (graphics->copy_of_ctm, mtx, graphics->copy_of_ctm );
-       cairo_matrix_destroy ( mtx);
-       cairo_set_matrix (graphics->ct, graphics->copy_of_ctm);
-       return Ok;
+        cairo_current_matrix (graphics->ct, matrix);
+        return Ok;
+}
+
+GpStatus
+GdipMultiplyWorldTransform (GpGraphics *graphics, const GpMatrix *matrix, GpMatrixOrder order)
+{
+        GpMatrix *tmp = matrix;
+        Status s = GdipMultiplyMatrix (graphics->copy_of_ctm, tmp, order);
+        
+        if (s != Ok)
+                return s;
+
+        else {
+                cairo_set_matrix (graphics->ct, graphics->copy_of_ctm);
+                return Ok;
+        }
 }
 
 GpStatus 
-GdipTranslateWorldTransform (GpGraphics *graphics, float dx, float dy, int order)
+GdipRotateWorldTransform (GpGraphics *graphics, float angle, GpMatrixOrder order)
 {
-       /* FIXME: consider order here */
-       cairo_matrix_translate (graphics->copy_of_ctm, dx, dy);
-       cairo_set_matrix (graphics->ct, graphics->copy_of_ctm);
-       return Ok;
+       GpStatus s = GdipRotateMatrix (graphics->copy_of_ctm, angle, order);
+
+        if (s != Ok)
+                return s;
+        else {
+                cairo_set_matrix (graphics->ct, graphics->copy_of_ctm);
+                return Ok;
+        }
+}
+
+GpStatus 
+GdipTranslateWorldTransform (GpGraphics *graphics, float dx, float dy, GpMatrixOrder order)
+{
+        GpStatus s = GdipTranslateMatrix (graphics->copy_of_ctm, dx, dy, order);
+
+        if (s != Ok) 
+                return s;
+        else {
+                cairo_set_matrix (graphics->ct, graphics->copy_of_ctm);
+                return Ok;
+        }
 }
 
 /* XXX: TODO */
@@ -633,10 +681,6 @@ GdipSetRenderingOrigin (GpGraphics *graphics, int x, int y)
         return gdip_get_status (cairo_status (graphics->ct));
 }
 
-/*
- * FIXME: cairo_current_point does not reflect changes made from
- * cairo_move_to.
- */
 GpStatus 
 GdipGetRenderingOrigin (GpGraphics *graphics, int *x, int *y)
 {
index 6d4e5dcdb6fe8dabe2885512601c2eda9cb53255..d125308713f61e38fb7f59829df7b4d5ca897588 100644 (file)
 #include <math.h>
 #include "gdip.h"
 
-GpStatus
+GpStatus 
 GdipCreateMatrix (GpMatrix **matrix)
 {
         *matrix = cairo_matrix_create ();
-
+        cairo_matrix_set_affine (*matrix, 1, 0, 0, 1, 0, 0);
         return Ok;
 }
 
@@ -29,20 +29,44 @@ GdipCreateMatrix2 (float m11, float m12, float m21, float m22, float dx, float d
 }
 
 GpStatus
-GdipCreateMatrix3 (GpRectF *rect, GpPointF *dstplg, GpMatrix **matrix)
+GdipCreateMatrix3 (const GpRectF *rect, const GpPointF *dstplg, GpMatrix **matrix)
 {
-        return NotImplemented;
+        *matrix = cairo_matrix_create ();
+        double m11 = rect->left;
+        double m12 = rect->top;
+        double m21 = (rect->right) - (rect->left); /* width */
+        double m22 = (rect->bottom) - (rect->top); /* height */
+        double dx = dstplg->X;
+        double dy = dstplg->Y;
+
+        Status s = cairo_matrix_set_affine (
+                        *matrix, m11, m12, m21, m22, dx, dy);
+
+        return gdip_get_status (s);
 }
 
 GpStatus
-GdipCreateMatrix3I (GpRect *rect, GpPoint *dstplg, GpMatrix **matrix)
+GdipCreateMatrix3I (const GpRect *rect, const GpPoint *dstplg, GpMatrix **matrix)
 {
-        return NotImplemented;
+        *matrix = cairo_matrix_create ();
+        double m11 = rect->left;
+        double m12 = rect->top;
+        double m21 = (rect->right) - (rect->left); /* width */
+        double m22 = (rect->bottom) - (rect->top); /* height */
+        double dx = dstplg->X;
+        double dy = dstplg->Y;
+        
+        Status s = cairo_matrix_set_affine (
+                        *matrix, m11, m12, m21, m22, dx, dy);
+
+        return gdip_get_status (s);
 }
 
 GpStatus
 GdipCloneMatrix (GpMatrix *matrix, GpMatrix **cloneMatrix)
 {
+        *cloneMatrix = cairo_matrix_create ();
+        
         return gdip_get_status (
                 cairo_matrix_copy (*cloneMatrix, matrix));
 }
@@ -50,7 +74,8 @@ GdipCloneMatrix (GpMatrix *matrix, GpMatrix **cloneMatrix)
 GpStatus
 GdipDeleteMatrix (GpMatrix *matrix)
 {
-        cairo_matrix_destroy (matrix);
+        if (matrix)
+                cairo_matrix_destroy (matrix);
         return Ok;
 }
 
@@ -65,16 +90,15 @@ GpStatus
 GdipGetMatrixElements (GpMatrix *matrix, float *matrixOut)
 {
         double a, b, c, d, tx, ty;
-        matrixOut = malloc (6 * sizeof (float));
-
+        
         cairo_matrix_get_affine (matrix, &a, &b, &c, &d, &tx, &ty);
         
-        matrixOut [0] = (float) a;
-        matrixOut [1] = (float) b;
-        matrixOut [2] = (float) c;
-        matrixOut [3] = (float) d;
-        matrixOut [4] = (float) tx;
-        matrixOut [5] = (float) ty;
+        matrixOut[0] = (float) a;
+        matrixOut[1] = (float) b;
+        matrixOut[2] = (float) c;
+        matrixOut[3] = (float) d;
+        matrixOut[4] = (float) tx;
+        matrixOut[5] = (float) ty;
 
         return Ok;
 }
@@ -82,19 +106,17 @@ GdipGetMatrixElements (GpMatrix *matrix, float *matrixOut)
 GpStatus
 GdipMultiplyMatrix (GpMatrix *matrix, GpMatrix *matrix2, GpMatrixOrder order)
 {
-        GpMatrix *result = NULL;
         cairo_status_t status;
 
         if (order == MatrixOrderPrepend)
-                status = cairo_matrix_multiply (result, matrix, matrix2);
-
-        if (order == MatrixOrderAppend)
-                status = cairo_matrix_multiply (result, matrix2, matrix);
+                status = cairo_matrix_multiply (matrix, matrix, matrix2);
 
+        else if (order == MatrixOrderAppend)
+                status = cairo_matrix_multiply (matrix, matrix2, matrix);
+        
         else
                 return GenericError;
 
-        matrix = result;
         return gdip_get_status (status);
 }
 
@@ -154,10 +176,22 @@ GdipRotateMatrix (GpMatrix *matrix, float angle, GpMatrixOrder order)
         return s;
 }
 
+static GpMatrix *
+set_shear (float shearX, float shearY)
+{
+        GpMatrix *matrix = cairo_matrix_create ();
+        cairo_matrix_set_affine (matrix, 1, shearX, shearY, 1, 0, 0);
+        return matrix;
+}
+
 GpStatus
 GdipShearMatrix (GpMatrix *matrix, float shearX, float shearY, GpMatrixOrder order)
 {
-        return NotImplemented;
+        GpMatrix *tmp = set_shear (shearX, shearY);
+        GpStatus s = GdipMultiplyMatrix (matrix, tmp, order);
+        GdipDeleteMatrix (tmp);
+
+        return s;
 }
 
 GpStatus
@@ -179,6 +213,7 @@ GdipTransformMatrixPoints (GpMatrix *matrix, GpPointF *pts, int count)
                 status = cairo_matrix_transform_point (matrix, &x, &y);
                 if (status != CAIRO_STATUS_SUCCESS)
                         return gdip_get_status (status);
+
                 pts->X = (float) x;
                 pts->Y = (float) y;
         }
@@ -250,30 +285,44 @@ GdipIsMatrixInvertible (GpMatrix *matrix, int *result)
         cairo_status_t status = cairo_matrix_invert (matrix);
 
         if (status == CAIRO_STATUS_INVALID_MATRIX)
-                *result = 1;
+                *result = 0;
 
-        *result = 0;
+        *result = 1;
         return Ok;
 }
 
+static int
+matrix_equals (GpMatrix *x, GpMatrix *y)
+{
+        double ax, bx, cx, dx, ex, fx;
+        double ay, by, cy, dy, ey, fy;
+
+        cairo_matrix_get_affine (x, &ax, &bx, &cx, &dx, &ex, &fx);
+        cairo_matrix_get_affine (y, &ay, &by, &cy, &dy, &ey, &fy);
+
+        if ((ax != ay) || (bx != by) || (cx != cy) ||
+            (dx != dy) || (ex != ey) || (fx != fy))
+                return 0;
+
+        return 1;
+}
+
 GpStatus
 GdipIsMatrixIdentity (GpMatrix *matrix, int *result)
 {
-        cairo_matrix_t *identity = cairo_matrix_create ();
-
-/*         if (cairo_matrix_equals (matrix, identity)) */
-/*                 *result = 1; */
+        GpMatrix *identity = cairo_matrix_create ();
+        cairo_matrix_set_identity (identity);
 
-        *result = 0;
+        Status s = GdipIsMatrixEqual (matrix, identity, result);
+        GdipDeleteMatrix (identity);
 
-        cairo_matrix_destroy (identity);
-        return Ok;
+        return s;
 }
 
 GpStatus
 GdipIsMatrixEqual (GpMatrix *matrix, GpMatrix *matrix2, int *result)
 {
-/*         *result = cairo_matrix_equals (matrix, matrix2); */
-
+        *result = matrix_equals (matrix, matrix2);
         return Ok;
 }
+
index 7eb6e116df51a4e4ad999ed2970623152f79a86a..17bfd8b7b8fdef2821a7ff90ddf5d9e05e108885 100644 (file)
@@ -188,7 +188,7 @@ GdipResetPenTransform (GpPen *pen)
 }
 
 GpStatus
-GdipMultiplyPenTransform (GpPen *pen, const GpMatrix *matrix, GpMatrixOrder order)
+GdipMultiplyPenTransform (GpPen *pen, GpMatrix *matrix, GpMatrixOrder order)
 {
         return GdipMultiplyMatrix (pen->matrix, matrix, order);
 }