Loading core/tests/coretests/src/android/graphics/TypefaceSystemFallbackTest.java +51 −14 Original line number Diff line number Diff line Loading @@ -67,6 +67,7 @@ public class TypefaceSystemFallbackTest { private static final String TEST_FONT_DIR; private static final String TEST_OEM_XML; private static final String TEST_OEM_DIR; private static final String TEST_UPDATABLE_FONT_DIR; private static final float GLYPH_1EM_WIDTH; private static final float GLYPH_2EM_WIDTH; Loading @@ -82,9 +83,11 @@ public class TypefaceSystemFallbackTest { TEST_FONTS_XML = new File(cacheDir, "fonts.xml").getAbsolutePath(); TEST_OEM_DIR = cacheDir.getAbsolutePath() + "/oem_fonts/"; TEST_OEM_XML = new File(cacheDir, "fonts_customization.xml").getAbsolutePath(); TEST_UPDATABLE_FONT_DIR = cacheDir.getAbsolutePath() + "/updatable_fonts/"; new File(TEST_FONT_DIR).mkdirs(); new File(TEST_OEM_DIR).mkdirs(); new File(TEST_UPDATABLE_FONT_DIR).mkdirs(); final AssetManager am = InstrumentationRegistry.getInstrumentation().getContext().getAssets(); Loading @@ -103,18 +106,11 @@ public class TypefaceSystemFallbackTest { InstrumentationRegistry.getInstrumentation().getContext().getAssets(); for (final String fontFile : TEST_FONT_FILES) { final String sourceInAsset = "fonts/" + fontFile; final File outInCache = new File(TEST_FONT_DIR, fontFile); try (InputStream is = am.open(sourceInAsset)) { Files.copy(is, outInCache.toPath(), StandardCopyOption.REPLACE_EXISTING); } catch (IOException e) { throw new RuntimeException(e); } final File outOemInCache = new File(TEST_OEM_DIR, fontFile); try (InputStream is = am.open(sourceInAsset)) { Files.copy(is, outOemInCache.toPath(), StandardCopyOption.REPLACE_EXISTING); } catch (IOException e) { throw new RuntimeException(e); copyAssetToFile(sourceInAsset, new File(TEST_FONT_DIR, fontFile)); copyAssetToFile(sourceInAsset, new File(TEST_OEM_DIR, fontFile)); } for (final File fontFile : new File(TEST_UPDATABLE_FONT_DIR).listFiles()) { fontFile.delete(); } } Loading @@ -124,7 +120,20 @@ public class TypefaceSystemFallbackTest { final File outInCache = new File(TEST_FONT_DIR, fontFile); outInCache.delete(); final File outOemInCache = new File(TEST_OEM_DIR, fontFile); outInCache.delete(); outOemInCache.delete(); } for (final File fontFile : new File(TEST_UPDATABLE_FONT_DIR).listFiles()) { fontFile.delete(); } } private static void copyAssetToFile(String sourceInAsset, File out) { final AssetManager am = InstrumentationRegistry.getInstrumentation().getContext().getAssets(); try (InputStream is = am.open(sourceInAsset)) { Files.copy(is, out.toPath(), StandardCopyOption.REPLACE_EXISTING); } catch (IOException e) { throw new RuntimeException(e); } } Loading @@ -138,7 +147,7 @@ public class TypefaceSystemFallbackTest { } final FontConfig.Alias[] aliases = SystemFonts.buildSystemFallback(TEST_FONTS_XML, TEST_FONT_DIR, oemCustomization, fallbackMap); TEST_FONT_DIR, TEST_UPDATABLE_FONT_DIR, oemCustomization, fallbackMap); Typeface.initSystemDefaultTypefaces(fontMap, fallbackMap, aliases); } Loading Loading @@ -835,4 +844,32 @@ public class TypefaceSystemFallbackTest { + "</fonts-modification>"; readFontCustomization(oemXml); } @Test public void testBuildSystemFallback_UpdatableFont() { final String xml = "<?xml version='1.0' encoding='UTF-8'?>" + "<familyset>" + " <family name='test'>" + " <font weight='400' style='normal'>a3em.ttf</font>" + " </family>" + "</familyset>"; final ArrayMap<String, Typeface> fontMap = new ArrayMap<>(); final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>(); final FontCustomizationParser.Result oemCustomization = new FontCustomizationParser.Result(); // Install all2em.ttf as a3em.ttf copyAssetToFile("fonts/all2em.ttf", new File(TEST_UPDATABLE_FONT_DIR, "a3em.ttf")); buildSystemFallback(xml, oemCustomization, fontMap, fallbackMap); final Paint paint = new Paint(); final Typeface sansSerifTypeface = fontMap.get("test"); assertNotNull(sansSerifTypeface); paint.setTypeface(sansSerifTypeface); assertEquals(GLYPH_2EM_WIDTH, paint.measureText("a"), 0.0f); assertEquals(GLYPH_2EM_WIDTH, paint.measureText("b"), 0.0f); assertEquals(GLYPH_2EM_WIDTH, paint.measureText("c"), 0.0f); } } graphics/java/android/graphics/FontListParser.java +27 −13 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.graphics; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; import android.graphics.fonts.FontVariationAxis; import android.os.Build; Loading @@ -25,6 +26,7 @@ import android.util.Xml; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; Loading @@ -41,26 +43,26 @@ public class FontListParser { /* Parse fallback list (no names) */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static FontConfig parse(InputStream in) throws XmlPullParserException, IOException { return parse(in, "/system/fonts"); return parse(in, "/system/fonts", null); } /** * Parse the fonts.xml */ public static FontConfig parse(InputStream in, String fontDir) throws XmlPullParserException, IOException { public static FontConfig parse(InputStream in, String fontDir, @Nullable String updatableFontDir) throws XmlPullParserException, IOException { try { XmlPullParser parser = Xml.newPullParser(); parser.setInput(in, null); parser.nextTag(); return readFamilies(parser, fontDir); return readFamilies(parser, fontDir, updatableFontDir); } finally { in.close(); } } private static FontConfig readFamilies(XmlPullParser parser, String fontDir) throws XmlPullParserException, IOException { private static FontConfig readFamilies(XmlPullParser parser, String fontDir, @Nullable String updatableFontDir) throws XmlPullParserException, IOException { List<FontConfig.Family> families = new ArrayList<>(); List<FontConfig.Alias> aliases = new ArrayList<>(); Loading @@ -69,7 +71,7 @@ public class FontListParser { if (parser.getEventType() != XmlPullParser.START_TAG) continue; String tag = parser.getName(); if (tag.equals("family")) { families.add(readFamily(parser, fontDir)); families.add(readFamily(parser, fontDir, updatableFontDir)); } else if (tag.equals("alias")) { aliases.add(readAlias(parser)); } else { Loading @@ -83,8 +85,8 @@ public class FontListParser { /** * Reads a family element */ public static FontConfig.Family readFamily(XmlPullParser parser, String fontDir) throws XmlPullParserException, IOException { public static FontConfig.Family readFamily(XmlPullParser parser, String fontDir, @Nullable String updatableFontDir) throws XmlPullParserException, IOException { final String name = parser.getAttributeValue(null, "name"); final String lang = parser.getAttributeValue("", "lang"); final String variant = parser.getAttributeValue(null, "variant"); Loading @@ -93,7 +95,7 @@ public class FontListParser { if (parser.getEventType() != XmlPullParser.START_TAG) continue; final String tag = parser.getName(); if (tag.equals("font")) { fonts.add(readFont(parser, fontDir)); fonts.add(readFont(parser, fontDir, updatableFontDir)); } else { skip(parser); } Loading @@ -114,8 +116,8 @@ public class FontListParser { private static final Pattern FILENAME_WHITESPACE_PATTERN = Pattern.compile("^[ \\n\\r\\t]+|[ \\n\\r\\t]+$"); private static FontConfig.Font readFont(XmlPullParser parser, String fontDir) throws XmlPullParserException, IOException { private static FontConfig.Font readFont(XmlPullParser parser, String fontDir, @Nullable String updatableFontDir) throws XmlPullParserException, IOException { String indexStr = parser.getAttributeValue(null, "index"); int index = indexStr == null ? 0 : Integer.parseInt(indexStr); List<FontVariationAxis> axes = new ArrayList<FontVariationAxis>(); Loading @@ -137,10 +139,22 @@ public class FontListParser { } } String sanitizedName = FILENAME_WHITESPACE_PATTERN.matcher(filename).replaceAll(""); return new FontConfig.Font(fontDir + sanitizedName, index, axes.toArray( String fontName = findFontFile(sanitizedName, fontDir, updatableFontDir); return new FontConfig.Font(fontName, index, axes.toArray( new FontVariationAxis[axes.size()]), weight, isItalic, fallbackFor); } private static String findFontFile(String fileName, String fontDir, @Nullable String updatableFontDir) { if (updatableFontDir != null) { String updatableFontName = updatableFontDir + fileName; if (new File(updatableFontName).exists()) { return updatableFontName; } } return fontDir + fileName; } private static FontVariationAxis readAxis(XmlPullParser parser) throws XmlPullParserException, IOException { String tagStr = parser.getAttributeValue(null, "tag"); Loading graphics/java/android/graphics/fonts/FontCustomizationParser.java +1 −1 Original line number Diff line number Diff line Loading @@ -97,7 +97,7 @@ public class FontCustomizationParser { throw new IllegalArgumentException("customizationType must be specified"); } if (customizationType.equals("new-named-family")) { out.mAdditionalNamedFamilies.add(FontListParser.readFamily(parser, fontDir)); out.mAdditionalNamedFamilies.add(FontListParser.readFamily(parser, fontDir, null)); } else { throw new IllegalArgumentException("Unknown customizationType=" + customizationType); } Loading graphics/java/android/graphics/fonts/SystemFonts.java +27 −3 Original line number Diff line number Diff line Loading @@ -91,7 +91,9 @@ public final class SystemFonts { final FontCustomizationParser.Result oemCustomization = readFontCustomization("/product/etc/fonts_customization.xml", "/product/fonts/"); Map<String, FontFamily[]> map = new ArrayMap<>(); buildSystemFallback("/system/etc/fonts.xml", "/system/fonts/", oemCustomization, map); // TODO: use updated fonts buildSystemFallback("/system/etc/fonts.xml", "/system/fonts/", null /* updatableFontDir */, oemCustomization, map); Set<Font> res = new HashSet<>(); for (FontFamily[] families : map.values()) { for (FontFamily family : families) { Loading Loading @@ -225,12 +227,27 @@ public final class SystemFonts { fallbackListMap.put(familyName, fallback); } /** * @see #buildSystemFallback(String, String, String, FontCustomizationParser.Result, Map) * @hide */ @VisibleForTesting public static FontConfig.Alias[] buildSystemFallback(@NonNull String xmlPath, @NonNull String fontDir, @NonNull FontCustomizationParser.Result oemCustomization, @NonNull Map<String, FontFamily[]> fallbackMap) { return buildSystemFallback(xmlPath, fontDir, null /* updatableFontDir */, oemCustomization, fallbackMap); } /** * Build the system fallback from xml file. * * @param xmlPath A full path string to the fonts.xml file. * @param fontDir A full path string to the system font directory. This must end with * slash('/'). * @param updatableFontDir A full path string to the updatable system font directory. This * must end with slash('/'). * @param fallbackMap An output system fallback map. Caller must pass empty map. * @return a list of aliases * @hide Loading @@ -238,11 +255,12 @@ public final class SystemFonts { @VisibleForTesting public static FontConfig.Alias[] buildSystemFallback(@NonNull String xmlPath, @NonNull String fontDir, @Nullable String updatableFontDir, @NonNull FontCustomizationParser.Result oemCustomization, @NonNull Map<String, FontFamily[]> fallbackMap) { try { final FileInputStream fontsIn = new FileInputStream(xmlPath); final FontConfig fontConfig = FontListParser.parse(fontsIn, fontDir); final FontConfig fontConfig = FontListParser.parse(fontsIn, fontDir, updatableFontDir); final HashMap<String, ByteBuffer> bufferCache = new HashMap<String, ByteBuffer>(); final FontConfig.Family[] xmlFamilies = fontConfig.getFamilies(); Loading Loading @@ -306,11 +324,17 @@ public final class SystemFonts { /** @hide */ public static @NonNull Pair<FontConfig.Alias[], Map<String, FontFamily[]>> initializePreinstalledFonts() { return initializeSystemFonts(null); } /** @hide */ public static Pair<FontConfig.Alias[], Map<String, FontFamily[]>> initializeSystemFonts(@Nullable String updatableFontDir) { final FontCustomizationParser.Result oemCustomization = readFontCustomization("/product/etc/fonts_customization.xml", "/product/fonts/"); Map<String, FontFamily[]> map = new ArrayMap<>(); FontConfig.Alias[] aliases = buildSystemFallback("/system/etc/fonts.xml", "/system/fonts/", oemCustomization, map); updatableFontDir, oemCustomization, map); synchronized (LOCK) { sFamilyMap = map; } Loading Loading
core/tests/coretests/src/android/graphics/TypefaceSystemFallbackTest.java +51 −14 Original line number Diff line number Diff line Loading @@ -67,6 +67,7 @@ public class TypefaceSystemFallbackTest { private static final String TEST_FONT_DIR; private static final String TEST_OEM_XML; private static final String TEST_OEM_DIR; private static final String TEST_UPDATABLE_FONT_DIR; private static final float GLYPH_1EM_WIDTH; private static final float GLYPH_2EM_WIDTH; Loading @@ -82,9 +83,11 @@ public class TypefaceSystemFallbackTest { TEST_FONTS_XML = new File(cacheDir, "fonts.xml").getAbsolutePath(); TEST_OEM_DIR = cacheDir.getAbsolutePath() + "/oem_fonts/"; TEST_OEM_XML = new File(cacheDir, "fonts_customization.xml").getAbsolutePath(); TEST_UPDATABLE_FONT_DIR = cacheDir.getAbsolutePath() + "/updatable_fonts/"; new File(TEST_FONT_DIR).mkdirs(); new File(TEST_OEM_DIR).mkdirs(); new File(TEST_UPDATABLE_FONT_DIR).mkdirs(); final AssetManager am = InstrumentationRegistry.getInstrumentation().getContext().getAssets(); Loading @@ -103,18 +106,11 @@ public class TypefaceSystemFallbackTest { InstrumentationRegistry.getInstrumentation().getContext().getAssets(); for (final String fontFile : TEST_FONT_FILES) { final String sourceInAsset = "fonts/" + fontFile; final File outInCache = new File(TEST_FONT_DIR, fontFile); try (InputStream is = am.open(sourceInAsset)) { Files.copy(is, outInCache.toPath(), StandardCopyOption.REPLACE_EXISTING); } catch (IOException e) { throw new RuntimeException(e); } final File outOemInCache = new File(TEST_OEM_DIR, fontFile); try (InputStream is = am.open(sourceInAsset)) { Files.copy(is, outOemInCache.toPath(), StandardCopyOption.REPLACE_EXISTING); } catch (IOException e) { throw new RuntimeException(e); copyAssetToFile(sourceInAsset, new File(TEST_FONT_DIR, fontFile)); copyAssetToFile(sourceInAsset, new File(TEST_OEM_DIR, fontFile)); } for (final File fontFile : new File(TEST_UPDATABLE_FONT_DIR).listFiles()) { fontFile.delete(); } } Loading @@ -124,7 +120,20 @@ public class TypefaceSystemFallbackTest { final File outInCache = new File(TEST_FONT_DIR, fontFile); outInCache.delete(); final File outOemInCache = new File(TEST_OEM_DIR, fontFile); outInCache.delete(); outOemInCache.delete(); } for (final File fontFile : new File(TEST_UPDATABLE_FONT_DIR).listFiles()) { fontFile.delete(); } } private static void copyAssetToFile(String sourceInAsset, File out) { final AssetManager am = InstrumentationRegistry.getInstrumentation().getContext().getAssets(); try (InputStream is = am.open(sourceInAsset)) { Files.copy(is, out.toPath(), StandardCopyOption.REPLACE_EXISTING); } catch (IOException e) { throw new RuntimeException(e); } } Loading @@ -138,7 +147,7 @@ public class TypefaceSystemFallbackTest { } final FontConfig.Alias[] aliases = SystemFonts.buildSystemFallback(TEST_FONTS_XML, TEST_FONT_DIR, oemCustomization, fallbackMap); TEST_FONT_DIR, TEST_UPDATABLE_FONT_DIR, oemCustomization, fallbackMap); Typeface.initSystemDefaultTypefaces(fontMap, fallbackMap, aliases); } Loading Loading @@ -835,4 +844,32 @@ public class TypefaceSystemFallbackTest { + "</fonts-modification>"; readFontCustomization(oemXml); } @Test public void testBuildSystemFallback_UpdatableFont() { final String xml = "<?xml version='1.0' encoding='UTF-8'?>" + "<familyset>" + " <family name='test'>" + " <font weight='400' style='normal'>a3em.ttf</font>" + " </family>" + "</familyset>"; final ArrayMap<String, Typeface> fontMap = new ArrayMap<>(); final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>(); final FontCustomizationParser.Result oemCustomization = new FontCustomizationParser.Result(); // Install all2em.ttf as a3em.ttf copyAssetToFile("fonts/all2em.ttf", new File(TEST_UPDATABLE_FONT_DIR, "a3em.ttf")); buildSystemFallback(xml, oemCustomization, fontMap, fallbackMap); final Paint paint = new Paint(); final Typeface sansSerifTypeface = fontMap.get("test"); assertNotNull(sansSerifTypeface); paint.setTypeface(sansSerifTypeface); assertEquals(GLYPH_2EM_WIDTH, paint.measureText("a"), 0.0f); assertEquals(GLYPH_2EM_WIDTH, paint.measureText("b"), 0.0f); assertEquals(GLYPH_2EM_WIDTH, paint.measureText("c"), 0.0f); } }
graphics/java/android/graphics/FontListParser.java +27 −13 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.graphics; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; import android.graphics.fonts.FontVariationAxis; import android.os.Build; Loading @@ -25,6 +26,7 @@ import android.util.Xml; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; Loading @@ -41,26 +43,26 @@ public class FontListParser { /* Parse fallback list (no names) */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static FontConfig parse(InputStream in) throws XmlPullParserException, IOException { return parse(in, "/system/fonts"); return parse(in, "/system/fonts", null); } /** * Parse the fonts.xml */ public static FontConfig parse(InputStream in, String fontDir) throws XmlPullParserException, IOException { public static FontConfig parse(InputStream in, String fontDir, @Nullable String updatableFontDir) throws XmlPullParserException, IOException { try { XmlPullParser parser = Xml.newPullParser(); parser.setInput(in, null); parser.nextTag(); return readFamilies(parser, fontDir); return readFamilies(parser, fontDir, updatableFontDir); } finally { in.close(); } } private static FontConfig readFamilies(XmlPullParser parser, String fontDir) throws XmlPullParserException, IOException { private static FontConfig readFamilies(XmlPullParser parser, String fontDir, @Nullable String updatableFontDir) throws XmlPullParserException, IOException { List<FontConfig.Family> families = new ArrayList<>(); List<FontConfig.Alias> aliases = new ArrayList<>(); Loading @@ -69,7 +71,7 @@ public class FontListParser { if (parser.getEventType() != XmlPullParser.START_TAG) continue; String tag = parser.getName(); if (tag.equals("family")) { families.add(readFamily(parser, fontDir)); families.add(readFamily(parser, fontDir, updatableFontDir)); } else if (tag.equals("alias")) { aliases.add(readAlias(parser)); } else { Loading @@ -83,8 +85,8 @@ public class FontListParser { /** * Reads a family element */ public static FontConfig.Family readFamily(XmlPullParser parser, String fontDir) throws XmlPullParserException, IOException { public static FontConfig.Family readFamily(XmlPullParser parser, String fontDir, @Nullable String updatableFontDir) throws XmlPullParserException, IOException { final String name = parser.getAttributeValue(null, "name"); final String lang = parser.getAttributeValue("", "lang"); final String variant = parser.getAttributeValue(null, "variant"); Loading @@ -93,7 +95,7 @@ public class FontListParser { if (parser.getEventType() != XmlPullParser.START_TAG) continue; final String tag = parser.getName(); if (tag.equals("font")) { fonts.add(readFont(parser, fontDir)); fonts.add(readFont(parser, fontDir, updatableFontDir)); } else { skip(parser); } Loading @@ -114,8 +116,8 @@ public class FontListParser { private static final Pattern FILENAME_WHITESPACE_PATTERN = Pattern.compile("^[ \\n\\r\\t]+|[ \\n\\r\\t]+$"); private static FontConfig.Font readFont(XmlPullParser parser, String fontDir) throws XmlPullParserException, IOException { private static FontConfig.Font readFont(XmlPullParser parser, String fontDir, @Nullable String updatableFontDir) throws XmlPullParserException, IOException { String indexStr = parser.getAttributeValue(null, "index"); int index = indexStr == null ? 0 : Integer.parseInt(indexStr); List<FontVariationAxis> axes = new ArrayList<FontVariationAxis>(); Loading @@ -137,10 +139,22 @@ public class FontListParser { } } String sanitizedName = FILENAME_WHITESPACE_PATTERN.matcher(filename).replaceAll(""); return new FontConfig.Font(fontDir + sanitizedName, index, axes.toArray( String fontName = findFontFile(sanitizedName, fontDir, updatableFontDir); return new FontConfig.Font(fontName, index, axes.toArray( new FontVariationAxis[axes.size()]), weight, isItalic, fallbackFor); } private static String findFontFile(String fileName, String fontDir, @Nullable String updatableFontDir) { if (updatableFontDir != null) { String updatableFontName = updatableFontDir + fileName; if (new File(updatableFontName).exists()) { return updatableFontName; } } return fontDir + fileName; } private static FontVariationAxis readAxis(XmlPullParser parser) throws XmlPullParserException, IOException { String tagStr = parser.getAttributeValue(null, "tag"); Loading
graphics/java/android/graphics/fonts/FontCustomizationParser.java +1 −1 Original line number Diff line number Diff line Loading @@ -97,7 +97,7 @@ public class FontCustomizationParser { throw new IllegalArgumentException("customizationType must be specified"); } if (customizationType.equals("new-named-family")) { out.mAdditionalNamedFamilies.add(FontListParser.readFamily(parser, fontDir)); out.mAdditionalNamedFamilies.add(FontListParser.readFamily(parser, fontDir, null)); } else { throw new IllegalArgumentException("Unknown customizationType=" + customizationType); } Loading
graphics/java/android/graphics/fonts/SystemFonts.java +27 −3 Original line number Diff line number Diff line Loading @@ -91,7 +91,9 @@ public final class SystemFonts { final FontCustomizationParser.Result oemCustomization = readFontCustomization("/product/etc/fonts_customization.xml", "/product/fonts/"); Map<String, FontFamily[]> map = new ArrayMap<>(); buildSystemFallback("/system/etc/fonts.xml", "/system/fonts/", oemCustomization, map); // TODO: use updated fonts buildSystemFallback("/system/etc/fonts.xml", "/system/fonts/", null /* updatableFontDir */, oemCustomization, map); Set<Font> res = new HashSet<>(); for (FontFamily[] families : map.values()) { for (FontFamily family : families) { Loading Loading @@ -225,12 +227,27 @@ public final class SystemFonts { fallbackListMap.put(familyName, fallback); } /** * @see #buildSystemFallback(String, String, String, FontCustomizationParser.Result, Map) * @hide */ @VisibleForTesting public static FontConfig.Alias[] buildSystemFallback(@NonNull String xmlPath, @NonNull String fontDir, @NonNull FontCustomizationParser.Result oemCustomization, @NonNull Map<String, FontFamily[]> fallbackMap) { return buildSystemFallback(xmlPath, fontDir, null /* updatableFontDir */, oemCustomization, fallbackMap); } /** * Build the system fallback from xml file. * * @param xmlPath A full path string to the fonts.xml file. * @param fontDir A full path string to the system font directory. This must end with * slash('/'). * @param updatableFontDir A full path string to the updatable system font directory. This * must end with slash('/'). * @param fallbackMap An output system fallback map. Caller must pass empty map. * @return a list of aliases * @hide Loading @@ -238,11 +255,12 @@ public final class SystemFonts { @VisibleForTesting public static FontConfig.Alias[] buildSystemFallback(@NonNull String xmlPath, @NonNull String fontDir, @Nullable String updatableFontDir, @NonNull FontCustomizationParser.Result oemCustomization, @NonNull Map<String, FontFamily[]> fallbackMap) { try { final FileInputStream fontsIn = new FileInputStream(xmlPath); final FontConfig fontConfig = FontListParser.parse(fontsIn, fontDir); final FontConfig fontConfig = FontListParser.parse(fontsIn, fontDir, updatableFontDir); final HashMap<String, ByteBuffer> bufferCache = new HashMap<String, ByteBuffer>(); final FontConfig.Family[] xmlFamilies = fontConfig.getFamilies(); Loading Loading @@ -306,11 +324,17 @@ public final class SystemFonts { /** @hide */ public static @NonNull Pair<FontConfig.Alias[], Map<String, FontFamily[]>> initializePreinstalledFonts() { return initializeSystemFonts(null); } /** @hide */ public static Pair<FontConfig.Alias[], Map<String, FontFamily[]>> initializeSystemFonts(@Nullable String updatableFontDir) { final FontCustomizationParser.Result oemCustomization = readFontCustomization("/product/etc/fonts_customization.xml", "/product/fonts/"); Map<String, FontFamily[]> map = new ArrayMap<>(); FontConfig.Alias[] aliases = buildSystemFallback("/system/etc/fonts.xml", "/system/fonts/", oemCustomization, map); updatableFontDir, oemCustomization, map); synchronized (LOCK) { sFamilyMap = map; } Loading