字体渲染详解

两年前掀起的Web字体革命让众人遗忘多年的字体渲染话题再次浮现。Web字体赋予我们自由的同时也带来新的挑战。字体选择及使用并不仅仅只是风格问题,其背后的技术实现也值关注。

我们没办法控制网站访客所用的浏览器与操作系统,因此理解字体渲染原理有助于确保网站在各类情况下都适宜阅读。截至最近,我们手头可用的“web安全”字体仍屈指可数。虽然安全字体的种类非常少,但这些字体都是针对显示屏精心制作和调整过了的,因此在字体显示效果方面不用太担心。

如今,在选择网站字体方面我们已有极大的灵活性,然而将设计图转换成实际像素的过程并不流畅自然,操作系统厂商在字体渲染上采取不同的策略,而且还在随时间剧烈的演变中。随着对屏幕上字体的深入了解,我们会发现,这些字形(glyphs)的渲染会因操作系统和字体格式而存在明显差异。另外,如果字体缺少关键的要素——字体微调(hinting),一款设计优秀的字体在Windows操作系统下可能非常难看。

本文介绍了字体渲染的原理,字体渲染技术的形成,以及各类操作系统和浏览器所采用的渲染技术及原因,这样当你需要为下个项目选择字体的时候,你就清楚需要注意哪些细节才可确保高质量排印效果。

渲染策略

理想的形状(左),黑白渲染(中)及灰度渲染(右)

栅格化(Rasterization)

数字形态下,字符是用抽象化的图案绘制成的。当文本显示在屏幕上时,位置非常精确,理想的字体形状需要用一定数量的像素栅格显示。随着屏幕从单纯的打印输出预览设备变成实际的阅读载体,工业界开发出了越来复杂且先进的字体渲染方法,确保屏显字体易于阅读。

黑白渲染

最早人们是用黑白像素来显示字符形状,有时这种方法也被称为二值渲染(bi-level rendering)。目前打印机就仍在使用这种方法,由于打印机的高输出分辨率,打印的结果能很好地再现原图。但是在屏幕上,有限的像素无法很好地传递字体形状的微妙之处。虽然我们无法分辨单个像素,但是肉眼仍可觉察到弧形轮廓线上的毛刺。

灰度渲染

在上世纪90年代中期,操作系统开始采用非常巧妙的手段。尽管屏幕的分辨率非常低,但是操作系统可以控制每个像素的明暗。这就可以在栅格化图像中存储更多信息。

在灰度渲染模式下,处于字形边界上的像素变成灰色。该像素亮度取决于自身被理想字体形状所覆盖的面积比值所决定。这样,字体轮廓看起来就更平滑,字体设计的细节也得以再现。字体在屏幕上看起不仅清晰——而且还能体现字体本身特征及风格。

这种被称为抗锯齿的原理与图片从高分辨率转换成低分辨率时所用的重采样(resampled)原理是相同的。我们的眼睛和大脑可以解读灰色像素中的信息,并补充到原先锐利的字体轮廓中,因此,我们感觉到的字体形状与初始的形状就很接近。如果我们把报纸拿远点,报纸上印刷品质相对糟糕的图片着色看起来也会不错,这背后的原理是类似的。最近,加里·安德鲁·克拉克(Gary Andrew Clarke)在Art Remixed系列作品中就把这一原理运用到了极致。

次像素渲染

彩色像素增加了分辨率

第三代渲染技术的一个重要特征是引入彩色像素。如果我们将屏幕截屏放大,发现字体边缘呈红色和蓝色,那么我们便可断言它采用的是次像素渲染技术。

在LCD屏上,用来控制像素颜色和亮度的红、绿和蓝色次像素紧密排列。当次像素非常小时,我们不会把次像素视为单独的色点。我们对上图白点标注的“红色”像素近距离观察就会发现它采用的策略:所有次像素都可单独控制开与关。如果“空白”像素最右边的次像素是红色次像素,则其对应的像素点从技术上讲就是红色的。

LCD屏幕上的次像素渲染

如果我们需要降低图片色彩的饱和度,采用该技术的好处就显而易见。与单纯的灰度渲染相比,水平方向的分辨率翻了三倍。竖笔(vertical stems)的位置及粗细就可表现的更为精确,文本外观也就更为清晰。

