📄 cfont.cpp
字号:
//带字体显示文字
//原代码来自 金点时空 的 圣剑英雄传 翻外篇 原代码
//加入带颜色的动态文字显示
#include "CFont.h"
#include "CAlpha.h"
#include "CDraw.h"
#include "Ddutil.h"
DWORD CFont::DELAYTICK[10]; //文字出现的延时
#define _DELETE(X) { if( (X) != NULL ) { delete (X); (X) = NULL; } }
#define _FREE(X) { if( (X) != NULL ) { free(X); (X)=NULL; } }
CFont::CFont()
{
font_Size=14; //大小
font_Family="宋体"; //字体
font_Color=RGB(255,255,255);
font_BK=TRANSPARENT; //字的背景是否镂空
font_BKColor=RGB(255,255,255); //背景色
font_Width=70; //一行的文字数 中文=width/2
font_LineHeight=20; //行间距
bChangeColor=true;
DelayTick=30;
if( font_Font != NULL ) DeleteObject( font_Font );
font_Font=CreateFont(font_Size,0,0,0,font_Weight,FALSE,FALSE,0,GB2312_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,
DEFAULT_PITCH|FF_SWISS,font_Family);
font_Color=RGB(255,255,255);
}
void CFont::SetFont(int FontSize,char *FontType)
{
font_Size=FontSize; //大小
font_Family=FontType; //字体
font_Color=RGB(255,255,255);
font_BK=TRANSPARENT; //字的背景是否镂空
font_BKColor=RGB(255,255,255); //背景色
font_Width=70; //一行的文字数 中文=width/2
font_LineHeight=20; //行间距
bChangeColor=true;
DelayTick=30;
if( font_Font != NULL ) DeleteObject( font_Font );
font_Font = CreateFont( FontSize, // 字符高度(逻辑单位)
0, // 字符宽度(逻辑单位) 0为自动匹配
0, // 字符行角度
0, // 字符基线角度
font_Weight, // 0--1000 字体浓暗程度, 400为正常, 700为粗体
FALSE, // 是否为斜体字
FALSE, // 是否加下划线
0, // 是否加中划线
GB2312_CHARSET, // 指定字符集
OUT_DEFAULT_PRECIS, // 指定输出精度
CLIP_DEFAULT_PRECIS, // 指定剪切精度
DEFAULT_QUALITY, // 指定输出质量
DEFAULT_PITCH|FF_SWISS, // 指定间距, 字体族
FontType // 字体名
);
}
void CFont::GetFont(int &FontSize,char *&FontType)
{
FontSize=font_Size; //大小
FontType=font_Family; //字体
}
//*****************
//设置颜色
void CFont::SetColor(COLORREF color)
{
font_Color=color;
}
//******************
//获取颜色
DWORD CFont::GetColor()
{
return font_Color;
}
//恢复缺省字体
void CFont::Restore_Default_Font()
{
font_BK=TRANSPARENT; //字的背景是否镂空
font_BKColor=RGB(255,255,255); //背景色
font_Width=80; //一行的文字数 中文=width/2
font_LineHeight=20; //行间距
}
//设置字的背景是否镂空
void CFont::SetBK(bool c)
{
if( c )
font_BK=TRANSPARENT;
else
font_BK=OPAQUE;
}
//设置一个字符串中间是否可以变色
void CFont::SetChangeColor(bool c)
{
bChangeColor=c;
}
//*********************************
//文字显示
void CFont::PrintText(LPDIRECTDRAWSURFACE7 Surf,int x,int y,char *Text,...)
{
char *str;
str=new char[strlen(Text)+256];
char *BackStr=str; //备份指针,等到free使用
va_list va;
va_start(va,Text);
vsprintf(str,Text,va);
va_end(va);
if( str=="" )
{
if (BackStr!=NULL) delete[]BackStr;BackStr=NULL;
return;
}
//获取GDI表面
HDC hdc;
Surf->GetDC(&hdc);
SetBkMode(hdc, font_BK);
SetBkColor(hdc, font_BKColor);
SetTextColor(hdc, font_Color);
SelectObject(hdc,font_Font);
int StrLen, CurLen, LeftLen;
int ascii=0, Chars=0;
int showx=x; //文字显示位置
char Tmp[256];
StrLen=int(strlen(str));
while( str < BackStr + StrLen )
{
ascii=0;
Chars=0;
showx=x;
ZeroMemory(Tmp,256); //清零
//计算本行的字符数
LeftLen=int(StrLen-(str-BackStr)); //剩余的字符长度
if( LeftLen > font_Width )
CurLen=font_Width;
else
CurLen=LeftLen;
while( Chars < CurLen&&*str )
{
//特殊功能
if( *str=='<' )
{
//设置字体颜色
if( *(str+1)=='c' && *(str+3)=='>' ) //<c1>等等,设置颜色功能
{
if( bChangeColor ) //允许彩色显示
{
TextOut(hdc, showx, y, Tmp, int(strlen(Tmp))); //显示前面的部分
SetTextColor(hdc, font_Color); //设置颜色
showx+=int(strlen(Tmp))*(font_Size+font_Exp)/2; //接着显示的位置
CurLen-=int(strlen(Tmp)); //本行剩下的长度
ZeroMemory(Tmp,256); //清零
Chars=0; //位置复位
}
str+=4; //跳过控制字符
continue; //接着显示后面的内容
}
//恢复字体颜色
if( *(str+1)=='/' && *(str+2)=='c' && *(str+3)=='>' ) //恢复颜色
{
if( bChangeColor ) //能够改变颜色
{
TextOut(hdc, showx, y, Tmp, int(strlen(Tmp))); //显示
SetTextColor(hdc, font_Color); //设置颜色
showx+=int(strlen(Tmp))*(font_Size+font_Exp)/2;
CurLen-=int(strlen(Tmp));
ZeroMemory(Tmp,256); //清零
Chars=0;
}
str+=4;
continue;
}
//设置延时
if( *(str+1)=='d' && *(str+3)=='>' ) //<d>延时功能
{
DelayTick=DELAYTICK[*(str+2)-'0']; //查表得到延时长短
str+=4; //跳过
continue;
}
//恢复原来的速度
if( *(str+1)=='/' && *(str+2)=='d' && *(str+3)=='>' )
{
DelayTick=DELAYTICK[3];
str+=4;
continue;
}
//换行
if( *(str+1)=='/' && *(str+2)=='n' && *(str+3)=='>' )
{
str+=4;
goto _Show;
}
}
Tmp[Chars]=*str; //正常字符,直接copy
str++;
Chars++;
//计算英文字符数量(0=双数 1=单数)
if( (unsigned char)Tmp[Chars-1]<128 ) //同样的中英文处理
ascii=1-ascii;
}
//如果最后半个是汉字
if( ascii==1 && str < BackStr + StrLen )
{
str--; //留到下一行
Tmp[Chars-1]=0;
}
_Show:
TextOut(hdc, showx, y, Tmp, int(strlen(Tmp)));
y+=font_LineHeight; //下一行的y坐标
}
Surf->ReleaseDC(hdc);
if (BackStr!=NULL) delete[]BackStr;BackStr=NULL;
}
//*********************************
//Alpha文字显示
void CFont::PrintAlphaText(LPDIRECTDRAWSURFACE7 Surf, int x, int y, int alpha, char *Text,...)
{
va_list va;
char *str;
str=new char[strlen(Text)+256]; //预先留下256个char的空间
char *Str=str; //保存该指针到以后的free用
va_start(va,Text);
vsprintf(str,Text,va); //放到str中
va_end(va);
HDC hdc;
int ChrLen;
int ascii=0;
char Tmp[256];
if( str[0]==0 )
{
if (Str!=NULL) delete[]Str;Str=NULL;
return;
}
//临时页面
RECT rect={0,0,font_Width*font_Size , font_Size};
LPDIRECTDRAWSURFACE7 TempSurface;
if (CreateSurface(TempSurface, NULL,rect.right , rect.bottom)!=true) return;//建立页面错误
DDCOLORKEY ddck;
Surf->GetColorKey(NULL,&ddck); //获取颜色键
DDSetColorKey(TempSurface, ddck.dwColorSpaceHighValue);
Clrscr(TempSurface, RGB16(ddck.dwColorSpaceHighValue));
//获取GDI表面
TempSurface->GetDC(&hdc);
SetBkMode(hdc, font_BK);
SetBkColor(hdc, font_BKColor);
SetTextColor(hdc, font_Color);
SelectObject(hdc,font_Font);
ChrLen=int(strlen(str))+1;
for(int i=0; i<=ChrLen/font_Width; i++ ) //分行处理
{
ascii=0;
ZeroMemory(Tmp,256); //清0
//如果不是最后一行,就用一行做长度,否则是剩余的长度
int Chr=((i==ChrLen/font_Width)?ChrLen%font_Width:font_Width);
for(int j=0; j<Chr; j++)
{
Tmp[j]=*str;
str++;
//计算英文数量(0=双数 1=单数)
if( (unsigned char)Tmp[j]<128 ) //汉字的显示,全是大于128的
ascii=1-ascii; //说明是个英文,记数
if( *str=='<' && *(str+1)=='C' && *(str+2)=='R' && *(str+3)=='>' )
{
str=str+4; //〈CR〉是换行
i--;
goto _Show;
}
}
//如果最后半个是汉字:要是英文的数目是单数的话,必然会单出一个来
if( ascii==1 )
{
str--; //留到下一行
}
_Show: TextOut(hdc, 0, 0, Tmp, int(strlen(Tmp))); //显示到临时页面
TempSurface->ReleaseDC(hdc);
AlphaSRP(Surf, x, y, TempSurface, rect,alpha,RGB16(ddck.dwColorSpaceHighValue)); //AlphaBlt
y+=font_LineHeight; //显示下一行文字的y坐标
Clrscr(TempSurface, RGB16(ddck.dwColorSpaceHighValue)); //清除页面
//重新获取GDI表面
TempSurface->GetDC(&hdc);
SetBkMode(hdc, font_BK);
SetBkColor(hdc, font_BKColor);
SetTextColor(hdc, font_Color);
SelectObject(hdc,font_Font);
}
TempSurface->ReleaseDC(hdc);
if (TempSurface!=NULL) {TempSurface->Release();TempSurface=NULL;} //清除类
if (Str!=NULL) delete[]Str;Str=NULL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -