日历
网志分类
· 所有网志 (4)
· BSD/Unix (2)
· GNU/Linux (2)
· Shell/Script (0)
· Database (0)
站内搜索
友情链接
· 我的歪酷 非非共享界

订阅 RSS

0003170

歪酷博客

BSD/Unix 及其它


« 上一篇: Archlinux字体设置
冷水浴 @ 2008-06-23 08:46

  Fontconfig 文件类型定义在延伸的实体“fonts.dtd”中,通常存储在默认的字体设置目录(/etc/fonts)。每个配置文件必须包括下列的结构:
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
...
</fontconfig>


   fonts.conf 是简单的 xml 格式,包含了fontconfig函数库的配置信息,其中有用来寻找字体及相关信息的目录名称,还有在尝试匹配现有字体前执行的字体样板编辑指令。在 etc/ 里面的 fonts.conf,一般不建议直接更改它,可以更改~/.fonts.conf .
   ~/.fonts.conf 是当前用户字体配置的默认位置,实际的位置可以在fonts.conf文件里指定。
   fonts.dtd 是一个描述配置文件格式的DTD文件。
fonts.conf
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<!-- /etc/fonts/fonts.conf file to configure system font access -->
<fontconfig>

配置头部,fontconfig是字体匹配设置的开始。
<!-- Font directory list -->
<dir>/usr/share/fonts</dir>
<dir>/usr/share/X11/fonts</dir> <dir>/usr/local/share/fonts</dir>
<dir>~/.fonts</dir>

<dir> 里面是一个路径,fontconfig 会自己递归地去找这个路径里头的所有字型
<!-- Font cache directory list -->
<cachedir>/var/cache/fontconfig</cachedir>
<cachedir>~/.fontconfig</cachedir>

   包含一个为每个用户设置的缓存字体信息的文件名称。如果它以“~”开始的话,代表一个在用户主目录的文件。这个文件是用来保留在为每个目录设置的缓存文件中没有的字体信息的。Fontconfig将会自动处理缓存文件。

match 主要有两种用法, 一种是 pattern match, 另一种是 font match.
前者会把所有的字型 match 出来,所以针对它的更改会套用到所有的字型的选择方式上。为什么要更改字型的属性? 因为这样可以针对个别的字型告诉 Fontconfig 该如何去处理这些字型,或是告诉 renderer 该如何去画这些字型。这里是一些常用到属性的列表:
* family - String - 就是一般所看到的字型的名称了, 如 Arial
* style - String - 字型的 style, 像是 Regular, Bold, Italic...
* spacing - Int - 字型的宽度, Proportional 是有不同的宽度, monospace 是单一的宽度 (如 terminal 的字型)
* antialias - Bool - 决定该字型是否要被 anti-alias 绘制; 只能用在向量字型上
* hinting - Bool - 决定该字型是否要打开 hinting
* autohint - Bool - 决定是否要用 Freetype 自己的 hint 方法来 hint 字型, 还是用预设的方法来 hint
* rgba - Bool - 决定是否要用 subpixel 的方式来画字, 可以是 none (只用灰阶), rgb, bgr, vrgb, vbgr
match target="pattern"
这个单元先存放(可能是空的)test元素列表,然后是一个edit元素列表(也可能是空的)。匹配检测(test元素)条件的样板将受到 edit元素列表的影响。如果“target”设定为“font”而不是默认的“pattern”的话,那么这个单元就将应用到一个匹配后的字体名称,而不是一个需要匹配的字体样板。
test qual="any" name="property" compare="eq"
这个单元包含一个单独的值,用来和样本的属性“property”比较(可以替换property为任意一个上面列出的属性)。 “compare”可以是“eq”(等于),“not_eq”(不等于),“less”(小于),“less_eq”(小于等于),“more”(大于),“more_eq”(大于等于)。“qual”可以为默认的“any”,在这种情况下,只要任意一个之字体属性符合比较的值,匹配就成功。如果 “qual”为“all”的话,只有当所有的字体属性都符合比较的值的时候,匹配才成功。
edit name="property" mode="assign" binding="weak"
这个单元包括一个表达式单元的列表(任何赋值和操作单元)。表达式单元将在运行的时候被执行并且将修改属性“property”。是否修改依赖于 “property”的值是否匹配相应的test单元。如果匹配的话,这个修改将会影响第一个匹配的值。任何插入到属性的值都可以给出绑定(binding)说明。“mode”可以是以下列表其中的一个:
Mode
有匹配条件
没有匹配条件
"assign"
替换匹配的值
替换所有值
"assign_replace"
替换所有值
替换所有值
"prepend"
在匹配前插入
在列表头部插入
"prepend_first"
在列表头部插入
在列表头部插入
"append"
在匹配后添加
在列表底部添加
"append_last"
在列表底部添加 在列表底部添加
要使用 pattern match, 只需要加入如下的 pattern, 它就会对所有的字型作用:
<match target="pattern">
...
</match>

中间放的可以是一连串的 test, 然后是一连串的 edit.

test 的用法是:
<test qual="any|all|first|not_first" name="属性"compare="eq|not_eq|less|less_eq|more|more_eq|contains|not_contains">

</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 条件的属性:
<edit name="属性" mode="assign|assign_replace|prepend|append|prepend_first|append_last">

</edit>

注意在 fontconfig 中, 属性 (property) 可以是一个 list, 亦即一个属性可有许多的值。
assign 是说把 match 到的值取代掉,
assign_replace 是说把该 list 的所有值取代成指定的值,
prepend 则是插在 list 中被 match 到的那个值的前头, 以此类推。
<!--
 Accept deprecated 'mono' alias, replacing it with 'monospace'
 字型的 family 叫做 mono,就强制把要请求的字体改为monospace
-->
<match target="pattern">
<test qual="any" name="family">
<string>mono</string>
</test>
<edit name="family" mode="assign">
<string>monospace</string>
</edit>
</match>

<!--
 Accept alternate 'sans serif' spelling, replacing it with 'sans-serif'
 字型的 family 叫做 sans serif,就强制把要请求的字体改为sans-serif
-->
<match target="pattern">
<test qual="any" name="family">
<string>sans serif</string>
</test>
<edit name="family" mode="assign">
<string>sans-serif</string>
</edit>
</match>
 
<!--
 Accept deprecated 'sans' alias, replacing it with 'sans-serif'
 字型的 family 叫做 sans,就强制把要请求的字体改为sans-serif
-->
<match target="pattern">
<test qual="any" name="family">
<string>sans</string>
</test>
<edit name="family" mode="assign">
<string>sans-serif</string>
</edit>
</match>
 
<!--
 Load local system customization file
 读入用户配置文件conf.d,如果不存在的话不发出警告信息
-->
<include ignore_missing="yes">conf.d</include>

这个单元包含一个附加的配置文件名称。当XML数据类型被FcConfigParse扫描处理后,这个文件的内容也将会通过传送文件名称到 FcConfigLoadAndParse,从而被包括在配置中。如果“ignore_missing”设成“yes”而不是默认的“no”的话,一个丢失的文件将不会引起函数库的警告信息。

<config>
config这个单元提供一个整合附加的配置信息的地方。config可以按照任意顺序包含blank和rescan单元。
<blank>
blank字体通常包含“破碎”的字型,它们在编码中存在但在屏幕上却被绘制成空白。我们在blank单元中放置每个预计是空白的unicode字符到int单元中。这些绘制为空白的字符将从字体支持的字符集中忽略。
<!--
 These are the default Unicode chars that are expected to be blank
 in fonts.  All other blank chars are assumed to be broken and
 won't appear in the resulting charsets
