summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSeigo Nonaka <nona@google.com>2023-11-17 05:30:12 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2023-11-17 05:30:12 +0000
commitb86a47f7aaae91efd5176e79367bc926301bb388 (patch)
tree453287d32a06407c0b92c53a28113c8203cd3dd3
parent94f5fb01d2bdc78f95daabbde30590e391d0b5c8 (diff)
parentbfc7021406422b9f817b4813266a86814f8fac16 (diff)
downloadminikin-b86a47f7aaae91efd5176e79367bc926301bb388.tar.gz
Merge "Fallback to non-variant match if nothing matches" into main
-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);