www.gusucode.com > VC++游戏圣剑英雄传2双刃剑源程序+开发文档-源码程序 > VC++游戏圣剑英雄传2双刃剑源程序+开发文档-源码程序\code\source\GAMELIB\Gp_text.cpp

    //Download by http://www.NewXing.com
//********************************************
//	文字显示相关处理函数
//  softboy 创建于2000年1月25日
//********************************************
#include <windows.h>
#include <stdio.h>
#include <fstream.h>
#include <ddraw.h>
#include "ddutil.h"
#include "gp_init.h"
#include "gp_other.h"
#include "gp_iniset.h"
#include "gp_draw.h"
#include "gp_alpha.h"
#include "gp_text.h"

/*****************************************************************/
/*和文字相关变量
/*****************************************************************/

DWORD CGpFont::FONTCOLOR[10];	//10种系统设定的字体颜色
DWORD CGpFont::DELAYTICK[10];	//文字出现的延时

CGpFont::CGpFont(bool set)
{
	if( set )
	{
		FONTCOLOR[0]=RGB(0,0,0);		//颜色
		FONTCOLOR[1]=RGB(255,0,0);
		FONTCOLOR[2]=RGB(0,255,0);
		FONTCOLOR[3]=RGB(0,0,255);
		FONTCOLOR[4]=RGB(255,255,0);
		FONTCOLOR[5]=RGB(255,0,255);
		FONTCOLOR[6]=RGB(0,255,255);
		FONTCOLOR[7]=RGB(255,0,255);
		FONTCOLOR[8]=RGB(127,127,127);
		FONTCOLOR[9]=RGB(225,255,225);

		DELAYTICK[0]=0;					//延时
		DELAYTICK[1]=10;
		DELAYTICK[2]=20;
		DELAYTICK[3]=30;
		DELAYTICK[4]=50;
		DELAYTICK[5]=80;
		DELAYTICK[6]=100;
		DELAYTICK[7]=200;
		DELAYTICK[8]=500;
		DELAYTICK[9]=1000;
	}
}

CGpFont::~CGpFont()
{
	if(font_Font!=NULL)					//释放资源
		DeleteObject(font_Font);
}


