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
17package android.graphics;
18
19import static org.junit.Assert.assertEquals;
20import static org.junit.Assert.assertFalse;
21import static org.junit.Assert.assertNotNull;
22import static org.junit.Assert.assertTrue;
23
24import android.content.Context;
25import android.content.res.AssetManager;
26import android.support.test.InstrumentationRegistry;
27import android.support.test.filters.SmallTest;
28import android.support.test.runner.AndroidJUnit4;
29import android.util.ArrayMap;
30
31import org.junit.After;
32import org.junit.Before;
33import org.junit.Test;
34import org.junit.runner.RunWith;
35
36import java.io.File;
37import java.io.FileOutputStream;
38import java.io.IOException;
39import java.io.InputStream;
40import java.nio.charset.Charset;
41import java.nio.file.Files;
42import java.nio.file.StandardCopyOption;
43import java.util.Locale;
44
45@SmallTest
46@RunWith(AndroidJUnit4.class)
47public class TypefaceSystemFallbackTest {
48    private static final String SYSTEM_FONT_DIR = "/system/fonts/";
49    private static final String SYSTEM_FONTS_XML = "/system/etc/fonts.xml";
50
51    private static final String[] TEST_FONT_FILES = {
52        "a3em.ttf",  // Supports "a","b","c". The width of "a" is 3em,  others are 1em.
53        "b3em.ttf",  // Supports "a","b","c". The width of "b" is 3em,  others are 1em.
54        "c3em.ttf",  // Supports "a","b","c". The width of "c" is 3em,  others are 1em.
55        "all2em.ttf",  // Supports "a,","b","c". All of them have the same width of 2em.
56        "no_coverage.ttf",  // This font doesn't support any characters.
57    };
58    private static final String TEST_FONTS_XML;
59    private static final String TEST_FONT_DIR;
60
61    private static final float GLYPH_1EM_WIDTH;
62    private static final float GLYPH_2EM_WIDTH;
63    private static final float GLYPH_3EM_WIDTH;
64
65    static {
66        final Context targetCtx = InstrumentationRegistry.getInstrumentation().getTargetContext();
67        final File cacheDir = new File(targetCtx.getCacheDir(), "TypefaceSystemFallbackTest");
68        if (!cacheDir.isDirectory()) {
69            cacheDir.mkdirs();
70        }
71        TEST_FONT_DIR = cacheDir.getAbsolutePath() + "/";
72        TEST_FONTS_XML = new File(cacheDir, "fonts.xml").getAbsolutePath();
73
74        final AssetManager am =
75                InstrumentationRegistry.getInstrumentation().getContext().getAssets();
76        final Paint paint = new Paint();
77        paint.setTypeface(new Typeface.Builder(am, "fonts/a3em.ttf").build());
78        GLYPH_3EM_WIDTH = paint.measureText("a");
79        GLYPH_1EM_WIDTH = paint.measureText("b");
80
81        paint.setTypeface(new Typeface.Builder(am, "fonts/all2em.ttf").build());
82        GLYPH_2EM_WIDTH = paint.measureText("a");
83    }
84
85    @Before
86    public void setUp() {
87        final AssetManager am =
88                InstrumentationRegistry.getInstrumentation().getContext().getAssets();
89        for (final String fontFile : TEST_FONT_FILES) {
90            final String sourceInAsset = "fonts/" + fontFile;
91            final File outInCache = new File(TEST_FONT_DIR, fontFile);
92            try (InputStream is = am.open(sourceInAsset)) {
93                Files.copy(is, outInCache.toPath(), StandardCopyOption.REPLACE_EXISTING);
94            } catch (IOException e) {
95                throw new RuntimeException(e);
96            }
97        }
98    }
99
100    @After
101    public void tearDown() {
102        for (final String fontFile : TEST_FONT_FILES) {
103            final File outInCache = new File(TEST_FONT_DIR, fontFile);
104            outInCache.delete();
105        }
106    }
107
108    private static void buildSystemFallback(String xml,
109            ArrayMap<String, Typeface> fontMap, ArrayMap<String, FontFamily[]> fallbackMap) {
110        try (FileOutputStream fos = new FileOutputStream(TEST_FONTS_XML)) {
111            fos.write(xml.getBytes(Charset.forName("UTF-8")));
112        } catch (IOException e) {
113            throw new RuntimeException(e);
114        }
115        Typeface.buildSystemFallback(TEST_FONTS_XML, TEST_FONT_DIR, fontMap, fallbackMap);
116    }
117
118    @Test
119    public void testBuildSystemFallback() {
120        final ArrayMap<String, Typeface> fontMap = new ArrayMap<>();
121        final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
122
123        Typeface.buildSystemFallback(SYSTEM_FONTS_XML, SYSTEM_FONT_DIR, fontMap, fallbackMap);
124
125        assertFalse(fontMap.isEmpty());
126        assertFalse(fallbackMap.isEmpty());
127    }
128
129    @Test
130    public void testBuildSystemFallback_NonExistentFontShouldBeIgnored() {
131        final String xml = "<?xml version='1.0' encoding='UTF-8'?>"
132                + "<familyset>"
133                + "  <family name='sans-serif'>"
134                + "    <font weight='400' style='normal'>a3em.ttf</font>"
135                + "    <font weight='400' style='normal'>NoSuchFont.ttf</font>"
136                + "  </family>"
137                + "  <family name='NoSuchFont'>"
138                + "    <font weight='400' style='normal'>NoSuchFont.ttf</font>"
139                + "  </family>"
140                + "  <family>"
141                + "    <font weight='400' style='normal'>NoSuchFont.ttf</font>"
142                + "  </family>"
143                + "</familyset>";
144        final ArrayMap<String, Typeface> fontMap = new ArrayMap<>();
145        final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
146
147        buildSystemFallback(xml, fontMap, fallbackMap);
148
149        assertEquals(1, fontMap.size());
150        assertTrue(fontMap.containsKey("sans-serif"));
151        assertEquals(1, fallbackMap.size());
152        assertTrue(fallbackMap.containsKey("sans-serif"));
153    }
154
155    @Test
156    public void testBuildSystemFallback_NamedFamily() {
157        final String xml = "<?xml version='1.0' encoding='UTF-8'?>"
158                + "<familyset>"
159                + "  <family name='sans-serif'>"
160                + "    <font weight='400' style='normal'>a3em.ttf</font>"
161                + "  </family>"
162                + "  <family name='test'>"
163                + "    <font weight='400' style='normal'>b3em.ttf</font>"
164                + "  </family>"
165                + "  <family name='test2'>"
166                + "    <font weight='400' style='normal'>c3em.ttf</font>"
167                + "  </family>"
168                + "  <family>"
169                + "    <font weight='400' style='normal'>all2em.ttf</font>"
170                + "  </family>"
171                + "</familyset>";
172        final ArrayMap<String, Typeface> fontMap = new ArrayMap<>();
173        final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
174
175        buildSystemFallback(xml, fontMap, fallbackMap);
176
177        final Paint paint = new Paint();
178
179        final Typeface sansSerifTypeface = fontMap.get("sans-serif");
180        assertNotNull(sansSerifTypeface);
181        paint.setTypeface(sansSerifTypeface);
182        assertEquals(GLYPH_3EM_WIDTH, paint.measureText("a"), 0.0f);
183        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("b"), 0.0f);
184        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
185
186        final Typeface testTypeface = fontMap.get("test");
187        assertNotNull(testTypeface);
188        paint.setTypeface(testTypeface);
189        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("a"), 0.0f);
190        assertEquals(GLYPH_3EM_WIDTH, paint.measureText("b"), 0.0f);
191        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
192
193        final Typeface test2Typeface = fontMap.get("test2");
194        assertNotNull(test2Typeface);
195        paint.setTypeface(test2Typeface);
196        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("a"), 0.0f);
197        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("b"), 0.0f);
198        assertEquals(GLYPH_3EM_WIDTH, paint.measureText("c"), 0.0f);
199    }
200
201    @Test
202    public void testBuildSystemFallback_defaultFallback() {
203        final String xml = "<?xml version='1.0' encoding='UTF-8'?>"
204                + "<familyset>"
205                + "  <family name='sans-serif'>"
206                + "    <font weight='400' style='normal'>no_coverage.ttf</font>"
207                + "  </family>"
208                + "  <family name='test'>"
209                + "    <font weight='400' style='normal'>no_coverage.ttf</font>"
210                + "  </family>"
211                + "  <family>"
212                + "    <font weight='400' style='normal'>a3em.ttf</font>"
213                + "  </family>"
214                + "  <family>"
215                + "    <font weight='400' style='normal'>all2em.ttf</font>"
216                + "  </family>"
217                + "</familyset>";
218        final ArrayMap<String, Typeface> fontMap = new ArrayMap<>();
219        final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
220
221        buildSystemFallback(xml, fontMap, fallbackMap);
222
223        final Paint paint = new Paint();
224
225        final Typeface sansSerifTypeface = fontMap.get("sans-serif");
226        assertNotNull(sansSerifTypeface);
227        paint.setTypeface(sansSerifTypeface);
228        assertEquals(GLYPH_3EM_WIDTH, paint.measureText("a"), 0.0f);
229        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("b"), 0.0f);
230        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
231
232        final Typeface testTypeface = fontMap.get("test");
233        assertNotNull(testTypeface);
234        paint.setTypeface(testTypeface);
235        assertEquals(GLYPH_3EM_WIDTH, paint.measureText("a"), 0.0f);
236        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("b"), 0.0f);
237        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
238    }
239
240    @Test
241    public void testBuildSystemFallback_namedFallbackFamily() {
242        final String xml = "<?xml version='1.0' encoding='UTF-8'?>"
243                + "<familyset>"
244                + "  <family name='sans-serif'>"
245                + "    <font weight='400' style='normal'>no_coverage.ttf</font>"
246                + "  </family>"
247                + "  <family name='test'>"
248                + "    <font weight='400' style='normal'>no_coverage.ttf</font>"
249                + "  </family>"
250                + "  <family name='test2'>"
251                + "    <font weight='400' style='normal'>no_coverage.ttf</font>"
252                + "  </family>"
253                + "  <family>"
254                + "    <font weight='400' style='normal' fallbackFor='test'>a3em.ttf</font>"
255                + "  </family>"
256                + "  <family>"
257                + "    <font weight='400' style='normal' fallbackFor='test2'>b3em.ttf</font>"
258                + "  </family>"
259                + "  <family>"
260                + "    <font weight='400' style='normal'>all2em.ttf</font>"
261                + "  </family>"
262                + "</familyset>";
263        final ArrayMap<String, Typeface> fontMap = new ArrayMap<>();
264        final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
265
266        buildSystemFallback(xml, fontMap, fallbackMap);
267
268        final Paint paint = new Paint();
269
270        final Typeface sansSerifTypeface = fontMap.get("sans-serif");
271        assertNotNull(sansSerifTypeface);
272        paint.setTypeface(sansSerifTypeface);
273        assertEquals(GLYPH_2EM_WIDTH, paint.measureText("a"), 0.0f);
274        assertEquals(GLYPH_2EM_WIDTH, paint.measureText("b"), 0.0f);
275        assertEquals(GLYPH_2EM_WIDTH, paint.measureText("c"), 0.0f);
276
277        final Typeface testTypeface = fontMap.get("test");
278        assertNotNull(testTypeface);
279        paint.setTypeface(testTypeface);
280        assertEquals(GLYPH_3EM_WIDTH, paint.measureText("a"), 0.0f);
281        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("b"), 0.0f);
282        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
283
284        final Typeface test2Typeface = fontMap.get("test2");
285        assertNotNull(test2Typeface);
286        paint.setTypeface(test2Typeface);
287        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("a"), 0.0f);
288        assertEquals(GLYPH_3EM_WIDTH, paint.measureText("b"), 0.0f);
289        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
290    }
291
292    @Test
293    public void testBuildSystemFallback_namedFallbackFamily2() {
294        final String xml = "<?xml version='1.0' encoding='UTF-8'?>"
295                + "<familyset>"
296                + "  <family name='sans-serif'>"
297                + "    <font weight='400' style='normal'>no_coverage.ttf</font>"
298                + "  </family>"
299                + "  <family name='test'>"
300                + "    <font weight='400' style='normal'>no_coverage.ttf</font>"
301                + "  </family>"
302                + "  <family name='test2'>"
303                + "    <font weight='400' style='normal'>no_coverage.ttf</font>"
304                + "  </family>"
305                + "  <family>"
306                + "    <font weight='400' style='normal' fallbackFor='test'>a3em.ttf</font>"
307                + "    <font weight='400' style='normal'>b3em.ttf</font>"
308                + "  </family>"
309                + "  <family>"
310                + "    <font weight='400' style='normal'>all2em.ttf</font>"
311                + "  </family>"
312                + "</familyset>";
313        final ArrayMap<String, Typeface> fontMap = new ArrayMap<>();
314        final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
315
316        buildSystemFallback(xml, fontMap, fallbackMap);
317
318        final Paint paint = new Paint();
319
320        final Typeface sansSerifTypeface = fontMap.get("sans-serif");
321        assertNotNull(sansSerifTypeface);
322        paint.setTypeface(sansSerifTypeface);
323        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("a"), 0.0f);
324        assertEquals(GLYPH_3EM_WIDTH, paint.measureText("b"), 0.0f);
325        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
326
327        final Typeface testTypeface = fontMap.get("test");
328        assertNotNull(testTypeface);
329        paint.setTypeface(testTypeface);
330        assertEquals(GLYPH_3EM_WIDTH, paint.measureText("a"), 0.0f);
331        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("b"), 0.0f);
332        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
333
334        final Typeface test2Typeface = fontMap.get("test2");
335        assertNotNull(test2Typeface);
336        paint.setTypeface(test2Typeface);
337        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("a"), 0.0f);
338        assertEquals(GLYPH_3EM_WIDTH, paint.measureText("b"), 0.0f);
339        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
340    }
341
342    @Test
343    public void testBuildSystemFallback_ImplicitSansSerifFallback() {
344        final String xml = "<?xml version='1.0' encoding='UTF-8'?>"
345                + "<familyset>"
346                + "  <family name='sans-serif'>"
347                + "    <font weight='400' style='normal'>a3em.ttf</font>"
348                + "  </family>"
349                + "  <family name='test'>"
350                + "    <font weight='400' style='normal'>no_coverage.ttf</font>"
351                + "  </family>"
352                + "  <family name='test2'>"
353                + "    <font weight='400' style='normal'>no_coverage.ttf</font>"
354                + "  </family>"
355                + "  <family>"
356                + "    <font weight='400' style='normal'>all2em.ttf</font>"
357                + "  </family>"
358                + "</familyset>";
359        final ArrayMap<String, Typeface> fontMap = new ArrayMap<>();
360        final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
361
362        buildSystemFallback(xml, fontMap, fallbackMap);
363
364        final Paint paint = new Paint();
365
366        final Typeface testTypeface = fontMap.get("test");
367        assertNotNull(testTypeface);
368        paint.setTypeface(testTypeface);
369        assertEquals(GLYPH_3EM_WIDTH, paint.measureText("a"), 0.0f);
370        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("b"), 0.0f);
371        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
372
373        final Typeface test2Typeface = fontMap.get("test2");
374        assertNotNull(test2Typeface);
375        paint.setTypeface(test2Typeface);
376        assertEquals(GLYPH_3EM_WIDTH, paint.measureText("a"), 0.0f);
377        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("b"), 0.0f);
378        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
379    }
380
381    @Test
382    public void testBuildSystemFallback_ElegantFallback() {
383        final String xml = "<?xml version='1.0' encoding='UTF-8'?>"
384                + "<familyset>"
385                + "  <family name='sans-serif'>"
386                + "    <font weight='400' style='normal'>no_coverage.ttf</font>"
387                + "  </family>"
388                + "  <family name='serif'>"
389                + "    <font weight='400' style='normal'>no_coverage.ttf</font>"
390                + "  </family>"
391                + "  <family variant='elegant'>"
392                + "    <font weight='400' style='normal'>a3em.ttf</font>"
393                + "  </family>"
394                + "  <family variant='compact'>"
395                + "    <font weight='400' style='normal'>b3em.ttf</font>"
396                + "  </family>"
397                + "</familyset>";
398        final ArrayMap<String, Typeface> fontMap = new ArrayMap<>();
399        final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
400
401        buildSystemFallback(xml, fontMap, fallbackMap);
402
403        final Paint paint = new Paint();
404
405        final Typeface testTypeface = fontMap.get("serif");
406        assertNotNull(testTypeface);
407        paint.setTypeface(testTypeface);
408        paint.setElegantTextHeight(true);
409        assertEquals(GLYPH_3EM_WIDTH, paint.measureText("a"), 0.0f);
410        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("b"), 0.0f);
411        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
412
413        paint.setElegantTextHeight(false);
414        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("a"), 0.0f);
415        assertEquals(GLYPH_3EM_WIDTH, paint.measureText("b"), 0.0f);
416        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
417    }
418
419    @Test
420    public void testBuildSystemFallback_ElegantFallback_customFallback() {
421        final String xml = "<?xml version='1.0' encoding='UTF-8'?>"
422                + "<familyset>"
423                + "  <family name='sans-serif'>"
424                + "    <font weight='400' style='normal'>no_coverage.ttf</font>"
425                + "  </family>"
426                + "  <family name='serif'>"
427                + "    <font weight='400' style='normal'>no_coverage.ttf</font>"
428                + "  </family>"
429                + "  <family variant='elegant'>"
430                + "    <font weight='400' style='normal'>a3em.ttf</font>"
431                + "    <font weight='400' style='normal' fallbackFor='serif'>b3em.ttf</font>"
432                + "  </family>"
433                + "  <family variant='compact'>"
434                + "    <font weight='400' style='normal'>c3em.ttf</font>"
435                + "  </family>"
436                + "</familyset>";
437        final ArrayMap<String, Typeface> fontMap = new ArrayMap<>();
438        final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
439
440        buildSystemFallback(xml, fontMap, fallbackMap);
441
442        final Paint paint = new Paint();
443
444        Typeface testTypeface = fontMap.get("serif");
445        assertNotNull(testTypeface);
446        paint.setTypeface(testTypeface);
447        paint.setElegantTextHeight(true);
448        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("a"), 0.0f);
449        assertEquals(GLYPH_3EM_WIDTH, paint.measureText("b"), 0.0f);
450        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
451
452        paint.setElegantTextHeight(false);
453        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("a"), 0.0f);
454        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("b"), 0.0f);
455        assertEquals(GLYPH_3EM_WIDTH, paint.measureText("c"), 0.0f);
456
457        testTypeface = fontMap.get("sans-serif");
458        assertNotNull(testTypeface);
459        paint.setTypeface(testTypeface);
460        paint.setElegantTextHeight(true);
461        assertEquals(GLYPH_3EM_WIDTH, paint.measureText("a"), 0.0f);
462        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("b"), 0.0f);
463        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
464
465        paint.setElegantTextHeight(false);
466        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("a"), 0.0f);
467        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("b"), 0.0f);
468        assertEquals(GLYPH_3EM_WIDTH, paint.measureText("c"), 0.0f);
469    }
470
471    @Test
472    public void testBuildSystemFallback_multiLingualFamilies() {
473        final String xml = "<?xml version='1.0' encoding='UTF-8'?>"
474                + "<familyset>"
475                + "  <family name='sans-serif'>"
476                + "    <font weight='400' style='normal'>no_coverage.ttf</font>"
477                + "  </family>"
478                + "  <family lang='de'>"
479                + "    <font weight='400' style='normal'>a3em.ttf</font>"
480                + "  </family>"
481                + "  <family lang='it fr'>"
482                + "    <font weight='400' style='normal'>b3em.ttf</font>"
483                + "  </family>"
484                + "</familyset>";
485        final ArrayMap<String, Typeface> fontMap = new ArrayMap<>();
486        final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
487
488        buildSystemFallback(xml, fontMap, fallbackMap);
489
490        final Paint paint = new Paint();
491        paint.setTypeface(fontMap.get("sans-serif"));
492
493        paint.setTextLocale(Locale.GERMANY);
494        assertEquals(GLYPH_3EM_WIDTH, paint.measureText("a"), 0.0f);
495        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("b"), 0.0f);
496        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
497
498        paint.setTextLocale(Locale.ITALY);
499        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("a"), 0.0f);
500        assertEquals(GLYPH_3EM_WIDTH, paint.measureText("b"), 0.0f);
501        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
502
503        paint.setTextLocale(Locale.FRANCE);
504        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("a"), 0.0f);
505        assertEquals(GLYPH_3EM_WIDTH, paint.measureText("b"), 0.0f);
506        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
507    }
508
509    @Test
510    public void testBuildSystemFallback_ElegantFallback_customFallback_missingFile() {
511        final String xml = "<?xml version='1.0' encoding='UTF-8'?>"
512                + "<familyset>"
513                + "  <family name='sans-serif'>"
514                + "    <font weight='400' style='normal'>no_coverage.ttf</font>"
515                + "  </family>"
516                + "  <family name='serif'>"
517                + "    <font weight='400' style='normal'>no_coverage.ttf</font>"
518                + "  </family>"
519                + "  <family>"
520                + "    <font weight='400' style='normal'>a3em.ttf</font>"
521                + "    <font weight='400' style='normal' fallbackFor='serif'>NoSuchFont.ttf</font>"
522                + "  </family>"
523                + "  <family>"
524                + "    <font weight='400' style='normal'>b3em.ttf</font>"
525                + "  </family>"
526                + "</familyset>";
527        final ArrayMap<String, Typeface> fontMap = new ArrayMap<>();
528        final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
529
530        buildSystemFallback(xml, fontMap, fallbackMap);
531
532        final Paint paint = new Paint();
533
534        Typeface testTypeface = fontMap.get("serif");
535        assertNotNull(testTypeface);
536        paint.setTypeface(testTypeface);
537        assertEquals(GLYPH_3EM_WIDTH, paint.measureText("a"), 0.0f);
538        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("b"), 0.0f);
539        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
540
541        testTypeface = fontMap.get("sans-serif");
542        assertNotNull(testTypeface);
543        paint.setTypeface(testTypeface);
544        assertEquals(GLYPH_3EM_WIDTH, paint.measureText("a"), 0.0f);
545        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("b"), 0.0f);
546        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
547    }
548
549    @Test
550    public void testBuildSystemFallback_ElegantFallback_customFallback_missingFile2() {
551        final String xml = "<?xml version='1.0' encoding='UTF-8'?>"
552                + "<familyset>"
553                + "  <family name='sans-serif'>"
554                + "    <font weight='400' style='normal'>no_coverage.ttf</font>"
555                + "  </family>"
556                + "  <family name='serif'>"
557                + "    <font weight='400' style='normal'>no_coverage.ttf</font>"
558                + "  </family>"
559                + "  <family>"
560                + "    <font weight='400' style='normal' fallbackFor='serif'>NoSuchFont.ttf</font>"
561                + "  </family>"
562                + "  <family>"
563                + "    <font weight='400' style='normal'>a3em.ttf</font>"
564                + "  </family>"
565                + "</familyset>";
566        final ArrayMap<String, Typeface> fontMap = new ArrayMap<>();
567        final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
568
569        buildSystemFallback(xml, fontMap, fallbackMap);
570
571        final Paint paint = new Paint();
572
573        Typeface testTypeface = fontMap.get("serif");
574        assertNotNull(testTypeface);
575        paint.setTypeface(testTypeface);
576        assertEquals(GLYPH_3EM_WIDTH, paint.measureText("a"), 0.0f);
577        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("b"), 0.0f);
578        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
579
580        testTypeface = fontMap.get("sans-serif");
581        assertNotNull(testTypeface);
582        paint.setTypeface(testTypeface);
583        assertEquals(GLYPH_3EM_WIDTH, paint.measureText("a"), 0.0f);
584        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("b"), 0.0f);
585        assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
586    }
587
588}
589