2 // System.Drawing.Drawing2D.Matrix.cs
5 // Stefan Maierhofer <sm@cg.tuwien.ac.at>
6 // Dennis Hayes (dennish@Raytek.com)
7 // Duncan Mak (duncan@ximian.com)
8 // Ravindra (rkumar@novell.com)
10 // (C) Ximian, Inc. http://www.ximian.com
11 // (C) Novell, Inc. http://www.novell.com
15 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
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:
25 // The above copyright notice and this permission notice shall be
26 // included in all copies or substantial portions of the Software.
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.
39 using System
.Runtime
.InteropServices
;
41 namespace System
.Drawing
.Drawing2D
43 public sealed class Matrix
: MarshalByRefObject
, IDisposable
45 internal IntPtr nativeMatrix
;
48 internal Matrix (IntPtr ptr
)
55 Status status
= GDIPlus
.GdipCreateMatrix (out nativeMatrix
);
56 GDIPlus
.CheckStatus (status
);
59 public Matrix (Rectangle rect
, Point
[] plgpts
)
61 Status status
= GDIPlus
.GdipCreateMatrix3I (rect
, plgpts
, out nativeMatrix
);
62 GDIPlus
.CheckStatus (status
);
65 public Matrix (RectangleF rect
, PointF
[] pa
)
67 Status status
= GDIPlus
.GdipCreateMatrix3 (rect
, pa
, out nativeMatrix
);
68 GDIPlus
.CheckStatus (status
);
71 public Matrix (float m11
, float m12
, float m21
, float m22
, float dx
, float dy
)
73 Status status
= GDIPlus
.GdipCreateMatrix2 (m11
, m12
, m21
, m22
, dx
, dy
, out nativeMatrix
);
74 GDIPlus
.CheckStatus (status
);
78 public float[] Elements
{
80 IntPtr tmp
= Marshal
.AllocHGlobal (Marshal
.SizeOf (typeof (float)) * 6);
81 float [] retval
= new float [6];
83 Status status
= GDIPlus
.GdipGetMatrixElements (nativeMatrix
, tmp
);
84 GDIPlus
.CheckStatus (status
);
86 Marshal
.Copy (tmp
, retval
, 0, 6);
88 Marshal
.FreeHGlobal (tmp
);
93 public bool IsIdentity
{
96 Status status
= GDIPlus
.GdipIsMatrixIdentity (nativeMatrix
, out retval
);
97 GDIPlus
.CheckStatus (status
);
102 public bool IsInvertible
{
105 Status status
= GDIPlus
.GdipIsMatrixInvertible (nativeMatrix
, out retval
);
106 GDIPlus
.CheckStatus (status
);
111 public float OffsetX
{
113 return this.Elements
[4];
117 public float OffsetY
{
119 return this.Elements
[5];
123 public Matrix
Clone()
126 Status status
= GDIPlus
.GdipCloneMatrix (nativeMatrix
, out retval
);
127 GDIPlus
.CheckStatus (status
);
128 return new Matrix (retval
);
132 public void Dispose ()
134 Status status
= GDIPlus
.GdipDeleteMatrix (nativeMatrix
);
135 GDIPlus
.CheckStatus (status
);
138 public override bool Equals (object obj
)
140 Matrix m
= obj
as Matrix
;
144 Status status
= GDIPlus
.GdipIsMatrixEqual (nativeMatrix
, m
.nativeMatrix
, out retval
);
145 GDIPlus
.CheckStatus (status
);
157 public override int GetHashCode ()
159 return base.GetHashCode ();
162 public void Invert ()
164 Status status
= GDIPlus
.GdipInvertMatrix (nativeMatrix
);
165 GDIPlus
.CheckStatus (status
);
168 public void Multiply (Matrix matrix
)
170 Multiply (matrix
, MatrixOrder
.Prepend
);
173 public void Multiply (Matrix matrix
, MatrixOrder order
)
175 Status status
= GDIPlus
.GdipMultiplyMatrix (nativeMatrix
, matrix
.nativeMatrix
, order
);
176 GDIPlus
.CheckStatus (status
);
181 Status status
= GDIPlus
.GdipSetMatrixElements (nativeMatrix
, 1, 0, 0, 1, 0, 0);
182 GDIPlus
.CheckStatus (status
);
185 public void Rotate (float angle
)
187 Rotate (angle
, MatrixOrder
.Prepend
);
190 public void Rotate (float angle
, MatrixOrder order
)
192 Status status
= GDIPlus
.GdipRotateMatrix (nativeMatrix
, angle
, order
);
193 GDIPlus
.CheckStatus (status
);
196 public void RotateAt (float angle
, PointF point
)
198 RotateAt (angle
, point
, MatrixOrder
.Prepend
);
201 public void RotateAt (float angle
, PointF point
, MatrixOrder order
)
203 angle
*= (float) (Math
.PI
/ 180.0); // degrees to radians
204 float cos
= (float) Math
.Cos (angle
);
205 float sin
= (float) Math
.Sin (angle
);
206 float e4
= -point
.X
* cos
+ point
.Y
* sin
+ point
.X
;
207 float e5
= -point
.X
* sin
- point
.Y
* cos
+ point
.Y
;
208 float[] m
= this.Elements
;
212 if (order
== MatrixOrder
.Prepend
)
213 status
= GDIPlus
.GdipSetMatrixElements (nativeMatrix
,
214 cos
* m
[0] + sin
* m
[2],
215 cos
* m
[1] + sin
* m
[3],
216 -sin
* m
[0] + cos
* m
[2],
217 -sin
* m
[1] + cos
* m
[3],
218 e4
* m
[0] + e5
* m
[2] + m
[4],
219 e4
* m
[1] + e5
* m
[3] + m
[5]);
221 status
= GDIPlus
.GdipSetMatrixElements (nativeMatrix
,
222 m
[0] * cos
+ m
[1] * -sin
,
223 m
[0] * sin
+ m
[1] * cos
,
224 m
[2] * cos
+ m
[3] * -sin
,
225 m
[2] * sin
+ m
[3] * cos
,
226 m
[4] * cos
+ m
[5] * -sin
+ e4
,
227 m
[4] * sin
+ m
[5] * cos
+ e5
);
228 GDIPlus
.CheckStatus (status
);
231 public void Scale (float scaleX
, float scaleY
)
233 Scale (scaleX
, scaleY
, MatrixOrder
.Prepend
);
236 public void Scale (float scaleX
, float scaleY
, MatrixOrder order
)
238 Status status
= GDIPlus
.GdipScaleMatrix (nativeMatrix
, scaleX
, scaleY
, order
);
239 GDIPlus
.CheckStatus (status
);
242 public void Shear (float shearX
, float shearY
)
244 Shear (shearX
, shearY
, MatrixOrder
.Prepend
);
247 public void Shear (float shearX
, float shearY
, MatrixOrder order
)
249 Status status
= GDIPlus
.GdipShearMatrix (nativeMatrix
, shearX
, shearY
, order
);
250 GDIPlus
.CheckStatus (status
);
253 public void TransformPoints (Point
[] pts
)
255 Status status
= GDIPlus
.GdipTransformMatrixPointsI (nativeMatrix
, pts
, pts
.Length
);
256 GDIPlus
.CheckStatus (status
);
259 public void TransformPoints (PointF
[] pts
)
261 Status status
= GDIPlus
.GdipTransformMatrixPoints (nativeMatrix
, pts
, pts
.Length
);
262 GDIPlus
.CheckStatus (status
);
265 public void TransformVectors (Point
[] pts
)
267 Status status
= GDIPlus
.GdipVectorTransformMatrixPointsI (nativeMatrix
, pts
, pts
.Length
);
268 GDIPlus
.CheckStatus (status
);
271 public void TransformVectors (PointF
[] pts
)
273 Status status
= GDIPlus
.GdipVectorTransformMatrixPoints (nativeMatrix
, pts
, pts
.Length
);
274 GDIPlus
.CheckStatus (status
);
277 public void Translate (float offsetX
, float offsetY
)
279 Translate (offsetX
, offsetY
, MatrixOrder
.Prepend
);
282 public void Translate (float offsetX
, float offsetY
, MatrixOrder order
)
284 Status status
= GDIPlus
.GdipTranslateMatrix (nativeMatrix
, offsetX
, offsetY
, order
);
285 GDIPlus
.CheckStatus (status
);
288 public void VectorTransformPoints (Point
[] pts
)
290 TransformVectors (pts
);
293 internal IntPtr NativeObject
299 nativeMatrix
= value;