翻译

Sketch的文字排版策略

如何将字体更好的渲染出来是一个很复杂的问题,看Sketch团队是如何解决这个问题的

2019年1月16日
Sketch的文字排版策略
本文共有1995字,预计阅读时间9分钟
原文:Typesetting inSketch
文字,和颜色一样,是个表面上看起来很简单,但当你深究起来却很复杂的话题。设计师预期的字体系统(type system)和苹果或其他厂商建立的文字排版系统并不一样。 
一直以来我们都希望提升Sketch上字体的表现,但你继续读下去就会发现,应对这些挑战需要我们深入探究苹果的文字渲染系统,进行底层的修改。我们相信我们实现了这个目标,希望你们喜欢。
在了解我们亟需解决的问题之前,首先看一下Sketch中的一个文字图层。
https://darmau-image-1256887306.cos.ap-hongkong.myqcloud.com/1_Glty62_aid_Eb0_Jm_Re_GP_2p_Q_2x_02180c0a6c_d35760af55.png
文字图层的高度由“line-height”属性决定。这个值并不总是和字号相对应,不同的字体在相同字号下的line-height差别可能很大,有的几乎是字号的两倍,有的则接近字号。字形在图层内绘制的位置由baseline决定,baseline由字体定义。
由于字体之间的差别非常大,当你在切换字体的时候,文字图层也会发生相应的变化,尤其是当你在同一个图层中混用不同的字体。另一个棘手的情况是当你切换字体时,画布上的文本经常上下偏移。
我们经常被问到,为什么Sketch会渲染看起来空白的区域(上图蓝色部分),而不是将边界定为升部ascender和降部descender。蓝色区域也是由字体本身定义,但是简单点说,一些对你来说很少见的字符会占用这些空间,特别是包含变音符号的字符。比如出现在大写S(Š,一些斯拉夫语)和小写c(ç,法语最常见)中的符号是最常见的例子。
在Sketch 3.6中,我们对文字图层进行了一些更改,特别是对于具有固定行高的段落。要了解它是如何工作的,以及发生了什么变化,我们需要了解Apple的[文字系统](https://en.wikipedia.org/wiki/Cocoa_text_system),它如何产生我们的文本,以及如何应用于Sketch。
Continue

字符和字形

设置文本段落的第一步是将文本的字符和字体属性转换为字形glyph。字形是给定字体的一个或多个字符的直观表示。字符和字形之间的映射不是1:1。例如,单个字形可以表示多个字符 - 这些字符称为连字。以不同方式排序的相同字符可能会产生不同的连字,从而产生不同数量的字形。我们遇到的最极端的例子是Zapfino字体中的“Zapfino”。七个字符连成一个字形:
https://darmau-image-1256887306.cos.ap-hongkong.myqcloud.com/1_Mv_Ki_WPM_5_Hv_CO_311w_C_Vm_Sw_2x_png_d692699680_d69842c13a.webp

文本容器和line fragment

我们可以在一行上放置多少个字形由文本容器的宽度决定。
在Sketch中,文本容器的大小由文本图层的宽度决定。要使用字形填充文本容器,我们需要将其拆分为若干行。包含某单行的所有字形的矩形称为“文字区块line fragment”。只要您在段落中使用单个字体或大小,所有内容都会像您期望的那样:
https://darmau-image-1256887306.cos.ap-hongkong.myqcloud.com/1_Hg_Ch3_Kv_BW_7_P_Vf_Ck_Prz_GJQ_2x_png_d099e3bbb5_6aacae3acc.webp
在正常排版中,line fragment的高度由该行最高的字体确定(准确地说,是字体在上方升部和在baseline下方降部的距离)。混合字体可以生成不同高度的文字区块,这是事情开始变得棘手的地方:
https://darmau-image-1256887306.cos.ap-hongkong.myqcloud.com/1_IN_3t_Y_Hjqf_WJKQ_Hz_Ce47_HA_2x_png_3c1e15a3f9_e905615901.webp

固定行高

段落还可以指定最小和最大行高。这限制了line fragment矩形的高度。如果我们使用相同的最小值和最大值,我们得到一个固定的行高。通常来说,这就是Sketch中设置的行高。它适用于相同字体的段落。
https://darmau-image-1256887306.cos.ap-hongkong.myqcloud.com/1_6r_KUCJ_7a8_Wqf_Jp_WJW_4s_RA_2x_png_118a05902d_7390cd9028.webp
具有不同字体的段落在Sketch中通常看起来不对劲。我们设置固定行高,所以为什么会有问题?我们需要确定排版机制将baseline放在line fragment矩形内的的具体位置。
事实证明,对于每个line fragment,Cocoa的typesetter会找到该行文字最高字形的降部,并将其用作baseline和文字区块底边的距离。使用混合字体,固定了行高,但baseline却变得不可控。
https://darmau-image-1256887306.cos.ap-hongkong.myqcloud.com/1_x2uz4dhqpu_P_Ot_K6p_O6vzd_Q_2x_png_0cae779853_dead96983d.webp
当设计师谈到将行高设置为20pt时,他们的意思是他们想baseline之间距离为20pt,而不是20pt高度的line fragment矩形。这是有道理的,因为决定文本垂直视觉节奏的是baseline,它比这些抽象矩形更容易感知。那我们怎么解决这个问题呢?

一致的baseline

https://darmau-image-1256887306.cos.ap-hongkong.myqcloud.com/1_q_PX_1_RUV_8_JG_2_Vt_O06_U7_G5_Pg_2x_png_a175b14a78_55b9f26ef0.webp
在Sketch 3.6中,我们引入了一种新的排版机制,它为具有固定行高的段落生成一致的基线偏移。我们通过检查段落中的所有line fragment来实现这个目的,并选择适合所有line fragment的基线偏移。
段落之间也保持一致的基线偏移,即使是不同的字体,只要它们具有固定的行高。当没有设置固定的行高时,我们使用指定的字体来设定,我们看到的可以给我们留下不同的结果。当您将其设置为固定时,您将获得美观,可预测的垂直节奏:
https://darmau-image-1256887306.cos.ap-hongkong.myqcloud.com/1_D1yc_x_GX_Cq_JS_Mo9swn_P_nw_2x_png_2c81f10f18_8f134d2ff4.webp
如何在原来的设计稿中使用?默认情况下,新文本图层使用一致的基线排版,并且在早期版本的Sketch中创建的文本图层可以通过更改行高来应用新的排版机制。

其他改进

我们对行高的改进也对行高小于字号的段落的编辑产生积极影响,因为基线始终位于文字区块内。它还改进了文本图层的边界矩形。
最后,在更改文本图层的字体时,我们已经留了一些长度来保留第一个基线的位置,因此在更改字体时,文本图层将不再会上下偏移。

最后一点

数字排版是一个非常复杂的问题。我们生活在一个激动人心的时代,我们意识到在每个设备和平台上让设计看起来一样是几乎不可能的。
对于我们来说,创建一个类似于iOS,Android或Windows中的Chrome或Mac中的Safari的渲染系统也是不可能的。所有这些的渲染机制的差异非常大也非常复杂。
我们听取了您的反馈,并试图建立一个非常一致和可靠的渲染系统。我们在此次更新时非常强调行间距,但我们刚刚开始。这是我们计划在今年发布的一系列类型改进的一部分。

评论