diff --git a/engine/src/flutter/libs/minikin/FontCollection.cpp b/engine/src/flutter/libs/minikin/FontCollection.cpp index 5f669a176a..75cbd76893 100644 --- a/engine/src/flutter/libs/minikin/FontCollection.cpp +++ b/engine/src/flutter/libs/minikin/FontCollection.cpp @@ -177,9 +177,15 @@ uint32_t FontCollection::calcCoverageScore(uint32_t ch, uint32_t vs, FontFamily* } if (vs == 0xFE0F || vs == 0xFE0E) { - // TODO use all language in the list. - const FontLanguage lang = FontLanguageListCache::getById(fontFamily->langId())[0]; - const bool hasEmojiFlag = lang.hasEmojiFlag(); + const FontLanguages& langs = FontLanguageListCache::getById(fontFamily->langId()); + bool hasEmojiFlag = false; + for (size_t i = 0; i < langs.size(); ++i) { + if (langs[i].hasEmojiFlag()) { + hasEmojiFlag = true; + break; + } + } + if (vs == 0xFE0F) { return hasEmojiFlag ? 2 : 1; } else { // vs == 0xFE0E @@ -208,13 +214,12 @@ uint32_t FontCollection::calcCoverageScore(uint32_t ch, uint32_t vs, FontFamily* uint32_t FontCollection::calcLanguageMatchingScore( uint32_t userLangListId, const FontFamily& fontFamily) { const FontLanguages& langList = FontLanguageListCache::getById(userLangListId); - // TODO use all language in the list. - FontLanguage fontLanguage = FontLanguageListCache::getById(fontFamily.langId())[0]; + const FontLanguages& fontLanguages = FontLanguageListCache::getById(fontFamily.langId()); const size_t maxCompareNum = std::min(langList.size(), FONT_LANGUAGES_LIMIT); - uint32_t score = fontLanguage.getScoreFor(langList[0]); // maxCompareNum can't be zero. - for (size_t i = 1; i < maxCompareNum; ++i) { - score = score * 3u + fontLanguage.getScoreFor(langList[i]); + uint32_t score = 0; + for (size_t i = 0; i < maxCompareNum; ++i) { + score = score * 3u + langList[i].calcScoreFor(fontLanguages); } return score; } diff --git a/engine/src/flutter/libs/minikin/FontLanguage.cpp b/engine/src/flutter/libs/minikin/FontLanguage.cpp index db630592b8..bccb4bf9e8 100644 --- a/engine/src/flutter/libs/minikin/FontLanguage.cpp +++ b/engine/src/flutter/libs/minikin/FontLanguage.cpp @@ -126,24 +126,59 @@ bool FontLanguage::isEqualScript(const FontLanguage& other) const { return other.mScript == mScript; } -bool FontLanguage::supportsScript(uint8_t requestedBits) const { - return requestedBits != 0 && (mSubScriptBits & requestedBits) == requestedBits; +// static +bool FontLanguage::supportsScript(uint8_t providedBits, uint8_t requestedBits) { + return requestedBits != 0 && (providedBits & requestedBits) == requestedBits; } bool FontLanguage::supportsHbScript(hb_script_t script) const { static_assert(SCRIPT_TAG('J', 'p', 'a', 'n') == HB_TAG('J', 'p', 'a', 'n'), "The Minikin script and HarfBuzz hb_script_t have different encodings."); if (script == mScript) return true; - return supportsScript(scriptToSubScriptBits(script)); + return supportsScript(mSubScriptBits, scriptToSubScriptBits(script)); } -int FontLanguage::getScoreFor(const FontLanguage other) const { - if (isUnsupported() || other.isUnsupported()) { - return 0; - } else if (isEqualScript(other) || supportsScript(other.mSubScriptBits)) { - return mLanguage == other.mLanguage ? 2 : 1; - } else { - return 0; +int FontLanguage::calcScoreFor(const FontLanguages& supported) const { + int score = 0; + for (size_t i = 0; i < supported.size(); ++i) { + if (isEqualScript(supported[i]) || + supportsScript(supported[i].mSubScriptBits, mSubScriptBits)) { + if (mLanguage == supported[i].mLanguage) { + return 2; + } else { + score = 1; + } + } + } + + if (score == 1) { + return score; + } + + if (supportsScript(supported.getUnionOfSubScriptBits(), mSubScriptBits)) { + // Gives score of 2 only if the language matches all of the font languages except for the + // exact match case handled above. + return (mLanguage == supported[0].mLanguage && supported.isAllTheSameLanguage()) ? 2 : 1; + } + + return 0; +} + +FontLanguages::FontLanguages(std::vector&& languages) + : mLanguages(std::move(languages)) { + if (mLanguages.empty()) { + return; + } + + const FontLanguage& lang = mLanguages[0]; + + mIsAllTheSameLanguage = true; + mUnionOfSubScriptBits = lang.mSubScriptBits; + for (size_t i = 1; i < mLanguages.size(); ++i) { + mUnionOfSubScriptBits |= mLanguages[i].mSubScriptBits; + if (mIsAllTheSameLanguage && lang.mLanguage != mLanguages[i].mLanguage) { + mIsAllTheSameLanguage = false; + } } } diff --git a/engine/src/flutter/libs/minikin/FontLanguage.h b/engine/src/flutter/libs/minikin/FontLanguage.h index 1a20480fb5..f944174a86 100644 --- a/engine/src/flutter/libs/minikin/FontLanguage.h +++ b/engine/src/flutter/libs/minikin/FontLanguage.h @@ -24,6 +24,11 @@ namespace android { +// Due to the limits in font fallback score calculation, we can't use anything more than 17 +// languages. +const size_t FONT_LANGUAGES_LIMIT = 17; +class FontLanguages; + // FontLanguage is a compact representation of a BCP 47 language tag. It // does not capture all possible information, only what directly affects // font rendering. @@ -54,12 +59,16 @@ public: std::string getString() const; + // Calculates a matching score. This score represents how well the input languages cover this + // language. The maximum score in the language list is returned. // 0 = no match, 1 = script match, 2 = script and primary language match. - int getScoreFor(const FontLanguage other) const; + int calcScoreFor(const FontLanguages& supported) const; uint64_t getIdentifier() const { return (uint64_t)mScript << 32 | (uint64_t)mLanguage; } private: + friend class FontLanguages; // for FontLanguages constructor + // ISO 15924 compliant script code. The 4 chars script code are packed into a 32 bit integer. uint32_t mScript; @@ -80,12 +89,37 @@ private: uint8_t mSubScriptBits; static uint8_t scriptToSubScriptBits(uint32_t script); - bool supportsScript(uint8_t requestedBits) const; + + // Returns true if the provide subscript bits has the requested subscript bits. + // Note that this function returns false if the requested subscript bits are empty. + static bool supportsScript(uint8_t providedBits, uint8_t requestedBits); }; -// Due to the limit of font fallback cost calculation, we can't use anything more than 17 languages. -const size_t FONT_LANGUAGES_LIMIT = 17; -typedef std::vector FontLanguages; +// An immutable list of languages. +class FontLanguages { +public: + FontLanguages(std::vector&& languages); + FontLanguages() : mUnionOfSubScriptBits(0), mIsAllTheSameLanguage(false) {} + FontLanguages(FontLanguages&&) = default; + + size_t size() const { return mLanguages.size(); } + bool empty() const { return mLanguages.empty(); } + const FontLanguage& operator[] (size_t n) const { return mLanguages[n]; } + +private: + friend struct FontLanguage; // for calcScoreFor + + std::vector mLanguages; + uint8_t mUnionOfSubScriptBits; + bool mIsAllTheSameLanguage; + + uint8_t getUnionOfSubScriptBits() const { return mUnionOfSubScriptBits; } + bool isAllTheSameLanguage() const { return mIsAllTheSameLanguage; } + + // Do not copy and assign. + FontLanguages(const FontLanguages&) = delete; + void operator=(const FontLanguages&) = delete; +}; } // namespace android diff --git a/engine/src/flutter/libs/minikin/FontLanguageListCache.cpp b/engine/src/flutter/libs/minikin/FontLanguageListCache.cpp index 5d177b5827..6b661f0384 100644 --- a/engine/src/flutter/libs/minikin/FontLanguageListCache.cpp +++ b/engine/src/flutter/libs/minikin/FontLanguageListCache.cpp @@ -76,8 +76,8 @@ static size_t toLanguageTag(char* output, size_t outSize, const std::string& loc return outLength; } -static FontLanguages constructFontLanguages(const std::string& input) { - FontLanguages result; +static std::vector parseLanguageList(const std::string& input) { + std::vector result; size_t currentIdx = 0; size_t commaLoc = 0; char langTag[ULOC_FULLNAME_CAPACITY]; @@ -121,11 +121,11 @@ uint32_t FontLanguageListCache::getId(const std::string& languages) { // Given language list is not in cache. Insert it and return newly assigned ID. const uint32_t nextId = inst->mLanguageLists.size(); - FontLanguages fontLanguages = constructFontLanguages(languages); + FontLanguages fontLanguages(parseLanguageList(languages)); if (fontLanguages.empty()) { return kEmptyListId; } - inst->mLanguageLists.push_back(fontLanguages); + inst->mLanguageLists.push_back(std::move(fontLanguages)); inst->mLanguageListLookupTable.insert(std::make_pair(languages, nextId)); return nextId; } @@ -146,7 +146,7 @@ FontLanguageListCache* FontLanguageListCache::getInstance() { // Insert an empty language list for mapping default language list to kEmptyListId. // The default language list has only one FontLanguage and it is the unsupported language. - instance->mLanguageLists.push_back(FontLanguages({FontLanguage()})); + instance->mLanguageLists.push_back(FontLanguages()); instance->mLanguageListLookupTable.insert(std::make_pair("", kEmptyListId)); } return instance; diff --git a/engine/src/flutter/tests/FontCollectionItemizeTest.cpp b/engine/src/flutter/tests/FontCollectionItemizeTest.cpp index 22971c8523..45587e9d89 100644 --- a/engine/src/flutter/tests/FontCollectionItemizeTest.cpp +++ b/engine/src/flutter/tests/FontCollectionItemizeTest.cpp @@ -698,72 +698,104 @@ TEST_F(FontCollectionItemizeTest, itemize_vs_sequence_but_no_base_char) { TEST_F(FontCollectionItemizeTest, itemize_LanguageScore) { struct TestCase { std::string userPreferredLanguages; - std::string fontLanguages; + std::vector fontLanguages; int selectedFontIndex; } testCases[] = { + // Font can specify empty language. + { "und", { "", "" }, 0 }, + { "und", { "", "en-Latn" }, 0 }, + { "en-Latn", { "", "" }, 0 }, + { "en-Latn", { "", "en-Latn" }, 1 }, + // Single user preferred language. // Exact match case - { "en-Latn", "en-Latn,ja-Jpan", 0 }, - { "ja-Jpan", "en-Latn,ja-Jpan", 1 }, - { "en-Latn", "en-Latn,nl-Latn,es-Latn", 0 }, - { "nl-Latn", "en-Latn,nl-Latn,es-Latn", 1 }, - { "es-Latn", "en-Latn,nl-Latn,es-Latn", 2 }, - { "es-Latn", "en-Latn,en-Latn,nl-Latn", 0 }, + { "en-Latn", { "en-Latn", "ja-Jpan" }, 0 }, + { "ja-Jpan", { "en-Latn", "ja-Jpan" }, 1 }, + { "en-Latn", { "en-Latn", "nl-Latn", "es-Latn" }, 0 }, + { "nl-Latn", { "en-Latn", "nl-Latn", "es-Latn" }, 1 }, + { "es-Latn", { "en-Latn", "nl-Latn", "es-Latn" }, 2 }, + { "es-Latn", { "en-Latn", "en-Latn", "nl-Latn" }, 0 }, // Exact script match case - { "en-Latn", "nl-Latn,be-Latn", 0 }, - { "en-Arab", "nl-Latn,ar-Arab", 1 }, - { "en-Latn", "be-Latn,ar-Arab,bd-Beng", 0 }, - { "en-Arab", "be-Latn,ar-Arab,bd-Beng", 1 }, - { "en-Beng", "be-Latn,ar-Arab,bd-Beng", 2 }, - { "en-Beng", "be-Latn,ar-Beng,bd-Beng", 1 }, - { "zh-Hant", "zh-Hant,zh-Hans", 0 }, - { "zh-Hans", "zh-Hant,zh-Hans", 1 }, + { "en-Latn", { "nl-Latn", "e-Latn" }, 0 }, + { "en-Arab", { "nl-Latn", "ar-Arab" }, 1 }, + { "en-Latn", { "be-Latn", "ar-Arab", "d-Beng" }, 0 }, + { "en-Arab", { "be-Latn", "ar-Arab", "d-Beng" }, 1 }, + { "en-Beng", { "be-Latn", "ar-Arab", "d-Beng" }, 2 }, + { "en-Beng", { "be-Latn", "ar-Beng", "d-Beng" }, 1 }, + { "zh-Hant", { "zh-Hant", "zh-Hans" }, 0 }, + { "zh-Hans", { "zh-Hant", "zh-Hans" }, 1 }, // Subscript match case, e.g. Jpan supports Hira. - { "en-Hira", "ja-Jpan", 0 }, - { "zh-Hani", "zh-Hans,zh-Hant", 0 }, - { "zh-Hani", "zh-Hant,zh-Hans", 0 }, - { "en-Hira", "zh-Hant,ja-Jpan,ja-Jpan", 1 }, + { "en-Hira", { "ja-Jpan" }, 0 }, + { "zh-Hani", { "zh-Hans", "zh-Hant" }, 0 }, + { "zh-Hani", { "zh-Hant", "zh-Hans" }, 0 }, + { "en-Hira", { "zh-Hant", "ja-Jpan", "ja-Jpan" }, 1 }, // Language match case - { "ja-Latn", "zh-Latn,ja-Latn", 1 }, - { "zh-Latn", "zh-Latn,ja-Latn", 0 }, - { "ja-Latn", "zh-Latn,ja-Latn", 1 }, - { "ja-Latn", "zh-Latn,ja-Latn,ja-Latn", 1 }, + { "ja-Latn", { "zh-Latn", "ja-Latn" }, 1 }, + { "zh-Latn", { "zh-Latn", "ja-Latn" }, 0 }, + { "ja-Latn", { "zh-Latn", "ja-Latn" }, 1 }, + { "ja-Latn", { "zh-Latn", "ja-Latn", "ja-Latn" }, 1 }, // Mixed case // Script/subscript match is strongest. - { "ja-Jpan", "en-Latn,ja-Latn,en-Jpan", 2 }, - { "ja-Hira", "en-Latn,ja-Latn,en-Jpan", 2 }, - { "ja-Hira", "en-Latn,ja-Latn,en-Jpan,en-Jpan", 2 }, + { "ja-Jpan", { "en-Latn", "ja-Latn", "en-Jpan" }, 2 }, + { "ja-Hira", { "en-Latn", "ja-Latn", "en-Jpan" }, 2 }, + { "ja-Hira", { "en-Latn", "ja-Latn", "en-Jpan", "en-Jpan" }, 2 }, // Language match only happens if the script matches. - { "ja-Hira", "en-Latn,ja-Latn", 0 }, - { "ja-Hira", "en-Jpan,ja-Jpan", 1 }, + { "ja-Hira", { "en-Latn", "ja-Latn" }, 0 }, + { "ja-Hira", { "en-Jpan", "ja-Jpan" }, 1 }, // Multiple languages. // Even if all fonts have the same score, use the 2nd language for better selection. - { "en-Latn,ja-Jpan", "zh-Hant,zh-Hans,ja-Jpan", 2 }, - { "en-Latn,nl-Latn", "es-Latn,be-Latn,nl-Latn", 2 }, - { "en-Latn,br-Latn,nl-Latn", "es-Latn,be-Latn,nl-Latn", 2 }, - { "en-Latn,br-Latn,nl-Latn", "es-Latn,be-Latn,nl-Latn,nl-Latn", 2 }, + { "en-Latn,ja-Jpan", { "zh-Hant", "zh-Hans", "ja-Jpan" }, 2 }, + { "en-Latn,nl-Latn", { "es-Latn", "be-Latn", "nl-Latn" }, 2 }, + { "en-Latn,br-Latn,nl-Latn", { "es-Latn", "be-Latn", "nl-Latn" }, 2 }, + { "en-Latn,br-Latn,nl-Latn", { "es-Latn", "be-Latn", "nl-Latn", "nl-Latn" }, 2 }, // Script score. - { "en-Latn,ja-Jpan", "en-Arab,en-Jpan", 1 }, - { "en-Latn,ja-Jpan", "en-Arab,en-Jpan,en-Jpan", 1 }, + { "en-Latn,ja-Jpan", { "en-Arab", "en-Jpan" }, 1 }, + { "en-Latn,ja-Jpan", { "en-Arab", "en-Jpan", "en-Jpan" }, 1 }, // Language match case - { "en-Latn,ja-Latn", "bd-Latn,ja-Latn", 1 }, - { "en-Latn,ja-Latn", "bd-Latn,ja-Latn,ja-Latn", 1 }, + { "en-Latn,ja-Latn", { "bd-Latn", "ja-Latn" }, 1 }, + { "en-Latn,ja-Latn", { "bd-Latn", "ja-Latn", "ja-Latn" }, 1 }, // Language match only happens if the script matches. - { "en-Latn,ar-Arab", "en-Beng,ar-Arab", 1 }, + { "en-Latn,ar-Arab", { "en-Beng", "ar-Arab" }, 1 }, + + // Multiple languages in the font settings. + { "ko-Jamo", { "ja-Jpan", "ko-Kore", "ko-Kore,ko-Jamo"}, 2 }, + { "en-Latn", { "ja-Jpan", "en-Latn,ja-Jpan"}, 1 }, + { "en-Latn", { "ja-Jpan", "ja-Jpan,en-Latn"}, 1 }, + { "en-Latn", { "ja-Jpan,zh-Hant", "en-Latn,ja-Jpan", "en-Latn"}, 1 }, + { "en-Latn", { "zh-Hant,ja-Jpan", "ja-Jpan,en-Latn", "en-Latn"}, 1 }, + + // Kore = Hang + Hani, etc. + { "ko-Kore", { "ko-Hang", "ko-Jamo,ko-Hani", "ko-Hang,ko-Hani"}, 2 }, + { "ja-Hrkt", { "ja-Hira", "ja-Kana", "ja-Hira,ja-Kana"}, 2 }, + { "ja-Jpan", { "ja-Hira", "ja-Kana", "ja-Hani", "ja-Hira,ja-Kana,ja-Hani"}, 3 }, + { "zh-Hanb", { "zh-Hant", "zh-Bopo", "zh-Hant,zh-Bopo"}, 2 }, + { "zh-Hanb", { "ja-Hanb", "zh-Hant,zh-Bopo"}, 1 }, + + // Language match with unified subscript bits. + { "zh-Hanb", { "zh-Hant", "zh-Bopo", "ja-Hant,ja-Bopo", "zh-Hant,zh-Bopo"}, 3 }, + { "zh-Hanb", { "zh-Hant", "zh-Bopo", "ja-Hant,zh-Bopo", "zh-Hant,zh-Bopo"}, 3 }, }; for (auto testCase : testCases) { + std::string fontLanguagesStr = "{"; + for (size_t i = 0; i < testCase.fontLanguages.size(); ++i) { + if (i != 0) { + fontLanguagesStr += ", "; + } + fontLanguagesStr += "\"" + testCase.fontLanguages[i] + "\""; + } + fontLanguagesStr += "}"; SCOPED_TRACE("Test of user preferred languages: \"" + testCase.userPreferredLanguages + - "\" with font languages: " + testCase.fontLanguages); + "\" with font languages: " + fontLanguagesStr); std::vector families; @@ -778,12 +810,10 @@ TEST_F(FontCollectionItemizeTest, itemize_LanguageScore) { // Each font family is associated with a specified language. All font families except for // the first font support U+9AA8. std::unordered_map fontLangIdxMap; - const FontLanguages& fontLanguages = registerAndGetFontLanguages(testCase.fontLanguages); - for (size_t i = 0; i < fontLanguages.size(); ++i) { - const FontLanguage& fontLanguage = fontLanguages[i]; + for (size_t i = 0; i < testCase.fontLanguages.size(); ++i) { FontFamily* family = new FontFamily( - FontStyle::registerLanguageList(fontLanguage.getString()), 0 /* variant */); + FontStyle::registerLanguageList(testCase.fontLanguages[i]), 0 /* variant */); MinikinFont* minikin_font = new MinikinFontForTest(kJAFont); family->addFont(minikin_font); families.push_back(family); diff --git a/engine/src/flutter/tests/FontFamilyTest.cpp b/engine/src/flutter/tests/FontFamilyTest.cpp index 34a92964dc..907f3950bf 100644 --- a/engine/src/flutter/tests/FontFamilyTest.cpp +++ b/engine/src/flutter/tests/FontFamilyTest.cpp @@ -30,7 +30,7 @@ namespace android { typedef ICUTestBase FontLanguagesTest; typedef ICUTestBase FontLanguageTest; -static FontLanguages createFontLanguages(const std::string& input) { +static const FontLanguages& createFontLanguages(const std::string& input) { AutoMutex _l(gMinikinLock); uint32_t langId = FontLanguageListCache::getId(input); return FontLanguageListCache::getById(langId); @@ -217,35 +217,30 @@ TEST_F(FontLanguagesTest, basicTests) { EXPECT_EQ(0u, emptyLangs.size()); FontLanguage english = createFontLanguage("en"); - FontLanguages singletonLangs = createFontLanguages("en"); + const FontLanguages& singletonLangs = createFontLanguages("en"); EXPECT_EQ(1u, singletonLangs.size()); EXPECT_EQ(english, singletonLangs[0]); FontLanguage french = createFontLanguage("fr"); - FontLanguages twoLangs = createFontLanguages("en,fr"); + const FontLanguages& twoLangs = createFontLanguages("en,fr"); EXPECT_EQ(2u, twoLangs.size()); EXPECT_EQ(english, twoLangs[0]); EXPECT_EQ(french, twoLangs[1]); } TEST_F(FontLanguagesTest, unsupportedLanguageTests) { - FontLanguage unsupportedLang = createFontLanguage("abcd"); - ASSERT_TRUE(unsupportedLang.isUnsupported()); + const FontLanguages& oneUnsupported = createFontLanguages("abcd-example"); + EXPECT_TRUE(oneUnsupported.empty()); - FontLanguages oneUnsupported = createFontLanguages("abcd-example"); - EXPECT_EQ(1u, oneUnsupported.size()); - EXPECT_TRUE(oneUnsupported[0].isUnsupported()); - - FontLanguages twoUnsupporteds = createFontLanguages("abcd-example,abcd-example"); - EXPECT_EQ(1u, twoUnsupporteds.size()); - EXPECT_TRUE(twoUnsupporteds[0].isUnsupported()); + const FontLanguages& twoUnsupporteds = createFontLanguages("abcd-example,abcd-example"); + EXPECT_TRUE(twoUnsupporteds.empty()); FontLanguage english = createFontLanguage("en"); - FontLanguages firstUnsupported = createFontLanguages("abcd-example,en"); + const FontLanguages& firstUnsupported = createFontLanguages("abcd-example,en"); EXPECT_EQ(1u, firstUnsupported.size()); EXPECT_EQ(english, firstUnsupported[0]); - FontLanguages lastUnsupported = createFontLanguages("en,abcd-example"); + const FontLanguages& lastUnsupported = createFontLanguages("en,abcd-example"); EXPECT_EQ(1u, lastUnsupported.size()); EXPECT_EQ(english, lastUnsupported[0]); } @@ -256,20 +251,20 @@ TEST_F(FontLanguagesTest, repeatedLanguageTests) { FontLanguage englishInLatn = createFontLanguage("en-Latn"); ASSERT_TRUE(english == englishInLatn); - FontLanguages langs = createFontLanguages("en,en-Latn"); + const FontLanguages& langs = createFontLanguages("en,en-Latn"); EXPECT_EQ(1u, langs.size()); EXPECT_EQ(english, langs[0]); // Country codes are ignored. - FontLanguages fr = createFontLanguages("fr,fr-CA,fr-FR"); + const FontLanguages& fr = createFontLanguages("fr,fr-CA,fr-FR"); EXPECT_EQ(1u, fr.size()); EXPECT_EQ(french, fr[0]); // The order should be kept. - langs = createFontLanguages("en,fr,en-Latn"); - EXPECT_EQ(2u, langs.size()); - EXPECT_EQ(english, langs[0]); - EXPECT_EQ(french, langs[1]); + const FontLanguages& langs2 = createFontLanguages("en,fr,en-Latn"); + EXPECT_EQ(2u, langs2.size()); + EXPECT_EQ(english, langs2[0]); + EXPECT_EQ(french, langs2[1]); } TEST_F(FontLanguagesTest, undEmojiTests) { diff --git a/engine/src/flutter/tests/FontLanguageListCacheTest.cpp b/engine/src/flutter/tests/FontLanguageListCacheTest.cpp index fbbd9376f0..2a046713c9 100644 --- a/engine/src/flutter/tests/FontLanguageListCacheTest.cpp +++ b/engine/src/flutter/tests/FontLanguageListCacheTest.cpp @@ -56,18 +56,18 @@ TEST_F(FontLanguageListCacheTest, getById) { FontLanguage english = FontLanguageListCache::getById(enLangId)[0]; FontLanguage japanese = FontLanguageListCache::getById(jpLangId)[0]; - FontLanguages defLangs = FontLanguageListCache::getById(0); - EXPECT_EQ(1UL, defLangs.size()); - EXPECT_TRUE(defLangs[0].isUnsupported()); + const FontLanguages& defLangs = FontLanguageListCache::getById(0); + EXPECT_TRUE(defLangs.empty()); - FontLanguages langs = FontLanguageListCache::getById(FontLanguageListCache::getId("en")); + const FontLanguages& langs = FontLanguageListCache::getById(FontLanguageListCache::getId("en")); ASSERT_EQ(1UL, langs.size()); EXPECT_EQ(english, langs[0]); - langs = FontLanguageListCache::getById(FontLanguageListCache::getId("en,jp")); - ASSERT_EQ(2UL, langs.size()); - EXPECT_EQ(english, langs[0]); - EXPECT_EQ(japanese, langs[1]); + const FontLanguages& langs2 = + FontLanguageListCache::getById(FontLanguageListCache::getId("en,jp")); + ASSERT_EQ(2UL, langs2.size()); + EXPECT_EQ(english, langs2[0]); + EXPECT_EQ(japanese, langs2[1]); } } // android