OSDN Git Service

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