游戏开发论坛

 找回密码
 立即注册
搜索
查看: 5702|回复: 6

cegui如何和python结合

[复制链接]

2

主题

5

帖子

7

积分

新手上路

Rank: 1

积分
7
发表于 2009-11-23 22:03:00 | 显示全部楼层 |阅读模式
正在学习python,想把cegui改成用python的,那位大神搞过, [em6]

0

主题

7

帖子

7

积分

新手上路

Rank: 1

积分
7
发表于 2009-11-25 00:13:00 | 显示全部楼层

Re: cegui如何和python结合

这个网站上有类似的东东 可以参考下
http://www.koders.com/noncode/fid90E1CC851C7D25F526081ACD02088A22CC60E5A5.aspx?s=mdef%3apython%2f
http://blog.csdn.net/hbaizj/archive/2008/03/20/2200630.aspx
http://www.cppblog.com/d3d/archive/2008/12/14/69397.html

---------基于Gpu技术的批量汉字的显示
http://bbs.gameres.com/showthread.asp?threadid=114113

http://bbs.gameres.com/showthread.asp?threadid=64404&page=1
http://bbs.gameres.com/showthread.asp?threadid=115009
http://hack.gameres.com/showthread.asp?threadid=72096
http://bbs.gameres.com/showthread.asp?threadid=62945

0

主题

7

帖子

7

积分

新手上路

Rank: 1

积分
7
发表于 2009-11-25 00:50:00 | 显示全部楼层

Re: cegui如何和python结合

完整的包文件

http://blog.sina.com.cn/s/blog_613d5bdc0100er4g.html
在CEGUI中为了显示中文,常常需要将string转换为wstring,在网上查找了好几种方法,发现有的转换不了汉字,有的函数抽风,转换过来都是空的。最终还是找到了解决问题的办法,拿出来共享一下:



std::wstring  StringToWString(const std::string& s)

{

     std::wstring wszStr;



     int nLength = MultiByteToWideChar( CP_ACP, 0, s.c_str(), -1, NULL, NULL );

     wszStr.resize(nLength);

     LPWSTR lpwszStr = new wchar_t[nLength];

     MultiByteToWideChar( CP_ACP, 0, s.c_str(), -1, lpwszStr, nLength );

     wszStr = lpwszStr;

     delete [] lpwszStr;



     return wszStr;

}


0

主题

7

帖子

7

积分

新手上路

Rank: 1

积分
7
发表于 2009-11-28 23:39:00 | 显示全部楼层

Re: cegui如何和python结合

这边有个好帖http://bbs.gameres.com/showthread.asp?threadid=62945
http://bbs.gameres.com/showthread.asp?threadid=133603

今天心情很不错 - Tale.Teller - 谦恭如狗,骄傲如龙

解决了CEGUI的MultilineEditbox的输入法窗口跟随插入点问题。解决的关键就是获取插入点的屏幕坐标。具体怎么获取的,往下拉,授你们鱼。

想要渔的,点这里。CE真是个好人,赞一下。



这个问题的成功解决,是一系列功能得以实现的先决条件。值得我po出来开心一下。

那么,上代码。

void getCaretPos(POINT& point,const CEGUI::MultiLineEditbox* pmleb)
{
CEGUI::Vector2 clientPos;

size_t caretIndex = pmleb->getCaratIndex();

size_t lineNumber = pmleb->getLineNumberFromIndex(caretIndex);

CEGUI::Font *pFont = pmleb->getFont();

clientPos.d_y = (lineNumber + 1) * pFont->getFontHeight();

const CEGUI::MultiLineEditbox:ineList& lineList = pmleb->getFormattedLines();

size_t lineListSize = lineList.size();

const CEGUI::MultiLineEditbox::LineInfo& lineInfo = lineList.at(lineNumber);

CEGUI::String subString = pmleb->getText();

size_t lineInfoStartIndex = lineInfo.d_startIdx;

subString = subString.substr(lineInfoStartIndex,caretIndex-lineInfoStartIndex);

clientPos.d_x = pFont->getTextExtent(subString);

CEGUI::Rect textRenderArea = pmleb->getTextRenderArea();

clientPos.d_x -= textRenderArea.d_left;
clientPos.d_y -= textRenderArea.d_top;

CEGUI::Vector2 screenPos = CEGUI::CoordConverter::windowToScreen(*pmleb,clientPos);

point.x = screenPos.d_x;
point.y = screenPos.d_y;
}

