Skip to content

Commit

Permalink
libtxt: cache fallback fonts found by a Minikin font collection (flut…
Browse files Browse the repository at this point in the history
…ter#14482)

If a new fallback font is discovered during paragraph layout, the fallback
font cache in txt::FontCollection will use that font in future layouts.

However, that cache is not available if the new fallback font needs to be
used for other characters within the current layout.  This PR adds a cache
to minikin::FontCollection and checks whether fonts in the cache can handle
a character before calling the fallback font provider.

See flutter#13257
  • Loading branch information
jason-simmons authored Dec 13, 2019
1 parent 00cbfd3 commit d6172fd
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 4 deletions.
30 changes: 26 additions & 4 deletions third_party/txt/src/minikin/FontCollection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -302,8 +302,7 @@ const std::shared_ptr<FontFamily>& FontCollection::getFamilyForChar(
// libtxt: check if the fallback font provider can match this character
if (mFallbackFontProvider) {
const std::shared_ptr<FontFamily>& fallback =
mFallbackFontProvider->matchFallbackFont(ch,
GetFontLocale(langListId));
findFallbackFont(ch, vs, langListId);
if (fallback) {
return fallback;
}
Expand Down Expand Up @@ -340,8 +339,7 @@ const std::shared_ptr<FontFamily>& FontCollection::getFamilyForChar(
// libtxt: check if the fallback font provider can match this character
if (mFallbackFontProvider) {
const std::shared_ptr<FontFamily>& fallback =
mFallbackFontProvider->matchFallbackFont(ch,
GetFontLocale(langListId));
findFallbackFont(ch, vs, langListId);
if (fallback) {
return fallback;
}
Expand All @@ -365,6 +363,30 @@ const std::shared_ptr<FontFamily>& FontCollection::getFamilyForChar(
: mFamilies[bestFamilyIndex];
}

const std::shared_ptr<FontFamily>& FontCollection::findFallbackFont(
uint32_t ch,
uint32_t vs,
uint32_t langListId) const {
std::string locale = GetFontLocale(langListId);

const auto it = mCachedFallbackFamilies.find(locale);
if (it != mCachedFallbackFamilies.end()) {
for (const auto& fallbackFamily : it->second) {
if (calcCoverageScore(ch, vs, fallbackFamily)) {
return fallbackFamily;
}
}
}

const std::shared_ptr<FontFamily>& fallback =
mFallbackFontProvider->matchFallbackFont(ch, GetFontLocale(langListId));

if (fallback) {
mCachedFallbackFamilies[locale].push_back(fallback);
}
return fallback;
}

const uint32_t NBSP = 0x00A0;
const uint32_t SOFT_HYPHEN = 0x00AD;
const uint32_t ZWJ = 0x200C;
Expand Down
9 changes: 9 additions & 0 deletions third_party/txt/src/minikin/FontCollection.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#ifndef MINIKIN_FONT_COLLECTION_H
#define MINIKIN_FONT_COLLECTION_H

#include <map>
#include <memory>
#include <unordered_set>
#include <vector>
Expand Down Expand Up @@ -100,6 +101,9 @@ class FontCollection {
uint32_t langListId,
int variant) const;

const std::shared_ptr<FontFamily>&
findFallbackFont(uint32_t ch, uint32_t vs, uint32_t langListId) const;

uint32_t calcFamilyScore(uint32_t ch,
uint32_t vs,
int variant,
Expand Down Expand Up @@ -148,6 +152,11 @@ class FontCollection {

// libtxt extension: Fallback font provider.
std::unique_ptr<FallbackFontProvider> mFallbackFontProvider;

// libtxt extension: Fallback fonts discovered after this font collection
// was constructed.
mutable std::map<std::string, std::vector<std::shared_ptr<FontFamily>>>
mCachedFallbackFamilies;
};

} // namespace minikin
Expand Down

0 comments on commit d6172fd

Please sign in to comment.