gdiplusmatrix.h 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. /*
  2. * gdiplusmatrix.h
  3. *
  4. * GDI+ Matrix class
  5. *
  6. * This file is part of the w32api package.
  7. *
  8. * Contributors:
  9. * Created by Markus Koenig <markus@stber-koenig.de>
  10. *
  11. * THIS SOFTWARE IS NOT COPYRIGHTED
  12. *
  13. * This source code is offered for use in the public domain. You may
  14. * use, modify or distribute it freely.
  15. *
  16. * This code is distributed in the hope that it will be useful but
  17. * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
  18. * DISCLAIMED. This includes but is not limited to warranties of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  20. *
  21. */
  22. #ifndef __GDIPLUS_MATRIX_H
  23. #define __GDIPLUS_MATRIX_H
  24. #if __GNUC__ >=3
  25. #pragma GCC system_header
  26. #endif
  27. #ifndef __cplusplus
  28. #error "A C++ compiler is required to include gdiplusmatrix.h."
  29. #endif
  30. #define GDIP_MATRIX_PI \
  31. 3.1415926535897932384626433832795028841971693993751058209749445923078164
  32. class Matrix: public GdiplusBase
  33. {
  34. friend class Graphics;
  35. friend class GraphicsPath;
  36. friend class LinearGradientBrush;
  37. friend class PathGradientBrush;
  38. friend class Pen;
  39. friend class Region;
  40. friend class TextureBrush;
  41. public:
  42. Matrix(): nativeMatrix(NULL), lastStatus(Ok)
  43. {
  44. lastStatus = DllExports::GdipCreateMatrix(&nativeMatrix);
  45. }
  46. Matrix(REAL m11, REAL m12, REAL m21, REAL m22, REAL dx, REAL dy):
  47. nativeMatrix(NULL), lastStatus(Ok)
  48. {
  49. lastStatus = DllExports::GdipCreateMatrix2(
  50. m11, m12, m21, m22, dx, dy,
  51. &nativeMatrix);
  52. }
  53. Matrix(const RectF& rect, const PointF *dstplg):
  54. nativeMatrix(NULL), lastStatus(Ok)
  55. {
  56. lastStatus = DllExports::GdipCreateMatrix3(
  57. &rect, dstplg, &nativeMatrix);
  58. }
  59. Matrix(const Rect& rect, const Point *dstplg):
  60. nativeMatrix(NULL), lastStatus(Ok)
  61. {
  62. lastStatus = DllExports::GdipCreateMatrix3I(
  63. &rect, dstplg, &nativeMatrix);
  64. }
  65. ~Matrix()
  66. {
  67. DllExports::GdipDeleteMatrix(nativeMatrix);
  68. }
  69. Matrix* Clone() const
  70. {
  71. GpMatrix *cloneMatrix = NULL;
  72. Status status = updateStatus(DllExports::GdipCloneMatrix(
  73. nativeMatrix, &cloneMatrix));
  74. if (status == Ok) {
  75. Matrix *result = new Matrix(cloneMatrix, lastStatus);
  76. if (!result) {
  77. DllExports::GdipDeleteMatrix(cloneMatrix);
  78. lastStatus = OutOfMemory;
  79. }
  80. return result;
  81. } else {
  82. return NULL;
  83. }
  84. }
  85. BOOL Equals(const Matrix *matrix) const
  86. {
  87. BOOL result;
  88. updateStatus(DllExports::GdipIsMatrixEqual(
  89. nativeMatrix,
  90. matrix ? matrix->nativeMatrix : NULL, &result));
  91. return result;
  92. }
  93. Status GetElements(REAL *m) const
  94. {
  95. return updateStatus(DllExports::GdipGetMatrixElements(
  96. nativeMatrix, m));
  97. }
  98. Status GetLastStatus() const
  99. {
  100. Status result = lastStatus;
  101. lastStatus = Ok;
  102. return result;
  103. }
  104. Status Invert()
  105. {
  106. return updateStatus(DllExports::GdipInvertMatrix(nativeMatrix));
  107. }
  108. BOOL IsIdentity() const
  109. {
  110. BOOL result;
  111. updateStatus(DllExports::GdipIsMatrixIdentity(
  112. nativeMatrix, &result));
  113. return result;
  114. }
  115. BOOL IsInvertible() const
  116. {
  117. BOOL result;
  118. updateStatus(DllExports::GdipIsMatrixInvertible(
  119. nativeMatrix, &result));
  120. return result;
  121. }
  122. Status Multiply(const Matrix *matrix,
  123. MatrixOrder order = MatrixOrderPrepend)
  124. {
  125. return updateStatus(DllExports::GdipMultiplyMatrix(
  126. nativeMatrix,
  127. matrix ? matrix->nativeMatrix : NULL, order));
  128. }
  129. REAL OffsetX() const
  130. {
  131. REAL m[6];
  132. updateStatus(DllExports::GdipGetMatrixElements(nativeMatrix, m));
  133. return m[4];
  134. }
  135. REAL OffsetY() const
  136. {
  137. REAL m[6];
  138. updateStatus(DllExports::GdipGetMatrixElements(nativeMatrix, m));
  139. return m[5];
  140. }
  141. Status Reset()
  142. {
  143. return updateStatus(DllExports::GdipSetMatrixElements(
  144. nativeMatrix,
  145. 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f));
  146. }
  147. Status Rotate(REAL angle, MatrixOrder order = MatrixOrderPrepend)
  148. {
  149. return updateStatus(DllExports::GdipRotateMatrix(
  150. nativeMatrix, angle, order));
  151. }
  152. Status RotateAt(REAL angle, const PointF& center,
  153. MatrixOrder order = MatrixOrderPrepend)
  154. {
  155. REAL angleRadian = angle * GDIP_MATRIX_PI / 180.0f;
  156. REAL cosAngle = ::cos(angleRadian);
  157. REAL sinAngle = ::sin(angleRadian);
  158. REAL x = center.X;
  159. REAL y = center.Y;
  160. Matrix matrix2(cosAngle, sinAngle, -sinAngle, cosAngle,
  161. x * (1.0f-cosAngle) + y * sinAngle,
  162. -x * sinAngle + y * (1.0f-cosAngle));
  163. Status status = matrix2.GetLastStatus();
  164. if (status == Ok) {
  165. return Multiply(&matrix2, order);
  166. } else {
  167. return lastStatus = status;
  168. }
  169. }
  170. Status Scale(REAL scaleX, REAL scaleY,
  171. MatrixOrder order = MatrixOrderPrepend)
  172. {
  173. return updateStatus(DllExports::GdipScaleMatrix(
  174. nativeMatrix, scaleX, scaleY, order));
  175. }
  176. Status SetElements(REAL m11, REAL m12, REAL m21, REAL m22,
  177. REAL dx, REAL dy)
  178. {
  179. return updateStatus(DllExports::GdipSetMatrixElements(
  180. nativeMatrix, m11, m12, m21, m22, dx, dy));
  181. }
  182. Status Shear(REAL shearX, REAL shearY,
  183. MatrixOrder order = MatrixOrderPrepend)
  184. {
  185. return updateStatus(DllExports::GdipShearMatrix(
  186. nativeMatrix, shearX, shearY, order));
  187. }
  188. Status TransformPoints(PointF *pts, INT count = 1) const
  189. {
  190. return updateStatus(DllExports::GdipTransformMatrixPoints(
  191. nativeMatrix, pts, count));
  192. }
  193. Status TransformPoints(Point *pts, INT count = 1) const
  194. {
  195. return updateStatus(DllExports::GdipTransformMatrixPointsI(
  196. nativeMatrix, pts, count));
  197. }
  198. Status TransformVectors(PointF *pts, INT count = 1) const
  199. {
  200. return updateStatus(DllExports::GdipVectorTransformMatrixPoints(
  201. nativeMatrix, pts, count));
  202. }
  203. Status TransformVectors(Point *pts, INT count = 1) const
  204. {
  205. return updateStatus(DllExports::GdipVectorTransformMatrixPointsI(
  206. nativeMatrix, pts, count));
  207. }
  208. Status Translate(REAL offsetX, REAL offsetY,
  209. MatrixOrder order = MatrixOrderPrepend)
  210. {
  211. return updateStatus(DllExports::GdipTranslateMatrix(
  212. nativeMatrix, offsetX, offsetY, order));
  213. }
  214. private:
  215. Matrix(GpMatrix *matrix, Status status):
  216. nativeMatrix(matrix), lastStatus(status) {}
  217. Matrix(const Matrix&);
  218. Matrix& operator=(const Matrix&);
  219. Status updateStatus(Status newStatus) const
  220. {
  221. if (newStatus != Ok) lastStatus = newStatus;
  222. return newStatus;
  223. }
  224. GpMatrix *nativeMatrix;
  225. mutable Status lastStatus;
  226. };
  227. #undef GDIP_MATRIX_PI
  228. #endif /* __GDIPLUS_MATRIX_H */