Commit 57d76b83 authored by Sergey Ulanov's avatar Sergey Ulanov Committed by Commit Bot

[Fuchsia] Avoid redundant IPC in PlatformFallbackFontForCharacter()

Previously PlatformFallbackFontForCharacter() was sending 2 font
provider requests and didn't guarantee that the returned font actually
contain requested character. Rewrote it to fix both issues.

Also added FontCache::GetBcp47LocaleForRequest() and updated all
matchFamilyStyleCharacter() callers to use it.

Bug: 957256
Change-Id: I989c1e0b8fdc46a81d4d58d63ae3f3d02133f357
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1586476Reviewed-by: default avatarDominik Röttsches <drott@chromium.org>
Commit-Queue: Sergey Ulanov <sergeyu@chromium.org>
Auto-Submit: Sergey Ulanov <sergeyu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#657319}
parent 08c174f0
......@@ -65,6 +65,11 @@
namespace blink {
// Special locale for retrieving the color emoji font based on the proposed
// changes in UTR #51 for introducing an Emoji script code:
// https://unicode.org/reports/tr51/#Emoji_Script
static const char kColorEmojiLocale[] = "und-Zsye";
SkFontMgr* FontCache::static_font_manager_ = nullptr;
#if defined(OS_LINUX) || defined(OS_CHROMEOS)
......@@ -461,4 +466,26 @@ sk_sp<SkTypeface> FontCache::CreateTypefaceFromUniqueName(
return nullptr;
}
// static
FontCache::Bcp47Vector FontCache::GetBcp47LocaleForRequest(
const FontDescription& font_description,
FontFallbackPriority fallback_priority) {
Bcp47Vector result;
// Fill in the list of locales in the reverse priority order.
// Skia expects the highest array index to be the first priority.
const LayoutLocale* content_locale = font_description.Locale();
if (const LayoutLocale* han_locale =
LayoutLocale::LocaleForHan(content_locale)) {
result.push_back(han_locale->LocaleForHanForSkFontMgr());
}
result.push_back(LayoutLocale::GetDefault().LocaleForSkFontMgr());
if (content_locale)
result.push_back(content_locale->LocaleForSkFontMgr());
if (fallback_priority == FontFallbackPriority::kEmojiEmoji)
result.push_back(kColorEmojiLocale);
return result;
}
} // namespace blink
......@@ -246,6 +246,11 @@ class PLATFORM_EXPORT FontCache {
~FontCache() = default;
private:
// BCP47 list used when requesting fallback font for a character.
// inlineCapacity is set to 4: the array vector not need to hold more than 4
// elements.
using Bcp47Vector = WTF::Vector<const char*, 4>;
scoped_refptr<SimpleFontData> PlatformFallbackFontForCharacter(
const FontDescription&,
UChar32,
......@@ -255,6 +260,10 @@ class PLATFORM_EXPORT FontCache {
const FontFaceCreationParams& creation_params,
CString& name);
static Bcp47Vector GetBcp47LocaleForRequest(
const FontDescription& font_description,
FontFallbackPriority fallback_priority);
friend class FontGlobalContext;
FontCache();
......@@ -292,15 +301,16 @@ class PLATFORM_EXPORT FontCache {
const FontFaceCreationParams&,
CString& name);
#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_FUCHSIA)
#if defined(OS_ANDROID) || defined(OS_LINUX)
static AtomicString GetFamilyNameForCharacter(SkFontMgr*,
UChar32,
const FontDescription&,
FontFallbackPriority);
#endif // defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_FUCHSIA)
#endif // defined(OS_ANDROID) || defined(OS_LINUX)
scoped_refptr<SimpleFontData> FallbackOnStandardFontStyle(const FontDescription&,
UChar32);
scoped_refptr<SimpleFontData> FallbackOnStandardFontStyle(
const FontDescription&,
UChar32);
// Don't purge if this count is > 0;
int purge_prevent_count_;
......
......@@ -46,18 +46,29 @@ void FontCache::SetSystemFontFamily(const AtomicString& family_name) {
scoped_refptr<SimpleFontData> FontCache::PlatformFallbackFontForCharacter(
const FontDescription& font_description,
UChar32 c,
UChar32 character,
const SimpleFontData* font_data_to_substitute,
FontFallbackPriority fallback_priority) {
sk_sp<SkFontMgr> font_mgr(SkFontMgr::RefDefault());
AtomicString family_name = GetFamilyNameForCharacter(
font_mgr.get(), c, font_description, fallback_priority);
if (family_name.IsEmpty())
return GetLastResortFallbackFont(font_description, kDoNotRetain);
return FontDataFromFontPlatformData(
GetFontPlatformData(font_description,
FontFaceCreationParams(family_name)),
kDoNotRetain);
CString family_name = font_description.Family().Family().Utf8();
Bcp47Vector locales =
GetBcp47LocaleForRequest(font_description, fallback_priority);
sk_sp<SkTypeface> typeface(font_mgr->matchFamilyStyleCharacter(
family_name.data(), font_description.SkiaFontStyle(), locales.data(),
locales.size(), character));
if (!typeface)
return nullptr;
bool synthetic_bold =
font_description.IsSyntheticBold() && !typeface->isBold();
bool synthetic_italic =
font_description.IsSyntheticItalic() && !typeface->isItalic();
auto font_data = std::make_unique<FontPlatformData>(
std::move(typeface), CString(), font_description.EffectiveFontSize(),
synthetic_bold, synthetic_italic, font_description.Orientation());
return FontDataFromFontPlatformData(font_data.get(), kDoNotRetain);
}
} // namespace blink
......@@ -60,13 +60,7 @@ AtomicString ToAtomicString(const SkString& str) {
return AtomicString::FromUTF8(str.c_str(), str.size());
}
#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_FUCHSIA)
// Android special locale for retrieving the color emoji font
// based on the proposed changes in UTR #51 for introducing
// an Emoji script code:
// http://www.unicode.org/reports/tr51/proposed.html#Emoji_Script
static const char kAndroidColorEmojiLocale[] = "und-Zsye";
#if defined(OS_ANDROID) || defined(OS_LINUX)
// This function is called on android or when we are emulating android fonts on
// linux and the embedder has overriden the default fontManager with
// WebFontRendering::setSkiaFontMgr.
......@@ -78,25 +72,10 @@ AtomicString FontCache::GetFamilyNameForCharacter(
FontFallbackPriority fallback_priority) {
DCHECK(fm);
const int kMaxLocales = 4;
const char* bcp47_locales[kMaxLocales];
int locale_count = 0;
// Fill in the list of locales in the reverse priority order.
// Skia expects the highest array index to be the first priority.
const LayoutLocale* content_locale = font_description.Locale();
if (const LayoutLocale* han_locale =
LayoutLocale::LocaleForHan(content_locale))
bcp47_locales[locale_count++] = han_locale->LocaleForHanForSkFontMgr();
bcp47_locales[locale_count++] =
LayoutLocale::GetDefault().LocaleForSkFontMgr();
if (content_locale)
bcp47_locales[locale_count++] = content_locale->LocaleForSkFontMgr();
if (fallback_priority == FontFallbackPriority::kEmojiEmoji)
bcp47_locales[locale_count++] = kAndroidColorEmojiLocale;
SECURITY_DCHECK(locale_count <= kMaxLocales);
Bcp47Vector locales =
GetBcp47LocaleForRequest(font_description, fallback_priority);
sk_sp<SkTypeface> typeface(fm->matchFamilyStyleCharacter(
nullptr, SkFontStyle(), bcp47_locales, locale_count, c));
nullptr, SkFontStyle(), locales.data(), locales.size(), c));
if (!typeface)
return g_empty_atom;
......@@ -104,7 +83,7 @@ AtomicString FontCache::GetFamilyNameForCharacter(
typeface->getFamilyName(&skia_family_name);
return ToAtomicString(skia_family_name);
}
#endif // defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_FUCHSIA)
#endif // defined(OS_ANDROID) || defined(OS_LINUX)
void FontCache::PlatformInit() {}
......
......@@ -197,22 +197,12 @@ scoped_refptr<SimpleFontData> FontCache::PlatformFallbackFontForCharacter(
}
if (use_skia_font_fallback_) {
const char* bcp47_locale = nullptr;
int locale_count = 0;
// If the font description has a locale, use that. Otherwise, Skia will
// fall back on the user's default locale.
// TODO(kulshin): extract locale fallback logic from
// FontCacheAndroid.cpp and share that code
if (font_description.Locale()) {
bcp47_locale = font_description.Locale()->LocaleForSkFontMgr();
locale_count = 1;
}
CString family_name = font_description.Family().Family().Utf8();
Bcp47Vector locales =
GetBcp47LocaleForRequest(font_description, fallback_priority);
SkTypeface* typeface = font_manager_->matchFamilyStyleCharacter(
family_name.data(), font_description.SkiaFontStyle(), &bcp47_locale,
locale_count, character);
family_name.data(), font_description.SkiaFontStyle(), locales.data(),
locales.size(), character);
if (typeface) {
SkString skia_family;
typeface->getFamilyName(&skia_family);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment