手头项目遇到个ass库,在这个库的中用到了fontconfig库,由于字符编码问题,导致找不到字体文件,所以不得不修改下fontconfig库,看了看源码,头大眼皮沉。。。写个记录屡屡思路
首先libass调用fontconfig库集成了几个函数
fontconfig_init();初始化fontfontconfg库
fontconfig_select();选择一个字体,输入族名编码等参数,返回一个可用的字体的字体文件路径。
fontconfig_done();销毁库对象
fontconfig_update();更新kudu库对象
libass库的rander.c文件中的调用顺序是init - select - update -select -update -……done;
并且定义了一个FCInstance的结构体作为上下文,其中有个FcConfig*的指针存放fontconfig库返回的上下文,FcConfig结构体内存放了一系列的set结构,其中包括config配置文件的路径,字体文件夹的路径,具体字体文件的路径,字体替换的patterns等信息。fontconfig的运行主要依靠该结构体。
首先是初始化
调用 FcConfigCreate();
函数返回一个FcConfig结构体指针,并对结构体内各个set结构初始化,置零。
调用FcConfigParseAndLoad();
参数为FcConfig结构体指针 和 字体配置文件的路径,最后是是否覆盖。
说道这里就得说下字体配置文件一般命名为fonts.conf ,该文件可以根据自己需求编辑,也可以直接找一个套用(文档后会附一份我常用的字体配置文件)。所谓fonts.con文件其实就是一个xml,格式如下
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<!-- /etc/fonts/fonts.conf file to configure system font access -->
<fontconfig>
<!--
DO NOT EDIT THIS FILE.
IT WILL BE REPLACED WHEN FONTCONFIG IS UPDATED.
LOCAL CHANGES BELONG IN 'local.conf'.
The intent of this standard configuration file is to be adequate for
most environments. If you have a reasonably normal environment and
have found problems with this configuration, they are probably
things that others will also want fixed. Please submit any
problems to the fontconfig bugzilla system located at fontconfig.org
Note that the normal 'make install' procedure for fontconfig is to
replace any existing fonts.conf file with the new version. Place
any local customizations in local.conf which this file references.
Keith Packard
-->
<!-- Font directory list -->
<!--
Uncomment this directory if we need libass and fontconfig to access all system fonts.
The drawback is the long initial indexing time by fontconfig, and mkv files usually
include their fonts.
<dir>WINDOWSFONTDIR</dir>
-->
<dir>c:/windows/fonts</dir>
<dir>media/Fonts</dir> <!-- used by an installed XBMC -->
<dir>../../media/Fonts</dir> <!-- used when running in Visual Studio -->
<dir>~/.fonts</dir>
<!-- Font cache directory list -->
<cachedir>WINDOWSTEMPDIR_FONTCONFIG_CACHE</cachedir>
<cachedir>~/.fontconfig</cachedir>
<!--
Accept deprecated 'mono' alias, replacing it with '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'
-->
<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'
-->
<match target="pattern">
<test qual="any" name="family">
<string>sans</string>
</test>
<edit name="family" mode="assign">
<string>sans-serif</string>
</edit>
</match>
<!--
Accept deprecated 'sans' alias, replacing it with 'sans-serif'
-->
<match target="pattern">
<test qual="any" name="family">
<string>Arial</string>
</test>
<edit name="family" mode="assign">
<string>宋体</string>
</edit>
</match>
<!--
Accept deprecated 'sans' alias, replacing it with '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>
<!-- 将一些著名的 Type1 字体替换为对应的 TrueType 版本,以改善屏幕显示效果 -->
<alias>
<family>Times</family>
<prefer><family>Times New Roman</family></prefer>
<default><family>serif</family></default>
</alias>
<alias>
<family>Helvetica</family>
<prefer><family>Arial</family></prefer>
<default><family>sans</family></default>
</alias>
<alias>
<family>Courier</family>
<prefer><family>Courier New</family></prefer>
<default><family>monospace</family></default>
</alias>
<!-- 为标准的字族名称提供所需的别名,把这个配置段放在用户自己定制配置文件之后,以确保能够覆盖用户的设置 -->
<alias>
<family>serif</family>
<prefer><family>Times New Roman</family></prefer>
</alias>
<alias>
<family>sans</family>
<prefer><family>Arial</family></prefer>
</alias>
<alias>
<family>monospace</family>
<prefer><family>Andale Mono</family></prefer>
</alias>
<!--
Load local system customization file
-->
<include ignore_missing="yes">conf.d</include>
<config>
<!--
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
-->
<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 configuration every 30 seconds when FcFontSetList is called
-->
<rescan>
<int>30</int>
</rescan>
</config>
</fontconfig>
其中最重要的是<dir>WINDOWSFONTDIR</dir>属性,fontconfig会递归的查找该文件夹下的所有字体文件。
再有就是<match target="pattern"> 是一个选择模板 如:
<match target="pattern">
<test qual="any" name="family">
<string>mono</string>
</test>
<edit name="family" mode="assign">
<string>monospace</string>
</edit>
</match>
意思就是 尝试(test)是否符合 family 的值中包含 mono 如果有,则编辑(edit ) family值为 monospace 。qual="any"的意思是只要有相同的就进入edit ,mode="assign"的意思是替换,由于family的属性值为一个列表,所以assgin是替换di的意第一个匹配值,还有assign_all就是替换shux属性值list中所有符合规则的值。
其实就是一个条件替换的功能,将模板中的信息按照写出的规则替换。<match target="font">时,就是对字体参数进行操作了。比如字体的粗细,大小等。语法相近。
其他的参数用到时在详细了解。
初始化获取配置文件结束。