首页 技术 正文
技术 2022年11月15日
0 收藏 663 点赞 3,249 浏览 10797 个字

由于SOUI是一种双渲染引擎的DUI库,默认在SKIA渲染引擎下是支持特效字体的,具体请参考DEMO中的源码。

但是使用GDI+渲染时是没有这些特效的,着实比较苦恼,此代抛砖引玉,细节实现 请自己再去封装,此处只封装了STATIC控件。

部分效果使用了库:TextDesigner

CodeProject: http://www.codeproject.com/Articles/42529/Outline-Text

此代码有一个小BUG,在使用SOUI布局时,POS必须4个参数都指定,类似如此:pos=”15,20,-15,@25″

有兴趣的朋友可以自己实现一下。

先看下预览效果

[原创]SOUI GDI+渲染引擎下的字体特效,抛砖引玉

我只实现了部分效果,由于效果组合太多,所以这里暂时把我常用的先贴出来。

参数说明:

drawMode: 1为描边 2阴影 3外发光 4双描边,具体特效请自己设置颜色和渲染效果

EffectColor: 特效的颜色数值

EffectColor2: 使用双效果时的第二个数值颜色

底层使用GDI+所以默认支持多行,但是请根据多行来设置对应的高宽,否则显示肯定错误。

头文件:

 /*!
* \file SEffectStatic.h
* \date 2016/02/15 19:51
*
* \author koangel
* Contact: jackliu100@gmail.com
* blog: http://www.cnblogs.com/koangel/
*
* \brief GDI渲染模式下专用静态特效渲染库
*
* \note GDI+渲染模式下专用,如果在SKIA模式下,直接切换为标准SSTAIC模式渲染
* 效果使用GDI编写,暂不支持SKIA
* 部分效果使用TextDesigner库编写。
* CodeProject: http://www.codeproject.com/Articles/42529/Outline-Text
* TextDesigner版权归原作者所有。
*/
#pragma once
#include <gdiplus.h> #pragma comment(lib,"gdiplus.lib") class SEffectStatic : public SStatic
{
SOUI_CLASS_NAME(SStatic, L"eff_text")
public:
SEffectStatic();
virtual ~SEffectStatic();
/**
* SStatic::SDrawText
* @brief 绘制文本
* @param IRenderTarget *pRT -- 绘制设备句柄
* @param LPCTSTR pszBuf -- 文本内容字符串
* @param int cchText -- 字符串长度
* @param LPRECT pRect -- 指向矩形结构RECT的指针
* @param UINT uFormat -- 正文的绘制选项
*
* Describe 对DrawText封装
*/
virtual void DrawText(IRenderTarget *pRT, LPCTSTR pszBuf, int cchText, LPRECT pRect, UINT uFormat); protected: void DrawMultiLine(IRenderTarget *pRT, LPCTSTR pszBuf, int cchText, LPRECT pRect, UINT uFormat);
void DrawShadowMultiLine(IRenderTarget *pRT, LPCTSTR pszBuf, int cchText, LPRECT pRect, UINT uFormat); // 渲染带阴影的字体
void DrawShadowText(IRenderTarget *pRT, LPCTSTR pszBuf, int cchText, LPRECT pRect, UINT uFormat);
void DrawStrokeText(IRenderTarget *pRT, LPCTSTR pszBuf, int cchText, LPRECT pRect, UINT uFormat);
void DrawDoubleStrokeText(IRenderTarget *pRT, LPCTSTR pszBuf, int cchText, LPRECT pRect, UINT uFormat);
void DrawGowText(IRenderTarget *pRT, LPCTSTR pszBuf, int cchText, LPRECT pRect, UINT uFormat); void initGDIFont(IRenderTarget *pRT,Gdiplus::Font& gf); LOGFONT* GetGDIFont(IRenderTarget *pRT);
Gdiplus::StringFormat* toFormat(UINT uFormat); int m_nEffectDrawMode; /**< 渲染模式 */
COLORREF m_nEffectColor; /**< 效果颜色 */
COLORREF m_nEffectColor2; /**< 效果颜色 */
WORD m_StrokeSize; /**< 描边大小 */ SOUI_ATTRS_BEGIN()
ATTR_INT(L"drawMode", m_nEffectDrawMode, FALSE)
ATTR_COLOR(L"effectColor", m_nEffectColor, FALSE)
ATTR_COLOR(L"effectColor2", m_nEffectColor2, FALSE)
ATTR_INT(L"strokeSize", m_StrokeSize, FALSE)
SOUI_ATTRS_END()
};

