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 @@ ...@@ -65,6 +65,11 @@
namespace blink { 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; SkFontMgr* FontCache::static_font_manager_ = nullptr;
#if defined(OS_LINUX) || defined(OS_CHROMEOS) #if defined(OS_LINUX) || defined(OS_CHROMEOS)
...@@ -461,4 +466,26 @@ sk_sp<SkTypeface> FontCache::CreateTypefaceFromUniqueName( ...@@ -461,4 +466,26 @@ sk_sp<SkTypeface> FontCache::CreateTypefaceFromUniqueName(
return nullptr; 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 } // namespace blink
...@@ -246,6 +246,11 @@ class PLATFORM_EXPORT FontCache { ...@@ -246,6 +246,11 @@ class PLATFORM_EXPORT FontCache {
~FontCache() = default; ~FontCache() = default;
private: 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( scoped_refptr<SimpleFontData> PlatformFallbackFontForCharacter(
const FontDescription&, const FontDescription&,
UChar32, UChar32,
...@@ -255,6 +260,10 @@ class PLATFORM_EXPORT FontCache { ...@@ -255,6 +260,10 @@ class PLATFORM_EXPORT FontCache {
const FontFaceCreationParams& creation_params, const FontFaceCreationParams& creation_params,
CString& name); CString& name);
static Bcp47Vector GetBcp47LocaleForRequest(
const FontDescription& font_description,
FontFallbackPriority fallback_priority);
friend class FontGlobalContext; friend class FontGlobalContext;
FontCache(); FontCache();
...@@ -292,14 +301,15 @@ class PLATFORM_EXPORT FontCache { ...@@ -292,14 +301,15 @@ class PLATFORM_EXPORT FontCache {
const FontFaceCreationParams&, const FontFaceCreationParams&,
CString& name); CString& name);
#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_FUCHSIA) #if defined(OS_ANDROID) || defined(OS_LINUX)
static AtomicString GetFamilyNameForCharacter(SkFontMgr*, static AtomicString GetFamilyNameForCharacter(SkFontMgr*,
UChar32, UChar32,
const FontDescription&, const FontDescription&,
FontFallbackPriority); FontFallbackPriority);
#endif // defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_FUCHSIA) #endif // defined(OS_ANDROID) || defined(OS_LINUX)
scoped_refptr<SimpleFontData> FallbackOnStandardFontStyle(const FontDescription&, scoped_refptr<SimpleFontData> FallbackOnStandardFontStyle(
const FontDescription&,
UChar32); UChar32);
// Don't purge if this count is > 0; // Don't purge if this count is > 0;
......
...@@ -46,18 +46,29 @@ void FontCache::SetSystemFontFamily(const AtomicString& family_name) { ...@@ -46,18 +46,29 @@ void FontCache::SetSystemFontFamily(const AtomicString& family_name) {
scoped_refptr<SimpleFontData> FontCache::PlatformFallbackFontForCharacter( scoped_refptr<SimpleFontData> FontCache::PlatformFallbackFontForCharacter(
const FontDescription& font_description, const FontDescription& font_description,
UChar32 c, UChar32 character,
const SimpleFontData* font_data_to_substitute, const SimpleFontData* font_data_to_substitute,
FontFallbackPriority fallback_priority) { FontFallbackPriority fallback_priority) {
sk_sp<SkFontMgr> font_mgr(SkFontMgr::RefDefault()); sk_sp<SkFontMgr> font_mgr(SkFontMgr::RefDefault());
AtomicString family_name = GetFamilyNameForCharacter( CString family_name = font_description.Family().Family().Utf8();
font_mgr.get(), c, font_description, fallback_priority); Bcp47Vector locales =
if (family_name.IsEmpty()) GetBcp47LocaleForRequest(font_description, fallback_priority);
return GetLastResortFallbackFont(font_description, kDoNotRetain); sk_sp<SkTypeface> typeface(font_mgr->matchFamilyStyleCharacter(
return FontDataFromFontPlatformData( family_name.data(), font_description.SkiaFontStyle(), locales.data(),
GetFontPlatformData(font_description, locales.size(), character));
FontFaceCreationParams(family_name)), if (!typeface)
kDoNotRetain); 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 } // namespace blink
...@@ -60,13 +60,7 @@ AtomicString ToAtomicString(const SkString& str) { ...@@ -60,13 +60,7 @@ AtomicString ToAtomicString(const SkString& str) {
return AtomicString::FromUTF8(str.c_str(), str.size()); return AtomicString::FromUTF8(str.c_str(), str.size());
} }
#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_FUCHSIA) #if defined(OS_ANDROID) || defined(OS_LINUX)
// 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";
// This function is called on android or when we are emulating android fonts on // This function is called on android or when we are emulating android fonts on
// linux and the embedder has overriden the default fontManager with // linux and the embedder has overriden the default fontManager with
// WebFontRendering::setSkiaFontMgr. // WebFontRendering::setSkiaFontMgr.
...@@ -78,25 +72,10 @@ AtomicString FontCache::GetFamilyNameForCharacter( ...@@ -78,25 +72,10 @@ AtomicString FontCache::GetFamilyNameForCharacter(
FontFallbackPriority fallback_priority) { FontFallbackPriority fallback_priority) {
DCHECK(fm); DCHECK(fm);
const int kMaxLocales = 4; Bcp47Vector locales =
const char* bcp47_locales[kMaxLocales]; GetBcp47LocaleForRequest(font_description, fallback_priority);
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);
sk_sp<SkTypeface> typeface(fm->matchFamilyStyleCharacter( sk_sp<SkTypeface> typeface(fm->matchFamilyStyleCharacter(
nullptr, SkFontStyle(), bcp47_locales, locale_count, c)); nullptr, SkFontStyle(), locales.data(), locales.size(), c));
if (!typeface) if (!typeface)
return g_empty_atom; return g_empty_atom;
...@@ -104,7 +83,7 @@ AtomicString FontCache::GetFamilyNameForCharacter( ...@@ -104,7 +83,7 @@ AtomicString FontCache::GetFamilyNameForCharacter(
typeface->getFamilyName(&skia_family_name); typeface->getFamilyName(&skia_family_name);
return ToAtomicString(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() {} void FontCache::PlatformInit() {}
......
...@@ -197,22 +197,12 @@ scoped_refptr<SimpleFontData> FontCache::PlatformFallbackFontForCharacter( ...@@ -197,22 +197,12 @@ scoped_refptr<SimpleFontData> FontCache::PlatformFallbackFontForCharacter(
} }
if (use_skia_font_fallback_) { 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(); CString family_name = font_description.Family().Family().Utf8();
Bcp47Vector locales =
GetBcp47LocaleForRequest(font_description, fallback_priority);
SkTypeface* typeface = font_manager_->matchFamilyStyleCharacter( SkTypeface* typeface = font_manager_->matchFamilyStyleCharacter(
family_name.data(), font_description.SkiaFontStyle(), &bcp47_locale, family_name.data(), font_description.SkiaFontStyle(), locales.data(),
locale_count, character); locales.size(), character);
if (typeface) { if (typeface) {
SkString skia_family; SkString skia_family;
typeface->getFamilyName(&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