一。背景
尽量写简单一点这次就不废话了。



二。分析



2.1.

文件系统中字体的位置:

/system/fonts/ 其中的ttf文件都是字库对于源码/frameworks/data/fonts/下的字体文件
DroidSans-Bold.ttf 粗体的无衬线字体(拉丁字母等)
DroidSans.ttf 常规的无衬线字体(拉丁字母等)
DroidSansFallback.ttf 常规的无衬线字体(中文字符等,一般换字库就是替换此文件)
DroidSansMono.ttf 等宽的无衬线字体(拉丁字母等)
DroidSerif-Bold.ttf 粗体的衬线字体(拉丁字母等)
DroidSerif-BoldItalic.ttf 粗体+斜体的衬线字体(拉丁字母等)
DroidSerif-Italic.ttf 斜体的衬线字体(拉丁字母等)
DroidSerif-Regular.ttf 常规的衬线字体(拉丁字母等)
Clockopia.ttf (显示数字时钟时用的字体,非必须)

在frameworks/fonts/下有三个xml文件,分别是fallback_fonts.xml、system_fonts.xml、vendor_fonts.xml,最终被编进系统的是前面两个。

 

改变字体有不外乎两种方法,一是强制替换掉系统的默认字体,也就是把你想要替换的字体重命名成DroidSansFallback.ttf,替换掉/system/fonts/下原来的那个,另外一种方法就是通过定义vendor fonts xml的方法来设置,对于我们来说,第一种方法太过于暴力,且没有选择的余地。所以第二种方法更为可行

暴力替换法就不说了,现在说说厂商字体法:


2.2.vendor fonts方法:

假设你要添加一个XXXXX.ttf格式的字体文件:

按照android用例vendor_fonts.xml文件中注释介绍的方法,在/vendor/etc/目录下创建一个fallback_fonts.xml,例如

<familyset>
    <family order="9">
        <fileset>
XXXXX.ttf</file>
        </fileset>
    </family>
</familyset>

其中family order就表示描述的插入的vendor字体的需要代替的位置,即/system/etc/fallback_fonts.xml中描述的第10个family(从0开始),也就是DroidSansFallback.ttf,使用这种方法前也需要将“XXXXX.ttf”拷贝到/system/fonts下



三。总结:

这次也不废话了,不过要提醒一下,字库大部分都是有版权的,所以用别人的字库前都要小心,这也是为什么Android不再Settings中添加字体的选择栏的原因,如果你用了别人的字库没有交保护费的话而产品又买了不少钱的话,呵呵,律师函估计已经在抵达的途中。


------------------------------------



修改安卓字体续篇:针对4.0(ICS)修改字体

http://www.douban.com/note/222712555/

此文是针对我去年日志《网上的方法都过时了!一个字体搞定安卓英日韩显示,你懂的!》的追加。原文讲的是2.x时代的字体文件用途,到了4.x(最新的4.1尚未测试,估计变化不大),中英文字体都有较大变动,需要写一篇新的日志说明下。
4.x以后最显著的变化是新增了Roboto家族,有Regular/Bold/Italic/BoldItalic四种变体,相比原来的DroidSans多了两个斜体。原来的DroidSans家族还在,但是已经被指向到Roboto家族,再修改原来的文件是无效的。
由于中文字体至今未出现独立斜体和独立粗斜体,因此我在这里建议大家中英文分开替换,这样可以保证英文有斜体和粗斜体,同时中英文有更多种独立搭配。
为了替换英文字体,我们需要准备四个字体(蛮多字体都有独立斜体的,很容易找)分别替换以下四个文件:

Roboto-Regular.ttf
 Roboto-Italic.ttf
 Roboto-Bold.ttf
 Roboto-BoldItalic.ttf


更换的前期准备和操作要领见文首引用的那篇日志。
针对中文,4.x还是一个DroidSansFallback.ttf完成。有的固件可能是DroidSansFallbackFull.ttf一类名称,总之体积最大的那个是我们需要替换的。个人是对字体要求比较高的,也喜欢针对中日韩文字使用独立粗体,因此我针对独立粗体又进行了探索,收获见下。
用RootExplorer进入/System/etc目录下可以找到fallback_fonts.xml这个文件。这是4.x后对新增语种文字的配置文件,可以用记事本打开进行修改。熟悉Linux的朋友会对这种文件结构了如指掌,之中定义好了字体家族和不同的变体。我们可以发现,这里中日韩还是一行如下的编码:

<family>
 <fileset>
 <file>DroidSansFallback.ttf</file>
 </fileset>
 </family>
 这就是说,系统没有给我们准备好粗体。不必气馁,我们发现文件开头有定义粗体的语句:
 <family>
 <fileset>
 <file>DroidSansHebrew-Regular.ttf</file>
 <file>DroidSansHebrew-Bold.ttf</file>
 </fileset>
 </family>


这是希伯来文,谷歌为它打造了独立粗体。我们仿照上面的语句,在<file>DroidSansFallback.ttf</file>后面另起一行加入:

<file>DroidSansFallback-Bold.ttf</file>


