DocumentServer/ActiveX/Common/PaintStruct.h
nikolay ivanov a8be6b9e72 init repo
2014-07-05 18:22:49 +00:00

4196 lines
94 KiB
C++

/*
* (c) Copyright Ascensio System SIA 2010-2014
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
* version 3 as published by the Free Software Foundation. In accordance with
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
* that Ascensio System SIA expressly excludes the warranty of non-infringement
* of any third-party rights.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
*
* You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia,
* EU, LV-1021.
*
* The interactive user interfaces in modified source and object code versions
* of the Program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU AGPL version 3.
*
* Pursuant to Section 7(b) of the License you must retain the original Product
* logo when distributing the program. Pursuant to Section 7(e) we decline to
* grant you any rights under trademark law for use of our trademarks.
*
* All the Product's GUI elements, including illustrations and icon sets, as
* well as technical writing content are licensed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
*
*/
#pragma once
#include <atlcoll.h>
#include <math.h>
#include <Gdiplus.h>
#include "streamutils.h"
#include "xmlutils.h"
#include "atldefine.h"
#include "GdiplusEx.h"
namespace Painter
{
const int c_BrushTypeSolid_ = 0;
const int c_BrushTypeHorizontal_ = 1;
const int c_BrushTypeVertical_ = 2;
const int c_BrushTypeDiagonal1_ = 3;
const int c_BrushTypeDiagonal2_ = 4;
const int c_BrushTypeCenter_ = 5;
const int c_BrushTypePathGradient1_ = 6;
const int c_BrushTypePathGradient2_ = 7;
const int c_BrushTypeTexture_ = 8;
const int c_BrushTypeHatch1_ = 9;
const int c_BrushTypeHatch53_ = 61;
const int c_BrushTypeGradient1_ = 62;
const int c_BrushTypeGradient6_ = 70;
const int c_BrushTypeSolid = 1000;
const int c_BrushTypeHorizontal = 2001;
const int c_BrushTypeVertical = 2002;
const int c_BrushTypeDiagonal1 = 2003;
const int c_BrushTypeDiagonal2 = 2004;
const int c_BrushTypeCenter = 2005;
const int c_BrushTypePathGradient1 = 2006;
const int c_BrushTypePathGradient2 = 2007;
const int c_BrushTypeCylinderHor = 2008;
const int c_BrushTypeCylinderVer = 2009;
const int c_BrushTypeTexture = 3008;
const int c_BrushTypeHatch1 = 4009;
const int c_BrushTypeHatch53 = 4061;
const int c_BrushTextureModeStretch = 0;
const int c_BrushTextureModeTile = 1;
const int c_BrushTextureModeTileCenter = 2;
const int c_AlphModeDoNothing = 0;
const int c_AlphModeReplaceWithBrushAlpha = 1;
const int c_AlphModeCombine = 2;
inline int ConstantCompatible(int nConstant)
{
if( c_BrushTypeDiagonal1_ == nConstant )
nConstant = c_BrushTypeDiagonal2_;
else if( c_BrushTypeDiagonal2_ == nConstant )
nConstant = c_BrushTypeDiagonal1_;
if (1000 <= nConstant)
return nConstant;
if (c_BrushTypeSolid_ == nConstant)
return nConstant + 1000;
if (c_BrushTypeHorizontal_ <= nConstant && c_BrushTypePathGradient2_ >= nConstant)
return nConstant + 2000;
if (c_BrushTypeTexture_ == nConstant)
return nConstant + 3000;
if (c_BrushTypeHatch1_ <= nConstant && c_BrushTypeHatch53_ >= nConstant)
return nConstant + 4000;
if (c_BrushTypeGradient1_ <= nConstant && c_BrushTypeGradient6_ >= nConstant)
return nConstant + 2000 - 61;
return 1000;
}
inline BOOL IsBrushTypeGradient(int nType)
{
int nCompatibleType = ConstantCompatible(nType);
return (nCompatibleType >= Painter::c_BrushTypeHorizontal && nCompatibleType <= Painter::c_BrushTypeCylinderVer);
}
inline void DrawBlurString(int currentBlurSize, Graphics* Gr, Gdiplus::Font* font, StringFormat* format, Brush* brush, BSTR Text, int len, RectF& rect)
{
for(int j = 0; j < currentBlurSize; j++)
{
rect.X += 1;
Gr->DrawString(Text, len, font, rect, format, brush);
}
for(int j = 0; j < currentBlurSize; j++)
{
rect.Y += 1;
Gr->DrawString(Text, len, font, rect, format, brush);
}
for(int j = 0; j < currentBlurSize; j++)
{
rect.X -= 1;
Gr->DrawString(Text, len, font, rect, format, brush);
}
for(int j = 0; j < currentBlurSize; j++)
{
rect.X -= 1;
Gr->DrawString(Text, len, font, rect, format, brush);
}
for(int j = 0; j < currentBlurSize; j++)
{
rect.Y -= 1;
Gr->DrawString(Text, len, font, rect, format, brush);
}
for(int j = 0; j < currentBlurSize; j++)
{
rect.Y -= 1;
Gr->DrawString(Text, len, font, rect, format, brush);
}
for(int j = 0; j < currentBlurSize; j++)
{
rect.X += 1;
Gr->DrawString(Text, len, font, rect, format, brush);
}
for(int j = 0; j < currentBlurSize; j++)
{
rect.X += 1;
Gr->DrawString(Text, len, font, rect, format, brush);
}
for(int j = 0; j < currentBlurSize; j++)
{
rect.Y += 1;
Gr->DrawString(Text, len, font, rect, format, brush);
}
}
inline void GetRectCurrentCharacter(Gdiplus::Graphics* graphics, Gdiplus::StringFormat* stringFormat, Gdiplus::Font* font, BSTR Text, int length, int index, Gdiplus::RectF& rectString, Gdiplus::RectF& rectCharacter)
{
CharacterRange charRanges[1] = {CharacterRange(index, 1)};
Region pCharRangeRegions;
stringFormat->SetMeasurableCharacterRanges(1, charRanges);
graphics->MeasureCharacterRanges(Text, length, font, rectString, stringFormat, 1, &pCharRangeRegions);
int count = 1;
Matrix matrix;
pCharRangeRegions.GetRegionScans(&matrix, &rectCharacter, &count);
}
class CStream
{
protected:
BYTE* m_pBuffer;
int m_nOrigin;
public:
CStream()
{
m_pBuffer = 0;
m_nOrigin = 0;
}
inline BOOL IsValid() const
{ if (m_pBuffer) return TRUE; return FALSE; }
BYTE*& GetBuffer()
{ return m_pBuffer; }
void SetBuffer(BYTE* pBuffer)
{ m_pBuffer = pBuffer; }
void Seek(int nOrigin = 0)
{ m_nOrigin = nOrigin; }
int GetPosition()
{ return m_nOrigin; }
BYTE* GetData()
{ return m_pBuffer + m_nOrigin; }
BYTE ReadByte()
{
int nOldOrigin = m_nOrigin;
m_nOrigin += sizeof(BYTE);
return *(BYTE*)(m_pBuffer + nOldOrigin);
}
short ReadShort()
{
int nOldOrigin = m_nOrigin;
m_nOrigin += sizeof(short);
return *(short*)(m_pBuffer + nOldOrigin);
}
long ReadLong()
{
int nOldOrigin = m_nOrigin;
m_nOrigin += sizeof(long);
return *(long*)(m_pBuffer + nOldOrigin);
}
double ReadDouble()
{
int nOldOrigin = m_nOrigin;
m_nOrigin += sizeof(double);
return *(double*)(m_pBuffer + nOldOrigin);
}
float ReadFloat()
{
int nOldOrigin = m_nOrigin;
m_nOrigin += sizeof(float);
return *(float*)(m_pBuffer + nOldOrigin);
}
CString ReadString()
{
int nOldOrigin = m_nOrigin;
while (TRUE)
{
m_nOrigin++;
if (m_pBuffer[m_nOrigin - 1] == 0)
break;
}
return CString((char*)(m_pBuffer + nOldOrigin));
}
BYTE* ReadPointer(int nSize)
{
int nOldOrigin = m_nOrigin;
m_nOrigin += nSize;
return (BYTE*)(m_pBuffer + nOldOrigin);
}
void WriteByte(BYTE nValue)
{
memcpy(m_pBuffer + m_nOrigin, &nValue, sizeof(BYTE));
m_nOrigin += sizeof(BYTE);
}
void WriteShort(short nValue)
{
memcpy(m_pBuffer + m_nOrigin, &nValue, sizeof(short));
m_nOrigin += sizeof(short);
}
void WriteLong(long nValue)
{
memcpy(m_pBuffer + m_nOrigin, &nValue, sizeof(long));
m_nOrigin += sizeof(long);
}
void WriteDouble(double dValue)
{
memcpy(m_pBuffer + m_nOrigin, &dValue, sizeof(double));
m_nOrigin += sizeof(double);
}
void WriteFloat(float fValue)
{
memcpy(m_pBuffer + m_nOrigin, &fValue, sizeof(float));
m_nOrigin += sizeof(float);
}
void WriteString(CString strValue)
{
TCHAR* pstr = strValue.GetBuffer();
memcpy(m_pBuffer + m_nOrigin, pstr, strValue.GetLength());
m_nOrigin += strValue.GetLength();
m_pBuffer[m_nOrigin] = 0;
m_nOrigin += sizeof(_T("0"));
}
void WritePointer(BYTE* pData, int nSize)
{
memcpy(m_pBuffer + m_nOrigin, pData, nSize);
m_nOrigin += nSize;
}
};
class CBuffer
{
BYTE* m_pBuffer;
int m_nSize;
public:
CBuffer()
{
m_nSize = 0;
m_pBuffer = 0;
}
~CBuffer()
{
if (m_pBuffer)
delete[] m_pBuffer;
}
};
class CTexture
{
public:
Gdiplus::Bitmap* Bitmap;
CString Path;
BYTE* BitmapData;
BOOL bFlipVertical;
BOOL bAttach;
int nWidth;
int nHeight;
int nStride;
public:
CTexture()
{
Path = "";
Bitmap = 0;
BitmapData = 0;
bFlipVertical = FALSE;
bAttach = FALSE;
nWidth = 0;
nHeight = 0;
nStride = 0;
}
~CTexture()
{
Clear();
}
void Clear()
{
if (Bitmap)
{
delete Bitmap;
Bitmap = 0;
}
if( FALSE == bAttach )
{
if (BitmapData)
{
delete[] BitmapData;
BitmapData = 0;
}
}
Path = "";
bFlipVertical = FALSE;
bAttach = FALSE;
nWidth = 0;
nHeight = 0;
nStride = 0;
}
BOOL Create(CString path, BOOL bFlip = FALSE)
{
Clear();
BSTR bstr = path.AllocSysString();
Bitmap = new Gdiplus::Bitmap(bstr);
SysFreeString(bstr);
if (!Bitmap || Bitmap->GetLastStatus() != Ok)
return FALSE;
RectF boundsRect;
Unit unit;
Bitmap->GetBounds(&boundsRect, &unit);
nWidth = int(boundsRect.Width + 0.5);
nHeight = int(boundsRect.Height + 0.5);
Path = path;
bFlipVertical = bFlip;
if (bFlip)
Bitmap->RotateFlip(RotateNoneFlipY);
return TRUE;
}
BOOL SetImage(CString Name, SAFEARRAY* pImage)
{
if (NULL == pImage)
return FALSE;
VARTYPE type;
long lBoundC, uBoundC;
long lBoundW, uBoundW;
long lBoundH, uBoundH;
if (SafeArrayGetDim(pImage) != 3)
return FALSE;
if (FAILED(SafeArrayGetVartype(pImage, &type)) || type != VT_UI1 || SafeArrayGetElemsize(pImage) != 1)
return FALSE;
if (FAILED(SafeArrayGetLBound(pImage, 1, &lBoundC)) || FAILED(SafeArrayGetUBound(pImage, 1, &uBoundC)) ||
FAILED(SafeArrayGetLBound(pImage, 2, &lBoundW)) || FAILED(SafeArrayGetUBound(pImage, 2, &uBoundW)) ||
FAILED(SafeArrayGetLBound(pImage, 3, &lBoundH)) || FAILED(SafeArrayGetUBound(pImage, 3, &uBoundH)))
return FALSE;
int Channels = 1 + uBoundC - lBoundC;
int Width = 1 + uBoundW - lBoundW;
int Height = 1 + uBoundH - lBoundH;
if (Channels != 4 || Width < 2 || Height < 2)
return FALSE;
Clear();
int sizeImage = 4*Width*Height;
BitmapData = new BYTE[sizeImage];
memcpy(BitmapData,(BYTE*)((pImage)->pvData), sizeImage);
Bitmap = new Gdiplus::Bitmap(Width, Height, Width*4, PixelFormat32bppARGB, BitmapData);
Bitmap->RotateFlip(RotateNoneFlipY);
Path = Name;
bAttach = FALSE;
nWidth = Width;
nHeight = Height;
nStride = 4*Width;
return TRUE;
}
};
class CTextureManager
{
CAtlArray<CTexture*> m_textures;
public:
~CTextureManager()
{
Clear();
}
int GetCount()
{
return (int)m_textures.GetCount();
}
CTexture* GetAt(int index)
{
if (index < 0 || index >= GetCount())
return 0;
return m_textures[index];
}
CTexture* operator[] (int index)
{
return GetAt(index);
}
int Find(CString path)
{
path.MakeLower();
for (int index = 0; index < GetCount(); ++index)
{
if (m_textures[index]->Path == path)
return index;
}
return -1;
}
void Clear()
{
for (int index = 0; index < GetCount(); ++index)
{
CTexture* texture = m_textures[index];
if (texture)
delete texture;
}
m_textures.RemoveAll();
}
void RemoveAt(int index)
{
if (index < 0 || index >= GetCount())
return;
CTexture* texture = m_textures[index];
if (texture)
delete texture;
m_textures.RemoveAt(index);
}
long Add(CString path)
{
path.MakeLower();
int index = Find(path);
if (index >= 0)
return index;
CTexture* texture = new CTexture();
if (!texture->Create(path))
{
delete texture;
return -1;
}
m_textures.Add(texture);
return GetCount() - 1;
}
long Add(CString path, BOOL bVerticalFlip)
{
path.MakeLower();
int index = Find(path);
if (index >= 0)
return index;
CTexture* texture = new CTexture();
if (!texture->Create(path, bVerticalFlip))
{
delete texture;
return -1;
}
m_textures.Add(texture);
return GetCount() - 1;
}
long Add(CString Name, SAFEARRAY* pImage)
{
Name.MakeLower();
int index = Find(Name);
if (index >= 0)
return index;
CTexture* texture = new CTexture();
if (!texture->SetImage(Name, pImage))
{
delete texture;
return -1;
}
m_textures.Add(texture);
return GetCount() - 1;
}
long Add( CTexture* pTexture )
{
if( !pTexture )
return -1;
int index = Find( pTexture->Path );
if( index >= 0 )
return index;
m_textures.Add( pTexture );
return GetCount() - 1;
}
};
class CPen
{
Gdiplus::Pen* m_pen;
public:
long Color;
long Alpha;
double Size;
byte DashStyle;
byte LineStartCap;
byte LineEndCap;
byte LineJoin;
REAL* DashPattern;
long Count;
REAL DashOffset;
PenAlignment Align;
public:
int GetSize()
{
return 2*sizeof(long) + sizeof(double) + 4*sizeof(byte) + sizeof(REAL*) + sizeof(long) + sizeof(REAL);
}
void Write(CStream& stream)
{
stream.WriteLong(Color);
stream.WriteLong(Alpha);
stream.WriteDouble(Size);
stream.WriteByte(DashStyle);
stream.WriteByte(LineStartCap);
stream.WriteByte(LineEndCap);
stream.WriteByte(LineJoin);
stream.WriteLong(Count);
if (DashPattern != NULL)
{
for (int i = 0; i < Count; ++i)
{
stream.WriteFloat(DashPattern[i]);
}
}
stream.WriteFloat(DashOffset);
}
void Read(CStream& stream)
{
Color = stream.ReadLong();
Alpha = stream.ReadLong();
Size = stream.ReadDouble();
DashStyle = stream.ReadByte();
LineStartCap = stream.ReadByte();
LineEndCap = stream.ReadByte();
LineJoin = stream.ReadByte();
Count = stream.ReadLong();
RELEASEARRAYOBJECTS(DashPattern);
if (Count != 0)
{
DashPattern = new REAL[Count];
for (int i = 0; i < Count; ++i)
{
DashPattern[i] = stream.ReadFloat();
}
}
DashOffset = stream.ReadFloat();
Update();
}
CString ToXmlString(CString strRootNodeName = _T("pen"), BOOL bAttributed = FALSE)
{
XmlUtils::CXmlWriter oXmlWriter;
if (!bAttributed)
{
oXmlWriter.WriteNodeBegin(strRootNodeName);
oXmlWriter.WriteNode(_T("color"), Color);
oXmlWriter.WriteNode(_T("alpha"), Alpha);
oXmlWriter.WriteNode(_T("size"), Size);
oXmlWriter.WriteNode(_T("style"), DashStyle);
oXmlWriter.WriteNode(_T("line-start-cap"), LineStartCap);
oXmlWriter.WriteNode(_T("line-end-cap"), LineEndCap);
oXmlWriter.WriteNode(_T("line-join"), LineJoin);
oXmlWriter.WriteNode(_T("dash-pattern-count"), Count);
oXmlWriter.WriteNodeBegin(_T("dash-pattern"));
if (DashPattern != NULL)
{
for (int i = 0; i < Count; ++i)
{
oXmlWriter.WriteNode(_T("dash"), DashPattern[i]);
}
}
oXmlWriter.WriteNodeEnd(_T("dash-pattern"));
oXmlWriter.WriteNode(_T("dash-offset"), DashOffset);
oXmlWriter.WriteNode(_T("alignment"), Align);
oXmlWriter.WriteNodeEnd(strRootNodeName);
}
else
{
oXmlWriter.WriteNodeBegin(strRootNodeName, TRUE);
ToXmlAttributes(oXmlWriter);
oXmlWriter.WriteNodeEnd(strRootNodeName, TRUE);
}
return oXmlWriter.GetXmlString();
}
void FromXmlString(CString strXml)
{
XmlUtils::CXmlReader oXmlReader;
oXmlReader.SetXmlString(strXml);
oXmlReader.ReadRootNode();
FromXmlAttributes(oXmlReader);
}
BOOL FromStream(Streams::IStream* pStream)
{
if (!pStream)
return FALSE;
try
{
Color = pStream->ReadLong();
Alpha = pStream->ReadLong();
Size = pStream->ReadDouble();
DashStyle = pStream->ReadByte();
LineStartCap = pStream->ReadByte();
LineEndCap = pStream->ReadByte();
LineJoin = pStream->ReadByte();
Count = pStream->ReadLong();
RELEASEARRAYOBJECTS(DashPattern);
if (Count > 0)
{
DashPattern = new REAL[Count];
for (int i = 0; i < Count; ++i)
{
DashPattern[i] = pStream->ReadFloat();
}
}
DashOffset = pStream->ReadFloat();
Update();
return TRUE;
}
catch (...)
{
}
return FALSE;
}
BOOL ToStream(Streams::IStream* pStream)
{
if (!pStream)
return FALSE;
try
{
pStream->WriteLong(Color);
pStream->WriteLong(Alpha);
pStream->WriteDouble(Size);
pStream->WriteByte(DashStyle);
pStream->WriteByte(LineStartCap);
pStream->WriteByte(LineEndCap);
pStream->WriteByte(LineJoin);
pStream->WriteLong(Count);
if (DashPattern != NULL)
{
for (int i = 0; i < Count; ++i)
{
pStream->WriteFloat(DashPattern[i]);
}
}
pStream->WriteFloat(DashOffset);
return TRUE;
}
catch (...)
{
}
return FALSE;
}
void ToXmlAttributes(XmlUtils::CXmlWriter& oXmlWriter)
{
oXmlWriter.WriteAttribute(_T("color"), Color);
oXmlWriter.WriteAttribute(_T("alpha"), Alpha);
oXmlWriter.WriteAttribute(_T("size"), Size);
oXmlWriter.WriteAttribute(_T("style"), DashStyle);
oXmlWriter.WriteAttribute(_T("line-start-cap"), LineStartCap);
oXmlWriter.WriteAttribute(_T("line-end-cap"), LineEndCap);
oXmlWriter.WriteAttribute(_T("line-join"), LineJoin);
oXmlWriter.WriteAttribute(_T("dash-offset"), DashOffset);
oXmlWriter.WriteAttribute(_T("alignment"), Align);
}
void FromXmlAttributes(XmlUtils::CXmlReader& oXmlReader)
{
Color = XmlUtils::GetInteger(oXmlReader.ReadNodeAttributeOrValue(_T("color"), _T("0")));
Alpha = XmlUtils::GetInteger(oXmlReader.ReadNodeAttributeOrValue(_T("alpha"), _T("0")));
Size = XmlUtils::GetDouble(oXmlReader.ReadNodeAttributeOrValue(_T("size"), _T("0")));
DashStyle = (byte)XmlUtils::GetInteger(oXmlReader.ReadNodeAttributeOrValue(_T("style"), _T("0")));
LineStartCap = (byte)XmlUtils::GetInteger(oXmlReader.ReadNodeAttributeOrValue(_T("line-start-cap"), _T("0")));
LineEndCap = (byte)XmlUtils::GetInteger(oXmlReader.ReadNodeAttributeOrValue(_T("line-end-cap"), _T("0")));
LineJoin = (byte)XmlUtils::GetInteger(oXmlReader.ReadNodeAttributeOrValue(_T("line-join"), _T("0")));
RELEASEARRAYOBJECTS(DashPattern);
Count = XmlUtils::GetInteger(oXmlReader.ReadNodeAttributeOrValue(_T("dash-pattern-count"), _T("0")));
if (Count != 0)
{
XmlUtils::CXmlNode oPatternNode;
oXmlReader.ReadNodeList(_T("dash-pattern"));
if (oPatternNode.FromXmlString(oXmlReader.ReadNodeXml(0)))
{
XmlUtils::CXmlNodes oDashNodes;
if (oPatternNode.GetNodes(_T("dash"), oDashNodes))
{
Count = oDashNodes.GetCount();
if (Count != 0)
{
DashPattern = new REAL[Count];
XmlUtils::CXmlNode oDashNode;
for (int i = 0; i < Count; ++i)
{
oDashNodes.GetAt(i, oDashNode);
DashPattern[i] = (REAL)XmlUtils::GetDouble(oDashNode.GetText());
}
}
}
}
}
DashOffset = (REAL)XmlUtils::GetDouble(oXmlReader.ReadNodeAttributeOrValue(_T("dash-offset"), _T("0")));
SetAlignment( XmlUtils::GetInteger(oXmlReader.ReadNodeAttribute(_T("alignment"), _T("0"))) );
Update();
}
void FromXmlNode(XmlUtils::CXmlNode& oXmlNode)
{
Color = XmlUtils::GetInteger(oXmlNode.GetAttributeOrValue(_T("color"), _T("0")));
Alpha = XmlUtils::GetInteger(oXmlNode.GetAttributeOrValue(_T("alpha"), _T("0")));
Size = XmlUtils::GetDouble(oXmlNode.GetAttributeOrValue(_T("size"), _T("0")));
DashStyle = (byte)XmlUtils::GetInteger(oXmlNode.GetAttributeOrValue(_T("style"), _T("0")));
LineStartCap = (byte)XmlUtils::GetInteger(oXmlNode.GetAttributeOrValue(_T("line-start-cap"), _T("0")));
LineEndCap = (byte)XmlUtils::GetInteger(oXmlNode.GetAttributeOrValue(_T("line-end-cap"), _T("0")));
LineJoin = (byte)XmlUtils::GetInteger(oXmlNode.GetAttributeOrValue(_T("line-join"), _T("0")));
RELEASEARRAYOBJECTS(DashPattern);
Count = XmlUtils::GetInteger(oXmlNode.GetAttributeOrValue(_T("dash-pattern-count"), _T("0")));
if (Count != 0)
{
XmlUtils::CXmlNode oPatternNode;
if (oXmlNode.GetNode(_T("dash-pattern"), oPatternNode))
{
XmlUtils::CXmlNodes oDashNodes;
if (oPatternNode.GetNodes(_T("dash"), oDashNodes))
{
Count = oDashNodes.GetCount();
if (Count != 0)
{
DashPattern = new REAL[Count];
XmlUtils::CXmlNode oDashNode;
for (int i = 0; i < Count; ++i)
{
oDashNodes.GetAt(i, oDashNode);
DashPattern[i] = (REAL)XmlUtils::GetDouble(oDashNode.GetText());
}
}
}
}
}
DashOffset = (REAL)XmlUtils::GetDouble(oXmlNode.GetAttributeOrValue(_T("dash-offset"), _T("0")));
SetAlignment( XmlUtils::GetInteger(oXmlNode.GetAttributeOrValue(_T("alignment"), _T("0"))) );
Update();
}
long GetColor() const
{
return Color;
}
void SetColor(long nColor)
{
if (Color != nColor)
Clear();
Color = nColor;
}
long GetAlpha() const
{
return Alpha;
}
void SetAlpha(long nAlpha)
{
if (Alpha != nAlpha)
Clear();
Alpha = nAlpha;
}
double GetSize() const
{
return Size;
}
void SetSize(double dSize)
{
if (fabs(Size - dSize) > 0.0001)
Clear();
Size = dSize;
}
byte GetStyle() const
{
return DashStyle;
}
void SetStyle(byte nStyle)
{
if (DashStyle != nStyle)
Clear();
DashStyle = nStyle;
}
byte GetLineStartCap() const
{
return LineStartCap;
}
void SetLineStartCap(byte nLineStartCap)
{
if (LineStartCap != nLineStartCap)
Clear();
LineStartCap = nLineStartCap;
}
byte GetLineEndCap() const
{
return LineEndCap;
}
void SetLineEndCap(byte nLineEndCap)
{
if (LineEndCap != nLineEndCap)
Clear();
LineEndCap = nLineEndCap;
}
byte GetLineJoin() const
{
return LineJoin;
}
void SetLineJoin(byte nLineJoin)
{
if (LineJoin != nLineJoin)
Clear();
LineJoin = nLineJoin;
}
long GetDashPatternCount() const
{
return Count;
}
void GetDashPattern(REAL* arrDashPattern, long& nCount) const
{
if (nCount == Count)
{
for (int i = 0; i < Count; ++i)
{
arrDashPattern[i] = DashPattern[i];
}
}
}
void SetDashPattern(REAL* arrDashPattern, long nCount)
{
if ((arrDashPattern == NULL) || (nCount == 0))
{
Count = 0;
RELEASEARRAYOBJECTS(DashPattern);
}
else
{
if (Count != nCount)
{
Count = nCount;
RELEASEARRAYOBJECTS(DashPattern);
DashPattern = new REAL[Count];
}
for (int i = 0; i < Count; ++i)
{
DashPattern[i] = arrDashPattern[i];
}
}
}
REAL GetDashOffset() const
{
return DashOffset;
}
void SetDashOffset(REAL fDashOffset)
{
if (DashOffset != fDashOffset)
Clear();
DashOffset = fDashOffset;
}
void SetAlignment( int align )
{
Align = (align == PenAlignmentInset) ? PenAlignmentInset : PenAlignmentCenter;
if( m_pen )
m_pen->SetAlignment( Align );
}
int GetAlignment() const
{
return Align;
}
void ScaleAlpha( double dScale )
{
long dNewAlpha = long(Alpha * dScale + 0.5);
if( dNewAlpha > 255 ) dNewAlpha = 255;
else if( dNewAlpha < 0 ) dNewAlpha = 0;
SetAlpha( dNewAlpha );
}
void FromPen(const CPen& oPen)
{
SetColor(oPen.GetColor());
SetAlpha(oPen.GetAlpha());
SetSize(oPen.GetSize());
SetStyle(oPen.GetStyle());
SetLineStartCap(oPen.GetLineStartCap());
SetLineEndCap(oPen.GetLineEndCap());
SetLineJoin(oPen.GetLineJoin());
long nCount = oPen.GetDashPatternCount();
REAL* arrDashPattern = new REAL[nCount];
oPen.GetDashPattern(arrDashPattern, nCount);
SetDashPattern(arrDashPattern, nCount);
RELEASEARRAYOBJECTS(arrDashPattern);
SetDashOffset(oPen.GetDashOffset());
SetAlignment(oPen.GetAlignment());
}
BOOL IsEqual(CPen* pPen)
{
if (NULL == pPen)
return FALSE;
return ((Color == pPen->Color) && (Alpha == pPen->Alpha) && (Size == pPen->Size) &&
(DashStyle == pPen->DashStyle) && (LineStartCap == pPen->LineStartCap) &&
(LineEndCap == pPen->LineEndCap) && (LineJoin == pPen->LineJoin));
}
void SetDefaultParams()
{
Color = 0;
Alpha = 255;
Size = 1;
DashStyle = 0;
LineStartCap = 0;
LineEndCap = 0;
LineJoin = 0;
DashPattern = NULL;
Count = 0;
DashOffset = 0;
Align = Gdiplus::PenAlignmentCenter;
}
public:
CPen()
{
m_pen = 0;
Color = 0;
Alpha = 255;
Size = 1;
DashStyle = 0;
LineStartCap = 0;
LineEndCap = 0;
LineJoin = 0;
DashPattern = NULL;
Count = 0;
DashOffset = 0;
Align = PenAlignmentCenter;
}
CPen( const CPen& other )
{
m_pen = NULL;
Color = other.Color;
Alpha = other.Alpha;
Size = other.Size;
DashStyle = other.DashStyle;
LineStartCap = other.LineStartCap;
LineEndCap = other.LineEndCap;
LineJoin = other.LineJoin;
Count = other.Count;
if (Count != 0)
{
DashPattern = new REAL[Count];
for (int i = 0; i < Count; ++i)
{
DashPattern[i] = other.DashPattern[i];
}
}
DashOffset = other.DashOffset;
Align = other.Align;
}
CPen& operator=(const CPen& pen)
{
Clear();
FromPen(pen);
return *this;
}
~CPen()
{
RELEASEARRAYOBJECTS(DashPattern);
Clear();
}
void Update()
{
Clear();
}
void Clear()
{
if (m_pen)
{
delete m_pen;
m_pen = 0;
}
}
Gdiplus::Pen* GetPen()
{
if (m_pen)
return m_pen;
Gdiplus::Color color((BYTE)Alpha, GetRValue(Color), GetGValue(Color), GetBValue(Color));
m_pen = new Gdiplus::Pen(color, (REAL)Size);
m_pen->SetDashStyle((Gdiplus::DashStyle)DashStyle);
m_pen->SetStartCap((LineCap)LineStartCap);
m_pen->SetEndCap((LineCap)LineEndCap);
m_pen->SetLineJoin((Gdiplus::LineJoin)LineJoin);
if ((Count != 0) && (DashPattern != NULL))
{
m_pen->SetDashPattern(DashPattern, Count);
}
m_pen->SetDashOffset(DashOffset);
m_pen->SetAlignment( Align );
return m_pen;
}
};
class CBrush
{
Gdiplus::Brush* m_brush;
double m_dTransparency;
public:
long Type;
long Color1;
long Color2;
long Alpha1;
long Alpha2;
long GradientAngle;
CString TexturePath;
long TextureAlpha;
long TextureMode;
BOOL Rectable;
RectF Rect;
public:
int GetSize()
{
return 4*sizeof(double) + 9*sizeof(long) + TexturePath.GetLength() + 1;
}
void Write(CStream& stream)
{
stream.WriteLong(Type);
stream.WriteLong(Color1);
stream.WriteLong(Alpha1);
stream.WriteLong(Color2);
stream.WriteLong(Alpha2);
stream.WriteLong(GradientAngle);
stream.WriteString(TexturePath);
stream.WriteLong(TextureAlpha);
stream.WriteLong(TextureMode);
stream.WriteLong(Rectable);
stream.WriteDouble(Rect.X);
stream.WriteDouble(Rect.Y);
stream.WriteDouble(Rect.Width);
stream.WriteDouble(Rect.Height);
}
void Read(CStream& stream)
{
Type = stream.ReadLong();
Color1 = stream.ReadLong();
Alpha1 = stream.ReadLong();
Color2 = stream.ReadLong();
Alpha2 = stream.ReadLong();
GradientAngle = stream.ReadLong();
TexturePath = stream.ReadString();
TextureAlpha = stream.ReadLong();
TextureMode = stream.ReadLong();
Rectable = stream.ReadLong();
Rect.X = (REAL)stream.ReadDouble();
Rect.Y = (REAL)stream.ReadDouble();
Rect.Width = (REAL)stream.ReadDouble();
Rect.Height = (REAL)stream.ReadDouble();
Update();
}
CString ToXmlString(CString strRootNodeName = _T("brush"), BOOL bAttributed = FALSE)
{
XmlUtils::CXmlWriter oXmlWriter;
if (!bAttributed)
{
oXmlWriter.WriteNodeBegin(strRootNodeName);
oXmlWriter.WriteNode(_T("type"), Type);
oXmlWriter.WriteNode(_T("color1"), Color1);
oXmlWriter.WriteNode(_T("color2"), Color2);
oXmlWriter.WriteNode(_T("alpha1"), Alpha1);
oXmlWriter.WriteNode(_T("alpha2"), Alpha2);
oXmlWriter.WriteNode(_T("gradient-angle"), GradientAngle);
oXmlWriter.WriteNode(_T("texturepath"), TexturePath);
oXmlWriter.WriteNode(_T("texturealpha"), TextureAlpha);
oXmlWriter.WriteNode(_T("texturemode"), TextureMode);
oXmlWriter.WriteNode(_T("rectable"), Rectable);
oXmlWriter.WriteNodeBegin(_T("rectangle"), TRUE);
oXmlWriter.WriteAttribute(_T("left"), Rect.X);
oXmlWriter.WriteAttribute(_T("top"), Rect.Y);
oXmlWriter.WriteAttribute(_T("width"), Rect.Width);
oXmlWriter.WriteAttribute(_T("height"), Rect.Height);
oXmlWriter.WriteNodeEnd(_T("rectangle"), TRUE);
oXmlWriter.WriteNodeEnd(strRootNodeName);
}
else
{
oXmlWriter.WriteNodeBegin(strRootNodeName, TRUE);
ToXmlAttributes(oXmlWriter);
oXmlWriter.WriteNodeEnd(strRootNodeName, TRUE);
}
return oXmlWriter.GetXmlString();
}
void FromXmlString(CString strXml)
{
XmlUtils::CXmlReader oXmlReader;
oXmlReader.SetXmlString(strXml);
oXmlReader.ReadRootNode();
FromXmlAttributes(oXmlReader);
}
BOOL FromStream(Streams::IStream* pStream)
{
if (!pStream)
return FALSE;
try
{
Type = pStream->ReadLong();
Type = ConstantCompatible(Type);
Color1 = pStream->ReadLong();
Alpha1 = pStream->ReadLong();
Color2 = pStream->ReadLong();
Alpha2 = pStream->ReadLong();
GradientAngle = pStream->ReadLong();
TexturePath = pStream->ReadString();
TextureAlpha = pStream->ReadLong();
TextureMode = pStream->ReadLong();
Rectable = pStream->ReadLong();
Rect.X = (REAL)pStream->ReadDouble();
Rect.Y = (REAL)pStream->ReadDouble();
Rect.Width = (REAL)pStream->ReadDouble();
Rect.Height = (REAL)pStream->ReadDouble();
Update();
return TRUE;
}
catch (...)
{
}
return FALSE;
}
BOOL ToStream(Streams::IStream* pStream)
{
if (!pStream)
return FALSE;
try
{
pStream->WriteLong(Type);
pStream->WriteLong(Color1);
pStream->WriteLong(Alpha1);
pStream->WriteLong(Color2);
pStream->WriteLong(Alpha2);
pStream->WriteLong(GradientAngle);
pStream->WriteString(TexturePath);
pStream->WriteLong(TextureAlpha);
pStream->WriteLong(TextureMode);
pStream->WriteLong(Rectable);
pStream->WriteDouble(Rect.X);
pStream->WriteDouble(Rect.Y);
pStream->WriteDouble(Rect.Width);
pStream->WriteDouble(Rect.Height);
return TRUE;
}
catch (...)
{
}
return FALSE;
}
void ToXmlAttributes(XmlUtils::CXmlWriter& oXmlWriter)
{
oXmlWriter.WriteAttribute(_T("type"), Type);
oXmlWriter.WriteAttribute(_T("color1"), Color1);
oXmlWriter.WriteAttribute(_T("color2"), Color2);
oXmlWriter.WriteAttribute(_T("alpha1"), Alpha1);
oXmlWriter.WriteAttribute(_T("alpha2"), Alpha2);
oXmlWriter.WriteAttribute(_T("gradient-angle"), GradientAngle);
oXmlWriter.WriteAttribute(_T("texturepath"), TexturePath);
oXmlWriter.WriteAttribute(_T("texturealpha"), TextureAlpha);
oXmlWriter.WriteAttribute(_T("texturemode"), TextureMode);
oXmlWriter.WriteAttribute(_T("rectable"), Rectable);
oXmlWriter.WriteAttribute(_T("rect-left"), Rect.X);
oXmlWriter.WriteAttribute(_T("rect-top"), Rect.Y);
oXmlWriter.WriteAttribute(_T("rect-width"), Rect.Width);
oXmlWriter.WriteAttribute(_T("rect-height"), Rect.Height);
}
void FromXmlAttributes(XmlUtils::CXmlReader& oXmlReader)
{
Type = XmlUtils::GetInteger(oXmlReader.ReadNodeAttributeOrValue(_T("type"), _T("0")));
Type = ConstantCompatible(Type);
Color1 = XmlUtils::GetInteger(oXmlReader.ReadNodeAttributeOrValue(_T("color1"), _T("0")));
Color2 = XmlUtils::GetInteger(oXmlReader.ReadNodeAttributeOrValue(_T("color2"), _T("0")));
Alpha1 = XmlUtils::GetInteger(oXmlReader.ReadNodeAttributeOrValue(_T("alpha1"), _T("0")));
Alpha2 = XmlUtils::GetInteger(oXmlReader.ReadNodeAttributeOrValue(_T("alpha2"), _T("0")));
GradientAngle = XmlUtils::GetInteger(oXmlReader.ReadNodeAttributeOrValue(_T("gradient-angle"), _T("0")));
TexturePath = oXmlReader.ReadNodeAttributeOrValue(_T("texturepath"), _T(""));
TextureAlpha = XmlUtils::GetInteger(oXmlReader.ReadNodeAttributeOrValue(_T("texturealpha"), _T("0")));
TextureMode = XmlUtils::GetInteger(oXmlReader.ReadNodeAttributeOrValue(_T("texturemode"), _T("0")));
Rectable = XmlUtils::GetInteger(oXmlReader.ReadNodeAttributeOrValue(_T("rectable"), _T("0")));
Rect.X = (REAL)XmlUtils::GetDouble(oXmlReader.ReadNodeAttributeOrValue(_T("rect-left")));
Rect.Y = (REAL)XmlUtils::GetDouble(oXmlReader.ReadNodeAttributeOrValue(_T("rect-top")));
Rect.Width = (REAL)XmlUtils::GetDouble(oXmlReader.ReadNodeAttributeOrValue(_T("rect-width")));
Rect.Height = (REAL)XmlUtils::GetDouble(oXmlReader.ReadNodeAttributeOrValue(_T("rect-height")));
if (oXmlReader.ReadNode(_T("rectangle")))
{
Rect.X = (REAL)XmlUtils::GetDouble(oXmlReader.ReadNodeAttribute(_T("left")));
Rect.Y = (REAL)XmlUtils::GetDouble(oXmlReader.ReadNodeAttribute(_T("top")));
Rect.Width = (REAL)XmlUtils::GetDouble(oXmlReader.ReadNodeAttribute(_T("width")));
Rect.Height = (REAL)XmlUtils::GetDouble(oXmlReader.ReadNodeAttribute(_T("height")));
}
Update();
}
void FromXmlNode(XmlUtils::CXmlNode& oXmlNode)
{
Type = XmlUtils::GetInteger(oXmlNode.GetAttributeOrValue(_T("type"), _T("0")));
Type = ConstantCompatible(Type);
Color1 = XmlUtils::GetInteger(oXmlNode.GetAttributeOrValue(_T("color1"), _T("0")));
Color2 = XmlUtils::GetInteger(oXmlNode.GetAttributeOrValue(_T("color2"), _T("0")));
Alpha1 = XmlUtils::GetInteger(oXmlNode.GetAttributeOrValue(_T("alpha1"), _T("0")));
Alpha2 = XmlUtils::GetInteger(oXmlNode.GetAttributeOrValue(_T("alpha2"), _T("0")));
GradientAngle = XmlUtils::GetInteger(oXmlNode.GetAttributeOrValue(_T("gradient-angle"), _T("0")));
TexturePath = oXmlNode.GetAttributeOrValue(_T("texturepath"), _T(""));
TextureAlpha = XmlUtils::GetInteger(oXmlNode.GetAttributeOrValue(_T("texturealpha"), _T("0")));
TextureMode = XmlUtils::GetInteger(oXmlNode.GetAttributeOrValue(_T("texturemode"), _T("0")));
Rectable = XmlUtils::GetInteger(oXmlNode.GetAttributeOrValue(_T("rectable"), _T("0")));
Rect.X = (REAL)XmlUtils::GetDouble(oXmlNode.GetAttributeOrValue(_T("rect-left")));
Rect.Y = (REAL)XmlUtils::GetDouble(oXmlNode.GetAttributeOrValue(_T("rect-top")));
Rect.Width = (REAL)XmlUtils::GetDouble(oXmlNode.GetAttributeOrValue(_T("rect-width")));
Rect.Height = (REAL)XmlUtils::GetDouble(oXmlNode.GetAttributeOrValue(_T("rect-height")));
XmlUtils::CXmlNode oNodeRect;
if (oXmlNode.GetNode(_T("rectangle"), oNodeRect))
{
Rect.X = (REAL)XmlUtils::GetDouble(oNodeRect.GetAttributeOrValue(_T("left")));
Rect.Y = (REAL)XmlUtils::GetDouble(oNodeRect.GetAttributeOrValue(_T("top")));
Rect.Width = (REAL)XmlUtils::GetDouble(oNodeRect.GetAttributeOrValue(_T("width")));
Rect.Height = (REAL)XmlUtils::GetDouble(oNodeRect.GetAttributeOrValue(_T("height")));
}
Update();
}
long GetType() const
{
return ConstantCompatible(Type);
}
void SetType(long nType)
{
if (Type != nType)
Clear();
Type = ConstantCompatible(nType);
}
long GetColor1() const
{
return Color1;
}
void SetColor1(long nColor1)
{
if (Color1 != nColor1)
Clear();
Color1 = nColor1;
}
long GetColor2() const
{
return Color2;
}
void SetColor2(int nColor2)
{
if (Color2 != nColor2)
Clear();
Color2 = nColor2;
}
long GetAlpha1() const
{
return Alpha1;
}
void SetAlpha1(long nAlpha1)
{
if (Alpha1 != nAlpha1)
Clear();
Alpha1 = nAlpha1;
}
long GetAlpha2() const
{
return Alpha2;
}
void SetAlpha2(long nAlpha2)
{
if (Alpha2 != nAlpha2)
Clear();
Alpha2 = nAlpha2;
}
long GetGradientAngle() const
{
return GradientAngle;
}
void SetGradientAngle(long nGradientAngle)
{
if (GradientAngle != nGradientAngle)
Clear();
GradientAngle = nGradientAngle;
}
CString GetTexturePath() const
{
return TexturePath;
}
void SetTexturePath(const CString& strTexturePath)
{
if (TexturePath != strTexturePath)
Clear();
TexturePath = strTexturePath;
}
long GetTextureAlpha() const
{
return TextureAlpha;
}
void SetTextureAlpha(long nTextureAlpha)
{
if (TextureAlpha != nTextureAlpha)
Clear();
TextureAlpha = nTextureAlpha;
}
long GetTextureMode() const
{
return TextureMode;
}
void SetTextureMode(long nTextureMode)
{
if (TextureMode != nTextureMode)
Clear();
TextureMode = nTextureMode;
}
BOOL GetRectable() const
{
return Rectable;
}
Gdiplus::RectF GetRect() const
{
return Rect;
}
void SetRect(Gdiplus::RectF* pRect)
{
if (NULL == pRect)
{
if (Rectable)
Clear();
Rectable = FALSE;
}
else
{
if (!Rectable || pRect->X != Rect.X || pRect->Y != Rect.Y || pRect->Width != Rect.Width || pRect->Height != Rect.Height)
Clear();
Rect = *pRect;
Rectable = TRUE;
}
}
void ScaleAlpha1( double dScale )
{
long dNewAlpha = long(Alpha1 * dScale + 0.5);
if( dNewAlpha > 255 ) dNewAlpha = 255;
else if( dNewAlpha < 0 ) dNewAlpha = 0;
SetAlpha1( dNewAlpha );
}
void ScaleAlpha2( double dScale )
{
long dNewAlpha = long(Alpha2 * dScale + 0.5);
if( dNewAlpha > 255 ) dNewAlpha = 255;
else if( dNewAlpha < 0 ) dNewAlpha = 0;
SetAlpha2( dNewAlpha );
}
void ScaleTextureAlpha( double dScale )
{
long dNewAlpha = long(TextureAlpha * dScale + 0.5);
if( dNewAlpha > 255 ) dNewAlpha = 255;
else if( dNewAlpha < 0 ) dNewAlpha = 0;
SetTextureAlpha( dNewAlpha );
}
void FromBrush(const CBrush& oBrush)
{
SetType(oBrush.GetType());
SetColor1(oBrush.GetColor1());
SetColor2(oBrush.GetColor2());
SetAlpha1(oBrush.GetAlpha1());
SetAlpha2(oBrush.GetAlpha2());
SetGradientAngle(oBrush.GetGradientAngle());
SetTexturePath(oBrush.GetTexturePath());
SetTextureAlpha(oBrush.GetTextureAlpha());
SetTextureMode(oBrush.GetTextureMode());
if (!oBrush.GetRectable())
SetRect(NULL);
else
SetRect(&oBrush.GetRect());
}
void SetTransparency( double dIntensity )
{
if( dIntensity > 1 ) dIntensity = 1;
if( dIntensity < 0 ) dIntensity = 0;
if( dIntensity != m_dTransparency )
{
int nOldAlpha1 = int(m_dTransparency * Alpha1 + 0.5);
int nNewAlpha1 = int(dIntensity * Alpha1 + 0.5);
int nOldAlpha2 = int(m_dTransparency * Alpha2 + 0.5);
int nNewAlpha2 = int(dIntensity * Alpha2 + 0.5);
int nOldTextureAlpha = int(m_dTransparency * TextureAlpha + 0.5);
int nNewTextureAlpha = int(dIntensity * TextureAlpha + 0.5);
if( nNewAlpha1 != nOldAlpha1 ||
nNewAlpha2 != nOldAlpha2 ||
nNewTextureAlpha != nOldTextureAlpha )
{
Update();
}
m_dTransparency = dIntensity;
}
}
double GetTransparency() const
{
return m_dTransparency;
}
BOOL IsEqual(CBrush* pBrush)
{
if (NULL == pBrush)
return FALSE;
return ((Type == pBrush->Type) &&
(Color1 == pBrush->Color1) && (Color2 == pBrush->Color2) &&
(Alpha1 == pBrush->Alpha1) && (Alpha2 == pBrush->Alpha2) && (GradientAngle == pBrush->GradientAngle));
}
void SetDefaultParams()
{
Type = c_BrushTypeSolid;
Color1 = 0;
Alpha1 = 255;
Color2 = 0;
Alpha2 = 255;
TextureAlpha = 255;
TextureMode = c_BrushTextureModeStretch;
TexturePath = _T("");
Rectable = FALSE;
Rect.X = 0.0F;
Rect.Y = 0.0F;
Rect.Width = 0.0F;
Rect.Height = 0.0F;
}
public:
CBrush()
{
m_brush = 0;
Type = 0;
Color1 = 0;
Alpha1 = 255;
Color2 = 0;
Alpha2 = 255;
GradientAngle = 0;
TextureAlpha = 255;
TextureMode = c_BrushTextureModeStretch;
Rectable = FALSE;
Rect.X = 0.0F;
Rect.Y = 0.0F;
Rect.Width = 0.0F;
Rect.Height = 0.0F;
m_dTransparency = 1;
}
CBrush( const CBrush& other )
{
m_brush = NULL;
Type = other.Type;
Color1 = other.Color1;
Alpha1 = other.Alpha1;
Color2 = other.Color2;
Alpha2 = other.Alpha2;
GradientAngle = other.GradientAngle;
TexturePath = other.TexturePath;
TextureAlpha = other.TextureAlpha;
TextureMode = other.TextureMode;
Rectable = other.Rectable;
Rect = other.Rect;
m_dTransparency = other.m_dTransparency;
}
CBrush& operator=(const CBrush& brush)
{
Clear();
FromBrush(brush);
return *this;
}
~CBrush()
{
Clear();
}
void Update()
{
Clear();
}
void Clear()
{
if( m_brush )
{
delete m_brush;
m_brush = 0;
}
}
static bool GetTextRect(BSTR Text, Graphics* pGr, Gdiplus::Font* font, double Left, double Top, RectF* textRect)
{
if (!pGr || !font || !textRect)
return false;
PointF point((REAL)Left, (REAL)Top);
Status s = pGr->MeasureString(Text, SysStringLen(Text), font, point, textRect);
if (s != Ok)
return false;
return true;
}
Gdiplus::Brush* GetBrush(CTextureManager* manager = 0, RectF* pRect = 0, int index = 0, BOOL bAddIfNotExists = FALSE)
{
if( m_brush )
{
if( EqualsRectable( pRect ) )
return m_brush;
if( BrushTypeTextureFill == m_brush->GetType() )
{
Gdiplus::TextureBrush* pBrush = (Gdiplus::TextureBrush*)m_brush;
SetTextureBrushTransform( pBrush, pRect );
return m_brush;
}
Rectable = FALSE;
Clear();
}
int nBrushType = GetType();
if (c_BrushTypeTexture == nBrushType && manager)
{
int index = manager->Find(TexturePath);
if (index < 0 && bAddIfNotExists)
index = manager->Add(TexturePath);
if (index >= 0)
{
Gdiplus::TextureBrush* brush = GetTexureBrush(manager->GetAt(index), pRect );
m_brush = brush;
return m_brush;
}
}
else if (nBrushType >= c_BrushTypeHatch1 && nBrushType <= c_BrushTypeHatch53)
{
Gdiplus::Color color1((BYTE)(Alpha1 * m_dTransparency + 0.5), GetRValue(Color1), GetGValue(Color1), GetBValue(Color1));
Gdiplus::Color color2((BYTE)(Alpha2 * m_dTransparency + 0.5), GetRValue(Color2), GetGValue(Color2), GetBValue(Color2));
Gdiplus::HatchBrush* brush = new HatchBrush((HatchStyle)(nBrushType - c_BrushTypeHatch1), color1, color2);
m_brush = brush;
return m_brush;
}
else if (GradientAngle>0 && pRect && nBrushType!=c_BrushTypeSolid)
{
Gdiplus::LinearGradientBrush* brush = GetLinearGradientBrushAngle(GradientAngle, pRect);
m_brush = brush;
return m_brush;
}
else if (nBrushType >= c_BrushTypeHorizontal && nBrushType <= c_BrushTypeDiagonal2 && pRect)
{
int angle = 0;
switch(nBrushType)
{
case c_BrushTypeVertical:
angle = 90;
break;
case c_BrushTypeDiagonal1:
angle = 45;
break;
case c_BrushTypeDiagonal2:
angle = 135;
break;
}
Gdiplus::LinearGradientBrush* brush = GetLinearGradientBrushAngle(90 - angle, pRect);
m_brush = brush;
return m_brush;
}
else if ((c_BrushTypeCenter == nBrushType && pRect) || (c_BrushTypePathGradient1 == nBrushType && pRect))
{
Gdiplus::PathGradientBrush* brush = GetPathGradientBrushCenter(pRect);
m_brush = brush;
return m_brush;
}
if (c_BrushTypePathGradient2 == nBrushType && pRect)
{
Gdiplus::PathGradientBrush* brush = GetPathGradientBrush(pRect, index);
m_brush = brush;
return m_brush;
}
else if (nBrushType >= c_BrushTypeCylinderHor && nBrushType <= c_BrushTypeCylinderVer && pRect)
{
Gdiplus::LinearGradientBrush* brush = GetLinearGradientBrushCHV(nBrushType - c_BrushTypeCylinderHor, pRect);
m_brush = brush;
return m_brush;
}
Gdiplus::Color color((BYTE)(Alpha1 * m_dTransparency + 0.5), GetRValue(Color1), GetGValue(Color1), GetBValue(Color1));
Gdiplus::SolidBrush* brush = new Gdiplus::SolidBrush(color);
m_brush = brush;
return m_brush;
}
private:
ImageAttributes* GetImageAttributes( int nAlpha )
{
if( nAlpha < 0 || nAlpha >= 255 )
return NULL;
REAL alph = (REAL)(nAlpha / 255.0);
ColorMatrix colorMatrix = {
1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, alph, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f, 1.0f
};
ImageAttributes* pImageAtt = new ImageAttributes();
if( pImageAtt )
pImageAtt->SetColorMatrix(&colorMatrix, ColorMatrixFlagsDefault, ColorAdjustTypeBitmap);
return pImageAtt;
}
void SetTextureBrushTransform( Gdiplus::TextureBrush* pBrush, Gdiplus::RectF* pBrushRect )
{
if( !pBrush )
return;
Gdiplus::Image* pImage = pBrush->GetImage();
Gdiplus::RectF oImageRect;
Gdiplus::Unit oImageUnit;
if( pImage )
{
pImage->GetBounds( &oImageRect, &oImageUnit );
delete pImage;
}
pBrush->ResetTransform();
Gdiplus::PointF oBrushOffset;
if( pBrushRect )
{
oBrushOffset.X = pBrushRect->X;
oBrushOffset.Y = pBrushRect->Y;
}
switch(TextureMode)
{
case c_BrushTextureModeStretch:
if( pBrushRect )
{
pBrush->ScaleTransform( pBrushRect->Width / oImageRect.Width, pBrushRect->Height / oImageRect.Height );
break;
}
case c_BrushTextureModeTileCenter:
if( pBrushRect )
{
oBrushOffset.X += (pBrushRect->Width - oImageRect.Width)/2;
oBrushOffset.Y += (pBrushRect->Height - oImageRect.Height)/2;
pBrush->SetWrapMode( WrapModeTile );
break;
}
default:
pBrush->SetWrapMode( WrapModeTile );
}
if( oBrushOffset.X != 0 || oBrushOffset.Y != 0)
{
pBrush->TranslateTransform( oBrushOffset.X, oBrushOffset.Y, MatrixOrderAppend );
SetRectable( pBrushRect );
}
}
Gdiplus::TextureBrush* GetTexureBrush( Painter::CTexture* pTexture, Gdiplus::RectF* pRect)
{
int nAlpha = int(TextureAlpha * m_dTransparency + 0.5);
if( nAlpha < 1 )
return NULL;
if( !pTexture )
return NULL;
Gdiplus::TextureBrush* pBrush = NULL;
Gdiplus::Bitmap* pTextureBitmap = pTexture->Bitmap;
if( !pTextureBitmap )
{
BYTE* pBGRA = pTexture->BitmapData;
int nWidth = pTexture->nWidth;
int nHeight = pTexture->nHeight;
int nStride = pTexture->nStride;
if( NULL == pBGRA || nWidth <=0 || nHeight <= 0 || abs(nStride) < nWidth * 4 )
return NULL;
BYTE* pBuffer = NULL;
if( nAlpha < 255 )
{
pBuffer = new BYTE[nWidth*nHeight*4];
if( pBuffer )
{
if( nStride < 0 )
{
pBGRA += nStride * (nHeight - 1);
nStride = -nStride;
}
nStride -= nWidth * 4;
BYTE* pSrc = pBGRA;
BYTE* pDst = pBuffer;
for( int nRow = nHeight; nRow > 0; --nRow, pSrc += nStride )
{
for( int nPos = nWidth; nPos > 0; --nPos, pDst += 4, pSrc += 4 )
{
DWORD alpha = ((DWORD(pSrc[3]) << 8) + 127) / 255;
pDst[0] = BYTE(pSrc[0] * alpha >> 8);
pDst[1] = BYTE(pSrc[1] * alpha >> 8);
pDst[2] = BYTE(pSrc[2] * alpha >> 8);
pDst[3] = BYTE(nAlpha);
}
}
pBGRA = pBuffer;
nStride = nWidth*4;
}
}
Gdiplus::Bitmap oImage( nWidth, nHeight, nStride, PixelFormat32bppARGB, pBGRA );
if( Gdiplus::Ok == oImage.GetLastStatus() )
{
pBrush = new Gdiplus::TextureBrush( &oImage, Gdiplus::Rect(0, 0, nWidth, nHeight), NULL);
}
if( pBuffer )
delete [] pBuffer;
}
else
{
Gdiplus::ImageAttributes* pImageAttr = GetImageAttributes( nAlpha );
pBrush = new Gdiplus::TextureBrush(pTextureBitmap, Gdiplus::Rect(0, 0, pTexture->nWidth, pTexture->nHeight), pImageAttr);
if( pImageAttr )
{
delete pImageAttr;
pImageAttr = NULL;
}
}
SetTextureBrushTransform( pBrush, pRect );
return pBrush;
}
Gdiplus::LinearGradientBrush* GetLinearGradientBrushHVD(int type, RectF* pRect)
{
Gdiplus::Color color1((BYTE)(Alpha1 * m_dTransparency + 0.5), GetRValue(Color1), GetGValue(Color1), GetBValue(Color1));
Gdiplus::Color color2((BYTE)(Alpha2 * m_dTransparency + 0.5), GetRValue(Color2), GetGValue(Color2), GetBValue(Color2));
Gdiplus::LinearGradientBrush* brush = new Gdiplus::LinearGradientBrush(*pRect, color1, color2, (LinearGradientMode)type);
if( brush )
{
brush->SetWrapMode( Gdiplus::WrapModeTileFlipXY );
}
SetRectable(pRect);
return brush;
}
Gdiplus::LinearGradientBrush* GetLinearGradientBrushCHV(int type, RectF* pRect)
{
Gdiplus::Color color1((BYTE)(Alpha1 * m_dTransparency + 0.5), GetRValue(Color1), GetGValue(Color1), GetBValue(Color1));
Gdiplus::Color color2((BYTE)(Alpha2 * m_dTransparency + 0.5), GetRValue(Color2), GetGValue(Color2), GetBValue(Color2));
float angle = 0;
switch(type)
{
case 0: angle = -90; break;
case 1: angle = -180; break;
}
Gdiplus::LinearGradientBrush* brush = new Gdiplus::LinearGradientBrush(*pRect, color1, color2, angle);
if( brush )
{
brush->SetBlendBellShape(0.70f);
brush->SetWrapMode( Gdiplus::WrapModeTileFlipXY );
}
SetRectable(pRect);
return brush;
}
Gdiplus::LinearGradientBrush* GetLinearGradientBrushAngle(int nAngle, RectF* pRect)
{
Gdiplus::Color color1((BYTE)(Alpha1 * m_dTransparency + 0.5), GetRValue(Color1), GetGValue(Color1), GetBValue(Color1));
Gdiplus::Color color2((BYTE)(Alpha2 * m_dTransparency + 0.5), GetRValue(Color2), GetGValue(Color2), GetBValue(Color2));
float angle = (float)(90 - nAngle);
Gdiplus::LinearGradientBrush* brush = new Gdiplus::LinearGradientBrush(*pRect, color1, color2, angle);
if( brush )
{
brush->SetWrapMode( Gdiplus::WrapModeTileFlipXY );
}
SetRectable(pRect);
return brush;
}
Gdiplus::PathGradientBrush* GetPathGradientBrushCenter(RectF* pRect)
{
Gdiplus::Color color1((BYTE)(Alpha1 * m_dTransparency + 0.5), GetRValue(Color1), GetGValue(Color1), GetBValue(Color1));
Gdiplus::Color color2((BYTE)(Alpha2 * m_dTransparency + 0.5), GetRValue(Color2), GetGValue(Color2), GetBValue(Color2));
Gdiplus::GraphicsPath path; path.AddRectangle(*pRect);
PathGradientBrush* brush = new PathGradientBrush(&path);
if( brush )
{
Color colors[] = {color1};
int count = 1;
brush->SetSurroundColors(colors, &count);
brush->SetCenterColor(color2);
brush->SetWrapMode( Gdiplus::WrapModeTileFlipXY );
}
SetRectable(pRect);
return brush;
}
Gdiplus::PathGradientBrush* GetPathGradientBrush(RectF* pRect, int index)
{
Gdiplus::Color color1((BYTE)(Alpha1 * m_dTransparency + 0.5), GetRValue(Color1), GetGValue(Color1), GetBValue(Color1));
Gdiplus::Color color2((BYTE)(Alpha2 * m_dTransparency + 0.5), GetRValue(Color2), GetGValue(Color2), GetBValue(Color2));
Gdiplus::GraphicsPath path; path.AddRectangle(*pRect);
PathGradientBrush* brush = new PathGradientBrush(&path);
if( brush )
{
int colorsCount = 4;
Color colors1[] = {color1, color2, color2, color1};
Color colors2[] = {color2, color1, color1, color2};
Color* pColors = (index % 2) ? colors2 : colors1;
Color& oColor = (index % 2) ? color2 : color1;
brush->SetSurroundColors(pColors, &colorsCount);
brush->SetCenterColor(oColor);
brush->SetWrapMode( Gdiplus::WrapModeTileFlipXY );
}
SetRectable(pRect);
return brush;
}
void SetRectable(RectF* pRect)
{
if( pRect )
{
Rect = *pRect;
}
Rectable = TRUE;
}
BOOL EqualsRectable( Gdiplus::RectF* pRect )
{
if( !Rectable )
return TRUE;
if( !pRect )
return !Rect.Width && !Rect.Height && !Rect.X && !Rect.Y;
else
return Rect.Equals( *pRect );
}
};
class CFont
{
Gdiplus::Font* m_font;
public:
CString Name;
CString Path;
double Size;
BOOL Bold;
BOOL Italic;
BOOL Underline;
BOOL Strikeout;
public:
int GetSize()
{
return Name.GetLength() + 1 + sizeof(double) + 4*sizeof(long) + Path.GetLength() + 1;
}
void Write(CStream& stream)
{
stream.WriteString(Name);
stream.WriteString(Path);
stream.WriteDouble(Size);
stream.WriteLong(Bold);
stream.WriteLong(Italic);
stream.WriteLong(Underline);
stream.WriteLong(Strikeout);
}
void Read(CStream& stream)
{
Name = stream.ReadString();
Path = stream.ReadString();
Size = stream.ReadDouble();
Bold = stream.ReadLong();
Italic = stream.ReadLong();
Underline = stream.ReadLong();
Strikeout = stream.ReadLong();
Update();
}
CString ToXmlString(CString strRootNodeName = _T("font"), BOOL bAttributed = FALSE)
{
XmlUtils::CXmlWriter oXmlWriter;
if (!bAttributed)
{
oXmlWriter.WriteNodeBegin(strRootNodeName);
oXmlWriter.WriteNode(_T("name"), Name);
oXmlWriter.WriteNode(_T("path"), Path);
oXmlWriter.WriteNode(_T("size"), Size);
oXmlWriter.WriteNode(_T("bold"), Bold);
oXmlWriter.WriteNode(_T("italic"), Italic);
oXmlWriter.WriteNode(_T("underline"), Underline);
oXmlWriter.WriteNode(_T("strikeout"), Strikeout);
oXmlWriter.WriteNodeEnd(strRootNodeName);
}
else
{
oXmlWriter.WriteNodeBegin(strRootNodeName, TRUE);
ToXmlAttributes(oXmlWriter);
oXmlWriter.WriteNodeEnd(strRootNodeName, TRUE);
}
return oXmlWriter.GetXmlString();
}
void FromXmlString(CString strXml)
{
XmlUtils::CXmlReader oXmlReader;
oXmlReader.SetXmlString(strXml);
oXmlReader.ReadRootNode();
FromXmlAttributes(oXmlReader);
}
BOOL FromStream(Streams::IStream* pStream)
{
if (!pStream)
return FALSE;
try
{
Name = pStream->ReadString();
Path = pStream->ReadString();
Size = pStream->ReadDouble();
Bold = pStream->ReadLong();
Italic = pStream->ReadLong();
Underline = pStream->ReadLong();
Strikeout = pStream->ReadLong();
Update();
return TRUE;
}
catch (...)
{
}
return FALSE;
}
BOOL ToStream(Streams::IStream* pStream)
{
if (!pStream)
return FALSE;
try
{
pStream->WriteString(Name);
pStream->WriteString(Path);
pStream->WriteDouble(Size);
pStream->WriteLong(Bold);
pStream->WriteLong(Italic);
pStream->WriteLong(Underline);
pStream->WriteLong(Strikeout);
return TRUE;
}
catch (...)
{
}
return FALSE;
}
void ToXmlAttributes(XmlUtils::CXmlWriter& oXmlWriter)
{
oXmlWriter.WriteAttribute(_T("name"), Name);
oXmlWriter.WriteAttribute(_T("path"), Path);
oXmlWriter.WriteAttribute(_T("size"), Size);
oXmlWriter.WriteAttribute(_T("bold"), Bold);
oXmlWriter.WriteAttribute(_T("italic"), Italic);
oXmlWriter.WriteAttribute(_T("underline"), Underline);
oXmlWriter.WriteAttribute(_T("strikeout"), Strikeout);
}
void FromXmlAttributes(XmlUtils::CXmlReader& oXmlReader)
{
Name = oXmlReader.ReadNodeAttributeOrValue(_T("name"), _T("Arial"));
Path = oXmlReader.ReadNodeAttributeOrValue(_T("path"), _T(""));
Size = XmlUtils::GetDouble(oXmlReader.ReadNodeAttributeOrValue(_T("size"), _T("0")));
Bold = XmlUtils::GetInteger(oXmlReader.ReadNodeAttributeOrValue(_T("bold"), _T("0")));
Italic = XmlUtils::GetInteger(oXmlReader.ReadNodeAttributeOrValue(_T("italic"), _T("0")));
Underline = XmlUtils::GetInteger(oXmlReader.ReadNodeAttributeOrValue(_T("underline"), _T("0")));
Strikeout = XmlUtils::GetInteger(oXmlReader.ReadNodeAttributeOrValue(_T("strikeout"), _T("0")));
Update();
}
void FromXmlNode(XmlUtils::CXmlNode& oXmlNode)
{
Name = oXmlNode.GetAttributeOrValue(_T("name"), _T("Arial"));
Path = oXmlNode.GetAttributeOrValue(_T("path"), _T(""));
Size = XmlUtils::GetDouble(oXmlNode.GetAttributeOrValue(_T("size"), _T("0")));
Bold = XmlUtils::GetInteger(oXmlNode.GetAttributeOrValue(_T("bold"), _T("0")));
Italic = XmlUtils::GetInteger(oXmlNode.GetAttributeOrValue(_T("italic"), _T("0")));
Underline = XmlUtils::GetInteger(oXmlNode.GetAttributeOrValue(_T("underline"), _T("0")));
Strikeout = XmlUtils::GetInteger(oXmlNode.GetAttributeOrValue(_T("strikeout"), _T("0")));
Update();
}
CString GetName() const
{
return Name;
}
void SetName(const CString& strName)
{
if (Name != strName)
Clear();
Name = strName;
}
CString GetPath() const
{
return Path;
}
void SetPath(const CString& strPath)
{
if ( Path != strPath )
Clear();
Path = strPath;
}
double GetFontSize() const
{
return Size;
}
void SetFontSize(double dSize)
{
if (fabs(Size - dSize) > 0.0001)
Clear();
Size = dSize;
}
BOOL GetBold() const
{
return Bold;
}
void SetBold(BOOL bBold)
{
if (Bold != bBold)
Clear();
Bold = bBold;
}
BOOL GetItalic() const
{
return Italic;
}
void SetItalic(BOOL bItalic)
{
if (Italic != bItalic)
Clear();
Italic = bItalic;
}
BOOL GetUnderline() const
{
return Underline;
}
void SetUnderline(BOOL bUnderline)
{
if (Underline != bUnderline)
Clear();
Underline = bUnderline;
}
BOOL GetStrikeout() const
{
return Strikeout;
}
void SetStrikeout(BOOL bStrikeout)
{
if (Strikeout != bStrikeout)
Clear();
Strikeout = bStrikeout;
}
void FromFont(const CFont& oFont)
{
SetName(oFont.GetName());
SetPath(oFont.GetPath());
SetFontSize(oFont.GetFontSize());
SetBold(oFont.GetBold());
SetItalic(oFont.GetItalic());
SetUnderline(oFont.GetUnderline());
SetStrikeout(oFont.GetStrikeout());
}
BOOL IsEqual(CFont* pFont)
{
if (NULL == pFont)
return FALSE;
return ((Name == pFont->Name) && (Path == pFont->Path) && (Size == pFont->Size) &&
(Bold == pFont->Bold) && (Italic == pFont->Italic) &&
(Underline == pFont->Underline) && (Strikeout == pFont->Strikeout));
}
void SetDefaultParams()
{
Name = _T("Arial");
Path = _T("");
Size = 0;
Bold = FALSE;
Italic = FALSE;
Underline = 0;
Strikeout = 0;
}
public:
CFont()
{
m_font = 0;
Size = 0;
Bold = FALSE;
Italic = FALSE;
Underline = FALSE;
Strikeout = FALSE;
}
CFont( const CFont& other )
{
m_font = 0;
Name = other.Name;
Path = other.Path;
Size = other.Size;
Bold = other.Bold;
Italic = other.Italic;
Underline = other.Underline;
Strikeout = other.Strikeout;
}
CFont& operator=(const CFont& font)
{
Clear();
FromFont(font);
return *this;
}
~CFont()
{
Clear();
}
void Update()
{
Clear();
}
void Clear()
{
if (m_font)
{
delete m_font;
m_font = 0;
}
}
Gdiplus::Font* GetFont(Gdiplus::Unit units = Gdiplus::UnitPixel)
{
if (m_font)
return m_font;
BSTR family = Name.AllocSysString();
int style = Gdiplus::FontStyleRegular;
if (Bold)
style |= Gdiplus::FontStyleBold;
if (Italic)
style |= Gdiplus::FontStyleItalic;
if (Underline)
style |= Gdiplus::FontStyleUnderline;
if (Strikeout)
style |= Gdiplus::FontStyleStrikeout;
Gdiplus::Font* font = new Gdiplus::Font(family, (REAL)Size, style, units);
SysFreeString(family);
m_font = font;
return m_font;
}
};
class CFormat
{
Gdiplus::StringFormat* m_stringFormat;
public:
BOOL AntiAliasPen;
BOOL AntiAliasBrush;
BOOL AntiAliasText;
long StringAlignmentVertical;
long StringAlignmentHorizontal;
long ImageAlphMode;
public:
int GetSize()
{
return 6*sizeof(long);
}
void Write(CStream& stream)
{
stream.WriteLong(AntiAliasPen);
stream.WriteLong(AntiAliasBrush);
stream.WriteLong(AntiAliasText);
stream.WriteLong(StringAlignmentVertical);
stream.WriteLong(StringAlignmentHorizontal);
stream.WriteLong(ImageAlphMode);
}
void Read(CStream& stream)
{
AntiAliasPen = stream.ReadLong();
AntiAliasBrush = stream.ReadLong();
AntiAliasText = stream.ReadLong();
StringAlignmentVertical = stream.ReadLong();
StringAlignmentHorizontal = stream.ReadLong();
ImageAlphMode = stream.ReadLong();
Update();
}
CString ToXmlString(CString strRootNodeName = _T("format"), BOOL bAttributed = FALSE)
{
XmlUtils::CXmlWriter oXmlWriter;
if (!bAttributed)
{
oXmlWriter.WriteNodeBegin(strRootNodeName);
oXmlWriter.WriteNode(_T("antialiaspen"), AntiAliasPen);
oXmlWriter.WriteNode(_T("antialiasbrush"), AntiAliasBrush);
oXmlWriter.WriteNode(_T("antialiastext"), AntiAliasText);
oXmlWriter.WriteNode(_T("stringalignmentvertical"), StringAlignmentVertical);
oXmlWriter.WriteNode(_T("stringalignmenthorizontal"), StringAlignmentHorizontal);
oXmlWriter.WriteNode(_T("imagealphmode"), ImageAlphMode);
oXmlWriter.WriteNodeEnd(strRootNodeName);
}
else
{
oXmlWriter.WriteNodeBegin(strRootNodeName, TRUE);
ToXmlAttributes(oXmlWriter);
oXmlWriter.WriteNodeEnd(strRootNodeName, TRUE);
}
return oXmlWriter.GetXmlString();
}
void FromXmlString(CString strXml)
{
XmlUtils::CXmlReader oXmlReader;
oXmlReader.SetXmlString(strXml);
oXmlReader.ReadRootNode();
FromXmlAttributes(oXmlReader);
}
BOOL FromStream(Streams::IStream* pStream)
{
if (!pStream)
return FALSE;
try
{
AntiAliasPen = pStream->ReadLong();
AntiAliasBrush = pStream->ReadLong();
AntiAliasText = pStream->ReadLong();
StringAlignmentVertical = pStream->ReadLong();
StringAlignmentHorizontal = pStream->ReadLong();
ImageAlphMode = pStream->ReadLong();
Update();
return TRUE;
}
catch (...)
{
}
return FALSE;
}
BOOL ToStream(Streams::IStream* pStream)
{
if (!pStream)
return FALSE;
try
{
pStream->WriteLong(AntiAliasPen);
pStream->WriteLong(AntiAliasBrush);
pStream->WriteLong(AntiAliasText);
pStream->WriteLong(StringAlignmentVertical);
pStream->WriteLong(StringAlignmentHorizontal);
pStream->WriteLong(ImageAlphMode);
return TRUE;
}
catch (...)
{
}
return FALSE;
}
void ToXmlAttributes(XmlUtils::CXmlWriter& oXmlWriter)
{
oXmlWriter.WriteAttribute(_T("antialiaspen"), AntiAliasPen);
oXmlWriter.WriteAttribute(_T("antialiasbrush"), AntiAliasBrush);
oXmlWriter.WriteAttribute(_T("antialiastext"), AntiAliasText);
oXmlWriter.WriteAttribute(_T("stringalignmentvertical"), StringAlignmentVertical);
oXmlWriter.WriteAttribute(_T("stringalignmenthorizontal"), StringAlignmentHorizontal);
oXmlWriter.WriteAttribute(_T("imagealphmode"), ImageAlphMode);
}
void FromXmlAttributes(XmlUtils::CXmlReader& oXmlReader)
{
AntiAliasPen = XmlUtils::GetInteger(oXmlReader.ReadNodeAttributeOrValue(_T("antialiaspen"), _T("1")));
AntiAliasBrush = XmlUtils::GetInteger(oXmlReader.ReadNodeAttributeOrValue(_T("antialiasbrush"), _T("1")));
AntiAliasText = XmlUtils::GetInteger(oXmlReader.ReadNodeAttributeOrValue(_T("antialiastext"), _T("0")));
StringAlignmentVertical = XmlUtils::GetInteger(oXmlReader.ReadNodeAttributeOrValue(_T("stringalignmentvertical"), _T("0")));
StringAlignmentHorizontal = XmlUtils::GetInteger(oXmlReader.ReadNodeAttributeOrValue(_T("stringalignmenthorizontal"), _T("0")));
ImageAlphMode = XmlUtils::GetInteger(oXmlReader.ReadNodeAttributeOrValue(_T("imagealphmode"), _T("0")));
Update();
}
void FromXmlNode(XmlUtils::CXmlNode& oXmlNode)
{
AntiAliasPen = XmlUtils::GetInteger(oXmlNode.GetAttributeOrValue(_T("antialiaspen"), _T("1")));
AntiAliasBrush = XmlUtils::GetInteger(oXmlNode.GetAttributeOrValue(_T("antialiasbrush"), _T("1")));
AntiAliasText = XmlUtils::GetInteger(oXmlNode.GetAttributeOrValue(_T("antialiastext"), _T("0")));
StringAlignmentVertical = XmlUtils::GetInteger(oXmlNode.GetAttributeOrValue(_T("stringalignmentvertical"), _T("0")));
StringAlignmentHorizontal = XmlUtils::GetInteger(oXmlNode.GetAttributeOrValue(_T("stringalignmenthorizontal"), _T("0")));
ImageAlphMode = XmlUtils::GetInteger(oXmlNode.GetAttributeOrValue(_T("imagealphmode"), _T("0")));
Update();
}
static StringAlignment GetAlignment(long val)
{
switch(val)
{
case 0:
return StringAlignmentNear;
case 1:
return StringAlignmentCenter;
case 2:
return StringAlignmentFar;
}
return StringAlignmentNear;
}
BOOL GetAntiAliasPen() const
{
return AntiAliasPen;
}
void SetAntiAliasPen(BOOL bAntiAliasPen)
{
AntiAliasPen = bAntiAliasPen;
}
BOOL GetAntiAliasBrush() const
{
return AntiAliasBrush;
}
void SetAntiAliasBrush(BOOL bAntiAliasBrush)
{
AntiAliasBrush = bAntiAliasBrush;
}
BOOL GetAntiAliasText() const
{
return AntiAliasText;
}
void SetAntiAliasText(BOOL bAntiAliasText)
{
AntiAliasText = bAntiAliasText;
}
long GetStringAlignmentVertical() const
{
return StringAlignmentVertical;
}
void SetStringAlignmentVertical(long nStringAlignmentVertical)
{
if (StringAlignmentVertical != nStringAlignmentVertical)
Clear();
StringAlignmentVertical = nStringAlignmentVertical;
}
long GetStringAlignmentHorizontal() const
{
return StringAlignmentHorizontal;
}
void SetStringAlignmentHorizontal(long nStringAlignmentHorizontal)
{
if (StringAlignmentHorizontal != nStringAlignmentHorizontal)
Clear();
StringAlignmentHorizontal = nStringAlignmentHorizontal;
}
long GetImageAlphaMode() const
{
return ImageAlphMode;
}
void SetImageAlphaMode(long nImageAlphaMode)
{
ImageAlphMode = nImageAlphaMode;
}
void FromFormat(const CFormat& oFormat)
{
SetAntiAliasPen(oFormat.GetAntiAliasPen());
SetAntiAliasBrush(oFormat.GetAntiAliasBrush());
SetAntiAliasText(oFormat.GetAntiAliasText());
SetStringAlignmentVertical(oFormat.GetStringAlignmentVertical());
SetStringAlignmentHorizontal(oFormat.GetStringAlignmentHorizontal());
SetImageAlphaMode(oFormat.GetImageAlphaMode());
}
public:
CFormat()
{
m_stringFormat = 0;
AntiAliasPen = TRUE;
AntiAliasBrush = TRUE;
AntiAliasText = TRUE;
StringAlignmentVertical = 0;
StringAlignmentHorizontal = 0;
ImageAlphMode = 0;
}
CFormat( const CFormat& other )
{
m_stringFormat = 0;
AntiAliasPen = other.AntiAliasPen;
AntiAliasBrush = other.AntiAliasBrush;
AntiAliasText = other.AntiAliasText;
StringAlignmentVertical = other.StringAlignmentVertical;
StringAlignmentHorizontal = other.StringAlignmentHorizontal;
ImageAlphMode = other.ImageAlphMode;
}
CFormat& operator=(const CFormat& other)
{
Clear();
AntiAliasPen = other.AntiAliasPen;
AntiAliasBrush = other.AntiAliasBrush;
AntiAliasText = other.AntiAliasText;
StringAlignmentVertical = other.StringAlignmentVertical;
StringAlignmentHorizontal = other.StringAlignmentHorizontal;
ImageAlphMode = other.ImageAlphMode;
return *this;
}
~CFormat()
{
Clear();
}
void Update()
{
Clear();
}
void Clear()
{
if (m_stringFormat)
{
delete m_stringFormat;
m_stringFormat = 0;
}
}
Gdiplus::StringFormat* GetStringFormat()
{
if (m_stringFormat)
return m_stringFormat;
StringFormat* pStringFormat = new StringFormat();
pStringFormat->SetAlignment(GetAlignment(StringAlignmentHorizontal));
pStringFormat->SetLineAlignment(GetAlignment(StringAlignmentVertical));
m_stringFormat = pStringFormat;
return m_stringFormat;
}
};
class CShadow
{
Gdiplus::Brush* m_brush;
public:
BOOL Visible;
double DistanceX;
double DistanceY;
double BlurSize;
long Color;
long Alpha;
public:
int GetSize()
{
return 3*sizeof(long) + 3*sizeof(double);
}
void Write(CStream& stream)
{
stream.WriteLong(Visible);
stream.WriteDouble(DistanceX);
stream.WriteDouble(DistanceY);
stream.WriteDouble(BlurSize);
stream.WriteLong(Color);
stream.WriteLong(Alpha);
}
void Read(CStream& stream)
{
Visible = stream.ReadLong();
DistanceX = stream.ReadDouble();
DistanceY = stream.ReadDouble();
BlurSize = stream.ReadDouble();
Color = stream.ReadLong();
Alpha = stream.ReadLong();
Update();
}
CString ToXmlString(CString strRootNodeName = _T("shadow"), BOOL bAttributed = FALSE)
{
XmlUtils::CXmlWriter oXmlWriter;
if (!bAttributed)
{
oXmlWriter.WriteNodeBegin(strRootNodeName);
oXmlWriter.WriteNode(_T("visible"), Visible);
oXmlWriter.WriteNode(_T("distancex"), DistanceX);
oXmlWriter.WriteNode(_T("distancey"), DistanceY);
oXmlWriter.WriteNode(_T("blursize"), BlurSize);
oXmlWriter.WriteNode(_T("color"), Color);
oXmlWriter.WriteNode(_T("alpha"), Alpha);
oXmlWriter.WriteNodeEnd(strRootNodeName);
}
else
{
oXmlWriter.WriteNodeBegin(strRootNodeName, TRUE);
ToXmlAttributes(oXmlWriter);
oXmlWriter.WriteNodeEnd(strRootNodeName, TRUE);
}
return oXmlWriter.GetXmlString();
}
void FromXmlString(CString strXml)
{
XmlUtils::CXmlReader oXmlReader;
oXmlReader.SetXmlString(strXml);
oXmlReader.ReadRootNode();
FromXmlAttributes(oXmlReader);
}
BOOL FromStream(Streams::IStream* pStream)
{
if (!pStream)
return FALSE;
try
{
Visible = pStream->ReadLong();
DistanceX = pStream->ReadDouble();
DistanceY = pStream->ReadDouble();
BlurSize = pStream->ReadDouble();
Color = pStream->ReadLong();
Alpha = pStream->ReadLong();
Update();
return TRUE;
}
catch (...)
{
}
return FALSE;
}
BOOL ToStream(Streams::IStream* pStream)
{
if (!pStream)
return FALSE;
try
{
pStream->WriteLong(Visible);
pStream->WriteDouble(DistanceX);
pStream->WriteDouble(DistanceY);
pStream->WriteDouble(BlurSize);
pStream->WriteLong(Color);
pStream->WriteLong(Alpha);
return TRUE;
}
catch (...)
{
}
return FALSE;
}
void ToXmlAttributes(XmlUtils::CXmlWriter& oXmlWriter)
{
oXmlWriter.WriteAttribute(_T("visible"), Visible);
oXmlWriter.WriteAttribute(_T("distancex"), DistanceX);
oXmlWriter.WriteAttribute(_T("distancey"), DistanceY);
oXmlWriter.WriteAttribute(_T("blursize"), BlurSize);
oXmlWriter.WriteAttribute(_T("color"), Color);
oXmlWriter.WriteAttribute(_T("alpha"), Alpha);
}
void FromXmlAttributes(XmlUtils::CXmlReader& oXmlReader)
{
Visible = XmlUtils::GetInteger(oXmlReader.ReadNodeAttributeOrValue(_T("visible"), _T("0")));
DistanceX = XmlUtils::GetDouble(oXmlReader.ReadNodeAttributeOrValue(_T("distancex"), _T("0")));
DistanceY = XmlUtils::GetDouble(oXmlReader.ReadNodeAttributeOrValue(_T("distancey"), _T("0")));
BlurSize = XmlUtils::GetDouble(oXmlReader.ReadNodeAttributeOrValue(_T("blursize"), _T("0")));
Color = XmlUtils::GetInteger(oXmlReader.ReadNodeAttributeOrValue(_T("color"), _T("0")));
Alpha = XmlUtils::GetInteger(oXmlReader.ReadNodeAttributeOrValue(_T("alpha"), _T("0")));
Update();
}
void FromXmlNode(XmlUtils::CXmlNode& oXmlNode)
{
Visible = XmlUtils::GetInteger(oXmlNode.GetAttributeOrValue(_T("visible"), _T("0")));
DistanceX = XmlUtils::GetDouble(oXmlNode.GetAttributeOrValue(_T("distancex"), _T("0")));
DistanceY = XmlUtils::GetDouble(oXmlNode.GetAttributeOrValue(_T("distancey"), _T("0")));
BlurSize = XmlUtils::GetDouble(oXmlNode.GetAttributeOrValue(_T("blursize"), _T("0")));
Color = XmlUtils::GetInteger(oXmlNode.GetAttributeOrValue(_T("color"), _T("0")));
Alpha = XmlUtils::GetInteger(oXmlNode.GetAttributeOrValue(_T("alpha"), _T("0")));
Update();
}
BOOL GetVisible() const
{
return Visible;
}
void SetVisible(BOOL bVisible)
{
Visible = bVisible;
}
double GetDistanceX() const
{
return DistanceX;
}
void SetDistanceX(double nDistanceX)
{
DistanceX = nDistanceX;
}
double GetDistanceY() const
{
return DistanceY;
}
void SetDistanceY(double nDistanceY)
{
DistanceY = nDistanceY;
}
double GetBlurSize() const
{
return BlurSize;
}
void SetBlurSize(double nBlurSize)
{
BlurSize = nBlurSize;
}
long GetColor() const
{
return Color;
}
void SetColor(long nColor)
{
if (Color != nColor)
Clear();
Color = nColor;
}
long GetAlpha() const
{
return Alpha;
}
void SetAlpha(long nAlpha)
{
if (Alpha != nAlpha)
Clear();
Alpha = nAlpha;
}
void FromShadow(const CShadow& oShadow)
{
SetVisible(oShadow.GetVisible());
SetDistanceX(oShadow.GetDistanceX());
SetDistanceY(oShadow.GetDistanceY());
SetBlurSize(oShadow.GetBlurSize());
SetColor(oShadow.GetColor());
SetAlpha(oShadow.GetAlpha());
}
void SetDefaultParams()
{
Visible = FALSE;
DistanceX = 15;
DistanceY = 15;
BlurSize = 0;
Color = 0;
Alpha = 120;
}
public:
CShadow()
{
m_brush = 0;
Visible = TRUE;
DistanceX = 15;
DistanceY = 15;
BlurSize = 0;
Color = 0;
Alpha = 120;
}
CShadow( const CShadow& other )
{
m_brush = NULL;
Visible = other.Visible;
DistanceX = other.DistanceX;
DistanceY = other.DistanceY;
BlurSize = other.BlurSize;
Color = other.Color;
Alpha = other.Alpha;
}
CShadow& operator=(const CShadow& shadow)
{
Clear();
FromShadow(shadow);
return *this;
}
~CShadow()
{
Clear();
}
void Update()
{
Clear();
}
void Clear()
{
if( m_brush )
{
delete m_brush;
m_brush = 0;
}
}
Gdiplus::Brush* GetBrush()
{
if (m_brush)
return m_brush;
Gdiplus::Color color((BYTE)Alpha, GetRValue(Color), GetGValue(Color), GetBValue(Color));
Gdiplus::Brush* pBrush = new SolidBrush(color);
m_brush = pBrush;
return m_brush;
}
void Draw(Graphics* Gr, Gdiplus::Font* font, StringFormat* format, BSTR Text, int len, RectF& rectDraw)
{
if (!Visible || !Gr)
return;
RectF shadowRect = rectDraw;
shadowRect.X += float(DistanceX);
shadowRect.Y += float(DistanceY);
if (BlurSize)
{
Gdiplus::Color color((BYTE)Alpha, GetRValue(Color), GetGValue(Color), GetBValue(Color));
SolidBrush solid(color);
RectF temp = shadowRect;
for(float i = (float)BlurSize + 1.0F; i >= 1.0F; i--)
{
int iAlpha = (int)((double)(Alpha/8./i/1.1));
solid.SetColor(Gdiplus::Color((BYTE)iAlpha, GetRValue(Color), GetGValue(Color), GetBValue(Color)));
DrawBlurString((int)i, Gr, font, format, &solid, Text, len, temp);
temp = shadowRect;
}
}
else
Gr->DrawString(Text, len, font, shadowRect, format, GetBrush());
}
void Draw(Graphics* Gr, Gdiplus::Font* font, StringFormat* format, BSTR Text, int len, RectF& rectDraw, BYTE alpha)
{
if (!Visible || !Gr)
return;
RectF shadowRect = rectDraw;
shadowRect.X += float(DistanceX);
shadowRect.Y += float(DistanceY);
Gdiplus::Color color((BYTE)(Alpha*alpha/255), GetRValue(Color), GetGValue(Color), GetBValue(Color));
SolidBrush solid(color);
if (BlurSize)
{
RectF temp = shadowRect;
int nBlurSize = int(BlurSize);
for(int i = 1; i <= nBlurSize + 1; i++)
{
int iAlpha = (int)((double)((Alpha*alpha/255.)/8/(i)/1.1));
solid.SetColor(Gdiplus::Color((BYTE)iAlpha, GetRValue(Color), GetGValue(Color), GetBValue(Color)));
DrawBlurString(i, Gr, font, format, &solid, Text, len, temp);
temp = shadowRect;
}
}
else
Gr->DrawString(Text, len, font, shadowRect, format, &solid);
}
};
class CEdgeText
{
Gdiplus::Brush* m_brush;
Gdiplus::Pen* m_pen;
double m_dTransparency;
public:
long Visible;
double Dist;
long Color;
long Alpha;
public:
int GetSize()
{
return 3*sizeof(long) + sizeof(double);
}
void Write(CStream& stream)
{
stream.WriteLong(Visible);
stream.WriteDouble(Dist);
stream.WriteLong(Color);
stream.WriteLong(Alpha);
}
void Read(CStream& stream)
{
Visible = stream.ReadLong();
Dist = stream.ReadDouble();
Color = stream.ReadLong();
Alpha = stream.ReadLong();
Update();
}
CString ToXmlString(CString strRootNodeName = _T("edgetext"), BOOL bAttributed = FALSE)
{
XmlUtils::CXmlWriter oXmlWriter;
if (!bAttributed)
{
oXmlWriter.WriteNodeBegin(strRootNodeName);
oXmlWriter.WriteNode(_T("visible"), Visible);
oXmlWriter.WriteNode(_T("dist"), Dist);
oXmlWriter.WriteNode(_T("color"), Color);
oXmlWriter.WriteNode(_T("alpha"), Alpha);
oXmlWriter.WriteNodeEnd(strRootNodeName);
}
else
{
oXmlWriter.WriteNodeBegin(strRootNodeName, TRUE);
ToXmlAttributes(oXmlWriter);
oXmlWriter.WriteNodeEnd(strRootNodeName, TRUE);
}
return oXmlWriter.GetXmlString();
}
void FromXmlString(CString strXml)
{
XmlUtils::CXmlReader oXmlReader;
oXmlReader.SetXmlString(strXml);
oXmlReader.ReadRootNode();
FromXmlAttributes(oXmlReader);
}
BOOL FromStream(Streams::IStream* pStream)
{
if (!pStream)
return FALSE;
try
{
Visible = pStream->ReadLong();
Dist = pStream->ReadDouble();
Color = pStream->ReadLong();
Alpha = pStream->ReadLong();
Update();
return TRUE;
}
catch (...)
{
}
return FALSE;
}
BOOL ToStream(Streams::IStream* pStream)
{
if (!pStream)
return FALSE;
try
{
pStream->WriteLong(Visible);
pStream->WriteDouble(Dist);
pStream->WriteLong(Color);
pStream->WriteLong(Alpha);
return TRUE;
}
catch (...)
{
}
return FALSE;
}
void ToXmlAttributes(XmlUtils::CXmlWriter& oXmlWriter)
{
oXmlWriter.WriteAttribute(_T("visible"), Visible);
oXmlWriter.WriteAttribute(_T("dist"), Dist);
oXmlWriter.WriteAttribute(_T("color"), Color);
oXmlWriter.WriteAttribute(_T("alpha"), Alpha);
}
void FromXmlAttributes(XmlUtils::CXmlReader& oXmlReader)
{
Visible = XmlUtils::GetInteger(oXmlReader.ReadNodeAttributeOrValue(_T("visible"), _T("0")));
Dist = XmlUtils::GetDouble(oXmlReader.ReadNodeAttributeOrValue(_T("dist"), _T("0")));
Color = XmlUtils::GetInteger(oXmlReader.ReadNodeAttributeOrValue(_T("color"), _T("0")));
Alpha = XmlUtils::GetInteger(oXmlReader.ReadNodeAttributeOrValue(_T("alpha"), _T("0")));
Update();
}
void FromXmlNode(XmlUtils::CXmlNode& oXmlNode)
{
Visible = XmlUtils::GetInteger(oXmlNode.GetAttributeOrValue(_T("visible"), _T("0")));
Dist = XmlUtils::GetDouble(oXmlNode.GetAttributeOrValue(_T("dist"), _T("0")));
Color = XmlUtils::GetInteger(oXmlNode.GetAttributeOrValue(_T("color"), _T("0")));
Alpha = XmlUtils::GetInteger(oXmlNode.GetAttributeOrValue(_T("alpha"), _T("0")));
Update();
}
long GetVisible() const
{
return Visible;
}
void SetVisible(long nVisible)
{
Visible = nVisible;
}
double GetDistance() const
{
return Dist;
}
void SetDistance(double nDistance)
{
Dist = nDistance;
}
long GetColor() const
{
return Color;
}
void SetColor(long nColor)
{
if (Color != nColor)
Clear();
Color = nColor;
}
long GetAlpha() const
{
return Alpha;
}
void SetAlpha(long nAlpha)
{
if (Alpha != nAlpha)
Clear();
Alpha = nAlpha;
}
void FromEdge(const CEdgeText& oEdge)
{
SetVisible(oEdge.GetVisible());
SetDistance(oEdge.GetDistance());
SetColor(oEdge.GetColor());
SetAlpha(oEdge.GetAlpha());
}
void SetDefaultParams()
{
Visible = 0;
Dist = 5;
Color = 0;
Alpha = 255;
}
public:
CEdgeText()
{
m_brush = 0;
m_pen = 0;
Visible = 0;
Dist = 5;
Color = 0;
Alpha = 255;
m_dTransparency = 1;
}
CEdgeText( const CEdgeText& other )
{
m_brush = 0;
m_pen = 0;
Visible = other.Visible;
Dist = other.Dist;
Color = other.Color;
Alpha = other.Alpha;
m_dTransparency = other.m_dTransparency;
}
CEdgeText& operator=(const CEdgeText& edge)
{
Clear();
FromEdge(edge);
return *this;
}
~CEdgeText()
{
Clear();
}
void Update()
{
Clear();
}
void Clear()
{
if (m_brush)
{
delete m_brush;
m_brush = 0;
}
if (m_pen)
{
delete m_pen;
m_pen = 0;
}
}
void SetTransparency( double dIntensity )
{
if( dIntensity > 1 ) dIntensity = 1;
if( dIntensity < 0 ) dIntensity = 0;
if( dIntensity != m_dTransparency )
{
int nOldAlpha = int(m_dTransparency * Alpha + 0.5);
int nNewAlpha = int(dIntensity * Alpha + 0.5);
if( nNewAlpha != nOldAlpha )
{
Update();
}
m_dTransparency = dIntensity;
}
}
double GetTransparency() const
{
return m_dTransparency;
}
Gdiplus::Brush* GetBrush()
{
if (m_brush)
return m_brush;
Gdiplus::Color color((BYTE)(Alpha * m_dTransparency + 0.5), GetRValue(Color), GetGValue(Color), GetBValue(Color));
Gdiplus::Brush* pBrush = new SolidBrush(color);
m_brush = pBrush;
return m_brush;
}
Gdiplus::Pen* GetPen()
{
if (m_pen)
return m_pen;
Gdiplus::Color color((BYTE)(Alpha * m_dTransparency + 0.5), GetRValue(Color), GetGValue(Color), GetBValue(Color));
Gdiplus::Pen* pPen = new Gdiplus::Pen( color, REAL(Dist) );
if( pPen )
{
pPen->SetLineJoin(LineJoinRound);
}
m_pen = pPen;
return pPen;
}
void Draw(Graphics* Gr, Gdiplus::Font* font, StringFormat* format, BSTR Text, int len, RectF& rectDraw)
{
if (!Visible || !Gr)
return;
if (Visible == -1)
{
Gdiplus::Color color((BYTE)(Alpha), GetRValue(Color), GetGValue(Color), GetBValue(Color));
SolidBrush solid(color);
RectF temp = rectDraw;
int offset = int(Dist);
for(int i = offset; i >= 1; i--)
{
int iAlpha = (int)((double)(Alpha/8/(i)/1.1));
solid.SetColor(Gdiplus::Color((BYTE)iAlpha, GetRValue(Color), GetGValue(Color), GetBValue(Color)));
DrawBlurString(i, Gr, font, format, &solid, Text, len, temp);
temp = rectDraw;
}
}
if (Visible == 1)
{
SmoothingMode oldSmoothingMode = Gr->GetSmoothingMode();
Gr->SetSmoothingMode(SmoothingModeHighQuality);
RectF temp = rectDraw;
FontFamily family; font->GetFamily(&family);
GraphicsPath path; path.AddString(Text, len, &family, font->GetStyle(), font->GetSize(), temp, format);
int offset = int(Dist);
for (int i = 1; i <= offset; i++)
{
Gdiplus::Pen pen(Gdiplus::Color((BYTE)(Alpha*i/offset), GetRValue(Color), GetGValue(Color), GetBValue(Color)), (REAL) 2*(offset - i + 1));
pen.SetLineCap(LineCapRound, LineCapRound, DashCapRound);
Gr->DrawPath(&pen, &path);
}
Gr->SetSmoothingMode(oldSmoothingMode);
}
if (Visible == 2)
{
GraphicsState state = Gr->Save();
Gr->SetSmoothingMode(SmoothingModeHighQuality);
Gr->SetClip(rectDraw);
RectF temp = rectDraw;
FontFamily family; font->GetFamily(&family);
GraphicsPath path; path.AddString(Text, len, &family, font->GetStyle(), font->GetSize(), temp, format);
int offset = int(Dist);
for (int i = 1; i <= offset; i++)
{
Gdiplus::Pen pen(Gdiplus::Color((BYTE)(Alpha*i/offset), GetRValue(Color), GetGValue(Color), GetBValue(Color)), (REAL) 2*(offset - i + 1));
pen.SetLineCap(LineCapRound, LineCapRound, DashCapRound);
Gr->DrawPath(&pen, &path);
}
Gr->Restore(state);
}
}
void Draw(Graphics* Gr, Gdiplus::Font* font, StringFormat* format, BSTR Text, int len, RectF& rectDraw, BYTE alpha)
{
if (!Visible || !Gr)
return;
if (Visible == -1)
{
Gdiplus::Color color((BYTE)((double)(Alpha*alpha/255.), GetRValue(Color), GetGValue(Color), GetBValue(Color)));
SolidBrush solid(color);
RectF temp = rectDraw;
for(int i = 1; i <= Dist; i++)
{
int iAlpha = (int)((double)(Alpha*alpha/255./8/(i)/1.1));
solid.SetColor(Gdiplus::Color((BYTE)iAlpha, GetRValue(Color), GetGValue(Color), GetBValue(Color)));
DrawBlurString(i, Gr, font, format, &solid, Text, len, temp);
temp = rectDraw;
}
}
if (Visible == 1)
{
SmoothingMode oldSmoothingMode = Gr->GetSmoothingMode();
Gr->SetSmoothingMode(SmoothingModeHighQuality);
FontFamily family; font->GetFamily(&family);
GraphicsPath path; path.AddString(Text, len, &family, font->GetStyle(), font->GetSize(), rectDraw, format);
int offset = int(Dist);
for (int i = 1; i <= offset; i++)
{
Gdiplus::Pen pen(Gdiplus::Color((BYTE)(Alpha*i*alpha/(offset*255)), GetRValue(Color), GetGValue(Color), GetBValue(Color)), (REAL) 2*(offset - i + 1));
pen.SetLineCap(LineCapRound, LineCapRound, DashCapRound);
Gr->DrawPath(&pen, &path);
}
Gr->SetSmoothingMode(oldSmoothingMode);
}
}
};
class CLine
{
public:
double X1;
double Y1;
double X2;
double Y2;
public:
int GetSize()
{
return 4*sizeof(double) + (4);
}
void Write(CStream& stream)
{
stream.WriteDouble(X1);
stream.WriteDouble(Y1);
stream.WriteDouble(X2);
stream.WriteDouble(Y2);
}
void Read(CStream& stream)
{
Clear();
X1 = stream.ReadDouble();
Y1 = stream.ReadDouble();
X2 = stream.ReadDouble();
Y2 = stream.ReadDouble();
}
CString ToXmlString(CString strRootNodeName = _T("line"), BOOL bAttributed = FALSE)
{
XmlUtils::CXmlWriter oXmlWriter;
if (!bAttributed)
{
oXmlWriter.WriteNodeBegin(strRootNodeName);
oXmlWriter.WriteNode(_T("x1"), X1);
oXmlWriter.WriteNode(_T("y1"), Y1);
oXmlWriter.WriteNode(_T("x2"), X2);
oXmlWriter.WriteNode(_T("y2"), Y2);
oXmlWriter.WriteNodeEnd(strRootNodeName);
}
else
{
oXmlWriter.WriteNodeBegin(strRootNodeName, TRUE);
oXmlWriter.WriteAttribute(_T("x1"), X1);
oXmlWriter.WriteAttribute(_T("y1"), Y1);
oXmlWriter.WriteAttribute(_T("x2"), X2);
oXmlWriter.WriteAttribute(_T("y2"), Y2);
oXmlWriter.WriteNodeEnd(strRootNodeName, TRUE);
}
return oXmlWriter.GetXmlString();
}
void FromXmlString(CString strXml)
{
Clear();
XmlUtils::CXmlReader oXmlReader;
oXmlReader.SetXmlString(strXml);
oXmlReader.ReadRootNode();
X1 = XmlUtils::GetDouble(oXmlReader.ReadNodeAttributeOrValue(_T("x1"), _T("0")));
Y1 = XmlUtils::GetDouble(oXmlReader.ReadNodeAttributeOrValue(_T("y1"), _T("0")));
X2 = XmlUtils::GetDouble(oXmlReader.ReadNodeAttributeOrValue(_T("x2"), _T("0")));
Y2 = XmlUtils::GetDouble(oXmlReader.ReadNodeAttributeOrValue(_T("y2"), _T("0")));
}
public:
CLine()
{
X1 = 0;
Y1 = 0;
X2 = 0;
Y2 = 0;
}
CLine& operator=(const CLine& line)
{
Clear();
X1 = line.X1;
Y1 = line.Y1;
X2 = line.X2;
Y2 = line.Y2;
return *this;
}
~CLine()
{
Clear();
}
void Clear()
{
X1 = 0;
Y1 = 0;
X2 = 0;
Y2 = 0;
}
};
class CRectangle
{
public:
double Left;
double Top;
double Width;
double Height;
public:
int GetSize()
{
return 4*sizeof(double) + (4);
}
void Write(CStream& stream)
{
stream.WriteDouble(Left);
stream.WriteDouble(Top);
stream.WriteDouble(Width);
stream.WriteDouble(Height);
}
void Read(CStream& stream)
{
Clear();
Left = stream.ReadDouble();
Top = stream.ReadDouble();
Width = stream.ReadDouble();
Height = stream.ReadDouble();
}
CString ToXmlString(CString strRootNodeName = _T("rectangle"), BOOL bAttributed = FALSE)
{
XmlUtils::CXmlWriter oXmlWriter;
if (!bAttributed)
{
oXmlWriter.WriteNodeBegin(strRootNodeName);
oXmlWriter.WriteNode(_T("left"), Left);
oXmlWriter.WriteNode(_T("top"), Top);
oXmlWriter.WriteNode(_T("width"), Width);
oXmlWriter.WriteNode(_T("height"), Height);
oXmlWriter.WriteNodeEnd(strRootNodeName);
}
else
{
oXmlWriter.WriteNodeBegin(strRootNodeName, TRUE);
oXmlWriter.WriteAttribute(_T("left"), Left);
oXmlWriter.WriteAttribute(_T("top"), Top);
oXmlWriter.WriteAttribute(_T("width"), Width);
oXmlWriter.WriteAttribute(_T("height"), Height);
oXmlWriter.WriteNodeEnd(strRootNodeName, TRUE);
}
return oXmlWriter.GetXmlString();
}
void FromXmlString(CString strXml)
{
Clear();
XmlUtils::CXmlReader oXmlReader;
oXmlReader.SetXmlString(strXml);
oXmlReader.ReadRootNode();
Left = XmlUtils::GetDouble(oXmlReader.ReadNodeAttributeOrValue(_T("left"), _T("0")));
Top = XmlUtils::GetDouble(oXmlReader.ReadNodeAttributeOrValue(_T("top"), _T("0")));
Width = XmlUtils::GetDouble(oXmlReader.ReadNodeAttributeOrValue(_T("width"), _T("0")));
Height = XmlUtils::GetDouble(oXmlReader.ReadNodeAttributeOrValue(_T("height"), _T("0")));
}
public:
CRectangle()
{
Left = 0;
Top = 0;
Width = 0;
Height = 0;
}
CRectangle& operator=(const CRectangle& rectangle)
{
Clear();
Left = rectangle.Left;
Top = rectangle.Top;
Width = rectangle.Width;
Height = rectangle.Height;
return *this;
}
~CRectangle()
{
Clear();
}
void Clear()
{
Left = 0;
Top = 0;
Width = 0;
Height = 0;
}
};
class CEllipse
{
public:
double Left;
double Top;
double Width;
double Height;
public:
int GetSize()
{
return 4*sizeof(double) + (4);
}
void Write(CStream& stream)
{
stream.WriteDouble(Left);
stream.WriteDouble(Top);
stream.WriteDouble(Width);
stream.WriteDouble(Height);
}
void Read(CStream& stream)
{
Clear();
Left = stream.ReadDouble();
Top = stream.ReadDouble();
Width = stream.ReadDouble();
Height = stream.ReadDouble();
}
CString ToXmlString(CString strRootNodeName = _T("ellipse"), BOOL bAttributed = FALSE)
{
XmlUtils::CXmlWriter oXmlWriter;
if (!bAttributed)
{
oXmlWriter.WriteNodeBegin(strRootNodeName);
oXmlWriter.WriteNode(_T("left"), Left);
oXmlWriter.WriteNode(_T("top"), Top);
oXmlWriter.WriteNode(_T("width"), Width);
oXmlWriter.WriteNode(_T("height"), Height);
oXmlWriter.WriteNodeEnd(strRootNodeName);
}
else
{
oXmlWriter.WriteNodeBegin(strRootNodeName, TRUE);
oXmlWriter.WriteAttribute(_T("left"), Left);
oXmlWriter.WriteAttribute(_T("top"), Top);
oXmlWriter.WriteAttribute(_T("width"), Width);
oXmlWriter.WriteAttribute(_T("height"), Height);
oXmlWriter.WriteNodeEnd(strRootNodeName, TRUE);
}
return oXmlWriter.GetXmlString();
}
void FromXmlString(CString strXml)
{
Clear();
XmlUtils::CXmlReader oXmlReader;
oXmlReader.SetXmlString(strXml);
oXmlReader.ReadRootNode();
Left = XmlUtils::GetDouble(oXmlReader.ReadNodeAttributeOrValue(_T("left"), _T("0")));
Top = XmlUtils::GetDouble(oXmlReader.ReadNodeAttributeOrValue(_T("top"), _T("0")));
Width = XmlUtils::GetDouble(oXmlReader.ReadNodeAttributeOrValue(_T("width"), _T("0")));
Height = XmlUtils::GetDouble(oXmlReader.ReadNodeAttributeOrValue(_T("height"), _T("0")));
}
public:
CEllipse()
{
Left = 0;
Top = 0;
Width = 0;
Height = 0;
}
CEllipse& operator=(const CEllipse& ellipse)
{
Clear();
Left = ellipse.Left;
Top = ellipse.Top;
Width = ellipse.Width;
Height = ellipse.Height;
return *this;
}
~CEllipse()
{
Clear();
}
void Clear()
{
Left = 0;
Top = 0;
Width = 0;
Height = 0;
}
};
class CText
{
public:
double Left;
double Top;
double Width;
double Height;
CString Text;
public:
int GetSize()
{
return 4*sizeof(double) + Text.GetLength() + 1 + (4);
}
void Write(CStream& stream)
{
stream.WriteDouble(Left);
stream.WriteDouble(Top);
stream.WriteDouble(Width);
stream.WriteDouble(Height);
stream.WriteString(Text);
}
void Read(CStream& stream)
{
Clear();
Left = stream.ReadDouble();
Top = stream.ReadDouble();
Width = stream.ReadDouble();
Height = stream.ReadDouble();
Text = stream.ReadString();
}
CString ToXmlString(CString strRootNodeName = _T("text"), BOOL bAttributed = FALSE)
{
XmlUtils::CXmlWriter oXmlWriter;
if (!bAttributed)
{
oXmlWriter.WriteNodeBegin(strRootNodeName);
oXmlWriter.WriteNode(_T("left"), Left);
oXmlWriter.WriteNode(_T("top"), Top);
oXmlWriter.WriteNode(_T("width"), Width);
oXmlWriter.WriteNode(_T("height"), Height);
oXmlWriter.WriteNode(_T("text"), Text);
oXmlWriter.WriteNodeEnd(strRootNodeName);
}
else
{
oXmlWriter.WriteNodeBegin(strRootNodeName, TRUE);
oXmlWriter.WriteAttribute(_T("left"), Left);
oXmlWriter.WriteAttribute(_T("top"), Top);
oXmlWriter.WriteAttribute(_T("width"), Width);
oXmlWriter.WriteAttribute(_T("height"), Height);
oXmlWriter.WriteAttribute(_T("text"), Text);
oXmlWriter.WriteNodeEnd(strRootNodeName, TRUE);
}
return oXmlWriter.GetXmlString();
}
void FromXmlString(CString strXml)
{
Clear();
XmlUtils::CXmlReader oXmlReader;
oXmlReader.SetXmlString(strXml);
oXmlReader.ReadRootNode();
Left = XmlUtils::GetDouble(oXmlReader.ReadNodeAttributeOrValue(_T("left"), _T("0")));
Top = XmlUtils::GetDouble(oXmlReader.ReadNodeAttributeOrValue(_T("top"), _T("0")));
Width = XmlUtils::GetDouble(oXmlReader.ReadNodeAttributeOrValue(_T("width"), _T("0")));
Height = XmlUtils::GetDouble(oXmlReader.ReadNodeAttributeOrValue(_T("height"), _T("0")));
Text = oXmlReader.ReadNodeAttributeOrValue(_T("text"), _T(""));
}
public:
CText()
{
Left = 0;
Top = 0;
Width = 0;
Height = 0;
Text = "";
}
CText& operator=(const CText& text)
{
Clear();
Left = text.Left;
Top = text.Top;
Width = text.Width;
Height = text.Height;
Text = text.Text;
return *this;
}
~CText()
{
Clear();
}
void Clear()
{
Left = 0;
Top = 0;
Width = 0;
Height = 0;
Text = "";
}
};
class CTransformCrop
{
public:
BOOL ClearBackground;
double Left;
double Top;
double Width;
double Height;
public:
int GetSize()
{
return 4*sizeof(double) + sizeof(long) + (4);
}
void Write(CStream& stream)
{
stream.WriteLong(ClearBackground);
stream.WriteDouble(Left);
stream.WriteDouble(Top);
stream.WriteDouble(Width);
stream.WriteDouble(Height);
}
void Read(CStream& stream)
{
Clear();
ClearBackground = stream.ReadLong();
Left = stream.ReadDouble();
Top = stream.ReadDouble();
Width = stream.ReadDouble();
Height = stream.ReadDouble();
}
CString ToXmlString(CString strRootNodeName = _T("transform-crop"), BOOL bAttributed = FALSE)
{
XmlUtils::CXmlWriter oXmlWriter;
if (!bAttributed)
{
oXmlWriter.WriteNodeBegin(strRootNodeName);
oXmlWriter.WriteNode(_T("clear"), ClearBackground);
oXmlWriter.WriteNode(_T("left"), Left);
oXmlWriter.WriteNode(_T("top"), Top);
oXmlWriter.WriteNode(_T("width"), Width);
oXmlWriter.WriteNode(_T("height"), Height);
oXmlWriter.WriteNodeEnd(strRootNodeName);
}
else
{
oXmlWriter.WriteNodeBegin(strRootNodeName, TRUE);
oXmlWriter.WriteAttribute(_T("clear"), ClearBackground);
oXmlWriter.WriteAttribute(_T("left"), Left);
oXmlWriter.WriteAttribute(_T("top"), Top);
oXmlWriter.WriteAttribute(_T("width"), Width);
oXmlWriter.WriteAttribute(_T("height"), Height);
oXmlWriter.WriteNodeEnd(strRootNodeName, TRUE);
}
return oXmlWriter.GetXmlString();
}
void FromXmlString(CString strXml)
{
Clear();
XmlUtils::CXmlReader oXmlReader;
oXmlReader.SetXmlString(strXml);
oXmlReader.ReadRootNode();
ClearBackground = XmlUtils::GetInteger(oXmlReader.ReadNodeAttributeOrValue(_T("clear"), _T("0")));
Left = XmlUtils::GetDouble(oXmlReader.ReadNodeAttributeOrValue(_T("left"), _T("0")));
Top = XmlUtils::GetDouble(oXmlReader.ReadNodeAttributeOrValue(_T("top"), _T("0")));
Width = XmlUtils::GetDouble(oXmlReader.ReadNodeAttributeOrValue(_T("width"), _T("0")));
Height = XmlUtils::GetDouble(oXmlReader.ReadNodeAttributeOrValue(_T("height"), _T("0")));
}
public:
CTransformCrop()
{
ClearBackground = 1;
Left = 0;
Top = 0;
Width = 0;
Height = 0;
}
CTransformCrop& operator=(const CTransformCrop& transform)
{
Clear();
ClearBackground = transform.ClearBackground;
Left = transform.Left;
Top = transform.Top;
Width = transform.Width;
Height = transform.Height;
return *this;
}
~CTransformCrop()
{
Clear();
}
void Clear()
{
ClearBackground = 1;
Left = 0;
Top = 0;
Width = 0;
Height = 0;
}
};
}