Files
core/ASCImageStudio3/ASCGraphics/Interfaces/StructuresGDI.h

523 lines
15 KiB
C++
Raw Blame History

#pragma once
#include "Gdiplus.h"
#include "..\Objects\Structures.h"
namespace NSStructuresGDI
{
inline void DrawBlurString(int currentBlurSize, Gdiplus::Graphics* Gr, Gdiplus::Font* font,
Gdiplus::StringFormat* format, Gdiplus::Brush* brush, BSTR Text, int len, Gdiplus::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);
}
}
class CPen : public NSStructures::CPen
{
public:
CPen() : NSStructures::CPen()
{
}
CPen( const CPen& other ) : NSStructures::CPen(other)
{
}
CPen& operator=(const CPen& other)
{
NSStructures::CPen::operator=(other);
return *this;
}
virtual ~CPen()
{
}
Gdiplus::Pen* GetPen()
{
Gdiplus::Color color((BYTE)Alpha, GetRValue(Color), GetGValue(Color), GetBValue(Color));
Gdiplus::Pen* pPen = new Gdiplus::Pen(color, (Gdiplus::REAL)Size);
pPen->SetDashStyle((Gdiplus::DashStyle)DashStyle);
pPen->SetStartCap((Gdiplus::LineCap)LineStartCap);
pPen->SetEndCap((Gdiplus::LineCap)LineEndCap);
pPen->SetLineJoin((Gdiplus::LineJoin)LineJoin);
if ((Count != 0) && (DashPattern != NULL))
{
Gdiplus::REAL* pPattern = new Gdiplus::REAL[Count];
for (long i = 0; i < Count; ++i)
{
pPattern[i] = (Gdiplus::REAL)DashPattern[i];
}
pPen->SetDashPattern(pPattern, Count);
RELEASEARRAYOBJECTS(pPattern);
}
pPen->SetDashOffset((float)DashOffset);
pPen->SetAlignment( (Gdiplus::PenAlignment)Align );
return pPen;
}
};
class CBrush : public NSStructures::CBrush
{
public:
CBrush() : NSStructures::CBrush()
{
}
CBrush( const CBrush& other ) : NSStructures::CBrush(other)
{
}
CBrush& operator=(const CBrush& other)
{
NSStructures::CBrush::operator=(other);
return *this;
}
virtual ~CBrush()
{
}
Gdiplus::Brush* GetBrush()
{
// create texture brush
if (c_BrushTypeTexture == Type || c_BrushTypePattern == Type)
{
Gdiplus::TextureBrush* brush = GetTextureBrush();
return brush;
}
// create hatch brush
else if (Type >= c_BrushTypeHatch1 && Type <= c_BrushTypeHatch53)
{
Gdiplus::Color color1((BYTE)Alpha1, GetRValue(Color1), GetGValue(Color1), GetBValue(Color1));
Gdiplus::Color color2((BYTE)Alpha2, GetRValue(Color2), GetGValue(Color2), GetBValue(Color2));
Gdiplus::HatchBrush* brush = new Gdiplus::HatchBrush((Gdiplus::HatchStyle)(Type - c_BrushTypeHatch1), color1, color2);
return brush;
}
// create gradient brush (Horizontal, Vertical, Diagonals)
else if (Type >= c_BrushTypeHorizontal && Type <= c_BrushTypeDiagonal2)
{
Gdiplus::LinearGradientBrush* brush = GetLinearGradientBrushHVD(Type - c_BrushTypeHorizontal);
return brush;
}
// create gradient brush (rect with center)
else if ((c_BrushTypeCenter == Type) || (c_BrushTypePathGradient1 == Type))
{
Gdiplus::PathGradientBrush* brush = GetPathGradientBrushCenter();
return brush;
}
// create path gradient brush 2 for letter
if (c_BrushTypePathGradient2 == Type)
{
Gdiplus::PathGradientBrush* brush = GetPathGradientBrush();
return brush;
}
// create gradient brush (Cylinder Horizontal, Cylinder Vertical)
else if (Type >= c_BrushTypeCylinderHor && Type <= c_BrushTypeCylinderVer)
{
Gdiplus::LinearGradientBrush* brush = GetLinearGradientBrushCHV(Type - c_BrushTypeCylinderHor);
return brush;
}
// create solid brush
// if (c_BrushTypeSolid == nBrushType)
Gdiplus::Color color((BYTE)Alpha1, GetRValue(Color1), GetGValue(Color1), GetBValue(Color1));
Gdiplus::SolidBrush* brush = new Gdiplus::SolidBrush(color);
return brush;
}
Gdiplus::ImageAttributes* GetImageAttributes( int nAlpha )
{
if( nAlpha < 0 || nAlpha >= 255 )
return NULL;
Gdiplus::REAL alph = (Gdiplus::REAL)(nAlpha / 255.0);
Gdiplus::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
};
Gdiplus::ImageAttributes* pImageAtt = new Gdiplus::ImageAttributes();
if( pImageAtt )
pImageAtt->SetColorMatrix(&colorMatrix, Gdiplus::ColorMatrixFlagsDefault, Gdiplus::ColorAdjustTypeBitmap);
return pImageAtt;
}
void SetTextureBrushTransform( Gdiplus::TextureBrush* pBrush )
{
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;
oBrushOffset.X = Rect.X;
oBrushOffset.Y = Rect.Y;
switch(TextureMode)
{
case c_BrushTextureModeStretch:
pBrush->ScaleTransform( Rect.Width / oImageRect.Width, Rect.Height / oImageRect.Height );
break;
case c_BrushTextureModeTileCenter:
oBrushOffset.X += (Rect.Width - oImageRect.Width)/2;
oBrushOffset.Y += (Rect.Height - oImageRect.Height)/2;
pBrush->SetWrapMode( Gdiplus::WrapModeTile );
break;
default:
pBrush->SetWrapMode( Gdiplus::WrapModeTile );
}
if( oBrushOffset.X != 0 || oBrushOffset.Y != 0)
{
pBrush->TranslateTransform( oBrushOffset.X, oBrushOffset.Y, Gdiplus::MatrixOrderAppend );
}
}
// create texture brush
Gdiplus::TextureBrush* GetTextureBrush()
{
// create texture brush with textureAlpha
Gdiplus::TextureBrush* pBrush = NULL;
BSTR bsPath = TexturePath.AllocSysString();
Gdiplus::Bitmap oTextureBitmap(bsPath);
SysFreeString(bsPath);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Gdiplus::ImageAttributes* pImageAttr = GetImageAttributes( Alpha1 );
pBrush = new Gdiplus::TextureBrush(&oTextureBitmap, Gdiplus::Rect(0, 0, oTextureBitmap.GetWidth(), oTextureBitmap.GetHeight()), pImageAttr);
RELEASEOBJECT(pImageAttr);
SetTextureBrushTransform( pBrush );
return pBrush;
}
// create gradient brush (Horizontal, Vertical, Diagonals)
Gdiplus::LinearGradientBrush* GetLinearGradientBrushHVD(int type)
{
Gdiplus::Color color1((BYTE)Alpha1, GetRValue(Color1), GetGValue(Color1), GetBValue(Color1));
Gdiplus::Color color2((BYTE)Alpha2, GetRValue(Color2), GetGValue(Color2), GetBValue(Color2));
Gdiplus::LinearGradientBrush* brush = new Gdiplus::LinearGradientBrush(Rect, color1, color2, (Gdiplus::LinearGradientMode)type);
if( brush )
{
brush->SetWrapMode( Gdiplus::WrapModeTileFlipXY );
}
// TODO: brush->SetGammaCorrection(TRUE);
return brush;
}
// create gradient brush (Cylinder Horizontal, Cylinder Vertical)
Gdiplus::LinearGradientBrush* GetLinearGradientBrushCHV(int type)
{
Gdiplus::Color color1((BYTE)Alpha1, GetRValue(Color1), GetGValue(Color1), GetBValue(Color1));
Gdiplus::Color color2((BYTE)Alpha2, 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(Rect, color1, color2, angle);
if( brush )
{
brush->SetBlendBellShape(0.70f);
brush->SetWrapMode( Gdiplus::WrapModeTileFlipXY );
}
return brush;
}
// create gradient brush (rect with center)
Gdiplus::PathGradientBrush* GetPathGradientBrushCenter()
{
Gdiplus::Color color1((BYTE)Alpha1, GetRValue(Color1), GetGValue(Color1), GetBValue(Color1));
Gdiplus::Color color2((BYTE)Alpha2, GetRValue(Color2), GetGValue(Color2), GetBValue(Color2));
Gdiplus::GraphicsPath path; path.AddRectangle(Rect);
Gdiplus::PathGradientBrush* brush = new Gdiplus::PathGradientBrush(&path);
if( brush )
{
Gdiplus::Color colors[] = {color1};
int count = 1;
brush->SetSurroundColors(colors, &count);
brush->SetCenterColor(color2);
brush->SetWrapMode( Gdiplus::WrapModeTileFlipXY );
// TODO: need add Center coordinate
}
return brush;
}
// create path gradient brush2 for letter
Gdiplus::PathGradientBrush* GetPathGradientBrush(int index = 1)
{
Gdiplus::Color color1((BYTE)Alpha1, GetRValue(Color1), GetGValue(Color1), GetBValue(Color1));
Gdiplus::Color color2((BYTE)Alpha2, GetRValue(Color2), GetGValue(Color2), GetBValue(Color2));
Gdiplus::GraphicsPath path; path.AddRectangle(Rect);
Gdiplus::PathGradientBrush* brush = new Gdiplus::PathGradientBrush(&path);
if( brush )
{
int colorsCount = 4;
Gdiplus::Color colors1[] = {color1, color2, color2, color1};
Gdiplus::Color colors2[] = {color2, color1, color1, color2};
Gdiplus::Color* pColors = (index % 2) ? colors2 : colors1;
Gdiplus::Color& oColor = (index % 2) ? color2 : color1;
brush->SetSurroundColors(pColors, &colorsCount);
brush->SetCenterColor(oColor);
brush->SetWrapMode( Gdiplus::WrapModeTileFlipXY );
}
return brush;
}
};
class CFont : public NSStructures::CFont
{
public:
CFont() : NSStructures::CFont()
{
}
CFont( const CFont& other ) : NSStructures::CFont(other)
{
}
CFont& operator=(const CFont& other)
{
NSStructures::CFont::operator=(other);
return *this;
}
virtual ~CFont()
{
}
Gdiplus::Font* GetFont(Gdiplus::Unit units = Gdiplus::UnitPixel)
{
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, (Gdiplus::REAL)Size, style, units);
SysFreeString(family);
return font;
}
Gdiplus::Font* GetFontBySize(double dSize, Gdiplus::Unit units = Gdiplus::UnitPixel)
{
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, (Gdiplus::REAL)dSize, style, units);
SysFreeString(family);
return font;
}
};
class CShadow : public NSStructures::CShadow
{
public:
CShadow() : NSStructures::CShadow()
{
}
CShadow( const CShadow& other ) : NSStructures::CShadow(other)
{
}
CShadow& operator=(const CShadow& other)
{
NSStructures::CShadow::operator=(other);
return *this;
}
virtual ~CShadow()
{
}
void Draw(Gdiplus::Graphics* Gr, Gdiplus::Font* font, Gdiplus::StringFormat* format, BSTR Text, int len, Gdiplus::RectF& rectDraw, BYTE alpha = 0xFF)
{
if (!Visible || !Gr)
return;
Gdiplus::RectF shadowRect = rectDraw;
shadowRect.X += float(DistanceX);
shadowRect.Y += float(DistanceY);
Gdiplus::Color color((BYTE)(Alpha*alpha/255), GetRValue(Color), GetGValue(Color), GetBValue(Color));
Gdiplus::SolidBrush solid(color);
if (BlurSize)
{
Gdiplus::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 CBackground : public NSStructures::CBackground
{
public:
CBackground() : NSStructures::CBackground()
{
}
CBackground( const CBackground& other ) : NSStructures::CBackground(other)
{
}
CBackground& operator=(const CBackground& other)
{
NSStructures::CBackground::operator=(other);
return *this;
}
virtual ~CBackground()
{
}
void Draw(Gdiplus::Graphics* Gr, Gdiplus::Font* font, Gdiplus::StringFormat* format, BSTR Text, int len, Gdiplus::RectF& rectDraw, BYTE alpha = 0xFF)
{
}
};
class CEdgeText : public NSStructures::CEdgeText
{
public:
CEdgeText() : NSStructures::CEdgeText()
{
}
CEdgeText( const CEdgeText& other ) : NSStructures::CEdgeText(other)
{
}
CEdgeText& operator=(const CEdgeText& other)
{
NSStructures::CEdgeText::operator=(other);
return *this;
}
virtual ~CEdgeText()
{
}
void Draw(Gdiplus::Graphics* Gr, Gdiplus::Font* font, Gdiplus::StringFormat* format, BSTR Text, int len, Gdiplus::RectF& rectDraw, BYTE alpha = 0xFF)
{
if (!Visible || !Gr)
return;
if (Visible == -1)
{
Gdiplus::Color color((BYTE)((double)(Alpha*alpha/255.), GetRValue(Color), GetGValue(Color), GetBValue(Color)));
Gdiplus::SolidBrush solid(color);
Gdiplus::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)
{
// save old smoothing mode and set high quality mode
Gdiplus::SmoothingMode oldSmoothingMode = Gr->GetSmoothingMode();
Gr->SetSmoothingMode(Gdiplus::SmoothingModeHighQuality);
// get glyphs path
Gdiplus::FontFamily family; font->GetFamily(&family);
Gdiplus::GraphicsPath path; path.AddString(Text, len, &family, font->GetStyle(), font->GetSize(), rectDraw, format);
// draw text
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)), (Gdiplus::REAL) 2*(offset - i + 1));
pen.SetLineCap(Gdiplus::LineCapRound, Gdiplus::LineCapRound, Gdiplus::DashCapRound);
Gr->DrawPath(&pen, &path);
}
// restore old smoothing mode
Gr->SetSmoothingMode(oldSmoothingMode);
}
}
};
}