目前渲染技术的应用情况

在显示文本时,几乎所有的浏览器都依赖操作系统的字体栅格器,在关注Web字体渲染时,我们需要留意的一个关键差异就是操作系统。不过,浏览器对字距调整(kerning)、连字(ligatures),以及下划线位置和厚度等方面的支持也存在不同,因此我们不可奢望所有浏览器(甚至是同一平台上的)都可获得完全一致的渲染效果。另外在Windows平台上,浏览器可以使用系统默认的技术——GDI技术渲染字体,也可使用DirectWrite技术渲染字体。

在深入了解渲染技术细节之前,我们首先了解下各渲染技术在浏览器上大致的运用情况:

各Windows浏览器所使用的渲染模式。

WINDOWS

在windows平台上,字体格式对渲染有重大影响。PostScript字体和TrueType字体之间就存在明显差别。这种差别并不是指两类字体引入浏览器的方式。只要底层的字体格式一样,我们看到的渲染效果就会相同。

尽管我们最好不要完全依赖命名规则来判断字体底层所用的渲染技术,但字体的文件格式还是可以给我们提供了一些线索。比如EOT和.tff文件一定是TrueType字体,而.otf文件通常是PostScript字体。但是还有一种封装类型的字体格式WOFF,它可包含其中任意一种字体格式。因此光看文件名的话,我们还不清楚它包含何种字体,因此也就不清出它可能采用的渲染技术。除了EOT或.ttf文件必然是TrueType字体外,其他文件格式包含的是何种字体还无法完全确定。因此在购买字体时,你最好对所购买的字体做进一步研究。

TrueType 和 PostScript 区别在于在描绘曲线时所有的数学方法不一样——光栅器(rasterizers)对这点没做过多关注。只有需要编辑字形的时,字体设计人员才会觉察到两者的区别。另一个更重要的区别是所采用的字体微调方法。PostScript 字体包含字母组成的各类要素的位置抽象信息,而TrueType字体则包含了详细的底层指令,直接控制渲染过程。然而两种渲染方式的实际差异并不在于概念上的区别,而是源自微软只对TrueType字体应用新渲染引擎的决定。

WINDOWS: TrueType 字体


Windows 灰度模式下的TrueType字体渲染效果

在Windows XP 上,许多浏览器采用灰度模式渲染文本的。尽管渲染效果比不上Mac OS采用的次像素渲染技术,但字母在大尺寸下效果不错,边缘很平滑。

Windows GDI ClearType模式下的TrueType字体渲染

ClearType是微软对次像素渲染技术的一次借鉴。它最先供GDI使用,GDI是经典的Window应用程序接口(API)。尽管在Window XP平台上已可以使用,但是所有浏览器并未使用该技术。在Windows 7和Vista中,ClearTyep才默认开启,从而成为使用最为广泛的渲染技术(如果我们把所有的互联网用户算在内)。不过需要注意的是,这项渲染技术只运用在TrueType类的Web字体上——GDI-ClearType技术没运用在PostScript字体上。

这项渲染技术有一个很奇怪的地方,微软水平方向上吸取了次像素渲染技术的优点,但是却彻底放弃了对字体垂直方向上平滑度的改进。因此ClearType实际上是次像素和黑白渲软技术的混合。结果字体轮廓线上出现锯齿,在大尺寸下,这点尤其明显。曲线顶部和底部的锯齿看起来非常不舒服,但是无法避免——即便是最好的字体微调也无法让其消失

对于大尺寸的字体,ClearType在渲染质量是一种退步。水平方向上精确度带来的好处并不明显,而粗糙的渲染轮廓却毁了整体的效果。


DirectWrite模式下的TrueType字体渲染。

未来是光明的,至少对于Windows字体的渲染而言是这样的。在GDI技术的继任者DirectWrite中,微软为ClearType增加了垂直方向上平滑度。新的渲染模式(目前IE9在使用)在所有尺寸下都可提供平滑而精确的渲染。它与Mac OS的主要区别是Windows的DirectWrite仍试图将轮廓与全像素高度(full pixel heights)对齐。字体微调得当的话,此举可以获得更好的渲染效果。另外,DirectWrite可以进行次像素定位(subpixel positioning),从而使得字符间的间隙与设计的完全一致,另外该技术改善了字体纹理总体的匀称度。

