19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
171a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyenpackage android.graphics;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
194a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonakaimport static org.junit.Assert.assertEquals;
204a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonakaimport static org.junit.Assert.assertTrue;
214a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka
224a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonakaimport android.content.Context;
234a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonakaimport android.content.res.AssetManager;
244a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonakaimport android.content.res.Resources;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Paint;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Typeface;
274a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonakaimport android.support.test.InstrumentationRegistry;
284a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonakaimport android.support.test.runner.AndroidJUnit4;
294a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonakaimport android.test.suitebuilder.annotation.LargeTest;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.test.suitebuilder.annotation.MediumTest;
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.test.suitebuilder.annotation.SmallTest;
32ede3a17f6079b7da62240bbcaf613591ba2fc055Roozbeh Pournader
334a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonakaimport com.android.frameworks.coretests.R;
344a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka
354a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonakaimport org.junit.Test;
364a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonakaimport org.junit.runner.RunWith;
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
384a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonakaimport java.util.Random;
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
404a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka@RunWith(AndroidJUnit4.class)
414a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonakapublic class TypefaceTest {
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // create array of all std faces
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final Typeface[] mFaces = new Typeface[] {
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Typeface.create(Typeface.SANS_SERIF, 0),
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Typeface.create(Typeface.SANS_SERIF, 1),
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Typeface.create(Typeface.SERIF, 0),
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Typeface.create(Typeface.SERIF, 1),
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Typeface.create(Typeface.SERIF, 2),
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Typeface.create(Typeface.SERIF, 3),
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Typeface.create(Typeface.MONOSPACE, 0)
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    };
534a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @SmallTest
554a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka    @Test
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void testBasic() throws Exception {
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        assertTrue("basic", Typeface.DEFAULT != null);
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        assertTrue("basic", Typeface.DEFAULT_BOLD != null);
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        assertTrue("basic", Typeface.SANS_SERIF != null);
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        assertTrue("basic", Typeface.SERIF != null);
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        assertTrue("basic", Typeface.MONOSPACE != null);
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
634a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @SmallTest
654a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka    @Test
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void testUnique() throws Exception {
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int n = mFaces.length;
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < n; i++) {
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int j = i + 1; j < n; j++) {
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                assertTrue("unique", mFaces[i] != mFaces[j]);
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @SmallTest
764a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka    @Test
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void testStyles() throws Exception {
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        assertTrue("style", mFaces[0].getStyle() == Typeface.NORMAL);
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        assertTrue("style", mFaces[1].getStyle() == Typeface.BOLD);
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        assertTrue("style", mFaces[2].getStyle() == Typeface.NORMAL);
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        assertTrue("style", mFaces[3].getStyle() == Typeface.BOLD);
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        assertTrue("style", mFaces[4].getStyle() == Typeface.ITALIC);
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        assertTrue("style", mFaces[5].getStyle() == Typeface.BOLD_ITALIC);
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        assertTrue("style", mFaces[6].getStyle() == Typeface.NORMAL);
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @MediumTest
884a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka    @Test
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void testUniformY() throws Exception {
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint p = new Paint();
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int n = mFaces.length;
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 1; i <= 36; i++) {
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.setTextSize(i);
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            float ascent = 0;
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            float descent = 0;
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int j = 0; j < n; j++) {
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                p.setTypeface(mFaces[j]);
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Paint.FontMetrics fm = p.getFontMetrics();
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (j == 0) {
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    ascent = fm.ascent;
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    descent = fm.descent;
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    assertTrue("fontMetrics", fm.ascent == ascent);
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    assertTrue("fontMetrics", fm.descent == descent);
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1104a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka    @LargeTest
1114a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka    @Test
1124a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka    public void testMultithreadCacheStressTest() {
1134a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka        final Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
1144a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka        final Resources res = context.getResources();
1154a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka        final AssetManager assets = res.getAssets();
1164a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka        final Typeface[] baseTypefaces = {
1174a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka            null,
1184a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka            Typeface.SANS_SERIF,
1194a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka            Typeface.SERIF,
1204a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka            Typeface.MONOSPACE,
1214a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka            res.getFont(R.font.samplefont),
1224a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka            res.getFont(R.font.samplefont2),
1234a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka            res.getFont(R.font.samplefont3),
1244a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka            res.getFont(R.font.samplefont4),
1254a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka            res.getFont(R.font.samplexmlfont),
1264a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka            Typeface.createFromAsset(assets, "fonts/a3em.ttf"),
1274a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka            Typeface.createFromAsset(assets, "fonts/b3em.ttf"),
1284a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka            Typeface.createFromAsset(assets, "fonts/c3em.ttf"),
1294a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka            Typeface.createFromAsset(assets, "fonts/all2em.ttf"),
1304a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka            Typeface.createFromAsset(assets, "fonts/hasGlyphTestFont.ttf"),
1314a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka            Typeface.createFromAsset(assets, "fonts/samplefont1.ttf"),
1324a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka            Typeface.createFromAsset(assets, "fonts/no_coverage.ttf"),
1334a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka        };
1344a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka
1354a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka        final int loopCount = 10000;
1364a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka
1374a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka        final Runnable threadedCreater = () -> {
1384a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka            final Random random = new Random();
1394a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka            for (int i = 0; i < loopCount; ++i) {
1404a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka                final Typeface base = baseTypefaces[random.nextInt(baseTypefaces.length)];
1414a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka                if (random.nextBoolean()) {
1424a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka                    final int style = random.nextInt(3);
1434a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka                    final Typeface result = Typeface.create(base, style);
1444a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka                    assertEquals(style, result.getStyle());
1454a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka                } else {
1464a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka                    final int weight = 100 * (random.nextInt(10) + 1);  // [100, 1000]
1474a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka                    final boolean italic = random.nextBoolean();
1484a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka                    final Typeface result = Typeface.create(base, weight, italic);
1494a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka                    assertEquals(italic, result.isItalic());
1504a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka                    assertEquals(weight, result.getWeight());
1514a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka                }
1524a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka            }
1534a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka        };
1544a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka
1554a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka        final int threadCount = 4;
1564a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka        final Thread[] threads = new Thread[threadCount];
1574a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka        for (int i = 0; i < threadCount; ++i) {
1584a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka            threads[i] = new Thread(threadedCreater);
1594a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka        }
1604a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka
1614a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka        for (int i = 0; i < threadCount; ++i) {
1624a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka            threads[i].start();
1634a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka        }
1644a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka
1654a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka        for (int i = 0; i < threadCount; ++i) {
1664a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka            try {
1674a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka                threads[i].join();
1684a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka            } catch (InterruptedException e) {
1694a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka                // ignore
1704a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka            }
1714a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka        }
1724a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka
1734a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka    }
1744a40e0febf3de60c54c19797aecd3c698b770699Seigo Nonaka
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
176