308 lines
8.7 KiB
C
308 lines
8.7 KiB
C
|
/**************************************************************************\
|
||
|
*
|
||
|
* 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;
|
||
|
};
|