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 Typefaces
有一些現成的中英文混排字體實現了中英字寬 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 的維護者提出的主要使用場景是「在英文多、中文少的編程環境(可能需要顯示中文字串或註解)」,所以優先照顧英文字體的閱讀體驗,犧牲了中文字的觀感。
Latin Typefaces
我自己需要使用與中文對齊的西文字體的場景,也就只有上文提到的 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 的預設 fallback 中文字體(PingFang?)已經滿足要求。
那麼選擇哪個英文字體呢?
- Iosevka
- Iosevka 的自訂選項非常豐富。首先,它支援很多 Stylistic Sets,可以模仿其它流行字體的風格,迎合不同口味;
- 在選定了一個(或保持預設) stylistic set 的基礎上,我們還可以使用 character variants 特性,逐一自訂每個字符的風格。例如我使用
"editor.fontLigatures": "'ss12', 'cv17' 11, 'cv41' 12, 'cv45' 6, 'cv54' 8"讓小寫fjt的曲線部分變短,並給大寫G加上襯線。
- M+ Code Latin
- 這是日本語字體家族 M+ Fonts 中的 monospace 字體,設計時也考慮了與 CJK 字符對齊。僅包含 Latin 字符,不會影響 CJK 字體 fallback,推薦非日本語(或任何不想影響原 CJK 字體的)使用者使用。
- M+ Code Latin 是可變寬度字體,在 VS Code 中,可以使用
"editor.fontVariations": "'wdth' 125"這樣的配置項進行調節。M+ Code Latin 支援的變寬範圍是100(500 EM units,即 1/2 CJK 字符寬度) 到125(600 EM units,與多數流行的 monospace 字體如 JetBrains Mono、Source Code Pro 等寬度相同) - 該家族的另一套 typeface M+ 1 Code 同時支持日文與 Latin 字符。
以上兩個字體在顯示非代碼類西文文本(e.g., large paragraphs of English text)時顯得密度有點高(因為每個字符都是「高瘦」的),我自己並不習慣。我通常只在中英文混排(以中文為主)及 Terminal Emulator 中使用這種高瘦的字體。
對高密度 Latin 字符閱讀的場景(如果確實想要使用等寬字體,例如編輯 Markdown 源碼時),我更喜歡 Source Code Pro 這種刻意使用較小 x-height、"to give the ascenders more ‘room to breathe’ and give the design ‘a more bookish feel’" 的西文字體。
我還發現了另一類英文字寬 500 EM units 的字體,例如 Ubuntu Mono 和 Inconsolata 。雖然這兩個字體不會給人「過於細長」的感覺,但由於它們相比同字號的其他 monospace 字體,字型整體看起來偏小,以至於很多人認為這是一個 bug。2023 年新款的 Ubuntu Sans Mono 修復了這個 “bug”,整體字型看起來更加和諧,但也失去了 字符寬為 500 EM units 的 feature。