近期有多位网友对“CEGUI中的汉字显示实现”的代码部分提出质疑,并索要代码。但因为最近实在太忙,并没有一一回复,今天抽时间将代码重新整理,摘录如下:
CEGUI中的汉字显示实现的汉字显示实现主要更改"CEGUIFreeTypeFont.h CEGUIFreeTypeFont.cpp"文件。
在CEGUIFreeTypeFont.h文件中FreeTypeFont类里添加代码:
virtual void rasterizeHZ (utf32 codepoint);
void InitHZFont();
Imageset *hzImageset;
argb_t *hzmem_buffer;
uint m_nHZX, m_nHZY, m_nHZYB;
在CEGUIFreeTypeFont.cpp中涉及到相关的代码:
void FreeTypeFont::load ()
{
InitHZFont();//初始化汉字
}
void FreeTypeFont::InitHZFont(){
uint texsize = 512;//设置纹理大小
hzImageset = ImagesetManager::getSingleton ().createImageset (
d_name + "_auto_glyph_images_" ,
System::getSingleton ().getRenderer ()->createTexture ());
d_glyphImages.push_back (hzImageset);//产生hzImageset文件名
hzmem_buffer = new argb_t [texsize * texsize];//初始化存放纹理像素数组
memset (hzmem_buffer, 0, texsize * texsize * sizeof (argb_t));
m_nHZX = INTER_GLYPH_PAD_SPACE;//初始化字间隔
m_nHZY = INTER_GLYPH_PAD_SPACE;
m_nHZYB = INTER_GLYPH_PAD_SPACE;
}
void FreeTypeFont::rasterizeHZ (utf32 codepoint){
int num;
uint texsize = 512;
if(d_hz_map.size() < 256)
{
float adv = d_fontFace->glyph->metrics.horiAdvance * float(FT_POS_COEF);
d_hz_map[codepoint] = FontGlyph (adv);
}
else
{
d_hz_map.clear();
ImagesetManager::getSingleton ().destroyImageset (hzImageset->getName ());
hzImageset = ImagesetManager::getSingleton ().createImageset (
d_name + "_auto_glyph_images_" ,
System::getSingleton ().getRenderer ()->createTexture ());
d_glyphImages.push_back (hzImageset);
float adv = d_fontFace->glyph->metrics.horiAdvance * float(FT_POS_COEF);
d_hz_map[codepoint] = FontGlyph (adv);
}
CodepointMap::const_iterator hzInter = d_hz_map.find(codepoint);
if (!hzInter->second.getImage()){
if (FT_Load_Char (d_fontFace, hzInter->first, FT_LOAD_RENDER | FT_LOAD_FORCE_AUTOHINT |
(d_antiAliased ? FT_LOAD_TARGET_NORMAL : FT_LOAD_TARGET_MONO)))
{
std::stringstream err;
Logger::getSingleton ().logEvent (err.str (), Errors);
Rect area(0, 0, 0, 0);
Point offset(0, 0);
String name;
name += hzInter->first;
hzImageset->defineImage(name, area, offset);
((FontGlyph &)hzInter->second).setImage(&hzImageset->getImage(name));
}
else
{
uint glyph_w = d_fontFace->glyph->bitmap.width + INTER_GLYPH_PAD_SPACE;
uint glyph_h = d_fontFace->glyph->bitmap.rows + INTER_GLYPH_PAD_SPACE;
uint x_next = m_nHZX + glyph_w;
if (x_next > texsize)
{
m_nHZX = INTER_GLYPH_PAD_SPACE;
x_next = m_nHZX + glyph_w;
m_nHZY = m_nHZYB;
}
uint y_bot = m_nHZY + glyph_h;
drawGlyphToBuffer (hzmem_buffer + (m_nHZY * texsize) + m_nHZX, texsize);
Rect area(static_cast<float>(m_nHZX),
static_cast<float>(m_nHZY),
static_cast<float>(m_nHZX + glyph_w - INTER_GLYPH_PAD_SPACE),
static_cast<float>(m_nHZY + glyph_h - INTER_GLYPH_PAD_SPACE));
Point offset(d_fontFace->glyph->metrics.horiBearingX *static_cast<float>(FT_POS_COEF),
-d_fontFace->glyph->metrics.horiBearingY *static_cast<float>(FT_POS_COEF));
String name;
name += hzInter->first;
hzImageset->defineImage (name, area, offset);
((FontGlyph &)hzInter->second).setImage (&hzImageset->getImage (name));
m_nHZX = x_next;
if (y_bot > m_nHZYB)
{
m_nHZYB = y_bot;
}
}
}
hzImageset->getTexture ()->loadFromMemory (hzmem_buffer, texsize, texsize,Texture::PF_RGBA);
}
void FreeTypeFont::free ()
{
d_hz_map.clear();
hzImageset = ImagesetManager::getSingleton ().createImageset ( //释放文字Imageset
d_name + "_auto_glyph_images_" ,
System::getSingleton ().getRenderer ()->createTexture ());
d_glyphImages.push_back (hzImageset);
}
对于网友提出的ImagesetManager::getSingleton ().destroyImageset (hzImageset->getName ())这一句是一定被调用的,因为我们创建的纹理只存放256个汉字,超过这个数目,就要在销毁所有汉字的同时销毁所有文字图像与Imageset的对应关系。