iOS 排版概念

字符和标志符号(character和glyph)

字符是书面语言中带有意义的最小的单位,它可以对应语言中可读形式的一个读音,就像罗马字母表中的字母;也可以代表一个完整的词,比如中国的(象形)汉字;它们也可以代表某种特定的概念,比如数学符号。在这些情况中,字符都是一个抽象的概念。

虽然字符可以由一块显示区域中的某个可识别的形状所表示,但表示同一个字符的形状可能有很多,而且它们各自之间并不相同。比如对于大写字母A,则根据笔划的粗细,字符书写的是倾斜还是竖直,所呈现的形状都会不一样。同时还有有衬线(笔划始终处 在大致垂直于笔划方向添加的一条小短线)和无衬线之分,字符这些形状中任何一个形状即称为一个标志符号即glyph。

字符A的glyphs

字符与glyph之间并没有一对一的关系,也就是说一个字符有时可能需要多个glyph来表示,而一个glyph有时也可以代表多个字符,比如é可能是由"e"和重读glyph"´"结合起来表示的。而一个glyph表示多个字母的情况则是连体字母,即特定的字母先后出现时所显示的glyph

连体字母出现时字符与glyph的对应关系

众所周知,计算机存储字符的形式是将每个字符对应字符编码表中的某个编码,iOS和OS X中的编码规则是遵守Unicode规则的。Unicode编码规则将全世界所有语言中的字符都定义在其中,这个规则是独立于平台,程序和编程语言的。并解决了一个长期以来困扰计算机界的问题,那就是数百种不同计算机系统中都使用着自身设计的不一样的字符编码系统,而这些编码系统之间,同一个编码代表的可能是各不一样的字符。

同时更为关键的是Unicode同时还规定了处理双向的文本和(字符)前后关系的形式,组成字和换行的方法,排布不同语言文本的方法,怎样对不同的语言格式化数字,日期,时间等数据。

glyph也是由称为glyph code的数字化代码所表示的,用来描述字符的glyph是由layout manger在组合和layout过程中选择的。layout manager决定用哪个glyph及在显示区域的哪些位置放置这些glyphs。layout manager会缓存glyph code并提供方法来做字符和glyph之间的转换及字符坐标与view坐标之间的转换。

字体:typeface和font

a typeface是可写语言中部分或所有字符所具有的一组视觉上相关的形状。比如Times即是一种typeface,它的所有字母在外观上都可以看出是相关的,即所有字母在字母主干(竖直的比划)和counter(字母body中的圆形转角)及其他部分的比例都是一致的。这样在显示一大块文本的时候,同一种typeface的字符形状可以一起增加可读性。

a typestyle或者简单地说style,是特定typeface的一种区分于其他typeface的视觉特征。比如罗马typestyle有这样的特征:大写字母有衬线,字母主干笔划比水平要粗。在斜体的typestyle中字母向右倾斜,更圆润看起来更像草书或者手写的字母。一种typeface通常有多种相关的typestyle。

a font是一系列的glyphs分别代表一种size, typeface和typestyle的组合。fonts包含所有上下文关联的形式的glyph,比如连体字符,也包括正常的字符形式。

font family代表同一typeface的多种font,各font有不同的typestyle。

styles也称为traits,特性的变化有粗体,斜体,浓缩,扩展,窄,small caps,海报字体和fixed pitch。文本系统包含称为字体描述符的对象,这个对象提供字体匹配功能,比如可以简单地通过创建一个font描述符描述一种字符,比如可以通过font family名和weight,就可以找到系统中匹配对应trait的所有字体。

text layout

text layout是在显示设备上排布glyph的过程,显示设备中这块叫做text view的区域,它代表的是类似于传统排版中称为page的一块区域。glyph互相布局的顺序叫做text direction。在英语及源于拉丁语的语言中,glyph是由字符一个挨一个组成单词,再由一个个空格将单词隔开的。words是从text view的左上部分从左向右开始排列直到到达view的右边界,随后便在前一行的下一行用同样的方式继续排列直到到达view的底部。

在其他语言中,glyph的排布会不一样,比如有的语言是从右向左排的,甚至有的是竖直排布而不是水平排布的。在技术文档中,很常见的情况是在同一行中会混合不同glyph排布方向的语言,有些文本系统甚至会隔行即变换文本排布方向。有些语言并不通过空格分隔由glyph组合成的字,甚至有的app需要进行任意的glyph排布,比如在某个场景,layout需要glyph按非线性的路径进行排列。

从一串glyphs中创建文本行的过程中,layout 引擎必须打到一个断行的点以结束一行并开启另一行。文本系统中,可以指定任意的字或者glyph边界作为断行的点,在罗马文本中,如果在字中间断行需要在断行点处插入一个连字符glyph。

layout manager在layout glyph的时候是沿着一条不可见的称为baseline的线进行排列的。在罗马文本中,baseline是水平的,大部分glyph的底部边缘都位于这条线上。有些glyph会延伸到baseline之下,比如"g"这样有下行或者叫尾巴的字母,以及大的圆形的字符比如"O"这样为了显示效果需要往baseline下面移一点。其他writing system会将glyph放置在baseline之下或者中心位于baseline上。每个glyph都有一个用于layout manager用来与baseline对齐的origin点。

glyph设计者为每种font都提供了称为metrics的一组数据,描述字体中每个glyph周围的空间。layout manager使用这些metrics信息来决定glyph的位置。在水平文本中,glyph有一个metrics叫做advance width,它表示的是沿着baseline的方向,其相对于后面的glyph的origin点的空白空间。通常在origin点与glyph之间也是有一定的空白空间的,这段距离的metrics叫做left-side bearing。而定义advance width的这个点与glyph之间的空白空间的metrics(如果有的话)叫做right-side bearing。origin点(在baseline上)与glyph在baseline上的最高点之间的竖直距离metrics叫做ascent,到glyph在baseline之下最低点的距离metrics叫做descent。包裹glyph可见部分的矩形区域叫做bounding rectangle或者bounding box。

glyph metrics描述

水平文本默认情况下排列glyph的时候都会放置对应的advance width,而在有些结合中,会通过使用kerning来使文本更可读,kerning即是使glyph之间的空间更紧密或者更松弛。最常见的kerning的例子即发生在大写的W和A之间的,如下图所示。font中是有设计都提供的kerning metrics信息的,文本系统提供了方法可以选择关闭kerning或者让kerning在选中的文本中更松弛或者更紧密。

kerning

排版系统通常使用称为点的单位来衡量font metrics,在大多数计算机排版系统中,通常是72点每英寸。通过将ascent和descent加起来即可以算出字体的point size。

排版过程中在每行之间添加的空间叫做leading,而font的行高则定义为ascent加descent加leading(leading有时也称为linegap,通常某段文本所设定的 font point size和line height使用一个比率来表示,比如14/16.5)

虽然从前的排版概念可能难懂一些,但大部分使用过计算机文档或者打字机的读者应该对页面的文本布局概念比较熟悉。比如margin指页面边界与文本区域之间的空白,alignment描述文本行相对于margin排列的方式,比如水平文本可以左,右或者居中对齐。

文本行也可以justified,对于需要左右对齐的水平文本行,会改变字间及glyph间的空间以在左右分别对齐。如下图所示,如果在被请求之后,系统会进行justification和alignment,即在文本流已经断成行并添加了连字符之后进行。

justified

推荐阅读更多精彩内容