转自:http://blog.csdn.net/showlong/article/details/1675145
HGE是不款不错的2D引擎渲染引擎...为什么这样说呢...
HGE目前没有物理,不过官方已经公布下一个版本将会有物理引擎进入.
因此该版本将会是一个非常好的2D引擎代表作..期待ing...
不过HGE是不支持中文的...这的确比较麻烦...
有没有解决办法呢?
答案是肯定的...
下面我就有来讲讲怎么让HGE支持中文...
我们先来搞定中文的显示,.再来搞定中文的输入.(输入将在下一篇文章上讲到)
先把我将"微妙的平衡"的一份代码弄下来改了一下.
hgefontc.h文件如下:
/*
*****************************************************
原作者:微妙的平衡
修改者:sf.tk
修改日期:2007-06-28
修改者 :Showlong
修改内容:去掉format的bug.
不需要处理多张字符纹理.
修改数据类型的不平衡.
修正SetBlendMode函数内部错误
填加获取串指定个数的长度
填加渲染长度截取
*************************************************** */
#pragma once
#include " hge.h "
#include " hgesprite.h "
#include < iostream >
class hgeFontCN
{
enum FONTCN_DATA
{
VALUE_FIX = 1 ,
HZ_H_MAX = 87 + VALUE_FIX, // 0xA1~0xF7 汉字编码范围高位(+1是给普通字母与标点符号留位置)
HZ_W_MAX = 95 , // 0xA0~0xFE 汉字编码范围底位
HZ_H_FIX = 0xA1 ,
HZ_W_FIX = 0xA0 ,
HZ_H_END = 0xF7 ,
HZ_W_END = 0xFE ,
ASCII_FIX = 0x20 ,
ASCII_END = 0x7f ,
ASCII_W = 6
};
struct FontCN_Head
{
char strHead[ 32 ];
char ImgFileNum; // 字模文件数
char firstImgFileName[ 40 ]; // 第一个字模文件名
DWORD dwStringCol;
DWORD dwStringRow;
DWORD dwFontWidth;
DWORD dwFontHeight;
public :
void SetData( char * head, char num, const char * firstImg, DWORD nCol, DWORD nRow, DWORD nFWidth, DWORD nFHeight);
};
struct FontCN_Frame
{
BYTE HZ[ 2 ];
BYTE fileIdx; // 所属的字模文件
WORD dwFontX;
WORD dwFontY;
public :
void SetData(BYTE h, BYTE l, BYTE idx, WORD fx, WORD fy);
};
public :
hgeFontCN( const char * filename); // 根据字体文件创建
~ hgeFontCN( void );
void Render( float x, float y, const char * string , int cutlen = 0 ); // 绘制字符串
void printf( float x, float y, const char * format, ...); // 绘制格式字符串
void SetColor(DWORD col){m_allSprite -> SetColor(col);} // 设置字体颜色
void SetZ( float z){m_allSprite -> SetZ(z);} // 设置Z缓冲
void SetBlendMode( int blend){m_allSprite -> SetBlendMode(blend);} // 设置混和模式
void SetScale( float scale) {fScale = scale;} // 设置比例
void SetRotation( float rot) {fRot = rot;} // 设置旋转角度
void SetTracking( float tracking) {fTracking = tracking;} // 设置轨迹
DWORD GetColor() const { return m_allSprite -> GetColor();} // 获得颜色
float GetZ() const { return m_allSprite -> GetZ();} // 获得Z缓冲
int GetBlendMode() const { return m_allSprite -> GetBlendMode();} // 获得混和模式
float GetScale() const { return fScale;} // 获得比例
float GetRotation() const { return fRot;} // 获得旋转角度
float GetTracking() const { return fTracking;} // 获得轨迹
float GetHeight() const { return fHeight; } // 获得字体高度
int GetCNWidth() const { return ( int )fCNWidth; }
int GetENWidth() const { return ( int )fENWidth; }
float GetStringWidth( const char * string ) const ; // 获得字符串的象素级宽度
float GetStringWidth( const char * string , int & pos, bool getpos = true ) const ;
private :
static HGE * hge;
hgeSprite * m_allSprite; // 所有字模精灵
int dx; // 修正值
FontCN_Frame letters[HZ_H_MAX][HZ_W_MAX]; // 所有字符
float fCNWidth; // 汉字宽度
float fENWidth; // ASCII宽度
float fHeight; // 字符高度
float fScale, fRot; // 字符显示比例与角度
float fTracking; // 字符轨迹
char buffer[ 1024 ]; // 文本缓存
};
inline void hgeFontCN::FontCN_Head::SetData( char * head, char num, const char * firstImg, DWORD nCol, DWORD nRow, DWORD nFWidth, DWORD nFHeight)
{
strcpy(strHead, head);
ImgFileNum = num;
strcpy(firstImgFileName, firstImg);
dwStringCol = nCol;
dwStringRow = nRow;
dwFontWidth = nFWidth;
dwFontHeight = nFHeight;
}
inline void hgeFontCN::FontCN_Frame::SetData(BYTE h,BYTE l,BYTE idx, WORD fx,WORD fy)
{
HZ[ 0 ] = h;
HZ[ 1 ] = l;
fileIdx = idx;
dwFontX = fx;
dwFontY = fy;
}
原作者:微妙的平衡
修改者:sf.tk
修改日期:2007-06-28
修改者 :Showlong
修改内容:去掉format的bug.
不需要处理多张字符纹理.
修改数据类型的不平衡.
修正SetBlendMode函数内部错误
填加获取串指定个数的长度
填加渲染长度截取
*************************************************** */
#pragma once
#include " hge.h "
#include " hgesprite.h "
#include < iostream >
class hgeFontCN
{
enum FONTCN_DATA
{
VALUE_FIX = 1 ,
HZ_H_MAX = 87 + VALUE_FIX, // 0xA1~0xF7 汉字编码范围高位(+1是给普通字母与标点符号留位置)
HZ_W_MAX = 95 , // 0xA0~0xFE 汉字编码范围底位
HZ_H_FIX = 0xA1 ,
HZ_W_FIX = 0xA0 ,
HZ_H_END = 0xF7 ,
HZ_W_END = 0xFE ,
ASCII_FIX = 0x20 ,
ASCII_END = 0x7f ,
ASCII_W = 6
};
struct FontCN_Head
{
char strHead[ 32 ];
char ImgFileNum; // 字模文件数
char firstImgFileName[ 40 ]; // 第一个字模文件名
DWORD dwStringCol;
DWORD dwStringRow;
DWORD dwFontWidth;
DWORD dwFontHeight;
public :
void SetData( char * head, char num, const char * firstImg, DWORD nCol, DWORD nRow, DWORD nFWidth, DWORD nFHeight);
};
struct FontCN_Frame
{
BYTE HZ[ 2 ];
BYTE fileIdx; // 所属的字模文件
WORD dwFontX;
WORD dwFontY;
public :
void SetData(BYTE h, BYTE l, BYTE idx, WORD fx, WORD fy);
};
public :
hgeFontCN( const char * filename); // 根据字体文件创建
~ hgeFontCN( void );
void Render( float x, float y, const char * string , int cutlen = 0 ); // 绘制字符串
void printf( float x, float y, const char * format, ...); // 绘制格式字符串
void SetColor(DWORD col){m_allSprite -> SetColor(col);} // 设置字体颜色
void SetZ( float z){m_allSprite -> SetZ(z);} // 设置Z缓冲
void SetBlendMode( int blend){m_allSprite -> SetBlendMode(blend);} // 设置混和模式
void SetScale( float scale) {fScale = scale;} // 设置比例
void SetRotation( float rot) {fRot = rot;} // 设置旋转角度
void SetTracking( float tracking) {fTracking = tracking;} // 设置轨迹
DWORD GetColor() const { return m_allSprite -> GetColor();} // 获得颜色
float GetZ() const { return m_allSprite -> GetZ();} // 获得Z缓冲
int GetBlendMode() const { return m_allSprite -> GetBlendMode();} // 获得混和模式
float GetScale() const { return fScale;} // 获得比例
float GetRotation() const { return fRot;} // 获得旋转角度
float GetTracking() const { return fTracking;} // 获得轨迹
float GetHeight() const { return fHeight; } // 获得字体高度
int GetCNWidth() const { return ( int )fCNWidth; }
int GetENWidth() const { return ( int )fENWidth; }
float GetStringWidth( const char * string ) const ; // 获得字符串的象素级宽度
float GetStringWidth( const char * string , int & pos, bool getpos = true ) const ;
private :
static HGE * hge;
hgeSprite * m_allSprite; // 所有字模精灵
int dx; // 修正值
FontCN_Frame letters[HZ_H_MAX][HZ_W_MAX]; // 所有字符
float fCNWidth; // 汉字宽度
float fENWidth; // ASCII宽度
float fHeight; // 字符高度
float fScale, fRot; // 字符显示比例与角度
float fTracking; // 字符轨迹
char buffer[ 1024 ]; // 文本缓存
};
inline void hgeFontCN::FontCN_Head::SetData( char * head, char num, const char * firstImg, DWORD nCol, DWORD nRow, DWORD nFWidth, DWORD nFHeight)
{
strcpy(strHead, head);
ImgFileNum = num;
strcpy(firstImgFileName, firstImg);
dwStringCol = nCol;
dwStringRow = nRow;
dwFontWidth = nFWidth;
dwFontHeight = nFHeight;
}
inline void hgeFontCN::FontCN_Frame::SetData(BYTE h,BYTE l,BYTE idx, WORD fx,WORD fy)
{
HZ[ 0 ] = h;
HZ[ 1 ] = l;
fileIdx = idx;
dwFontX = fx;
dwFontY = fy;
}
欢迎转载:查看原作blog(ShowLong)
hgefontc.cpp文件如下:
#include " ....includehgefontcn.h "
#include < stdlib.h >
#include < stdio.h >
HGE * hgeFontCN::hge = 0 ;
hgeFontCN:: ~ hgeFontCN( void )
{
hge -> Texture_Free(m_allSprite -> GetTexture());
delete m_allSprite;
m_allSprite = 0 ;
hge -> Release();
}
hgeFontCN::hgeFontCN( const char * filename)
{
hge = hgeCreate(HGE_VERSION);
fScale = 1.0f ;
fRot = 0.0f ;
fTracking = 0.0f ;
HTEXTURE hTexture = 0 ;
FontCN_Head fonthead;
FILE * pFontFile = fopen(filename, " rb " );
if (pFontFile)
{
size_t filesize = 0 ;
filesize = fread( & fonthead, 1 , sizeof (FontCN_Head),pFontFile);
if (filesize != sizeof (FontCN_Head))
{
fclose(pFontFile);
return ;
}
if (strcmp(fonthead.strHead, " [HGEFONTCN] " ))
{
fclose(pFontFile);
return ;
}
// 获得字模文件名
std:: string imgFileName(fonthead.firstImgFileName);
int fileNum = fonthead.ImgFileNum;
// 获得字符宽度
fCNWidth = ( float )fonthead.dwFontWidth;
fENWidth = ( float )(fCNWidth / 2 + 1 );
// fENWidth = fCNWidth;
fHeight = ( float )fonthead.dwFontHeight;
int oneFileCharNum = fonthead.dwStringRow * fonthead.dwStringCol; // 一张图上最大字数
char szFullImgFile[_MAX_PATH];
char drive[_MAX_DRIVE];
char dir[_MAX_DIR];
char fname[_MAX_FNAME];
char ext[_MAX_EXT];
_splitpath( filename, drive, dir, fname, ext );
// 读入texture,建立sprite
sprintf(szFullImgFile, " %s%s " ,dir,imgFileName.c_str());
hTexture = hge -> Texture_Load(szFullImgFile); // 加载指定字模图片
if ( ! hTexture)
{
fclose(pFontFile);
return ;
}
m_allSprite = new hgeSprite(hTexture, 0 , 0 ,( float )hge -> Texture_GetWidth(hTexture, true ),( float )hge -> Texture_GetHeight(hTexture, true ));
// 修正值(如显示不正常请自行调整)
if (fCNWidth < 20 )
dx = int (fCNWidth / 7 );
else if (fCNWidth < 50 )
dx = int (fCNWidth / 4.5 );
else
dx = int (fCNWidth / 3.3 );
FontCN_Frame fontbody;
// 读入所有字符
while ( ! feof(pFontFile))
{
filesize = 0 ;
filesize = fread( & fontbody, 1 , sizeof (FontCN_Frame),pFontFile);
if (filesize != sizeof (FontCN_Frame))
break ;
BYTE hz0 = fontbody.HZ[ 0 ];
BYTE hz1 = fontbody.HZ[ 1 ];
// 读取汉字字模
if (hz0 >= HZ_H_FIX && hz0 <= HZ_H_END)
{
hz0 -= HZ_H_FIX;
if (hz1 >= HZ_W_FIX && hz1 <= HZ_W_END)
hz1 -= HZ_W_FIX;
else
continue ;
}
// 读取标准ASCII字模
else if (hz0 == 0xff )
{
hz0 = HZ_H_MAX - VALUE_FIX;
if (hz1 >= ASCII_FIX && hz1 < ASCII_END)
hz1 -= ASCII_FIX;
else
continue ;
}
// 如果不是汉字也不是标准ASCII字模就读下一个
else
continue ;
letters[hz0][hz1] = fontbody;
}
fclose(pFontFile);
}
SetBlendMode(BLEND_COLORMUL | BLEND_ALPHABLEND | BLEND_NOZWRITE);
}
void hgeFontCN::Render( float x, float y, const char * string , int cutlen)
{
float fx = x;
int i( 0 ),j( 0 );
while ( * string )
{
BYTE hz0 = * string ;
BYTE hz1 = * ( string + 1 );
// 遇到回车
if ( * string == ' ' )
{
y += fHeight * fScale;
fx = x;
}
// 遇到汉字
else if (hz0 >= HZ_H_FIX && hz0 <= HZ_H_END)
{
// letters[hz0 - HZ_H_FIX][hz1 - HZ_W_FIX]->RenderEx(fx, y, fRot, fScale);
i = hz0 - HZ_H_FIX;
j = hz1 - HZ_W_FIX;
m_allSprite -> SetTextureRect( float (letters[i][j].dwFontX + dx),( float )letters[i][j].dwFontY,fCNWidth,fHeight);
m_allSprite -> RenderEx(fx,y,fRot,fScale);
fx += (fCNWidth + fTracking) * fScale;
string ++ ;
}
// 遇到ASCII
else if (hz0 >= ASCII_FIX && hz0 < ASCII_END)
{
i = HZ_H_MAX - VALUE_FIX;
j = hz0 - ASCII_FIX;
m_allSprite -> SetTextureRect( float (letters[i][j].dwFontX + dx),( float )letters[i][j].dwFontY,fENWidth,fHeight);
m_allSprite -> RenderEx(fx,y,fRot,fScale);
fx += (fENWidth + fTracking) * fScale;
}
else
{
i = HZ_H_MAX - VALUE_FIX;
j = ' ? ' ;
m_allSprite -> SetTextureRect( float (letters[i][j].dwFontX + dx),( float )letters[i][j].dwFontY,fENWidth,fHeight);
m_allSprite -> RenderEx(fx,y,fRot,fScale);
fx += (fENWidth + fTracking) * fScale;
}
string ++ ;
if (cutlen > 0 && fx - x >= cutlen)
return ;
}
}
// 绘制格式字符串
void hgeFontCN::printf( float x, float y, const char * format, ...)
{
char * pArg = ( char * ) & format + sizeof (format);
_vsnprintf(buffer, sizeof (buffer) - 1 , format, pArg);
buffer[ sizeof (buffer) - 1 ] = 0 ;
Render(x,y,buffer);
}
float hgeFontCN::GetStringWidth( const char * string ) const
{
float w = 0 ;
while ( * string && * string != ' ' )
{
BYTE hz0 = (unsigned char ) * string ;
BYTE hz1 = (unsigned char ) * ( string + 1 );
if (hz0 >= HZ_H_FIX && hz0 <= HZ_H_END)
w += fCNWidth + fTracking, string ++ ;
else if (hz0 >= ASCII_FIX && hz0 < ASCII_END)
w += fENWidth + fTracking;
else
w += fENWidth + fTracking;
string ++ ;
}
return w * fScale;
}
float hgeFontCN::GetStringWidth( const char * string , int & pos, bool getpos) const
{
float w = 0 ;
int p = 0 ;
while ( * string && * string != ' ' )
{
BYTE hz0 = (unsigned char ) * string ;
BYTE hz1 = (unsigned char ) * ( string + 1 );
if (hz0 >= HZ_H_FIX && hz0 <= HZ_H_END)
w += fCNWidth + fTracking, string ++ ;
else if (hz0 >= ASCII_FIX && hz0 < ASCII_END)
w += fENWidth + fTracking;
else
w += fENWidth + fTracking;
string ++ ;
if ( ++ p >= pos && ! getpos)
return w * fScale;
}
if (getpos)
pos = p;
return w * fScale;
}
***********最新的代码请看"HGE中文输入最新修改",这里的已经旧了.最新工具也在里面***********
至于生成fontcn所需的bin文件..这里有一份生成工具..
exe和ini文件放同级目录。。
这样就可以生成所需的png和文字配置文件了。
使用的时候只需像hgeFont一样使用。
pFont = new hgeFontCN("xxx.bin");
为此。中文即可显示了。。
下一篇讲如何进行中文输入。