保存。把这个文件用RootExplorer覆盖掉原来目录中同名文件,设置好权限。
然后把我们需要的中文的常规体和粗体分别命名为DroidSansFallback.ttf和DroidSansFallback-Bold.ttf,覆盖掉原来的字体,并将覆盖后的字体和新加入到的DroidSansFallback-Bold.ttf的权限都如同我上一篇教程那样修改。
这样一番工作完成后可以重启查看效果了,这样保证了英文替换的同时中文新增了粗体,对于字体控们来说赏心悦目。
当然,上面的fallback_fonts.xml理论上可以无限增加字体家族。譬如我刚刚替换的字体只有中日文(蛮多字体没有韩文),我在后面定义新的家族如DroidSansKorean.ttf和DroidSansKorean-Bold.ttf(随便自己取名)然后新增字体理论上也是可以继续fallback的,fallback的顺序就是fallback_fonts.xml中上下顺序决定。
囿于本人的手机可用空间太小就没有尝试验证上面的假说,有兴趣的网友可以自己试试。
效果和上一篇教程基本一致,就没有插图了,希望谅解。

实际操作:

修改字模相关文件后,都需要重启机器,或者重启android,即在adb shell中输入stop;start。

1.根据网上资料,字模可以添加到DroidSansFallback.ttf中,理论上就在flash,air(基于air开发的apk)、网页等地方显示出来了。

实际上,非自造字都显示不出来了。后来在/system/etc/fallback_fonts.xml中看到如下注释:

<!-- Note: complex scripts (i.e. those requiring shaping in Harfbuzz) have
         a cumulative limit of 64k glyphs. Thus, if they are placed after the
         large fonts such as DroidSansFallback, they are likely to render
         incorrectly. Please use caution when putting fonts toward the end of
         the list.
    -->

大概意思是说字模文件中的字模总数不能超过64K,并且在大字模文件(比如DroidSansFallback.ttf)后面的字模文件可能显示不正常。

我们尝试过把自造字模添加到DroidSansFallback.ttf,这导致文件增加到8M多,原来只有4M多,结果很多文字显示不出来。

这与直接删除DroidSansFallback.ttf时的效果是一样的。

 

2.基于上面的原因,改用小字模文件,只包含自造字模,测验用的自造字模文件约1M。

增加文件/vendor/etc/fallback_fonts.xml,格式参考/system/etc/fallback_fonts.xml,具体内容如下:

<?xml version="1.0" encoding="utf-8"?>

<familyset>
    <family order="14">
        <fileset>
            <file>diy.ttf</file>
        </fileset>
    </family>
</familyset>

把字体文件diy.ttf push到/system/fonts/下面,order="14"是参考/system/etc/fallback_fonts.xml,保证顺序在DroidSansFallback.ttf前面。
但测试结果还是不行,网页,flash,air中的自造字模都显示不了,不知道哪里搞错了,或者是系统不支持。

3.上面的方法不行,打算直接修改/system/etc/fallback_fonts.xml,在DroidSansFallback.ttf前面增加:

<family>
        <fileset>
            <file>diy.ttf</file>
        </fileset>
    </family>
    <family>
        <fileset>
            <file>DroidSansFallback.ttf</file>
        </fileset>
    </family>

同样需要把diy.ttf push到/system/fonts/下面。此时,网页、flash中的自造字可以正常显示了,但air中自造字显示不了。

4.把自造字模添加到Roboto-Regular.ttf:

把自造字模添加到/system/fonts/Roboto-Regular.ttf中,重启机器,air、flash中的自造字看正常显示了。但是网页中的自造字显示不了。

 

5.根据实验结果,需要同时使用两种方法:

  a.添加字模文件/system/fonts/diy.ttf,并相应修改/system/etc/fallback_fonts.xml;

  b.把自造字模添加到/system/fonts/Roboto-Regular.ttf中。

这样网页、flash、air中都显示正常的了。

 

其他知识:

系统字模必须放在/system/fonts/下面,需要使用的字模要配置到/system/etc/system_fonts.xml和/system/etc/fallback_fonts.xml中。

系统优先从system_fonts.xml中列出的字模中查找字模,其次才是fallback_fonts.xml。

如果要求粗斜体也要显示自造字,下面文件中都要添加字模。

Roboto-Italic.ttf
 Roboto-Light.ttf
 Roboto-LightItalic.ttf
 Roboto-Regular.ttf
 Roboto-Thin.ttf
 Roboto-ThinItalic.ttf

这次是在android4.2的机器上操作的,系统字模列表如下:

AndroidClock.ttf
AndroidClock_Highlight.ttf
AndroidClock_Solid.ttf
AndroidEmoji.ttf
AnjaliNewLipi-light.ttf
Clockopia.ttf
DroidNaskh-Regular.ttf
DroidNaskh-Regular-SystemUI.ttf
DroidSansArmenian.ttf
DroidSansDevanagari-Regular.ttf
DroidSansEthiopic-Regular.ttf
DroidSansFallback.ttf
DroidSansGeorgian.ttf
DroidSansHebrew-Bold.ttf
DroidSansHebrew-Regular.ttf
DroidSansMono.ttf
DroidSansTamil-Bold.ttf
DroidSansTamil-Regular.ttf
DroidSansThai.ttf
DroidSerif-Bold.ttf
DroidSerif-BoldItalic.ttf
DroidSerif-Italic.ttf
DroidSerif-Regular.ttf
Lohit-Bengali.ttf
Lohit-Kannada.ttf
Lohit-Telugu.ttf
MTLmr3m.ttf
NanumGothic.ttf
Roboto-Bold.ttf
Roboto-BoldItalic.ttf
RobotoCondensed-Bold.ttf
RobotoCondensed-BoldItalic.ttf
RobotoCondensed-Italic.ttf
RobotoCondensed-Regular.ttf
Roboto-Italic.ttf
Roboto-Light.ttf
Roboto-LightItalic.ttf
Roboto-Regular.ttf
Roboto-Thin.ttf
Roboto-ThinItalic.ttf