/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.graphics.cts;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import android.content.Context;
import android.content.res.AssetManager;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.graphics.Typeface.Builder;

import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Locale;

@SmallTest
@RunWith(AndroidJUnit4.class)
public class TypefaceTest {
    // generic family name for monospaced fonts
    private static final String MONO = "monospace";
    private static final String DEFAULT = (String)null;
    private static final String INVALID = "invalid-family-name";

    private static final float GLYPH_1EM_WIDTH;
    private static final float GLYPH_3EM_WIDTH;

    private static float measureText(String text, Typeface typeface) {
        final Paint paint = new Paint();
        // Fix the locale so that fix the locale based fallback.
        paint.setTextLocale(Locale.US);
        paint.setTypeface(typeface);
        return paint.measureText(text);
    }

    static {
        // 3em.ttf supports "a", "b", "c". The width of "a" is 3em, others are 1em.
        final Context ctx = InstrumentationRegistry.getTargetContext();
        final Typeface typeface = ctx.getResources().getFont(R.font.a3em);
        GLYPH_3EM_WIDTH = measureText("a", typeface);
        GLYPH_1EM_WIDTH = measureText("b", typeface);
    }

    // list of family names to try when attempting to find a typeface with a given style
    private static final String[] FAMILIES =
            { (String) null, "monospace", "serif", "sans-serif", "cursive", "arial", "times" };

    private Context mContext;

    /**
     * Create a typeface of the given style. If the default font does not support the style,
     * a number of generic families are tried.
     * @return The typeface or null, if no typeface with the given style can be found.
     */
    private static Typeface createTypeface(int style) {
        for (String family : FAMILIES) {
            Typeface tf = Typeface.create(family, style);
            if (tf.getStyle() == style) {
                return tf;
            }
        }
        return null;
    }

    @Before
    public void setup() {
        mContext = InstrumentationRegistry.getTargetContext();
    }

    @Test
    public void testIsBold() {
        Typeface typeface = createTypeface(Typeface.BOLD);
        if (typeface != null) {
            assertEquals(Typeface.BOLD, typeface.getStyle());
            assertTrue(typeface.isBold());
            assertFalse(typeface.isItalic());
        }

        typeface = createTypeface(Typeface.ITALIC);
        if (typeface != null) {
            assertEquals(Typeface.ITALIC, typeface.getStyle());
            assertFalse(typeface.isBold());
            assertTrue(typeface.isItalic());
        }

        typeface = createTypeface(Typeface.BOLD_ITALIC);
        if (typeface != null) {
            assertEquals(Typeface.BOLD_ITALIC, typeface.getStyle());
            assertTrue(typeface.isBold());
            assertTrue(typeface.isItalic());
        }

        typeface = createTypeface(Typeface.NORMAL);
        if (typeface != null) {
            assertEquals(Typeface.NORMAL, typeface.getStyle());
            assertFalse(typeface.isBold());
            assertFalse(typeface.isItalic());
        }
    }

    @Test
    public void testCreate() {
        Typeface typeface = Typeface.create(DEFAULT, Typeface.NORMAL);
        assertNotNull(typeface);
        typeface = Typeface.create(MONO, Typeface.BOLD);
        assertNotNull(typeface);
        typeface = Typeface.create(INVALID, Typeface.ITALIC);
        assertNotNull(typeface);

        typeface = Typeface.create(typeface, Typeface.NORMAL);
        assertNotNull(typeface);
        typeface = Typeface.create(typeface, Typeface.BOLD);
        assertNotNull(typeface);
    }

    @Test
    public void testDefaultFromStyle() {
        Typeface typeface = Typeface.defaultFromStyle(Typeface.NORMAL);
        assertNotNull(typeface);
        typeface = Typeface.defaultFromStyle(Typeface.BOLD);
        assertNotNull(typeface);
        typeface = Typeface.defaultFromStyle(Typeface.ITALIC);
        assertNotNull(typeface);
        typeface = Typeface.defaultFromStyle(Typeface.BOLD_ITALIC);
        assertNotNull(typeface);
    }