//****初始化字体******
void CGpFont::InitFont(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 CGpFont::LoadFont(char *filename, char *index)
{
	//初始化字体
	CIniSet FontIni(filename);
	int size=FontIni.ReadInt(index, "font_Size");
	char *font=FontIni.ReadText(index, "font_Family");
	font_Weight=FontIni.ReadInt(index, "font_Weight");

	InitFont(size, font);
	if( font_Weight >= 700 ) font_Exp=1;
	else font_Exp=0;
	_FREE( font );
	
	font_LineHeight=FontIni.ReadInt(index,"font_LineHeight");
	font_Width=FontIni.ReadInt(index,"font_Width");
	
	char *Col=FontIni.ReadText(index, "font_Color");
	font_Color=RGB(FontIni.ReadInt(Col, "Red"), FontIni.ReadInt(Col, "Green"), FontIni.ReadInt(Col,"Blue"));
	_FREE( Col );
	
	char *BkCol=FontIni.ReadText(index, "font_BKColor");
	font_BKColor=RGB(FontIni.ReadInt(BkCol, "Red"), FontIni.ReadInt(BkCol, "Green"), FontIni.ReadInt(BkCol,"Blue"));
	_FREE( BkCol );

	if( FontIni.ReadInt(index, "font_BK") )
		font_BK=TRANSPARENT;	//字的背景是否镂空
	else
		font_BK=OPAQUE;
}

//*****************
//设置颜色
void CGpFont::SetColor(DWORD color)
{
	font_Color=color;
}

//******************
//获取颜色
DWORD CGpFont::GetColor()
{
	return font_Color;
}

//恢复缺省字体
void CGpFont::Restore_Default_Font()
{
	font_BK=TRANSPARENT;	//字的背景是否镂空
	font_BKColor=RGB(255,255,255);	//背景色
	font_Width=80;			//一行的文字数 中文=width/2
	font_LineHeight=20;		//行间距
}

//设置字的背景是否镂空
void CGpFont::SetBK(bool c)
{
	if( c )
		font_BK=TRANSPARENT;
	else
		font_BK=OPAQUE;
}

//设置一个字符串中间是否可以变色
void CGpFont::SetChangeColor(bool c)
{
	bChangeColor=c;
}

//*********************************
//Alpha文字显示
void CGpFont::PrintAlphaText(LPDIRECTDRAWSURFACE Surf, int x, int y, int alpha, char *Text,...)
{
	va_list va;
	char *str;
	str=(char *)malloc(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 ) 
	{
		_FREE(Str);
		return;
	}

	//临时页面
	RECT rect={0,0,font_Width*font_Size , font_Size};
	LPDIRECTDRAWSURFACE TempSurface;
	CreateBitmap(TempSurface, rect.right , rect.bottom);
	DDSetColorKey(TempSurface, ColorKey);
	FillSurface(TempSurface, ColorKey16);

	//获取GDI表面
	TempSurface->GetDC(&hdc);
	SetBkMode(hdc, font_BK);
	SetBkColor(hdc, font_BKColor);
	SetTextColor(hdc, font_Color);
	SelectObject(hdc,font_Font);

	ChrLen=strlen(str)+1;		

	for(int i=0; i<=ChrLen/font_Width; i++ )	//分行处理
	{
		ascii=0;
		memset(Tmp,0,256);
		//如果不是最后一行,就用一行做长度,否则是剩余的长度
		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, strlen(Tmp));		//显示到临时页面
		TempSurface->ReleaseDC(hdc);

		ABlt(Surf, x, y, TempSurface, rect, ColorKey16, alpha);		//AlphaBlt
		y+=font_LineHeight;							//显示下一行文字的y坐标

		FillSurface(TempSurface, ColorKey16);		//清除页面
		//重新获取GDI表面
		TempSurface->GetDC(&hdc);
		SetBkMode(hdc, font_BK);
		SetBkColor(hdc, font_BKColor);
		SetTextColor(hdc, font_Color);
		SelectObject(hdc,font_Font);
	}

	TempSurface->ReleaseDC(hdc);
	_RELEASE( TempSurface );
	_FREE(Str);
}

//*********************************
//文字显示
void CGpFont::PrintText(LPDIRECTDRAWSURFACE Surf,int x,int y,char *Text,...)
{
	char *str;
	str=(char *)malloc(strlen(Text)+256);
	char *BackStr=str;	//备份指针,等到free使用

	va_list va;
	va_start(va,Text);
	vsprintf(str,Text,va);
	va_end(va);

	if( str=="" ) 
	{
		_FREE(BackStr);
		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=strlen(str);
	while( str < BackStr + StrLen )
	{
		ascii=0;
		Chars=0;
		showx=x;
		memset(Tmp,0,256);

		//计算本行的字符数
		LeftLen=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, strlen(Tmp));	//显示前面的部分
						SetTextColor(hdc, FONTCOLOR[*(str+2)-'0'] );	//设置颜色
					
						showx+=strlen(Tmp)*(font_Size+font_Exp)/2;	//接着显示的位置
						CurLen-=strlen(Tmp);			//本行剩下的长度
						memset(Tmp,0,256);				//清0
						Chars=0;						//位置复位
					}
					
					str+=4;								//跳过控制字符
					continue;							//接着显示后面的内容
				}
				
				//恢复字体颜色
				if( *(str+1)=='/' && *(str+2)=='c' && *(str+3)=='>' )	//恢复颜色
				{
					if( bChangeColor )					//能够改变颜色
					{
						TextOut(hdc, showx, y, Tmp, strlen(Tmp));		//显示
						SetTextColor(hdc, font_Color);					//设置颜色

						showx+=strlen(Tmp)*(font_Size+font_Exp)/2;			
						CurLen-=strlen(Tmp);
						memset(Tmp,0,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, strlen(Tmp));
		y+=font_LineHeight;			//下一行的y坐标
	}

	Surf->ReleaseDC(hdc);
	_FREE( BackStr );
}
// 字体信息
void CGpFont::GetFontInfo(LPDIRECTDRAWSURFACE surf, TEXTMETRIC *tm)
{
	HDC hdc;
	surf->GetDC(&hdc);
	GetTextMetrics(hdc,tm);
	surf->ReleaseDC(hdc);
}