Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 433ca7c

Browse files
committed
libtxt: cache fallback fonts found by a Minikin font collection
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 #13257
1 parent bdd4e4d commit 433ca7c

File tree

2 files changed

+35
-4
lines changed

2 files changed

+35
-4
lines changed

third_party/txt/src/minikin/FontCollection.cpp

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -302,8 +302,7 @@ const std::shared_ptr<FontFamily>& FontCollection::getFamilyForChar(
302302
// libtxt: check if the fallback font provider can match this character
303303
if (mFallbackFontProvider) {
304304
const std::shared_ptr<FontFamily>& fallback =
305-
mFallbackFontProvider->matchFallbackFont(ch,
306-
GetFontLocale(langListId));
305+
findFallbackFont(ch, vs, langListId);
307306
if (fallback) {
308307
return fallback;
309308
}
@@ -340,8 +339,7 @@ const std::shared_ptr<FontFamily>& FontCollection::getFamilyForChar(
340339
// libtxt: check if the fallback font provider can match this character
341340
if (mFallbackFontProvider) {
342341
const std::shared_ptr<FontFamily>& fallback =
343-
mFallbackFontProvider->matchFallbackFont(ch,
344-
GetFontLocale(langListId));
342+
findFallbackFont(ch, vs, langListId);
345343
if (fallback) {
346344
return fallback;
347345
}
@@ -365,6 +363,30 @@ const std::shared_ptr<FontFamily>& FontCollection::getFamilyForChar(
365363
: mFamilies[bestFamilyIndex];
366364
}
367365

366+
const std::shared_ptr<FontFamily>& FontCollection::findFallbackFont(
367+
uint32_t ch,
368+
uint32_t vs,
369+
uint32_t langListId) const {
370+
std::string locale = GetFontLocale(langListId);
371+
372+
const auto it = mCachedFallbackFamilies.find(locale);
373+
if (it != mCachedFallbackFamilies.end()) {
374+
for (const auto& fallbackFamily : it->second) {
375+
if (calcCoverageScore(ch, vs, fallbackFamily)) {
376+
return fallbackFamily;
377+
}
378+
}
379+
}
380+
381+
const std::shared_ptr<FontFamily>& fallback =
382+
mFallbackFontProvider->matchFallbackFont(ch, GetFontLocale(langListId));
383+
384+
if (fallback) {
385+
mCachedFallbackFamilies[locale].push_back(fallback);
386+
}
387+
return fallback;
388+
}
389+
368390
const uint32_t NBSP = 0x00A0;
369391
const uint32_t SOFT_HYPHEN = 0x00AD;
370392
const uint32_t ZWJ = 0x200C;

third_party/txt/src/minikin/FontCollection.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#ifndef MINIKIN_FONT_COLLECTION_H
1818
#define MINIKIN_FONT_COLLECTION_H
1919

20+
#include <map>
2021
#include <memory>
2122
#include <unordered_set>
2223
#include <vector>
@@ -100,6 +101,9 @@ class FontCollection {
100101
uint32_t langListId,
101102
int variant) const;
102103

104+
const std::shared_ptr<FontFamily>&
105+
findFallbackFont(uint32_t ch, uint32_t vs, uint32_t langListId) const;
106+
103107
uint32_t calcFamilyScore(uint32_t ch,
104108
uint32_t vs,
105109
int variant,
@@ -148,6 +152,11 @@ class FontCollection {
148152

149153
// libtxt extension: Fallback font provider.
150154
std::unique_ptr<FallbackFontProvider> mFallbackFontProvider;
155+
156+
// libtxt extension: Fallback fonts discovered after this font collection
157+
// was constructed.
158+
mutable std::map<std::string, std::vector<std::shared_ptr<FontFamily>>>
159+
mCachedFallbackFamilies;
151160
};
152161

153162
} // namespace minikin

0 commit comments

Comments
 (0)