Matrix.cs 10 KB

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