Skip to content

Commit

Permalink
Fallback font match caching to fix emoji lag. (flutter#7208)
Browse files Browse the repository at this point in the history
  • Loading branch information
GaryQian authored Dec 13, 2018
1 parent 18a4e33 commit eff5e67
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 1 deletion.
17 changes: 16 additions & 1 deletion third_party/txt/src/txt/font_collection.cc
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,22 @@ std::shared_ptr<minikin::FontFamily> FontCollection::CreateMinikinFontFamily(
const std::shared_ptr<minikin::FontFamily>& 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<minikin::FontFamily>* match =
&DoMatchFallbackFont(ch, locale);
fallback_match_cache_.insert(std::make_pair(ch, match));
return *match;
}

const std::shared_ptr<minikin::FontFamily>& FontCollection::DoMatchFallbackFont(
uint32_t ch,
std::string locale) {
for (const sk_sp<SkFontMgr>& manager : GetFontManagerOrder()) {
std::vector<const char*> bcp47;
if (!locale.empty())
Expand All @@ -219,7 +235,6 @@ const std::shared_ptr<minikin::FontFamily>& FontCollection::MatchFallbackFont(

return GetFallbackFontFamily(manager, family_name);
}

return g_null_family;
}

Expand Down
12 changes: 12 additions & 0 deletions third_party/txt/src/txt/font_collection.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ class FontCollection : public std::enable_shared_from_this<FontCollection> {
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<minikin::FontFamily>& MatchFallbackFont(
uint32_t ch,
std::string locale);
Expand Down Expand Up @@ -80,12 +82,22 @@ class FontCollection : public std::enable_shared_from_this<FontCollection> {
std::shared_ptr<minikin::FontCollection>,
FamilyKey::Hasher>
font_collections_cache_;
// Cache that stores the results of MatchFallbackFont to ensure lag-free emoji
// font fallback matching.
std::unordered_map<uint32_t, const std::shared_ptr<minikin::FontFamily>*>
fallback_match_cache_;
std::unordered_map<std::string, std::shared_ptr<minikin::FontFamily>>
fallback_fonts_;
std::unordered_map<std::string, std::set<std::string>>
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<minikin::FontFamily>& DoMatchFallbackFont(
uint32_t ch,
std::string locale);

std::vector<sk_sp<SkFontMgr>> GetFontManagerOrder() const;

std::shared_ptr<minikin::FontFamily> CreateMinikinFontFamily(
Expand Down

0 comments on commit eff5e67

Please sign in to comment.