本文解說如何透過fontconfig改善Linux中文字體的種種問題,包括字體優先順序(優先級)、修正模糊、解決Emoji無法顯示。
我原本是用Noto Sans CJK TC當Linux系統字體,發現Flatpak版Steam玩《Team Fortress 2》會無法顯示中文字體,裝了文泉驛正黑體才正常。可是一裝下去,Linux的中文字體優先順序就被覆蓋了,其他應用程式跟著變成採用文泉驛正黑體來顯示文字!
老實說文泉驛很難看,不適合當螢幕文字的呀。以前我還發生過裝「標楷體」,導致整個系統預設都是該字體,變超級醜的狀況。
此時解決方案有:
將該字體套件解除安裝。認真?夫所以養而害所養譬猶削足而適履。
強行在瀏覽器指定字體。我覺得不行,這會覆寫部份網站的設定,我的原則是只要瀏覽器UI顯示跟系統一樣的字體,其他交給網站自行決定。
那麼,就透過撰寫fontconfig設定檔來指定系統應用程式要優先使用的字體吧。在設定完成後,系統就會優先使用Noto Sans來顯示界面文字了。
1. 了解Linux常用的中文字體#
Linux系統常用的中文字體有:
- Noto Sans CJK (內含TC/SC/HK/JP,分別對應正體字/簡體字/香港繁體/日文漢字)
- 思源黑體 (Adobe Source Hans)
- 文泉驛正黑體 (WQY Zhenhei)
- 楷體 (UKai)
- 明體 (UMing)
近年因表情符號盛行,多半還會裝個顯示Emoji的Noto Font Emoji。
大多數Linux發行版都有提供對應套件安裝,例如Noto Sans字體家族,Ubuntu與Arch Linux皆有收:
# Ubuntu
sudo apt install fonts-noto-cjk fonts-noto-color-emoji
# Arch Linux
sudo pacman -S noto-fonts-cjk noto-fonts-emoji
如果要手動安裝字體的話就是自行下載zip,解壓縮將.ttf檔放到/usr/share/fonts
(需要sudo)或者~/.fonts
,再用fc-cache -fv
指令更新字體快取,其他程式方能使用,連Wine跑的程式都能存取。
使用fc-list
指令列出系統安裝的字體。
2. fontconfig的設定檔位置#
fontsconfig用於告訴系統字體的優先級別。
要對系統全域生效的話就是修改 → /etc/fontconfig/fonts.conf
要對個別使用者者生效的話就是修改 → ~/.config/fontconfig/fonts.conf
別亂動系統的/etc/fontconfig/fonts.conf
,該檔案fontconfig一更新就會遭覆蓋,這裡以個別使用者下去設定比較適當。
- 假設要讓所有應用程式優先使用Noto Sans CJK TC字型的話,新增設定檔
touch ~/.config/fontconfig/fonts.conf
vim ~/.config/fontconfig/fonts.conf
- 參考双猫CC的設定,填入以下內容。
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<!-- 設定讓system-ui使用Sans-serif字體 -->
<match target="pattern">
<test name="family">
<string>system-ui</string>
</test>
<edit name="family" mode="prepend" binding="strong">
<string>sans-serif</string>
</edit>
</match>
<!-- 預設sans-serif字體 -->
<match target="pattern">
<test name="family">
<string>sans-serif</string>
</test>
<edit name="family" mode="prepend" binding="strong">
<string>Noto Sans CJK TC</string>
<string>Noto Sans</string>
<string>Noto Color Emoji</string>
</edit>
</match>
<!-- 預設seriff字體 -->
<match target="pattern">
<test name="family">
<string>serif</string>
</test>
<edit name="family" mode="prepend" binding="strong">
<string>Noto Serif CJK TC</string>
<string>Noto Serif</string>
<string>Noto Color Emoji</string>
</edit>
</match>
<!-- 預設monospace字體 -->
<match target="pattern">
<test name="family">
<string>monospace</string>
</test>
<edit name="family" mode="prepend" binding="strong">
<string>Noto Sans Mono CJK TC</string>
<string>Noto Sans Mono</string>
<string>Noto Color Emoji</string>
</edit>
</match>
</fontconfig>
這個檔案的內容是設定系統要求使用
sans-serif
字體時,就優先使用Noto Sans CJK TC
,不行的話再用Noto Sans
,而Emoji最後才會用到Noto Sans Emoji。其他字體以此類推。設定完成後更新字體快取,重開用程式看看有無變更。
fc-cache -fv
3. Flatpak應用程式中文字體的問題#
根據 Github的討論,儘管 Flatpak應用程式可以使用系統字體,但卻不採納系統fonts.conf的設定,而是以自己的優先順序來顯示字體,有時候在Wayland下還會導致字體模糊(跟縮放無關)。
只要開放Flatpak程式讀取xdg-config/fontconfig:ro
就行。
例如Flatpak版Google Chrome:
flatpak override --filesystem=xdg-config/fontconfig:ro com.google.Chrome