usage:pass a pointer of MultilineEditbox via param #2, the result will be filled into a POINT struct instance by ref passed via param #1.

那么就这样吧。

话说最近都没啥人评论或者留言了。我的博真的如此?迕矗



CEGUI中实现中文输入是一个老话题了,网上的资料也很多,但是实现的都不是那么完美,其中最重要的问题就是输入法界面的跟随和输入状态时对按键的屏蔽。

先来说下如何把中文输入进入。
先添加一个中文注入的函数:
/////// 中文输入注入字符 (Added by Azure)
static bool ChnInjectChar(CEGUI::utf32 code_point);
///////
函数的实现如下:
bool Win32AppHelper::ChnInjectChar(CEGUI::utf32 code_point)
{
#ifndef UNICODE
  static char s_tempChar[3] = "";
  static wchar_t s_tempWchar[2] = L"";
  static bool s_flag = false;
  unsigned char uch = (unsigned char)code_point;
  if( uch >= 0xA1 )
  {
    if( !s_flag )
    {
      s_tempChar[0] = (char)uch; //第一个字节
      s_flag = true;
      return true;
    }
    else if( uch >= 0xA1 )
    {
      s_tempChar[1] = (char)uch; //第二个字节
      s_flag = false;
      MultiByteToWideChar( 0, 0, s_tempChar, 2, s_tempWchar, 1); //转成宽字节
      s_tempWchar[1] = L'\0';
      CEGUI::utf32 code = (CEGUI::utf32)s_tempWchar[0];
      return CEGUI::System::getSingleton().injectChar( code );
    }
    else
    {
      return CEGUI::System::getSingleton().injectChar(code_point);
    }
  }
  else
  {
    s_flag = false;
    return CEGUI::System::getSingleton().injectChar(code_point);
  }
#else
  return CEGUI::System::getSingleton().injectChar(code_point );
#endif
}
此函数是我从网上抄来的一个,没有什么特别的,挺好用的。

然后在WndProc回调函数中添加:
case WM_CHAR:
// 不要这个
//CEGUI::System::getSingleton().injectChar((CEGUI::utf32)wParam);
// 改用自己的注入
ChnInjectChar((CEGUI::utf32)wParam);
break;
这样中文就可以基本输入了,但是还有很多问题,原来不能BackSpace删除,和游标移动啊!

下面我们来添加控制按键的处理。
由于wParam不能直接传入CEGUI中,我们必须写一个虚拟按键到扫描码的翻译函数,我们添加下面一个函数。
/////// 虚拟按键转扫描码 (Added by Azure)
static UINT VirtualKeyToScanCode(WPARAM wParam, LPARAM lParam);
该函数的实现为:
UINT Win32AppHelper::VirtualKeyToScanCode(WPARAM wParam, LPARAM lParam)
{
  if(HIWORD(lParam) & 0x0F00)
  {
    UINT scancode = MapVirtualKey(wParam, 0);
    return scancode | 0x80;
  }
  else
  {
    return HIWORD(lParam) & 0x00FF;
  }
}
同样的我们在WndProc消息回调中添加代码:
case WM_KEYDOWN:
{
//输入法跟随
IMEFollow(hWnd);
   
//输入法状态时,输入不传递到UI系统中去。
UINT vk = (UINT)ImmGetVirtualKey(hWnd);
if(vk == wParam)
  break;
      
CEGUI::System::getSingleton().injectKeyDown((CEGUI::utf32)(VirtualKeyToScanCode(wParam, lParam)));
}
break;

case WM_KEYUP:
CEGUI::System::getSingleton().injectKeyUp((CEGUI::utf32)(VirtualKeyToScanCode(wParam, lParam)));
break;
有两个陌生的函数,IMEFollow(hWnd) 和 ImmGetVirtualKey() 分别是为了输入法跟随,和过滤掉输入法处理过的按键,比较关键。

关于输入法跟随的函数体为:
/////// 获得输入框的坐标 (Added by Azure)
static bool getFocusedInputBoxCoord(POINT& point, float& height);

