Skip to content

Commit

Permalink
Cache resolved typefaces by Unichar + SkFontStyle + locale
Browse files Browse the repository at this point in the history
Bug: skia:9983
Change-Id: I0dbb1cc72b95f896f21b4588a0c935c0dcdf9439
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/275463
Reviewed-by: Ben Wagner <bungeman@google.com>
Commit-Queue: Julia Lavrova <jlavrova@google.com>
  • Loading branch information
Rusino authored and Skia Commit-Bot committed Mar 6, 2020
1 parent 36c81d9 commit 54de2fa
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 8 deletions.
41 changes: 33 additions & 8 deletions modules/skparagraph/src/OneLineShaper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -413,15 +413,27 @@ void OneLineShaper::matchResolvedFonts(const TextStyle& textStyle,
auto unresolvedRange = fUnresolvedBlocks.front().fText;
auto unresolvedText = fParagraph->text(unresolvedRange);
const char* ch = unresolvedText.begin();
// TODO: Make in a global cache for all fallback fonts
std::unordered_set<SkUnichar> tried;
// We have the global cache for all already found typefaces for SkUnichar
// but we still need to keep track of all SkUnichars used in this unresolved block
SkTHashSet<SkUnichar> alreadyTried;
SkUnichar unicode = utf8_next(&ch, unresolvedText.end());
while (true) {
auto typeface = fParagraph->fFontCollection->defaultFallback(
unicode, textStyle.getFontStyle(), textStyle.getLocale());

if (typeface == nullptr) {
return;
sk_sp<SkTypeface> typeface;

// First try to find in in a cache
FontKey fontKey(unicode, textStyle.getFontStyle(), textStyle.getLocale());
auto found = fFallbackFonts.find(fontKey);
if (found != nullptr) {
typeface = *found;
} else {
typeface = fParagraph->fFontCollection->defaultFallback(
unicode, textStyle.getFontStyle(), textStyle.getLocale());

if (typeface == nullptr) {
return;
}
fFallbackFonts.set(fontKey, typeface);
}

auto resolved = visitor(typeface);
Expand All @@ -443,8 +455,9 @@ void OneLineShaper::matchResolvedFonts(const TextStyle& textStyle,
// We can stop here or we can switch to another DIFFERENT codepoint
while (ch != unresolvedText.end()) {
unicode = utf8_next(&ch, unresolvedText.end());
if (tried.find(unicode) == tried.end()) {
tried.emplace(unicode);
auto found = alreadyTried.find(unicode);
if (found == nullptr) {
alreadyTried.add(unicode);
break;
}
}
Expand Down Expand Up @@ -650,5 +663,17 @@ TextRange OneLineShaper::clusteredText(GlyphRange glyphs) {

return { textRange.start, textRange.end };
}

bool OneLineShaper::FontKey::operator==(const OneLineShaper::FontKey& other) const {
return fUnicode == other.fUnicode && fFontStyle == other.fFontStyle && fLocale == other.fLocale;
}

size_t OneLineShaper::FontKey::Hasher::operator()(const OneLineShaper::FontKey& key) const {

return SkGoodHash()(key.fUnicode) ^
SkGoodHash()(key.fFontStyle) ^
SkGoodHash()(key.fLocale.c_str());
}

}
}
19 changes: 19 additions & 0 deletions modules/skparagraph/src/OneLineShaper.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,25 @@ class OneLineShaper : public SkShaper::RunHandler {
std::shared_ptr<Run> fCurrentRun;
std::queue<RunBlock> fUnresolvedBlocks;
std::vector<RunBlock> fResolvedBlocks;

// Keeping all resolved typefaces
struct FontKey {

FontKey() {}

FontKey(SkUnichar unicode, SkFontStyle fontStyle, SkString locale)
: fUnicode(unicode), fFontStyle(fontStyle), fLocale(locale) { }
SkUnichar fUnicode;
SkFontStyle fFontStyle;
SkString fLocale;

bool operator==(const FontKey& other) const;

struct Hasher {
size_t operator()(const FontKey& key) const;
};
};
SkTHashMap<FontKey, sk_sp<SkTypeface>, FontKey::Hasher> fFallbackFonts;
};

}
Expand Down

0 comments on commit 54de2fa

Please sign in to comment.