|
楼主 |
发表于 2012-3-1 16:23:03
|
显示全部楼层
Post by RichardGv;2161035
最重要的建议只有五个字:仔细看文档!man fonts-conf基本上把一切都解释清楚了。下次您问可以从文档中轻易得到答案的问题,我就只能用RTFM来回答了。
感觉兄台的英文水平相当了得,一定有过在纯英文环境下工作或生活的经历。另外,我感觉我的问题也不全在文档之内。
Post by RichardGv;2161035
/etc/fonts/conf.d中有很多配置文件可能会干扰您的配置,所以如果您打算详细配置fontconfig,要尽量关掉可能导致问题的配置文件。60-latin.conf和 65-nonlatin.conf是两个比较明显的例子。
非常感谢帮我纠正错误。其实,这两个文件里面除了定义sans、sans serif、mono,还定义了Fantasy、Cursive,通常的字体分类里好像没有见过,这两个是什么呢?
60-latin.conf和 65-nonlatin.conf是不是与49-sansserif.conf也不能共存呢?
Post by RichardGv;2161035
fontconfig内部对TrueType/OpenType字体会调用freetype的函数FT_Get_Sfnt_Name()来查询字体名称,所有的名称都会被查询到。"NSimSun"和"新宋体"会匹配到相同的字体。没有必要指定一个字体的多个名称。
这个好像不在文档之中啊。而且早几年的配置之中都会有这样的语句:- <match target="pattern">
- <test name="family">
- <string>新宋体</string>
- </test>
- <edit name="family" mode="assign">
- <string>NSimSun</string>
- </edit>
- </match>
复制代码 看来兄台对于freetype模块提供的接口很了解啊!佩服。
Post by RichardGv;2161035
这样,我简要介绍一下fontconfig做match处理的过程。因为正统的解释涉及术语太多,晦涩难懂,我们做个类比:您(某个应用程序)在"Xft"餐馆吃饭,负责点菜,就是点出您需要的字体(嗯,这样多好,只点菜,不付账 );fontconfig是服务生,负责匹配字体,也就是菜式;freetype是大厨,负责渲染字体,也就是做菜;Xft是另一个服务生,负责用XRender显示渲染出的字体,就是端菜。
您懒得看菜单,要求服务生根据餐馆可以做出来的菜式决定您具体吃的菜。您的要求是:
- “有红烧带鱼就点红烧带鱼;没有红烧带鱼,水煮鱼也可以;连水煮鱼也没有,就要一份宫爆鸡丁好了。”
- “嗯,我正在节食,来一小盘就好。“
- “不许弄辣椒啊!"
您的要求我们就可以记成:- 菜式:红烧带鱼 -> 水煮鱼 -> 宫爆鸡丁
- 大小:小盘
- 辣椒:不放
复制代码 对应于fontconfig,应用程序提出的要求(pattern/FcPattern)就可能是"4pt的文泉驿点阵宋,开抗锯齿”:- family: 文泉驿点阵宋, 宋体, 文泉驿正黑
- size: 4(pt)
- antialias: FcTrue
复制代码
接下来服务生对您的要求进行预处理,按内置的默认选项补充您的要求:- 菜式:红烧带鱼 -> 水煮鱼 -> 宫爆鸡丁
- 大小:小盘
- 盘子直径:150mm
- 辣椒:不放
- 盐:通常量
- 胡椒粉:不放
复制代码 真正的fontconfig通常会增加一大堆属性:
(注意,在这个阶段,fontconfig不在乎您的系统中是否有文泉驿点阵宋等等字体,它只是在修改您的要求!)- family: 文泉驿点阵宋, 宋体, 文泉驿正黑
- size: 4(pt)
- pixelsize: 4.1
- hintstyle: 3
- hinting: FcTrue
- slant: 0
- weight: 100
- width: 100
- ...
复制代码
然后服务生fontconfig开始阅读它的配置文件(老板娘的嘱咐? ),对您的要求进行修改。更准确地说,它目前只考虑target="pattern"的规则,而且它阅读的不是规则文件,而是一个定期刷新的配置文件的cache。假设配置文件中有这样一条规则:- <match target="pattern">
- <test qual="any" name="菜式"><string>水煮鱼</string></test>
- <edit name="菜式" mode="assign"><string>烤鱼</string></edit>
- </match>
复制代码 就是说,如果找到菜式中有水煮鱼的话,把它替换成烤鱼:- 菜式:红烧带鱼 -> 烤鱼 -> 宫爆鸡丁
- 大小:小盘
- 盘子直径:150mm
- 辣椒:不放
- 盐:通常量
- 胡椒粉:不放
复制代码 如果将mode="assign"换成mode="prepend",这个规则就成了:如果找到菜式中有水煮鱼的话,把烤鱼放在水煮鱼前面。
mode="append"就是后面了。fontconfig现在完全不考虑餐馆有没有水煮鱼或者烤鱼这两道菜!
为了解释<alias>的功用,我们来一个<alias>规则:- <alias>
- <family>宫爆鸡丁</family>
- <family>烤鸡翅</family>
- <accept>
- <family>炸鸡腿</family>
- <family>煮鸡腿</family>
- </accept>
- </alias>
复制代码 这个规则的意思就是,如果找到菜式中有宫爆鸡丁或者烤鸡翅的话,把炸鸡腿、煮鸡腿放在找到的宫爆鸡丁或者烤鸡翅后面:- 菜式:红烧带鱼 -> 烤鱼 -> 宫爆鸡丁 -> 炸鸡腿 -> 煮鸡腿
- 大小:小盘
- 盘子直径:150mm
- 辣椒:不放
- 盐:通常量
- 胡椒粉:不放
复制代码 <prefer>和<default>与<accept>区别只是插入的位置不同。同样,fontconfig不考虑餐馆有没有宫爆鸡丁、炸鸡腿。
最后一条规则:- <match target="pattern">
- <test qual="all" name="菜式" compare="not_eq">
- <string>清水煮白菜</string>
- </test>
- <edit name="菜式" mode="append_last">
- <string>清水煮白菜</string>
- </edit>
- </match>
复制代码 compare="not_eq" + qual="all" = "所有项目全部不是",append_last就是“加到最后面”。
这一条规则是指,如果您的菜式列表中所有项目全部不是"清水煮白菜",就将"清水煮白菜"插入菜式列表的末尾。
好了,配置文件中的规则执行完了。服务生fontconfig开始阅读菜单(终于开始了...),考虑具体给您上哪一道菜最符合要求。经过处理后您的要求是:- 菜式:红烧带鱼 -> 烤鱼 -> 宫爆鸡丁 -> 炸鸡腿 -> 煮鸡腿 -> 清水煮白菜
- 大小:小盘
- 盘子直径:150mm
- 辣椒:不放
- 盐:通常量
- 胡椒粉:不放
复制代码 (这哪里是您的要求啊,简直面目全非...)
相应的,真正的fontconfig会阅读您的字体列表(的cache...),找到最符合要求的字体。
服务生阅读列表后,发现红烧带鱼、烤鱼、宫爆鸡丁、炸鸡腿、煮鸡腿今天都没有,只有清水煮白菜... 于是他认定最符合要求的菜式是清水煮白菜。清水煮白菜没有小盘的,只有大碗装的。但是没有更匹配的菜式了,所以服务生会告诉大厨,要做的菜是大碗的清水煮白菜。
真正的fontconfig发现系统中有文泉驿点阵宋,文泉驿点阵宋处在family列表的最高位,所以选择文泉驿点阵宋。文泉驿点阵宋其实没有4pt这种大小,但是,fontconfig还是选择了某一个文泉驿点阵宋的字体文件(我们假定他选择了9pt的)。您的"4pt"大小要求被无视了。
这里实际上隐含了一个各种属性的优先权问题,对服务生来说,菜式的匹配最重要,盘子大小的匹配不重要。对真正的fontconfig来说,各种属性的匹配顺序是:foundry, charset, family, lang, spacing, pixelsize, style, slant, weight, antialias, rasterizer, outline,如果字体名family匹配而大小size不匹配,大小就会被忽视。
可怜的服务生fontconfig还有工作要做:将配置文件中所有target="font"的修改规则施加到最终选择的菜上。例如有这样一条规则:- <match target="font">
- <edit name="辣椒" mode="assign">
- <bool>放</bool>
- </edit>
- </match>
复制代码 简单地说就是:这是川菜馆,辣椒你吃也得吃,不吃也得吃!
对真正的fontconfig而言,所有target="font"规则都会在这一步被施加到最终选择的字体上。比如这样的规则:- <match target="font" >
- <edit name="antialias" mode="assign">
- <bool>false</bool>
- </edit>
- </match>
复制代码 就是说强制关闭抗锯齿处理。(不过这一点我还有些没想通...)
然后,终于开始做菜了。您点了不辣的小盘红烧带鱼,而服务生Xft最后给您盛上了一大碗放了辣椒的清水煮白菜... 坑人啊,幸好在Xft餐馆您不必付钱...
您对fontconfig提出的要求是4pt的文泉驿点阵宋,开启抗锯齿处理,而fontconfig给出的结果是关闭抗锯齿处理的9pt文泉驿点阵宋,这个还靠谱一些...
感谢兄台不厌其烦的解释,大概明白了alias的作用了。当然,请恕我愚钝,pattern这段还有几个东西需要再想想才能明白。还想问个不靠谱的问题:
如果应用程序的配置文件里面自行设定了字体要求(也即自带菜单),例如rxvt-unicode的配置文件中指定使用字体Lucida Grande,但系统里没有安装这个字体,这个时候xft怎么工作呢?
Post by RichardGv;2161035
对中文fontconfig用户而言,一个重要的概念就是binding。不了解binding可能会在涉及多语言的fontconfig配置上碰到很难解释的问题。呃,我今天码字太多了,懒得解释了,您自己一定要在man fonts-conf中找到binding相关内容仔细看看。
这个我会仔细看的。 |
|