試析FreeBSD桌面系統中利用Fontconfig進行字體配置的運作原理(一)

試析FreeBSD桌面系統中利用Fontconfig進行字體配置的運作原理(一)

杜比環繞聲

概要:本文以KDE桌面環境爲例,試析Fontconfig的運作機制


一、Fontconfig在桌面系統中的作用

KDE是類Unix系統中建立在X基礎上的一個主流桌面環境,對用戶來說,它提供了良好的圖形界面和語言切換機制,用以滿足來自不同國家、使用不同語言的用戶的使用需求,這種機制簡稱“國際化”。主要包括界面文字的翻譯,多種語言字體的管理、顯示的支持以及輸入法等等。這其中系統層面字體的管理和顯示的支持直接關係到文字的顯示效果,因此顯得尤爲重要。在KDE系統中,字體管理、顯示的支持採用的是如下框架。

Fontconfig(字體配置)-------->Freetype(字庫操作)-------------->xft(字體渲染)

Fontconfig : 管理系統安裝的字體,根據應用程序的字體配置,match(匹配)一種字體,填充match字體的各種屬性。

Freetype : 以Fontconfig匹配到的字體爲參數,根據應用程序需要讀取相應的字庫。

xft: 對需要顯示的語言文字進行渲染

二、X系統中字體的管理

作爲KDE底層支持的X,它使用字體服務器(xfs)對安裝的字體進行管理,也稱之爲“核心字庫管理系統”,基本配置原理是xfs使用可維護的字體安裝目錄和fonts.dir文件對字體進行操作。

X爲之提供了一些工具來完成管理操作。諸如 :

mkfontdir,mkfontscale 用來生成安裝字體的 fonts.dir和fonts.scale。

xlsfonts 用來顯示安裝的字體。

xfd 用來顯示指定字庫的信息。

xset 用來管理字體服務器。

對於FreeBSD,在安裝了xorg 7.2並且X server運行的情況下,字體安裝目錄可用 xset q來查詢

shell>xset q

Font Path:
/usr/local/lib/X11/fonts/misc/,/usr/local/lib/X11/fonts/TTF/,
/usr/local/lib/X11/fonts/OTF,/usr/local/lib/X11/fonts/Type1/,
/usr/local/lib/X11/fonts/100dpi/,/usr/local/lib/X11/fonts/75dpi/,
/home/dbhrscom/.fonts

上面顯示的是X系統安裝時定義的字體目錄。在這些目錄中,都有利用mkfontdir生成的fonts.dir(對於true type 字體需要使用mkfontscale 生成 fonts.scale,然後拷貝到fonts.dir中)。fonts.dir是個文本文件,裏面保存的是所在目錄的字體信息。關於這些信息的具體含義,可以參見X的man手冊,這裏不再贅述。

如果準備把一個字體安裝到X系統中,並且使用Xfs進行管理,大致需要以下過程:

1、建立一個目錄,並且把字庫文件拷貝到這個目錄下

2、運行mkfontdir或者mkfontscale,生成安裝字庫的fonts.dir文件。

3、運行“mkfontdir -e 系統編碼目錄” 生成encodings.dir 文件(可選)

4、運行 “xset +fp 字體目錄” 或者  “xset fp+ 字體目錄”,把字體目錄添加到xfs的字體目錄列表中。需要注意的是當字體目錄沒有fonts.dir這個文件時,這種添加字體目錄操作會失敗。

5、運行“xset rehash”進行更新,確保新添加的字體可用。

注意:作爲一種X系統的約定,安裝字體最方便的做法是把字體文件拷貝到“$HOME/.fonts/“目錄下,這樣省去了添加字體目錄的操作,而且xset +fp 是針對當前會話有效,如果準備系統啓動時有效,還要修改相關的配置文件。

三、Fontconfig的字體管理

簡單的說Fontconfig是使用字體緩存的機制來進行字體管理的。這個Xfs有所不同。fontconfig提供fc-cache來建立這個緩存。

shell >fc-cache -v

