文字渲染相关知识
字体
计算机字体(英语:computer font),简称字体(font),是包含有一套字形与字符的电子数据文件。
字体类型与格式
现今计算机使用的绝大多数字体,都是属于点阵字体或者轮廓字体二者之一。
点阵字体(Bitmap Fonts)
点阵字体通过点阵表现字形,其本质上只是一组图片。每一种字体变体都包括一组完整的字符,一个字符占一张图片。假设总字符数量为3,即包括三个字符,提供粗体和斜体的组合(即无、粗体、斜体、粗斜体四种变体),该字体总共有12张图片。
由于受到容量和绘图速度的限制,早期电脑多采用点阵字体,而现在已不再被广泛使用,原因是其他字体编码方法在视觉效果和功能都超过了它。但它在某些 场合(特别是在显示小字号的汉字字符的时候)还是很有用的,因为可缩放字体缩小过多笔画的字时,容易挤成一片导致无法辨认,因此小号字体仍使用点阵格式。
点阵字体被用于Linux终端,Windows修复控制台和嵌入式系统。
每种字形的每种形式和每种尺寸的图像都由点或者像素组成的矩阵构成。由于位图的原故,点阵字体很难进行缩放,特定的点阵字体只能清晰地显示在相应的字号下。但对于 12-16 px 的小号汉字来说,点阵字体往往比其它类型的字体在屏幕上有更好的显示效果。
轮廓字体(Outline Font)
使用贝塞尔曲线、绘图指令和数学公式来描述每种字形,使得字体可以适应各种尺寸。轮廓字体,又称矢量字体、描边字体,主要包括:
PostScript字体
PostScript字体由Adobe公司为专业数字排版开发。它使用PostScript,字形以3次贝兹曲线描述,因此一组字体可以通过简单的数学变形放大或缩小。但是事实上,很大或很小的字体需要额外的信息(hints)才能好看。其下又分为Type1, Type3,OCF, CID等类型。
- Type 1字体只有1字节,因此只能容纳256个字符。它使用Adobe私有的hinting系统,价格昂贵。需要注意的是,很多被称为Type1的字体实际上是Type3或Type5。
- Type 3字体完全支持PostScript描述性语言,可以勾画出较复杂的字体,如:渐变。
- OCF字体:中文日文等双字节语言可以使用的字体。按照PostScript类型,它属于Type0 (也就是Type1或3的组合形式)
- CID字体:OCF字体的改良。具有异体字切换功能。按照PostScript类型,多数字体属于Type9(基于TrueType的CID字体等除外)
TrueType字体
TrueType是一种最初由苹果电脑公司开发的字体技术。考虑到Type 1字体太昂贵,有意用TrueType字体替换Type 1字体。像Type1字体一样,贝兹曲线用于描述字体,并可以内置点阵字体。现在它十分普及,在所有主要的操作系统上都有使用。能用PostScript打印机处理的TrueType字体称为Type42.
OpenType字体
OpenType字体是为了实现Windows和Macintosh系统兼容,而产生的一种新字体格式;具有TrueType和PostScript两种形式,具有高度的异体字切换功能,并有动态下载功能,因此不需要打印机字体。若按照PostScript的类型分类,它属于Type2型,可以控制字体文件数据大小。
常见格式
- bdf 与 bdf.gz – 点阵字体,bitmap distribution format(位图布局格式)的缩写,后者表示以 gzip 压缩的 bdf。
- pcf 与 pcf.gz – 点阵字体, portable compiled font(可移植编译字体)的缩写,后者表示以 gzip 压缩的 pcf。
- psf,psfu与psf.gz,psfu.gz – 点阵字体,前两者分别是 PC screen font(电脑屏幕字体)与 PC screen font Unicode(Unicode 电脑屏幕字体)的缩写。两者分别表示用 gzip 压缩的 psf 与 {{ic|psfu}(不适用于 X.Org)。
- pfa 与 pfb – 矢量字体,分别是 PostScript font ASCII 与 PostScript font binary 的缩写。PostScript 字体内带有打印指令。
- ttf – outline,TrueType 字体。作为 PostScript 字体的替代。
- otf – outline,OpenType 字体。带有 PostScript 打印指令的 TrueType 字体。
在多数情况下,TrueType 和 OpenType 的技术差异可以忽略,一些带有 ttf 扩展的字体实际上是 OpenType 字体。
常用字体相关库
Fontconfig
- Fontconfig 包含两个基本的模块,即读取XML文件并建立内部配置的配置模块和接受请求的字体样板并返回最接近所需字体的匹配模块。
Freetype
- Freetype库是一个完全免费 ( 开源 ) 的、高质量的且可移植的字体引擎,它提供统一的接口来访问多种字体格式文件,包括TrueType, OpenType, Type1, CID, CFF, Windows FON/FNT,X11 PCF 等。支持单色位图 (homochromous bitmap) 、反走样位图( anti-alias bitmap )的渲染。 Freetype 是高度模块化设计的程序库。Freetype 提供 libXft/cairo 如何画字的信息,包括处理 anti-aliasing 或 hinting. 因此 freetype 的改变会影响到 libXft/cairo 画出来的字,而 Fontconfig 的改变会影响到 libXft/cario 如何去选字来画。
Pango
- Pango 是个开源的整合到GTK+2的渲染国际化文本文件的库,pango 的名字是由 希腊语 "Pan" (Παν; lit. all) + 日语 "Go" (語; lit. language)组合成。也就是All language,Pango负责多国语言文本(如同一个文本文件中由英文,日文,中文等不同的语系组成)的渲染。需要注意的是Pango属于高级的库, 不参加画字的过程。
GTK+(基于DirectFB)的字体绘制是通过pango+freetype+fontconfig三者协作来完成的,其中, fontconfig负责字体的管理和配置,freetype负责单个字符的绘制,pango则完成对文字的排版布局。Freetype是一个操作字体的 函数库,它不但可以处理点阵字体,也可以处理多种矢量字体,包括truetype字体,为上层应用程序提供了一个统一的调用接口。
文字渲染流程
现在的 Gtk/Gnome,KDE/Qt 程序都是程序自己绘制字体为图片,然后将绘制好的图片显示到 X-Window。
大体上是:
1. 程序自己先提出想要某个字体(比如想要“sans-serif“字体名)
2. 程序使用 fontconfig 库读取 fontconfig 配置(比如 /etc/fonts/ 下那堆 .conf xml 文件)
得知 "sans-serif" 是一个合成的虚拟字体,是依次尝试使用 DejaVu、文泉驿微米黑等实际字体合成,
并且知道需要开启 AA 反锯齿、开启微调来渲染绘制字体,屏幕 RGB 次序是 XXX
3. 程序从 fontconfig 得知字体配置后,查找出字体实际文件(比如某个路径的 .TTF)
用 FreeType 库打开字体文件,并依照字体文件信息渲染绘制出字符的图片
(多数情况下应用程序并不直接用 FreeType 库,而是通过 Gtk 库调用 Pango 2D 绘图库,再让 Pango
库自己去处理 FreeType、Fontconfig 之类“细节”问题,以及适当排版)
4. 绘制好字符图片后,将它发送到 X-Window 屏幕(比如通过 Xinerama 扩展,或干脆 OpenGL)
5. 于是屏幕上就显示出了你所看到的画面
KDE/Qt 程序跟 Gnome/Gtk 程序字体处理大体上差不多,
只是中间用的并非 Pango,而且对 Fontconfig 的解析过程稍有差异,
但都同样是程序自己绘制出字符图片,再发送到屏幕显示,
X-Window 服务和 Linux 内核都不参与字体处理。
文字渲染相关概念
Hinting 与 Autohinter
- Hinting 用来最佳化字型显示的方法。由于屏幕的像素有限,向量字型的缩放需要有更多的考虑, 例如当一条线位在两个像素格子中间时, 该取左边的格子还是右边的格子? 如果这方面的控制没有做好,就常常会出现字型的衬线没有对齐,或是小字歪七扭八的情况。 Hinting 是额外的信息, 它告诉 renderer 该如何处理这些细节的部份,使得向量字在小字的时候能够好看。也因此 Hinting 是非常费时费人力的工作,TrueType 字型很多,但是有良好 Hinting 的字型不多。拙劣的 Hinting 就会让字变得很难看。
为了稍微改善这个问题,freetype 有 autohint 的功能,可以自动为没有 hint 的字型做 hinting 的工作。另外由于 TrueType 的 hinting 是有专利的,不能完全自由地使用, autohint 就不受这个限制。autohint 自然无法做得像人力的 hint 一样好,不过至少比没有 hint 要好些。话虽如此,对于许多笔划复杂的文字 (如中文) 目前 freetype 的 autohint 还做得不甚完美,而因为建立完整的 hinting 的难度,即使是英文字,原本就很高,内建有 hinting 的中文字型就少之又少了。所以常常有人抱怨中文字在屏幕上很难看,就是没有理想 hinting, 或者是使用了 autohinter 所造成的一些反效果。
AA(Anti-aliasing)
- Antialiasing 是将字体在后台先以数倍的大小来绘画,然后再缩成想要的大小,未满一格的格子用灰阶补点。由于原本 X 所支持的 logic 运算不敷使用,所以才用 XRender 的 extension 来达成目的。 Antialiasing 会给人一种朦胧的感觉,习惯了Windows XP 下清晰,锐利的字体显示时,Antialiasing 会让人不太适应,会让用户觉得Linux下的字体显示不如Windows XP。但是,其实 Antialiasing是一种很先进的显示技术 ,当长时间显示器上阅读的时候,Windows XP 下的锐利的字体显示风格,会让眼睛更加容易疲劳,使用Antialiasing,字体的显示更加柔和,更加适合长时间的在显示器上阅读文档,减少眼睛的疲 劳。