-->
<config>
<blank>
<int>0x0020</int><!-- SPACE -->
<int>0x00A0</int><!-- NO-BREAK SPACE -->
<int>0x00AD</int><!-- SOFT HYPHEN -->
<int>0x034F</int><!-- COMBINING GRAPHEME JOINER -->
<int>0x0600</int><!-- ARABIC NUMBER SIGN -->
<int>0x0601</int><!-- ARABIC SIGN SANAH -->
<int>0x0602</int><!-- ARABIC FOOTNOTE MARKER -->
<int>0x0603</int><!-- ARABIC SIGN SAFHA -->
<int>0x06DD</int><!-- ARABIC END OF AYAH -->
<int>0x070F</int><!-- SYRIAC ABBREVIATION MARK -->
<int>0x115F</int><!-- HANGUL CHOSEONG FILLER -->
<int>0x1160</int><!-- HANGUL JUNGSEONG FILLER -->
<int>0x1680</int><!-- OGHAM SPACE MARK -->
<int>0x17B4</int><!-- KHMER VOWEL INHERENT AQ -->
<int>0x17B5</int><!-- KHMER VOWEL INHERENT AA -->
<int>0x180E</int><!-- MONGOLIAN VOWEL SEPARATOR -->
<int>0x2000</int><!-- EN QUAD -->
<int>0x2001</int><!-- EM QUAD -->
<int>0x2002</int><!-- EN SPACE -->
<int>0x2003</int><!-- EM SPACE -->
<int>0x2004</int><!-- THREE-PER-EM SPACE -->
<int>0x2005</int><!-- FOUR-PER-EM SPACE -->
<int>0x2006</int><!-- SIX-PER-EM SPACE -->
<int>0x2007</int><!-- FIGURE SPACE -->
<int>0x2008</int><!-- PUNCTUATION SPACE -->
<int>0x2009</int><!-- THIN SPACE -->
<int>0x200A</int><!-- HAIR SPACE -->
<int>0x200B</int><!-- ZERO WIDTH SPACE -->
<int>0x200C</int><!-- ZERO WIDTH NON-JOINER -->
<int>0x200D</int><!-- ZERO WIDTH JOINER -->
<int>0x200E</int><!-- LEFT-TO-RIGHT MARK -->
<int>0x200F</int><!-- RIGHT-TO-LEFT MARK -->
<int>0x2028</int><!-- LINE SEPARATOR -->
<int>0x2029</int><!-- PARAGRAPH SEPARATOR -->
<int>0x202A</int><!-- LEFT-TO-RIGHT EMBEDDING -->
<int>0x202B</int><!-- RIGHT-TO-LEFT EMBEDDING -->
<int>0x202C</int><!-- POP DIRECTIONAL FORMATTING -->
<int>0x202D</int><!-- LEFT-TO-RIGHT OVERRIDE -->
<int>0x202E</int><!-- RIGHT-TO-LEFT OVERRIDE -->
<int>0x202F</int><!-- NARROW NO-BREAK SPACE -->
<int>0x205F</int><!-- MEDIUM MATHEMATICAL SPACE -->
<int>0x2060</int><!-- WORD JOINER -->
<int>0x2061</int><!-- FUNCTION APPLICATION -->
<int>0x2062</int><!-- INVISIBLE TIMES -->
<int>0x2063</int><!-- INVISIBLE SEPARATOR -->
<int>0x206A</int><!-- INHIBIT SYMMETRIC SWAPPING -->
<int>0x206B</int><!-- ACTIVATE SYMMETRIC SWAPPING -->
<int>0x206C</int><!-- INHIBIT ARABIC FORM SHAPING -->
<int>0x206D</int><!-- ACTIVATE ARABIC FORM SHAPING -->
<int>0x206E</int><!-- NATIONAL DIGIT SHAPES -->
<int>0x206F</int><!-- NOMINAL DIGIT SHAPES -->
<int>0x3000</int><!-- IDEOGRAPHIC SPACE -->
<int>0x3164</int><!-- HANGUL FILLER -->
<int>0xFEFF</int><!-- ZERO WIDTH NO-BREAK SPACE -->
<int>0xFFA0</int><!-- HALFWIDTH HANGUL FILLER -->
<int>0xFFF9</int><!-- INTERLINEAR ANNOTATION ANCHOR -->
<int>0xFFFA</int><!-- INTERLINEAR ANNOTATION SEPARATOR -->
<int>0xFFFB</int><!-- INTERLINEAR ANNOTATION TERMINATOR -->
</blank>


rescan单元存放一个表示自动扫描字体配置文件变化间隔时间的int单元。每次间隔过后,Fontconfig都将验证所有的配置文件和目录并且自动重建内部的数据结构。
<!--
 Rescan configuration every 30 seconds when FcFontSetList is called
-->
<rescan>
<int>30</int>
</rescan>
</config>
</fontconfig>


int, double, string, bool
这些单元保存单独一个声明的类型。bool 单元保存true或者false。在赋浮点数的时候有一个重要的限制——fontconfig要求尾数必须以一个数字开始,而不是一个小数点,所以应该碰到纯小数的时候应该插入一个起始的"0"。(例如用0.5而不是.5,-0.5而不是-.5。)
Matrix:这个单元保存一个防射变换的四个double元素。
Name:保存一个属性名称。从字体属性的第一个值判断出来的,而不是样板的第一个值。
Const:保存一个常量的名称。以下这些数值总是整数并且作为一般字体值的字符表达。
language-selector.conf
<fontconfig>
<include ignore_missing="yes">CJK_aliases</include>
<alias>
Alias (别名)单元为需要替代一个字体家族名称到另一个的一套通用匹配操作提供简化符号。它们包含一个family单元,紧跟着是可选的prefer, accept和default单元。匹配family单元的字体将被编辑,使得prefer家族在匹配family的前面,accept家族在匹配的 family后面并且default家族在家族列表的最后。
Family:保存一个单独的字体家族名称
prefer, accpet, default:这些单元保存一个让alias单元使用的字体列表。
<alias> 
<family>serif</family>
<prefer>
<family>Bitstream Vera Serif</family>
<family>DejaVu Serif</family>

