This commit was manufactured by cvs2svn to create branch 'mono-1-0'.
[mono.git] / mcs / class / System.Drawing / System.Drawing.Drawing2D / Matrix.cs
1 //\r
2 // System.Drawing.Drawing2D.Matrix.cs\r
3 //\r
4 // Authors:\r
5 //   Stefan Maierhofer <sm@cg.tuwien.ac.at>\r
6 //   Dennis Hayes (dennish@Raytek.com)\r
7 //   Duncan Mak (duncan@ximian.com)\r
8 //   Ravindra (rkumar@novell.com)
9 //\r
10 // (C) Ximian, Inc.  http://www.ximian.com
11 // (C) Novell, Inc.  http://www.novell.com\r
12 //\r
13
14 //
15 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
16 //
17 // Permission is hereby granted, free of charge, to any person obtaining
18 // a copy of this software and associated documentation files (the
19 // "Software"), to deal in the Software without restriction, including
20 // without limitation the rights to use, copy, modify, merge, publish,
21 // distribute, sublicense, and/or sell copies of the Software, and to
22 // permit persons to whom the Software is furnished to do so, subject to
23 // the following conditions:
24 // 
25 // The above copyright notice and this permission notice shall be
26 // included in all copies or substantial portions of the Software.
27 // 
28 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
29 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
30 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
31 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
32 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
33 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
34 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35 //
36 \r
37 using System;\r
38 using System.Drawing;\r
39 using System.Runtime.InteropServices;\r
40 \r
41 namespace System.Drawing.Drawing2D\r
42 {\r
43         public sealed class Matrix : MarshalByRefObject, IDisposable\r
44         {\r
45                 internal IntPtr nativeMatrix;\r
46                 \r
47                 // constructors\r
48                 internal Matrix (IntPtr ptr)\r
49                 {\r
50                         nativeMatrix = ptr;\r
51                 }\r
52                 \r
53                 public Matrix ()\r
54                 {\r
55                         Status status = GDIPlus.GdipCreateMatrix (out nativeMatrix);
56                         GDIPlus.CheckStatus (status);\r
57                 }\r
58         \r
59                 public Matrix (Rectangle rect , Point[] plgpts)\r
60                 {\r
61                         Status status = GDIPlus.GdipCreateMatrix3I (rect, plgpts, out nativeMatrix);
62                         GDIPlus.CheckStatus (status);\r
63                 }\r
64         \r
65                 public Matrix (RectangleF rect , PointF[] pa)\r
66                 {\r
67                         Status status = GDIPlus.GdipCreateMatrix3 (rect, pa, out nativeMatrix);
68                         GDIPlus.CheckStatus (status);\r
69                 }\r
70 \r
71                 public Matrix (float m11, float m12, float m21, float m22, float dx, float dy)\r
72                 {\r
73                         Status status = GDIPlus.GdipCreateMatrix2 (m11, m12, m21, m22, dx, dy, out nativeMatrix);
74                         GDIPlus.CheckStatus (status);\r
75                 }\r
76         \r
77                 // properties\r
78                 public float[] Elements {\r
79                         get {\r
80                                 IntPtr tmp = Marshal.AllocHGlobal (Marshal.SizeOf (typeof (float)) * 6);\r
81                                 float [] retval = new float [6];\r
82 \r
83                                 Status status = GDIPlus.GdipGetMatrixElements (nativeMatrix, tmp);\r
84                                 GDIPlus.CheckStatus (status);
85 \r
86                                 Marshal.Copy (tmp, retval, 0, 6);\r
87 \r
88                                 Marshal.FreeHGlobal (tmp);\r
89                                 return retval;\r
90                         }\r
91                 }\r
92         \r
93                 public bool IsIdentity {\r
94                         get {\r
95                                 bool retval;\r
96                                 Status status = GDIPlus.GdipIsMatrixIdentity (nativeMatrix, out retval);\r
97                                 GDIPlus.CheckStatus (status);\r
98                                 return retval;\r
99                         }\r
100                 }\r
101         \r
102                 public bool IsInvertible {\r
103                         get {\r
104                                 bool retval;\r
105                                 Status status = GDIPlus.GdipIsMatrixInvertible (nativeMatrix, out retval);\r
106                                 GDIPlus.CheckStatus (status);\r
107                                 return retval;\r
108                         }\r
109                 }\r
110         \r
111                 public float OffsetX {\r
112                         get {\r
113                                 return this.Elements [4];\r
114                         }\r
115                 }\r
116         \r
117                 public float OffsetY {\r
118                         get {\r
119                                 return this.Elements [5];\r
120                         }\r
121                 }\r
122 \r
123                 public Matrix Clone()\r
124                 {\r
125                         IntPtr retval;\r
126                         Status status = GDIPlus.GdipCloneMatrix (nativeMatrix, out retval);
127                         GDIPlus.CheckStatus (status);\r
128                         return new Matrix (retval);\r
129                 }\r
130                 \r
131         \r
132                 public void Dispose ()\r
133                 {\r
134                         Status status = GDIPlus.GdipDeleteMatrix (nativeMatrix);
135                         GDIPlus.CheckStatus (status);\r
136                 }                       \r
137         \r
138                 public override bool Equals (object obj)\r
139                 {\r
140                         Matrix m = obj as Matrix;\r
141 \r
142                         if (m != null) {\r
143                                 bool retval;\r
144                                 Status status = GDIPlus.GdipIsMatrixEqual (nativeMatrix, m.nativeMatrix, out retval);
145                                 GDIPlus.CheckStatus (status);\r
146                                 return retval;\r
147 \r
148                         } else\r
149                                 return false;\r
150                 }\r
151         \r
152                 ~Matrix()\r
153                 {\r
154                         Dispose ();\r
155                 }\r
156                 \r
157                 public override int GetHashCode ()\r
158                 {\r
159                         return base.GetHashCode ();\r
160                 }\r
161         \r
162                 public void Invert ()\r
163                 {\r
164                         Status status = GDIPlus.GdipInvertMatrix (nativeMatrix);
165                         GDIPlus.CheckStatus (status);\r
166                 }\r
167         \r
168                 public void Multiply (Matrix matrix)\r
169                 {\r
170                         Multiply (matrix, MatrixOrder.Prepend);\r
171                 }\r
172         \r
173                 public void Multiply (Matrix matrix, MatrixOrder order)\r
174                 {\r
175                         Status status = GDIPlus.GdipMultiplyMatrix (nativeMatrix, matrix.nativeMatrix, order);
176                         GDIPlus.CheckStatus (status);\r
177                 }\r
178         \r
179                 public void Reset()\r
180                 {\r
181                         Status status = GDIPlus.GdipSetMatrixElements (nativeMatrix, 1, 0, 0, 1, 0, 0);
182                         GDIPlus.CheckStatus (status);\r
183                 }\r
184         \r
185                 public void Rotate (float angle)\r
186                 {\r
187                         Rotate (angle, MatrixOrder.Prepend);\r
188                 }\r
189         \r
190                 public void Rotate (float angle, MatrixOrder order)\r
191                 {\r
192                         Status status = GDIPlus.GdipRotateMatrix (nativeMatrix, angle, order);
193                         GDIPlus.CheckStatus (status);\r
194                 }\r
195         \r
196                 public void RotateAt (float angle, PointF point)\r
197                 {\r
198                         RotateAt (angle, point, MatrixOrder.Prepend);\r
199                 }\r
200         \r
201                 public void RotateAt (float angle, PointF point, MatrixOrder order)\r
202                 {\r
203                         angle *= (float) (Math.PI / 180.0);  // degrees to radians\r
204                         float cos = (float) Math.Cos (angle);\r
205                         float sin = (float) Math.Sin (angle);\r
206                         float e4 = -point.X * cos + point.Y * sin + point.X;\r
207                         float e5 = -point.X * sin - point.Y * cos + point.Y;\r
208                         float[] m = this.Elements;
209 \r
210                         Status status;
211 \r
212                         if (order == MatrixOrder.Prepend)\r
213                                 status = GDIPlus.GdipSetMatrixElements (nativeMatrix,\r
214                                                                 cos * m[0] + sin * m[2],\r
215                                                                 cos * m[1] + sin * m[3],\r
216                                                                 -sin * m[0] + cos * m[2],\r
217                                                                 -sin * m[1] + cos * m[3],\r
218                                                                 e4 * m[0] + e5 * m[2] + m[4],\r
219                                                                 e4 * m[1] + e5 * m[3] + m[5]);\r
220                         else\r
221                                 status = GDIPlus.GdipSetMatrixElements (nativeMatrix,\r
222                                                                 m[0] * cos + m[1] * -sin,\r
223                                                                 m[0] * sin + m[1] * cos,\r
224                                                                 m[2] * cos + m[3] * -sin,\r
225                                                                 m[2] * sin + m[3] * cos,\r
226                                                                 m[4] * cos + m[5] * -sin + e4,\r
227                                                                 m[4] * sin + m[5] * cos + e5);
228                         GDIPlus.CheckStatus (status);\r
229                 }\r
230         \r
231                 public void Scale (float scaleX, float scaleY)\r
232                 {\r
233                         Scale (scaleX, scaleY, MatrixOrder.Prepend);\r
234                 }\r
235         \r
236                 public void Scale (float scaleX, float scaleY, MatrixOrder order)\r
237                 {\r
238                         Status status = GDIPlus.GdipScaleMatrix (nativeMatrix, scaleX, scaleY, order);
239                         GDIPlus.CheckStatus (status);\r
240                 }\r
241         \r
242                 public void Shear (float shearX, float shearY)\r
243                 {\r
244                         Shear (shearX, shearY, MatrixOrder.Prepend);\r
245                 }\r
246         \r
247                 public void Shear (float shearX, float shearY, MatrixOrder order)\r
248                 {\r
249                         Status status = GDIPlus.GdipShearMatrix (nativeMatrix, shearX, shearY, order);
250                         GDIPlus.CheckStatus (status);\r
251                 }\r
252         \r
253                 public void TransformPoints (Point[] pts)\r
254                 {\r
255                         Status status = GDIPlus.GdipTransformMatrixPointsI (nativeMatrix, pts, pts.Length);
256                         GDIPlus.CheckStatus (status);\r
257                 }\r
258         \r
259                 public void TransformPoints (PointF[] pts)\r
260                 {\r
261                         Status status = GDIPlus.GdipTransformMatrixPoints (nativeMatrix, pts, pts.Length);
262                         GDIPlus.CheckStatus (status);\r
263                 }\r
264         \r
265                 public void TransformVectors (Point[] pts)\r
266                 {\r
267                         Status status = GDIPlus.GdipVectorTransformMatrixPointsI (nativeMatrix, pts, pts.Length);
268                         GDIPlus.CheckStatus (status);\r
269                 }\r
270         \r
271                 public void TransformVectors (PointF[] pts)\r
272                 {\r
273                         Status status = GDIPlus.GdipVectorTransformMatrixPoints (nativeMatrix, pts, pts.Length);
274                         GDIPlus.CheckStatus (status);\r
275                 }\r
276         \r
277                 public void Translate (float offsetX, float offsetY)\r
278                 {\r
279                         Translate (offsetX, offsetY, MatrixOrder.Prepend);\r
280                 }\r
281         \r
282                 public void Translate (float offsetX, float offsetY, MatrixOrder order)\r
283                 {\r
284                         Status status = GDIPlus.GdipTranslateMatrix (nativeMatrix, offsetX, offsetY, order);
285                         GDIPlus.CheckStatus (status);\r
286                 }\r
287         \r
288                 public void VectorTransformPoints (Point[] pts)\r
289                 {\r
290                         TransformVectors (pts);\r
291                 }\r
292                 \r
293                 internal IntPtr NativeObject\r
294                 {\r
295                         get{\r
296                                 return nativeMatrix;\r
297                         }\r
298                         set     {\r
299                                 nativeMatrix = value;\r
300                         }\r
301                 }\r
302         }\r
303 }\r