/usr/local/lib/X11/fonts: skipping, 0 fonts, 12 dirs
/usr/local/lib/X11/fonts/100dpi: skipping, 398 fonts, 0 dirs
/usr/local/lib/X11/fonts/75dpi: skipping, 398 fonts, 0 dirs
/usr/local/lib/X11/fonts/Fonts: skipping, 4 fonts, 0 dirs
/usr/local/lib/X11/fonts/OTF: skipping, 23 fonts, 0 dirs
/usr/local/lib/X11/fonts/TTF: skipping, 13 fonts, 0 dirs
/usr/local/lib/X11/fonts/Type1: skipping, 29 fonts, 0 dirs
/usr/local/lib/X11/fonts/bitstream-vera: skipping, 10 fonts, 0 dirs
/usr/local/lib/X11/fonts/cyrillic: skipping, 0 fonts, 0 dirs
/usr/local/lib/X11/fonts/encodings: skipping, 0 fonts, 1 dirs
/usr/local/lib/X11/fonts/encodings/large: skipping, 0 fonts, 0 dirs
/usr/local/lib/X11/fonts/local: skipping, 0 fonts, 0 dirs
/usr/local/lib/X11/fonts/misc: skipping, 55 fonts, 0 dirs
/usr/local/lib/X11/fonts/util: skipping, 0 fonts, 0 dirs
/home/dbhrscom/.fonts: skipping, 0 fonts, 0 dirs
/var/db/fontconfig: not cleaning unwritable cache directory
/home/dbhrscom/.fontconfig: cleaning cache directory
fc-cache: succeeded

fc-cache的運行原理是掃描fontconfig的配置文件中定義的字體目錄,然後利用掃描的結果生成系統字體緩存。在這個fc-cache -v的運行結果中可以看到,它所掃描的路徑已經涵蓋了xfs所管理的系統字體路徑。但這並不表示fontconfig和xfs的繼承關係,fontconfig掃描這些目錄,完全是因爲在配置文件fonts.conf中有這樣的定義!

<!-- Font directory list -->

        <dir>/usr/local/lib/X11/fonts</dir>

        <dir>~/.fonts</dir>

<!-- Font cache directory list -->

        <cachedir>/var/db/fontconfig</cachedir>
        <cachedir>~/.fontconfig</cachedir>

fc-cache所作的掃描都是基於以上的<dir></dir>定義。

這個配置文件在fontconfig最新版本中,默認放在下面的目錄中

/usr/local/etc/fonts/

而生成的字體緩存按照系統和當前用戶,分別存放到

/var/db/fontconfig
~/.fontconfig
這兩個目錄中,諸如下面所看到的

0c3f6abf7a2705d2e8570f7f70e9302d-x86.cache-2
1e99991e6eeb0b3e05d4185c886f4b19-x86.cache-2
2550ddc31d0b62d94bc27b0fea358aba-x86.cache-2
55cbb48b13195d29d336fd465f155e7b-x86.cache-2
75ff5e8ddb5aa19e5f229f72d89c73db-x86.cache-2

.cache-2 就是fc-cache的運行記號,fontconfig通過這個緩存來管理系統安裝的字體,也因爲這種機制在系統中安裝字體變得非常簡單,只要把字體文件放到fonts.conf定義的目錄中,然後運行一下fc-cache。

甚至fc-cache一下也不需要,因爲在fonts.conf中定義了刷新時間:

<!--
  Rescan configuration every 30 seconds when FcFontSetList is called
 -->
                <rescan>
                        <int>30</int>
                </rescan>
     

由此看出,fontconfig和xfs相比,fontconfig提供了更加靈活的字體管理機制,目前系統中保持xfs和fontconfig並行工作的理由,只能是爲必須使用xfs機制的程序提供一種支援。而作爲KDE,它使用的就是fontconfig進行字體管理。舉例來說,KDE的控制中心有個“字體安裝”模塊,通過分析可知它進行字體安裝的原理就是自定義一個安裝路徑,放到fontconfig的配置文件中,然後把字體拷貝到自定義的目錄。

四、Fontconfig配置文件的結構

在2.4.2以後的版本中,Fonfconfig的配置文件採用了模塊化的結構。配置文件由以下文件組成

