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 ...
随机推荐
- 全局函数的Result一定要每次都初始化,否则上次的结果会被保持到下一次继续使用
测试半天,原来是因为这个原因.下面例子中,Result:=''必须写,否则其结果会被累计,真是昏倒!! function MyPaths(tache: IXMLTaskType) : String; ...
- PowerShell远程连接主机进行会话
Get-ExecutionPolicy #脚本的执行策略set-ExecutionPolicy 枚举值 不同的策略,执行脚本的权限不同 允许开启远程 Enable-PSRemoting 添加域账户或者 ...
- JAVA Stack栈和Heap堆的区别(转)
首先分清楚Stack,Heap的中文翻译:Stack—栈,Heap—堆. 在中文里,Stack可以翻译为“堆栈”,所以我直接查找了计算机术语里面堆和栈开头的词语: ...
- Grok 正则捕获
Grok 正则捕获: \s+(?<request_time>\d+(?:\.\d+)?)\s+ 回顾下: (?:pattern) 匹 配 pattern 但不获取匹配结果,也就是说这是一个 ...
- rsyslog input 不支持变量
input(type="imfile" File="/usr/local/apache-tomcat-7.0.55_8082/logs/localhost_access_ ...
- UML--核心元素之用例
Use case 一个系统就是由各种各样的愿望组成的. 一个用例就是与参与者actor交互的,并且给参与者提供可观测的有意义的结果的一系列活动的集合. 例如你想做一顿饭吃,你需要完成煮饭和炒菜两件事情 ...
- 使用STS 创建spring配置文件
1.创建一个bean文件 2.输入文件名applicationContext.xml 3.这里会自动显示模板文件 4.创建后,自动填充头不定义 到这里就可以发现,我们创建spring文件时,需要的配置 ...
- POJ 3114 Countries in War(强连通+最短路)
POJ 3114 Countries in War 题目链接 题意:给定一个有向图.强连通分支内传送不须要花费,其它有一定花费.每次询问两点的最小花费 思路:强连通缩点后求最短路就可以 代码: #in ...
- OCR怎么能离开扫描仪呢?
说起OCR,说来说去就是和各种各样的图片打交道. 所以图片的质量很的关键. 说起图片的质量,不得不提的就是图片的採集. 眼下最靠谱的图像採集来源就是扫描仪. 扫描仪的话就大有说法,最靠谱的扫描仪,扫描 ...
- AfxBeginThread的介绍/基本用法
AfxBeginThread 用户界面线程和工作者线程都是由AfxBeginThread创建的.现在,考察该函数:MFC提供了两个重载版的AfxBeginThread,一个用于用户界面线程,另一 ...