summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSeigo Nonaka <nona@google.com>2023-11-10 17:04:34 +0900
committerSeigo Nonaka <nona@google.com>2023-11-17 10:18:54 +0900
commitbfc7021406422b9f817b4813266a86814f8fac16 (patch)
treee74d4bfcc4b26e3f50b21c3ea7a6417b4dbc745c
parentd27148d9ed3d653b6e8d95a769de0150be1104e9 (diff)
downloadminikin-bfc7021406422b9f817b4813266a86814f8fac16.tar.gz
Fallback to non-variant match if nothing matches
Bug: 310117531 Test: atest CtsGraphicsTestCases CtsTextTestCases CtsWidgetTestCases Change-Id: I574b641e50e8f2bc03c7490c0199697e79d81aa2
-rw-r--r--include/minikin/FontCollection.h5
-rw-r--r--libs/minikin/FontCollection.cpp50
2 files changed, 40 insertions, 15 deletions
diff --git a/include/minikin/FontCollection.h b/include/minikin/FontCollection.h
index 7ad644a..ee0315e 100644
--- a/include/minikin/FontCollection.h
+++ b/include/minikin/FontCollection.h
@@ -34,6 +34,8 @@ namespace minikin {
// The maximum number of font families.
constexpr uint32_t MAX_FAMILY_COUNT = 254;
+class LocaleList;
+
class FontCollection {
public:
static std::shared_ptr<FontCollection> create(
@@ -225,6 +227,9 @@ private:
bool isPrimaryFamily(const std::shared_ptr<FontFamily>& fontFamily) const;
+ void filterFamilyByLocale(const LocaleList& localeList,
+ const std::function<void(const FontFamily& family)>& callback) const;
+
static uint32_t calcLocaleMatchingScore(uint32_t userLocaleListId,
const FontFamily& fontFamily);
diff --git a/libs/minikin/FontCollection.cpp b/libs/minikin/FontCollection.cpp
index 440eab2..84e5dd9 100644
--- a/libs/minikin/FontCollection.cpp
+++ b/libs/minikin/FontCollection.cpp
@@ -608,6 +608,25 @@ FontCollection::FamilyMatchResult FontCollection::FamilyMatchResult::intersect(
return b.build();
}
+void FontCollection::filterFamilyByLocale(
+ const LocaleList& localeList,
+ const std::function<void(const FontFamily& family)>& callback) const {
+ for (uint8_t i = 0; i < mFamilyCount; ++i) {
+ const auto& family = getFamilyAt(i);
+
+ uint32_t fontLocaleId = family->localeListId();
+ if (fontLocaleId == LocaleListCache::kInvalidListId) {
+ continue;
+ }
+ const LocaleList& fontLocaleList = LocaleListCache::getById(fontLocaleId);
+ if (!localeList.atLeastOneScriptMatch(fontLocaleList)) {
+ continue;
+ }
+
+ callback(*family.get());
+ }
+}
+
MinikinExtent FontCollection::getReferenceExtentForLocale(const MinikinPaint& paint) const {
uint32_t localeId = paint.localeListId;
MinikinExtent result(0, 0);
@@ -635,34 +654,35 @@ MinikinExtent FontCollection::getReferenceExtentForLocale(const MinikinPaint& pa
const LocaleList& requestedLocaleList = LocaleListCache::getById(localeId);
bool familyFound = false;
- for (uint8_t i = 0; i < mFamilyCount; ++i) {
- const auto& family = getFamilyAt(i);
- const FamilyVariant familyVariant = family->variant() == FamilyVariant::DEFAULT
+ filterFamilyByLocale(requestedLocaleList, [&](const FontFamily& family) {
+ const FamilyVariant familyVariant = family.variant() == FamilyVariant::DEFAULT
? FamilyVariant::COMPACT
- : family->variant();
+ : family.variant();
if (familyVariant != requestVariant) {
- continue;
+ return;
}
- uint32_t fontLocaleId = family->localeListId();
- if (fontLocaleId == LocaleListCache::kInvalidListId) {
- continue;
- }
- const LocaleList& fontLocaleList = LocaleListCache::getById(fontLocaleId);
- if (!requestedLocaleList.atLeastOneScriptMatch(fontLocaleList)) {
- continue;
- }
+ MinikinExtent extent(0, 0);
+ FakedFont font = family.getClosestMatch(paint.fontStyle);
+ font.typeface()->GetFontExtent(&extent, paint, font.fakery);
+ result.extendBy(extent);
+ familyFound = true;
+ });
+
+ // If nothing matches, try non-variant match cases since it is used for fallback.
+ filterFamilyByLocale(requestedLocaleList, [&](const FontFamily& family) {
// Use this family
MinikinExtent extent(0, 0);
- FakedFont font = getFamilyAt(i)->getClosestMatch(paint.fontStyle);
+ FakedFont font = family.getClosestMatch(paint.fontStyle);
font.typeface()->GetFontExtent(&extent, paint, font.fakery);
result.extendBy(extent);
familyFound = true;
- }
+ });
+ // If nothing matches, use default font.
if (!familyFound) {
FakedFont font = getFamilyAt(0)->getClosestMatch(paint.fontStyle);
font.typeface()->GetFontExtent(&result, paint, font.fakery);