现在的位置: 首页 > 综合 > 正文

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

2012年12月26日 ⁄ 综合 ⁄ 共 10548字 ⁄ 字号 评论关闭

 

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 *stringint 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 *stringconst;            //获得字符串的象素级宽度
    float        GetStringWidth(const char *stringint& pos, bool getpos = trueconst;

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 *stringint 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 *stringconst
{
    
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 *stringint& 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");

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

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

抱歉!评论已关闭.