Files
core/ASCImageStudio3/ASCGraphics/agg/ASCWrapper/Brush.h

620 lines
13 KiB
C++
Raw Blame History

#pragma once
#include "..\ap_AggPlusTypes.h"
#include "..\ap_AggPlusEnums.h"
#include "Color.h"
#include "Matrix.h"
#include "Image.h"
#include "..\..\Objects\Structures.h"
namespace Aggplus
{
using namespace Gdiplus;
class CBrush
{
friend class CGraphics;
protected:
CBrush(BrushType bType) : m_bType(bType) { }
public:
virtual ~CBrush() { }
virtual CBrush *Clone() const = 0;
inline BrushType GetType() const
{
return m_bType;
}
public:
BrushType m_bType;
};
class CBrushSolid : public CBrush
{
public:
CBrushSolid(CColor dwColor) : CBrush(BrushTypeSolidColor), m_dwColor(dwColor)
{
}
virtual ~CBrushSolid()
{
}
virtual CBrush *Clone() const
{
return new CBrushSolid(m_dwColor);
}
void GetColor(CColor* color) const { *color = m_dwColor; }
void SetColor(const CColor &color) { m_dwColor = color; }
protected:
CColor m_dwColor;
};
class CBrushLinearGradient : public CBrush
{
friend class CGraphics;
public:
CBrushLinearGradient( const PointF& p1, const PointF& p2, const CColor& c1, const CColor& c2 )
: CBrush(BrushTypeLinearGradient)
{
m_points[0] = p1;
m_points[1] = p2;
m_colors[0] = c1;
m_colors[1] = c2;
m_angle = 0;
m_wrap = Aggplus::WrapModeTile;
m_bAngleScalable = FALSE;
m_bRectable = FALSE;
m_bRelativeCoords = FALSE;
}
CBrushLinearGradient( const Point& p1, const Point& p2, const CColor& c1, const CColor& c2 )
: CBrush(BrushTypeLinearGradient)
{
m_points[0].X = (float)p1.X;
m_points[0].Y = (float)p1.Y;
m_points[1].X = (float)p2.X;
m_points[1].Y = (float)p2.Y;
m_colors[0] = c1;
m_colors[1] = c2;
m_angle = 0;
m_wrap = Aggplus::WrapModeTile;
m_bAngleScalable = FALSE;
m_bRectable = FALSE;
m_bRelativeCoords = FALSE;
}
CBrushLinearGradient( const RectF& rect, const CColor& c1, const CColor& c2, float angle, BOOL isAngleScalable )
: CBrush(BrushTypeLinearGradient)
{
m_points[0].X = rect.GetLeft();
m_points[0].Y = rect.GetTop();
m_points[1].X = rect.GetRight();
m_points[1].Y = rect.GetBottom();
m_colors[0] = c1;
m_colors[1] = c2;
m_angle = angle;
m_wrap = Aggplus::WrapModeTile;
m_bAngleScalable = isAngleScalable;
m_bRectable = TRUE;
m_bRelativeCoords = FALSE;
}
CBrushLinearGradient( const Rect& rect, const CColor& c1, const CColor& c2, float angle, BOOL isAngleScalable )
: CBrush(BrushTypeLinearGradient)
{
m_points[0].X = (float)rect.GetLeft();
m_points[0].Y = (float)rect.GetTop();
m_points[1].X = (float)rect.GetRight();
m_points[1].Y = (float)rect.GetBottom();
m_colors[0] = c1;
m_colors[1] = c2;
m_angle = angle;
m_wrap = Aggplus::WrapModeTile;
m_bAngleScalable = isAngleScalable;
m_bRectable = TRUE;
m_bRelativeCoords = FALSE;
}
CBrushLinearGradient( const RectF& rect, const CColor& c1, const CColor& c2, Aggplus::LinearGradientMode mode )
: CBrush(BrushTypeLinearGradient)
{
m_points[0].X = rect.GetLeft();
m_points[0].Y = rect.GetTop();
m_points[1].X = rect.GetRight();
m_points[1].Y = rect.GetBottom();
switch( mode )
{
case LinearGradientModeHorizontal:
m_angle = 0;
break;
case LinearGradientModeVertical:
m_angle = 90;
break;
case LinearGradientModeForwardDiagonal:
m_angle = 45;
break;
default:
m_angle = 315;
}
m_colors[0] = c1;
m_colors[1] = c2;
m_wrap = Aggplus::WrapModeTile;
m_bAngleScalable = TRUE;
m_bRectable = TRUE;
m_bRelativeCoords = FALSE;
}
CBrushLinearGradient( const Rect& rect, const CColor& c1, const CColor& c2, Aggplus::LinearGradientMode mode )
: CBrush(BrushTypeLinearGradient)
{
m_points[0].X = rect.GetLeft();
m_points[0].Y = rect.GetTop();
m_points[1].X = rect.GetRight();
m_points[1].Y = rect.GetBottom();
switch( mode )
{
case LinearGradientModeHorizontal:
m_angle = 0;
break;
case LinearGradientModeVertical:
m_angle = 90;
break;
case LinearGradientModeForwardDiagonal:
m_angle = 45;
break;
default:
m_angle = 315;
}
m_colors[0] = c1;
m_colors[1] = c2;
m_wrap = Aggplus::WrapModeTile;
m_bAngleScalable = TRUE;
m_bRectable = TRUE;
m_bRelativeCoords = FALSE;
}
CBrushLinearGradient( const CBrushLinearGradient& out )
: CBrush(out.m_bType)
{
m_colors[0] = out.m_colors[0];
m_colors[1] = out.m_colors[1];
m_points[0] = out.m_points[0];
m_points[1] = out.m_points[1];
m_subcolors.Copy( out.m_subcolors );
m_matrix = out.m_matrix;
m_angle = out.m_angle;
m_wrap = out.m_wrap;
m_bAngleScalable = out.m_bAngleScalable;
m_bRectable = out.m_bRectable;
m_bRelativeCoords = out.m_bRelativeCoords;
}
Status GetLinearColors( CColor* colors ) const
{
if( !colors )
return InvalidParameter;
colors[0] = m_colors[0];
colors[1] = m_colors[1];
return Ok;
}
Status GetRectangle( Rect *rect ) const
{
if( !rect )
return InvalidParameter;
rect->X = (int)( m_points[0].X );
rect->Y = (int)( m_points[0].Y );
rect->Width = (int)( m_points[1].X ) - rect->X;
rect->Height = (int)( m_points[1].Y ) - rect->Y;
return Ok;
}
Status GetRectangle( RectF *rect ) const
{
if( !rect )
return InvalidParameter;
rect->X = m_points[0].X;
rect->Y = m_points[0].Y;
rect->Width = m_points[1].X - rect->X;
rect->Height = m_points[1].Y - rect->Y;
return Ok;
}
Status GetTransform( CMatrix* matrix ) const
{
if( !matrix )
return InvalidParameter;
*matrix = m_matrix;
return Ok;
}
Status MultiplyTransform( const CMatrix *matrix, MatrixOrder order = MatrixOrderPrepend)
{
if( !matrix )
return InvalidParameter;
m_matrix.Multiply( matrix, order );
return Ok;
}
Status ResetTransform()
{
m_matrix.Reset();
return Ok;
}
Status RotateTransform( REAL angle, MatrixOrder order = MatrixOrderPrepend )
{
m_matrix.Rotate( angle, order );
return Ok;
}
Status ScaleTransform( REAL sx, REAL sy, MatrixOrder order = MatrixOrderPrepend )
{
m_matrix.Scale( sx, sy, order );
return Ok;
}
void SetWrapMode( WrapMode mode )
{
m_wrap = mode;
}
WrapMode GetWrapMode() const
{
return m_wrap;
}
virtual CBrush *Clone() const
{
return new CBrushLinearGradient( *this );
}
Status SetInterpolationColors( const CColor *presetColors, const REAL *blendPositions, INT count )
{
m_subcolors.RemoveAll();
if( count > 0 && presetColors && blendPositions )
{
m_subcolors.SetCount( count, 0 );
for( int i = 0; i < count; i++ )
{
m_subcolors[i].color = presetColors[i];
m_subcolors[i].position = blendPositions[i];
}
}
return Ok;
}
Status GetInterpolationColors( CColor *presetColors, REAL *blendPositions, INT count ) const
{
if( count > 0 && count <= (INT)m_subcolors.GetCount() && presetColors && blendPositions )
{
for( int i = 0; i < count; i++ )
{
presetColors[i] = m_subcolors[i].color;
blendPositions[i] = m_subcolors[i].position;
}
}
return Ok;
}
INT GetInterpolationColorsCount() const
{
return (INT)m_subcolors.GetCount();
}
// additional methods
void GetSubColor( int nIndex, CColor* pColor, float* pPosition ) const
{
*pColor = m_subcolors[nIndex].color;
*pPosition = m_subcolors[nIndex].position;
}
void SetRelativeCoords( BOOL bRelative )
{
m_bRelativeCoords = bRelative;
}
BOOL IsRelativeCoords() const
{
return m_bRelativeCoords;
}
BOOL IsAngleScalable() const
{
return m_bAngleScalable;
}
BOOL IsRectable() const
{
return m_bRectable;
}
float GetAngle() const
{
return m_angle;
}
protected:
//std::vector<CColor> m_colors;
//double m_rotate_angle_radians;
CColor m_colors[2];
PointF m_points[2];
struct TSubColor
{
CColor color;
float position;
};
ATL::CAtlArray<TSubColor> m_subcolors;
CMatrix m_matrix;
float m_angle; // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> p1 -> p2
Aggplus::WrapMode m_wrap;
BOOL m_bAngleScalable; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> b = arctan( width / height * tan(angle) );
BOOL m_bRectable; // <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
BOOL m_bRelativeCoords; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
};
class CBrushTexture : public CBrush
{
friend class CGraphics;
protected:
CBrushTexture() : CBrush(BrushTypeTextureFill)
{
m_pImage = NULL;
m_bReleaseImage = FALSE;
m_bUsePattern = FALSE;
}
public:
CBrushTexture(const WCHAR *strName, WrapMode wrapMode = WrapModeTile) : CBrush(BrushTypeTextureFill), m_wrapMode(wrapMode)
{
m_pImage = new CImage(strName);
m_bReleaseImage = TRUE;
m_bUsePattern = FALSE;
}
CBrushTexture(CImage *pImage, WrapMode wrapMode = WrapModeTile) : CBrush(BrushTypeTextureFill), m_wrapMode(wrapMode)
{
//m_Image.CopyFrom(pImage);
m_pImage = pImage;
m_bReleaseImage = FALSE;
m_bUsePattern = FALSE;
}
virtual ~CBrushTexture()
{
if (m_bReleaseImage)
{
RELEASEOBJECT(m_pImage);
}
}
virtual CBrush *Clone() const
{
CBrushTexture *pRet = new CBrushTexture(m_pImage, m_wrapMode);
if( pRet )
{
pRet->m_mtx = m_mtx;
pRet->m_bUsePattern = m_bUsePattern;
}
return pRet;
}
void TranslateTransform(double dX, double dY, MatrixOrder order = MatrixOrderPrepend)
{
m_mtx.Translate(dX, dY, order);
}
void ScaleTransform(double dX, double dY, MatrixOrder order = MatrixOrderPrepend)
{
m_mtx.Scale(dX, dY, order);
}
void RotateTransform(double angle, MatrixOrder order = MatrixOrderPrepend)
{
m_mtx.Rotate(angle, order);
}
void GetTransform(CMatrix* matrix) const
{
*matrix = m_mtx;
}
void SetTransform(const CMatrix* matrix)
{
m_mtx = *matrix;
}
void SetWrapMode(WrapMode wMode)
{
m_wrapMode = wMode;
}
WrapMode GetWrapMode() const
{
return(m_wrapMode);
}
public:
void *PatternFinalize()
{
return(m_pImage->m_pImgData);
}
DWORD PatternGetWidth()
{
return(m_pImage->m_dwWidth);
}
DWORD PatternGetHeight()
{
return(m_pImage->m_dwHeight);
}
int PatternGetStride()
{
return(m_pImage->m_nStride);
}
public:
CImage* m_pImage;
BOOL m_bReleaseImage;
WrapMode m_wrapMode;
CMatrix m_mtx;
BOOL m_bUsePattern;
CColor m_colors[2];
};
static CBrush* CreateBrush(NSStructures::CBrush* pBrush)
{
if (NULL == pBrush)
return NULL;
LONG Type = pBrush->Type;
if ((0 == Type) || (c_BrushTypeSolid == Type) || (c_BrushTypeHatch1 <= Type && c_BrushTypeHatch53 >= Type))
{
Aggplus::CColor oColor((BYTE)pBrush->Alpha1, pBrush->Color1);
Aggplus::CBrushSolid* pNew = new Aggplus::CBrushSolid(oColor);
return pNew;
}
else if ((c_BrushTypeHorizontal == Type) ||
(c_BrushTypeVertical == Type) ||
(c_BrushTypeDiagonal1 == Type) ||
(c_BrushTypeDiagonal2 == Type) ||
(c_BrushTypeCenter == Type) ||
(c_BrushTypePathGradient1 == Type) ||
(c_BrushTypePathGradient2 == Type) ||
(c_BrushTypeCylinderHor == Type) ||
(c_BrushTypeCylinderVer == Type))
{
Aggplus::CColor o1((BYTE)pBrush->Alpha1, pBrush->Color1);
Aggplus::CColor o2((BYTE)pBrush->Alpha2, pBrush->Color2);
Aggplus::CBrushLinearGradient* pNew = new Aggplus::CBrushLinearGradient( Aggplus::RectF(0, 0, 1, 1), o1, o2, pBrush->LinearAngle, TRUE );
if( pNew )
{
pNew->SetRelativeCoords( TRUE );
int nCountSubColors = pBrush->m_arrSubColors.GetSize();
if( nCountSubColors > 0 )
{
Aggplus::CColor* pColors = new Aggplus::CColor[nCountSubColors];
float* pBlends = new float[nCountSubColors];
if( pColors && pBlends )
{
for( int i = 0; i < nCountSubColors; i++ )
{
pColors[i] = Aggplus::CColor(255, pBrush->m_arrSubColors[i].color);
pBlends[i] = (float)(pBrush->m_arrSubColors[i].position / 65536.0);
}
pNew->SetInterpolationColors( pColors, pBlends, nCountSubColors );
}
delete [] pColors;
delete [] pBlends;
}
}
return pNew;
}
else
{
Aggplus::CBrushTexture* pNew = new Aggplus::CBrushTexture(pBrush->TexturePath, /*(Aggplus::WrapMode)TextureMode*/Aggplus::WrapModeClamp);
return pNew;
}
//LONG lType = pBrush->Type;
//if ((0 == lType) || (c_BrushTypeSolid == lType) || (c_BrushTypeHatch1 <= lType && c_BrushTypeHatch53 >= lType))
//{
// CColor oColor((BYTE)pBrush->Alpha1, pBrush->Color1);
// CBrushSolid* pNew = new CBrushSolid(oColor);
// return pNew;
//}
//else if ((c_BrushTypeHorizontal == lType) ||
// (c_BrushTypeVertical == lType) ||
// (c_BrushTypeDiagonal1 == lType) ||
// (c_BrushTypeDiagonal2 == lType) ||
// (c_BrushTypeCenter == lType) ||
// (c_BrushTypePathGradient1 == lType) ||
// (c_BrushTypePathGradient2 == lType) ||
// (c_BrushTypeCylinderHor == lType) ||
// (c_BrushTypeCylinderVer == lType))
//{
// CColor c1((BYTE)pBrush->Alpha1, pBrush->Color1);
// CColor c2((BYTE)pBrush->Alpha2, pBrush->Color2);
// CBrushLinearGradient* pNew = new CBrushLinearGradient(c1, c2, 0.0);
// return pNew;
//}
//else
//{
// CBrushTexture* pNew = new CBrushTexture(pBrush->TexturePath, (WrapMode)pBrush->TextureMode);
// return pNew;
//}
}
}