    @Test
    public void testConstants() {
        assertNotNull(Typeface.DEFAULT);
        assertNotNull(Typeface.DEFAULT_BOLD);
        assertNotNull(Typeface.MONOSPACE);
        assertNotNull(Typeface.SANS_SERIF);
        assertNotNull(Typeface.SERIF);
    }

    @Test(expected=NullPointerException.class)
    public void testCreateFromAssetNull() {
        // input abnormal params.
        Typeface.createFromAsset(null, null);
    }

    @Test(expected=NullPointerException.class)
    public void testCreateFromAssetNullPath() {
        // input abnormal params.
        Typeface.createFromAsset(mContext.getAssets(), null);
    }

    @Test(expected=RuntimeException.class)
    public void testCreateFromAssetInvalidPath() {
        // input abnormal params.
        Typeface.createFromAsset(mContext.getAssets(), "invalid path");
    }

    @Test
    public void testCreateFromAsset() {
        Typeface typeface = Typeface.createFromAsset(mContext.getAssets(), "samplefont.ttf");
        assertNotNull(typeface);
    }

    @Test(expected=NullPointerException.class)
    public void testCreateFromFileByFileReferenceNull() {
        // input abnormal params.
        Typeface.createFromFile((File) null);
    }

    @Test
    public void testCreateFromFileByFileReference() throws IOException {
        File file = new File(obtainPath());
        Typeface typeface = Typeface.createFromFile(file);
        assertNotNull(typeface);
    }

    @Test(expected=RuntimeException.class)
    public void testCreateFromFileWithInvalidPath() throws IOException {
        File file = new File("/invalid/path");
        Typeface.createFromFile(file);
    }

    @Test(expected=NullPointerException.class)
    public void testCreateFromFileByFileNameNull() throws IOException {
        // input abnormal params.
        Typeface.createFromFile((String) null);
    }

    @Test(expected=RuntimeException.class)
    public void testCreateFromFileByInvalidFileName() throws IOException {
        // input abnormal params.
        Typeface.createFromFile("/invalid/path");
    }

    @Test
    public void testCreateFromFileByFileName() throws IOException {
        Typeface typeface = Typeface.createFromFile(obtainPath());
        assertNotNull(typeface);
    }

    private String obtainPath() throws IOException {
        File dir = mContext.getFilesDir();
        dir.mkdirs();
        File file = new File(dir, "test.jpg");
        if (!file.createNewFile()) {
            if (!file.exists()) {
                fail("Failed to create new File!");
            }
        }
        InputStream is = mContext.getAssets().open("samplefont.ttf");
        FileOutputStream fOutput = new FileOutputStream(file);
        byte[] dataBuffer = new byte[1024];
        int readLength = 0;
        while ((readLength = is.read(dataBuffer)) != -1) {
            fOutput.write(dataBuffer, 0, readLength);
        }
        is.close();
        fOutput.close();
        return (file.getPath());
    }

    @Test
    public void testInvalidCmapFont() {
        Typeface typeface = Typeface.createFromAsset(mContext.getAssets(), "bombfont.ttf");
        assertNotNull(typeface);
        final String testString = "abcde";
        float widthDefaultTypeface = measureText(testString, Typeface.DEFAULT);
        float widthCustomTypeface = measureText(testString, typeface);
        assertEquals(widthDefaultTypeface, widthCustomTypeface, 1.0f);
    }

    @Test
    public void testInvalidCmapFont2() {
        Typeface typeface = Typeface.createFromAsset(mContext.getAssets(), "bombfont2.ttf");
        assertNotNull(typeface);
        final String testString = "abcde";
        float widthDefaultTypeface = measureText(testString, Typeface.DEFAULT);
        float widthCustomTypeface = measureText(testString, typeface);
        assertEquals(widthDefaultTypeface, widthCustomTypeface, 1.0f);
    }