////// 输入法跟随 (Added by Azure)
static bool IMEFollow(HWND hWnd);
实现为:
bool Win32AppHelper::getFocusedInputBoxCoord(POINT& point, float& height)
{
  //寻找到有输入焦点的EditBox的左上坐标
  //遍历所有窗口
  CEGUI::WindowManager::WindowIterator wit = CEGUI::WindowManager::getSingleton().getIterator();
  while(!wit.isAtEnd())
  {
    const CEGUI::Window* widget = (*wit)->getActiveChild();
    //如果是EditBox或者MultiLineEditBox
    if(widget)
    {
      CEGUI::String windowType = widget->getType();
      if(windowType == "Vanilla/Editbox")                //根据具体的scheme来修改。
      {
        const CEGUI::UVector2& winPos = widget->getPosition();
        height = widget->getPixelRect().getHeight();
         
        CEGUI::Vector2 winPos1 = CEGUI::CoordConverter::windowToScreen(*widget, winPos);

        point.x = winPos1.d_x;
        point.y = winPos1.d_y;
        return true;
      }
    }
    wit++;
  }

  return false;
}

bool Win32AppHelper::IMEFollow(HWND hWnd)
{
  //判断输入法是否打开
  if (!ImmIsIME(GetKeyboardLayout(0)))
    return false;
  
  //获得输入框左上坐标
  bool result;
  POINT point;
  float height;
  result = getFocusedInputBoxCoord(point, height);
  if(!result)
    return false;
  
  //获得客户区的坐标
  RECT rect;
  GetClientRect(hWnd, &rect);
  point.x+=rect.left;
  point.y+=rect.top;

  //设置输入法位置
  HIMC hImc = ImmGetContext(hWnd);
  if(hImc==NULL) return false;
  COMPOSITIONFORM form;
  ImmGetCompositionWindow(hImc, &form);
  form.ptCurrentPos.x = point.x;
  form.ptCurrentPos.y = point.y + height;
  ImmSetCompositionWindow(hImc, &form);

  return true;  
}
这样一来一个完整的CEGUI输入法解决方案就完成了。
相关参考代码如下:

点击下载

www.azure.com.cn
评论Feed 评论Feed: http://www.azure.com.cn/feed.asp?q=comment&id=399

浏览模式: 显示全部 | 评论: 2 | 引用: 0 | 排序 | 浏览: 3619
Cloudage
[ 2009-05-30 18:11:00 ]
首先,Good Job [yes]

借助您的研究,我也轻松实现了中文输入和IME窗口跟随的支持。

不过,使用过程中发现对于MultilineEditbox而言,窗口跟随并不是很好,于是我在您的基础上进一步实现了IME窗口针对于MultilineEditbox的插入点跟随。

实现过程中多亏得到了CE本人的指点,不然某些函数还真不知道可以用来干这事。

关键代码在
http://taleofarcana.blog.163.com/blog/static/8228189920094300723456/edit/

请斧正。
etcheng
[ 2009-07-14 12:55:54 ]
你这个方法,有很多字都不能正常打出来把 例如:“?濉
在ChnInjectChar函数里面,应该改一下对uch的判断规则。

0

主题

7

帖子

7

积分

新手上路

Rank: 1

积分
7
发表于 2009-11-29 20:41:00 | 显示全部楼层

Re: cegui如何和python结合

http://blog.sina.com.cn/s/blog_613d5bdc0100er4f.html###

CEGUI中的汉字显示实现(2009-08-10 20:50:00)
标签:it          分类:CEGUI

几日前,用 CEGUI做界面,发现无法应用CEGUI的window中setText()函数直接显示中文。上网google一下,原来经过简单的字符转化可以显示中文(偷着乐,CEGUI太方便了)。



方法如下(引用):http://blog.csdn.net/kun1234567/archive/2008/04/11/2282761.aspx

CEGUI使用utf8编码格式。这就意味着我们可以很简单的就显示中文。



1、弄个包含中文的字体,在这里我借用大多数例子里的 “C:/windows/Font/simhei.ttf”文件。把这个文件拷贝到Datafiles文件夹的Font文件夹里。



2、随便照着一个 .Font文件,自己写一个simhei.font文件。可以用TXT写,然后保存,有的朋友说需要保存为utf8编码格式,实际上是不需要的。



