diff options
author | Seigo Nonaka <nona@google.com> | 2023-11-17 05:30:12 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2023-11-17 05:30:12 +0000 |
commit | b86a47f7aaae91efd5176e79367bc926301bb388 (patch) | |
tree | 453287d32a06407c0b92c53a28113c8203cd3dd3 | |
parent | 94f5fb01d2bdc78f95daabbde30590e391d0b5c8 (diff) | |
parent | bfc7021406422b9f817b4813266a86814f8fac16 (diff) | |
download | minikin-b86a47f7aaae91efd5176e79367bc926301bb388.tar.gz |
Merge "Fallback to non-variant match if nothing matches" into main
-rw-r--r-- | include/minikin/FontCollection.h | 5 | ||||
-rw-r--r-- | libs/minikin/FontCollection.cpp | 50 |
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); |