CJK-Compatible Monospace Fonts
# Motivation
在中英文混排的文本编辑场景中,我偶尔有「中英文字符宽度恰好是 2:1」的需求(以下亦称「西文等宽字体能与中文对齐」)。
- Example: 一个以中文为主的 Markdown 笔记,其中含有中英混排的表格。如能使用与中文对齐的西文字体,则在 editing(而不仅仅是 preview)界面,表格的竖线 | 也可以对齐。
| Col1 | Col2 | Col3 |
| --------- | ------------ | ---- |
| TEXT | 中文 English | ** |
| LONG TEXT | English 中文 | ## |
以上 Markdown 源码(在假定一个中文字符宽度恰好等于 2 个英文字符的前提下)已经对齐,但如果读者使用的字体并不满足「中英文字符宽度恰好 2:1」(本站并不强制读者的浏览器使用特定等宽字体),则看不到上述 code block 的对齐效果。
# Composite Fonts
有一些现成的中英文混排字体实现了中英字宽 2:1,例如:
- Sarasa Gothic Mono 更纱黑体 , a CJK composite font based on Inter, Iosevka and Source Han Sans.
- Maple Mono (CN)
Sarasa Gothic 更纱黑体采用了 Iosevka 的「瘦高」英文的方案,稍微牺牲了英文字符的可读性,将英文字宽压缩到 500 EM units (in a 1000 UPM box) 来实现中英字符宽度 2:1; 而 Maple Mono 选择了 保持英文字符宽度 600 EM units , 将中文的横向间距拉宽来实现 2:1。Maple Mono 的维护者提出的主要使用场景是「在英文多中文少的编程环境(可能需要显示中文字符串或注释)」,所以优先照顾英文字体的阅读体验,牺牲了中文字的观感。
# My Solution
我自己需要使用与中文对齐的西文字体的场景,也就只有上文提到的 Markdown 或者 LaTeX 中英文混排制表。至于一般的编程,我很少写中文注释;实际上,很多中英文混排的场景,例如带有中文 description 和 comments 的 Beancount 记账 ,只要不涉及制表或 ASCII 制图 ,那么中英文字符不对齐其实并不会严重影响观感。另一方面,在这些场景中,中文注释通常只会单独成行或者出现在每行末尾,并不会影响行首部分的英文字符(或 Beancount 中的金额/小数点)对齐。
由于 Sarasa Gothic 字体文件体积较大,英文部分选择自由度不高,我决定单独选择英文 monospace 字体,利用「巧合」使中英文对齐。「巧合」是指,我选择了一个字宽 500 EM units 的英文字体,我的编辑器需要恰好(或者指定)fallback 到一个字宽 1000 EM units 到中文字体,才能看上去满足中英字符对齐的要求。在不同的系统/软件环境下,字体 fallback 的机制不是一两条规则就能说明白的。好在字宽 1000 EM units 的中文字体是很常见的,macOS 上的 Visual Studio Code 的默认中文字体(PingFang?)已经满足要求。
那么选择哪个英文字体呢?
- Sarasa Gothic 作者 Belleve 维护的 Iosevka 有很多
Stylistic Sets
,可以满足不同的口味。我个人偏好
ss12/Ubuntu Mono和ss14/JetBrains Monostylistic sets. 用惯了其他流行(或系统默认)的西文等宽字体的人,初看 Iosevka 系列字体,可能会觉得它偏窄。- 在选定了一个 stylistic set 的基础上,我们还可以使用
character variants
特性单独定制每个字符的风格。例如我使用
"editor.fontLigatures": "'ss12', 'cv17' 11, 'cv41' 12, 'cv45' 6, 'cv54' 8"使小写fjt的曲线部分变短,并给大写G加上了衬线。
- 在选定了一个 stylistic set 的基础上,我们还可以使用
character variants
特性单独定制每个字符的风格。例如我使用
- 我还发现了另一类英文字宽 500 EM units 的字体,就是
Ubuntu Mono
和
Inconsolata
—— 虽然这两个字体不会给人“过于细长”的感觉,但由于它们相比同字号的其他 monospace 字体,字型看上去整体偏小,以至于很多人认为这是一个
bug
。
- 2023 年新款的 Ubuntu Sans Mono 修复了这个 “bug”,整体字型看上去更加和谐,但也 失去了 字符宽为 500 EM units 的 feature。