1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.text; 18 19 import android.annotation.NonNull; 20 import android.content.Context; 21 import android.content.res.AssetManager; 22 import android.graphics.FontListParser; 23 import android.graphics.Typeface; 24 import android.graphics.fonts.FontFamily; 25 import android.graphics.fonts.SystemFonts; 26 27 import androidx.test.InstrumentationRegistry; 28 29 import org.xmlpull.v1.XmlPullParserException; 30 31 import java.io.File; 32 import java.io.FileOutputStream; 33 import java.io.IOException; 34 import java.io.InputStream; 35 import java.nio.charset.Charset; 36 import java.nio.file.Files; 37 import java.nio.file.StandardCopyOption; 38 import java.util.Map; 39 40 public class FontFallbackSetup implements AutoCloseable { 41 private final String[] mTestFontFiles; 42 private final String mXml; 43 private final String mTestFontsDir; 44 private final Map<String, Typeface> mFontMap; 45 FontFallbackSetup(@onNull String testSubDir, @NonNull String[] testFontFiles, @NonNull String xml)46 public FontFallbackSetup(@NonNull String testSubDir, @NonNull String[] testFontFiles, 47 @NonNull String xml) { 48 mTestFontFiles = testFontFiles; 49 mXml = xml; 50 51 final Context targetCtx = InstrumentationRegistry.getInstrumentation().getTargetContext(); 52 final File cacheDir = new File(targetCtx.getCacheDir(), testSubDir); 53 if (!cacheDir.isDirectory()) { 54 final boolean dirsCreated = cacheDir.mkdirs(); 55 if (!dirsCreated) { 56 throw new RuntimeException("Creating test directories for fonts failed."); 57 } 58 } 59 mTestFontsDir = cacheDir.getAbsolutePath() + "/"; 60 61 final String testFontsXml = new File(mTestFontsDir, "fonts.xml").getAbsolutePath(); 62 final AssetManager am = 63 InstrumentationRegistry.getInstrumentation().getContext().getAssets(); 64 for (String fontFile : mTestFontFiles) { 65 final String sourceInAsset = "fonts/" + fontFile; 66 final File outInCache = new File(mTestFontsDir, fontFile); 67 try (InputStream is = am.open(sourceInAsset)) { 68 Files.copy(is, outInCache.toPath(), StandardCopyOption.REPLACE_EXISTING); 69 } catch (IOException e) { 70 throw new RuntimeException(e); 71 } 72 } 73 74 try (FileOutputStream fos = new FileOutputStream(testFontsXml)) { 75 fos.write(mXml.getBytes(Charset.forName("UTF-8"))); 76 } catch (IOException e) { 77 throw new RuntimeException(e); 78 } 79 80 FontConfig fontConfig; 81 try { 82 fontConfig = FontListParser.parse(testFontsXml, mTestFontsDir, null, null, null, 0, 0); 83 } catch (IOException | XmlPullParserException e) { 84 throw new RuntimeException(e); 85 } 86 87 Map<String, FontFamily[]> fallbackMap = SystemFonts.buildSystemFallback(fontConfig); 88 mFontMap = SystemFonts.buildSystemTypefaces(fontConfig, fallbackMap); 89 } 90 91 @NonNull getTypefaceFor(@onNull String fontName)92 public Typeface getTypefaceFor(@NonNull String fontName) { 93 return mFontMap.get(fontName); 94 } 95 96 @NonNull getPaintFor(@onNull String fontName)97 public TextPaint getPaintFor(@NonNull String fontName) { 98 final TextPaint paint = new TextPaint(); 99 paint.setTypeface(getTypefaceFor(fontName)); 100 return paint; 101 } 102 103 @Override close()104 public void close() { 105 for (String fontFile : mTestFontFiles) { 106 final File outInCache = new File(mTestFontsDir, fontFile); 107 outInCache.delete(); 108 } 109 } 110 } 111