3、同时注意修改你加载到程序里的scheme文件,将里面的字体文件设置成simhei.ttf。你也可以继续使用FirstWindow这个例子,这样的话直接修改源代码里的字体为simhei.tff。



4、现在在程序里进行字符编码转换,我拿代码说明问题:



std::wstring aa = L"123中文abcあいうえお";

char buff[128] = "";

WideCharToMultiByte( CP_UTF8, 0, aa.c_str(), aa.size(), buff, sizeof(buff), 0, 0);

button1->setText ( CEGUI::String ( CEGUI::utf8* )buff );



原理是这样的,对于utf8来说,英文字符和ansi编码在内存布局上没什么区别,都是一个UCHAR。但是对于非英文字符,则是UCHAR+UCHAR+UCHAR。如果我们手工进行编码格式转换,会比较烦琐。



比较偷懒的方法就是,我们先用WCHAR(unicode内存布局,UCHAR+UCHAR+UCHAR+UCHAR)来储存需要显示的字符串,然后调用Win32API来帮我们把宽字符转换成char(多字节字符集内存布局)。



这就是基本方法了,然后我们可以根据这个转换方针,利用Win32API随意的转换字符编码格式,从而满足程序中的各种需求。





       通过此方法可以显示中文,还没来得急高兴就发现了第二个问题:这种方法显示中文速度太慢(显示几十个字需要等上7、8秒左右)。难道没有高效的方法吗?

于是继续Google(我很懒,别人能做的事情从来不麻烦自己,懒得跟踪代码),结果还真让我找到了两篇相关的文章:一份是千里马肝的《游戏中汉字显示的实现与技巧》,另一份是免费打工仔的《让OGRE支持中文》。从中找到了原因:

       原来在游戏中,是将点阵字库或tif字体里的文字写进纹理,根据需求贴到指定的位置。英文的显示非常简单,只有26个字母,就算再加一些标点、符号什么的,用一张位图,就可以足以显示所有的单词了。而中文要像处理英文那样,把所有的汉字都保存在一张位图里,那么每一种字体都要生成一个巨型位图。在 GB2312中,一共有6000多个汉字,就算是用16*16,据说会有2.5M!(马肝兄说的,我没算过)

    继续Google,也没有找到解决问题的直接办法,唉,再懒也得自己上阵了。

通过跟踪调试,发现了问题所在,原来罪魁祸首就是他:



const FontGlyph *Font::getGlyphData (utf32 codepoint)

{

     if (codepoint > d_maxCodepoint)

         return 0;



         if (d_glyphPageLoaded)

         {

              uint page = codepoint / GLYPHS_PER_PAGE;

              uint mask = 1 << (page & (BITS_PER_UINT - 1));

              if (!(d_glyphPageLoaded [page / BITS_PER_UINT] & mask))

              {

                   d_glyphPageLoaded [page / BITS_PER_UINT] |= mask;

                   rasterize (codepoint & ~(GLYPHS_PER_PAGE - 1),

                       codepoint | (GLYPHS_PER_PAGE - 1));

              }

         }



         CodepointMap::const_iterator pos = d_cp_map.find (codepoint);

         return (pos != d_cp_map.end()) ? &pos->second : 0;

}



原来CEGUI根据Unicode字符的编码顺序,为每256个字符分配一张纹理(例如编码0-255存放在纹理一,编码768-1023 存放在纹理四)。英文很容易搞定了,那么几个字符一张纹理就够了,可中文就得靠运气了,有时显示几个字就要生成几张纹理,还要将每张纹理用不需要的相邻字填满,劳民伤财!

发现了问题,我便按照千里马肝的思想对函数进行了改造,将使用的文字放入一张纹理中,因为纹理最大承载256个字,所以,当汉字超过256个时,则将不常用的去掉,将新的字符写入。

后来我发现汉字的引用没有太多的规律,常用的一千多汉字出现的概率没有那么悬殊(废话,要不怎么是常用呢!),没有办法很好地按照使用的频率将汉字限制在256个字以内,写进纹理,就索性一旦满了就将字全部释放掉,重新写入。(也需有我没找到,还请高手指教)

代码如下:

