Eric Cheng 的[WWW] wiki 寫得很好,Ping 就多加利用一下... 依 CreativeCommons 之授權轉錄於下。 :)

另外有 statue 寫的 [WWW] FreeBSD Chinese HOWTO 中的[WWW] 字型一節也很值得參考。


警告

萬一本文有更新的版本, 也許可以在 [WWW] http://fractal.csie.org/~eric/fontconfig 找到,任何使用本文中提及的方法所造成之社會成本損失將不會被負責。

版權聲明

在保留此版權聲明及原作者的情況下, 本文可以被任意轉錄。有關於本文更詳細的條件 請見: [WWW] http://creativecommons.org/licenses/by-nc-sa/1.0/ -- [WWW] Eric Cheng

See also: * Wprint 中文列印 Patch 與 freetype

引言

「為什麼我把 xxx 升了之後字就變難看了?」

「X 的字真是又醜又難設」

「Fontconfig Xft Freetype 到底是什麼關係啊!?!?」

螢幕上的字是用電腦的人整天會看到的,而用螢幕上有限的像素來有效顯示文字,又要提高文字的可讀性一直不容易。除了點陣字外,早在 80 年代就有的 anti-alias 也使得情況變得很複雜,即使已經過了 20 年,由於

所以能夠隨著自己的喜好而設定的字型是挺重要的。在各家 X desktop, toolkit 與瀏覽器的戰國時代,前後出現了許多解決方案,而 Fontconfig 是到目前為止,算是廣為被支援的一種新的不錯的方式,姑且一試,也許它還不能完全令你滿意,不過比起從前是來得有彈性多了。

Fontconfig

晚近的 XFree86 除了有了 freetype 的內建,加強了對於 TrueType 等向量字型的支援外,最近 Keith Packard 的 Xft 與 Fontconfig 也是一個對於字型整合所做的嘗試,在最新的 XFree86 4.3.x 與 freetype/Xft2/Fontconfig 的支援下,X 下的程式對於一個統一的字型選擇與繪製介面又進了一步。

雖然 XFree86 本身包含 Fontconfig, Fontconfig 事實上是一個可以獨立出來的 介面,它是一個 library 不是一套 user app, 它所做的就是提供一套 font matching 的機制,讓使用 Fontconfig 的程式可以不必自己實作一套字型的選取 方法。如此只要使用 Fontconfig 的程式愈多,單一的一套設定檔就可以被用在愈 多的應用程式,應用程式本身可以利用 Fontconfig 所得到的字型名稱去畫字,也 可以架構在自己原先的字型選擇架構之上 (如 Qt), 以達成對舊的設定的一定的向 後相容性。

Fontconfig 有許多好處,例如:

Xft

Xft 也是一套 library, 它使用 Fontconfig match 到了所要的字型之後, 來決定 該如何畫這些字。Xft 會看情況而決定要不要使用 core protocol 或 XRender 來 畫字。XRender 是 XFree86 4.x 新增的 extension, 我認為這是為了保留 X 的向 後相容性所新增的一個 hack, 不過因為它可以用來畫 anti-aliased 的字,目前 的使用愈來愈廣泛。不過 anti-aliased text 只有在使用向量字型的時候有用, 繪製點陣字的時候就要使用 core lib. Core library(以 x-truetype 或 freetype 作為 backend)自然也是可以畫向量字,只不過畫出來的就不能有 anti-aliased 的效果了。

有時當 XRender 不能使用時(如你是透過網路用一個舊的 X server 來執行 X apps), Xft 也可以使用 core lib 來畫字。應用程式不必為這些問題操心,達到 資訊隱藏、各謀其政的目的。

Freetype

[WWW] Freetype 是一個很棒的畫字函式庫,XFree86 4.3 內含了 2.1.2. Freetype 提供 Xft 如何畫字的資訊,包括處理 anti-aliasing 或 hinting. 因此 freetype 的改變會影響到 Xft 畫出來的字,而 Fontconfig 的改變會影響到 Xft 如何去選字來畫。

fonts.conf

這裡所講的就是最新的 Fontconfig 與 Xft2 的設定。對於舊的 Xft1.0 的 ~/.xftconfig 就不提了。

如果你裝了 fontconfig, 那麼它應該已經附上了一套預設的設定檔。可以到 /etc/fonts/ (一些 Linux distributions) 或 /usr/X11R6/etc/fonts (一些 BSD flavors) 底下找找看 fonts.conf 這個檔案。

