diff options
author | Seigo Nonaka <nona@google.com> | 2023-09-27 08:32:00 +0900 |
---|---|---|
committer | Seigo Nonaka <nona@google.com> | 2023-10-11 09:53:49 +0900 |
commit | 35b2cc325e4e0bc19ebbc3f95a772c923cb883b6 (patch) | |
tree | 67c7bf7411cd7c2094cbb120be2162b04a7b1f64 | |
parent | 8f53bf73fc08a1fba55d2ae0edd8846688ca61ea (diff) | |
download | minikin-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.h | 2 | ||||
-rw-r--r-- | libs/minikin/FontCollection.cpp | 65 | ||||
-rw-r--r-- | libs/minikin/Locale.cpp | 16 | ||||
-rw-r--r-- | libs/minikin/Locale.h | 2 |
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 |