Font Rending 的 Hint 机制对排版的影响【转】

在设计一种 Font 时,设计者使用的是一个抽象的单位,叫做 EM,来源于大写 M 的宽度(通常英文字体中大写 M 的宽度最大)。EM 即不同于在屏幕显示时用的像素(Pixel)也不同于打印时用的点(Point; 1/72 inch),他是一种相对单位,随着字体和字号的不同变化。通常对于一个 12 号的字体一个 EM 的长度等于 12pt。

实际设计时会将 EM 分成更小的单位,一般成为 EM Unit,TrueType 中一般是 2048 Units = 1 EM,Type1 中一般是 1000 Unit = 1EM。假设在我们设计的字体中字母 a 的宽度为 998 Units,如果我们用 12 号字显示它,我们得到的字宽为 12 * 998 / 2048 = 5.84765625 Point。如果我们将这个字打印到纸上,在 2000 dpi 的打印机上我们需要放置 5.84765625 / 72 * 2000 = 162.434895833 个 Dot(可以将 Dot 理解成墨滴)。而实际上我们不可能得到 0.43 个 Dot,我们只能用 162 个点来描述字母 a。如果我们将同样的一个字母显示在屏幕上,一般来说屏幕多为 72dpi 或 96dpi,以 96dpi 为例也字母 a 需要 5.84765625 / 72 * 96 = 7.796875 个像素来显示,实际上我们得到的是 8 个。在排版时我们需要根据一个字符的宽度来计算下一个字符的位置,这里的问题是:由于输出设备的限制我们永远也不可能将字母放在理论中的位置,设备的分辨率越低结果偏差的越大。反锯齿能够在一定程度上缓解这个问题,但不总是能的到好的结果。

另外在字体渲染时有时候会出现这样的问题,字母 H 的两个竖笔画不一样粗,这通常跟字母在屏幕上的位置有关,为了解决类似的问题,字体设计时都会提供一些额外的信息来根据输出设备的分辨率调整笔画。这就是 Hint 机制,或者叫 Grid-Fitting。由于 Hint 的存在,同一个字母在不同的设备上输出会有不同的宽度,这对排版有很大影响。所见即所得的排版要求我们在屏幕和纸上有相同的排版结果。如果我们按照理论值排版,在屏幕上我们可能会看到不美观的输出,参见截图。如果我们按照屏幕 Fitting 值排版则不能够最大化的利用字体设计师的工作,他们仔细调整过的字宽不能在纸上还原。

下图是个程序示例(Java),展示了不同的渲染方式会得到不同的字体宽度和不同的渲染结果。图中左右半部分分别是没有使用反锯齿(左)和使用反锯齿(右)的效果,而图中上下半部分分别是使用整数坐标(上)和使用分数坐标(下)的效果。

在图上可以看出使用分数坐标的 M 具有不一致的间距。所有的这些都对实现“所见即所得”的排版软件带来了很大困难,在 FreeType 的主页上有一些有关的文章,参见这里。其中提出了两种解决方案:

There are two ways to achieve this: either use the scaled and unhinted glyph metrics when laying out text both in the rendering and printing processes, or simply use whatever metrics you want and store them with the text in order to get sure they are printed the same on all devices (the latter being probably the best solution, as it also enables font substitution without breaking text layouts).

为了确定主流排版/字处理软件是如何解决这个问题的,我使用同样的基准文档(Tahoma 12pt 大写 M)做了测试。在 MS Word 2007 & MS Word 2003 中的结果如下:

可以看出 MS Word 的渲染结果也有不一致的间距,另外每个 M 字符都完全相同,这意味着 MS Word 是将一个字符渲染出来,然后不断的贴图。这也是常见的做法,优点是速度快,不需要在每个位置重复渲染。

在 Adobe InDesign 中以高质量显示的结果如下:

可以看出 InDesign 的渲染结果也有不一致的间距,但是明显 Adobe 具有更好的反锯齿算法,视觉上很难发现不同,但放大后还是能够看得比较清楚。另外 InDesign 的每个 M 字符都不相同,也就是说 InDesign 是对每个字符单独进行渲染,难怪效果会好。

结论

1. 使用设备无关的(高精度的)方式进行排版.

2. 显示效果不好时,使用每个字符单独渲染的策略.

3. 有些时候需要根据输出设备的限制进行 Grid Fitting,比如在 AFP 中对字符的位置/宽度有很大限制.

