使用FreeType进行文本渲染

本文永久地址为http://www.cnblogs.com/vertexshader/articles/3201632.html,来源请注明。

尝试了一下使用FreeType来渲染字体,FreeType是一个免费且开源的,可移植的字体引擎,有许多程序包括游戏使用它作为字体渲染的库,下面说说我对FreeType的理解。

准备工作

首先是到freetype.org下载最新的FreeType库,在使用之前需要对其进行编译,还好在bulids目录下有相应平台的工程,可以直接打开FreeType进行编译。编译选项有Debug Multithreaded、Debug Singlethreaded、Release Multithreaded、Release Singlethreaded四个选项,这里要注意的是,如果链接FreeType的工程是Debug配置,那么应该使用FreeType的Debug配置编译出来的lib文件,否则可能导致未知的错误。主工程添加了库目录和库文件之后,相应的准备工作算是完成了。

开始使用FreeType

参考了FreeType大部分英文文档,理解了FreeType核心的几个操作,FreeType渲染文字需要好几步,以下是FreeType渲染字体的大致过程:

  1. 初始化FreeType Library;
  2. 初始化和载入Font Face;
  3. 设置字符大小;
  4. 渲染字符,得到相应的bitmap;
  5. 拷贝并排版文字。

关于FreeType入门方面的知识不是本文的重点,这里不想多述,可以参考官方的范例和文档,它们在这里

关于FreeType字符的排版

FreeType渲染字体后,生成的bitmap正好就是文字的大小,所以把bitmap拷贝到大图像上以后必须对其进行排版。文字不能都直接拷贝入同样大小的方形子图像上,虽然对于东亚文字问题不大,但是对于西方文字会非常的难看。因为东亚文字不存在基线,字符的大小也相同;而西方的文字存在基线,文字需要对齐,字符的大小也不相同。有助于排版的几个重要参数如下:

  1. font_face->size->metrics.height 这个参数其实就是每一行的高度,在设置相应的字体和字符大小之后生成的,每一行的字符都不会超过这个范围;
  2. font_face->size->metrics.ascender 这个参数就是上部的高度,同时也可以算出基线的高度,用于带基线的字符的对齐,在后面会详述;
  3. font_face->glyph->metrics.horiAdvance 这个参数就是每个字符的宽度,在渲染文字后可用;
  4. font_face_->glyph->bitmap.pitch 这个参数是生成的bitmap每行的像素数量,在渲染文字后可用;
  5. font_face->glyph->bitmap.rows 这个参数是生成的bitmap的行数,在渲染文字后可用;
  6. font_face->glyph->bitmap_left 这个参数是bitmap到文字左边界的距离,在渲染文字后可用;
  7. font_face->glyph->bitmap_top 这个参数是bitmap到文字上边界的距离,在渲染文字后可用。

这几个参数在排版时的关系如下:

 

 (此图有错误,horiadvance应该到最左边。)

如果以左上角(x,y)为复制起点的话,为了对齐字符,那么复制点应该在:

pos_x = x + bitmap_left;

pos_y = y + ascender - bitmap_top;

换行和换列,分别对应的算式应该是:

x += horiAdvance;

y += height;

对于超出图像宽度和高度的话,需要你自己限制一下。我自己做了一下,不够字符的宽度的话,那么就会自动换行;图片的高度不够行数的话,余下的都会被忽略并不会被渲染。

输出效果

获得在程序中获得这些信息后,可以在渲染的时候对其进行排版。不过如果用在游戏的文字显示上的话,用FreeType一个个文字去渲染的方法重复渲染的次数会比较多,有比较好的方法就是统一做一张大的纹理,把用到的字都提前渲染好,需要的时候进行提取。程序的排版效果如下,比较简单的内存输出,不同宽度的、带基线的文字都能正确显示了:

 

posted @ 2013-07-19 22:09 YangZhao1992 阅读(...) 评论(...) 编辑 收藏