summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSeigo Nonaka <nona@google.com>2023-09-27 08:32:00 +0900
committerSeigo Nonaka <nona@google.com>2023-10-11 09:53:49 +0900
commit35b2cc325e4e0bc19ebbc3f95a772c923cb883b6 (patch)
tree67c7bf7411cd7c2094cbb120be2162b04a7b1f64
parent8f53bf73fc08a1fba55d2ae0edd8846688ca61ea (diff)
downloadminikin-35b2cc325e4e0bc19ebbc3f95a772c923cb883b6.tar.gz
Add method that returns reference extent for locale
Bug: 303326708 Test: atest PaintFontMetricsForLocaleTest Change-Id: I1fe2a475aed21a58f69e33ab91320dea77f463d5
-rw-r--r--include/minikin/FontCollection.h2
-rw-r--r--libs/minikin/FontCollection.cpp65
-rw-r--r--libs/minikin/Locale.cpp16
-rw-r--r--libs/minikin/Locale.h2
4 files changed, 85 insertions, 0 deletions
diff --git a/include/minikin/FontCollection.h b/include/minikin/FontCollection.h
index 1679abc..7ad644a 100644
--- a/include/minikin/FontCollection.h
+++ b/include/minikin/FontCollection.h
@@ -147,6 +147,8 @@ public:
return itemize(text, style, localeListId, familyVariant, text.size());
}
+ MinikinExtent getReferenceExtentForLocale(const MinikinPaint& paint) const;
+
// Returns true if there is a glyph for the code point and variation selector pair.
// Returns false if no fonts have a glyph for the code point and variation
// selector pair, or invalid variation selector is passed.
diff --git a/libs/minikin/FontCollection.cpp b/libs/minikin/FontCollection.cpp
index 0c1a173..440eab2 100644
--- a/libs/minikin/FontCollection.cpp
+++ b/libs/minikin/FontCollection.cpp
@@ -30,6 +30,8 @@
#include "minikin/Characters.h"
#include "minikin/Emoji.h"
#include "minikin/FontFileParser.h"
+#include "minikin/MinikinExtent.h"
+#include "minikin/MinikinPaint.h"
using std::vector;
@@ -606,6 +608,69 @@ FontCollection::FamilyMatchResult FontCollection::FamilyMatchResult::intersect(
return b.build();
}
+MinikinExtent FontCollection::getReferenceExtentForLocale(const MinikinPaint& paint) const {
+ uint32_t localeId = paint.localeListId;
+ MinikinExtent result(0, 0);
+ for (uint8_t i = 0; i < mFamilyCount; ++i) {
+ const auto& family = getFamilyAt(i);
+ if (!family->isCustomFallback()) {
+ break;
+ }
+
+ // Use this family
+ MinikinExtent extent(0, 0);
+ FakedFont font = getFamilyAt(i)->getClosestMatch(paint.fontStyle);
+ font.typeface()->GetFontExtent(&extent, paint, font.fakery);
+ result.extendBy(extent);
+ }
+
+ if (localeId == LocaleListCache::kInvalidListId) {
+ return result;
+ }
+
+ // If default is requested, use compact one.
+ const FamilyVariant requestVariant = paint.familyVariant == FamilyVariant::DEFAULT
+ ? FamilyVariant::COMPACT
+ : paint.familyVariant;
+ 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
+ ? FamilyVariant::COMPACT
+ : family->variant();
+
+ if (familyVariant != requestVariant) {
+ continue;
+ }
+
+ uint32_t fontLocaleId = family->localeListId();
+ if (fontLocaleId == LocaleListCache::kInvalidListId) {
+ continue;
+ }
+ const LocaleList& fontLocaleList = LocaleListCache::getById(fontLocaleId);
+ if (!requestedLocaleList.atLeastOneScriptMatch(fontLocaleList)) {
+ continue;
+ }
+
+ // Use this family
+ MinikinExtent extent(0, 0);
+ FakedFont font = getFamilyAt(i)->getClosestMatch(paint.fontStyle);
+ font.typeface()->GetFontExtent(&extent, paint, font.fakery);
+ result.extendBy(extent);
+
+ familyFound = true;
+ }
+
+ if (!familyFound) {
+ FakedFont font = getFamilyAt(0)->getClosestMatch(paint.fontStyle);
+ font.typeface()->GetFontExtent(&result, paint, font.fakery);
+ }
+
+ return result;
+}
+
std::vector<FontCollection::Run> FontCollection::itemize(U16StringPiece text, FontStyle,
uint32_t localeListId,
FamilyVariant familyVariant,
diff --git a/libs/minikin/Locale.cpp b/libs/minikin/Locale.cpp
index d246020..a399944 100644
--- a/libs/minikin/Locale.cpp
+++ b/libs/minikin/Locale.cpp
@@ -528,4 +528,20 @@ LocaleList::LocaleList(std::vector<Locale>&& locales) : mLocales(std::move(local
}
}
+bool LocaleList::atLeastOneScriptMatch(const LocaleList& list) const {
+ if ((mUnionOfSubScriptBits & list.mUnionOfSubScriptBits) != 0) {
+ return true;
+ }
+
+ for (const Locale& myLocale : mLocales) {
+ for (const Locale& otherLocale : list.mLocales) {
+ if (myLocale.isEqualScript(otherLocale)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
} // namespace minikin
diff --git a/libs/minikin/Locale.h b/libs/minikin/Locale.h
index 285bb7b..31bd51f 100644
--- a/libs/minikin/Locale.h
+++ b/libs/minikin/Locale.h
@@ -217,6 +217,8 @@ public:
// The effective means the first non empty emoji style in the list.
EmojiStyle getEmojiStyle() const { return mEmojiStyle; }
+ bool atLeastOneScriptMatch(const LocaleList& list) const;
+
private:
friend struct Locale; // for calcScoreFor