blob: 917f0111235ebc9e1f487f3a51b5f5d7203bf7cc [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// 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/win/fallback_family_style_cache_win.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/platform/wtf/text/character_names.h"
#include "third_party/blink/renderer/platform/wtf/text/string_hash.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/skia/include/core/SkFontMgr.h"
#include "third_party/skia/include/core/SkRefCnt.h"
#include "third_party/skia/include/core/SkTypeface.h"
namespace {
const char kHanSimplifiedLocale[] = "zh-Hans";
const size_t kLruCacheTestSize = 5;
const char kFontFamilyNameArial[] = "Arial";
const UChar32 kFirstCJKIdeograph = 0x4E00;
const UChar32 kSecondCJKIdeograph = kFirstCJKIdeograph + 1;
sk_sp<SkTypeface> fallbackForLocale(String locale, UChar32 codepoint) {
sk_sp<SkFontMgr> font_mgr = SkFontMgr::RefDefault();
std::string locale_string(locale.Ascii());
const char* locale_char = locale_string.c_str();
return sk_sp<SkTypeface>(font_mgr->matchFamilyStyleCharacter(
kFontFamilyNameArial, SkFontStyle(), &locale_char, 1, codepoint));
}
void fillCacheWithDummies(blink::FallbackLruCache& lru_cache,
const char* format_string,
size_t count) {
for (size_t i = 0; i < count; ++i) {
blink::TypefaceVector dummy_typefaces;
dummy_typefaces.push_back(
SkTypeface::MakeFromName(kFontFamilyNameArial, SkFontStyle()));
lru_cache.Put(String::Format(format_string, i), std::move(dummy_typefaces));
}
}
} // namespace
namespace blink {
TEST(FallbackLruCacheTest, KeepChineseWhenFetched) {
// Put a Chinese font in the cache, add size - 1 more dummy fallback fonts so
// that the cache is full. Get() and verify typeface for Chinese to move them
// up to the top of the cache. Then fill again with size - 1 items and verify
// that Chinese is still in the cache. Then fill with # size items to evict
// the Chinese font and ensure it's gone.
FallbackLruCache lru_cache(kLruCacheTestSize);
EXPECT_EQ(lru_cache.size(), 0u);
TypefaceVector fallback_typefaces_zh;
fallback_typefaces_zh.push_back(
fallbackForLocale(kHanSimplifiedLocale, kFirstCJKIdeograph));
lru_cache.Put(kHanSimplifiedLocale, std::move(fallback_typefaces_zh));
EXPECT_EQ(lru_cache.size(), 1u);
fillCacheWithDummies(lru_cache, "dummy_locale_%zu", kLruCacheTestSize - 1);
TypefaceVector* chinese_typefaces = lru_cache.Get(kHanSimplifiedLocale);
EXPECT_TRUE(chinese_typefaces);
EXPECT_TRUE(chinese_typefaces->at(0)->unicharToGlyph(0x4E01));
EXPECT_EQ(lru_cache.size(), kLruCacheTestSize);
fillCacheWithDummies(lru_cache, "dummy_locale_2nd_%zu",
kLruCacheTestSize - 1);
chinese_typefaces = nullptr;
chinese_typefaces = lru_cache.Get(kHanSimplifiedLocale);
EXPECT_TRUE(chinese_typefaces);
EXPECT_EQ(chinese_typefaces->size(), 1u);
EXPECT_TRUE(chinese_typefaces->at(0)->unicharToGlyph(kSecondCJKIdeograph));
EXPECT_EQ(lru_cache.size(), kLruCacheTestSize);
fillCacheWithDummies(lru_cache, "dummy_locale_3rd_%zu", kLruCacheTestSize);
chinese_typefaces = nullptr;
chinese_typefaces = lru_cache.Get(kHanSimplifiedLocale);
EXPECT_FALSE(chinese_typefaces);
EXPECT_EQ(lru_cache.size(), kLruCacheTestSize);
}
TEST(FallbackLruCacheTest, LargeFillAndClear) {
FallbackLruCache lru_cache(kLruCacheTestSize);
EXPECT_EQ(lru_cache.size(), 0u);
fillCacheWithDummies(lru_cache, "dummy_locale_%zu", 1000);
EXPECT_EQ(lru_cache.size(), kLruCacheTestSize);
lru_cache.Clear();
EXPECT_EQ(lru_cache.size(), 0u);
}
TEST(FallbackLruCacheTest, KeyOverride) {
FallbackLruCache lru_cache(kLruCacheTestSize);
EXPECT_EQ(lru_cache.size(), 0u);
fillCacheWithDummies(lru_cache, "same_locale", 10);
EXPECT_EQ(lru_cache.size(), 1u);
}
} // namespace blink