WINDOWS: PostScript 字体

GDI灰度模式下PostScript字体渲染。

在使用GDI渲染的浏览器中,PostScript类型的Web字体是通过灰度渲染显示的。不同于流行的GDI-ClearType模式,这种渲染模式使得字体轮廓平滑过度。与TrueType字体的微调不同,PostScript字体的微调要简单,甚至可以自动完成。

DIrectWrite模式下的PostScript字体渲染。

DirectWrite不仅可以让轮廓更为平滑,它也使用次像素渲染技术渲染Postcript字体。不过与TrueType字体渲染还是有些不一样,为了更能真实的反映笔画粗细。它使用了更多的灰色像素。该技术做了相当多的权衡,非常接近Mac OS的渲染效果。

未来某个时候(浏览器厂商及用户采用新技术的速度不会如我们期望的那样快),DirectWrite将取代Windows陈旧的渲染方式,我们不用在纠结于是选择TrueType的Web字体还是选择PostScript的web字体。

WINDOWS: 未微调字体


灰度模式下的未微调字体。

在Windows老式的灰度模式下,完全未做微调的字体效果出奇的好。因为字体未通过微调使自身与全像素“对齐”,另外栅格器也未作强制处理,其效果很接近iOS上的字体渲染。遗憾的是,目前来看未微调字体不宜使用。见下图

GDI-ClearType渲染的未微调TrueType字体。

有关Web字体渲染质量的诸多讨论中就提到过,GDI-ClrearType极度依赖良好的微调。水平方向上的笔画需要通过微调精确定义,不然笔画的宽度可能会恰当。在大尺寸情况下,微调也极为重要。未微调字体在轮廓线未正确对齐像素网格的地方会突出一些“结疤”出来,上面例子就可以看到这点。

DirectWrite模式下的未微调字体渲染。

在DirectWrite模式下,未微调的PostScript和TrueType这两种Web字体的渲染效果几乎完全相同。这两种格式的文本字体仍需要良好的微调才可确保笔画的清晰和一致性。屏显字体甚至可以侥幸避免未微调的不良后果,因为在大尺寸下,微调与否区别不大。

MAC OS X

OS X上的字体渲染

在Mac OS系统上,所有浏览器使用的是Quartz渲染引擎。TrueType和PostScript字体都是以同样的方式渲染的,因此字体微调(hinting)被忽略了,而这正是两类字体在概念上最大的差别。Mac OS的次像素渲染技术非常牢靠,因此这是我们最不用担心的一个平台。栅格器不会试图理解构成字体的笔画及特征。因为万物都可用暗像素来呈现。字母形状不会解读,因而也就不会出现曲解的情况来。Quartz渲染引擎非常可靠,因为它不擅作主张。另外苹果似乎也会应用一些精妙的自动化措施增强渲染效果,但是这类自增强的技术没有文档说明,也完全超出我们的控制。

不过在某些情况下,这类技术也会导致一些不理想的效果。比如在上面的这个例子中,大号的“T”因为其理论的高度不是全像素值,因此在字母顶部有一行模糊的灰线。而且Mac OS也不会强迫字母对齐。这点不受字体创作者控制。不过,这类模糊只会在特定的字体大小下才会发生。因此一般只需选择稍不同的字体大小即避免此问题。稍微试错后,我们便可找到看起来舒服而又清晰的字体大小。

在Mac 上另外碰到的一个难以控制的现象是,字体会渲染的更重些。在文本字体大小下,这点差异尤其明显。同样的字体在Mac OS上看起来有点浓稠,而在Windows上则看起要清淡些。

iOS

iOS中的字体渲染

iOS上的字体渲染遵循与Mac OS 一样的原理——两者之间的主要区别就是iOS目前尚未运用次像素渲染技术。原因可能是当设备旋转后,系统需要重新运算并渲染结果。因为次像素的排列方向发生变化了,另外苹果想尽可能较少CPU的使用。

结论

