* Makefile: Build the make-map.exe in Mono.Unix.Native; add /nowarn:0618 to
[mono.git] / mcs / class / System.Drawing / System.Drawing.Drawing2D / Matrix.jvm.cs
1 using System;
2 using System.Drawing;
3 using System.Runtime.InteropServices;
4 using geom = java.awt.geom;
5 using JMath = java.lang.Math;
6
7 namespace System.Drawing.Drawing2D
8 {
9         public sealed class Matrix : MarshalByRefObject, IDisposable
10         {
11                 #region fields
12
13                 static internal readonly Matrix IdentityTransform = new Matrix();
14                 readonly geom.AffineTransform _nativeMatrix;                            
15
16                 #endregion
17                 
18                 #region ctors
19
20                 internal Matrix (geom.AffineTransform ptr)
21                 {
22                         _nativeMatrix = ptr;
23                 }
24                 
25                 public Matrix () : this(new geom.AffineTransform())
26                 {               
27                 }
28         
29                 public Matrix (Rectangle rect , Point[] plgpts)
30                 {
31                         double x1 = plgpts[1].X - plgpts[0].X;
32                         double y1 = plgpts[1].Y - plgpts[0].Y;
33                         
34                         double x2 = plgpts[2].X - plgpts[0].X;
35                         double y2 = plgpts[2].Y - plgpts[0].Y;
36
37                         _nativeMatrix = new geom.AffineTransform(x1/rect.Width, y1/rect.Width, x2/rect.Height, y2/rect.Height, plgpts[0].X, plgpts[0].Y);
38                         _nativeMatrix.translate(-rect.X,-rect.Y);
39                 }
40         
41                 public Matrix (RectangleF rect , PointF[] plgpts)
42                 {
43                         double x1 = plgpts[1].X - plgpts[0].X;
44                         double y1 = plgpts[1].Y - plgpts[0].Y;
45                         
46                         double x2 = plgpts[2].X - plgpts[0].X;
47                         double y2 = plgpts[2].Y - plgpts[0].Y;
48
49                         _nativeMatrix = new geom.AffineTransform(x1/rect.Width, y1/rect.Width, x2/rect.Height, y2/rect.Height, plgpts[0].X, plgpts[0].Y);
50                         _nativeMatrix.translate(-rect.X,-rect.Y);
51                 }
52
53                 public Matrix (float m11, float m12, float m21, float m22, float dx, float dy)
54                         : this(new geom.AffineTransform(m11,m12,m21,m22,dx,dy))
55                 {
56                 }
57
58                 #endregion
59         
60                 #region properties
61
62                 public float[] Elements 
63                 {
64                         get 
65                         {
66                                 float [] elems = new float[] {
67                                         (float)NativeObject.getScaleX(),
68                                         (float)NativeObject.getShearY(),
69                                         (float)NativeObject.getShearX(),
70                                         (float)NativeObject.getScaleY(),
71                                         (float)NativeObject.getTranslateX(),
72                                         (float)NativeObject.getTranslateY()};
73                                 return elems;
74                         }
75                 }
76         
77                 public bool IsIdentity 
78                 {
79                         get 
80                         {
81                                 return NativeObject.isIdentity();
82                         }
83                 }
84         
85                 public bool IsInvertible 
86                 {
87                         get 
88                         {
89                                 try
90                                 {
91                                         return NativeObject.getDeterminant() != 0.0;
92                                 }
93                                 catch(geom.NoninvertibleTransformException)
94                                 {
95                                         return false;
96                                 }
97                         }
98                 }
99         
100                 public float OffsetX 
101                 {
102                         get 
103                         {
104                                 return (float)NativeObject.getTranslateX();
105                         }
106                 }
107         
108                 public float OffsetY 
109                 {
110                         get 
111                         {
112                                 return (float)NativeObject.getTranslateY();
113                         }
114                 }
115
116                 #endregion
117
118                 #region methods
119
120                 public Matrix Clone()
121                 {
122                         return new Matrix ((geom.AffineTransform)NativeObject.clone());
123                 }
124                 
125         
126                 public void Dispose ()
127                 {
128                 }                       
129         
130                 internal void CopyTo(Matrix matrix) {
131                         matrix.NativeObject.setTransform(NativeObject);
132                 }
133
134                 public override bool Equals (object obj)
135                 {
136                         Matrix m = obj as Matrix;
137                                                 
138
139                         if (m == null) 
140                                 return false;
141
142                         return NativeObject.equals(m.NativeObject);
143                 }
144                 
145                 public override int GetHashCode ()
146                 {
147                         return NativeObject.hashCode();
148                 }
149         
150                 public void Invert ()
151                 {
152                         try {
153                                 _nativeMatrix.setTransform( _nativeMatrix.createInverse() );
154                         }
155                         catch(geom.NoninvertibleTransformException e) {
156                                 throw new ArgumentException(e.Message, e);
157                         }
158                 }
159         
160                 public void Multiply (Matrix matrix)
161                 {
162                         Multiply (matrix, MatrixOrder.Prepend);
163                 }
164         
165                 public void Multiply (Matrix matrix, MatrixOrder order)
166                 {
167                         Multiply(matrix.NativeObject, order);
168                 }
169         
170                 public void Reset()
171                 {
172                         NativeObject.setToIdentity();
173                 }
174         
175                 public void Rotate (float angle)
176                 {
177                         Rotate (angle, MatrixOrder.Prepend);
178                 }
179         
180                 public void Rotate (float angle, MatrixOrder order)
181                 {
182                         Multiply(geom.AffineTransform.getRotateInstance(JMath.toRadians(angle)), order);                                        
183                 }
184         
185                 public void RotateAt (float angle, PointF point)
186                 {
187                         RotateAt (angle, point, MatrixOrder.Prepend);
188                 }
189         
190                 public void RotateAt (float angle, PointF point, MatrixOrder order)
191                 {
192                         Multiply(geom.AffineTransform.getRotateInstance(JMath.toRadians(angle),point.X, point.Y), order);
193                 }
194         
195                 public void Scale (float scaleX, float scaleY)
196                 {
197                         Scale (scaleX, scaleY, MatrixOrder.Prepend);
198                 }
199         
200                 public void Scale (float scaleX, float scaleY, MatrixOrder order)
201                 {
202                         Multiply(geom.AffineTransform.getScaleInstance(scaleX, scaleY), order);
203                 }
204         
205                 public void Shear (float shearX, float shearY)
206                 {
207                         Shear (shearX, shearY, MatrixOrder.Prepend);
208                 }
209         
210                 public void Shear (float shearX, float shearY, MatrixOrder order)
211                 {
212                         Multiply(geom.AffineTransform.getShearInstance (shearX, shearY), order);
213                 }
214         
215                 public void TransformPoints (Point[] pts)
216                 {
217                         geom.Point2D.Float pt = new geom.Point2D.Float();
218                         for(int i =0;i < pts.Length;i++) {
219                                 pt.setLocation(pts[i].X,pts[i].Y);
220                                 NativeObject.transform(pt,pt);
221                                 pts[i].X=(int)pt.getX();
222                                 pts[i].Y=(int)pt.getY();
223                         }
224                 }
225         
226                 public void TransformPoints (PointF[] pts)
227                 {
228                         geom.Point2D.Float pt = new geom.Point2D.Float();
229                         for(int i =0;i < pts.Length;i++) {
230                                 pt.setLocation(pts[i].X,pts[i].Y);
231                                 NativeObject.transform(pt,pt);
232                                 pts[i].X=(float)pt.getX();
233                                 pts[i].Y=(float)pt.getY();
234                         }
235                 }
236         
237                 public void TransformVectors (Point[] pts)
238                 {
239                         geom.Point2D.Float pt = new geom.Point2D.Float();
240                         for(int i =0;i < pts.Length;i++) {
241                                 pt.setLocation(pts[i].X,pts[i].Y);
242                                 NativeObject.deltaTransform(pt,pt);
243                                 pts[i].X=(int)pt.getX();
244                                 pts[i].Y=(int)pt.getY();
245                         }
246                 }
247         
248                 public void TransformVectors (PointF[] pts)
249                 {
250                         geom.Point2D.Float pt = new geom.Point2D.Float();
251                         for(int i =0;i < pts.Length;i++) {
252                                 pt.setLocation(pts[i].X,pts[i].Y);
253                                 NativeObject.deltaTransform(pt,pt);
254                                 pts[i].X=(float)pt.getX();
255                                 pts[i].Y=(float)pt.getY();
256                         }
257                 }
258         
259                 public void Translate (float offsetX, float offsetY)
260                 {
261                         Translate (offsetX, offsetY, MatrixOrder.Prepend);
262                 }
263         
264                 public void Translate (float offsetX, float offsetY, MatrixOrder order)
265                 {
266                         Multiply(geom.AffineTransform.getTranslateInstance(offsetX, offsetY), order);
267                 }
268         
269                 public void VectorTransformPoints (Point[] pts)
270                 {
271                         TransformVectors (pts);
272                 }
273                 
274                 internal geom.AffineTransform NativeObject
275                 {
276                         get
277                         {
278                                 return _nativeMatrix;
279                         }
280                 }
281
282                 void Multiply(geom.AffineTransform at, MatrixOrder order) {
283                         Multiply(NativeObject, at, order);
284                 }
285
286                 internal static void Multiply(geom.AffineTransform to, geom.AffineTransform add, MatrixOrder order) {
287                         if(order == MatrixOrder.Prepend)
288                                 to.concatenate(add);
289                         else
290                                 to.preConcatenate(add);
291                 }
292
293                 #endregion
294         }
295 }