字體配置
Fontconfig 是一個用於向應用程式提供可用字體列表,以及字體渲染配置的庫。
FreeType 庫依此配置渲染字體。freetype2包 字體渲染包啟用了字節碼解釋器(bytecode interpreter,BCI)以優化字體渲染,尤其是在 LCD 屏幕上。參見#Fontconfig 配置和字體配置/示例。
儘管Fontconfig在現代類Unix系統中廣泛使用,但部分應用程式仍在使用原始的X Logical Font Description(XLFD)作為字體選擇與顯示方法。
為了使字體能夠被應用程式發現,必須對它們進行編目,以便快速訪問。
Fontconfig 的默認字體路徑是 /usr/share/fonts/ 和 ~/.local/share/fonts(以及過時的 ~/.fonts/)。Fontconfig 將在這些路徑下遞歸查找字體。為了便於安裝與管理,在安裝字體時,建議使用這些路徑。
以下命令列出 Fontconfig 已知的字體文件:
$ fc-list ':' file
fc-list(1) 中有更多的輸出格式。
Xorg 已知的字體路徑可通過其日誌了解:
$ grep /fonts ~/.local/share/xorg/Xorg.0.log
- 也可使用
xset q命令查看 Xorg 的已知字體。 - 若 Xorg 以根用戶權限運行,應查看
/var/log/Xorg.0.log。
Xorg 不像 Fontconfig 一樣遞歸查找 /usr/local/share/fonts。添加路徑時,必須像這樣添加絕對路徑:
Section "Files"
FontPath "/usr/share/fonts/local/"
EndSection
有關 Xorg 讀取配置的更多細節,請閱讀Xorg#配置。如果要為用戶單獨配置字體路徑,可以像這樣修改對應的 ~/.xinitrc 來添加或移除默認的字體路徑:
xset +fp /usr/share/fonts/local/ # 将一个自定义字体路径添加到 Xorg 的已知字体路径列表开头 xset -fp /usr/share/fonts/sucky_fonts/ # 从 Xorg 的已知字体路径列表中移除指定路径
要查看 Xorg 已知的字體列表,可使用 xorg-xlsfonts包 軟體包中的 xlsfonts 命令。
Fontconfig 的配置文檔見 fonts-conf(5)。
用戶配置文件位於 $XDG_CONFIG_HOME/fontconfig/fonts.conf 中(通常是 $HOME/.config/fontconfig/fonts.conf)。全局配置文件位於 /etc/fonts/local.conf。
用戶配置優先級高於全局配置。兩個文件使用相同的語法。
- 需要啟用
50-user.conf預設才能讓用戶配置生效,啟用51-local.conf預設才能讓全局配置生效。閱讀#預設一節了解如何啟用這些預設。 -
~/.fonts.conf/、~/.fonts.conf.d/和~/.fontconfig/*.cache-*已過時,以後的包將不再讀取這些路徑和文件。對應的新路徑分別是$XDG_CONFIG_HOME/fontconfig/fonts.conf、$XDG_CONFIG_HOME/fontconfig/conf.d/NN-name.conf和$XDG_CACHE_HOME/fontconfig/*.cache-*。如果使用第二個路徑,確保文件命名正確(NN是兩位數,如00、10和99)。
Fontconfig 把所有配置集中到一個單獨的中心文件(/etc/fonts/fonts.conf)中。Fontconfig 升級時會替換這個文件,因此不應當直接修改它。支持 Fontconfig 的程序查看這個文件以獲取可用的字體及如何渲染之;重啟這類程序即可載入新的配置。該文件是全局配置(/etc/fonts/local.conf)、預設配置(/etc/fonts/conf.d/)、用戶配置($XDG_CONFIG_HOME/fontconfig/fonts.conf)的組合。使用 fc-cache 命令重建 Fontconfig 的配置,但只有新運行的程序會使用新的配置。
Fontconfig 配置文件使用 XML 格式,其需要的頭部如下:
<?xml version="1.0"?> <!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd"> <fontconfig> <!-- settings go here --> </fontconfig>
文中的配置示例省略了這些標籤。
預設存放在 /usr/share/fontconfig/conf.avail。可以通過創建符號連結到此處來啟用,無論是單用戶配置還是全局配置。這些預設會覆蓋各自配置文件中的對應設置。
例如,以下命令啟用全局次像素 RGB 渲染:
# ln -s /usr/share/fontconfig/conf.avail/10-sub-pixel-rgb.conf /etc/fonts/conf.d/
以下命令啟用用戶級次像素 RGB 渲染:
$ mkdir $XDG_CONFIG_HOME/fontconfig/conf.d $ ln -s /usr/share/fontconfig/conf.avail/10-sub-pixel-rgb.conf $XDG_CONFIG_HOME/fontconfig/conf.d
字體光柵化將字體從向量數據(比如一個TrueType字體)轉換為光柵或者位圖數據。由於混疊現象,轉換後的字體可能會出現鋸齒狀邊緣。抗鋸齒技術可以使邊緣看起來更平滑。
Fontconfig默認啟用抗鋸齒,如要禁用:
<match target="font">
<edit name="antialias" mode="assign">
<bool>false</bool>
</edit>
</match>
字體微調使用數學指令來調整輪廓字體的顯示,使其與光柵化網格(如顯示器上的像素網格)對齊。它的預期效果是使字體看起來更清晰,從而使它們更容易閱讀。當顯示器擁有 300 左右的 DPI 時,字體即使不經微調也能正確排列。
TrueType 字體的微調指令由 FreeType 的解釋器使用 BCI 微調渲染。通常來說,微調指令完備的字體使用 BCI 微調效果很好。
微調是默認啟用的,如要禁用:
<match target="font">
<edit name="hinting" mode="assign">
<bool>false</bool>
</edit>
</match>
/etc/profile.d/freetype2.sh 中修改,通過傳遞參數 truetype:interpreter-version=NN 設置解釋器。NN 對應所選擇的版本,傳遞給腳本中的 FREETYPE_PROPERTIES 變量。一些流行的選項如下:
- 35 - 經典模式,模擬 Windows 98
- 40 - 最小模式(精簡版的無窮模式,默認值)
自動微調依自己的算法嘗試微調,無視字體內所有的微調指令。以前這是默認選項,因為 TrueType2 字體受專利保護,但現在專利已過期,基本不需要使用它。如果字體的微調指令很少或沒有,它的效果會更好,否則效果是不如 BCI 的。常見字體都有完備的微調指令,因此自動微調用處不大,現在是默認關閉的。如要啟用:
<match target="font">
<edit name="autohint" mode="assign">
<bool>true</bool>
</edit>
</match>
微調風格是指對字體進行調整顯示、使其與光柵化網格對齊的調整量。支持的值有 hintnone、hintslight、hintmedium 和 hintfull,微調程度依次加深,即字形變得更扭曲、更清晰——hintslight 會使字體更模糊,無法與網格對齊,但在保留字體形狀方面會更好(參見 [2]。),而 hintfull 會使字體更清晰,能很好地與像素網格對齊,但會讓字體嚴重變形。對於非 CFF(.otf)字體,hintslight 設置會在豎直方向上隱式使用自動微調,以支持這類字體的原生字體信息。
默認選項是 hintslight,如要更改:
<match target="font">
<edit name="hintstyle" mode="assign">
<const>hintnone</const>
</edit>
</match>
Fontconfig 需要知道你的次像素排布才能正確顯示字體。使用 次像素排布顯示器測試(The Lagom LCD 顯示器測試頁面的一部分)來找出你的次像素排列。
次像素幾何通過 rgba 屬性配置,可以是:
-
rgb— 紅、綠、藍 — 最常見,大多數現代顯示器使用 bgr-
vrgb— 縱向 vbgr-
none— 無次像素渲染
<match target="font">
<edit name="rgba" mode="assign">
<const>rgb</const>
</edit>
</match>
不支持 "Pentile" 和 "RGBY" 等不常見的次像素排布,這些排布偶爾出現在電視、OLED 和移動屏幕上。對於這些設備,最好放棄次像素渲染,使用 none 選項依賴灰度。
次像素渲染(英文維基百科頁面)通過單獨控制一個像素的三個分色,在一個方向上獲得三倍解析度,以使得字體看看起來更銳利。在 Windows 上,這項技術叫做 zhwp:ClearType。
FreeType2 提供兩種次像素渲染方式(FT_CONFIG_OPTION_SUBPIXEL_RENDERING),Harmony 和 ClearType [3]。從 FreeType 2.10.3 起,Arch 默認啟用 ClearType 次像素渲染 [4]。
啟用 ClearType 次像素渲染時建議使用 LCD 濾鏡。Harmony 次像素渲染不需要設置 LCD 濾鏡,在默認 LCD 幾何下,它等同於 ClearType 使用 lcdlight 濾鏡 [5]。參見下一節了解如何啟用 LCD 濾鏡及其好處。
LCD 濾鏡是用來減輕 ClearType 次像素渲染的色邊現象的。這是 FreeType 2 API 文檔對其的描述,其中 FT_LcdFilter 一節解釋了各個選項。這個網頁展示了各個 LCD 濾鏡的測試效果。
大多數用戶可使用 lcddefault。其他選項包括:適合太粗或模糊的字體使用的濾鏡 lcdlight、原始的 Cairo 濾鏡 lcdlegacy 、完全關閉 LCD 濾鏡的選項 lcdnone。
<match target="font">
<edit name="lcdfilter" mode="assign">
<const>lcddefault</const>
</edit>
</match>
如果對內置的 LCD 過濾器不滿意,可以通過構建一個自定義的 freetype2 軟體包並修改硬編碼的過濾器的方式,來非常具體地調整字體的渲染。Arch 構建系統可用於從原始碼構建和安裝軟體包。
查看 freetype2包 的 PKGBUILD 並下載/解壓構建文件。Arch 構建系統#通過 Git 獲取 PKGBUILD 源碼列出了一些方法。
編輯文件 src/freetype-VERSION/include/freetype/config/ftoption.h 並取消對 FT_CONFIG_OPTION_SUBPIXEL_RENDERING 宏的注釋,啟用 ClearType 次像素渲染。
然後,編輯文件 src/freetype-VERSION/src/base/ftlcdfil.c 並查找常量 default_weights 的定義:
static const FT_LcdFiveTapFilter default_weights =
{ 0x10, 0x40, 0x70, 0x40, 0x10 };
這個常量定義了一個應用於渲染的字形的低通濾波器。根據需要對其進行修改。(參考 freetype 郵件列表的討論)
最後,保存文件,構建並安裝自定義軟體包:
$ makepkg --noextract # pacman --remove --nodeps freetype2 # pacman --upgrade freetype2-VERSION-ARCH.pkg.tar.zstd
重啟 X。現在,lcddefault 過濾器應該會以不同方式渲染字體。
一些字體也許在 BCI 自動微調下外觀不佳。可以為這些字體禁用微調:
...
<match target="font">
<test name="family" qual="any">
<string>My Font</string>
</test>
<edit name="hinting" mode="assign">
<bool>false</bool>
</edit>
</match>
...
設置默認或後備字體的一個可靠方法是添加一個 XML 片段來進行匹配測試。例如,通過設置 "binding" 屬性,下面的設置將使 Georgia 回退到 Gentium。
... <match target="pattern"> <test qual="any" name="family" compare="eq"><string>Georgia</string></test> <edit name="family" mode="assign" binding="same"><string>Gentium Book Plus</string></edit> </match> ...
在上面的例子中,"compare" 屬性可以是 "eq"(即完全等於 Georgia)、"contains"(例如,匹配 Georgia 或 Georgia Pro),或其他值。參見 fonts-conf(5)。
另一種方法是使用 <alias> 來設置「首選」字體。<family> 元素指定的字體在匹配到實際字體前,會被修改為 <prefer> 字體列表中的一個字體,順序由上至下。下面的例子使 Helvetica 回退到 Bitstream Vera Sans:
...
<alias>
<family>Helvetica</family>
<prefer>
<family>Bitstream Vera Sans</family>
</prefer>
</alias>
...
<alias> 也可以用來指定當缺少某些字形時使用的後備字體。例如,一個用戶將 Noto Sans 設置為默認的無襯線字體後,安裝了 Helvetica Neue,想用它書寫拉丁文字。由於很多版本的 Helvetica Neue 並不包括希臘字符,這位用戶希望使用 FreeSans 來書寫希臘文字,因為它與 Helvetica 很像。但事實上,希臘文字將會回退到用戶設置的默認字體 Noto Sans,而使用下面的方法則可以實現:
...
<alias>
<family>Helvetica Neue LT Pro</family>
<prefer>
<family>Helvetica Neue LT Pro</family>
<family>FreeSans</family>
</prefer>
</alias>
...
如果用戶只是想在使用的字體缺少相應字形時,回退到默認字體,則不需要上述設置。
位圖字體有時會作為缺失字體的後備字體,可能導致文本渲染為像素化或過大。使用 70-no-bitmaps-except-emoji.conf #預設來禁用此行為。
要禁用所有字體的嵌入式位圖:
...
<match target="font">
<edit name="embeddedbitmap" mode="assign">
<bool>false</bool>
</edit>
</match>
...
如果要禁用所有字体的嵌入式位图,仍可以为特定字体启用它们,以防该字体在没有嵌入式位图时无法正常工作。例如,对于 Noto Color Emoji:
{{bc|<nowiki>
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd">
<fontconfig>
<match target="font">
<edit name="embeddedbitmap" mode="assign">
<bool>false</bool>
</edit>
</match>
<match target="font">
<test name="family" qual="any">
<string>Noto Color Emoji</string>
</test>
<edit name="embeddedbitmap">
<bool>true</bool>
</edit>
</match>
</fontconfig>
要禁用位圖字體的縮放(這通常會使它們模糊),刪除 /etc/fonts/conf.d/10-scale-bitmap-fonts.conf。
注意這可能會破壞 Segoe UI Emoji 等表情符號字體的縮放,使它們變得巨大。
要重新啟用位圖字體的縮放,重新創建符號連結:
# ln -s /usr/share/fontconfig/conf.avail/10-scale-bitmap-fonts.conf /etc/fonts/conf.d/
Fontconfig 按數字順序處理 /etc/fonts/conf.d 中的文件。因此,01-aaa.conf 和 02-bbb.conf 的規則將與單個 01-aaabbb.conf 文件具有相同的效果——首先包含 01-aaa 的規則,然後是 02-bbb 的規則。
通常來說,這意味著前綴較小文件將具有較高的優先級。但是,Fontconfig 的語法很靈活,允許新規則優先於現有規則。因此,建議#查看當前設置來測試規則相互作用的結果。
$XDG_CONFIG_HOME/fontconfig/fonts.conf 和目錄 $XDG_CONFIG_HOME/fontconfig/conf.d 中定義的用戶規則是通過文件 /etc/fonts/conf.d/50-user.conf 載入的,並且通常優先於以較大數字開頭的文件中定義的規則。要查看當前生效的設置,可使用 fc-match --verbose。例如:
$ fc-match --verbose Sans
family: "DejaVu Sans"(s) hintstyle: 3(i)(s) hinting: True(s) ...
可在 font-config(5) 中查詢數字的意義。例如,hintstyle: 3 代表 hintfull。
某些應用程式如 URxvt 會忽略 Fontconfig 設置。你可以通過使用 ~/.Xresources 來解決這個問題,但它不如 Fontconfig 靈活。示例(選項說明見 #Fontconfig 配置):
~/.Xresources
Xft.autohint: 0 Xft.lcdfilter: lcddefault Xft.hintstyle: hintslight Xft.hinting: 1 Xft.antialias: 1 Xft.rgba: rgb
確保 X 啟動時使用 xrdb -q 正確加載這些設置(更多信息請參閱 X 資源)。
系統 DPI 設置與顯示器的硬體 DPI 不匹配會導致字體顯示模糊不清;關於處理高 DPI 或混合 DPI 顯示器的說明,請參見HiDPI。
一些矢量字體內嵌有位圖版本,這些位圖字體主要用於在較小的尺寸下渲染。在這種情況下,使用公制兼容字體作為替代可以改善渲染效果。
你也可以通過禁用字體的嵌入式位圖來強制在所有尺寸下使用矢量字體,但會犧牲一些渲染質量。
一些應用程式或桌面環境可能會覆蓋默認的 Fontconfig 微調和抗鋸齒設置。這種情況可能發生在 GNOME 上,例如,當你使用 vlc包 或 smplayer包 等 Qt 應用程式時。在這種情況下,請使用該應用程式特定的配置程序。對於 GNOME,請嘗試使用 gnome-tweaks包。
在 GNOME 下,有時會發生這樣的情況:即使在 GNOME 設置中將微調設置為"無",Firefox 之類的應用也會使用"完全"微調設置渲染字體,導致字體變得寬而銳利。在這種情況下,你必須在你的 fonts.conf 文件中添加微調設置:
<?xml version="1.0"?> <!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd"> <fontconfig> <match target="font"> <edit mode="assign" name="hinting"> <bool>false</bool> </edit> </match> </fontconfig>
在上面的例子中,微調級別被設置為了 grayscale。
在某些桌面環境(尤其是 GNOME 和 Plasma 之外的)中,一些 GTK 應用程式無法正確讀取字體配置。為了解決這個問題,請安裝 xsettingsd包 或 xsettingsd-gitAUR 並在每次系統啟動時運行它。更多信息請參見 Xsettingsd 和xsettingsd wiki。
對於此問題,可以使用以下配置:
~/.xsettingsd
Xft/Hinting 1 Xft/HintStyle "hintslight" Xft/Antialias 1 Xft/RGBA "rgb"
如果這在一些應用程式中依然不起作用,可以安裝 xorg-xrdb包 並使用以下配置:
~/.Xresources
Xft.hinting: 1 Xft.hintstyle: hintslight Xft.antialias: 1 Xft.rgba: rgb
然後在每次系統啟動時執行腳本 xrdb -merge ~/.Xresources 來應用這些設置。參見 X resources 和 #不支持 Fontconfig 的程序。
此外,使用 GTK4 和 libadwaita 的程序會忽略字體微調設置。可以創建或修改以下配置來修正:
~/.config/gtk-4.0/settings.ini
[Settings] gtk-hint-font-metrics=true
如果執行如下命令
fc-match helvetica
返回
helvR12-ISO8859-1.pcf.gz: "Helvetica" "Regular"
那麼由 xorg-fonts-75dpi包 提供的位圖字體就有可能被嵌入到各種應用程式的"列印到文件"或"導出"功能所生成的 PDF 文件中。該位圖字體可能是在安裝整個 xorg包組 包組的時候安裝的(通常不推薦這樣做)。要解決這個問題,可以卸載該軟體包,並安裝gsfonts包(Type 1)或tex-gyre-fonts包(OpenType)字體,以獲得 Helvetica(以及其他 PostScript/PDF 基本字體)的自由替代品。
一些用戶報告說,在將 freetype2包 升級到 2.7.1 版本後,各個位圖字體的名稱發生了變化,導致終端模擬器和其他一些程序(如 dwm 或 dmenu)的字體混亂,因為它們會回退到另一種不同的字體進行顯示。該問題是由 PCF 字體族格式的改變造成的,這在他們的發布說明[6]中有所描述。從舊格式過渡到新格式的用戶可以通過創建字體別名來解決這個問題,就像[7]中描述的解決方案一樣;該方案同時在下面給出:
假設我們想為terminus-font包創建一個別名,在之前提到的 freetype2包 更新中,它從{ {ic|Terminus}} 被改名為 xos4 Terminus,那麼在 /etc/fonts/conf.d/ 中創建一個文件,用於設置字體別名:
/etc/fonts/conf.d/99-TerminusPCFFont.conf
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd">
<fontconfig>
<alias>
<family>Terminus</family>
<prefer><family>xos4 Terminus</family></prefer>
<default><family>fixed</family></default>
</alias>
</fontconfig>
現在,一切都應該能夠像之前一樣正常工作,但務必重新加載 .Xresources 或重啟顯示伺服器,以便使受影響的程序能夠使用字體別名。
自 Pango 1.44 起,在以某些字號使用 DejaVu Sans Mono 字體時,下劃線會消失。一種解決辦法是使用 Liberation Mono 作為等寬字體,見#設置默認或後備字體。
freetype2-demos包 提供用於調試 FreeType 字體配置的工具。ftview 是它的一個 GUI,你可以在其中實時預覽字體的渲染設置。比如:
$ ftview -e unic -d 1024x768x24 -r 96 10 /usr/share/fonts/noto/NotoSans-Regular.ttf
某些應用程式(如 Chromium/Electron)沒有正確應用伽馬校正,有些在特定場景(灰度)下禁用了伽馬校正,這會導致深色背景上的小文字模糊不清,在 <=1080p 的屏幕上出現難以閱讀的文字。這是 Chromium/Electron 的一個長期存在的問題,一個解決方法是使用 FREETYPE_PROPERTIES="cff:no-stem-darkening=0 autofitter:no-stem-darkening=0" 環境變量來啟用 stem darkerning。
你可以使用 font-config-info-gitAUR 收集有效的字體配置信息。它會從 多個 GTK 源、X resources、XSETTINGS 協議和 fontconfig包 查詢信息。
- Xft 教程 by Keith Packard
- X11 中的字體
- FreeType 2
- FreeType 2 API 參考:控制 FreeType 模塊
- Gentoo 字體渲染討論
- 關於輕微提示