summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSeigo Nonaka <nona@google.com>2018-02-16 19:17:08 -0800
committerSeigo Nonaka <nona@google.com>2018-02-20 08:32:32 -0800
commit7fbdd83e92a76c955c67a1c761088b36daf7158c (patch)
tree1d18f01137a808243746130c7b8a5d0badbb9c47
parent055beb393788376b6a96f7456054ef10a867cfff (diff)
downloadminikin-7fbdd83e92a76c955c67a1c761088b36daf7158c.tar.gz
Fix emoji presentation priority
Some non emoji font supports emoji font. To avoid selecting such font in case emoji presentation style is provided, give higher score for the presentation match. StaticLayout creation time: RandomText Balanced Hyphenation : 18,490,608 -> 18,507,043: (+0.1%) RandomText Balanced NoHyphenation: 7,597,070 -> 7,619,731: (+0.3%) RandomText Greedy Hyphenation : 7,540,346 -> 7,566,300: (+0.3%) RandomText Greedy NoHyphenation : 7,548,161 -> 7,571,481: (+0.3%) PrecomputedText creation time: NoStyled Hyphenation : 18,289,621 -> 18,331,562: (+0.2%) NoStyled Hyphenation WidthOnly : 17,834,643 -> 17,852,181: (+0.1%) NoStyled NoHyphenation : 7,559,071 -> 7,579,943: (+0.3%) NoStyled NoHyphenation WidthOnly : 7,117,840 -> 7,142,599: (+0.3%) Styled Hyphenation : 15,257,108 -> 15,391,763: (+0.9%) Styled Hyphenation WidthOnly : 14,243,001 -> 14,425,028: (+1.3%) Styled NoHyphenation : 14,812,011 -> 14,920,500: (+0.7%) Styled NoHyphenation WidthOnly : 13,862,758 -> 13,959,173: (+0.7%) StaticLayout draw time: RandomText NoStyled WithoutCache : 6,952,595 -> 6,974,445: (+0.3%) RandomText Styled WithoutCache : 3,457,777 -> 3,442,473: (-0.4%) Bug: 69321418 Bug: 31608997 Test: minikin_test Change-Id: I167705b2e0d8c7d14df2a5e3a99b89dfea057713
-rw-r--r--include/minikin/FontCollection.h2
-rw-r--r--include/minikin/FontFamily.h3
-rw-r--r--libs/minikin/FontCollection.cpp44
-rw-r--r--libs/minikin/FontFamily.cpp16
-rw-r--r--libs/minikin/Locale.cpp41
-rw-r--r--libs/minikin/Locale.h29
-rw-r--r--tests/unittest/FontCollectionItemizeTest.cpp52
-rw-r--r--tests/unittest/FontFamilyTest.cpp14
-rw-r--r--tests/util/FontTestUtils.cpp9
-rw-r--r--tests/util/FontTestUtils.h5
10 files changed, 142 insertions, 73 deletions
diff --git a/include/minikin/FontCollection.h b/include/minikin/FontCollection.h
index 61b4231..46c362d 100644
--- a/include/minikin/FontCollection.h
+++ b/include/minikin/FontCollection.h
@@ -82,7 +82,7 @@ private:
uint32_t localeListId,
const std::shared_ptr<FontFamily>& fontFamily) const;
- uint32_t calcCoverageScore(uint32_t ch, uint32_t vs,
+ uint32_t calcCoverageScore(uint32_t ch, uint32_t vs, uint32_t localeListId,
const std::shared_ptr<FontFamily>& fontFamily) const;
static uint32_t calcLocaleMatchingScore(uint32_t userLocaleListId,
diff --git a/include/minikin/FontFamily.h b/include/minikin/FontFamily.h
index 7605dd9..66fe3a8 100644
--- a/include/minikin/FontFamily.h
+++ b/include/minikin/FontFamily.h
@@ -145,7 +145,7 @@ public:
size_t getNumFonts() const { return mFonts.size(); }
const Font* getFont(size_t index) const { return &mFonts[index]; }
FontStyle getStyle(size_t index) const { return mFonts[index].style(); }
- bool isColorEmojiFamily() const;
+ bool isColorEmojiFamily() const { return mIsColorEmoji; }
const std::unordered_set<AxisTag>& supportedAxes() const { return mSupportedAxes; }
// Get Unicode coverage.
@@ -170,6 +170,7 @@ private:
Variant mVariant;
std::vector<Font> mFonts;
std::unordered_set<AxisTag> mSupportedAxes;
+ bool mIsColorEmoji;
SparseBitSet mCoverage;
std::vector<std::unique_ptr<SparseBitSet>> mCmapFmt14Coverage;
diff --git a/libs/minikin/FontCollection.cpp b/libs/minikin/FontCollection.cpp
index b20d779..b1d894b 100644
--- a/libs/minikin/FontCollection.cpp
+++ b/libs/minikin/FontCollection.cpp
@@ -126,7 +126,7 @@ const uint32_t kFirstFontScore = UINT32_MAX;
uint32_t FontCollection::calcFamilyScore(uint32_t ch, uint32_t vs, FontFamily::Variant variant,
uint32_t localeListId,
const std::shared_ptr<FontFamily>& fontFamily) const {
- const uint32_t coverageScore = calcCoverageScore(ch, vs, fontFamily);
+ const uint32_t coverageScore = calcCoverageScore(ch, vs, localeListId, fontFamily);
if (coverageScore == kFirstFontScore || coverageScore == kUnsupportedFontScore) {
// No need to calculate other scores.
return coverageScore;
@@ -151,7 +151,7 @@ uint32_t FontCollection::calcFamilyScore(uint32_t ch, uint32_t vs, FontFamily::V
// - Returns 2 if the vs is a text variation selector (U+FE0E) and if the font is not an emoji font.
// - Returns 1 if the variation selector is not specified or if the font family only supports the
// variation sequence's base character.
-uint32_t FontCollection::calcCoverageScore(uint32_t ch, uint32_t vs,
+uint32_t FontCollection::calcCoverageScore(uint32_t ch, uint32_t vs, uint32_t localeListId,
const std::shared_ptr<FontFamily>& fontFamily) const {
const bool hasVSGlyph = (vs != 0) && fontFamily->hasGlyph(ch, vs);
if (!hasVSGlyph && !fontFamily->getCoverage().get(ch)) {
@@ -165,31 +165,33 @@ uint32_t FontCollection::calcCoverageScore(uint32_t ch, uint32_t vs,
return kFirstFontScore;
}
- if (vs == 0) {
- return 1;
- }
-
- if (hasVSGlyph) {
+ if (vs != 0 && hasVSGlyph) {
return 3;
}
- if (vs == EMOJI_STYLE_VS || vs == TEXT_STYLE_VS) {
- const LocaleList& locales = LocaleListCache::getById(fontFamily->localeListId());
- bool hasEmojiFlag = false;
- for (size_t i = 0; i < locales.size(); ++i) {
- if (locales[i].getEmojiStyle() == Locale::EMSTYLE_EMOJI) {
- hasEmojiFlag = true;
+ bool colorEmojiRequest;
+ if (vs == EMOJI_STYLE_VS) {
+ colorEmojiRequest = true;
+ } else if (vs == TEXT_STYLE_VS) {
+ colorEmojiRequest = false;
+ } else {
+ switch (LocaleListCache::getById(localeListId).getEmojiStyle()) {
+ case EmojiStyle::EMOJI:
+ colorEmojiRequest = true;
+ break;
+ case EmojiStyle::TEXT:
+ colorEmojiRequest = false;
+ break;
+ case EmojiStyle::EMPTY:
+ case EmojiStyle::DEFAULT:
+ default:
+ // Do not give any extra score for the default emoji style.
+ return 1;
break;
- }
- }
-
- if (vs == EMOJI_STYLE_VS) {
- return hasEmojiFlag ? 2 : 1;
- } else { // vs == TEXT_STYLE_VS
- return hasEmojiFlag ? 1 : 2;
}
}
- return 1;
+
+ return colorEmojiRequest == fontFamily->isColorEmojiFamily() ? 2 : 1;
}
// Calculate font scores based on the script matching, subtag matching and primary locale matching.
diff --git a/libs/minikin/FontFamily.cpp b/libs/minikin/FontFamily.cpp
index 1c89960..b95d858 100644
--- a/libs/minikin/FontFamily.cpp
+++ b/libs/minikin/FontFamily.cpp
@@ -111,7 +111,11 @@ FontFamily::FontFamily(Variant variant, std::vector<Font>&& fonts)
: FontFamily(LocaleListCache::kEmptyListId, variant, std::move(fonts)) {}
FontFamily::FontFamily(uint32_t localeListId, Variant variant, std::vector<Font>&& fonts)
- : mLocaleListId(localeListId), mVariant(variant), mFonts(std::move(fonts)) {
+ : mLocaleListId(localeListId),
+ mVariant(variant),
+ mFonts(std::move(fonts)),
+ mIsColorEmoji(LocaleListCache::getById(localeListId).getEmojiStyle() ==
+ EmojiStyle::EMOJI) {
MINIKIN_ASSERT(!mFonts.empty(), "FontFamily must contain at least one font.");
computeCoverage();
}
@@ -150,16 +154,6 @@ FakedFont FontFamily::getClosestMatch(FontStyle style) const {
return FakedFont{bestFont, computeFakery(style, bestFont->style())};
}
-bool FontFamily::isColorEmojiFamily() const {
- const LocaleList& localeList = LocaleListCache::getById(mLocaleListId);
- for (size_t i = 0; i < localeList.size(); ++i) {
- if (localeList[i].getEmojiStyle() == Locale::EMSTYLE_EMOJI) {
- return true;
- }
- }
- return false;
-}
-
void FontFamily::computeCoverage() {
const Font* font = getClosestMatch(FontStyle()).font;
HbBlob cmapTable(font->baseFont(), MinikinFont::MakeTag('c', 'm', 'a', 'p'));
diff --git a/libs/minikin/Locale.cpp b/libs/minikin/Locale.cpp
index 346e5e4..4209413 100644
--- a/libs/minikin/Locale.cpp
+++ b/libs/minikin/Locale.cpp
@@ -209,13 +209,13 @@ Locale::Locale(const StringPiece& input) : Locale() {
mEmojiStyle = resolveEmojiStyle(input.data(), input.length());
finalize:
- if (mEmojiStyle == EMSTYLE_EMPTY) {
+ if (mEmojiStyle == EmojiStyle::EMPTY) {
mEmojiStyle = scriptToEmojiStyle(mScript);
}
}
// static
-Locale::EmojiStyle Locale::resolveEmojiStyle(const char* buf, size_t length) {
+EmojiStyle Locale::resolveEmojiStyle(const char* buf, size_t length) {
// First, lookup emoji subtag.
// 10 is the length of "-u-em-text", which is the shortest emoji subtag,
// unnecessary comparison can be avoided if total length is smaller than 10.
@@ -227,25 +227,25 @@ Locale::EmojiStyle Locale::resolveEmojiStyle(const char* buf, size_t length) {
pos += strlen(kPrefix);
const size_t remainingLength = length - (pos - buf);
if (isEmojiSubtag(pos, remainingLength, "emoji", 5)) {
- return EMSTYLE_EMOJI;
+ return EmojiStyle::EMOJI;
} else if (isEmojiSubtag(pos, remainingLength, "text", 4)) {
- return EMSTYLE_TEXT;
+ return EmojiStyle::TEXT;
} else if (isEmojiSubtag(pos, remainingLength, "default", 7)) {
- return EMSTYLE_DEFAULT;
+ return EmojiStyle::DEFAULT;
}
}
}
- return EMSTYLE_EMPTY;
+ return EmojiStyle::EMPTY;
}
-Locale::EmojiStyle Locale::scriptToEmojiStyle(uint32_t script) {
+EmojiStyle Locale::scriptToEmojiStyle(uint32_t script) {
// If no emoji subtag was provided, resolve the emoji style from script code.
if (script == packScript('Z', 's', 'y', 'e')) {
- return EMSTYLE_EMOJI;
+ return EmojiStyle::EMOJI;
} else if (script == packScript('Z', 's', 'y', 'm')) {
- return EMSTYLE_TEXT;
+ return EmojiStyle::TEXT;
}
- return EMSTYLE_EMPTY;
+ return EmojiStyle::EMPTY;
}
// static
@@ -379,7 +379,7 @@ int Locale::calcScoreFor(const LocaleList& supported) const {
bool scriptMatch = false;
for (size_t i = 0; i < supported.size(); ++i) {
- if (mEmojiStyle != EMSTYLE_EMPTY && mEmojiStyle == supported[i].mEmojiStyle) {
+ if (mEmojiStyle != EmojiStyle::EMPTY && mEmojiStyle == supported[i].mEmojiStyle) {
subtagMatch = true;
if (mLanguage == supported[i].mLanguage) {
return 4;
@@ -417,23 +417,20 @@ static hb_language_t buildHbLanguage(const Locale& locale) {
}
LocaleList::LocaleList(std::vector<Locale>&& locales) : mLocales(std::move(locales)) {
- if (mLocales.empty()) {
- return;
- }
-
- const Locale& firstLocale = mLocales[0];
-
mIsAllTheSameLocale = true;
- mUnionOfSubScriptBits = firstLocale.mSubScriptBits;
+ mUnionOfSubScriptBits = 0u;
mHbLangs.reserve(mLocales.size());
- mHbLangs.push_back(buildHbLanguage(firstLocale));
- for (size_t i = 1; i < mLocales.size(); ++i) {
- const Locale& locale = mLocales[i];
+ mEmojiStyle = EmojiStyle::EMPTY;
+ const auto firstLanguage = mLocales.empty() ? NO_LANGUAGE : mLocales[0].mLanguage;
+ for (const Locale& locale : mLocales) {
mUnionOfSubScriptBits |= locale.mSubScriptBits;
- if (mIsAllTheSameLocale && firstLocale.mLanguage != locale.mLanguage) {
+ if (mIsAllTheSameLocale && firstLanguage != locale.mLanguage) {
mIsAllTheSameLocale = false;
}
mHbLangs.push_back(buildHbLanguage(locale));
+ if (mEmojiStyle == EmojiStyle::EMPTY) {
+ mEmojiStyle = locale.getEmojiStyle();
+ }
}
}
diff --git a/libs/minikin/Locale.h b/libs/minikin/Locale.h
index 3ed81be..f030f92 100644
--- a/libs/minikin/Locale.h
+++ b/libs/minikin/Locale.h
@@ -55,18 +55,19 @@ inline constexpr SubtagBits operator|(SubtagBits l, SubtagBits r) {
return static_cast<SubtagBits>(static_cast<uint8_t>(l) | static_cast<uint8_t>(r));
}
+// Enum for emoji style.
+enum class EmojiStyle : uint8_t {
+ EMPTY = 0, // No emoji style is specified.
+ DEFAULT = 1, // Default emoji style is specified.
+ EMOJI = 2, // Emoji (color) emoji style is specified.
+ TEXT = 3, // Text (black/white) emoji style is specified.
+};
+
// Locale is a compact representation of a BCP 47 language tag.
// It does not capture all possible information, only what directly affects text layout:
// font rendering, hyphenation, word breaking, etc.
struct Locale {
public:
- enum EmojiStyle : uint8_t {
- EMSTYLE_EMPTY = 0,
- EMSTYLE_DEFAULT = 1,
- EMSTYLE_EMOJI = 2,
- EMSTYLE_TEXT = 3,
- };
-
enum class Variant : uint16_t { // Up to 12 bits
NO_VARIANT = 0x0000,
GERMAN_1901_ORTHOGRAPHY = 0x0001,
@@ -80,7 +81,7 @@ public:
mRegion(NO_REGION),
mSubScriptBits(0ul),
mVariant(Variant::NO_VARIANT),
- mEmojiStyle(EMSTYLE_EMPTY) {}
+ mEmojiStyle(EmojiStyle::EMPTY) {}
// Parse from string
Locale(const StringPiece& buf);
@@ -97,7 +98,7 @@ public:
inline bool hasScript() const { return mScript != NO_SCRIPT; }
inline bool hasRegion() const { return mRegion != NO_REGION; }
inline bool hasVariant() const { return mVariant != Variant::NO_VARIANT; }
- inline bool hasEmojiStyle() const { return mEmojiStyle != EMSTYLE_EMPTY; }
+ inline bool hasEmojiStyle() const { return mEmojiStyle != EmojiStyle::EMPTY; }
inline bool isSupported() const {
return hasLanguage() || hasScript() || hasRegion() || hasVariant() || hasEmojiStyle();
@@ -171,7 +172,10 @@ private:
class LocaleList {
public:
explicit LocaleList(std::vector<Locale>&& locales);
- LocaleList() : mUnionOfSubScriptBits(0), mIsAllTheSameLocale(false) {}
+ LocaleList()
+ : mUnionOfSubScriptBits(0),
+ mIsAllTheSameLocale(false),
+ mEmojiStyle(EmojiStyle::EMPTY) {}
LocaleList(LocaleList&&) = default;
size_t size() const { return mLocales.size(); }
@@ -180,6 +184,10 @@ public:
hb_language_t getHbLanguage(size_t n) const { return mHbLangs[n]; }
+ // Returns an effective emoji style of this locale list.
+ // The effective means the first non empty emoji style in the list.
+ EmojiStyle getEmojiStyle() const { return mEmojiStyle; }
+
private:
friend struct Locale; // for calcScoreFor
@@ -189,6 +197,7 @@ private:
std::vector<hb_language_t> mHbLangs;
uint8_t mUnionOfSubScriptBits;
bool mIsAllTheSameLocale;
+ EmojiStyle mEmojiStyle;
uint8_t getUnionOfSubScriptBits() const { return mUnionOfSubScriptBits; }
bool isAllTheSameLocale() const { return mIsAllTheSameLocale; }
diff --git a/tests/unittest/FontCollectionItemizeTest.cpp b/tests/unittest/FontCollectionItemizeTest.cpp
index d1ff460..a7fad69 100644
--- a/tests/unittest/FontCollectionItemizeTest.cpp
+++ b/tests/unittest/FontCollectionItemizeTest.cpp
@@ -1573,4 +1573,56 @@ TEST(FontCollectionItemizeTest, itemizeShouldKeepOrderForVS2) {
EXPECT_EQ(noCmapFormat14Family->getFont(0), runs[0].fakedFont.font);
}
+TEST(FontCollectionItemizeTest, colorEmojiSelectionTest) {
+ auto dummyFamily = buildFontFamily(kNoGlyphFont);
+ auto textEmojiFamily = buildFontFamily(kTextEmojiFont, "ja-JP");
+ auto colorEmojiFamily = buildFontFamily(kColorEmojiFont, "und-Zsye");
+
+ std::vector<std::shared_ptr<FontFamily>> families = {dummyFamily, textEmojiFamily,
+ colorEmojiFamily};
+ auto collection = std::make_shared<FontCollection>(families);
+ std::vector<FontCollection::Run> runs;
+ // Both textEmojiFamily and colorEmojiFamily supports U+203C and U+23E9.
+ // U+203C is text default emoji, and U+23E9 is color default emoji.
+ itemize(collection, "U+203C", "en-US,en-Zsym", &runs);
+ EXPECT_EQ(textEmojiFamily->getFont(0), runs[0].fakedFont.font);
+ itemize(collection, "U+23E9", "en-US,en-Zsym", &runs);
+ EXPECT_EQ(textEmojiFamily->getFont(0), runs[0].fakedFont.font);
+
+ itemize(collection, "U+203C", "en-US,en-Zsye", &runs);
+ EXPECT_EQ(colorEmojiFamily->getFont(0), runs[0].fakedFont.font);
+ itemize(collection, "U+23E9", "en-US,en-Zsye", &runs);
+ EXPECT_EQ(colorEmojiFamily->getFont(0), runs[0].fakedFont.font);
+
+ itemize(collection, "U+203C", "ja-Zsym-JP", &runs);
+ EXPECT_EQ(textEmojiFamily->getFont(0), runs[0].fakedFont.font);
+ itemize(collection, "U+23E9", "ja-Zsym-JP", &runs);
+ EXPECT_EQ(textEmojiFamily->getFont(0), runs[0].fakedFont.font);
+
+ itemize(collection, "U+203C", "ja-Zsye-JP", &runs);
+ EXPECT_EQ(colorEmojiFamily->getFont(0), runs[0].fakedFont.font);
+ itemize(collection, "U+23E9", "ja-Zsye-JP", &runs);
+ EXPECT_EQ(colorEmojiFamily->getFont(0), runs[0].fakedFont.font);
+
+ itemize(collection, "U+203C", "ja-JP-u-em-text", &runs);
+ EXPECT_EQ(textEmojiFamily->getFont(0), runs[0].fakedFont.font);
+ itemize(collection, "U+23E9", "ja-JP-u-em-text", &runs);
+ EXPECT_EQ(textEmojiFamily->getFont(0), runs[0].fakedFont.font);
+
+ itemize(collection, "U+203C", "ja-JP-u-em-emoji", &runs);
+ EXPECT_EQ(colorEmojiFamily->getFont(0), runs[0].fakedFont.font);
+ itemize(collection, "U+23E9", "ja-JP-u-em-emoji", &runs);
+ EXPECT_EQ(colorEmojiFamily->getFont(0), runs[0].fakedFont.font);
+
+ itemize(collection, "U+203C", "ja-JP,und-Zsym", &runs);
+ EXPECT_EQ(textEmojiFamily->getFont(0), runs[0].fakedFont.font);
+ itemize(collection, "U+23E9", "ja-JP,und-Zsym", &runs);
+ EXPECT_EQ(textEmojiFamily->getFont(0), runs[0].fakedFont.font);
+
+ itemize(collection, "U+203C", "ja-JP,und-Zsye", &runs);
+ EXPECT_EQ(colorEmojiFamily->getFont(0), runs[0].fakedFont.font);
+ itemize(collection, "U+23E9", "ja-JP,und-Zsye", &runs);
+ EXPECT_EQ(colorEmojiFamily->getFont(0), runs[0].fakedFont.font);
+}
+
} // namespace minikin
diff --git a/tests/unittest/FontFamilyTest.cpp b/tests/unittest/FontFamilyTest.cpp
index 7cdc6ad..9b3c39a 100644
--- a/tests/unittest/FontFamilyTest.cpp
+++ b/tests/unittest/FontFamilyTest.cpp
@@ -327,14 +327,14 @@ TEST(LocaleListTest, identifierTest) {
TEST(LocaleListTest, undEmojiTests) {
Locale emoji = createLocale("und-Zsye");
- EXPECT_EQ(Locale::EMSTYLE_EMOJI, emoji.getEmojiStyle());
+ EXPECT_EQ(EmojiStyle::EMOJI, emoji.getEmojiStyle());
Locale und = createLocale("und");
- EXPECT_EQ(Locale::EMSTYLE_EMPTY, und.getEmojiStyle());
+ EXPECT_EQ(EmojiStyle::EMPTY, und.getEmojiStyle());
EXPECT_FALSE(emoji == und);
Locale undExample = createLocale("und-example");
- EXPECT_EQ(Locale::EMSTYLE_EMPTY, undExample.getEmojiStyle());
+ EXPECT_EQ(EmojiStyle::EMPTY, undExample.getEmojiStyle());
EXPECT_FALSE(emoji == undExample);
}
@@ -361,7 +361,7 @@ TEST(LocaleListTest, subtagEmojiTest) {
for (auto subtagEmojiString : subtagEmojiStrings) {
SCOPED_TRACE("Test for \"" + subtagEmojiString + "\"");
Locale subtagEmoji = createLocale(subtagEmojiString);
- EXPECT_EQ(Locale::EMSTYLE_EMOJI, subtagEmoji.getEmojiStyle());
+ EXPECT_EQ(EmojiStyle::EMOJI, subtagEmoji.getEmojiStyle());
}
}
@@ -388,7 +388,7 @@ TEST(LocaleListTest, subtagTextTest) {
for (auto subtagTextString : subtagTextStrings) {
SCOPED_TRACE("Test for \"" + subtagTextString + "\"");
Locale subtagText = createLocale(subtagTextString);
- EXPECT_EQ(Locale::EMSTYLE_TEXT, subtagText.getEmojiStyle());
+ EXPECT_EQ(EmojiStyle::TEXT, subtagText.getEmojiStyle());
}
}
@@ -416,7 +416,7 @@ TEST(LocaleListTest, subtagDefaultTest) {
for (auto subtagDefaultString : subtagDefaultStrings) {
SCOPED_TRACE("Test for \"" + subtagDefaultString + "\"");
Locale subtagDefault = createLocale(subtagDefaultString);
- EXPECT_EQ(Locale::EMSTYLE_DEFAULT, subtagDefault.getEmojiStyle());
+ EXPECT_EQ(EmojiStyle::DEFAULT, subtagDefault.getEmojiStyle());
}
}
@@ -435,7 +435,7 @@ TEST(LocaleListTest, subtagEmptyTest) {
for (auto subtagEmptyString : subtagEmptyStrings) {
SCOPED_TRACE("Test for \"" + subtagEmptyString + "\"");
Locale subtagEmpty = createLocale(subtagEmptyString);
- EXPECT_EQ(Locale::EMSTYLE_EMPTY, subtagEmpty.getEmojiStyle());
+ EXPECT_EQ(EmojiStyle::EMPTY, subtagEmpty.getEmojiStyle());
}
}
diff --git a/tests/util/FontTestUtils.cpp b/tests/util/FontTestUtils.cpp
index 699d53b..fea19bd 100644
--- a/tests/util/FontTestUtils.cpp
+++ b/tests/util/FontTestUtils.cpp
@@ -26,6 +26,7 @@
#include "FontTestUtils.h"
#include "FreeTypeMinikinFontForTest.h"
+#include "LocaleListCache.h"
#include "MinikinInternal.h"
namespace minikin {
@@ -130,4 +131,12 @@ std::shared_ptr<FontFamily> buildFontFamily(const std::string& filePath) {
return std::make_shared<FontFamily>(std::move(fonts));
}
+std::shared_ptr<FontFamily> buildFontFamily(const std::string& filePath, const std::string& lang) {
+ auto font = std::make_shared<FreeTypeMinikinFontForTest>(filePath);
+ std::vector<Font> fonts;
+ fonts.push_back(Font::Builder(font).build());
+ return std::make_shared<FontFamily>(LocaleListCache::getId(lang), FontFamily::Variant::DEFAULT,
+ std::move(fonts));
+}
+
} // namespace minikin
diff --git a/tests/util/FontTestUtils.h b/tests/util/FontTestUtils.h
index 532ed71..b28603d 100644
--- a/tests/util/FontTestUtils.h
+++ b/tests/util/FontTestUtils.h
@@ -47,5 +47,10 @@ std::shared_ptr<FontCollection> buildFontCollection(const std::string& filePath)
*/
std::shared_ptr<FontFamily> buildFontFamily(const std::string& filePath);
+/**
+ * Build new FontFamily from single file with locale.
+ */
+std::shared_ptr<FontFamily> buildFontFamily(const std::string& filePath, const std::string& lang);
+
} // namespace minikin
#endif // MINIKIN_FONT_TEST_UTILS_H