终端字体 | Terminal Fonts
终端字体和代码字体一样,也是编程爱好者常用的字体,很多人不会细分这两种字体,但知则认为有必要区分这两种需求。代码字体主要是用于看代码的,所显示的内容对象主要是各类代码文件或者文本数据文件。但是编程并不是仅仅和文本文件打交道,还需要构建和调试。这就会用到虚拟终端和用于虚拟终端的字体。
终端小史
所谓终端机,就是一种由键盘和显示器以及必要的通信组件组成的古老设备,用于和计算机的主体连接,并于与其中的程序以文本形式进行交流。后来随着技术发展,这类设备逐渐被淘汰。但是,和计算机程序进行文本交流的需求还是存在的,于是就有了软件模拟的虚拟终端设备,称为“虚拟终端”。
这些虚拟终端程序本身就是图形化界面的一个窗体,但是窗体内部不显示图片和动画,仅仅有文本。和 Word 或者记事本这类文本编辑软件的不同之处在于,这个仅仅能显示文本的窗口并不具有复杂的样式和排版功能。所有字符都像大小固定的马赛克瓷砖一样整整齐齐地嵌入其中。这种功能退化一方面是为了准确还原物理终端机的使用体验,另一方面则是为了限制整个设备的复杂度——功能越受限、设备就越简单、操作也越容易。如果上手写过一些简单的 demo 程序就会知道,让程序往虚拟终端输出点信息可比绘制一个图形化界面的窗体简单多了。因为这里没有复杂的坐标、花哨的动画和多变的事件响应。
由于这些特性,虚拟终端一直是程序调试时的重要工具。所以程序员在编程时,会非常频繁地用到虚拟终端。而终端字体,就是专门用于这些虚拟终端的字体。
终端字体的需求
用于终端的字体的需求其实有很多与代码字体重合。因为终端输出的内容也是以 ASCII 可打印字符为主,其他非 ASCII 字符为辅,同时又要求字符等宽,尽量容易对齐。但终端和代码编辑的需求有所不同——代码编辑时,不论是代码文件还是文本数据文件,大体来说都是人能写,人能读,同时大概率要交给程序处理的;但除了人以外,计算机程序也能向终端机输出文本,而且这些呈现在终端上的文本主要是给人看,不一定需要交给程序处理。简单(且不严谨地)来说就是,代码是人写给机器看的,为了保证机器能看懂,尽量不出现非 ASCII 字符;而终端是机器写给人看的,不会再经由机器处理,更注重直观和人方便理解,只要能正常输出,具体使用了哪些字符关系不大。
因此,终端字体覆盖非 ASCII 字符的需求其实要比一般的代码字体强烈。而且这些额外的字体还不仅仅包括各种自然语言文字,更多地是一些图标符号。因为相比于一字一句的文本,人更愿意看图。
这里简单解释一下,为什么号称处理纯文本的终端机能够显示图像。首先,其实每一个文字的字形就是一幅图,字体文件就是一个图片集。和一般的图集不同之处在于,这个图集中每张图都有编号,而且那个编号映射哪个字都是有专门规定的。如果你希望利用这套机制显示某一个图,那么只需要给这个图分配一个合适的编号,然后把这个图放进字体文件里。(这些图转化成的字符一般不会在代码中出现,更少由人主动键入。)
其次,虚拟终端的界面是若干字符像马赛克瓷砖一样拼起来的平面区域。每一个字符相对于整个区域来说就类似一个像素点。如果以字符为边框纹理,按一定规则组合排列,那么整个区域就能拼凑出表格甚至图形的效果。
这些虚拟终端支持的额外字符的宽度一般来说应当和等宽字体的半角字符一致。但是有的字体中将其实现为和全角字符一致。后续会根据类别特殊说明。
表格边框
描述和来源详见: https://www.unicode.org/versions/Unicode15.0.0/ch22.pdf
虚拟终端中里虽然用字符当马赛克拼成网格状,但是却不能直接把网格边框显示出来。因此要在虚拟终端中表现出表格的效果,就需要让一些行列的字符显示为横线、竖线或者转角来凑成边框。在 ASCII 字符集中也能用 -|+
之类的字符大概实现这个效果,但是总显得不够自然。于是当年一些终端机就增加了一些专用于绘制表格的边框零件的字符。这些字符也被后来的 Unicode 的 Box Drawing 区域收录(分布在 U+2500
到 U+257F
)。以下是一个用这些字符绘制表格边框的例子(在文本编辑器中看时可能有一些空白间隔,在终端中则会连在一起):
╒═════╕
│ Z Z │
╞═════╡
│ZhiZe│
╘═════╛
在终端中绘制表格确实能让信息输出更加条理,甚至还能模拟 GUI 的窗口效果,因此不少终端程序都热衷于使用这些字符。
目前据我所知,以下字体支持这一区域字符的覆盖:
- Unifont
- Source Code Pro
- Noto Sans Mono
- Cascadia Code
- Ubuntu Mono (Incomplete)
- Fira Code
- Iosevka
- Source Han Sans HW SC VF (Full-width)
- Sarasa Gothic
- LXGW WenKai Mono
Incomplete 表示覆盖不全面,缺失部分字符。
Full-width 表示将这类字符实现为了和汉字等宽(而非和拉丁字符等宽)。
这些词在后续小节的列表中出现时意义同此,不再重复。
纹理绘制
描述和来源详见: https://www.unicode.org/versions/Unicode15.0.0/ch22.pdf
可能你在见过一些用文字拼凑出漫画形象乃至照片效果的文本。这类作品有时会被称作“ASCII Art”。其基本原理就是把每一个字符当作了像素点或者小的纹理块,通过大面积的字符矩阵来拼凑出图像的效果。这个技巧当然用 ASCII 也能玩 ,但是由于 ASCII 字形设计并不是绝对均匀的,所以色块填充效果并不是很好,要达到比较好的效果往往需要很大的字符矩阵。
Unicode 中的 Block Elements 区域(从 U+2580
到 U+259F
)则是一组专门设计的均匀纹理块和不同长宽的矩形。用它们做像素画能弥补 ASCII 字符集的表现力不足。此外,和虚拟终端的字符颜色控制搭配,这些字符还能做出类似 GUI 界面的阴影效果,乃至显示一些简单的彩图。
虽然理论上虚拟终端能显示一些彩图,但是由于字符颜色一般只有前景后景,而且字符数量往往很有限,所以实际的显示效果不可能做到非常好。这些纹理绘制字符存在的意义是给虚拟终端锦上添花,而不是取代显卡和像素显示器。
以下字体支持这一区域字符:
- Unifont
- Source Code Pro
- Noto Sans Mono
- Cascadia Code
- Ubuntu Mono (Incomplete)
- Fira Code
- Iosevka
- Source Han Sans HW SC VF (Full-width)
- Sarasa Gothic
- LXGW WenKai Mono (Incomplete)
Powerline Symbols
Powerline 是著名终端纯文本编辑器 Vim 的一个插件,能在终端中提供看起来不那么死板的状态栏和提示行。为此它在 PUA 区域约定了几个符号。这些符号有的是组成状态栏的形状和箭头,有的则是表示代码状态的 logo。例如说这两个字符
和
在一般字体中没有字形,但是在支持虚拟终端符号的字形中显示为一个三角和一个表示代码分支的符号。当程序输出这些字符时,如果你的终端字体也支持这些字符,那么就能看到一个漂亮到不像终端提示行的终端提示行。后来这些字符约定和相应的字形火出了圈,在 Vim 以外也开始使用这些字符和字形。
以下字体支持这一区域字符:
- Cascadia Code
- Fira Code (Incomplete)
- Iosevka
- Sarasa Gothic
- LXGW WenKai Mono
Powerline Extra Symbols
Powerline Extra Symbols 算是一个 Powerline 的拓展项目,在 Powerline 的基础上约定了更多花哨的形状和 logo。但是其普及程度不及 Powerline。内嵌了 Powerline Symbols 支持的字体不一定支持 Powerline Extra Symbols 的拓展字符。
以下字体支持 Powerline Extra Symbols 额外拓展的字符:
- Cascadia Code
- Iosevka (Incomplete)
- Sarasa Gothic (Incomplete)
- LXGW WenKai Mono (Incomplete)
本文源码采用 MIT 协议开放,托管于: https://github.com/ZhiZe-ZG/ZZToolLibrary
如果觉得本文内容对您有用,希望您能在能力和意愿范围内给我一些资助。我不以此为生,但我也是个普通人。