fonts.conf 是簡單的 xml 格式,在 etc/ 裡面的 fonts.conf 是 system-wide 的設定,一般不建議直接更改它,可以更改 local.conf 或是自己家目錄下面的 ~/.fonts.conf . 關於 fonts.conf 的各種語法,由於 manpage 裡頭已經寫得很 詳盡,所以這裡只是提及比較重要的一些部份,有興趣者可以 man fonts-conf. 所有的設定都放在 <fontconfig> 與 </fontconfig> 之間,而其中可以包含許多 tags, 詳細的 tags 可以參照 fonts.dtd 或者是 manpage.

<dir> 裡面是一個路徑,fontconfig 會自己遞迴地去找這個路徑裡頭的所有字型,如: <dir>/foo/bar/myfonts</dir>

<include> 可以把其他的設定檔引進來,它們的格式是一樣的。

其中最重要的 element 應該是 <match> 了。match 主要有兩種用法, 一種是 pattern match, 另一種是 font match. 前者會把所有的字型 match 出來,所以 針對它的更改會套用到所有的字型的選擇方式上。為什麼要更改字型的屬性? 因為 這樣可以針對個別的字型告訴 Fontconfig 該如何去處理這些字型,或是告訴 renderer 該如何去畫這些字型。這裡是一些常用到屬性的列表,關於所有的屬性 請洽 manpage:

Hinting 用來最佳化字型顯示的方法。由於螢幕的像素有限,向量字型的縮放需要 有更多的考量, 例如當一條線位在兩個像素格子中間時, 該取左邊的格子還是右邊 的格子? 如果這方面的控制沒有做好,就常常會出現字型的襯線沒有對齊,或是小 字歪七扭八的情況。 Hinting 是額外的資訊, 它告訴 renderer 該如何處理這些 細節的部份,使得向量字在小字的時候能夠好看。也因此 Hinting 是非常費時費 人力的工作,TrueType 字型很多,但是有良好 Hinting 的字型不多。拙劣的 Hinting 就會讓字變得很難看。

為了稍微改善這個問題,freetype 有 autohint 的功能,可以自動為沒有 hint 的字型做 hinting 的工作。另外由於 TrueType 的 hinting 是有專利的,不能完 全自由地使用, autohint 就不受這個限制。autohint 自然無法做得像人力的 hint 一樣好,不過至少比沒有 hint 要好些。話雖如此,對於許多筆劃複雜的文 字 (如中文) 目前 freetype 的 autohint 還做得不甚完美,而因為建立完整的 hinting 的難度,即使是英文字,原本就很高,內建有 hinting 的中文字型就少 之又少了。所以常常有人抱怨中文字在螢幕上很難看,就是沒有理想 hinting, 或 者是使用了 autohinter 所造成的一些反效果。

Anti-alias 是將字型在幕後先以數倍的大小來繪製,然後再縮成想要的大小,未 滿一格的格子用灰階補點。由於原本 X 所支援的 logic 運算不敷使用,所以才用 XRender 的 extension 來達成目的。除了一般的 Anti-alias 之外,Xft 還支援 了為 LCD 所設計的 subpixel rendering.

什麼是 subpixel rendering? 如果你用放大鏡去看 LCD, 會發現一個正方形的像素是由三個長方形小像素構成的。這排 列通常是紅綠藍,也就代表如果液晶螢幕的水平解析度是 1024 個像素,它其實有 1024x3 = 3072 個點,只不過這些點是 rgbrgbrgb... 依序排列的。以白底黑字為 例,如果需要滿格的像素,rgb 三格就需是全關 (0,0,0), 如果只是右邊三分之二 部份, 就關掉 g 和 b, 留下最左邊的 r 開著。這樣子理論上就會有原來三倍的水 平像素可以使用,大幅增加了液晶螢幕的解析度。但由於只開著紅色或黃色或其他 顏色,會有很明顯的光暈,所以一般會採用 filtering 的方式,把一個次像素的 值往左右兩格分散(因為無論對哪一格次像素來說,它的左右兩格的顏色和本身都 是不同的,所以往左右兩格分散可以均勻影響亮度),成為 1/3, 1/3, 1/3 分佈 ;但這樣的壞處是會顯得太模糊了一點,於是再多一層,把原先三格分成 5 格, 但權重改為 1/9 2/9 3/9 2/9 1/9。3/9 那一格就是原本的次像素,而鄰近的格子 就用這樣的方法分散後和原來該次像素格子的光度值相加,達到像素往中央集中, 卻又不太模糊的效果。Windows XP 有個 ClearType 選項可以打開對液晶螢幕顯示 最佳化,其基本原理就是 subpixel rendering. Xft 也有這樣的功能,不過 Xft 做得更多,除了 subpixel 外,還加上了 anti-aliasing。Fontconfig 的 rgba 選項就是設定液晶螢幕次像素的排列方式,一般都是 rgb, v 開頭的表示三種顏色 是縱向排列。如果好奇的話可以拿放大鏡仔細瞧瞧,或用數位相機近拍下來放大觀 察。

