源码
7.1
问题:
1.系统编译过程对应的/system/fonts资源来自?
注:
回答此问题,涉及很多编译方面的知识
例如,我们以Wifi only版为主:
build/target/product/generic_no_telephony.mk
$(call inherit-product-if-exists, frameworks/base/data/fonts/fonts.mk)
$(call inherit-product-if-exists, external/google-fonts/dancing-script/fonts.mk)
$(call inherit-product-if-exists, external/google-fonts/carrois-gothic-sc/fonts.mk)
$(call inherit-product-if-exists, external/google-fonts/coming-soon/fonts.mk)
$(call inherit-product-if-exists, external/google-fonts/cutive-mono/fonts.mk)
$(call inherit-product-if-exists, external/noto-fonts/fonts.mk)
$(call inherit-product-if-exists, external/naver-fonts/fonts.mk)
$(call inherit-product-if-exists, external/roboto-fonts/fonts.mk)
也就是说,我们的字体来源都是靠fonts.mk的集合。
如果裁剪涉及方案:
1.不进行编译。即从编译源头注销
2.裁剪fonts.mk中的部分模块
温馨提醒:
fonts.mk使用的是Android.mk的方式,也就是说,对于的字体仍需要耦合其他模块,所以需要重新生成一次。不然的话,可以直接使用PRODUCT_COPY_FILES
2.app在启动的时候,怎么进行字体的加载?
注:
回答此问题,涉及进程启动流程
1)进程启动,涉及资源文件加载
com.android.internal.os.ZygoteInit
main --> preload() --> preloadClasses()
private static final String PRELOADED_CLASSES = "/system/etc/preloaded-classes";
private static void preloadClasses() {
final VMRuntime runtime = VMRuntime.getRuntime();
InputStream is;
try {
is = new FileInputStream(PRELOADED_CLASSES);
} catch (FileNotFoundException e) {
Log.e(TAG, "Couldn't find " + PRELOADED_CLASSES + ".");
return;
}
······
try {
BufferedReader br
= new BufferedReader(new InputStreamReader(is), 256);
String line;
while ((line = br.readLine()) != null) {
·······
try {
·······
Class.forName(line, true, null);//初始化各种类,关键:Typeface
······
} catch (ClassNotFoundException e) {
}
·······
}
} catch (IOException e) {
Log.e(TAG, "Error reading " + PRELOADED_CLASSES + ".", e);
} finally {
······
}
}
因为初始化类时,也会把类中的static结构初始化。
android.graphics.Typeface
static {
init();
// Set up defaults and typefaces exposed in public API
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);
sDefaults = new Typeface[] {
DEFAULT,
DEFAULT_BOLD,
create((String) null, Typeface.ITALIC),
create((String) null, Typeface.BOLD_ITALIC),
};
}
private static File getSystemFontConfigLocation() {
return new File("/system/etc/");
}
static final String FONTS_CONFIG = "fonts.xml";
private static void init() {
// Load font config and initialize Minikin state
File systemFontConfigLocation = getSystemFontConfigLocation();
File configFilename = new File(systemFontConfigLocation, FONTS_CONFIG);
try {
FileInputStream fontsIn = new FileInputStream(configFilename);
FontListParser.Config fontConfig = FontListParser.parse(fontsIn);
Map<String, ByteBuffer> bufferForPath = new HashMap<String, ByteBuffer>();
List<FontFamily> familyList = new ArrayList<FontFamily>();
// Note that the default typeface is always present in the fallback list;
// this is an enhancement from pre-Minikin behavior.
for (int i = 0; i < fontConfig.families.size(); i++) {
FontListParser.Family f = fontConfig.families.get(i);
if (i == 0 || f.name == null) {
familyList.add(makeFamilyFromParsed(f, bufferForPath));
}
}
sFallbackFonts = familyList.toArray(new FontFamily[familyList.size()]);
setDefault(Typeface.createFromFamilies(sFallbackFonts));
Map<String, Typeface> systemFonts = new HashMap<String, Typeface>();
for (int i = 0; i < fontConfig.families.size(); i++) {
Typeface typeface;
FontListParser.Family f = fontConfig.families.get(i);
if (f.name != null) {
if (i == 0) {
// The first entry is the default typeface; no sense in
// duplicating the corresponding FontFamily.
typeface = sDefaultTypeface;
} else {
FontFamily fontFamily = makeFamilyFromParsed(f, bufferForPath);
FontFamily[] families = { fontFamily };
typeface = Typeface.createFromFamiliesWithDefault(families);
}
systemFonts.put(f.name, typeface);
}
}
for (FontListParser.Alias alias : fontConfig.aliases) {
Typeface base = systemFonts.get(alias.toName);
Typeface newFace = base;
int weight = alias.weight;
if (weight != 400) {
newFace = new Typeface(nativeCreateWeightAlias(base.native_instance, weight));
}
systemFonts.put(alias.name, newFace);
}
sSystemFontMap = systemFonts;//sSystemFontMap数据来源于/system/etc/fonts.xml
} catch (RuntimeException e) {
Log.w(TAG, "Didn't create default family (most likely, non-Minikin build)", e);
// TODO: normal in non-Minikin case, remove or make error when Minikin-only
} catch (FileNotFoundException e) {
Log.e(TAG, "Error opening " + configFilename, e);
} catch (IOException e) {
Log.e(TAG, "Error reading " + configFilename, e);
} catch (XmlPullParserException e) {
Log.e(TAG, "XML parse exception for " + configFilename, e);
}
}
总结:
尽管/system/fonts中有很多字体,但是如果/system/etc/fonts.xml中没有引用。
如果其他app也没有调用,那文件就是僵尸文件,完全可裁剪。
3.解读fonts.xml
1)fonts.xml来源于
frameworks\base\data\fonts\fonts.xml
2)
<family lang="zh-Hans">
<font weight="400" style="normal" index="2">NotoSansCJK-Regular.ttc</font>
</family>
lang对应的是支持的国家
特别注意:'und' for 'undetermined'.
frameworks/base/tools/fonts/fontchain_lint.py 涉及uud-**的转化
3) 支持的列表,可查:
external/skia/src/sfnt/SKOTTable_name.cpp 有对应的国家列表
frameworks/base/core/res/res/values/locale_config.xml 有对应的国家列表












网友评论