闲聊文本渲染技术的近期发展

在今年 7 月的 GUADEC 上 Behdad Esfahbod 做了一个题为 State of Text Rendering 的讲座,系统地综述了当前文本渲染技术的现状,顺带强调主要由他开发的 harfbuzz-ng 是未来发展的方向,4 个月过去了,最近文本渲染技术有了什么发展呢?这里谈谈我的一些印象和见解。

首先,harfbuzz-ng 到底想做成什么样子?我们知道底层的字体格式支持,开放的有 FreeType 一枝独秀,各平台私有的有 Win32 的 GDI font, Mac OS X 有 ATS 和 CGFont,上层的文本布局排版引擎,现在各家自有一套到两套:Windows 的 DirectWrite 和 Uniscribe;Mac OS X 有 Core Text 和 ATSUI,有 NSLayoutManager;GTK+ 有 pango,都是比较成熟的接口了,那 harfbuzz-ng 是要取代他们吗?

不是,也完全说不通,毕竟 pango 就是 Behdad Esfahbod 自己维护的,没理由拆自己的台。但是开放的 pango 等平台一直缺失的部分是 OpenType 复杂排版特性的支持,这一点 FreeType 没来得及解决,也因为和排版引擎关系太紧密,所以没法完全靠 FreeType 这种“字体格式解析库”来解决。harfbuzz-ng 要做的,正是在原来的 FreeType OpenType 排版代码的基础上,构建一个类似 ICU LayoutEngine 的、有简洁的 C API 的、支持 OpenType 特性的,而且还要比 pango 底层一些的库。

那不是和 ICU 重合了吗?ICU 一来是 C++ 的 API 用着比较累,而来确实也比较笨重,移植的时候够受的。ICU 虽然在近期版本里也开始提供 C 的排版引擎 API,但也只是试验性的。

所以总的看起来,Linux 下的文本渲染层次还真是够多的:GTK+ → pango/cairo → harfbuzz-ng → FreeType,同时 harfbuzz-ng 还可能用到 ICU, Graphite,在 Mac OS X 上还要用到 Core Text 和 Core Graphics。

细分层带来的好处就是不同的需求可以选择合适的 API 来实现:比如你要在图形界面上显示一段文字,就用 GTK+ 的 label;要绘制小段的文本,就用 cairo 和 pango;要高效率的、轻量地绘制大量的文本,就用 harfbuzz-ng 来自己攒一个排版引擎 — 大部分浏览器都是这样,只不过在没有 harfbuzz-ng 的情况下,或者要直接用 FreeType,不得不多写很多代码,或者就用 pango 这种重量级的,性能又得不到保证。

在 8 月份,harfbuzz-ng 的 API 提议已经出现,并在不断讨论中完善 (要我说,本来这个星球上有经验参与讨论的也最多不超过 20 个人,不如大家到一个屋子里开个会搞定得了)。

XeTeX 的作者 Jonathan Kew 虽然仍然在开发 TeXworks,但工作的重心已经放到了 Mozilla Firefox 3.6 的 WOFF 格式和 OpenType 复杂排版支持上,最近的一个视频里 Jonathan 提供了一个很棒的概览,有这样的一些特性之后,在浏览器里做一些认真的文本排版才可能成为现实 — 可惜浏览器仍然缺乏好的断行算法实现。这部分工作其实就是基于 harfbuzz-ng 的。而 WebKit-GTK 版本也开始了基于 harfbuzz-ng 的实现。

当然了,畅想了一番美好未来之后还是要回到现实,目前我想做的一个项目,是开发一套能跨 iPhone OS 和 Mac OS X 的、轻量级的排版引擎,专门给文本阅读器用。这个工作的出发点是:

  1. iPhone 上缺少 (按我的标准) 足够好的文本阅读器,而既然我已经开始写 Textus 了,不如把它移植到 iPhone 上;
  2. iPhone 上没有 Core Text 这个层次的框架,要渲染文本要么用 NSAttributedString,要么用 WebView,他们的额外开销都太多,太重量级了;
  3. 轻量的方法有神秘的 private API CGFontGetGlyphsForUnichars,如果不愿意用 private API 呢,就只好像 cocos2d-iphone 那样自己去实现 cmap 载入的代码,非常痛苦;
  4. 即使这样,也不支持复杂的 OpenType 排版特性,甚至简单一点的连字 (ligature) 都不支持,对于一个文本阅读器这是不能忍受的。

所以觉得写个这样的引擎会比较有用:

  • 做到后端独立,比如可以选用 ICU (iPhone OS 上), Core Text (Mac OS X 上), harfbuzz-ng
  • 能够支持 OpenType 复杂排版特性
  • 至少支持好大部分西方字符和 CJK 字符
  • API 尽可能的简单

最近刚刚开始做一些试验,比如用 Core Graphics 完成了一个简单的 CGFontInstance 给 ICU 用,这在目前还没看到类似的工作。

Author: jjgod

A software engineer from China, working on text rendering for a fruit company. Interested in typography and science fiction.

Leave a Reply

Your email address will not be published. Required fields are marked *