实现文件:

 /*!
* \file SEffectStatic.cpp
* \date 2016/02/16 13:00
*
* \author koangel
* Contact: jackliu100@gmail.com
*
* \brief 渲染对应的静态文本,多行文本渲染可能存在问题
*
* TODO: blog http://www.cnblogs.com/koangel/
*
* \note
*/
#include "stdafx.h"
#include "SEffectStatic.h"
enum DRAW_EFFECT_MODE
{
DRAW_TEXT_NORMAL = , // 默认渲染
DRAW_TEXT_STROKE, // 渲染 描边
DRAW_TEXT_SHADOW, // 渲染 阴影
DRAW_TEXT_GROW, // 渲染 外发光效果
DRAW_TEXT_DBSTROKE, // 渲染 双描边
}; #define GR(rgb) ((BYTE)(rgb))
#define GG(rgb) ((BYTE)(((WORD)(rgb)) >> 8))
#define GB(rgb) ((BYTE)((rgb)>>16)) // 默认调用之前的构造函数
SEffectStatic::SEffectStatic() : SStatic(),
m_nEffectColor(0xFFFFFF),
m_nEffectColor2(0xFF0080),
m_nEffectDrawMode(),
m_StrokeSize()
{
} SEffectStatic::~SEffectStatic()
{ } void SEffectStatic::DrawText(IRenderTarget *pRT, LPCTSTR pszBuf, int cchText, LPRECT pRect, UINT uFormat)
{
if (!m_bMultiLines)
{
switch (m_nEffectDrawMode)
{
case DRAW_TEXT_NORMAL:
__super::DrawText(pRT, pszBuf, cchText, pRect, uFormat);
break;
case DRAW_TEXT_STROKE:
DrawStrokeText(pRT, pszBuf, cchText, pRect, uFormat);
break;
case DRAW_TEXT_SHADOW:
DrawShadowText(pRT, pszBuf, cchText, pRect, uFormat);
break;
case DRAW_TEXT_GROW:
DrawGowText(pRT, pszBuf, cchText, pRect, uFormat);
break;
case DRAW_TEXT_DBSTROKE:
DrawDoubleStrokeText(pRT, pszBuf, cchText, pRect, uFormat);
break;
}
}
else
{
switch (m_nEffectDrawMode)
{
case DRAW_TEXT_NORMAL:
{
if (uFormat&(DT_VCENTER | DT_BOTTOM) && !(uFormat & DT_CALCRECT))
{
//static 多行控件支持垂直居中及底对齐
CRect rcText = *pRect;
DrawMultiLine(pRT, pszBuf, cchText, &rcText, uFormat | DT_CALCRECT);
CSize szTxt = rcText.Size();
rcText = *pRect;
switch (GetStyle().GetTextAlign()&(DT_VCENTER | DT_BOTTOM))
{
case DT_VCENTER:
rcText.DeflateRect(, (rcText.Height() - szTxt.cy) / );
break;
case DT_BOTTOM:
rcText.DeflateRect(, (rcText.Height() - szTxt.cy));
break;
}
DrawMultiLine(pRT, pszBuf, cchText, &rcText, uFormat);
}
else
{
DrawMultiLine(pRT, pszBuf, cchText, pRect, uFormat);
}
break;
}
case DRAW_TEXT_STROKE:
DrawStrokeText(pRT, pszBuf, cchText, pRect, uFormat);
break;
case DRAW_TEXT_SHADOW:
DrawShadowMultiLine(pRT, pszBuf, cchText, pRect, uFormat);
break;
case DRAW_TEXT_GROW:
DrawGowText(pRT, pszBuf, cchText, pRect, uFormat);
break;
case DRAW_TEXT_DBSTROKE:
DrawDoubleStrokeText(pRT, pszBuf, cchText, pRect, uFormat);
break;
}
}
} void SEffectStatic::DrawMultiLine(IRenderTarget *pRT, LPCTSTR pszBuf, int cchText, LPRECT pRect, UINT uFormat)
{
SIZE szChar;
int i = , nLine = ;
if (cchText == -) cchText = _tcslen(pszBuf);
LPCTSTR p1 = pszBuf;
POINT pt = { pRect->left,pRect->top };
pRT->MeasureText(_T("A"), , &szChar);
int nLineHei = szChar.cy;
int nRight = pRect->right;
pRect->right = pRect->left;
while (i<cchText)
{
LPTSTR p2 = CharNext(p1);
if (*p1 == _T('\\') && p2 && *p2 == _T('n'))
{
pt.y += nLineHei + m_nLineInter;
pt.x = pRect->left;
nLine++;
i += p2 - p1;
p1 = CharNext(p2);
i += p1 - p2;
continue;
}
pRT->MeasureText(p1, p2 - p1, &szChar);
if (pt.x + szChar.cx > nRight)
{
pt.y += nLineHei + m_nLineInter;
pt.x = pRect->left;
nLine++;
continue;
}
if (!(uFormat & DT_CALCRECT))
{
pRT->TextOut(pt.x, pt.y, p1, p2 - p1);
}
pt.x += szChar.cx;
if (pt.x > pRect->right && uFormat & DT_CALCRECT) pRect->right = pt.x;
i += p2 - p1;
p1 = p2;
}
if (uFormat & DT_CALCRECT)
{
pRect->bottom = pt.y + nLineHei;
}
} void SEffectStatic::DrawShadowMultiLine(IRenderTarget *pRT, LPCTSTR pszBuf, int cchText, LPRECT pRect, UINT uFormat)
{
COLORREF textColor = this->m_style.GetTextColor(); Gdiplus::StringFormat *strFmt = toFormat(uFormat); Gdiplus::Graphics gs(pRT->GetDC());
Gdiplus::Font gf(pRT->GetDC(), GetGDIFont(pRT)); gs.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
gs.SetTextRenderingHint(Gdiplus::TextRenderingHintAntiAliasGridFit);
gs.SetPixelOffsetMode(Gdiplus::PixelOffsetModeHighQuality); Gdiplus::Rect rectF(pRect->left, pRect->top, pRect->right - pRect->left, pRect->bottom - pRect->top); Gdiplus::FontFamily ffamliy;
gf.GetFamily(&ffamliy); Gdiplus::SolidBrush br1(Gdiplus::Color(, GR(textColor), GG(textColor), GB(textColor))); TextDesigner::OutlineText outtext;
outtext.EnableShadow(true);
outtext.TextNoOutline(br1);
outtext.Shadow(Gdiplus::Color(, GR(m_nEffectColor), GG(m_nEffectColor), GB(m_nEffectColor)), , Gdiplus::Point(,));
outtext.DrawString(&gs, &ffamliy, (Gdiplus::FontStyle) gf.GetStyle(), gf.GetSize(), pszBuf, rectF, strFmt);
} void SEffectStatic::DrawShadowText(IRenderTarget *pRT, LPCTSTR pszBuf, int cchText, LPRECT pRect, UINT uFormat)
{
COLORREF textColor = this->m_style.GetTextColor(); Gdiplus::StringFormat *strFmt = toFormat(uFormat);
Gdiplus::Graphics gs(pRT->GetDC());
Gdiplus::Font gf(pRT->GetDC(), GetGDIFont(pRT)); gs.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
gs.SetTextRenderingHint(Gdiplus::TextRenderingHintAntiAliasGridFit);
gs.SetPixelOffsetMode(Gdiplus::PixelOffsetModeHighQuality); Gdiplus::Rect rectF(pRect->left, pRect->top, pRect->right - pRect->left, pRect->bottom - pRect->top); Gdiplus::FontFamily ffamliy;
gf.GetFamily(&ffamliy); Gdiplus::SolidBrush br1(Gdiplus::Color(, GR(textColor), GG(textColor), GB(textColor))); TextDesigner::OutlineText outtext;
outtext.EnableShadow(true);
outtext.TextNoOutline(br1);
outtext.Shadow(Gdiplus::Color(, GR(m_nEffectColor), GG(m_nEffectColor), GB(m_nEffectColor)), , Gdiplus::Point(,));
outtext.DrawString(&gs, &ffamliy,(Gdiplus::FontStyle) gf.GetStyle(), gf.GetSize() , pszBuf, rectF, strFmt);
} void SEffectStatic::DrawStrokeText(IRenderTarget *pRT, LPCTSTR pszBuf, int cchText, LPRECT pRect, UINT uFormat)
{
COLORREF textColor = this->m_style.GetTextColor();
Gdiplus::Graphics gs(pRT->GetDC());
Gdiplus::Font gf(pRT->GetDC(), GetGDIFont(pRT));
Gdiplus::StringFormat *strFmt = toFormat(uFormat); gs.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
gs.SetTextRenderingHint(Gdiplus::TextRenderingHintAntiAliasGridFit);
gs.SetPixelOffsetMode(Gdiplus::PixelOffsetModeHighQuality); Gdiplus::RectF rectF(pRect->left, pRect->top, pRect->right - pRect->left, pRect->bottom - pRect->top); Gdiplus::SolidBrush br1(Gdiplus::Color(,GR(textColor), GG(textColor), GB(textColor)));
Gdiplus::SolidBrush br2(Gdiplus::Color(,GR(m_nEffectColor), GG(m_nEffectColor), GB(m_nEffectColor))); int nOffsetX[] = { ,,,,-,-,-, };
int nOffsetY[] = { -,,,,,,-,- }; for (int i = ; i < ;i++)
{
Gdiplus::RectF lRecf(rectF);
lRecf.Offset(nOffsetX[i], nOffsetY[i]);
gs.DrawString(pszBuf, cchText, &gf, lRecf, strFmt, &br2);
} gs.DrawString(pszBuf, cchText, &gf, rectF, toFormat(uFormat), &br1);
} void SEffectStatic::DrawDoubleStrokeText(IRenderTarget *pRT, LPCTSTR pszBuf, int cchText, LPRECT pRect, UINT uFormat)
{
COLORREF textColor = this->m_style.GetTextColor();
Gdiplus::StringFormat *strFmt = toFormat(uFormat);
Gdiplus::Graphics gs(pRT->GetDC());
Gdiplus::Font gf(pRT->GetDC(), GetGDIFont(pRT)); gs.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
gs.SetTextRenderingHint(Gdiplus::TextRenderingHintAntiAliasGridFit);
gs.SetPixelOffsetMode(Gdiplus::PixelOffsetModeHighQuality); Gdiplus::Rect rectF(pRect->left, pRect->top, pRect->right - pRect->left, pRect->bottom - pRect->top); Gdiplus::FontFamily ffamliy;
gf.GetFamily(&ffamliy); Gdiplus::SolidBrush br1(Gdiplus::Color(, GR(textColor), GG(textColor), GB(textColor))); TextDesigner::OutlineText outtext;
outtext.EnableShadow(false);
outtext.TextDblOutline(br1, Gdiplus::Color(, GR(m_nEffectColor), GG(m_nEffectColor), GB(m_nEffectColor)),
Gdiplus::Color(, GR(m_nEffectColor2), GG(m_nEffectColor2), GB(m_nEffectColor2)), ,);
outtext.DrawString(&gs, &ffamliy, (Gdiplus::FontStyle) gf.GetStyle(), gf.GetSize(), pszBuf, rectF, strFmt);
} void SEffectStatic::DrawGowText(IRenderTarget *pRT, LPCTSTR pszBuf, int cchText, LPRECT pRect, UINT uFormat)
{
COLORREF textColor = this->m_style.GetTextColor();
Gdiplus::StringFormat *strFmt = toFormat(uFormat);
Gdiplus::Graphics gs(pRT->GetDC());
Gdiplus::Font gf(pRT->GetDC(), GetGDIFont(pRT)); gs.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
gs.SetTextRenderingHint(Gdiplus::TextRenderingHintAntiAliasGridFit);
gs.SetPixelOffsetMode(Gdiplus::PixelOffsetModeHighQuality); Gdiplus::Rect rectF(pRect->left, pRect->top, pRect->right - pRect->left, pRect->bottom - pRect->top); Gdiplus::FontFamily ffamliy;
gf.GetFamily(&ffamliy); Gdiplus::SolidBrush br1(Gdiplus::Color(, GR(textColor), GG(textColor), GB(textColor))); TextDesigner::OutlineText outtext;
outtext.EnableShadow(false);
outtext.TextGlow(br1,Gdiplus::Color(, GR(m_nEffectColor), GG(m_nEffectColor), GB(m_nEffectColor)),);
outtext.DrawString(&gs, &ffamliy, (Gdiplus::FontStyle) gf.GetStyle(), gf.GetSize(), pszBuf, rectF, strFmt);
} LOGFONT* SEffectStatic::GetGDIFont(IRenderTarget *pRT)
{
SOUI::IFontPtr pFont = m_style.GetTextFont();
SOUI::IFontPtr pDFont = (SOUI::IFontPtr)pRT->GetCurrentObject(OT_FONT);
LOGFONT * logFont = NULL;
if (pFont == NULL)
logFont = (LOGFONT*)pDFont->LogFont();
else
logFont = (LOGFONT*)pFont->LogFont(); return logFont;
} Gdiplus::StringFormat* SEffectStatic::toFormat(UINT uFormat)
{
Gdiplus::StringFormat *strFmt = Gdiplus::StringFormat::GenericTypographic()->Clone(); if (uFormat&(DT_VCENTER | DT_BOTTOM))
{
strFmt->SetAlignment(Gdiplus::StringAlignmentCenter);
strFmt->SetLineAlignment(Gdiplus::StringAlignmentCenter);
}
else
{
strFmt->SetAlignment(Gdiplus::StringAlignmentNear);
strFmt->SetLineAlignment(Gdiplus::StringAlignmentNear);
} return strFmt;
}

以上代码抛砖引玉,希望各位发扬光大,多写一些组件库噢。

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,077
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,552
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,401
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,176
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,813
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,896