让HGE支持中文(1) - HGE中文显示

 

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;
}

欢迎转载:查看原作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  ( ++ >=  pos  &&   ! getpos)
            
return  w  *  fScale;
    }

    
if  (getpos)
        pos 
=  p;

    
return  w  *  fScale;
}

 ***********最新的代码请看"HGE中文输入最新修改",这里的已经旧了.最新工具也在里面***********

至于生成fontcn所需的bin文件..这里有一份生成工具..

hgeFontCN.exe

hgeFontCN.ini

exe和ini文件放同级目录。。

这样就可以生成所需的png和文字配置文件了。

使用的时候只需像hgeFont一样使用。

pFont = new hgeFontCN("xxx.bin");

为此。中文即可显示了。。

下一篇讲如何进行中文输入。

你可能感兴趣的:(HGE)