Linux 字体微调 - windows 效果版
作者:quanliking
转载请注明:来自
适用范围:针对 LCD 用户,CRT 用户做少量修改。
实验系统:Debian\Ubuntu,其它发行版应该也适用。
目的:使 linux 下的字体显示达到和 windows 下一样的效果。
一、必须掌握的概念 DPI (以下讨论先避免 sub-pixle 子像素渲染技术,以免混淆)
看过无数流行的汉化或字体美化的文章,往往存在一个致命伤,即忽略了 DPI 这个重要概念,因此是不完整的。
DPI 原来是印刷上的记量单位,意思是每个英寸上,所能印刷的网点数(Dot Per Inch)。但随着数字输入,输出设备快速发展,大多数的人也将数字影像的解析度用DPI表示,但较为严谨的人可能注意到,印刷时计算的网点(Dot)和电脑显示器的显示像素(Pixel)并非相同,所以较专业的人士,会用PPI(Pixel Per Inch)表示数字影像的解析度,以区分二者。而在本文中我们约定两个概念可以互换,即 DPI 就是 PPI。
参考:
问题一: dpi 和我们的 LCD 屏有什么关系呢?
把眼睛凑近屏幕,容易发现我们的屏幕是由一个个小方格组成,我们称这些方格为像素,LCD 中有个术语叫屏幕的 native resolution(物理解析度),指的的就是屏幕所包含的像素数量,比如我的 TFT LCD 14" native resolution 为 1024x768,即水平由 1024 个像素组成,垂直由 768 个像素组成。通常让我们的 LCD 工作在 native resolution,成像效果最好。
通过控制像素的开关和色彩的组合来显示我们需要的图像,但不要忽略了屏幕像素的数量是有限的,所以往往在低解析度的显示设备上看到的图像并不十分清晰,比如在观察白底黑字(或黑底白字)的文字时,文字的边缘有尖锐的锯齿状(阶梯状),长时间观看,眼睛很容易疲乏,这也就是很多人喜欢看纸制书籍的一个重要原因,制作精良的纸张,它包含的“像素”可以达到很高,边缘看起来非常的流畅。
问题二: 有什么办法可以解决或缓解上述缺陷呢?
除了通过各种辅助技术(hinting,anti-alias,sub-pixel,etc.)改善成像效果外,最快捷的途径是换一台高解析度(高分屏或高 dpi) 的屏幕,简单说像素越精细越好。
讲到这里你可能很关心自己的屏幕的 dpi 具体为多少?(拿去和别人炫耀 :)
到这里找找看有没有你的 LCD dpi 信息:
问题三: 如果找不到,如何来手工计算?
找把尺子,把 LCD 屏可视区域的宽和高量一下,比如我的屏幕 width = 287 mm = 28.7 cm,height = 215 mm = 21.5 cm
换算比例: 1 cm = 0.39 inch, 1 inch = 2.54 cm
水平 dpi = 水平 resolution * 2.54 / width = 1024 * 2.54 / 28.7 = 90.6
垂直 dpi = 垂直 resolution * 2.54 / height = 768 * 2.54 / 21.5 = 90.7
故我的 dpi 大概为 90x90,在某些机子上水平 dpi 和 垂直 dpi 会不相当,这是很正常的。
问题四: 下面我们看看自己的单个像素具体有多大?
术语:
pixel pitch - 像素间距,即单个像素的水平宽度,类似于 CRT 的 dot pitch(点距)我的 TFT 14" 1024x768
pixel pitch = 28.7 / 1024 = 0.028 cm = 0.28 mm
而一台 T43 高分屏 SXGA+ 14" 1400x1050, pixel pitch = 0.2047 mm
可以看出 SXGA+ 14" 要精细的多。羡慕啊!
问题五: 我要显示一个 px = 12 的文字,实际看起来会有多大?
术语: [color=red]px(pixel size) - 显示单个文字需要的水平像素数量
实际大小 = px * pixel pitch
TFT 14" 1024x768: 12 * 0.28 = 3.36 mm
SXGA+ 14" 1400x1050: 12 * 0.20 = 2.4 mm
看到这里高分屏的用户应该明白为什么同样是 12 px 的 SimSun 点阵字体(bitmap font),在自己的屏幕上看起来要小很多,因为你的 pixel pitch 小。pixel pitch 小不是更好么?
不是不好,而是字太小了,看起来太累,为了保护你的视力,你应该选择大一些的 px。
但要注意中文点阵字体提供商并没有为每个 px 制作点阵汉字,因为中文点阵都是手工绘制的,需要很高的专业技能,非常耗时,故一般只绘制最常用的 px,而且点阵的一个最大的缺点就是不能够缩放,每个点阵汉字的每一个像素都是事先安排好的,缩放后打乱了原有的布局,比如出现破碎,高高低低之类的现象,使字体变得非常丑陋。
好在 winxp 带的 simsun.ttc 除了 outline 字体外,还包含了丰富的点阵,ppem(pixels per em)分别为 12px, 13px, 14px, 15px, 16px, 18px,你可以根据你的需要选择。例如选择 16px:
实际大小 = 16 * 0.20 = 3.2 mm,这样看起来和 14" TFT 上的 12 px 字就差不多大小了。
当然因为 ppem 不同(或 px 不同),绘制点阵字体时的空间自由度也不同,出来的点阵效果也不同,而且竖线横线比划一般都只占用一个像素宽度,在高分屏上 16px 看起来会有细胳膊细腿的感觉,这也就是为什么不少人会觉得 12px 在 14" 1024x768 上会比较好看,比较符合东方人对中文的审美观。
要注意,由于点阵字体以上的缺陷,通常用在低解析度的屏幕上,现在随着技术的发展,屏幕解析度逐步提高,越来越流行使用 outline 字体,这种字体可以随意的缩放,而不影响形状,现在高分屏用户可以尝试用黑体,如 mac os 带的华文细黑或微软新出的雅黑,黑体比划很粗,适合一部分人的审美观,在大屏幕上效果比较好。
问题六:既然 dpi 都不一样,我要去和别人讨论字体大小,如何讲清楚该字体究竟有多大呢?
真是一个难题,显然用 pixel 这个相对度量去讨论是不合适的,谁也说不清。所以这里我们引入另外一个重要单位 point(磅)。
1 point = 1/72 inch
这里的 inch 就是实际生活中使用的 inch。没错 point 才是绝对度量,比如一个 9 point(9磅)的字的实际大小:
9 * 1/72 = 1/8 inch = 1/8 * 2.54 cm = 3.175 mm
这样的话,大家才能从同一个标准出发讨论问题。所以你看到 MS office word 里的 size,都是以 point 为单位的。
注意,不同家族的字体,如 Arial 和 Verdana 字体,由于设计思路不同,同样磅值的字,看起来 Verdana 感觉要大一些。
VS
不要让 windows 蒙蔽了你的眼睛!由于显示器市场的混乱,不同产品 dpi 都不同,为了统一,windows 默认设置 dpi 为 96。注意这里的 dpi 不是你机器的实际 dpi,而是 windows 给你强加上去的。
统一的 96 dpi 有它的优点,因为市面上大多数的显示器 dpi 和这个值接近,而且大多数人都是用 wndows 来设计网页,因此无形中 96dpi 成了一个 de facto 上的标准。但缺点也是很明显的,设计师在 96 dpi 显示器上设计的网页到了 120 dpi 的机器上看起来可能效果会差强人意。所以现在有人建议设置 em 值,这个已经超出我的知识范围。
问题七:你在自己机器上看到的 9 point 还是 9 point 大么?
初看这句话好像自相矛盾,难不成 1 != 1 了!小学老师欺骗了俺?!
别着急!因为你打开 MS word,字体设置栏里看到的 9 point 字,很可能是错误的信息。
假如你运气很好,你的机器实际 dpi 刚好为 96 dpi,那么恭喜你,你没受骗,你看到的是正确信息,如果你的实际 dpi 和 96 相差比较大,那么你看到的是虚假信息。为什么这么讲呢?
我们来做几道小学数学题:
文字在 LCD 上成像,不管是 bitmap font 还是 outline 字体,最终都是以像素绘制。
比方我有一台实际 96 dpi 的 LCD,我要显示一个 9 point 大小的字,我们来看看具体需要多少像素 px?
换算公式: px = pt * dpi / 72
96 dpi, 9 pt: px = 9 * 96 / 72 = 12
操作系统水平要用 12 个像素来描绘该字。
屏幕上看起来有多大?
12 * pixel pitch
假如我通过各种手段人为的把 dpi 改成了 72,来算一下需要的像素值 px?
72 dpi, 9 pt: px = 9 * 72 / 72 = 9
屏幕大小:9 * pixel pitch
注意 pixel pitch 是不变的,计算方法见上文。
现在操作系统就以 9 个像素给你描绘该字,显然比 12 像素描绘出来的小。
这也就是为什么很多人抱怨 Debian/Ubuntu 下默认的 75 dpi ,设置为 9 ponit 的字会看起来比 windows 96 dpi 下小的多的缘故。
此时最可能发生的做法就是,把 9 point 改成更高的 point,而不知其实是 dpi 在跟你开玩笑呢!正确做法,应该先调整好系统 dpi,使之接近你的实际 dpi。
再结合高分屏来讨论一下。
问题八: 同样显示一个 9 point 字(即实际大小一样),显然在 TFT 上需要描绘该字的像素比较少,因为像素个头比较大,而在 SXGA+ 上用来描绘的像素多,个头细,哪个会看起来更漂亮些呢?
我猜你会毫不犹豫选择后者,好比用一个高 dpi 的数码相机拍摄同一个场景,拍出来的效果比低 dpi 要好的多。
但我只能部分同意,还要看你选择的是哪种字体。
如果你正在使用 outline 字体,它是可以任意缩放的,明显同样大小在 SXGA+ 上的表现要好很多,即字体边缘更加光滑流畅,好比在一张好的和画布上作画。
点阵字体要分情况讨论,不要忘了点阵字体是不能缩放的,而且 px 并不完整,只绘制了一些最常用的 px。
例如:
拿两台实际 dpi 分别为 96 和 72 的机器来讨论,同样显示 9 point 的点阵汉字。
上面已经计算过,dpi 96 要用 12 px, dpi 72 要用 9 px 绘制该字。
而使用的字体只带了 9px, 10px, 11px, 13px,14px,15px .....,恰好没提供 12px。
此时 96 dpi 机器上的 9 point 汉字,将会非常丑陋,因为此时的 12px 点阵是机器为你合成的,现在的 AI 还没那么智能,远没达到和人类一样的审美能力。就好比一台高性能手机,可惜不在服务器,任你本事多强,也无用武之地,多郁闷啊!
而 72 dpi 的机器,9 point 刚好落在 9px,此时的字体比划端端正正,自然效果会好的多。
以上的讨论也正说明了点阵字体的缺点,很不灵活。
所以在后面的讨论中,对于 outline 字体,我们用 point size 讨论, 直观方便。而对于 simsun 内嵌的点阵(bitmap font)会用 pixel size 来控制比较好,因为用 point size 的话,还要进行换算,看看是否刚好落在特定的 px,而换算要用到 dpi,个人的实际 dpi 又不尽相同,事先没法得知,故用 point size 是不合适的。
总结一下,dpi 在这里就像是一个桥梁,将 point size 转化为需要的 pixel size。
听了这么多,你也累了,休息一下吧!然后我们一起来实践一下,注意 Linux 将会有多个需要调整 dpi 的地方,希望你能区分清楚。
1、告诉 X server 你的实际 dpi
Debian/Ubuntu 下 X server 默认会使用 75 dpi,可以通过以下命令查看你的 X server 的 dpi 设置:
代码:
$ xdpyinfo |grep resolution
resolution: 75x75 dots per inch
因为我的实际 dpi 为 90, 故 75 对我来说低了。如果让 X server 工作在正确的 dpi,有多种途径,而且不同发行版略有差异,由于篇幅所限,只能部分介绍,具体请参考:
引用其中的几句话,简单看一下有哪几种和它们的优先级:
引用:
How the XFree86 and Xorg servers calculate DPI
The DPI of the X server is determined in the following manner:
1. The -dpi command line option has highest priority. 2. If this is not used, the DisplaySize setting in the X config file is used to derive the DPI, given the screen resolution. 3. If no DisplaySize is given, the monitor size values from DDC are used to derive the DPI, given the screen resolution. 4. If DDC does not specify a size, 75 DPI is used by default.
You can check what DPI your X server is set to by running xdpyinfo | grep resolution in a terminal window. |
对于 Debian/Ubuntu 我采用方法 2,下面的设置改成你自己的,注意 dpi 的数值最好为 6 或 12 的倍数,原因:
引用:
As above, if this works, but at less than 100% satisfaction, tweak the number lower or higher to suit your preference. If possible, use a number that is a multiple of 6, or even 12, as numbers that aren't sometimes result in annoying rounding errors that cause adjacent bitmap font sizes to not increment and decrement linearly. |
同时你可以更加自己的满意程度,进行微调。
代码:
$ vi /etc/X11/xorg.conf 加入
Section "Monitor"
......
DisplaySize 287 215 # 1024x768 90dpi
......
EndSection
这里的 287, 215 即我的实际显示区域的宽和高,单位为 mm。
重启 X 后,生效。以 gdm 为例:
代码:
$ /etc/init.d/gdm restart
查看是否生效:
代码:
$ xdpyinfo |grep dimensions
dimensions: 1024x768 pixels (289x217 millimeters)
$ xdpyinfo |grep resolution
resolution: 90x90 dots per inch
告诉 X server 实际 dpi 后,最直观的感觉就是用 gdm 登录管理器,在使用默认 75dpi 下,gdm Option 菜单和输入框中的字体会显得较小,其它的变化待大家慢慢发觉吧!
2、fontconfig/xft
对于传统的程序或系统,使用 legacy x font server,简称 xfs,那么上面的做法应该已经足够,但对于现在的程序来说,通常使用 fontconfig/xft,还得做进一步的工作。
引用:
Unfortunately, variations in the implementations of X mean display size reconciliation as above won't be a solution on every system. Failure here seems to be common on newer systems using fontconfig instead of legacy xfs |
代码:
$ vi /etc/fonts/local.conf 或 vi ~/.fonts.conf 加入
90
fontconfig 将根据该 dpi 值来进行字体的 point size 到 pixel size 的转换,具体过程参考:
据我实践,kde Qt3 程序会使用该值,包括 kdm,用该值来控制 Qt3 程序的字体 dpi 比较方便。
3、dpi in gonome
引用:
GNOME also offers an interface to set the Xft DPI. If "gnome-settings-daemon" is running, this will advertise the DPI value set in the gnome-font-properties dialog to GNOME applications via XSETTINGS, and set the Xft.dpi X resource. Any Qt application started after gnome-settings-daemon is running will use the Xft.dpi value configured by GNOME. |
简单说 gnome 额外提供了一个接口来更加灵活的控制设置 fontconfig/xft 程序的 dpi,当你运行 gnome 时,将会运行 gnome-settings-daemon 这个守护进程,来通知 Gtk2 程序 dpi 值,同时设置 Xft.dpi 来影响 Qt 程序。
操作方法,在 gnome 的字体功能面板 dpi 设置栏里输入 90,就可以了,你可以根据喜好,进行微调,马上能见到效果。
查看 Xft.dpi 值,方法如下:
代码:
$ xrdb -query
......
Xft.antialias: 1
Xft.dpi: 90.00000
Xft.hinting: 1
Xft.hintstyle: hintfull
Xft.rgba: rgb
据我实践,Gtk2 程序标题栏和菜单栏字体发生明显变化,包括 gnome 的开始菜单、工具栏、桌面字体等等,。而对于 Qt3 程序,除了标题栏发生变化,其它稳丝不动,因此还是得通过 fontconfig 修改。
细节:
如果 gnome 中的 dpi 和 X server 中的不同,而且相差很大,比如一个 120,一个 90。那么你在登录到 gnome 那一瞬间,会发现开始菜单的字体一下子变大,原因是最开始时 gnome-settings-daemon 还没运行。
4、字体大小不等,dpi 惹得祸
如果你在使用 kde 或 fvwm 之类,而又没有运行 gnome-font-properties,那么你会发现同样是 9 point 字,gtk2 程序和 Qt3 程序的显示大小不同。例如你打开 gnome terminal 和 kde terminal 比较一下。
解决方法:
$ vi ~/.Xresources
我的理解是 kde 会自动读取 fontconfig 的 dpi 的设置,而 gtk2 程序依赖 Xft.dpi。
如果你 dpi 设置遇到问题或有关术语不清楚,请看参考链接:
二、安装 MS core fonts
即然讲的是实现和 Windows 一样的效果,而我却叽哩咕噜讲了一大堆 dpi,你也听烦了,听会音乐,暂时把 dpi 丢在一边。我们开始一些机械劳动。
1、字体下载
其它发行版,请到这里下载:
Debian/Ubuntu:
代码:
$ apt-get install msttcorefonts
字体将会被安装到 /usr/share/fonts/truetype/msttcorefonts
分别是:
Andale Mono, Arial, Comic Sans MS, Courier New, Georgia
Impact, Times New Roman, Trebuchet MS, Verdana, Webdings
先来分分类:
无衬线字体(San Serif):
Arial 和 Verdana 作为无衬线字体的经典代表,是我们平时浏览 Web 是最常见的字体,在小字体下都有很好的表现,但是 Verdana 字符间隔(spacing)比较大,在浏览某些网页时,会出现布局混乱的现象,故我们把 Arial 作为我们的主字体。Trebuchet MS 也是比较常见的页面字体。
见:
衬线字体 (Serif):
Georgia 和 Times New Roman 都是比较美观的衬线字体,Georgia 和 Verdana 都出自字体巨匠 Matthew Carter 之手,并由 Monotype's hinting 专家 Tom Rickner 润色,具有很优雅的外观,故同样选择作为我们的主字体。
见:
等宽字体 (monotype):
Courier New 和 Adobe 的 Courier 有很像的外观,在终端下有非常好的表现,适合编程故选为我们的主字体。
卡通字体
Comic_Sans_MS 很休闲,也非常出名的卡通字体,可以用来装饰桌面等,有时候作为页面字体,也有很好的可读性。
见:
界面字体 (UI):
Tahoma 一直以来都是 MS 很多主线产品的 UI 字体,在小字下也有很优秀的表现,故选为我们的主字体,不过由于版权问题,MS 并不提供 Tahoma 免费下载,故不包含在核心字体包里。
简体中文字体:
winxp 带的 simsun.ttc 是一个 truetype 字体集,包括 SimSun(宋体)和 NSimSun(新宋体),它们的中文部分完全一样,唯一不同在于英文部分,NSimSun 的英文是等宽的。不过它们所带的英文衬线字体并不美观,我们在下面将用到字体替换技术,替换成我们喜欢的英文字体。
选择 simsun,除了它是 winxp 的默认字体外,另一个重要原因是带有丰富的点阵字体,在特定的 px 下有非常锐利的外观,所带点阵有效像素(ppem) 分别为 12,13,14,15,16,18,不仅制作规整专业,而且方方正正,很适合一般人的习惯。当然点阵字体的缺点也很明显,不像 Outline 字体可以随意缩放,点阵字体的每个像素都是人为安排的,缩放后打乱了整体结构,会变得非常丑陋。不过不要担心,我会很详细的讲解如何显示特定像素大小的点阵。
注意如果没有必要,请不要使用 simsun18030.ttc 或 vista 中的 simsun.ttc,因为 simsun18030.ttc 所带的点阵只有 12,14,16 三种 ppem,而且没有 xp 中 simsun.ttc 的点阵设计美观,而 vista 中的 simsun.ttc 就好比 simsun18030.ttc 的缩小版,除了字符集小一点外,我没看出区别来,故不要被这些名字所迷惑。
见:
繁体中文字体:
mingliu.ttc 同样是 truetype 字符集,包含 MingLiU(细明体)和 PMingLiU(新细明体),这里刚好和 simsun 倒一下,MingLiU 的英文部分是才是等宽的,所带的 ppem 分别为 11,12,13,15,16,20。一个需要注意的地方是 mingliu 使用了 hinting 技术,必须打开 freetype2 中的 BYTECODE INTERPRETER,否则在某些字号下,字体会整个破碎掉。而使用 bytecode 会涉及到一些专利问题,引用 firefly 大虾的话:
引用:
宋体和 Freetype2 有什么关系呀? (新)宋体、楷体_GB2312使用 bytecode 组字法,与一般的 TrueType 格式不一样,一般的 TrueType 是存放“笔划”,所以字型引擎只要依照笔划指引,就可以绘出字形,而 bytecode 则是一些虚拟指令(类似 java 的虚拟指令),这时候,字型引擎就必须化身为一个解译器,来解释并执行这些虚拟指令,就像 JVM 一样,bytecode 的好处是减少字型档案的大小。
bytecode 有三个部份为 Apple 专利,正是因为这个缘故,freetype2 预设并未打开这个 bytecode 解译功能,所以当遇到了 bytecode 组字的字型时,就会不正常(破碎),幸好此类字型不常见,有个好消息是:freetype unstable 版已经避开了 Apple 专利部份,而且预设也是开启 bytecode 解译功能,可见专利问题已解决了(猜测),所以才会预设开启。 |
庆幸的是通过观察源代码 Debian/Ubuntu 通过补丁的形式默认都开启了 BYTECODE INTERPRETER,而省去了我们自己编译的麻烦。可能某些发行版没有这么做。
参考链接:
如果你看不到上述网页效果,很正常,因为你还安装完成。
代码:
$ mkdir /usr/share/fonts/truetype/winxp
找台 Winxp,拷贝 c:\windows\fonts 下的 tahoma.ttf tahomab.ttf simsun.ttf mingliu.ttf 到该目录下。
同时在 /etc/X11/xorg.conf 中加入该路径,好让 legacy X font server 找到是上述四个新添加字体。
代码:
$ vi /etc/X11/xorg.conf
FontPath "/usr/share/fonts/truetype/winxp"
这时候有人会问了,刚装的 MS core font 的路径需要加么?
答案是一般不用了,因为在 Debian/Ubuntu 中有 defoma 帮我们管理字体,而 defoma 会自动在 /etc/X11/xorg.conf 中添加自己的字体路径:
代码:
# path to defoma fonts
FontPath "/var/lib/defoma/x-ttcidfont-conf.d/dirs/TrueType"
在该路径中已经包含了指向 MS core fonts 的字体链接。
代码:
$ /var/lib/defoma/x-ttcidfont-conf.d/dirs/TrueType# ls -al |grep Arial
lrwxrwxrwx 1 root root 55 2006-08-02 20:06 Arial_Black.ttf -> /usr/share/fonts/truetype/msttcorefonts/Arial_Black.ttf
lrwxrwxrwx 1 root root 61 2006-08-02 20:05 Arial_Bold_Italic.ttf -> /usr/share/fonts/truetype/msttcorefonts/Arial_Bold_Italic.ttf
lrwxrwxrwx 1 root root 54 2006-08-02 20:06 Arial_Bold.ttf -> /usr/share/fonts/truetype/msttcorefonts/Arial_Bold.ttf
lrwxrwxrwx 1 root root 56 2006-08-02 20:05 Arial_Italic.ttf -> /usr/share/fonts/truetype/msttcorefonts/Arial_Italic.ttf
lrwxrwxrwx 1 root root 49 2006-08-02 20:05 Arial.ttf -> /usr/share/fonts/truetype/msttcorefonts/Arial.ttf
而且 defoma 会自动调用 mkfontdir,mkfontscale 来创建 fonts.dir,fonts.scale,这些是 legacy X font server 需要的,注意不是 fontconfig 的需要。但是你使用老式程序的话,你会用到 xfs。
这里要注意区分 fontconfig 和 xfs,它们在你的系统中是共存的,可以简单用新旧两代字体系统来区分。
重启 X, 使之生效。
2、建立字体缓存
$ sudo fc-cache -fv
它会搜索在 /etc/fonts/fonts.conf 指定的字体路径或你自定义的字体路径中的任何 fontconfig 可识别的格式:
代码:
/usr/share/fonts
/usr/share/X11/fonts /usr/local/share/fonts
~/.fonts
并在路径下建立字体缓存文件 fonts.cache-1,这才是 fontconfig 的痕迹。
3、两个很有用的命令
1) fc-list
让我们看看刚装的 MS core fonts
代码:
$ fc-list : family foundry spacing |grep monotype
Andale Mono:spacing=100:foundry=monotype
Arial:foundry=monotype
Arial Black:foundry=monotype
Impact:foundry=monotype
Courier New:spacing=100:foundry=monotype
Times New Roman:foundry=monotype
$ fc-list : family foundry spacing |grep microsoft
Verdana:foundry=microsoft
Georgia:foundry=microsoft
Tahoma:foundry=microsoft
Comic Sans MS:foundry=microsoft
Webdings:foundry=microsoft
Trebuchet MS:foundry=microsoft
$ fc-list : family foundry spacing |grep SimSun
SimSun,宋体:spacing=90:foundry=unknown
NSimSun,新宋体:spacing=90:foundry=unknown
quanli@tpr50-ubuntu:~/fonts$ fc-list : family foundry spacing |grep MingLiU
PMingLiU,新細明體:foundry=dynalab
MingLiU,細明體:spacing=90:foundry=dynalab
family 表示字体家族,foundry 表示出品人,spacing 表示字符间隔
很容易看出 MS 的很多字体都不是它自己制作的,而是委托其它专业字体公司,如 monotype 完成制作,然后获取授权。简单说就是付过钱的。
这里的数字 90 代表 dual-width(双宽度),100 表示 mono-width(等宽),没有默认为 0 表示 proportional (不等宽)。
终端字体最好用等宽字体,可以看出我们选择的 Courier New 就是英文等宽字体,spacing=100。
而中文字体如 SimSun,NSimSun,MingLiU 都是双宽度字体,spacing=90,字体渲染引擎 Freetype2 在处理这些双宽度亚洲字体时会出现错误,故我们在后面的配置中要涉及这个问题。
2) fc-match
如果我们要看到单个字体的具体信息
代码:
$ fc-match -v Tahoma
Pattern 31 of 32
file: "/usr/share/fonts/myfonts/winxp/tahoma.ttf"(s)
scalable: FcTrue(s)
slant: 0(i)(s)
prefer_bitmap: FcTrue(w)
rgba: 1(i)(w)
rh_prefer_bitmaps: FcTrue(w)
size: 12(f)(s)
fontversion: 209060(i)(s)
weight: 80(i)(s)
family: "Tahoma"(s)
familylang: "en"(s)
antialias: FcFalse(w)
outline: FcTrue(s)
foundry: "microsoft"(s)
dpi: 90(f)(s)
stylelang: "ca"(s)
style: "Normal"(s)
lang: aa|ab|af|ar|ast|ava|ay|az|az-ir|ba|bam|be|bg|bi|bin|br|bs|bua|ca|ce|ch|chm|co|cs|cu|cv|cy|da|de|el|en|eo|es|et|eu|fa|fi|fj|fo|fr|ful|fur|fy|ga|gd|gl|gn|gv|ha|haw|he|ho|hr|hu|ia|ibo|id|ie|ik|io|is|it|kaa|ki|kk|kl|ku|ku-ir|kum|kv|kw|ky|la|lb|lez|lt|lv|mg|mh|mi|mk|mo|mt|nb|nds|nl|nn|no|ny|oc|om|os|pl|ps-af|ps-pk|pt|rm|ro|ru|sah|sco|se|sel|sh|sk|sl|sm|sma|smj|smn|sms|so|sq|sr|sv|sw|tg|th|tk|tn|to|tr|ts|tt|tw|tyv|ug|uk|ur|uz|ven|vi|vo|vot|wa|wen|wo|xh|yap|yi|yo|zu(s)
fontformat: "TrueType"(s)
width: 100(i)(s)
charset: set(s)
index: 0(i)(s)
pixelsize: 15(f)(s)
capability: "otlayout:arab otlayout:cyrl otlayout:hebr otlayout:latn otlayout:thai"(s)
verticallayout: FcFalse(s)
hinting: FcTrue(w)
autohint: FcFalse(w)
embeddedbitmap: FcTrue(w)
scale: 1(f)(s)
hintstyle: 3(i)(w)
globaladvance: FcTrue(s)
注意如果你在后面使用了一些字体替换技术,可能看到的信息是替换后的字体信息,比如:
代码:
$ fc-match -v SimSun
Pattern 30 of 32
file: "/usr/share/fonts/truetype/msttcorefonts/arial.ttf"(s)
......
这里我因为在后面把 SimSun 中的英文替换为 Arial,故出现信息混乱的情况。
看到这里聪明的你一定学会了如何给 fc-list 添加你想看到的参数,同时不要忘了看一下 man。
如果你想学到更多关于 fontconfig 的知识,请看下面链接:
三、字体配置
该是我们开始对字体进行微调的时候了!Go go ...
1) $ sudo dpkg-reconfigure fontconfig
代码:
Select Native if you mostly use Bitstream Vera (the default in Debian) or any of the Microsoft fonts.
Select Autohinter if you mostly use other TrueType fonts.
Select None if you want blurry text.
How should fonts be tuned for the screen?
Native
Autohinter
None
选 Native。
解释一下 Native 表示使用字体自带的 hinting 信息,Autohinter 顾名思义采用 freetype 的 autohint 来机器生产 hint 信息。none 则不使用以上任何一种 hint,通常的结果就是字体更模糊。
选择 Native 的原因是 MS 的 truetype 都带有非常漂亮的 hinting,那什么是 hinting 呢?
引用:
The "mathematically correct" pixels for character outlines scaled to a given size and resolution are often unaesthetic or illegible. Hinting is the name for the set of techniques for restoring, as far as possible, their aesthetics and legibility. ...... Each glyph in the font contains its own little hint program, with which the control points of the outlines can be manipulated just prior to rasterization in any way the hint programmer desires. In practice, this means that the outline is carefully distorted by each glyph's hinting instructions to surround only those pixels that produce the desired bitmap image. |
hinting 是 truetype 的心脏,与其说它是程序,不如说它是数学。每个字符最终在屏幕上都是 bitmap 形式成像,在这之前要先生成 outline 字符,然后缩放到需要比例,在送到 rasterization 产生二维图形前,要先被 hinting 调整,从而生产出屏幕最美观的 bitmap 字体。
常用的英文符号或其它欧州字符并不是很多,因此可以花很多的时间来给它们手工或其它方式添加 hinting,其中不同的字号大小,不同的字体风格,如 roman,bold,italic,需要进行单独调整,非常费时,从而提供最佳的效果,当然还是那句老话,只有更好,没有最好。
一般来说,hinting 比 autohint 要效果好的多,但对于一些免费字体,用 autohint 反倒是效果更好,原因可能是 Freetype 的设计者对这些字体做了优化。
中文字体由于为数众多,而且字型复杂,为每个字型添加 hinting,显然不实际,也做不好,故很少带 hinting 的。
本文的下文将围绕 hinting 这个主角展开。
见:
代码:
Rendering text at a subpixel level generally makes it look a bit better on flat (LCD) screens, but can show color artifacts on CRT screens. The "Automatic" choice will enable it only if a LCD screen is detected.
screens. The "Automatic" choice will enable it only if a LCD screen is detected.
Automatic
Always
Never
如果你是 LCD 请选上 Always, CRT 选择 Never。
sub-pixel 技术(暂略)
见: [url=""]Sub-Pixel Font Rendering Technology[/url]
sub-pixel 开关可以单独对每个字体进行的,个人建议是全局开 sub-pixel,而对于中文字体关闭 sub-pixel,对于英文字体根据喜好,有选择性的关闭。
代码:
By default, only outline fonts are used by applications which support fontconfig. Outline fonts are fonts which scale well to various sizes. In contrast, bitmapped fonts are often lower quality. Enabling this option will affect the systemwide default; this and many other fontconfig options may be enabled or disabled on a per-user basis.
Enable bitmapped fonts by default?
在这里我们选 No。这里不用担心用不了 simsun 内置的点阵字体(bitmap font),等会我们会为它单独打开。
确定以后,它还会为我们作一次 fc-cache,故前面 fc-cache 可以不做。
现在看看 dpkg-reconfigure fontconfig 到底为我们做了什么,背地里的行为我看不到,我只发现多了这么两个软链接:
代码:
ubuntu:/etc/fonts/conf.d# ls -al
total 32
drwxr-xr-x 2 root root 4096 2006-08-03 22:41 .
drwxr-xr-x 3 root root 4096 2006-08-03 19:11 ..
lrwxrwxrwx 1 root root 32 2006-08-03 22:41 20-debconf-sub-pixel.conf -> /etc/fonts/conf.d/sub-pixel.conf
lrwxrwxrwx 1 root root 33 2006-08-03 22:41 30-debconf-no-bitmaps.conf -> /etc/fonts/conf.d/no-bitmaps.conf
-rw-r--r-- 1 root root 250 2006-05-19 14:44 autohint.conf
-rw-r--r-- 1 root root 306 2006-05-19 14:44 no-bitmaps.conf
-rw-r--r-- 1 root root 257 2006-05-19 14:44 no-sub-pixel.conf
-rw-r--r-- 1 root root 256 2006-05-19 14:44 sub-pixel.conf
-rw-r--r-- 1 root root 247 2006-05-19 14:44 unhinted.conf
-rw-r--r-- 1 root root 296 2006-05-19 14:44 yes-bitmaps.conf
前面带数字的两个软链接是 dpkg-reconfigure fontconfig 的杰作,很简单吧!自己可以学着改改。Freetype 默认开的是 hinting,故虽然我回答了三个问题,只多了两个软链接。
在 /etc/fonts/fonts.conf 里包含了 /etc/fonts/conf.d 这个路径,故它会 Load 里面的配置。
如果 dpkg-reconfigure fontconfig 只为我们做了这么一点工作,那么该命令是完全没有必要运行的。我们后面的工作可比这个复杂的多。我在这里主要是为了起推波助澜的作用,同时也作为一部分全局设置。如果你喜欢清清爽爽一个配置文件的话,你可以删掉软链接,直接都写在一个文件中去。
关于 Ubuntu 中的 fontconfig-voodoo 命令,其实就是帮你写了一个不痛不痒的 fontconfig 配置文件。比如:
代码:
$ fontconfig-voodoo -l
ja_JP
ko_KR
none
zh_CN
zh_HK
zh_SG
zh_TW
ubuntu:/etc/fonts# fontconfig-voodoo -s zh_CN -f
多了
language-selector.conf -> /usr/share/language-selector/fontconfig/zh_CN
也就是说除了读 fonts.conf 多读一个事先配置好的 zh_CN 文件,里面的内容你可以参考学习,但为了不影响本文,把它去掉:
代码:
ubuntu:/etc/fonts# fontconfig-voodoo -s none -f
language-selector.conf -> /usr/share/language-selector/fontconfig/none
2. 写自己的配置文件
不要去修改 /etc/fonts/fonts.conf,因为它很可能在以后升级过程中被替换掉,为了不让你辛苦配置好的文件付诸东流,我们把配置写到 /etc/fonts/local.conf,可以被每位用户读到,当然你也可以写到 ~/.fonts.conf,但要注意如果使用 kde, 每次在 kde 控制中心设置字体后,kde 都会自动创建 ~/.fonts.conf,如果已经存在则在最底下加上它的配置,从而可能覆盖或影响到你的配置,这种做法在我看来是很讨厌的。好在 /etc/fonts/local.conf 是在 ~/.fonts.conf 后被 fontconfig 读取,具有更高的优先级,所以放在这里最合适。
因为配置会很长,故我分三个文件:
local.conf 负责全局配置,本身被 fonts.conf 读取,
msttcorefonts.conf 负责 MS core fonts,被 local.conf 读取,
cjk.conf 负责中日韩字体,被 local.conf 读取。
任何 fontconfig 配置文件,都被包含在 XML 结构之中:
1) local.conf
给使用 fontconfig 的程序设定目标 dpi,程序包括 kdm, kde 等:
字体分类:
代码:
Georgia
Times New Roman
SimSun
PMingLiU
serif
Arial
Tahoma
Verdana
Trebuchet MS
Comic Sans MS
Arial Unicode MS
sans-serif
Courier New
Andale Mono
NSimSun
MingLiU
monospace
给标准字体名提供别名,越靠前的字体家族优先级越高。
代码:
serif
Georgia
Times New Roman
SimSun
PMingLiU
sans-serif
Arial
Verdana
Trebuchet MS
Comic Sans MS
SimSun
PMingLiU
Arial Unicode MS
monospace
Courier New
Andale Mono
NSimSun
MingLiU
这里在 serif 和 sans-serif 标准字体名里我都加入了 SimSun 和 PMingLiU,而照理说 SimSun 和 PMingLiU 都属于 Serif?
道理很简单,比如 Georgia 没有中文字型,会向下匹配查找,直到找到第一个中文字型,即 SimSun。这里要注意的地方是,如果你还放了其它中文字体或日文韩文等,一定要加到 pMingLiU 的后面,否则会先使用这些字体里的相同字型,到时界面很丑陋,可别哭啊!
同样 Arial 虽然为 sans-serif 字型,但同样没带中文字型,故使用 SimSun 和 PMingLiU 来补充。
而 NSimSun 和 MingLiU 都是等宽字型,故作为终端字体配合 Courier New 使用。
其实还有个字体叫 Arial Unicode MS,在 Office 2k/xp 里可以找到,带有很全的 Unicode 编码,包括 CJK,是一个很好的补充字体,为了不增加劳动量,我在这里就一撇带过了。
设置 3 个常见 Adobe 字体家族的可接受字体
代码:
Times
Times New Roman
Helvetica
Arial
Courier
Courier New
一般来说,正常安装 Debian/Ubuntu 过程,都会将以下两个字体包装上:
xfonts-100dpi xfonts-75dpi
分别包含 100 和 75 dpi 的字体 for X,里面包括了 Times, Helverica, Courier 这三个字体家族,但它们都是 pcf bitmap 字体格式,而且只包含部分字体大小,最重要的是 pcf 并非很有效的字体格式,在读取时要整个读入内存,故一般体积比较小,而 truetype 是非常先进的字体格式,支持字体部分读取,效率很高。而且 MS 提供的以上三种 turetype 字体都是 outline 字体,可以随意缩放。故我一般直接将上面两个包删除,因为我根本用不到它们。如果你觉得它们有用,比如你觉得 Courier 作为终端字体更好看,那么你保留它们。关于如何删除系统字体,而不影响依赖关系,有兴趣的朋友,可以在文章的最后看到。
见: pcf 的效率
包含 cjk.conf 和 msttcorefonts.conf 文件
代码:
./cjk.conf
./msttcorefonts.conf
2)MS core fonts - msttcorefonts.conf
对于核心字体的配置是本文的重点,是实现和 windows 一样显示效果的关键。
很多人在处理英文字体的时候,都会很草率的进行,比如将低于某个数值的字体关闭 Anti-alias(反锯齿),其它开 AA。这种做法在许多场合效果并不理想。因为 MS 的 truetype 在做 hinting 时,是针对不同大小,不同风格做不同的处理,而非一锤子买卖。
在这方面我不得不说 MS 做得很仁义,我们来看看 MS 提供的
代码:
font name smoothing and hinting*
smoothed hinted both
Arial 0 - 6 7 - 13 14+
Arial Bold 0 - 6 7 - 8 9+
Arial Italic 0 - 6 7 - 13 14+
Arial Bold Italic 0 - 6 7 - 8 9+
Arial Black 0 - 6 7 - 12 13+
注意这里的单位是 point,对于 outline 字体用 pixel 讨论,在我看来是没什么意义的。
smoothed 即 Anti-alias
hinted 即 hinting
both 即 Anti-alias + hinting
(注意字体版本不同,信息和上面可以有所出入。)
可以很清楚的看到 Arial 和 Arial Bold 的不同,对于不同分格做了不同优化。写到这里明眼人已经看出我取这个文章题目的原因,我所有的诡计已被识破,黔驴技穷了。
如果上面没有的字体,如何找呢?一般 MS 提供的字体都会自带此类信息,而且 MS 提供了一个工具来帮助你更加简单的查看字体信息。
如果你没有 windows,或你懒得一个个去看,你可以查看我收集的数据。如下:
代码:
Font Name version smoothed hinted both
Andale Mono 2.00 0-6 7-20 21+
Arial 2.82 0-6 7-13 14+
Arial Black 2.35 0-6 7-12 13+
Arial Bold 2.82 0-6 7-8 9+
Arial Bold Italic 2.82 0-6 7-8 9+
Arial Italic 2.82 0-6 7-13 14+
Comic Sans MS 2.10 0-6 7-11 12+
Comic Sans MS Bold 2.10 0-6 7-8 9+
Courier New 2.82 0-6 7-27 28+
Courier New Bold 2.82 0-6 7-11 12+
Courier New Bold Italic 2.82 0-6 7-12 13+
Courier New Italic 2.82 0-6 7-27 28+
Georgia 2.05 0-6 7-12 13+
Georgia Bold 2.05 0-6 7-12 13+
Georgia Bold Italic 2.05 0-6 7-12 13+
Georgia Italic 2.05 0-6 7-12 13+
Impact 2.35 0-6 7-16 17+
Times New Roman 2.82 0-6 7-13 14+
Times New Roman Bold 2.82 0-6 7-10 11+
Times New Roman Bold Italic 2.82 0-6 7-13 14+
Times New Roman Italic 2.82 0-6 7-15 16+
Trebuchet MS 1.22 0-6 7-12 13+
Trebuchet MS Bold 1.22 0-6 7-8 9+
Trebuchet MS Bold Italic 1.22 0-6 7-8 9+
Trebuchet MS Italic 1.22 0-6 7-12 13+
Verdana 2.35 0-6 7-12 13+
Verdana Bold 2.35 0-6 7-12 13+
Verdana Bold Italic 2.35 0-6 7-12 13+
Verdana Italic 2.35 0-6 7-12 13+
Webdings 1.03 0-6 7-21 22-1536 1537+
Tahoma 3.09 0-6 7-12 13+
Tahoma Bold 3.09 0-6 7-12 13+
SimSun 3.03 0-6 7-18 19+
MingLiU 5.03 0-6 7-36 37+
Others:
Arial Unicode MS 1.01 0-6 7-18 19+
MS 雅黑 0.72 0-6 7-17 18+
MS 雅黑 Bold 0.72 0-6 7-13 14+
Segoe UI 0.98 0-6 7-14 15+
Segoe UI Bold 0.98 0-6 7-14 15+
Segoe UI Italic 0.96 0-6 7-14 15+
Segoe UI Bold Italic 0.95 0-6 7-14 15+
接下来的工作是非常繁琐的,要针对每个字体微调,但你不必担心,我已经帮你做好。
代码:
$ vi /etc/fonts/msttcorefonts.conf
......
对应上述表格 both 栏,即最右边一栏,开 AA + hinting,注意这里的 size 即 point size
代码:
monotype
microsoft
true
false
true
hintfull
对应表格 smoothed 栏,即小于等于 6 point 的字,只开 AA
代码:
monotype
microsoft
6
true
false
false
对应表格 hinted 栏,只开 hinting。这里是最繁重的一关,我在配置文件中将每一种字体,每一种风格详细列出,方便大家以后自己微调。
篇幅关系,只举几个特例:
代码:
Arial
regular
roman
7
13
false
false
true
hintfull
还记得上面介绍的如何查看字体信息的方法么!这里 roman 表示非斜体,其它信息都是自解释的。
再来个
代码:
Times New Roman
bold
italic
7
13
false
false
true
hintfull
bold 表示出体,italic 表示斜体,这些都是常量,你也可以用对应的数字表示,具体参考:
如果某种风格的字体由于开了 sub-pixel,造成边缘花花绿绿,让你很不舒服,你可以单独的关闭它,插入以下语句:
因为这个因人而异,我没法帮你调。
3) CJK 字型
老规矩:
[code]
$ vi /etc/fonts/cjk.conf
......
CJK 双宽度纠正
代码:
zh
ja
ko
dual
proportional
false
替换 SimSun/NSimSun 和 PMingLiU/MingLiU 的英文部分为你喜欢的英文
代码:
SimSun
PMingLiU
Arial
NSimSun
MingLiU
Courier New
如果你喜欢 Verdana 把 Arial 改为 Verdana,如果你喜欢衬线字体,把 Arial 改为 Georgia 之类的。
以下是 SimSun/NSimSun,PMingLiU/MingLiU 微调,原则是存在点阵就优先使用点阵,否则选择 Outline 字体
代码:
SimSun
NSimSun
PMingLiU
MingLiU
none
true
false
true
hintfull
true
开启 SimSun/NSimSun 点阵字体,分别为 px = 12,13,14,15,16,18:
代码:
SimSun
NSimSun
12
18
false
SimSun
NSimSun
17
true
注意对于点阵我们要用 pixel size,道理上面说过了,这里看你个人的喜好,你不喜欢这么多,就少开点。
下面对 PMingLiU/MingLiU 做同样的处理,包含的点阵分别为 px = 11、12、13、15、16、20
代码:
MingLiU
PMingLiU
11
16
false
MingLiU
PMingLiU
14
true
20 px 的我觉得还是开 AA 吧!
为不带粗体的中文字体机器合成粗体
代码:
Song
Sun
Kai
Ming
180
true
其实 Win 下的 simsun 粗体也是合成的。还有的人觉得 Ubuntu 好像比其它发行版优秀,比如有斜体/粗体支持,其实不过是配置文件略有不同。
如果你觉得合成的粗体不过好看,可以用其它黑体/圆体之类来替换,可以增加下面的语句
再补充一个微软雅黑字体,作为输入法输入框字体很不错,黑体要求块头越大,越好看,很壮观的。
只要简单拷贝该字体到我们的字体路径下,然后 $ sudo fc-cache -fv,就 OK 了。
代码:
Microsoft YaHei
none
true
false
true
hintfull
配置文件我已经在附件中给出,写累了,休息一下,看看反馈意见。
按本文配置好后,到下面链接比较一下效果:
觉得不错,贴个图我看看,哪里不清楚,同样贴图让我知道,如果配置文件哪里写的不理想,应该怎么改更好,也让我学习一下,比如我用的是英文界面,中文界面我还没测试。觉得太烂了,也别骂我,水平实在有限。
顺便提一下 Ubuntu 中的 firefox,一定要关闭 PANGO
$ vi /etc/firefox/firefoxrc
MOZ_DISABLE_PANGO=1
附件更新时间
2006.08.08.21.28本文出自 51CTO.COM技术博客