Font Rending 的 Hint 机制对排版的影响的更多相关文章

  1. Cassandra1.2文档学习(12)—— hint机制

    参考文档:http://www.datastax.com/documentation/cassandra/1.2/webhelp/index.html#cassandra/dml/dml_about_ ...

  2. [Android] 字体使用dp单位避免设置系统字体大小对排版的影响

    [Android] 字体使用dp单位避免设置系统字体大小对排版的影响 以魄族mx3为例,在设置->显示->字体大小中能够选择字号大小例如以下图: 图1. 魄族mx3 会导致软件在有固定定高 ...

  3. android:hint属性对TextView的影响

    近期看到同事写的一段代码,非常easy吧就是: <LinearLayout android:layout_width="wrap_content" android:layou ...

  4. iOS开发事件分发机制—响应链—手势影响

    1.提纲 什么是iOS的事件分发机制 ? 一个事件UIEvent又是如何响应的? 手势对于响应链有何影响? 2.事件分发机制 2.1.来源 以直接触摸事件为例: 当用户一个手指触摸屏幕是会生成一个UI ...

  5. Redis的缓存策略和主键失效机制

    作为缓存系统都要定期清理无效数据,就需要一个主键失效和淘汰策略. >>EXPIRE主键失效机制 在Redis当中,有生存期的key被称为volatile,在创建缓存时,要为给定的key设置 ...

  6. PHP的autoload机制的实现解析

    在使用PHP的OO模式开发系统时,通常大家习惯上将每个类的实现都存放在一个单独的文件里,这样会很容易实现对类进行复用,同时将来维护时也很便利 一.autoload机制概述 在使用PHP的OO模式开发系 ...

  7. PHP自动加载__autoload的工作机制

    PHP自动加载__autoload的工作机制 PHP的懒加载lazy loading 在 2011年11月12日 那天写的     已经有 4559 次阅读了 感谢 参考或原文   服务器君一共花费了 ...

  8. 深入理解Redis主键失效原理及实现机制

    http://blog.jobbole.com/71095/ 对于缓存失效,不同的缓存有不同的处理机制,可以说是大同中有小异,作者通过对Redis 文档与相关源码的仔细研读,为大家详细剖析了 Redi ...

  9. 深入理解Redis中的主键失效及其实现机制

    参考:http://blog.sina.com.cn/s/articlelist_1221155353_0_1.html 作为一种定期清理无效数据的重要机制,主键失效存在于大多数缓存系统中,Reids ...

随机推荐

  1. [TYVJ] P1025 单数?双数?

    单数?双数? 背景 Background USACO OCT09 1ST   描述 Description Bessie那惨无人道的二年级老师搞了一个有 N (1 <= N <= 100) ...

  2. 【转】嵌入式Linux学习笔记

    一  嵌入式系统定义: 应用于特定环境的硬件体系. 二  两样非常重要的能力: 1.  掌握各种新概念的能力 2.  调试的能力( 包括软件, 硬件 ) 三  需要的基础知识: 1.  操作系统理论基 ...

  3. 最新版AltiumDesignerSummer9下载+破解

    下载地址:ed2k://|file|AltiumDesignerSummer9Build9.3.1.19182.7z|1875307483|e65d364bf987fb5dcfb81c081a1562 ...

  4. C# 序列化过程中的已知类型(Known Type)

    WCF下的序列化与反序列化解决的是数据在两种状态之间的相互转化:托管类型对象和XML.由于类型定义了对象的数据结构,所以无论对于序列化还是反序列化,都必须事先确定对象的类型.如果被序列化对象或者被反序 ...

  5. IOS回调机制——代理,通知中心以及Block

    Xcode5.0正式版 IOS7和Xcode5正式版在昨天正式可以下载.IOS7不多说了,交互设计,界面风格,操作的简化程度都属于比较领先的水平. 这里来说说Xcode5正式版,和以前的Xcode5测 ...

  6. Jquery 概念性内容编辑器

      概念性jQuery内容编辑器,这是一款非常有特色的jQuery编辑器,该编辑器支持文字.列表.视频.引用等功能,是一款小巧简洁,富有个性化的jQuery内容编辑器插件. 代码: <!doct ...

  7. Word Pattern II 解答

    Question Given a pattern and a string str, find if str follows the same pattern. Here follow means a ...

  8. Java 安装配置

    1.下载 进入官方网站,点击下载链接进入下载页面,选择合适的版本(如,jdk-6u31-windows-i586.exe)下载. 2.安装 双击jdk-6u31-windows-i586.exe文件, ...

  9. 利用智能手机(Android)追踪一块磁铁(三)

    更新磁铁追踪算法的源代码,Android Studio项目工程 github地址:https://github.com/amazingyyc/MagnetLocate 说明:将磁铁的位置信息封装成消息 ...

  10. C++中malloc/free和new/delete 的使用

    malloc/free 的使用要点 函数malloc的原型如下: void * malloc(size_t size); 用malloc申请一块长度为length的整数类型的内存,程序如下: int ...