/*
 * Copyright (C) 2017 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.
 */

#include <gtest/gtest.h>

#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <utils/Log.h>

#include "SkFontMgr.h"
#include "SkStream.h"

#include "hwui/MinikinSkia.h"
#include "hwui/Typeface.h"

using namespace android;

namespace {

constexpr char kRobotoRegular[] = "/system/fonts/Roboto-Regular.ttf";
constexpr char kRobotoBold[] = "/system/fonts/Roboto-Bold.ttf";
constexpr char kRobotoItalic[] = "/system/fonts/Roboto-Italic.ttf";
constexpr char kRobotoBoldItalic[] = "/system/fonts/Roboto-BoldItalic.ttf";

void unmap(const void* ptr, void* context) {
    void* p = const_cast<void*>(ptr);
    size_t len = reinterpret_cast<size_t>(context);
    munmap(p, len);
}

std::shared_ptr<minikin::FontFamily> buildFamily(const char* fileName) {
    int fd = open(fileName, O_RDONLY);
    LOG_ALWAYS_FATAL_IF(fd == -1, "Failed to open file %s", fileName);
    struct stat st = {};
    LOG_ALWAYS_FATAL_IF(fstat(fd, &st) == -1, "Failed to stat file %s", fileName);
    void* data = mmap(nullptr, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
    sk_sp<SkData> skData =
            SkData::MakeWithProc(data, st.st_size, unmap, reinterpret_cast<void*>(st.st_size));
    std::unique_ptr<SkStreamAsset> fontData(new SkMemoryStream(skData));
    sk_sp<SkFontMgr> fm(SkFontMgr::RefDefault());
    sk_sp<SkTypeface> typeface(fm->createFromStream(fontData.release()));
    LOG_ALWAYS_FATAL_IF(typeface == nullptr, "Failed to make typeface from %s", fileName);
    std::shared_ptr<minikin::MinikinFont> font = std::make_shared<MinikinFontSkia>(
            std::move(typeface), data, st.st_size, 0, std::vector<minikin::FontVariation>());
    return std::make_shared<minikin::FontFamily>(
            std::vector<minikin::Font>({ minikin::Font(std::move(font), minikin::FontStyle()) }));
}

std::vector<std::shared_ptr<minikin::FontFamily>> makeSingleFamlyVector(const char* fileName) {
    return std::vector<std::shared_ptr<minikin::FontFamily>>({ buildFamily(fileName) });
}

TEST(TypefaceTest, resolveDefault_and_setDefaultTest) {
    std::unique_ptr<Typeface> regular(
            Typeface::createFromFamilies(makeSingleFamlyVector(kRobotoRegular),
                    RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE));
    EXPECT_EQ(regular.get(), Typeface::resolveDefault(regular.get()));

    // Keep the original to restore it later.
    const Typeface* old = Typeface::resolveDefault(nullptr);
    ASSERT_NE(nullptr, old);

    Typeface::setDefault(regular.get());
    EXPECT_EQ(regular.get(), Typeface::resolveDefault(nullptr));

    Typeface::setDefault(old);  // Restore to the original.
}

TEST(TypefaceTest, createWithDifferentBaseWeight) {
    std::unique_ptr<Typeface> bold(Typeface::createWithDifferentBaseWeight(nullptr, 700));
    EXPECT_EQ(7, bold->fStyle.getWeight());
    EXPECT_FALSE(bold->fStyle.getItalic());
    EXPECT_EQ(SkTypeface::kNormal, bold->fSkiaStyle);

    std::unique_ptr<Typeface> light(Typeface::createWithDifferentBaseWeight(nullptr, 300));
    EXPECT_EQ(3, light->fStyle.getWeight());
    EXPECT_FALSE(light->fStyle.getItalic());
    EXPECT_EQ(SkTypeface::kNormal, light->fSkiaStyle);
}

TEST(TypefaceTest, createRelativeTest_fromRegular) {
    // In Java, Typeface.create(Typeface.DEFAULT, Typeface.NORMAL);
    std::unique_ptr<Typeface> normal(Typeface::createRelative(nullptr, SkTypeface::kNormal));
    EXPECT_EQ(4, normal->fStyle.getWeight());
    EXPECT_FALSE(normal->fStyle.getItalic());
    EXPECT_EQ(SkTypeface::kNormal, normal->fSkiaStyle);

    // In Java, Typeface.create(Typeface.DEFAULT, Typeface.BOLD);
    std::unique_ptr<Typeface> bold(Typeface::createRelative(nullptr, SkTypeface::kBold));
    EXPECT_EQ(7, bold->fStyle.getWeight());
    EXPECT_FALSE(bold->fStyle.getItalic());
    EXPECT_EQ(SkTypeface::kBold, bold->fSkiaStyle);

    // In Java, Typeface.create(Typeface.DEFAULT, Typeface.ITALIC);
    std::unique_ptr<Typeface> italic(Typeface::createRelative(nullptr, SkTypeface::kItalic));
    EXPECT_EQ(4, italic->fStyle.getWeight());
    EXPECT_TRUE(italic->fStyle.getItalic());
    EXPECT_EQ(SkTypeface::kItalic, italic->fSkiaStyle);

    // In Java, Typeface.create(Typeface.DEFAULT, Typeface.BOLD_ITALIC);
    std::unique_ptr<Typeface> boldItalic(
            Typeface::createRelative(nullptr, SkTypeface::kBoldItalic));
    EXPECT_EQ(7, boldItalic->fStyle.getWeight());
    EXPECT_TRUE(boldItalic->fStyle.getItalic());
    EXPECT_EQ(SkTypeface::kBoldItalic, boldItalic->fSkiaStyle);
}

TEST(TypefaceTest, createRelativeTest_BoldBase) {
    std::unique_ptr<Typeface> base(Typeface::createWithDifferentBaseWeight(nullptr, 700));

    // In Java, Typeface.create(Typeface.create("sans-serif-bold"), Typeface.NORMAL);
    std::unique_ptr<Typeface> normal(Typeface::createRelative(base.get(), SkTypeface::kNormal));
    EXPECT_EQ(7, normal->fStyle.getWeight());
    EXPECT_FALSE(normal->fStyle.getItalic());
    EXPECT_EQ(SkTypeface::kNormal, normal->fSkiaStyle);

    // In Java, Typeface.create(Typeface.create("sans-serif-bold"), Typeface.BOLD);
    std::unique_ptr<Typeface> bold(Typeface::createRelative(base.get(), SkTypeface::kBold));
    EXPECT_EQ(10, bold->fStyle.getWeight());
    EXPECT_FALSE(bold->fStyle.getItalic());
    EXPECT_EQ(SkTypeface::kBold, bold->fSkiaStyle);

    // In Java, Typeface.create(Typeface.create("sans-serif-bold"), Typeface.ITALIC);
    std::unique_ptr<Typeface> italic(Typeface::createRelative(base.get(), SkTypeface::kItalic));
    EXPECT_EQ(7, italic->fStyle.getWeight());
    EXPECT_TRUE(italic->fStyle.getItalic());
    EXPECT_EQ(SkTypeface::kItalic, italic->fSkiaStyle);

    // In Java, Typeface.create(Typeface.create("sans-serif-bold"), Typeface.BOLD_ITALIC);
    std::unique_ptr<Typeface>
            boldItalic(Typeface::createRelative(base.get(), SkTypeface::kBoldItalic));
    EXPECT_EQ(10, boldItalic->fStyle.getWeight());
    EXPECT_TRUE(boldItalic->fStyle.getItalic());
    EXPECT_EQ(SkTypeface::kBoldItalic, boldItalic->fSkiaStyle);
}

TEST(TypefaceTest, createRelativeTest_LightBase) {
    std::unique_ptr<Typeface> base(Typeface::createWithDifferentBaseWeight(nullptr, 300));

    // In Java, Typeface.create(Typeface.create("sans-serif-light"), Typeface.NORMAL);
    std::unique_ptr<Typeface> normal(Typeface::createRelative(base.get(), SkTypeface::kNormal));
    EXPECT_EQ(3, normal->fStyle.getWeight());
    EXPECT_FALSE(normal->fStyle.getItalic());
    EXPECT_EQ(SkTypeface::kNormal, normal->fSkiaStyle);

    // In Java, Typeface.create(Typeface.create("sans-serif-light"), Typeface.BOLD);
    std::unique_ptr<Typeface> bold(Typeface::createRelative(base.get(), SkTypeface::kBold));
    EXPECT_EQ(6, bold->fStyle.getWeight());
    EXPECT_FALSE(bold->fStyle.getItalic());
    EXPECT_EQ(SkTypeface::kBold, bold->fSkiaStyle);

    // In Java, Typeface.create(Typeface.create("sans-serif-light"), Typeface.ITLIC);
    std::unique_ptr<Typeface> italic(Typeface::createRelative(base.get(), SkTypeface::kItalic));
    EXPECT_EQ(3, italic->fStyle.getWeight());
    EXPECT_TRUE(italic->fStyle.getItalic());
    EXPECT_EQ(SkTypeface::kItalic, italic->fSkiaStyle);

    // In Java, Typeface.create(Typeface.create("sans-serif-light"), Typeface.BOLD_ITALIC);
    std::unique_ptr<Typeface>
            boldItalic(Typeface::createRelative(base.get(), SkTypeface::kBoldItalic));
    EXPECT_EQ(6, boldItalic->fStyle.getWeight());
    EXPECT_TRUE(boldItalic->fStyle.getItalic());
    EXPECT_EQ(SkTypeface::kBoldItalic, boldItalic->fSkiaStyle);
}

TEST(TypefaceTest, createRelativeTest_fromBoldStyled) {
    std::unique_ptr<Typeface> base(Typeface::createRelative(nullptr, SkTypeface::kBold));

    // In Java, Typeface.create(Typeface.create(Typeface.DEFAULT, Typeface.BOLD), Typeface.NORMAL);
    std::unique_ptr<Typeface> normal(Typeface::createRelative(base.get(), SkTypeface::kNormal));
    EXPECT_EQ(4, normal->fStyle.getWeight());
    EXPECT_FALSE(normal->fStyle.getItalic());
    EXPECT_EQ(SkTypeface::kNormal, normal->fSkiaStyle);

    // In Java Typeface.create(Typeface.create(Typeface.DEFAULT, Typeface.BOLD), Typeface.BOLD);
    std::unique_ptr<Typeface> bold(Typeface::createRelative(base.get(), SkTypeface::kBold));
    EXPECT_EQ(7, bold->fStyle.getWeight());
    EXPECT_FALSE(bold->fStyle.getItalic());
    EXPECT_EQ(SkTypeface::kBold, bold->fSkiaStyle);

    // In Java, Typeface.create(Typeface.create(Typeface.DEFAULT, Typeface.BOLD), Typeface.ITALIC);
    std::unique_ptr<Typeface> italic(Typeface::createRelative(base.get(), SkTypeface::kItalic));
    EXPECT_EQ(4, normal->fStyle.getWeight());
    EXPECT_TRUE(italic->fStyle.getItalic());
    EXPECT_EQ(SkTypeface::kItalic, italic->fSkiaStyle);

    // In Java,
    // Typeface.create(Typeface.create(Typeface.DEFAULT, Typeface.BOLD), Typeface.BOLD_ITALIC);
    std::unique_ptr<Typeface>
            boldItalic(Typeface::createRelative(base.get(), SkTypeface::kBoldItalic));
    EXPECT_EQ(7, boldItalic->fStyle.getWeight());
    EXPECT_TRUE(boldItalic->fStyle.getItalic());
    EXPECT_EQ(SkTypeface::kBoldItalic, boldItalic->fSkiaStyle);
}

TEST(TypefaceTest, createRelativeTest_fromItalicStyled) {
    std::unique_ptr<Typeface> base(Typeface::createRelative(nullptr, SkTypeface::kItalic));

    // In Java,
    // Typeface.create(Typeface.create(Typeface.DEFAULT, Typeface.ITALIC), Typeface.NORMAL);
    std::unique_ptr<Typeface> normal(Typeface::createRelative(base.get(), SkTypeface::kNormal));
    EXPECT_EQ(4, normal->fStyle.getWeight());
    EXPECT_FALSE(normal->fStyle.getItalic());
    EXPECT_EQ(SkTypeface::kNormal, normal->fSkiaStyle);

    // In Java, Typeface.create(Typeface.create(Typeface.DEFAULT, Typeface.ITALIC), Typeface.BOLD);
    std::unique_ptr<Typeface> bold(Typeface::createRelative(base.get(), SkTypeface::kBold));
    EXPECT_EQ(7, bold->fStyle.getWeight());
    EXPECT_FALSE(bold->fStyle.getItalic());
    EXPECT_EQ(SkTypeface::kBold, bold->fSkiaStyle);

    // In Java,
    // Typeface.create(Typeface.create(Typeface.DEFAULT, Typeface.ITALIC), Typeface.ITALIC);
    std::unique_ptr<Typeface> italic(Typeface::createRelative(base.get(), SkTypeface::kItalic));
    EXPECT_EQ(4, italic->fStyle.getWeight());
    EXPECT_TRUE(italic->fStyle.getItalic());
    EXPECT_EQ(SkTypeface::kItalic, italic->fSkiaStyle);

    // In Java,
    // Typeface.create(Typeface.create(Typeface.DEFAULT, Typeface.ITALIC), Typeface.BOLD_ITALIC);
    std::unique_ptr<Typeface>
            boldItalic(Typeface::createRelative(base.get(), SkTypeface::kBoldItalic));
    EXPECT_EQ(7, boldItalic->fStyle.getWeight());
    EXPECT_TRUE(boldItalic->fStyle.getItalic());
    EXPECT_EQ(SkTypeface::kBoldItalic, boldItalic->fSkiaStyle);
}

TEST(TypefaceTest, createRelativeTest_fromSpecifiedStyled) {
    std::unique_ptr<Typeface> base(Typeface::createAbsolute(nullptr, 400, false));

    // In Java,
    // Typeface typeface = new Typeface.Builder(invalid).setFallback("sans-serif")
    //     .setWeight(700).setItalic(false).build();
    // Typeface.create(typeface, Typeface.NORMAL);
    std::unique_ptr<Typeface> normal(Typeface::createRelative(base.get(), SkTypeface::kNormal));
    EXPECT_EQ(4, normal->fStyle.getWeight());
    EXPECT_FALSE(normal->fStyle.getItalic());
    EXPECT_EQ(SkTypeface::kNormal, normal->fSkiaStyle);

    // In Java,
    // Typeface typeface = new Typeface.Builder(invalid).setFallback("sans-serif")
    //     .setWeight(700).setItalic(false).build();
    // Typeface.create(typeface, Typeface.BOLD);
    std::unique_ptr<Typeface> bold(Typeface::createRelative(base.get(), SkTypeface::kBold));
    EXPECT_EQ(7, bold->fStyle.getWeight());
    EXPECT_FALSE(bold->fStyle.getItalic());
    EXPECT_EQ(SkTypeface::kBold, bold->fSkiaStyle);

    // In Java,
    // Typeface typeface = new Typeface.Builder(invalid).setFallback("sans-serif")
    //     .setWeight(700).setItalic(false).build();
    // Typeface.create(typeface, Typeface.ITALIC);
    std::unique_ptr<Typeface> italic(Typeface::createRelative(base.get(), SkTypeface::kItalic));
    EXPECT_EQ(4, italic->fStyle.getWeight());
    EXPECT_TRUE(italic->fStyle.getItalic());
    EXPECT_EQ(SkTypeface::kItalic, italic->fSkiaStyle);

    // In Java,
    // Typeface typeface = new Typeface.Builder(invalid).setFallback("sans-serif")
    //     .setWeight(700).setItalic(false).build();
    // Typeface.create(typeface, Typeface.BOLD_ITALIC);
    std::unique_ptr<Typeface>
            boldItalic(Typeface::createRelative(base.get(), SkTypeface::kBoldItalic));
    EXPECT_EQ(7, boldItalic->fStyle.getWeight());
    EXPECT_TRUE(boldItalic->fStyle.getItalic());
    EXPECT_EQ(SkTypeface::kBoldItalic, boldItalic->fSkiaStyle);
}

TEST(TypefaceTest, createAbsolute) {
    // In Java,
    // new Typeface.Builder(invalid).setFallback("sans-serif").setWeight(400).setItalic(false)
    //     .build();
    std::unique_ptr<Typeface> regular(Typeface::createAbsolute(nullptr, 400, false));
    EXPECT_EQ(4, regular->fStyle.getWeight());
    EXPECT_FALSE(regular->fStyle.getItalic());
    EXPECT_EQ(SkTypeface::kNormal, regular->fSkiaStyle);

    // In Java,
    // new Typeface.Builder(invalid).setFallback("sans-serif").setWeight(700).setItalic(false)
    //     .build();
    std::unique_ptr<Typeface> bold(Typeface::createAbsolute(nullptr, 700, false));
    EXPECT_EQ(7, bold->fStyle.getWeight());
    EXPECT_FALSE(bold->fStyle.getItalic());
    EXPECT_EQ(SkTypeface::kBold, bold->fSkiaStyle);

    // In Java,
    // new Typeface.Builder(invalid).setFallback("sans-serif").setWeight(400).setItalic(true)
    //     .build();
    std::unique_ptr<Typeface> italic(Typeface::createAbsolute(nullptr, 400, true));
    EXPECT_EQ(4, italic->fStyle.getWeight());
    EXPECT_TRUE(italic->fStyle.getItalic());
    EXPECT_EQ(SkTypeface::kItalic, italic->fSkiaStyle);

    // In Java,
    // new Typeface.Builder(invalid).setFallback("sans-serif").setWeight(700).setItalic(true)
    //     .build();
    std::unique_ptr<Typeface> boldItalic(Typeface::createAbsolute(nullptr, 700, true));
    EXPECT_EQ(7, boldItalic->fStyle.getWeight());
    EXPECT_TRUE(boldItalic->fStyle.getItalic());
    EXPECT_EQ(SkTypeface::kBoldItalic, boldItalic->fSkiaStyle);

    // In Java,
    // new Typeface.Builder(invalid).setFallback("sans-serif").setWeight(1100).setItalic(true)
    //     .build();
    std::unique_ptr<Typeface> over1000(Typeface::createAbsolute(nullptr, 1100, false));
    EXPECT_EQ(10, over1000->fStyle.getWeight());
    EXPECT_FALSE(over1000->fStyle.getItalic());
    EXPECT_EQ(SkTypeface::kBold, over1000->fSkiaStyle);
}

TEST(TypefaceTest, createFromFamilies_Single) {
    // In Java, new Typeface.Builder("Roboto-Regular.ttf").setWeight(400).setItalic(false).build();
    std::unique_ptr<Typeface> regular(
            Typeface::createFromFamilies(makeSingleFamlyVector(kRobotoRegular), 400, false));
    EXPECT_EQ(4, regular->fStyle.getWeight());
    EXPECT_FALSE(regular->fStyle.getItalic());
    EXPECT_EQ(SkTypeface::kNormal, regular->fSkiaStyle);

    // In Java, new Typeface.Builder("Roboto-Bold.ttf").setWeight(700).setItalic(false).build();
    std::unique_ptr<Typeface> bold(
            Typeface::createFromFamilies(makeSingleFamlyVector(kRobotoBold), 700, false));
    EXPECT_EQ(7, bold->fStyle.getWeight());
    EXPECT_FALSE(bold->fStyle.getItalic());
    EXPECT_EQ(SkTypeface::kBold, bold->fSkiaStyle);

    // In Java, new Typeface.Builder("Roboto-Italic.ttf").setWeight(400).setItalic(true).build();
    std::unique_ptr<Typeface> italic(
            Typeface::createFromFamilies(makeSingleFamlyVector(kRobotoItalic), 400, true));
    EXPECT_EQ(4, italic->fStyle.getWeight());
    EXPECT_TRUE(italic->fStyle.getItalic());
    EXPECT_EQ(SkTypeface::kItalic, italic->fSkiaStyle);

    // In Java,
    // new Typeface.Builder("Roboto-BoldItalic.ttf").setWeight(700).setItalic(true).build();
    std::unique_ptr<Typeface> boldItalic(
            Typeface::createFromFamilies(makeSingleFamlyVector(kRobotoBoldItalic), 700, true));
    EXPECT_EQ(7, boldItalic->fStyle.getWeight());
    EXPECT_TRUE(boldItalic->fStyle.getItalic());
    EXPECT_EQ(SkTypeface::kItalic, italic->fSkiaStyle);

    // In Java,
    // new Typeface.Builder("Roboto-BoldItalic.ttf").setWeight(1100).setItalic(false).build();
    std::unique_ptr<Typeface> over1000(
            Typeface::createFromFamilies(makeSingleFamlyVector(kRobotoBold), 1100, false));
    EXPECT_EQ(10, over1000->fStyle.getWeight());
    EXPECT_FALSE(over1000->fStyle.getItalic());
    EXPECT_EQ(SkTypeface::kBold, over1000->fSkiaStyle);
}

TEST(TypefaceTest, createFromFamilies_Single_resolveByTable) {
    // In Java, new Typeface.Builder("Roboto-Regular.ttf").build();
    std::unique_ptr<Typeface> regular(
            Typeface::createFromFamilies(makeSingleFamlyVector(kRobotoRegular),
                    RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE));
    EXPECT_EQ(4, regular->fStyle.getWeight());
    EXPECT_FALSE(regular->fStyle.getItalic());
    EXPECT_EQ(SkTypeface::kNormal, regular->fSkiaStyle);

    // In Java, new Typeface.Builder("Roboto-Bold.ttf").build();
    std::unique_ptr<Typeface> bold(
            Typeface::createFromFamilies(makeSingleFamlyVector(kRobotoBold),
                    RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE));
    EXPECT_EQ(7, bold->fStyle.getWeight());
    EXPECT_FALSE(bold->fStyle.getItalic());
    EXPECT_EQ(SkTypeface::kBold, bold->fSkiaStyle);

    // In Java, new Typeface.Builder("Roboto-Italic.ttf").build();
    std::unique_ptr<Typeface> italic(
            Typeface::createFromFamilies(makeSingleFamlyVector(kRobotoItalic),
                    RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE));
    EXPECT_EQ(4, italic->fStyle.getWeight());
    EXPECT_TRUE(italic->fStyle.getItalic());
    EXPECT_EQ(SkTypeface::kItalic, italic->fSkiaStyle);

    // In Java, new Typeface.Builder("Roboto-BoldItalic.ttf").build();
    std::unique_ptr<Typeface> boldItalic(
            Typeface::createFromFamilies(makeSingleFamlyVector(kRobotoBoldItalic),
                    RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE));
    EXPECT_EQ(7, boldItalic->fStyle.getWeight());
    EXPECT_TRUE(boldItalic->fStyle.getItalic());
    EXPECT_EQ(SkTypeface::kItalic, italic->fSkiaStyle);
}

TEST(TypefaceTest, createFromFamilies_Family) {
    std::vector<std::shared_ptr<minikin::FontFamily>> families = {
            buildFamily(kRobotoRegular), buildFamily(kRobotoBold), buildFamily(kRobotoItalic),
            buildFamily(kRobotoBoldItalic)
    };
    std::unique_ptr<Typeface> typeface(Typeface::createFromFamilies(std::move(families),
                    RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE));
    EXPECT_EQ(4, typeface->fStyle.getWeight());
    EXPECT_FALSE(typeface->fStyle.getItalic());
}

TEST(TypefaceTest, createFromFamilies_Family_withoutRegular) {
    std::vector<std::shared_ptr<minikin::FontFamily>> families = {
            buildFamily(kRobotoBold), buildFamily(kRobotoItalic), buildFamily(kRobotoBoldItalic)
    };
    std::unique_ptr<Typeface> typeface(Typeface::createFromFamilies(std::move(families),
                    RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE));
    EXPECT_EQ(7, typeface->fStyle.getWeight());
    EXPECT_FALSE(typeface->fStyle.getItalic());
}

}  // namespace