    @Test
    public void testInvalidCmapFont_tooLargeCodePoints() {
        // Following three font doen't have any coverage between U+0000..U+10FFFF. Just make sure
        // they don't crash us.
        final String[] INVALID_CMAP_FONTS = {
            "out_of_unicode_start_cmap12.ttf",
            "out_of_unicode_end_cmap12.ttf",
            "too_large_start_cmap12.ttf",
            "too_large_end_cmap12.ttf",
        };
        for (final String file : INVALID_CMAP_FONTS) {
            final Typeface typeface = Typeface.createFromAsset(mContext.getAssets(), file);
            assertNotNull(typeface);
        }
    }

    @Test
    public void testInvalidCmapFont_unsortedEntries() {
        // Following two font files have glyph for U+0400 and U+0100 but the fonts must not be used
        // due to invalid cmap data. For more details, see each ttx source file.
        final String[] INVALID_CMAP_FONTS = { "unsorted_cmap4.ttf", "unsorted_cmap12.ttf" };
        for (final String file : INVALID_CMAP_FONTS) {
            final Typeface typeface = Typeface.createFromAsset(mContext.getAssets(), file);
            assertNotNull(typeface);
            final String testString = "\u0100\u0400";
            final float widthDefaultTypeface = measureText(testString, Typeface.DEFAULT);
            final float widthCustomTypeface = measureText(testString, typeface);
            assertEquals(widthDefaultTypeface, widthCustomTypeface, 0.0f);
        }

        // Following two font files have glyph for U+0400 U+FE00 and U+0100 U+FE00 but the fonts
        // must not be used due to invalid cmap data. For more details, see each ttx source file.
        final String[] INVALID_CMAP_VS_FONTS = {
            "unsorted_cmap14_default_uvs.ttf",
            "unsorted_cmap14_non_default_uvs.ttf"
        };
        for (final String file : INVALID_CMAP_VS_FONTS) {
            final Typeface typeface = Typeface.createFromAsset(mContext.getAssets(), file);
            assertNotNull(typeface);
            final String testString = "\u0100\uFE00\u0400\uFE00";
            final float widthDefaultTypeface = measureText(testString, Typeface.DEFAULT);
            final float widthCustomTypeface = measureText(testString, typeface);
            assertEquals(widthDefaultTypeface, widthCustomTypeface, 0.0f);
        }
    }

    @Test
    public void testCreateFromAsset_cachesTypeface() {
        Typeface typeface1 = Typeface.createFromAsset(mContext.getAssets(), "samplefont.ttf");
        assertNotNull(typeface1);

        Typeface typeface2 = Typeface.createFromAsset(mContext.getAssets(), "samplefont.ttf");
        assertNotNull(typeface2);
        assertSame("Same font asset should return same Typeface object", typeface1, typeface2);

        Typeface typeface3 = Typeface.createFromAsset(mContext.getAssets(), "samplefont2.ttf");
        assertNotNull(typeface3);
        assertNotSame("Different font asset should return different Typeface object",
                typeface2, typeface3);

        Typeface typeface4 = Typeface.createFromAsset(mContext.getAssets(), "samplefont3.ttf");
        assertNotNull(typeface4);
        assertNotSame("Different font asset should return different Typeface object",
                typeface2, typeface4);
        assertNotSame("Different font asset should return different Typeface object",
                typeface3, typeface4);
    }

    @Test
    public void testBadFont() {
        Typeface typeface = Typeface.createFromAsset(mContext.getAssets(), "ft45987.ttf");
        assertNotNull(typeface);
    }

