| /* |
| * gdiplusmatrix.h |
| * |
| * GDI+ Matrix class |
| * |
| * This file is part of the w32api package. |
| * |
| * Contributors: |
| * Created by Markus Koenig <markus@stber-koenig.de> |
| * |
| * THIS SOFTWARE IS NOT COPYRIGHTED |
| * |
| * This source code is offered for use in the public domain. You may |
| * use, modify or distribute it freely. |
| * |
| * This code is distributed in the hope that it will be useful but |
| * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY |
| * DISCLAIMED. This includes but is not limited to warranties of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
| * |
| */ |
| |
| #ifndef __GDIPLUS_MATRIX_H |
| #define __GDIPLUS_MATRIX_H |
| #if __GNUC__ >=3 |
| #pragma GCC system_header |
| #endif |
| |
| #ifndef __cplusplus |
| #error "A C++ compiler is required to include gdiplusmatrix.h." |
| #endif |
| |
| #define GDIP_MATRIX_PI \ |
| 3.1415926535897932384626433832795028841971693993751058209749445923078164 |
| |
| class Matrix: public GdiplusBase |
| { |
| friend class Graphics; |
| friend class GraphicsPath; |
| friend class LinearGradientBrush; |
| friend class PathGradientBrush; |
| friend class Pen; |
| friend class Region; |
| friend class TextureBrush; |
| |
| public: |
| Matrix(): nativeMatrix(NULL), lastStatus(Ok) |
| { |
| lastStatus = DllExports::GdipCreateMatrix(&nativeMatrix); |
| } |
| Matrix(REAL m11, REAL m12, REAL m21, REAL m22, REAL dx, REAL dy): |
| nativeMatrix(NULL), lastStatus(Ok) |
| { |
| lastStatus = DllExports::GdipCreateMatrix2( |
| m11, m12, m21, m22, dx, dy, |
| &nativeMatrix); |
| } |
| Matrix(const RectF& rect, const PointF *dstplg): |
| nativeMatrix(NULL), lastStatus(Ok) |
| { |
| lastStatus = DllExports::GdipCreateMatrix3( |
| &rect, dstplg, &nativeMatrix); |
| } |
| Matrix(const Rect& rect, const Point *dstplg): |
| nativeMatrix(NULL), lastStatus(Ok) |
| { |
| lastStatus = DllExports::GdipCreateMatrix3I( |
| &rect, dstplg, &nativeMatrix); |
| } |
| ~Matrix() |
| { |
| DllExports::GdipDeleteMatrix(nativeMatrix); |
| } |
| Matrix* Clone() const |
| { |
| GpMatrix *cloneMatrix = NULL; |
| Status status = updateStatus(DllExports::GdipCloneMatrix( |
| nativeMatrix, &cloneMatrix)); |
| if (status == Ok) { |
| Matrix *result = new Matrix(cloneMatrix, lastStatus); |
| if (!result) { |
| DllExports::GdipDeleteMatrix(cloneMatrix); |
| lastStatus = OutOfMemory; |
| } |
| return result; |
| } else { |
| return NULL; |
| } |
| } |
| |
| BOOL Equals(const Matrix *matrix) const |
| { |
| BOOL result; |
| updateStatus(DllExports::GdipIsMatrixEqual( |
| nativeMatrix, |
| matrix ? matrix->nativeMatrix : NULL, &result)); |
| return result; |
| } |
| Status GetElements(REAL *m) const |
| { |
| return updateStatus(DllExports::GdipGetMatrixElements( |
| nativeMatrix, m)); |
| } |
| Status GetLastStatus() const |
| { |
| Status result = lastStatus; |
| lastStatus = Ok; |
| return result; |
| } |
| Status Invert() |
| { |
| return updateStatus(DllExports::GdipInvertMatrix(nativeMatrix)); |
| } |
| BOOL IsIdentity() const |
| { |
| BOOL result; |
| updateStatus(DllExports::GdipIsMatrixIdentity( |
| nativeMatrix, &result)); |
| return result; |
| } |
| BOOL IsInvertible() const |
| { |
| BOOL result; |
| updateStatus(DllExports::GdipIsMatrixInvertible( |
| nativeMatrix, &result)); |
| return result; |
| } |
| Status Multiply(const Matrix *matrix, |
| MatrixOrder order = MatrixOrderPrepend) |
| { |
| return updateStatus(DllExports::GdipMultiplyMatrix( |
| nativeMatrix, |
| matrix ? matrix->nativeMatrix : NULL, order)); |
| } |
| REAL OffsetX() const |
| { |
| REAL m[6]; |
| updateStatus(DllExports::GdipGetMatrixElements(nativeMatrix, m)); |
| return m[4]; |
| } |
| REAL OffsetY() const |
| { |
| REAL m[6]; |
| updateStatus(DllExports::GdipGetMatrixElements(nativeMatrix, m)); |
| return m[5]; |
| } |
| Status Reset() |
| { |
| return updateStatus(DllExports::GdipSetMatrixElements( |
| nativeMatrix, |
| 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f)); |
| } |
| Status Rotate(REAL angle, MatrixOrder order = MatrixOrderPrepend) |
| { |
| return updateStatus(DllExports::GdipRotateMatrix( |
| nativeMatrix, angle, order)); |
| } |
| Status RotateAt(REAL angle, const PointF& center, |
| MatrixOrder order = MatrixOrderPrepend) |
| { |
| REAL angleRadian = angle * GDIP_MATRIX_PI / 180.0f; |
| REAL cosAngle = ::cos(angleRadian); |
| REAL sinAngle = ::sin(angleRadian); |
| REAL x = center.X; |
| REAL y = center.Y; |
| |
| Matrix matrix2(cosAngle, sinAngle, -sinAngle, cosAngle, |
| x * (1.0f-cosAngle) + y * sinAngle, |
| -x * sinAngle + y * (1.0f-cosAngle)); |
| Status status = matrix2.GetLastStatus(); |
| if (status == Ok) { |
| return Multiply(&matrix2, order); |
| } else { |
| return lastStatus = status; |
| } |
| } |
| Status Scale(REAL scaleX, REAL scaleY, |
| MatrixOrder order = MatrixOrderPrepend) |
| { |
| return updateStatus(DllExports::GdipScaleMatrix( |
| nativeMatrix, scaleX, scaleY, order)); |
| } |
| Status SetElements(REAL m11, REAL m12, REAL m21, REAL m22, |
| REAL dx, REAL dy) |
| { |
| return updateStatus(DllExports::GdipSetMatrixElements( |
| nativeMatrix, m11, m12, m21, m22, dx, dy)); |
| } |
| Status Shear(REAL shearX, REAL shearY, |
| MatrixOrder order = MatrixOrderPrepend) |
| { |
| return updateStatus(DllExports::GdipShearMatrix( |
| nativeMatrix, shearX, shearY, order)); |
| } |
| Status TransformPoints(PointF *pts, INT count = 1) const |
| { |
| return updateStatus(DllExports::GdipTransformMatrixPoints( |
| nativeMatrix, pts, count)); |
| } |
| Status TransformPoints(Point *pts, INT count = 1) const |
| { |
| return updateStatus(DllExports::GdipTransformMatrixPointsI( |
| nativeMatrix, pts, count)); |
| } |
| Status TransformVectors(PointF *pts, INT count = 1) const |
| { |
| return updateStatus(DllExports::GdipVectorTransformMatrixPoints( |
| nativeMatrix, pts, count)); |
| } |
| Status TransformVectors(Point *pts, INT count = 1) const |
| { |
| return updateStatus(DllExports::GdipVectorTransformMatrixPointsI( |
| nativeMatrix, pts, count)); |
| } |
| Status Translate(REAL offsetX, REAL offsetY, |
| MatrixOrder order = MatrixOrderPrepend) |
| { |
| return updateStatus(DllExports::GdipTranslateMatrix( |
| nativeMatrix, offsetX, offsetY, order)); |
| } |
| |
| private: |
| Matrix(GpMatrix *matrix, Status status): |
| nativeMatrix(matrix), lastStatus(status) {} |
| Matrix(const Matrix&); |
| Matrix& operator=(const Matrix&); |
| |
| Status updateStatus(Status newStatus) const |
| { |
| if (newStatus != Ok) lastStatus = newStatus; |
| return newStatus; |
| } |
| |
| GpMatrix *nativeMatrix; |
| mutable Status lastStatus; |
| }; |
| |
| #undef GDIP_MATRIX_PI |
| |
| #endif /* __GDIPLUS_MATRIX_H */ |