GUI库中RichEdit控件开发的林林总总

之前开发了RichEdit控件,现在回顾总结一下。

Rich text format格式(通常缩写为RTF)是一种专有的文档文件格式,是1987年Microsoft对文件跨平台交换开发发布的规范,详情参考维基百科Rich text format(http://en.wikipedia.org/wiki/Rich_Text_Format),该格式支持在文档中显示多种类型的文本对象。该格式文档以带有转义序列的纯文本形式存储和交换。

游戏UI库中的richtext一般包含带颜色效果文本,图片,表情,超链接等文本对象,存储及解析时也以指定转义字符表示相关类型对象。如:

struct RichtextObj{

  int m_iType;

  ...

};

struct RichttextText : public RichtextObj{

  RichtextText()  { m_iType = RT_TEXT; }

  ...

};

struct RichtextImage : public RichtextObj{

  RichtextImage()  { m_iType = RT_IMAGE; }

};

...

每种对象类型在构建和绘制时需要按照类型处理。因此richtext渲染内容的内部存储结构初始应该定为这些对象的组合。如:

class Richtext{

  std::vector<RichtextObj*>  m_vObjList;

};

另外游戏聊天窗口内容刷新频率会非常高,极端情况下不能将服务器内所有玩家输入的内容都在控件中一直保存显示,因此需要richtext对显示内容进行裁剪,支持内容滚动显示。设置控件的最大显示行数,如果内容超过了最大行数,需要已fifo的方式释放掉前面的行。为了方便删除添加每行内容,以便于满足显示范围,richtext的渲染内容需要按照行,行再包含对象的方式进行存储。因此richtext的结构应该调整为

struct RichtextLine{

  std::vector<RichtextObj*>  m_vObjList;  

};

class Richtext{

  std::vector<RichtextLine*>  m_vLineList;

};

内容刷新时,删除前面超出的行,添入新的行可以满足该控件在聊天窗口的运行效率要求。控件显示内容裁剪后,对控件进行拉伸引起的效率问题也会较好的解决。在Intel i7 2600 主频3.4GHz的环境下做如下测试:聊天窗口richtext设置最大显示行数为100行,每0.1秒对其添加输入内容,内容包括三个中英文字符串和一个超链接中间穿插两个表情,一共110个字节左右。刷新的过程中水平方向伸缩行宽度,每次伸缩刷新渲染存储结构。渲染存储结构每次添加输入内容耗时5微秒左右,100行填满时,每次拉伸刷新渲染存储结构耗时800微秒左右。

由于在Richtext最大显示行数值较大时,整体刷新渲染存储结构比较耗时,因此要注意不要直接响应Windows拖拽消息来调用控件的刷新,这里对比了VisualStudio和editplus编辑器的做法,VisualStudio是在OnButtonUp时才会真正刷新显示内容结构;而editplus编辑器在水平方向拖拽时直接显示出一个滑动条,行宽度不改变,不对显示内容结构进行刷新。游戏中可以通过使用按钮缩放或限制拖拽最短刷新消时间来避免显示内容结构刷新过于频繁。

控件结构

 

光标

 

绘制

 

效率

 

posted @ 2014-09-21 16:48  南山一小妖  阅读(844)  评论(0编辑  收藏  举报