字体渲染 - Sub-Pixel Positioning【宝狼技术】

人们上网最主要获取的内容就是由文字。文字仍然是最为主要也是信息比特比最高的信息传达方式。所以对于浏览器来说,阅读体验是非常重要的一个环节。

最近做了不少涉及字体光栅化方面的工作,不如就乘此分享一些基本概念吧。

字体文件的格式主要是微软的TrueType以及苹果的OpenType,又分别有各自的ClearType以及字体光栅化的实现,技术争论持续了十数年,具体历史请各位参考wiki及搜索引擎大神们。不过作为企业,总是不能因为技术争论而停止产品开发,因此微软和苹果十多年前便进行了当时字体领域基础专利的交叉授权,当时相互提供的类库沿用至今。ClearType的主要目标是让字体边缘更加清晰,主要是采用子像素技术。

子像素,Sub-Pixel,就是说,一个黑色的像素通过两个像素点分别贡献自己的红色子像素以及蓝绿子像素,从而较为均匀的分布在两个像素之间,达到绘制比整数像素点更加精确的子像素的目的。
比如这条斜线:

缩小来看就会变成这样:

变成了一根既平滑,看上去也只有1pixel细的线。

在Sub-Pixel技术的支持下,ClearType的目的就能够很容易的达到。具体的ClearType的细节,也请参考许多前人的原创,我就不絮絮叨叨了。ClearType也是若干年前就已经在GDI中使用了,不是什么稀奇货。然而随着小屏幕设备的大量普及,缩放操作,也就是Zoom,变成了标配,无论是Windows 7还是嵌入式设备,都有缩放的需求,因此如何保持图像缩放的时候字体边缘仍然清晰,仍然提供良好的阅读体验就成为了一个考验。

在GDI中,由于只有整数接口指定字的位置,因此很难实现较好字体无级缩放并且保持光滑边缘。所以子像素技术再次被拿来实现字体无级缩放。早在6年多前微软的Microsoft Reader中就已经实验性的提供了基于子像素技术的字体渲染,不过可惜那个产品并没有很火,没有广为所知。不过基于子像素的字体光栅化技术开始在微软内部广泛受到重视,最新Windows 7所携带的DirectX 11中,就第一次提供了不基于GDI的字体光栅库,DirectWrite。

其实子像素技术很简单,子像素技术基础之上的字体无级缩放以及浮点定位也不会复杂到哪里去,我们看这张对比图:

先看图片下面一行,这是原始的GDI字体渲染结果加上无极缩放。

经过缩放之后,一个单词中各个字母的位置已经发生了细微的变化,原来字体库是依靠为每个字体大小提供一些Kerning、Hinting等调整参数来做到字体大小变化,但是每个字母仍然独立摆放位置,所以字间空隙就无法与字体放缩结合起来。比如图中的第三个字母v与第四个字母e之间,要么空间是0pixel,要么是1pixel,不可能根据无级缩放达到0.25pixel,所以就会让读者感觉这里第二个字母o与v距离比较近,v与e比较远。根据早年英美学者对于阅读速度的调查,这样的不匀称的字母间距会降低阅读速度最高40%。

其实需要做到无级缩放很简单,就是把空格也加进来一起使用子像素技术,把每个字母的调整参数计算在一起,然后一整个句子一起光栅化,就可以避免这样的不匀字间距。
图片中上面一行是使用了子像素技术进行无级缩放的,很明显虽然调整幅度很小(半像素级别),但是效果还是很明显(如果你不觉得,恩……或许至少对于老外是如此啦)


所以无级缩放下的完美阅读体验并不难实现,不过必须直接将字体光栅化库一起链接进来才可能效果最好,而且性能和内存会成为需要面对的最大问题。或许这也是为什么微软选择DirectX作为DirectWrite技术的平台的原因吧,高速并且直接访问显存,可能是唯一的性能选择。

希望那一天可以不用再忍受游戏中3D Surface上面那丑陋而模糊的字了。









posted @ 2009-07-29 23:33  珠宝狼  阅读(997)  评论(2)    收藏  举报