    @Test
    public void testTypefaceBuilder_AssetSource() {
        Typeface typeface1 = new Typeface.Builder(mContext.getAssets(), "samplefont.ttf").build();
        assertNotNull(typeface1);

        Typeface typeface2 = new Typeface.Builder(mContext.getAssets(), "samplefont.ttf").build();
        assertNotNull(typeface2);
        assertSame("Same font asset should return same Typeface object", typeface1, typeface2);

        Typeface typeface3 = new Typeface.Builder(mContext.getAssets(), "samplefont2.ttf").build();
        assertNotNull(typeface3);
        assertNotSame("Different font asset should return different Typeface object",
                typeface2, typeface3);

        Typeface typeface4 = new Typeface.Builder(mContext.getAssets(), "samplefont3.ttf").build();
        assertNotNull(typeface4);
        assertNotSame("Different font asset should return different Typeface object",
                typeface2, typeface4);
        assertNotSame("Different font asset should return different Typeface object",
                typeface3, typeface4);

        Typeface typeface5 = new Typeface.Builder(mContext.getAssets(), "samplefont.ttf")
                .setFontVariationSettings("'wdth' 1.0").build();
        assertNotNull(typeface5);
        assertNotSame("Different font font variation should return different Typeface object",
                typeface2, typeface5);

        Typeface typeface6 = new Typeface.Builder(mContext.getAssets(), "samplefont.ttf")
                .setFontVariationSettings("'wdth' 2.0").build();
        assertNotNull(typeface6);
        assertNotSame("Different font font variation should return different Typeface object",
                typeface2, typeface6);
        assertNotSame("Different font font variation should return different Typeface object",
                typeface5, typeface6);

        // TODO: Add ttc index case. Need TTC file for CTS. (b/36731640)
    }