很多問題是出在 hinting, 因為許多時候, distribution 會把 freetype 的 bytecode hinting 打開,代表使用字型內部的 bytecode 來做 hinting 修正,如 果像 freetype 預設沒有打開或是使用 freetype 裡頭的 autohinter, 有時效果 不錯,有時卻不盡人意。另外 hinting 費時費力,大部分的字型設計師在做 hinting 的時候都只有針對點陣字的顯示做 hinting 的工作,這表示如果我們在 顯示小字又用 anti-aliasing 的話,通常是不在字型設計師最佳化的範圍內的; 當 hinting 不當的時候,小字 anti-aliasing 就會顯得非常難看(如歪七扭八或 擠成一團)。關於這方面 freetype 做了很多的努力, autohinter 也就是讓程式 自己做 hinting 的演算法。由於 hinting 實在是個很棘手的問題,Mac OS X 對 於 anti-aliasing 字型就都不使用 hinting. 好在 fontconfig 可以讓我們調整 這些細部的設定,讓我們針對個別的字型做不同的處理。

話題回到 pattern match: 要使用 pattern match, 只需要加入如下的 pattern, 它就會對所有的字型作用:

中間放的可以是一連串的 test, 然後是一連串的 edit. test 的用法是:

any 指的是說, 只要字型的該屬性 list 之中有一項有符合要 test 的值, test 就會成立。all 的話要 list 之中所有的都符合,first 要第一個符合, not_first 要除了第一個以外有符合的。通常只會用到 any, 預設也是 any. name 裡面填的就是前面所提的屬性, 如 name="family". compare 是比較的條件, eq 是相等, less 是小於, 以此類推。 <test> 所包住的那個值就是要用來比較的值 ,包括: int, double, string, matrix, bool 等等。一旦 test 的條件都成立, 就會進行到 edit 的階段,代表編輯符合條件上述 test 條件的屬性:

注意在 fontconfig 中, 屬性 (property) 可以是一個 list, 亦即一個屬性可有 許多的值。 assign 是說把 match 到的值取代掉, assign_replace 是說把該 list 的所有值取代成指定的值, prepend 則是插在 list 中被 match 到的那個值 的前頭, 以此類推。

fonts.conf 裡面有一個範例:

這個 pattern match 是說, 當 prefer_outline 的值是 true 的時候, 而且字型 的 family 又叫做 Times, 那麼就把它的 family list 前面加入 Times New Roman。這樣做的原因是, Times 本身是點陣字, 如果希望在許多應用程式指定用 Times 顯示時, 不要用點陣字顯示, 而要用 Times New Roman 這個 TrueType 字 型顯示, 這樣可以把 Times New Roman 的優先權提在 Times 的前面。 Family matching 是另一種 match 方法,它的用法和 pattern matching 差不多 ,只是它是針對個別字型的屬性作修改,用法是:

舉個例子,如果我想讓所有字型預設能夠打開 anti-aliasing, hinting 並且使用 subpixel rendering, 我就寫:

但是我可能覺得 Luxi Mono 這個字型在某些時候, subpixel 不太好看, 我就寫:

FAQ

Q. 我手上有很多 ttf, 我要怎麼裝它們?

Q. 我裝好了字型, 可是我的程式 (rxvt, aterm, gtk1.x) 卻不能使用它們?

Q. 我想要使用新細明體,可以嗎?

Q. 我想要像 Windows 上小字那樣的新細明體,那是怎樣辦到的呢?為什麼在一些大小,新細明體的筆劃會破碎呢?

Q. 我的細明體 (MingLiU) 的英文字和中文字會等寬?

Q. 我想要把 Gnome2 選單的中英文字型分開設。

相關: * Screenshot

Q. 我遇到了奇怪的問題,可是不知從何找起,怎麼辦?

Q. 我手上的字型都很難看。有什麼比較不錯的字型?

Q. 這份 FAQ 實在太沒有幫助了。我要找的問題都找不到。很多地方都寫錯了。

Q. 我照著這些方法設卻不能動。一切都太麻煩了!


last edited 2005-06-11 02:13:10 by PingYeh