Font Rending 的 Hint 机制对排版的影响
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 机制对排版的影响的更多相关文章
- Cassandra1.2文档学习(12)—— hint机制
参考文档:http://www.datastax.com/documentation/cassandra/1.2/webhelp/index.html#cassandra/dml/dml_about_ ...
- [Android] 字体使用dp单位避免设置系统字体大小对排版的影响
[Android] 字体使用dp单位避免设置系统字体大小对排版的影响 以魄族mx3为例,在设置->显示->字体大小中能够选择字号大小例如以下图: 图1. 魄族mx3 会导致软件在有固定定高 ...
- android:hint属性对TextView的影响
近期看到同事写的一段代码,非常easy吧就是: <LinearLayout android:layout_width="wrap_content" android:layou ...
- iOS开发事件分发机制—响应链—手势影响
1.提纲 什么是iOS的事件分发机制 ? 一个事件UIEvent又是如何响应的? 手势对于响应链有何影响? 2.事件分发机制 2.1.来源 以直接触摸事件为例: 当用户一个手指触摸屏幕是会生成一个UI ...
- Redis的缓存策略和主键失效机制
作为缓存系统都要定期清理无效数据,就需要一个主键失效和淘汰策略. >>EXPIRE主键失效机制 在Redis当中,有生存期的key被称为volatile,在创建缓存时,要为给定的key设置 ...
- PHP的autoload机制的实现解析
在使用PHP的OO模式开发系统时,通常大家习惯上将每个类的实现都存放在一个单独的文件里,这样会很容易实现对类进行复用,同时将来维护时也很便利 一.autoload机制概述 在使用PHP的OO模式开发系 ...
- PHP自动加载__autoload的工作机制
PHP自动加载__autoload的工作机制 PHP的懒加载lazy loading 在 2011年11月12日 那天写的 已经有 4559 次阅读了 感谢 参考或原文 服务器君一共花费了 ...
- 深入理解Redis主键失效原理及实现机制
http://blog.jobbole.com/71095/ 对于缓存失效,不同的缓存有不同的处理机制,可以说是大同中有小异,作者通过对Redis 文档与相关源码的仔细研读,为大家详细剖析了 Redi ...
- 深入理解Redis中的主键失效及其实现机制
参考:http://blog.sina.com.cn/s/articlelist_1221155353_0_1.html 作为一种定期清理无效数据的重要机制,主键失效存在于大多数缓存系统中,Reids ...
随机推荐
- python 文件中的中文编码解决方法
# -*- coding: utf-8 -*- #查看安装的SDK默认的编码字符集在脚本中可以修改你的编码格式, 方法如下:#sys.getdefaultencoding()#reload(sys)# ...
- windows下wchar_t* 转char*
这个在windows下很常见,常用,留个档. 一般用这个函数: size_t wcstombs( char *mbstr, const wchar_t *wcstr, size_t count ); ...
- 【转】ubuntu设置PATH----不错
原文网址:http://no001.blog.51cto.com/1142339/554927 试了好多遍,多无效.. 最后在/etc/enviroment下设置才有效. 不过让有一些未解问题 我使用 ...
- Controlling Access in Java
Referrence: Oracle Java Doc Two levels top level: public, or package-private (no explicit modifier) ...
- Linux TCP/IP 协议栈之 Socket 的实现分析(一)
内核版本:2.6.37参考[作者:kendo的文章(基于内涵版本2.6.12)] 第一部份 Socket套接字的创建 socket 并不是 TCP/IP协议的一部份. 从广义上来讲,socket 是U ...
- iOS 3DES加密 和 java 3DES 解密
首先进入头文件: #import <CommonCrypto/CommonDigest.h> #import <CommonCrypto/CommonCryptor.h> #i ...
- VBA清除Excelpassword保护,2003/2007/2010均适用
Sub Macro1() ' ' Breaks worksheet and workbook structure passwords. Jason S ' probably originator of ...
- [转]轻量级 Java Web 框架架构设计
工作闲暇之余,我想设计并开发一款轻量级 Java Web 框架,看看能否取代目前最为流行的而又越来越重的 Spring.Hibernate 等框架.请原谅在下的大胆行为与不自量力,本人不是为了重造轮子 ...
- 伪元素first-letter(首字母变大)
让首字母变大 <p>Do you like to ride a bicycle?</p> p:first-letter{ font-size: 34px; }
- JS实现下拉框选中不同的项,对应显示不同的信息
实现的效果如下图: 页面代码 下拉框: <select id="select3" name="select3" onchange="showli ...