网站访客所用的操作系统及浏览器差异很大。有些是因为没及时更新,有些是因公司规定导致的,不是用户的错。我个人的意见是应该尽可能的给用户呈现最佳渲染效果,而不是指责操作系统厂商,或是要求用户换成更好的系统。

在Mac OS和iOS上我们对渲染很难有任何控制权,但这可以接受,因为一般情况下渲染引擎非常可靠。不过有一个问题就是字体渲染的太过浓稠。或许有一天,Web字体服务可以根据不同的平台提供稍浓或者稍淡的字体来改善字体的一致性。

在Windows上,微调极为重要,尤其是对TrueType字体而言(这是IE6-IE8唯一接受的Web字体格式)。除此之外,选择TrueType还是选择PostScript字体格式也会对渲染结果产生重大影响。除了小号微调字体外,PostScript格式在渲染效果方面不逊于甚至由于TrueType格式,另外字体的制作过程也要简单。尽管DirectWrite让Windows上的字体渲染效果更加愉悦,但是提供微调良好的字体仍有必要。

实际应用:改善屏显字体的渲染效果

一些Web字体提供商(比如Typekit和Just Another Foundry)已经开始提供PostScript格式的屏显字体。

不同渲染环境下的JAF Domus Titling字体

在IE6至IE8中,GDI CleartType的锯齿无法避免,其他环境下GDI ClearType可以得到平滑的渲染效果。IE6-IE8浏览器的市场份额仍然很大,目前还不适合提供不无法清晰渲染的字体,这意味着我们仍需要良好微调的字体,

Typekit上Underware设计室设计的Bello字体就是PostScript格式的Web字体(右),它比左边的TrueType字体轮廓要顺滑些。

Typekit开始采用混合策略,提供PostScript格式的屏显字体,以便在Windows GDI模式下获得更为顺滑的渲染效果。但是这需要对字体视觉效果制定一些评判依据。

“如何定义屏显字体?”你可能会问,实际上的确很难画出一条清晰的界线来定义屏显字体。一些字体制作商提供手工微调的高品质TrueType字体,用做正文文本字体也很不错(可惜的是在转换成PostScript字体后它会丢失微调信息)。一些文本字体很有可能在大尺寸的情况下使用。因此理想的情况是同一字体提供两套不同的格式。不过这会增加用户界面(和后端)的复杂度,目前还不适合采取这种方式。

未来的发展

越来越多的字体设计师开始留意使用Web字体所带来技术疑难问题,尤其是TrueType的微调。随着Web字体产业的增长,字体设计师会针对屏幕显示的特点。采取一些措施优化字体。不久的将来,我们有望看到大量精心打造的新字体面世(至少是对现有字体的更新)。

随着屏幕分辨率的增加(以及对栅格器的重大改进),我们慢慢地不用在担心字体渲染的技术细节。采用GDI渲染模式的浏览器必将拖后腿(boat anchor),正因为这样,我们未来几年仍没办法大规模那些未作微调的TrueType字体。只有当这类浏览器用户比重降到很小时,TrueType字体的微调处理(这个过程相当耗时,并且需要相当高的技巧)才不会那么重要。尽管目前市面上的大多数Web字体都是TrueType格式,我仍希望字体行业能大规模转换成PostScript字体,因为这种格式几乎是所有字体设计师制作字体所用的原生格式(这种字体的制作要容易些)。

相关资源

●《FireFox 6中的DirectWrite文本渲染》 Mozilla 官方博客

●《JAF Domus Titling  Web 字体》 Just Another Foundry

●《Typekit更新:改善Windows平台上的字体渲染》Typekit网站博客

●《Open Type/CFF格式相对True Type格式的优势》 Typblography

原文地址:https://www.cnblogs.com/zqhiuui/p/10209035.html

时间: 2024-10-11 07:45:49

字体渲染详解的相关文章

使用icomoon字体图标详解

使用icomoon字体图标详解 字体图标的优势:(isux的总结) 1.轻量性:一个图标字体比一系列的图像(特别是在Retina屏中使用双倍图像)要小.一旦图标字体加载了,图标就会马上渲染出来,不需要下载一个图像.可以减少HTTP请求,还可以配合HTML5离线存储做性能优化. 2.灵活性:图标字体可以用过font-size属性设置其任何大小,还可以加各种文字效果,包括颜色.Hover状态.透明度.阴影和翻转等效果.可以在任何背景下显示.使用位图的话,必须得为每个不同大小和不同效果的图像输出一个不