const FontGlyph *Font::getGlyphData (utf32 codepoint)

{

     if (codepoint > d_maxCodepoint)

         return 0;



     if(codepoint < 256)  //决定保留一张纹理放英文和字符

     {

         if (d_glyphPageLoaded)

         {

              uint page = codepoint / GLYPHS_PER_PAGE;

              uint mask = 1 << (page & (BITS_PER_UINT - 1));

              if (!(d_glyphPageLoaded [page / BITS_PER_UINT] & mask))

              {

                   d_glyphPageLoaded [page / BITS_PER_UINT] |= mask;

                   rasterize (codepoint & ~(GLYPHS_PER_PAGE - 1),

                       codepoint | (GLYPHS_PER_PAGE - 1));

              }

         }



         CodepointMap::const_iterator pos = d_cp_map.find (codepoint);

         return (pos != d_cp_map.end()) ? &pos->second : 0;

     }

     else //显示汉字啦

     {

         CodepointMap::const_iterator pos;



         pos = d_hz_map.find (codepoint);



         if(pos != d_hz_map.end())

         {

              return (pos != d_hz_map.end()) ? &pos->second : 0;

         }

         else

         {

              rasterizeHZ(codepoint);



              pos = d_hz_map.find (codepoint);

              return (pos != d_hz_map.end()) ? &pos->second : 0;

         }

     }

}



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())

     {

         // Render the glyph

         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;

              err << "Font::loadFreetypeGlyph - Failed to load glyph for codepoint: ";

              err << static_cast<unsigned int> (hzInter->first);

              err << ".  Will use an empty image for this glyph!";

              Logger::getSingleton ().logEvent (err.str (), Errors);



              // Create a 'null' image for this glyph so we do not seg later

              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;



              // Check if glyph right margin does not exceed texture size

              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;

              }



              // Check if glyph bottom margine does not exceed texture size

              uint y_bot = m_nHZY + glyph_h;

            



              // Copy rendered glyph to memory buffer in RGBA format

              drawGlyphToBuffer (hzmem_buffer + (m_nHZY * texsize) + m_nHZX, texsize);



              // Create a new image in the imageset

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



              // Advance to next position

              m_nHZX = x_next;

              if (y_bot > m_nHZYB)

              {

                   m_nHZYB = y_bot;

              }

         }

     }



     // Copy our memory buffer into the texture and free it

     hzImageset->getTexture ()->loadFromMemory (hzmem_buffer, texsize, texsize, Texture:F_RGBA);



}



     OK,问题搞定,打完收工。试试,效果还不错,可以洗洗睡了。特将自己的一点体会写出来,给新手提供个捷径,也希望高手批评指教。

前一篇:delta3d与osg
后一篇:string 到 wstring的转换
评论    重要提示:警惕虚假中奖信息,点击查看详情      免费任选1000款游戏新手卡[发评论]

    *

      新浪网友:
      2009-08-18 21:33:37

      你的代码里的成员变量都是哪里定义的呢?还有指针的保护也没有。写的仔细点嘛。
      ImagesetManager::getSingleton ().destroyImageset (hzImageset->getName ());
      hzImageset的声明在哪里?你能保证这一行一定就可以被执行?
      hzmem_buffer的声明呢?
      m_nHZX,m_nHZY的声明呢?

你的代码里的成员变量都是哪里定义的呢?还有指针的保护也没有。写的仔细点嘛。
ImagesetManager::getSingleton ().destroyImageset (hzImageset->getName ());
hzImageset的声明在哪里?你能保证这一行一定就可以被执行?
hzmem_buffer的声明呢?
m_nHZX,m_nHZY的声明呢?

0

主题

7

帖子

7

积分

新手上路

Rank: 1

积分
7
发表于 2009-11-29 21:37:00 | 显示全部楼层

Re: cegui如何和python结合

http://blog.sina.com.cn/s/blog_613d5bdc0100evwp.html

近期有多位网友对“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:F_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的对应关系。

5

主题

74

帖子

86

积分

注册会员

Rank: 2

积分
86
发表于 2009-12-16 13:37:00 | 显示全部楼层

Re:cegui如何和python结合

lz在轰炸,晕了,刚开看,爱莫能助~
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-6-17 10:41

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表