/usr/local/etc/fonts/fonts.conf
/usr/local/etc/fonts/conf.avail/*.conf
/usr/local/etc/fonts/conf.d/*.conf

/usr/local/etc/fonts/conf.d/ 目錄下的文件大多數是 conf.avail/ 目錄下的連接,大致是如下這些:

20-fix-globaladvance.conf
20-lohit-gujarati.conf
20-unhint-small-vera.conf
30-amt-aliases.conf
30-urw-aliases.conf
40-generic.conf
49-sansserif.conf
50-user.conf
51-local.conf
60-latin.conf
65-fonts-persian.conf
65-nonlatin.conf
69-unifont.conf
80-delicious.conf
90-synthetic.conf

前面的數字用來控制執行的先後順序,從名稱上就可以看出,每個.conf文件都有針對性的字體特性進行處理。

而實現這種模塊化,所藉助的就是 /usr/local/etc/fonts/fonts.conf 文件。

<!--
  Load local system customization file
-->
        <include ignore_missing="yes">conf.d</include>


分析/usr/local/etc/fonts/conf.d 目錄下的文件,並通過打開Fontconfig的調試功能,可知這些配置文件的執行順序:

        Loading config file /usr/local/etc/fonts/fonts.conf
        Scanning config dir /usr/local/etc/fonts/conf.d
        Loading config file /usr/local/etc/fonts/conf.d/20-fix-globaladvance.conf
        Loading config file /usr/local/etc/fonts/conf.d/20-lohit-gujarati.conf
        Loading config file /usr/local/etc/fonts/conf.d/20-unhint-small-vera.conf
        Loading config file /usr/local/etc/fonts/conf.d/30-amt-aliases.conf
        Loading config file /usr/local/etc/fonts/conf.d/30-urw-aliases.conf
        Loading config file /usr/local/etc/fonts/conf.d/40-generic.conf
        Loading config file /usr/local/etc/fonts/conf.d/49-sansserif.conf
        Loading config file /usr/local/etc/fonts/conf.d/50-user.conf
        Loading config file /home/dbhrscom/.fonts.conf
        Loading config file /usr/local/etc/fonts/conf.d/51-local.conf
        Loading config file /usr/local/etc/fonts/conf.d/60-latin.conf
        Loading config file /usr/local/etc/fonts/conf.d/65-fonts-persian.conf
        Loading config file /usr/local/etc/fonts/conf.d/65-nonlatin.conf
        Loading config file /usr/local/etc/fonts/conf.d/69-unifont.conf
        Loading config file /usr/local/etc/fonts/conf.d/80-delicious.conf
        Loading config file /usr/local/etc/fonts/conf.d/90-synthetic.conf

五、Fontconfig所提供的調試功能

Fontconfig提供了調製功能,用來診斷字體配置運行時的信息,使用調製功能非常簡單,在KDE環境下用模擬終端定義 FC_DEBUG 這個環境變量的值即可:

例如:csh環境下

setenv FC_DEBUG 1

在模擬終端中啓動相應的程序,就可以查看設定的調試信息。可以按照下面Fontconfig用戶手冊介紹的說明設定具體顯示的調試信息。

  MATCH            1    Brief information about font matching 字體匹配信息
  MATCHV           2    Extensive font matching information
  EDIT             4    Monitor match/test/edit execution 顯示match/test/edit信息
  FONTSET          8    Track loading of font information at startup
  CACHE           16    Watch cache files being written
  CACHEV          32    Extensive cache file writing information
  PARSE           64    (no longer in use)
  SCAN           128    Watch font files being scanned to build caches
  SCANV          256    Verbose font file scanning information
  MEMORY         512    Monitor fontconfig memory usage
  CONFIG        1024    Monitor which config files are loaded 顯示配置文件裝載信息
  LANGSET       2048    Dump char sets used to construct lang values
  OBJTYPES      4096    Display message when value typechecks fail



待續。。。。。。

[ 本帖最後由 杜比環繞聲 於 2007-5-30 16:17 編輯 ]



 哈蜜瓜 回覆於:2007-05-30 18:41:21

不錯!認真學習!


 大大狗 回覆於:2007-05-30 18:44:36

好文繼續


 zerng07 回覆於:2008-07-18 19:20:06

請問,如果執行時,順序上較後方的配置檔和較前方的配置檔有所衝突,fontconfig 會優先執行後方配置檔而忽略前方配置檔嗎?還是相反呢?


 lsstarboy 回覆於:2008-07-18 19:50:46

留着記號慢慢看。


 BruceShea 回覆於:2008-07-19 01:56:31

當了版主的果然牛啊!:mrgreen: :mrgreen:


 杜比環繞聲 回覆於:2008-07-19 09:12:41

引用:原帖由 zerng07 於 2008-7-18 19:20 發表 [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=8858618&ptid=942632]
請問,如果執行時,順序上較後方的配置檔和較前方的配置檔有所衝突,fontconfig 會優先執行後方配置檔而忽略前方配置檔嗎?還是相反呢? 



從fontconfig的掃描順序和生成字體匹配pattern來看,編號大的後執行,對有衝突的配置選項,後執行的會覆蓋前面掃描得到的

PS:kde 並不完全靠fontconfig進行字體匹配,其中還受qtconfig中字體替換規則的影響。


 杜比環繞聲 回覆於:2008-07-19 09:16:19

引用:原帖由 BruceShea 於 2008-7-19 01:56 發表 [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=8860334&ptid=942632]
當了版主的果然牛啊!:mrgreen: :mrgreen: 



一年以前的老文了!:mrgreen:




原文鏈接:http://bbs.chinaunix.net/viewthread.php?tid=942632
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章