FreeType解析矢量字体存在的问题以及优化技巧

一、前言

首先,再阅读本文之前需要对 FreeType 的使用方法有基本的了解,可以参考:FreeTpye库学习笔记:将矢量字体解析为位图

二、FreeType 存在的问题

矢量字体(TrueType)通过数学曲线来描述字形,包含字形边界上的关键点、连线的导数信息等。

FreeType 解析矢量字体的过程是将字形关键点按照规则连线变成字符轮廓,最后再将轮廓填充成点阵字。

很明显,在这个过程中,字形关键点是字体轮廓精准的度量,而位图则可以看成网格状态的,单位为像素,那么将坐标点转化为位图的过程势必会导致精度丢失,比如点坐标为(1.2, 2.8),那么转换成位图则变成了(1, 3)。

并且由于 FreeType 为了提高运算速度,采用位移的方式进行数学计算势必会导致精度丢失更加严重,在处理一些小字号字体或像素字体时,容易发生像素块粘连的现象。

例如,像素字体的字形如下图所示:

在这里插入图片描述

但解析后得到的位图如下,可以明显看见像素粘连:

在这里插入图片描述

三、针对 FreeType 存在问题的优化技巧

3.1 提高 FreeType 解析字体的精度

虽然 FreeType 解析字体时精度丢失无法避免,但提高运算精度依然可以优化显示效果。

FreeType 提供两种计算二次贝塞尔曲线的精度,低精度 0.5 个像素,高精度 0.0625 个像素。其默认采用低精度进行运算,通过设置标志位 FT_OUTLINE_HIGH_PRECISION 可让 FreeType 采用高精度运算。

uint32_t flags = FT_LOAD_DEFAULT | FT_LOAD_RENDER | FT_LOAD_NO_AUTOHINT | FT_OUTLINE_HIGH_PRECISION;

3.2 关闭 auto_hint

要了解 auto_hint 首先需要知道什么是 hinting 。

hinting 用来优化字体显示的方法。由于屏幕像素有限,矢量字体的缩放需要有更多的考虑,例如当一条线在两个像素格子中间时,该取左边的格子还是右边的格子?如果这方面没做好,就常常会出现字形衬线没对齐、或小字号字形歪七扭八、或像素块粘连到一起的情况。

hinting 是额外的信息,它告诉 渲染器 renderer 该如何处理这些细节部分,使矢量字在小字号时显示效果更好,因此,hinting 是非常费时费人力的工作,TrueType 字体很多,但是有良好 hinting 的不多,拙劣的 hinting 会让字变得很难看。

为了改善以上问题,FreeType 提供了 auto_hint 功能,并默认开启该功能,它可以自动为没有 hinting 的字体做 hinting 工作,auto_hint 肯定无法做得像人力 hinting 一样好,对于许多笔画复杂的文字(如中文)效果不佳,并且对于小字号的复杂字形,经常造成一系列反效果,最典型问题的就是像素粘连。

因此,经过多次测试,关闭 FreeType 的 auto_hint 功能可以对大多数矢量字体的中文显示效果更好,通过设置标志位 FT_LOAD_NO_AUTOHINT 可关闭该功能。

uint32_t flags = FT_LOAD_DEFAULT | FT_LOAD_RENDER | FT_LOAD_NO_AUTOHINT | FT_OUTLINE_HIGH_PRECISION;

四、总结

经过以上优化,FreeType 解析像素字体后得到的位图效果如下:

在这里插入图片描述

由此可见,对于字号较小的复杂字形以及像素字体,提高 FreeType 的解析精度并关闭 auto_hint 功能能有效提高显示效果。

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值