From eff5e67356acbee22375de68007f6cdc294837f7 Mon Sep 17 00:00:00 2001 From: Gary Qian Date: Thu, 13 Dec 2018 10:39:09 -0800 Subject: [PATCH] Fallback font match caching to fix emoji lag. (#7208) --- third_party/txt/src/txt/font_collection.cc | 17 ++++++++++++++++- third_party/txt/src/txt/font_collection.h | 12 ++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/third_party/txt/src/txt/font_collection.cc b/third_party/txt/src/txt/font_collection.cc index 5503e54e03f..71e6a5178e6 100644 --- a/third_party/txt/src/txt/font_collection.cc +++ b/third_party/txt/src/txt/font_collection.cc @@ -202,6 +202,22 @@ std::shared_ptr FontCollection::CreateMinikinFontFamily( const std::shared_ptr& FontCollection::MatchFallbackFont( uint32_t ch, std::string locale) { + // Check if the ch's matched font has been cached. We cache the results of + // this method as repeated matchFamilyStyleCharacter calls can become + // extremely laggy when typing a large number of complex emojis. + auto lookup = fallback_match_cache_.find(ch); + if (lookup != fallback_match_cache_.end()) { + return *lookup->second; + } + const std::shared_ptr* match = + &DoMatchFallbackFont(ch, locale); + fallback_match_cache_.insert(std::make_pair(ch, match)); + return *match; +} + +const std::shared_ptr& FontCollection::DoMatchFallbackFont( + uint32_t ch, + std::string locale) { for (const sk_sp& manager : GetFontManagerOrder()) { std::vector bcp47; if (!locale.empty()) @@ -219,7 +235,6 @@ const std::shared_ptr& FontCollection::MatchFallbackFont( return GetFallbackFontFamily(manager, family_name); } - return g_null_family; } diff --git a/third_party/txt/src/txt/font_collection.h b/third_party/txt/src/txt/font_collection.h index d512a6dd3ae..e3dfaa8d007 100644 --- a/third_party/txt/src/txt/font_collection.h +++ b/third_party/txt/src/txt/font_collection.h @@ -49,6 +49,8 @@ class FontCollection : public std::enable_shared_from_this { const std::string& family, const std::string& locale); + // Provides a FontFamily that contains glyphs for ch. This caches previously + // matched fonts. Also see FontCollection::DoMatchFallbackFont. const std::shared_ptr& MatchFallbackFont( uint32_t ch, std::string locale); @@ -80,12 +82,22 @@ class FontCollection : public std::enable_shared_from_this { std::shared_ptr, FamilyKey::Hasher> font_collections_cache_; + // Cache that stores the results of MatchFallbackFont to ensure lag-free emoji + // font fallback matching. + std::unordered_map*> + fallback_match_cache_; std::unordered_map> fallback_fonts_; std::unordered_map> fallback_fonts_for_locale_; bool enable_font_fallback_; + // Performs the actual work of MatchFallbackFont. The result is cached in + // fallback_match_cache_. + const std::shared_ptr& DoMatchFallbackFont( + uint32_t ch, + std::string locale); + std::vector> GetFontManagerOrder() const; std::shared_ptr CreateMinikinFontFamily(