/**************************************************************************\ * * Copyright (c) 1998-2001, Microsoft Corp. All Rights Reserved. * * Module Name: * * GdiplusMatrix.h * * Abstract: * * GDI+ Matrix class * \**************************************************************************/ class Matrix : public GdiplusBase { public: friend class Graphics; friend class GraphicsPath; friend class TextureBrush; friend class LinearGradientBrush; friend class PathGradientBrush; friend class Pen; friend class Region; // Default constructor is set to identity matrix. Matrix() { GpMatrix *matrix = NULL; lastResult = DllExports::GdipCreateMatrix(&matrix); SetNativeMatrix(matrix); } Matrix(IN REAL m11, IN REAL m12, IN REAL m21, IN REAL m22, IN REAL dx, IN REAL dy) { GpMatrix *matrix = NULL; lastResult = DllExports::GdipCreateMatrix2(m11, m12, m21, m22, dx, dy, &matrix); SetNativeMatrix(matrix); } Matrix(IN const RectF& rect, IN const PointF* dstplg) { GpMatrix *matrix = NULL; lastResult = DllExports::GdipCreateMatrix3(&rect, dstplg, &matrix); SetNativeMatrix(matrix); } Matrix(IN const Rect& rect, IN const Point* dstplg) { GpMatrix *matrix = NULL; lastResult = DllExports::GdipCreateMatrix3I(&rect, dstplg, &matrix); SetNativeMatrix(matrix); } ~Matrix() { DllExports::GdipDeleteMatrix(nativeMatrix); } Matrix *Clone() const { GpMatrix *cloneMatrix = NULL; SetStatus(DllExports::GdipCloneMatrix(nativeMatrix, &cloneMatrix)); if (lastResult != Ok) return NULL; return new Matrix(cloneMatrix); } Status GetElements(OUT REAL *m) const { return SetStatus(DllExports::GdipGetMatrixElements(nativeMatrix, m)); } Status SetElements(IN REAL m11, IN REAL m12, IN REAL m21, IN REAL m22, IN REAL dx, IN REAL dy) { return SetStatus(DllExports::GdipSetMatrixElements(nativeMatrix, m11, m12, m21, m22, dx, dy)); } REAL OffsetX() const { REAL elements[6]; if (GetElements(&elements[0]) == Ok) return elements[4]; else return 0.0f; } REAL OffsetY() const { REAL elements[6]; if (GetElements(&elements[0]) == Ok) return elements[5]; else return 0.0f; } Status Reset() { // set identity matrix elements return SetStatus(DllExports::GdipSetMatrixElements(nativeMatrix, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0)); } Status Multiply(IN const Matrix *matrix, IN MatrixOrder order = MatrixOrderPrepend) { return SetStatus(DllExports::GdipMultiplyMatrix(nativeMatrix, matrix->nativeMatrix, order)); } Status Translate(IN REAL offsetX, IN REAL offsetY, IN MatrixOrder order = MatrixOrderPrepend) { return SetStatus(DllExports::GdipTranslateMatrix(nativeMatrix, offsetX, offsetY, order)); } Status Scale(IN REAL scaleX, IN REAL scaleY, IN MatrixOrder order = MatrixOrderPrepend) { return SetStatus(DllExports::GdipScaleMatrix(nativeMatrix, scaleX, scaleY, order)); } Status Rotate(IN REAL angle, IN MatrixOrder order = MatrixOrderPrepend) { return SetStatus(DllExports::GdipRotateMatrix(nativeMatrix, angle, order)); } Status RotateAt(IN REAL angle, IN const PointF& center, IN MatrixOrder order = MatrixOrderPrepend) { if(order == MatrixOrderPrepend) { SetStatus(DllExports::GdipTranslateMatrix(nativeMatrix, center.X, center.Y, order)); SetStatus(DllExports::GdipRotateMatrix(nativeMatrix, angle, order)); return SetStatus(DllExports::GdipTranslateMatrix(nativeMatrix, -center.X, -center.Y, order)); } else { SetStatus(DllExports::GdipTranslateMatrix(nativeMatrix, - center.X, - center.Y, order)); SetStatus(DllExports::GdipRotateMatrix(nativeMatrix, angle, order)); return SetStatus(DllExports::GdipTranslateMatrix(nativeMatrix, center.X, center.Y, order)); } } Status Shear(IN REAL shearX, IN REAL shearY, IN MatrixOrder order = MatrixOrderPrepend) { return SetStatus(DllExports::GdipShearMatrix(nativeMatrix, shearX, shearY, order)); } Status Invert() { return SetStatus(DllExports::GdipInvertMatrix(nativeMatrix)); } // float version Status TransformPoints(IN OUT PointF* pts, IN INT count = 1) const { return SetStatus(DllExports::GdipTransformMatrixPoints(nativeMatrix, pts, count)); } Status TransformPoints(IN OUT Point* pts, IN INT count = 1) const { return SetStatus(DllExports::GdipTransformMatrixPointsI(nativeMatrix, pts, count)); } Status TransformVectors(IN OUT PointF* pts, IN INT count = 1) const { return SetStatus(DllExports::GdipVectorTransformMatrixPoints( nativeMatrix, pts, count)); } Status TransformVectors(IN OUT Point* pts, IN INT count = 1) const { return SetStatus(DllExports::GdipVectorTransformMatrixPointsI( nativeMatrix, pts, count)); } BOOL IsInvertible() const { BOOL result = FALSE; SetStatus(DllExports::GdipIsMatrixInvertible(nativeMatrix, &result)); return result; } BOOL IsIdentity() const { BOOL result = FALSE; SetStatus(DllExports::GdipIsMatrixIdentity(nativeMatrix, &result)); return result; } BOOL Equals(IN const Matrix *matrix) const { BOOL result = FALSE; SetStatus(DllExports::GdipIsMatrixEqual(nativeMatrix, matrix->nativeMatrix, &result)); return result; } Status GetLastStatus() const { Status lastStatus = lastResult; lastResult = Ok; return lastStatus; } private: Matrix(const Matrix &); Matrix& operator=(const Matrix &); protected: Matrix(GpMatrix *nativeMatrix) { lastResult = Ok; SetNativeMatrix(nativeMatrix); } VOID SetNativeMatrix(GpMatrix *nativeMatrix) { this->nativeMatrix = nativeMatrix; } Status SetStatus(Status status) const { if (status != Ok) return (lastResult = status); else return status; } protected: GpMatrix *nativeMatrix; mutable Status lastResult; };