<family>Microsoft Yahei</family>
<family>AR PL ShanHeiSun Uni</family>
<family>WenQuanYi Bitmap Song</family>
<family>AR PL UKai CN</family>
<family>AR PL ZenKai Uni</family>
</prefer>
</alias>


<alias>
<family>sans-serif</family>
<prefer>
<family>Bitstream Vera Sans</family>
<family>DejaVu Sans</family>

<family>Microsoft Yahei</family>
<family>AR PL ShanHeiSun Uni</family>
<family>WenQuanYi Bitmap Song</family>
<family>AR PL UKai CN</family>
<family>AR PL ZenKai Uni</family>
</prefer>
</alias>


<alias>
<family>monospace</family>
<prefer>
<family>Bitstream Vera Sans Mono</family>
<family>DejaVu Sans Mono</family>

<family>Microsoft Yahei</family>
<family>AR PL ShanHeiSun Uni</family>
<family>WenQuanYi Bitmap Song</family>
<family>AR PL UKai CN</family>
<family>AR PL ZenKai Uni</family>
</prefer>
</alias>

上面这一段用到了<prefer></prefer>参数,所以xft系统会按照上面排列的先后顺序优先使用字体,所以,把你希望使用的字体排在前面。

Family matching 是另一种 match 方法,它的用法和 pattern matching 差不多,只是它是针对个别字型的属性作修改,用法是:
<match target="font">
...
</match>

通常用来对字体进行微调,对不同大小的字体采用或者禁用发锯齿功能,决定字体渲染的方式等等,根据你自己的系统,显示器类型,或者分辨率高低进行调试,下面仅供参考。
<match target="font" >
<test name="family" compare="contains" >
<string>Song</string>
<string>Sun</string>
<string>Kai</string>
<string>Yahei</string>
</test>
<!-- 上面这一段表示对字体名中含有song,sun,kai,yahei的字体进行下面的操作 -->
<!-- check to see if the font is just regular -->
<test name="weight" compare="less_eq">
<int>100</int>
</test>
<test compare="more_eq" target="pattern" name="weight" >
<int>180</int>
</test>
<edit mode="assign" name="embolden" >
<bool>true</bool>
</edit>
</match>

<match target="font" >
<test name="family" compare="contains" >
<string>Song</string>
<string>Sun</string>
<string>Yahei</string>
</test>
<edit name="globaladvance">
<bool>false</bool>
</edit>
<edit name="spacing">
<int>0</int>
</edit>
<edit name="hinting">
<bool>true</bool>
</edit>
<edit name="autohint">
<bool>false</bool>
</edit>
<edit name="antialias" mode="assign">
<bool>true</bool>
</edit>
<!-- 下面这段表示对字号大于11和小于16的关闭反锯齿功能 -->
<test compare="more_eq" name="pixelsize">
<double>11</double>
</test>
<test compare="less_eq" name="pixelsize">
<double>16</double>
</test>
<edit name="antialias" mode="assign" >
<bool>false</bool>
</edit>
</match>

</fontconfig>

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 可以让我们调整这些细部的设定,让我们针对个别的字型做不同的处理。
.fonts.conf
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<match target="font" >
 <edit mode="assign" name="rgba" >
  <const>none</const>
 </edit>
</match>
<match target="font" >
 <edit mode="assign" name="hinting" >
  <bool>true</bool>
 </edit>
</match>
<match target="font" >
 <edit mode="assign" name="hintstyle" >
  <const>hintfull</const>
 </edit>
</match>
<match target="font" >
 <edit mode="assign" name="antialias" >
  <bool>true</bool>
 </edit>
</match>
</fontconfig>

注意,要先把hinting设为true,hintstyle的设置才有效。hintstyle有四种:none,hintslight,hintmedium,hintfull.对于LCD,可以使用hintfull.




评论 / 个人网页 / 扔小纸条
* 昵称

已经注册过? 请登录

新用户请先注册 以便能显示头像及追踪评论回复

Email
网址
* 评论
表情
 


 

分类小组论坛
杂谈 , 娱乐、八卦 , 文学、艺术 , 体育 , 旅游、同城 , 象牙塔 , 情感 , 时尚、生活 , 星座 , 科技

请注意遵守中华人民共和国法律法规, 如威胁到本站生存, 将依法向有关部门报告, 同时本站的相关记录可能成为对您不利的证据.

相关法律法规
全国人大常委会关于维护互联网安全的决定
中华人民共和国计算机信息系统安全保护条例
中华人民共和国计算机信息网络国际联网管理暂行规定
计算机信息网络国际联网安全保护管理办法
计算机信息系统国际联网保密管理规定