Naveen Neel / shedskin
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers gdiplusmatrix.h Source File

gdiplusmatrix.h

00001 /*
00002  * gdiplusmatrix.h
00003  *
00004  * GDI+ Matrix class
00005  *
00006  * This file is part of the w32api package.
00007  *
00008  * Contributors:
00009  *   Created by Markus Koenig <markus@stber-koenig.de>
00010  *
00011  * THIS SOFTWARE IS NOT COPYRIGHTED
00012  *
00013  * This source code is offered for use in the public domain. You may
00014  * use, modify or distribute it freely.
00015  *
00016  * This code is distributed in the hope that it will be useful but
00017  * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
00018  * DISCLAIMED. This includes but is not limited to warranties of
00019  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00020  *
00021  */
00022 
00023 #ifndef __GDIPLUS_MATRIX_H
00024 #define __GDIPLUS_MATRIX_H
00025 #if __GNUC__ >=3
00026 #pragma GCC system_header
00027 #endif
00028 
00029 #ifndef __cplusplus
00030 #error "A C++ compiler is required to include gdiplusmatrix.h."
00031 #endif
00032 
00033 #define GDIP_MATRIX_PI \
00034     3.1415926535897932384626433832795028841971693993751058209749445923078164
00035 
00036 class Matrix: public GdiplusBase
00037 {
00038     friend class Graphics;
00039     friend class GraphicsPath;
00040     friend class LinearGradientBrush;
00041     friend class PathGradientBrush;
00042     friend class Pen;
00043     friend class Region;
00044     friend class TextureBrush;
00045 
00046 public:
00047     Matrix(): nativeMatrix(NULL), lastStatus(Ok)
00048     {
00049         lastStatus = DllExports::GdipCreateMatrix(&nativeMatrix);
00050     }
00051     Matrix(REAL m11, REAL m12, REAL m21, REAL m22, REAL dx, REAL dy):
00052             nativeMatrix(NULL), lastStatus(Ok)
00053     {
00054         lastStatus = DllExports::GdipCreateMatrix2(
00055                 m11, m12, m21, m22, dx, dy,
00056                 &nativeMatrix);
00057     }
00058     Matrix(const RectF& rect, const PointF *dstplg):
00059             nativeMatrix(NULL), lastStatus(Ok)
00060     {
00061         lastStatus = DllExports::GdipCreateMatrix3(
00062                 &rect, dstplg, &nativeMatrix);
00063     }
00064     Matrix(const Rect& rect, const Point *dstplg):
00065             nativeMatrix(NULL), lastStatus(Ok)
00066     {
00067         lastStatus = DllExports::GdipCreateMatrix3I(
00068                 &rect, dstplg, &nativeMatrix);
00069     }
00070     ~Matrix()
00071     {
00072         DllExports::GdipDeleteMatrix(nativeMatrix);
00073     }
00074     Matrix* Clone() const
00075     {
00076         GpMatrix *cloneMatrix = NULL;
00077         Status status = updateStatus(DllExports::GdipCloneMatrix(
00078                 nativeMatrix, &cloneMatrix));
00079         if (status == Ok) {
00080             Matrix *result = new Matrix(cloneMatrix, lastStatus);
00081             if (!result) {
00082                 DllExports::GdipDeleteMatrix(cloneMatrix);
00083                 lastStatus = OutOfMemory;
00084             }
00085             return result;
00086         } else {
00087             return NULL;
00088         }
00089     }
00090 
00091     BOOL Equals(const Matrix *matrix) const
00092     {
00093         BOOL result;
00094         updateStatus(DllExports::GdipIsMatrixEqual(
00095                 nativeMatrix,
00096                 matrix ? matrix->nativeMatrix : NULL, &result));
00097         return result;
00098     }
00099     Status GetElements(REAL *m) const
00100     {
00101         return updateStatus(DllExports::GdipGetMatrixElements(
00102                 nativeMatrix, m));
00103     }
00104     Status GetLastStatus() const
00105     {
00106         Status result = lastStatus;
00107         lastStatus = Ok;
00108         return result;
00109     }
00110     Status Invert()
00111     {
00112         return updateStatus(DllExports::GdipInvertMatrix(nativeMatrix));
00113     }
00114     BOOL IsIdentity() const
00115     {
00116         BOOL result;
00117         updateStatus(DllExports::GdipIsMatrixIdentity(
00118                 nativeMatrix, &result));
00119         return result;
00120     }
00121     BOOL IsInvertible() const
00122     {
00123         BOOL result;
00124         updateStatus(DllExports::GdipIsMatrixInvertible(
00125                 nativeMatrix, &result));
00126         return result;
00127     }
00128     Status Multiply(const Matrix *matrix,
00129             MatrixOrder order = MatrixOrderPrepend)
00130     {
00131         return updateStatus(DllExports::GdipMultiplyMatrix(
00132                 nativeMatrix,
00133                 matrix ? matrix->nativeMatrix : NULL, order));
00134     }
00135     REAL OffsetX() const
00136     {
00137         REAL m[6];
00138         updateStatus(DllExports::GdipGetMatrixElements(nativeMatrix, m));
00139         return m[4];
00140     }
00141     REAL OffsetY() const
00142     {
00143         REAL m[6];
00144         updateStatus(DllExports::GdipGetMatrixElements(nativeMatrix, m));
00145         return m[5];
00146     }
00147     Status Reset()
00148     {
00149         return updateStatus(DllExports::GdipSetMatrixElements(
00150                 nativeMatrix,
00151                 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f));
00152     }
00153     Status Rotate(REAL angle, MatrixOrder order = MatrixOrderPrepend)
00154     {
00155         return updateStatus(DllExports::GdipRotateMatrix(
00156                 nativeMatrix, angle, order));
00157     }
00158     Status RotateAt(REAL angle, const PointF& center,
00159             MatrixOrder order = MatrixOrderPrepend)
00160     {
00161         REAL angleRadian = angle * GDIP_MATRIX_PI / 180.0f;
00162         REAL cosAngle = ::cos(angleRadian);
00163         REAL sinAngle = ::sin(angleRadian);
00164         REAL x = center.X;
00165         REAL y = center.Y;
00166 
00167         Matrix matrix2(cosAngle, sinAngle, -sinAngle, cosAngle,
00168                 x * (1.0f-cosAngle) + y * sinAngle,
00169                 -x * sinAngle + y * (1.0f-cosAngle));
00170         Status status = matrix2.GetLastStatus();
00171         if (status == Ok) {
00172             return Multiply(&matrix2, order);
00173         } else {
00174             return lastStatus = status;
00175         }
00176     }
00177     Status Scale(REAL scaleX, REAL scaleY,
00178             MatrixOrder order = MatrixOrderPrepend)
00179     {
00180         return updateStatus(DllExports::GdipScaleMatrix(
00181                 nativeMatrix, scaleX, scaleY, order));
00182     }
00183     Status SetElements(REAL m11, REAL m12, REAL m21, REAL m22,
00184             REAL dx, REAL dy)
00185     {
00186         return updateStatus(DllExports::GdipSetMatrixElements(
00187                 nativeMatrix, m11, m12, m21, m22, dx, dy));
00188     }
00189     Status Shear(REAL shearX, REAL shearY,
00190             MatrixOrder order = MatrixOrderPrepend)
00191     {
00192         return updateStatus(DllExports::GdipShearMatrix(
00193                 nativeMatrix, shearX, shearY, order));
00194     }
00195     Status TransformPoints(PointF *pts, INT count = 1) const
00196     {
00197         return updateStatus(DllExports::GdipTransformMatrixPoints(
00198                 nativeMatrix, pts, count));
00199     }
00200     Status TransformPoints(Point *pts, INT count = 1) const
00201     {
00202         return updateStatus(DllExports::GdipTransformMatrixPointsI(
00203                 nativeMatrix, pts, count));
00204     }
00205     Status TransformVectors(PointF *pts, INT count = 1) const
00206     {
00207         return updateStatus(DllExports::GdipVectorTransformMatrixPoints(
00208                 nativeMatrix, pts, count));
00209     }
00210     Status TransformVectors(Point *pts, INT count = 1) const
00211     {
00212         return updateStatus(DllExports::GdipVectorTransformMatrixPointsI(
00213                 nativeMatrix, pts, count));
00214     }
00215     Status Translate(REAL offsetX, REAL offsetY,
00216             MatrixOrder order = MatrixOrderPrepend)
00217     {
00218         return updateStatus(DllExports::GdipTranslateMatrix(
00219                 nativeMatrix, offsetX, offsetY, order));
00220     }
00221 
00222 private:
00223     Matrix(GpMatrix *matrix, Status status):
00224         nativeMatrix(matrix), lastStatus(status) {}
00225     Matrix(const Matrix&);
00226     Matrix& operator=(const Matrix&);
00227 
00228     Status updateStatus(Status newStatus) const
00229     {
00230         if (newStatus != Ok) lastStatus = newStatus;
00231         return newStatus;
00232     }
00233 
00234     GpMatrix *nativeMatrix;
00235     mutable Status lastStatus;
00236 };
00237 
00238 #undef GDIP_MATRIX_PI
00239 
00240 #endif /* __GDIPLUS_MATRIX_H */