标签:
在/system/etc/system_fonts.xml文件中有如下描述
也就是说,在没有指定具体的字体名字的情况下, 系统默认使用的字体家族是第一标签<family>中显示的字体家族。
一个xml文件中有多个字体家族,而多个字体家族会形成一个链表,如果整个链表中都没有某个字体,那么就在system/ect/fallback_fonts.xml配置文件中去找其他字体的描述。
如果我们想要额外增加或修改字体,则需要在vendor/etc/fallback_fonts.xml文件中进行配置。
<nameset>代表该font family的名字,一般第一个<name>标签代表字体家族的名字。<fileset>表示该font family所对应的*.ttf文件.每个字体家族都可以有normal,
粗体,斜体字,粗斜体等四种样式。但并不都是必须要有的。从上图中可以看出,三星(SM-N7508V)这个手机,(结论)优先使用的字体库为"Roboto-Regular.ttf"、"bold.ttf"、
"italic.ttf"、"Roboto- BoldItalic.ttf"。分别代表正常,粗体,斜体字,粗斜体等四种样式。三星手机字体库文件请见附件。
在 system/ect/fallback_fonts.xml文件中有如下描述:
这个文件中再次说明了,如果这个字体家族中没有某个字体,那么可以在system/ect/fallback_fonts.xml配置文件中找到其他字体的描述。
思考:那么这些XML文件是如何解析,字体库又是如何被初始化的。(请见第三部分<其他相关知识扩充>)。
a、 Typeface createFromAsset(AssetManager mgr, String path);
b、Typeface createFromFile(File path);
c、Typeface createFromFile(String path);
以及如下3个API来创建系统字体:
a、Typeface create(String familyName, int style);
b、Typeface create(Typeface family, int style);
c、Typeface defaultFromStyle(int style);
3、如何证明android默认包括这三类字体呢?system/ect/fallback_fonts.xml和/system/etc/system_fonts.xml文件是如何被解析的,字体库又是如何被初始化的?
往framework层去看,在如下路径下frameworks/base/core/java/com/android/internal/os/ZygoteInit.java。这个ZygoteInit类中的preloadClasses方法是加载字体库的入口
具体过程如下:
Zygote preloadClasses() -> Class.forName("android.graphics.Typeface")–> 执行Typeface.javastatic块 -> Typeface.cpp Typeface_create–> SkTypeface.cpp CreateFromName() -> SkFontHost.cpp load_system_fonts()
我们先看android.graphics.Typeface这个类
static {
DEFAULT = create((String)null,0);
DEFAULT_BOLD = create((String)null, Typeface.BOLD);
SANS_SERIF = create("sans-serif", 0);
SERIF =create("serif", 0);
MONOSPACE = create("monospace", 0);//从这里可以看出JAVA层面默认创建三类字体
sDefaults = newTypeface[] {
DEFAULT,
DEFAULT_BOLD,
create((String)null, Typeface.ITALIC),
create((String)null, Typeface.BOLD_ITALIC),
};
public static Typeface create(String familyName, int style) {
return newTypeface(nativeCreate(familyName, style));
}
nativeCreate()是jni方法,调用C++层的Typeface.cpp方法,在这个方法中,有一种数据结构(如下),它对应着/system/etc/system_fonts.xml文件中的每个family标签
struct FontFamily {
SkTDArray<constchar*> fNames;//保存<name>标签对应的名字
SkTDArray<const char*> fFileNames;//保存了<file>标签对应的文件名
int order;//每个字体家族的加载顺序
};
还有其他的一些的数据结构,就不在这列举啦!
最终会调用到C++层的SkFontHost.cpp中的load_system_fonts()方法完成字体加载。
4、(注意)字库大部分都是有版权的,所以你看到Android手机中很少有字体选择功能,即使有的话,那么一般都是链接到自己定义的字体库上。
标签:
原文地址:http://blog.csdn.net/yclfdn2004/article/details/51942225