Fnt字体格式详解

cocos2d里的数字和符号基本都会用到fnt字体, 从直观的使用来说, fnt就是讲我们熟悉和0123和图片绑定起来, 在使用0123时, 直接用图片代替, 当然这个图片不可能是矢量图, 所以在游戏中就要尽量避免对fnt字体的缩放操作, 因为对mac下fnt生成软件实在是用得不爽, 于是想写一个TexturePacker的插件, 自己实现fnt格式导出, 其中fnt文件的内容详解如下, 备忘: 第一行是对字体的介绍. info face="华康海报体W12(P)" size=32 b

Java的字体类详解(Font)-摘自Java API文档

字体是个非常平常的概念,以至于看到Java API文档对于字体的长篇大论的说明时,我突然感觉自己很无知. 以下是英文原文: java.awt.Font The Font class represents fonts, which are used to render text in a visible way. A font provides the information needed to map sequences of characters to sequences of glyphs

DOM节点渲染详解--盒子的生成到布局过程

CSS的可视化格式模型是一种处理文档并把它显示在可视化媒介中的一种算法.它是CSS的基本概念,可视化格式模型转化每个文档元素,生成0个或一个或多个符合CSS盒子模型规则的盒子.每个盒子的布局受如下几点影响: 1. 盒子的大小: 2. 盒子的类型: 3. 定位的方案: 4. 它的子代和兄弟: 5. 可视区域和位置: 6. 它包含的图片的已有大小: 7. 其他额外的信息: 特定的模型渲染每个盒子,这个模型与包含这个盒子的块相关.通常,一个盒子为他的后代元素建立一个包含块,除非这个盒子不受包含块的约束

Vue的条件渲染详解

Vue的条件渲染 v-if.v-else.v-else-if以及v-show的用法 v-if的渲染方式: 会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建: 只有当条件第一次变为真时,才会开始渲染条件块: 切换开销比v-show高: v-show的渲染方式: 不管初始条件是什么,元素总是会被渲染: 只是简单地基于 CSS 进行切换: v-show的初始渲染开销比v-if高: 如果需要频繁的切换,则使用v-show: 如果运行时条件很少改变,则用v-if: <!DOCTYPE ht

SVG生成字体图标详解

Android 颜色渲染(九) PorterDuff及Xfermode详解

版权声明:本文为博主原创文章,未经博主允许不得转载. Android 颜色渲染(九)  PorterDuff及Xfermode详解 之前已经讲过了除ComposeShader之外Shader的全部子类, 在讲ComposeShader(组合渲染)之前,  由于构造ComposeShader需要 PorterDuffXfermode或者PorterDuff.Mode作为参数,所以在此先详细地了解下这两个类的作用,这对之后的绘图会有很大的帮 助: 在讲具体的使用之前补充一点知识,这就是 Proter

CSS3新增属性text-shadow详解及燃烧的字体实战开发

今天我们有很多程序员在给文本设置样式时,都感觉无从下手.一般有两种情况: 1) 不知道关于文本到底有哪些样式属性: 2) 即使借助开发工具的自动提醒,依然不清楚样式属性的具体意思,以及具体用法. 今天这篇文章,我将带领大家一起来领受CSS3在文本样式应用方面的超强能力.通过精彩的实例,来使大家重新认识CSS3文本样式,真心希望大家通过此篇文章,即使不能做到精通CSS3的文本样式的应用,也会做到熟练应用. 实例: 如何利用CSS3制作燃烧的字体? 以前,如果我们网页上想要显示一个燃烧着的文本,大家

【three.js详解之二】渲染器篇

[three.js详解之二]渲染器篇 本篇文章将详细讲解three.js中渲染器(renderer)的设置方法. three.js文档中渲染器的分支如下: Renderers CanvasRenderer DOMRenderer SVGRenderer WebGLRenderer WebGLRenderTarget WebGLRenderTargetCube WebGLShaders 可以看到three.js提供了很多的渲染方式,我们选择的当然是WebGLRenderer,但我们这里要将Canv