blob: 9544a0ed0abbae3205c6ea186d354279e5a8e92a [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 "third_party/blink/renderer/platform/fonts/font_platform_data.h"
namespace blink {
namespace {
const wtf_size_t kMaxCacheSlots = 16;
String makeCacheKey(FontDescription::GenericFamilyType generic_family,
String bcp47_language_tag,
FontFallbackPriority fallback_priority) {
StringBuilder cache_key;
cache_key.Append(bcp47_language_tag);
cache_key.AppendNumber(
static_cast<
std::underlying_type<FontDescription::GenericFamilyType>::type>(
generic_family));
cache_key.AppendNumber(
static_cast<std::underlying_type<FontFallbackPriority>::type>(
fallback_priority));
return cache_key.ToString();
}
void getFallbackFamilyAndStyle(SkTypeface* typeface,
String* fallback_family,
SkFontStyle* fallback_style) {
SkString family;
typeface->getFamilyName(&family);
*fallback_family = family.c_str();
*fallback_style = typeface->fontStyle();
}
} // namespace
FallbackFamilyStyleCache::FallbackFamilyStyleCache()
: recent_fallback_fonts_(kMaxCacheSlots) {}
void FallbackFamilyStyleCache::Put(
FontDescription::GenericFamilyType generic_family,
String bcp47_language_tag,
FontFallbackPriority fallback_priority,
SkTypeface* typeface) {
String cache_key =
makeCacheKey(generic_family, bcp47_language_tag, fallback_priority);
TypefaceVector* existing_typefaces = recent_fallback_fonts_.Get(cache_key);
if (existing_typefaces) {
existing_typefaces->insert(0, sk_ref_sp(typeface));
} else {
TypefaceVector typefaces;
typefaces.push_back(sk_ref_sp(typeface));
recent_fallback_fonts_.Put(std::move(cache_key), std::move(typefaces));
}
}
void FallbackFamilyStyleCache::Get(
FontDescription::GenericFamilyType generic_family,
String bcp47_language_tag,
FontFallbackPriority fallback_priority,
UChar32 character,
String* fallback_family,
SkFontStyle* fallback_style) {
TypefaceVector* typefaces = recent_fallback_fonts_.Get(
makeCacheKey(generic_family, bcp47_language_tag, fallback_priority));
if (!typefaces)
return;
for (wtf_size_t i = 0; i < typefaces->size(); ++i) {
sk_sp<SkTypeface>& typeface = typefaces->at(i);
if (typeface->unicharToGlyph(character)) {
getFallbackFamilyAndStyle(typeface.get(), fallback_family,
fallback_style);
sk_sp<SkTypeface> tmp_typeface(typeface);
// For the vector of typefaces for this specific language tag, since this
// SkTypeface had a glyph, move it to the beginning to accelerate
// subsequent lookups.
typefaces->EraseAt(i);
typefaces->insert(0, std::move(tmp_typeface));
return;
}
}
}
} // namespace blink