    @Test
    public void testTypefaceBuilder_FileSource() {
        try {
            File file = new File(obtainPath());
            Typeface typeface1 = new Typeface.Builder(obtainPath()).build();
            assertNotNull(typeface1);

            Typeface typeface2 = new Typeface.Builder(file).build();
            assertNotNull(typeface2);

            Typeface typeface3 = new Typeface.Builder(file)
                    .setFontVariationSettings("'wdth' 1.0")
                    .build();
            assertNotNull(typeface3);
            assertNotSame(typeface1, typeface3);
            assertNotSame(typeface2, typeface3);

            // TODO: Add ttc index case. Need TTC file for CTS.
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Test
    public void testTypefaceBuilder_fallback() throws IOException {
        final File validFile = new File(obtainPath());
        final File invalidFile = new File("/some/invalid/path/to/font/file");
        final AssetManager assets = mContext.getAssets();
        // By default, returns null if no fallback font is specified.
        assertNull(new Typeface.Builder(invalidFile).build());

        assertNull(new Typeface.Builder(validFile)
                .setTtcIndex(100 /* non-existing ttc index */).build());

        assertNull(new Typeface.Builder(assets, "invalid path").build());

        assertNull(new Typeface.Builder(assets, "samplefont.ttf")
                .setTtcIndex(100 /* non-existing ttc index */).build());

        // If fallback is set, the builder never returns null.
        assertNotNull(new Typeface.Builder(invalidFile).setFallback("").build());

        assertNotNull(new Typeface.Builder(invalidFile).setFallback("invalid name").build());

        Typeface sansSerifTypeface = new Typeface.Builder(invalidFile)
                .setFallback("sans-serif").build();
        assertNotNull(sansSerifTypeface);

        Typeface serifTypeface = new Typeface.Builder(invalidFile).setFallback("serif").build();
        assertNotNull(serifTypeface);

        Typeface boldSansSerifTypeface = new Typeface.Builder(invalidFile)
                .setFallback("sans-serif").setWeight(700).build();
        assertNotNull(boldSansSerifTypeface);

        Typeface boldSerifTypeface = new Typeface.Builder(invalidFile)
                .setFallback("serif").setWeight(700).build();
        assertNotNull(boldSerifTypeface);

        Typeface italicSansSerifTypeface = new Typeface.Builder(invalidFile)
                .setFallback("sans-serif").setItalic(true).build();
        assertNotNull(italicSansSerifTypeface);

        Typeface italicSerifTypeface = new Typeface.Builder(invalidFile)
                .setFallback("serif").setItalic(true).build();
        assertNotNull(italicSerifTypeface);

        // All fallbacks should be different each other.
        assertNotSame(sansSerifTypeface, serifTypeface);
        assertNotSame(sansSerifTypeface, boldSansSerifTypeface);
        assertNotSame(sansSerifTypeface, boldSerifTypeface);
        assertNotSame(sansSerifTypeface, italicSansSerifTypeface);
        assertNotSame(sansSerifTypeface, italicSerifTypeface);
        assertNotSame(serifTypeface, boldSansSerifTypeface);
        assertNotSame(serifTypeface, boldSerifTypeface);
        assertNotSame(serifTypeface, italicSansSerifTypeface);
        assertNotSame(serifTypeface, italicSerifTypeface);
        assertNotSame(boldSansSerifTypeface, boldSerifTypeface);
        assertNotSame(boldSansSerifTypeface, italicSansSerifTypeface);
        assertNotSame(boldSansSerifTypeface, italicSerifTypeface);
        assertNotSame(boldSerifTypeface, italicSansSerifTypeface);
        assertNotSame(boldSerifTypeface, italicSerifTypeface);
        assertNotSame(italicSansSerifTypeface, italicSerifTypeface);

        // Cache should work for the same fallback.
        assertSame(sansSerifTypeface,
                new Typeface.Builder(assets, "samplefont.ttf").setFallback("sans-serif")
                        .setTtcIndex(100 /* non-existing ttc index */).build());
        assertSame(serifTypeface,
                new Typeface.Builder(assets, "samplefont.ttf").setFallback("serif")
                        .setTtcIndex(100 /* non-existing ttc index */).build());
        assertSame(boldSansSerifTypeface,
                new Typeface.Builder(assets, "samplefont.ttf").setFallback("sans-serif")
                        .setTtcIndex(100 /* non-existing ttc index */).setWeight(700).build());
        assertSame(boldSerifTypeface,
                new Typeface.Builder(assets, "samplefont.ttf").setFallback("serif")
                        .setTtcIndex(100 /* non-existing ttc index */).setWeight(700).build());
        assertSame(italicSansSerifTypeface,
                new Typeface.Builder(assets, "samplefont.ttf").setFallback("sans-serif")
                        .setTtcIndex(100 /* non-existing ttc index */).setItalic(true).build());
        assertSame(italicSerifTypeface,
                new Typeface.Builder(assets, "samplefont.ttf").setFallback("serif")
                        .setTtcIndex(100 /* non-existing ttc index */).setItalic(true).build());
    }

    @Test
    public void testTypefaceBuilder_FileSourceFD() {
        try (FileInputStream fis = new FileInputStream(obtainPath())) {
            assertNotNull(new Typeface.Builder(fis.getFD()).build());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Test
    public void testTypeface_SupportedCmapEncodingTest() {
        // We support the following combinations of cmap platfrom/endcoding pairs.
        String[] fontPaths = {
            "CmapPlatform0Encoding0.ttf",  // Platform ID == 0, Encoding ID == 0
            "CmapPlatform0Encoding1.ttf",  // Platform ID == 0, Encoding ID == 1
            "CmapPlatform0Encoding2.ttf",  // Platform ID == 0, Encoding ID == 2
            "CmapPlatform0Encoding3.ttf",  // Platform ID == 0, Encoding ID == 3
            "CmapPlatform0Encoding4.ttf",  // Platform ID == 0, Encoding ID == 4
            "CmapPlatform0Encoding6.ttf",  // Platform ID == 0, Encoding ID == 6
            "CmapPlatform3Encoding1.ttf",  // Platform ID == 3, Encoding ID == 1
            "CmapPlatform3Encoding10.ttf",  // Platform ID == 3, Encoding ID == 10
        };

        for (String fontPath : fontPaths) {
            Typeface typeface = Typeface.createFromAsset(mContext.getAssets(), fontPath);
            assertNotNull(typeface);
            final String testString = "a";
            float widthDefaultTypeface = measureText(testString, Typeface.DEFAULT);
            float widthCustomTypeface = measureText(testString, typeface);
            // The width of the glyph "a" from above fonts are 2em.
            // So the width should be different from the default one.
            assertNotEquals(widthDefaultTypeface, widthCustomTypeface, 1.0f);
        }
    }

    @Test
    public void testTypefaceBuilder_customFallback() {
        final String fontPath = "samplefont2.ttf";
        final Typeface regularTypeface = new Typeface.Builder(mContext.getAssets(), fontPath)
                .setWeight(400).build();
        final Typeface blackTypeface = new Typeface.Builder(mContext.getAssets(), fontPath)
                .setWeight(900).build();

        // W is not supported by samplefont2.ttf
        final String testString = "WWWWWWWWWWWWWWWWWWWWW";

        final Paint p = new Paint();
        p.setTextLocale(Locale.US);
        p.setTextSize(128);

        p.setTypeface(regularTypeface);
        final float widthFromRegular = p.measureText(testString);

        p.setTypeface(blackTypeface);
        final float widthFromBlack = p.measureText(testString);

        assertNotEquals(widthFromRegular, widthFromBlack, 1.0f);
    }

    @Test
    public void testTypefaceCreate_withExactWeight() {
        // multiweight_family has following fonts.
        // - a3em.ttf with weight = 100, style=normal configuration.
        //   This font supports "a", "b", "c". The weight "a" is 3em, others are 1em.
        // - b3em.ttf with weight = 400, style=normal configuration.
        //   This font supports "a", "b", "c". The weight "b" is 3em, others are 1em.
        // - c3em.ttf with weight = 700, style=normal configuration.
        //   This font supports "a", "b", "c". The weight "c" is 3em, others are 1em.
        final Typeface family = mContext.getResources().getFont(R.font.multiweight_family);
        assertNotNull(family);

        // By default, the font which weight is 400 is selected.
        assertEquals(GLYPH_1EM_WIDTH, measureText("a", family), 0f);
        assertEquals(GLYPH_3EM_WIDTH, measureText("b", family), 0f);
        assertEquals(GLYPH_1EM_WIDTH, measureText("c", family), 0f);

        // Draw with the font which weight is 100.
        final Typeface thinFamily = Typeface.create(family, 100 /* weight */, false /* italic */);
        assertEquals(GLYPH_3EM_WIDTH, measureText("a", thinFamily), 0f);
        assertEquals(GLYPH_1EM_WIDTH, measureText("b", thinFamily), 0f);
        assertEquals(GLYPH_1EM_WIDTH, measureText("c", thinFamily), 0f);

        // Draw with the font which weight is 700.
        final Typeface boldFamily = Typeface.create(family, 700 /* weight */, false /* italic */);
        assertEquals(GLYPH_1EM_WIDTH, measureText("a", boldFamily), 0f);
        assertEquals(GLYPH_1EM_WIDTH, measureText("b", boldFamily), 0f);
        assertEquals(GLYPH_3EM_WIDTH, measureText("c", boldFamily), 0f);
    }

    @Test
    public void testTypefaceCreate_withExactStyle() {
        // multiweight_family has following fonts.
        // - a3em.ttf with weight = 400, style=normal configuration.
        //   This font supports "a", "b", "c". The weight "a" is 3em, others are 1em.
        // - b3em.ttf with weight = 400, style=italic configuration.
        //   This font supports "a", "b", "c". The weight "b" is 3em, others are 1em.
        // - c3em.ttf with weight = 700, style=italic configuration.
        //   This font supports "a", "b", "c". The weight "c" is 3em, others are 1em.
        final Typeface family = mContext.getResources().getFont(R.font.multistyle_family);
        assertNotNull(family);

        // By default, the normal style font which weight is 400 is selected.
        assertEquals(GLYPH_3EM_WIDTH, measureText("a", family), 0f);
        assertEquals(GLYPH_1EM_WIDTH, measureText("b", family), 0f);
        assertEquals(GLYPH_1EM_WIDTH, measureText("c", family), 0f);

        // Draw with the italic font.
        final Typeface italicFamily = Typeface.create(family, 400 /* weight */, true /* italic */);
        assertEquals(GLYPH_1EM_WIDTH, measureText("a", italicFamily), 0f);
        assertEquals(GLYPH_3EM_WIDTH, measureText("b", italicFamily), 0f);
        assertEquals(GLYPH_1EM_WIDTH, measureText("c", italicFamily), 0f);

        // Draw with the italic font which weigth is 700.
        final Typeface boldItalicFamily =
                Typeface.create(family, 700 /* weight */, true /* italic */);
        assertEquals(GLYPH_1EM_WIDTH, measureText("a", boldItalicFamily), 0f);
        assertEquals(GLYPH_1EM_WIDTH, measureText("b", boldItalicFamily), 0f);
        assertEquals(GLYPH_3EM_WIDTH, measureText("c", boldItalicFamily), 0f);
    }

    @Test
    public void testFontVariationSettings() {
        // WeightEqualsEmVariableFont is a special font generating the outlines a glyph of 1/1000
        // width of the given wght axis. For example, if 300 is given as the wght value to the font,
        // the font will generate 0.3em of the glyph for the 'a'..'z' characters.
        // The minimum, default, maximum value of 'wght' is 0, 0, 1000.
        // No other axes are supported.

        final AssetManager am = mContext.getAssets();
        final Paint paint = new Paint();
        paint.setTextSize(100);  // Make 1em = 100px

        // By default, WeightEqualsEmVariableFont has 0 'wght' value.
        paint.setTypeface(new Typeface.Builder(am, "WeightEqualsEmVariableFont.ttf").build());
        assertEquals(0.0f, paint.measureText("a"), 0.0f);

        paint.setTypeface(new Typeface.Builder(am, "WeightEqualsEmVariableFont.ttf")
                .setFontVariationSettings("'wght' 100").build());
        assertEquals(10.0f, paint.measureText("a"), 0.0f);

        paint.setTypeface(new Typeface.Builder(am, "WeightEqualsEmVariableFont.ttf")
                .setFontVariationSettings("'wght' 300").build());
        assertEquals(30.0f, paint.measureText("a"), 0.0f);

        paint.setTypeface(new Typeface.Builder(am, "WeightEqualsEmVariableFont.ttf")
                .setFontVariationSettings("'wght' 800").build());
        assertEquals(80.0f, paint.measureText("a"), 0.0f);

        paint.setTypeface(new Typeface.Builder(am, "WeightEqualsEmVariableFont.ttf")
                .setFontVariationSettings("'wght' 550").build());
        assertEquals(55.0f, paint.measureText("a"), 0.0f);
    }

    @Test
    public void testFontVariationSettings_UnsupportedAxes() {
        // WeightEqualsEmVariableFont is a special font generating the outlines a glyph of 1/1000
        // width of the given wght axis. For example, if 300 is given as the wght value to the font,
        // the font will generate 0.3em of the glyph for the 'a'..'z' characters.
        // The minimum, default, maximum value of 'wght' is 0, 0, 1000.
        // No other axes are supported.

        final AssetManager am = mContext.getAssets();
        final Paint paint = new Paint();
        paint.setTextSize(100);  // Make 1em = 100px

        // Unsupported axes do not affect the result.
        paint.setTypeface(new Typeface.Builder(am, "WeightEqualsEmVariableFont.ttf")
                .setFontVariationSettings("'wght' 300, 'wdth' 10").build());
        assertEquals(30.0f, paint.measureText("a"), 0.0f);

        paint.setTypeface(new Typeface.Builder(am, "WeightEqualsEmVariableFont.ttf")
                .setFontVariationSettings("'wdth' 10, 'wght' 300").build());
        assertEquals(30.0f, paint.measureText("a"), 0.0f);
    }

    @Test
    public void testFontVariationSettings_OutOfRangeValue() {
        // WeightEqualsEmVariableFont is a special font generating the outlines a glyph of 1/1000
        // width of the given wght axis. For example, if 300 is given as the wght value to the font,
        // the font will generate 0.3em of the glyph for the 'a'..'z' characters.
        // The minimum, default, maximum value of 'wght' is 0, 0, 1000.
        // No other axes are supported.

        final AssetManager am = mContext.getAssets();
        final Paint paint = new Paint();
        paint.setTextSize(100);  // Make 1em = 100px

        // Out of range value needs to be clipped at the minimum or maximum values.
        paint.setTypeface(new Typeface.Builder(am, "WeightEqualsEmVariableFont.ttf")
                .setFontVariationSettings("'wght' -100").build());
        assertEquals(0.0f, paint.measureText("a"), 0.0f);

        paint.setTypeface(new Typeface.Builder(am, "WeightEqualsEmVariableFont.ttf")
                .setFontVariationSettings("'wght' 1300").build());
        assertEquals(100.0f, paint.measureText("a"), 0.0f);
    }

    @Test
    public void testTypefaceCreate_getWeight() {
        Typeface typeface = Typeface.DEFAULT;
        assertEquals(400, typeface.getWeight());
        assertFalse(typeface.isItalic());

        typeface = Typeface.create(Typeface.DEFAULT, 100, false /* italic */);
        assertEquals(100, typeface.getWeight());
        assertFalse(typeface.isItalic());

        typeface = Typeface.create(Typeface.DEFAULT, 100, true /* italic */);
        assertEquals(100, typeface.getWeight());
        assertTrue(typeface.isItalic());

        typeface = Typeface.create(Typeface.DEFAULT, 400, false /* italic */);
        assertEquals(400, typeface.getWeight());
        assertFalse(typeface.isItalic());

        typeface = Typeface.create(Typeface.DEFAULT, 400, true /* italic */);
        assertEquals(400, typeface.getWeight());
        assertTrue(typeface.isItalic());

        typeface = Typeface.create(Typeface.DEFAULT, 700, false /* italic */);
        assertEquals(700, typeface.getWeight());
        assertFalse(typeface.isItalic());

        typeface = Typeface.create(Typeface.DEFAULT, 700, true /* italic */);
        assertEquals(700, typeface.getWeight());
        assertTrue(typeface.isItalic());

        // Non-standard weight.
        typeface = Typeface.create(Typeface.DEFAULT, 250, false /* italic */);
        assertEquals(250, typeface.getWeight());
        assertFalse(typeface.isItalic());

        typeface = Typeface.create(Typeface.DEFAULT, 250, true /* italic */);
        assertEquals(250, typeface.getWeight());
        assertTrue(typeface.isItalic());

    }

    @Test
    public void testTypefaceCreate_customFont_getWeight() {
        final AssetManager am = mContext.getAssets();

        Typeface typeface = new Builder(am, "ascii_a3em_weight100_upright.ttf").build();
        assertEquals(100, typeface.getWeight());
        assertFalse(typeface.isItalic());

        typeface = new Builder(am, "ascii_b3em_weight100_italic.ttf").build();
        assertEquals(100, typeface.getWeight());
        assertTrue(typeface.isItalic());

    }

    @Test
    public void testTypefaceCreate_customFont_customWeight() {
        final AssetManager am = mContext.getAssets();
        Typeface typeface = new Builder(am, "ascii_a3em_weight100_upright.ttf")
                .setWeight(400).build();
        assertEquals(400, typeface.getWeight());
        assertFalse(typeface.isItalic());

        typeface = new Builder(am, "ascii_b3em_weight100_italic.ttf").setWeight(400).build();
        assertEquals(400, typeface.getWeight());
        assertTrue(typeface.isItalic());
    }

    @Test
    public void testTypefaceCreate_customFont_customItalic() {
        final AssetManager am = mContext.getAssets();

        Typeface typeface = new Builder(am, "ascii_a3em_weight100_upright.ttf")
                .setItalic(true).build();
        assertEquals(100, typeface.getWeight());
        assertTrue(typeface.isItalic());

        typeface = new Builder(am, "ascii_b3em_weight100_italic.ttf").setItalic(false).build();
        assertEquals(100, typeface.getWeight());
        assertFalse(typeface.isItalic());
    }
}
