chromium/third_party/blink/renderer/platform/fonts/android/font_cache_android_test.cc

// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "third_party/blink/renderer/platform/fonts/font_cache.h"

#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/platform/fonts/simple_font_data.h"

namespace blink {

class FontCacheAndroidTest : public testing::Test {
 protected:
  // Returns a locale-specific `serif` typeface, or `nullptr` if the system
  // does not have a locale-specific `serif`.
  sk_sp<SkTypeface> CreateSerifTypeface(const LayoutLocale* locale) {
    FontCache& font_cache = FontCache::Get();
    FontDescription font_description;
    font_description.SetLocale(locale);
    font_description.SetGenericFamily(FontDescription::kSerifFamily);
    return font_cache.CreateLocaleSpecificTypeface(font_description, "serif");
  }

  FontCachePurgePreventer purge_preventer;
};

TEST_F(FontCacheAndroidTest, FallbackFontForCharacter) {
  // Perform the test for the default font family (kStandardFamily) and the
  // -webkit-body font family (kWebkitBodyFamily) since they behave the same in
  // term of font/glyph selection.
  // TODO(crbug.com/1065468): Remove the test for kWebkitBodyFamily when
  // -webkit-body in unshipped.
  for (FontDescription::GenericFamilyType family_type :
       {FontDescription::kStandardFamily, FontDescription::kWebkitBodyFamily}) {
    // A Latin character in the common locale system font, but not in the
    // Chinese locale-preferred font.
    const UChar32 kTestChar = 228;

    FontDescription font_description;
    font_description.SetLocale(LayoutLocale::Get(AtomicString("zh")));
    ASSERT_EQ(USCRIPT_SIMPLIFIED_HAN, font_description.GetScript());
    font_description.SetGenericFamily(family_type);

    FontCache& font_cache = FontCache::Get();
    const SimpleFontData* font_data =
        font_cache.FallbackFontForCharacter(font_description, kTestChar, 0);
    EXPECT_TRUE(font_data);
  }
}

TEST_F(FontCacheAndroidTest, FallbackFontForCharacterSerif) {
  // Test is valid only if the system has a locale-specific `serif`.
  const LayoutLocale* ja = LayoutLocale::Get(AtomicString("ja"));
  sk_sp<SkTypeface> serif_ja_typeface = CreateSerifTypeface(ja);
  if (!serif_ja_typeface)
    return;

  // When |GenericFamily| set to |kSerifFamily|, it should find the
  // locale-specific serif font.
  FontDescription font_description;
  font_description.SetGenericFamily(FontDescription::kSerifFamily);
  font_description.SetLocale(ja);
  FontCache& font_cache = FontCache::Get();
  const UChar32 kTestChar = 0x4E00;  // U+4E00 CJK UNIFIED IDEOGRAPH-4E00
  const SimpleFontData* font_data =
      font_cache.FallbackFontForCharacter(font_description, kTestChar, nullptr);
  EXPECT_TRUE(font_data);
  EXPECT_EQ(serif_ja_typeface.get(), font_data->PlatformData().Typeface());
}

TEST_F(FontCacheAndroidTest, LocaleSpecificTypeface) {
  // Perform the test for the default font family (kStandardFamily) and the
  // -webkit-body font family (kWebkitBodyFamily) since they behave the same in
  // term of font/glyph selection.
  // TODO(crbug.com/1065468): Remove the test for kWebkitBodyFamily when
  // -webkit-body in unshipped.
  for (FontDescription::GenericFamilyType family_type :
       {FontDescription::kStandardFamily, FontDescription::kWebkitBodyFamily}) {
    // Test is valid only if the system has a locale-specific `serif`.
    const LayoutLocale* ja = LayoutLocale::Get(AtomicString("ja"));
    sk_sp<SkTypeface> serif_ja_typeface = CreateSerifTypeface(ja);
    if (!serif_ja_typeface)
      return;

    // If the system has one, it must be different from the default font.
    FontDescription standard_ja_description;
    standard_ja_description.SetLocale(ja);
    standard_ja_description.SetGenericFamily(family_type);
    std::string name;
    FontCache& font_cache = FontCache::Get();
    sk_sp<SkTypeface> standard_ja_typeface = font_cache.CreateTypeface(
        standard_ja_description, FontFaceCreationParams(), name);
    EXPECT_NE(serif_ja_typeface.get(), standard_ja_typeface.get());
  }
}

// Check non-CJK locales do not create locale-specific typeface.
// TODO(crbug.com/1233315 crbug.com/1237860): Locale-specific serif is supported
// only for CJK until these issues were fixed.
TEST_F(FontCacheAndroidTest, LocaleSpecificTypefaceOnlyForCJK) {
  EXPECT_EQ(CreateSerifTypeface(LayoutLocale::Get(AtomicString("en"))),
            nullptr);
  // We can't test CJK locales return non-nullptr because not all devices on all
  // versions of Android have CJK serif fonts.
}

TEST(FontCacheAndroid, GenericFamilyNameForScript) {
  FontDescription english;
  english.SetLocale(LayoutLocale::Get(AtomicString("en")));
  FontDescription chinese;
  chinese.SetLocale(LayoutLocale::Get(AtomicString("zh")));

  AtomicString fallback("MyGenericFamilyNameFallback");

  font_family_names::Init();
  // For non-CJK, getGenericFamilyNameForScript should return the given
  // generic_family_name_fallback except monospace.
  EXPECT_EQ(fallback,
            FontCache::GetGenericFamilyNameForScript(
                font_family_names::kWebkitStandard, fallback, english));
  EXPECT_EQ(font_family_names::kMonospace,
            FontCache::GetGenericFamilyNameForScript(
                font_family_names::kMonospace, fallback, english));

  // For CJK, getGenericFamilyNameForScript should return CJK fonts except
  // monospace.
  EXPECT_NE(fallback,
            FontCache::GetGenericFamilyNameForScript(
                font_family_names::kWebkitStandard, fallback, chinese));
  EXPECT_EQ(font_family_names::kMonospace,
            FontCache::GetGenericFamilyNameForScript(
                font_family_names::kMonospace, fallback, chinese));
}

}  // namespace blink