MyGUI中原有的MyGUI_ResourceTrueTypeFont中已经支持了对TTF格式文字的载入,不过该方式在初始换资源时便将所有字静态的存入纹理缓存中。core_font.xml中可以看到,其脚本可以设置字库名,字号大小,间距等,并且通过code range字段对字库进行了分段管理。code range可根据自己的需求去分配,中文,英文,字符等,并且可以用<Code hide="1104"/>隐藏一些字。
其大致的渲染方式如下:
ResourceTrueTypeFont这个类实现了FreeType字体的创建。FontManager对字体进行管理,MyGUI_IFont接口类提供接口给上层控件MyGUI_EditText和MyGUI_SimpleText使用。通过IFont的虚函数GlyphInfo* getGlyphInfo(Char _id)来得当相应的GlyphInfo,这是一个包含对应字符ID和纹理坐标的结构体。底层渲染时以此取得相应的纹理坐标。
说一下我实现的方案,重建一个动态字体类,继承IFont函数,根据字体风格(字型,字号等这个结构体可以自己灵活控制)初始化时按字号计算出该块纹理所能容下的字的数量,记得要考虑间距。
输入字符时就去纹理缓存中查找该风格的这个字是否存在,存在直接返回对应的GlyphInfo,否则打开对应的字库,取出字模绘制到该纹理缓存中,再返回对应的GlyphInfo,最后底层渲染时根据相应的纹理坐标直接绘制出来。
这个动态字库的核心就是两点,对FreeType字库的操作和对这块纹理缓存的管理。FreeType就不多说了。对纹理的管理要注意 1.行满时U,V坐标的切换 2.纹理满时的清除操作。 u,v坐标记得判断是否到行尾,到了换行即可。要尽量提高查找效率,所以我定了一个map,用字符id和其风格id作key值,存储相应的GlyphInfo,每次调用getGlyphInfo(Char _id)查找该map,查不到的再打开字库找到字模存入这块纹理中。为了提高纹理满时清除的效率,我同时用一个list对这块纹理进行管理,采用先进先出的方式,将最先进入的list的纹理区域清空,放入新字。一定要注意map和list的管理,因为里边的GlyphInfo指针是共用的。