1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
/*
* Copyright (C) 2014 Cyanogen, Inc.
*/
package com.cyngn.theme.util;
import android.content.Context;
import android.content.pm.ThemeUtils;
import android.content.res.AssetManager;
import android.graphics.FontListParser;
import android.graphics.FontListParser.Family;
import android.graphics.Typeface;
import android.util.Log;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.List;
/**
* Assists in loading a themes font typefaces.
* Will load system default if there is a load issue
*/
public class ThemedTypefaceHelper {
private static final String TAG = ThemedTypefaceHelper.class.getName();
private static final String FAMILY_SANS_SERIF = "sans-serif";
private static final String FONTS_DIR = "fonts";
private static final String SYSTEM_FONTS_XML = "/system/etc/system_fonts.xml";
private static final String SYSTEM_FONTS_DIR = "/system/fonts";
private boolean mIsLoaded;
private Context mThemeContext;
private List<FontListParser.Family> mFamilies;
private Typeface[] mTypefaces = new Typeface[4];
public void load(Context context, String pkgName) {
try {
loadThemedFonts(context, pkgName);
return;
} catch(Exception e) {
Log.w(TAG, "Unable to parse and load themed fonts for " + pkgName +
". Falling back to system fonts", e );
}
try {
loadSystemFonts();
return;
} catch(Exception e) {
Log.e(TAG, "Parsing system fonts failed. Falling back to Typeface loaded fonts", e);
}
// There is no reason for this to happen unless someone
// messed up the system_fonts.xml
loadDefaultFonts();
}
private void loadThemedFonts(Context context, String pkgName) throws Exception {
//Parse the font XML
mThemeContext = context.createPackageContext(pkgName, Context.CONTEXT_IGNORE_SECURITY);
AssetManager assetManager = mThemeContext.getAssets();
InputStream is = assetManager.open(FONTS_DIR + File.separator + ThemeUtils.FONT_XML);
FontListParser.Config fontConfig = FontListParser.parse(is, FONTS_DIR);
mFamilies = fontConfig.families;
//Load the typefaces for sans-serif
Family sanSerif = getFamily(FAMILY_SANS_SERIF);
mTypefaces[Typeface.NORMAL] = loadTypeface(sanSerif, Typeface.NORMAL);
mTypefaces[Typeface.BOLD] = loadTypeface(sanSerif, Typeface.BOLD);
mTypefaces[Typeface.ITALIC] = loadTypeface(sanSerif, Typeface.ITALIC);
mTypefaces[Typeface.BOLD_ITALIC] = loadTypeface(sanSerif, Typeface.BOLD_ITALIC);
mIsLoaded = true;
}
private void loadSystemFonts() throws Exception {
//Parse the system font XML
File file = new File(SYSTEM_FONTS_XML);
InputStream is = new FileInputStream(file);
FontListParser.Config fontConfig = FontListParser.parse(is, SYSTEM_FONTS_DIR);
mFamilies = fontConfig.families;
//Load the typefaces for sans-serif
Family sanSerif = getFamily(FAMILY_SANS_SERIF);
if (mTypefaces[Typeface.NORMAL] == null) {
mTypefaces[Typeface.NORMAL] = loadSystemTypeface(sanSerif, Typeface.NORMAL);
}
if (mTypefaces[Typeface.BOLD] == null) {
mTypefaces[Typeface.BOLD] = loadSystemTypeface(sanSerif, Typeface.BOLD);
}
if (mTypefaces[Typeface.ITALIC] == null) {
mTypefaces[Typeface.ITALIC] = loadSystemTypeface(sanSerif, Typeface.ITALIC);
}
if (mTypefaces[Typeface.BOLD_ITALIC] == null) {
mTypefaces[Typeface.BOLD_ITALIC] = loadSystemTypeface(sanSerif, Typeface.BOLD_ITALIC);
}
mIsLoaded = true;
}
private void loadDefaultFonts() {
mTypefaces[Typeface.NORMAL] = Typeface.DEFAULT;
mTypefaces[Typeface.BOLD] = Typeface.DEFAULT_BOLD;
mIsLoaded = true;
}
private Family getFamily(String familyName) throws Exception {
for(Family family : mFamilies) {
if (family.name.equals(familyName)) {
return family;
}
}
throw new Exception("Unable to find " + familyName);
}
private Typeface loadTypeface(Family family, int style) {
AssetManager assets = mThemeContext.getAssets();
String path = family.fonts.get(style).fontName;
return Typeface.createFromAsset(assets, path);
}
private Typeface loadSystemTypeface(Family family, int style) {
return Typeface.createFromFile(family.fonts.get(style).fontName);
}
public Typeface getTypeface(int style) {
if (!mIsLoaded) throw new IllegalStateException("Helper was not loaded");
return mTypefaces[style];
}
}
|