TTF文字的渲染
一、简介
- 全称:TrueType Font
- 特点:渲染较快的矢量字实现方案,在电子设备的屏幕上显示效果比较好(相对 type1 而言)
二、TTF的字形轮廓描述
![](https://img2020.cnblogs.com/blog/1034810/202103/1034810-20210321224841261-863283953.png)
- TTF为每个字符保存了一系列的点以及点的连接顺序:
- on-curve(图中的实心点)
- off-curve(图中的空心点)
- 组成TTF字形的两种线型:
- 线段(on-curve ~ on-curve)
- 二次贝塞尔曲线(on-curve ~ off-curve ~ on-curve)
- 多段的贝塞尔曲线,可以省略掉两个off-curve中间的on-curve,例如右下角的两个off-curve。
三、TTF的字符度量
字符度量用于处理将字符组成句子,段落的摆放问题。
![](https://img2020.cnblogs.com/blog/1034810/202103/1034810-20210321224900544-961530875.png)
- 关键信息
- 边界包围盒(xMin,yMin,xMax,yMax)
- 步进包围盒(originX, advanceX, originY, advanceY)
- 例子
![](https://img2020.cnblogs.com/blog/1034810/202103/1034810-20210321224921089-932184429.png)
绿色方框是边界包围盒
四、字体库freetype 及 字形光栅化
- 往哪边着色?
![](https://img2020.cnblogs.com/blog/1034810/202103/1034810-20210321224939212-1848298213.png)
- 非0环绕数法则
- 从点p向外作任意方向的一条射线,多边形的边从左到右经过射线时环数减1,多边形的边从右往左经过射线时环数加1,最后环数不为0,即表示在多边形内部。
![](https://img2020.cnblogs.com/blog/1034810/202103/1034810-20210321224955815-141681243.png)
- 如何着色?
- 对每个像素的中心计算非0环绕数来判断要不要上色
- 字号较小时带来的走样问题:
![](https://img2020.cnblogs.com/blog/1034810/202103/1034810-20210321225012077-1277485302.png)
- freetype
- 开源的字体库,可以加载ttf字体并生成字符位图(bitmap)
- 生成位图的过程
- 主轮廓的点被缩放到适当的大小。
- 按比例绘制的轮廓按照其相关说明进行网格对齐。
- 字距微调,生成适合光栅显示的位图图像。
![](https://img2020.cnblogs.com/blog/1034810/202103/1034810-20210321225027447-1572735967.png)
网格对齐是核心过程,freetype内部有复杂的补偿算法。TTF文件也可能对这个过程提供指导信息,例如 interpreter(一段编好的程序)。一段interpreter对应一个字符的一个字号。
五、.ttf文件的额外信息
- 字形微调信息,某些字型对需要特殊的间距。
![](https://img2020.cnblogs.com/blog/1034810/202103/1034810-20210321225050181-1757713853.png)
- 某些字符小字号(1-20)的点阵字(即位图)。
六、游戏中加载TTF文字的优化建议
- 由字体轮廓生成位图是一个比较耗时的过程,游戏引擎一般都会缓存已经生成的字体纹理,通常将其放到一个大纹理中。尽量避免在一帧里面加载大量未加载过的字符。
- 对于同一个字符,游戏中如果使用了两种的字号,会生成两次,并缓存两份位图。在游戏中固定使用几种特定字号;或者使用邻近字号通过缩放的方式生成新的字号可能是一个更好的方案。
- 以上对cocos和unity都适用
参考资料: