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

原创 2007年07月02日 11:15:00

 

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");

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

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

让HGE支持中文(3) - HGE字符串处理

前面都已经讲了怎么请HGE支持并显示中文..另外呢.我们还需要的一个处理字符串的类..当然也可以不用.所以放到最后拿出来.不过当对于UNICODE与非UNICODE之间切来切去的时候.你不可能一直在那...
  • ShowLong
  • ShowLong
  • 2007-07-02 12:07:00
  • 2587

HGE的中文显示解决方案

最近在自己借鉴hge写一个2d游戏引擎,无意中看到中文字体的简单解决方案,先记下来备忘。 HGE本身并不支持中文的显示,因此我使用由 微妙的平衡 大神提供的解决方案. 大神提供的代码本来包含g...
  • tjunxin
  • tjunxin
  • 2013-08-15 21:46:53
  • 3352

HGE基础教程(1)

作者:寰子 来源:http://www.hgechina.com/ 前言: 写道: 无意中发现了H...
  • zhuzhao
  • zhuzhao
  • 2008-04-07 14:17:00
  • 11247

hge1.81 源码

  • 2009年11月02日 11:51
  • 3.71MB
  • 下载

HGE引擎开源了

HGE简单的说,就是以3D加速实现2D图像的做法, 听起来很玄,其实在幻想森林的大家早已在使用。 没错,就是RMXP内部的绘图功能(Game Maker也是), HGE使用DX8作为图像加速库,在Wi...
  • guo_wangwei
  • guo_wangwei
  • 2007-08-23 17:04:00
  • 2559

对HGE游戏引擎的一次封装

 HGE游戏引擎是一个开源2D游戏引擎,基于directX。它的渲染及逻辑是基于帧回调的框架模式,其提供一些基本的图像操作和输入控制功能。 我在之前写一个2D游戏的时候对它整个框架进行了一次封装,很多...
  • rcfalcon
  • rcfalcon
  • 2010-02-12 11:31:00
  • 16254

让HGE支持中文(4) - 编辑框的实现

阅读此文章前请先确认你已经阅读以下文章:让HGE支持中文(1) - HGE中文显示 (必需) 让HGE支持中文(2) - HGE中文输入 (必需) 让HGE支持中文(3) - HGE字符串处理 (可选...
  • ShowLong
  • ShowLong
  • 2008-06-27 11:51:00
  • 3852

【HGE引擎】源码解析——枚举(一)

本文主要介绍和分析HGE开源引擎hge.h文件的使用技巧和诸多方面学习一 系统层API通常我们开始写一个简单的hge例子,基本都会包含这个hge.h文件,这个文件是干嘛的呢? 它就是众矢之的,系统层A...
  • feng1790291543
  • feng1790291543
  • 2016-07-03 02:56:07
  • 1341

开源项目之开源的2D游戏引擎 HGE

HGE游戏引擎是一个基于directX的游戏引擎,它的渲染及逻辑是基于帧回调的框架模式,其提供一些基本的图像操作和输入控制功能。 项目如图: fontconv测试代码(参数二:文件...
  • banketree
  • banketree
  • 2012-10-16 21:11:13
  • 20366

<考古笔记>hge游戏引擎(一)Tutorials

官网:http://hge.relishgames.com/ 我为什么说是考古呢? 因为这是个用DirectX8写(所以介绍说可以硬件加速)的2D引擎,而现在微软官网新的DirectX11 SDK里面...
  • tjj00686
  • tjj00686
  • 2016-03-05 22:55:39
  • 1744
收藏助手
不良信息举报
您举报文章:让HGE支持中文(1) - HGE中文显示
举报原因:
原因补充:

(最多只允许输入30个字)