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