xref: /aosp_15_r20/frameworks/minikin/tests/unittest/FontFamilyTest.cpp (revision 834a2baab5fdfc28e9a428ee87c7ea8f6a06a53d)
1*834a2baaSAndroid Build Coastguard Worker /*
2*834a2baaSAndroid Build Coastguard Worker  * Copyright (C) 2015 The Android Open Source Project
3*834a2baaSAndroid Build Coastguard Worker  *
4*834a2baaSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*834a2baaSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*834a2baaSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*834a2baaSAndroid Build Coastguard Worker  *
8*834a2baaSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*834a2baaSAndroid Build Coastguard Worker  *
10*834a2baaSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*834a2baaSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*834a2baaSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*834a2baaSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*834a2baaSAndroid Build Coastguard Worker  * limitations under the License.
15*834a2baaSAndroid Build Coastguard Worker  */
16*834a2baaSAndroid Build Coastguard Worker 
17*834a2baaSAndroid Build Coastguard Worker #include <gtest/gtest.h>
18*834a2baaSAndroid Build Coastguard Worker #include <malloc.h>
19*834a2baaSAndroid Build Coastguard Worker 
20*834a2baaSAndroid Build Coastguard Worker #include "BufferUtils.h"
21*834a2baaSAndroid Build Coastguard Worker #include "FontTestUtils.h"
22*834a2baaSAndroid Build Coastguard Worker #include "FreeTypeMinikinFontForTest.h"
23*834a2baaSAndroid Build Coastguard Worker #include "LocaleListCache.h"
24*834a2baaSAndroid Build Coastguard Worker #include "MinikinInternal.h"
25*834a2baaSAndroid Build Coastguard Worker #include "minikin/Constants.h"
26*834a2baaSAndroid Build Coastguard Worker #include "minikin/FontFamily.h"
27*834a2baaSAndroid Build Coastguard Worker #include "minikin/LocaleList.h"
28*834a2baaSAndroid Build Coastguard Worker 
29*834a2baaSAndroid Build Coastguard Worker namespace minikin {
30*834a2baaSAndroid Build Coastguard Worker 
createLocaleList(const std::string & input)31*834a2baaSAndroid Build Coastguard Worker static const LocaleList& createLocaleList(const std::string& input) {
32*834a2baaSAndroid Build Coastguard Worker     uint32_t localeListId = LocaleListCache::getId(input);
33*834a2baaSAndroid Build Coastguard Worker     return LocaleListCache::getById(localeListId);
34*834a2baaSAndroid Build Coastguard Worker }
35*834a2baaSAndroid Build Coastguard Worker 
createLocale(const std::string & input)36*834a2baaSAndroid Build Coastguard Worker static Locale createLocale(const std::string& input) {
37*834a2baaSAndroid Build Coastguard Worker     uint32_t localeListId = LocaleListCache::getId(input);
38*834a2baaSAndroid Build Coastguard Worker     return LocaleListCache::getById(localeListId)[0];
39*834a2baaSAndroid Build Coastguard Worker }
40*834a2baaSAndroid Build Coastguard Worker 
createLocaleWithoutICUSanitization(const std::string & input)41*834a2baaSAndroid Build Coastguard Worker static Locale createLocaleWithoutICUSanitization(const std::string& input) {
42*834a2baaSAndroid Build Coastguard Worker     return Locale(input);
43*834a2baaSAndroid Build Coastguard Worker }
44*834a2baaSAndroid Build Coastguard Worker 
TEST(LocaleTest,basicTests)45*834a2baaSAndroid Build Coastguard Worker TEST(LocaleTest, basicTests) {
46*834a2baaSAndroid Build Coastguard Worker     Locale defaultLocale;
47*834a2baaSAndroid Build Coastguard Worker     Locale emptyLocale("");
48*834a2baaSAndroid Build Coastguard Worker     Locale english = createLocale("en");
49*834a2baaSAndroid Build Coastguard Worker     Locale french = createLocale("fr");
50*834a2baaSAndroid Build Coastguard Worker     Locale und = createLocale("und");
51*834a2baaSAndroid Build Coastguard Worker     Locale undZsye = createLocale("und-Zsye");
52*834a2baaSAndroid Build Coastguard Worker 
53*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ(english, english);
54*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ(french, french);
55*834a2baaSAndroid Build Coastguard Worker 
56*834a2baaSAndroid Build Coastguard Worker     EXPECT_TRUE(defaultLocale != defaultLocale);
57*834a2baaSAndroid Build Coastguard Worker     EXPECT_TRUE(emptyLocale != emptyLocale);
58*834a2baaSAndroid Build Coastguard Worker     EXPECT_TRUE(defaultLocale != emptyLocale);
59*834a2baaSAndroid Build Coastguard Worker     EXPECT_TRUE(defaultLocale != und);
60*834a2baaSAndroid Build Coastguard Worker     EXPECT_TRUE(emptyLocale != und);
61*834a2baaSAndroid Build Coastguard Worker     EXPECT_TRUE(english != defaultLocale);
62*834a2baaSAndroid Build Coastguard Worker     EXPECT_TRUE(english != emptyLocale);
63*834a2baaSAndroid Build Coastguard Worker     EXPECT_TRUE(english != french);
64*834a2baaSAndroid Build Coastguard Worker     EXPECT_TRUE(english != undZsye);
65*834a2baaSAndroid Build Coastguard Worker     EXPECT_TRUE(und != undZsye);
66*834a2baaSAndroid Build Coastguard Worker     EXPECT_TRUE(english != und);
67*834a2baaSAndroid Build Coastguard Worker     EXPECT_TRUE(createLocale("de-1901") != createLocale("de-1996"));
68*834a2baaSAndroid Build Coastguard Worker 
69*834a2baaSAndroid Build Coastguard Worker     EXPECT_TRUE(defaultLocale.isUnsupported());
70*834a2baaSAndroid Build Coastguard Worker     EXPECT_TRUE(emptyLocale.isUnsupported());
71*834a2baaSAndroid Build Coastguard Worker 
72*834a2baaSAndroid Build Coastguard Worker     EXPECT_FALSE(english.isUnsupported());
73*834a2baaSAndroid Build Coastguard Worker     EXPECT_FALSE(french.isUnsupported());
74*834a2baaSAndroid Build Coastguard Worker     EXPECT_FALSE(und.isUnsupported());
75*834a2baaSAndroid Build Coastguard Worker     EXPECT_FALSE(undZsye.isUnsupported());
76*834a2baaSAndroid Build Coastguard Worker }
77*834a2baaSAndroid Build Coastguard Worker 
TEST(LocaleTest,getStringTest)78*834a2baaSAndroid Build Coastguard Worker TEST(LocaleTest, getStringTest) {
79*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("en-Latn-US", createLocale("en").getString());
80*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("en-Latn-US", createLocale("en-Latn").getString());
81*834a2baaSAndroid Build Coastguard Worker 
82*834a2baaSAndroid Build Coastguard Worker     // Capitalized language code or lowercased script should be normalized.
83*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("en-Latn-US", createLocale("EN-LATN").getString());
84*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("en-Latn-US", createLocale("EN-latn").getString());
85*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("en-Latn-US", createLocale("en-latn").getString());
86*834a2baaSAndroid Build Coastguard Worker 
87*834a2baaSAndroid Build Coastguard Worker     // Invalid script should be kept.
88*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("en-Xyzt-US", createLocale("en-xyzt").getString());
89*834a2baaSAndroid Build Coastguard Worker 
90*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("en-Latn-US", createLocale("en-Latn-US").getString());
91*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("ja-Jpan-JP", createLocale("ja").getString());
92*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("zh-Hant-TW", createLocale("zh-TW").getString());
93*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("zh-Hant-HK", createLocale("zh-HK").getString());
94*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("zh-Hant-MO", createLocale("zh-MO").getString());
95*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("zh-Hans-CN", createLocale("zh").getString());
96*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("zh-Hans-CN", createLocale("zh-CN").getString());
97*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("zh-Hans-SG", createLocale("zh-SG").getString());
98*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("und", createLocale("und").getString());
99*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("und", createLocale("UND").getString());
100*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("und", createLocale("Und").getString());
101*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("und-Zsye", createLocale("und-Zsye").getString());
102*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("und-Zsye", createLocale("Und-ZSYE").getString());
103*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("und-Zsye", createLocale("Und-zsye").getString());
104*834a2baaSAndroid Build Coastguard Worker 
105*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("es-Latn-419", createLocale("es-Latn-419").getString());
106*834a2baaSAndroid Build Coastguard Worker 
107*834a2baaSAndroid Build Coastguard Worker     // Variant
108*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("de-Latn-DE", createLocale("de").getString());
109*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("de-Latn-DE-1901", createLocale("de-1901").getString());
110*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("de-Latn-DE-1996", createLocale("de-DE-1996").getString());
111*834a2baaSAndroid Build Coastguard Worker 
112*834a2baaSAndroid Build Coastguard Worker     // Line Break subtag is dropped from getString().
113*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("ja-Jpan-JP", createLocale("ja-JP-u-lb-loose").getString());
114*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("ja-Jpan-JP", createLocale("ja-JP-u-lb-normal").getString());
115*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("ja-Jpan-JP", createLocale("ja-JP-u-lb-strict").getString());
116*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("ja-Jpan-JP", createLocale("ja-JP-u-lb-loose-em-emoji").getString());
117*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("ja-Jpan-JP", createLocale("ja-JP-u-em-default-lb-strict").getString());
118*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("ja-Jpan-JP", createLocale("ja-JP-u-lb-bogus").getString());
119*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("ja-Jpan-JP", createLocale("ja-JP-u-lw-phrase").getString());
120*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("ja-Jpan-JP", createLocale("ja-JP-u-lb-normal-lw-phrase").getString());
121*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("ja-Jpan-JP", createLocale("ja-JP-u-lb-strict-lw-phrase").getString());
122*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("ja-Jpan-JP", createLocale("ja-JP-u-lb-loose-lw-phrase-em-emoji").getString());
123*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("ja-Jpan-JP", createLocale("ja-JP-u-em-default-lb-strict-lw-phrase").getString());
124*834a2baaSAndroid Build Coastguard Worker 
125*834a2baaSAndroid Build Coastguard Worker     // Emoji subtag is dropped from getString().
126*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("es-Latn-419", createLocale("es-419-u-em-emoji").getString());
127*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("es-Latn-419", createLocale("es-Latn-419-u-em-emoji").getString());
128*834a2baaSAndroid Build Coastguard Worker 
129*834a2baaSAndroid Build Coastguard Worker     // This is not a necessary desired behavior, just known behavior.
130*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("en-Latn-US", createLocale("und-Abcdefgh").getString());
131*834a2baaSAndroid Build Coastguard Worker }
132*834a2baaSAndroid Build Coastguard Worker 
TEST(LocaleTest,getStringWithLineBreakOptionTest)133*834a2baaSAndroid Build Coastguard Worker TEST(LocaleTest, getStringWithLineBreakOptionTest) {
134*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("en-Latn-US", createLocale("en").getStringWithLineBreakOption(
135*834a2baaSAndroid Build Coastguard Worker                                     LineBreakStyle::None, LineBreakWordStyle::None));
136*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("en-Latn-US-u-lb-loose", createLocale("en").getStringWithLineBreakOption(
137*834a2baaSAndroid Build Coastguard Worker                                                LineBreakStyle::Loose, LineBreakWordStyle::None));
138*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("en-Latn-US-u-lb-normal", createLocale("en").getStringWithLineBreakOption(
139*834a2baaSAndroid Build Coastguard Worker                                                 LineBreakStyle::Normal, LineBreakWordStyle::None));
140*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("en-Latn-US-u-lb-strict", createLocale("en").getStringWithLineBreakOption(
141*834a2baaSAndroid Build Coastguard Worker                                                 LineBreakStyle::Strict, LineBreakWordStyle::None));
142*834a2baaSAndroid Build Coastguard Worker 
143*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("en-Latn-US-u-lw-phrase", createLocale("en").getStringWithLineBreakOption(
144*834a2baaSAndroid Build Coastguard Worker                                                 LineBreakStyle::None, LineBreakWordStyle::Phrase));
145*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("en-Latn-US-u-lb-loose-lw-phrase",
146*834a2baaSAndroid Build Coastguard Worker               createLocale("en").getStringWithLineBreakOption(LineBreakStyle::Loose,
147*834a2baaSAndroid Build Coastguard Worker                                                               LineBreakWordStyle::Phrase));
148*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("en-Latn-US-u-lb-normal-lw-phrase",
149*834a2baaSAndroid Build Coastguard Worker               createLocale("en").getStringWithLineBreakOption(LineBreakStyle::Normal,
150*834a2baaSAndroid Build Coastguard Worker                                                               LineBreakWordStyle::Phrase));
151*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("en-Latn-US-u-lb-strict-lw-phrase",
152*834a2baaSAndroid Build Coastguard Worker               createLocale("en").getStringWithLineBreakOption(LineBreakStyle::Strict,
153*834a2baaSAndroid Build Coastguard Worker                                                               LineBreakWordStyle::Phrase));
154*834a2baaSAndroid Build Coastguard Worker }
155*834a2baaSAndroid Build Coastguard Worker 
TEST(LocaleTest,invalidLanguageTagTest)156*834a2baaSAndroid Build Coastguard Worker TEST(LocaleTest, invalidLanguageTagTest) {  // just make sure no crash happens
157*834a2baaSAndroid Build Coastguard Worker     LocaleListCache::getId("ja-JP-u-lb-lb-strict");
158*834a2baaSAndroid Build Coastguard Worker }
159*834a2baaSAndroid Build Coastguard Worker 
TEST(LocaleTest,testReconstruction)160*834a2baaSAndroid Build Coastguard Worker TEST(LocaleTest, testReconstruction) {
161*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("en", createLocaleWithoutICUSanitization("en").getString());
162*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("fil", createLocaleWithoutICUSanitization("fil").getString());
163*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("und", createLocaleWithoutICUSanitization("und").getString());
164*834a2baaSAndroid Build Coastguard Worker 
165*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("en-Latn", createLocaleWithoutICUSanitization("en-Latn").getString());
166*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("fil-Taga", createLocaleWithoutICUSanitization("fil-Taga").getString());
167*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("und-Zsye", createLocaleWithoutICUSanitization("und-Zsye").getString());
168*834a2baaSAndroid Build Coastguard Worker 
169*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("en-US", createLocaleWithoutICUSanitization("en-US").getString());
170*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("fil-PH", createLocaleWithoutICUSanitization("fil-PH").getString());
171*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("es-419", createLocaleWithoutICUSanitization("es-419").getString());
172*834a2baaSAndroid Build Coastguard Worker 
173*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("en-Latn-US", createLocaleWithoutICUSanitization("en-Latn-US").getString());
174*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("fil-Taga-PH", createLocaleWithoutICUSanitization("fil-Taga-PH").getString());
175*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("es-Latn-419", createLocaleWithoutICUSanitization("es-Latn-419").getString());
176*834a2baaSAndroid Build Coastguard Worker 
177*834a2baaSAndroid Build Coastguard Worker     // Possible minimum/maximum values.
178*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("aa", createLocaleWithoutICUSanitization("aa").getString());
179*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("zz", createLocaleWithoutICUSanitization("zz").getString());
180*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("aa-Aaaa", createLocaleWithoutICUSanitization("aa-Aaaa").getString());
181*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("zz-Zzzz", createLocaleWithoutICUSanitization("zz-Zzzz").getString());
182*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("aaa-Aaaa-AA", createLocaleWithoutICUSanitization("aaa-Aaaa-AA").getString());
183*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("zzz-Zzzz-ZZ", createLocaleWithoutICUSanitization("zzz-Zzzz-ZZ").getString());
184*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("aaa-Aaaa-000", createLocaleWithoutICUSanitization("aaa-Aaaa-000").getString());
185*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ("zzz-Zzzz-999", createLocaleWithoutICUSanitization("zzz-Zzzz-999").getString());
186*834a2baaSAndroid Build Coastguard Worker }
187*834a2baaSAndroid Build Coastguard Worker 
TEST(LocaleTest,ReconstructFromIdentifierTest)188*834a2baaSAndroid Build Coastguard Worker TEST(LocaleTest, ReconstructFromIdentifierTest) {
189*834a2baaSAndroid Build Coastguard Worker     std::string locales[] = {
190*834a2baaSAndroid Build Coastguard Worker             // Language
191*834a2baaSAndroid Build Coastguard Worker             "en",
192*834a2baaSAndroid Build Coastguard Worker             "fil",
193*834a2baaSAndroid Build Coastguard Worker             "und",
194*834a2baaSAndroid Build Coastguard Worker             // Script
195*834a2baaSAndroid Build Coastguard Worker             "en-Latn",
196*834a2baaSAndroid Build Coastguard Worker             "fil-Taga",
197*834a2baaSAndroid Build Coastguard Worker             "und-Zsye",
198*834a2baaSAndroid Build Coastguard Worker             // Region
199*834a2baaSAndroid Build Coastguard Worker             "en-US",
200*834a2baaSAndroid Build Coastguard Worker             "fil-PH",
201*834a2baaSAndroid Build Coastguard Worker             "es-419",
202*834a2baaSAndroid Build Coastguard Worker             // Variant
203*834a2baaSAndroid Build Coastguard Worker             "de-Latn-DE",
204*834a2baaSAndroid Build Coastguard Worker             "de-Latn-DE-1901",
205*834a2baaSAndroid Build Coastguard Worker             "de-Latn-DE-1996",
206*834a2baaSAndroid Build Coastguard Worker             // Line break style
207*834a2baaSAndroid Build Coastguard Worker             "ja-JP-u-lb-loose",
208*834a2baaSAndroid Build Coastguard Worker             "ja-JP-u-lb-normal",
209*834a2baaSAndroid Build Coastguard Worker             "ja-JP-u-lb-strict",
210*834a2baaSAndroid Build Coastguard Worker             // Emoji subtag
211*834a2baaSAndroid Build Coastguard Worker             "es-Latn-419-u-em-emoji",
212*834a2baaSAndroid Build Coastguard Worker             // Everything
213*834a2baaSAndroid Build Coastguard Worker             "de-Latn-DE-1996-u-lb-loose-u-em-emoji",
214*834a2baaSAndroid Build Coastguard Worker     };
215*834a2baaSAndroid Build Coastguard Worker     for (const std::string& locale : locales) {
216*834a2baaSAndroid Build Coastguard Worker         EXPECT_EQ(createLocaleWithoutICUSanitization(locale),
217*834a2baaSAndroid Build Coastguard Worker                   Locale(createLocaleWithoutICUSanitization(locale).getIdentifier()))
218*834a2baaSAndroid Build Coastguard Worker                 << "locale = " << locale;
219*834a2baaSAndroid Build Coastguard Worker     }
220*834a2baaSAndroid Build Coastguard Worker }
221*834a2baaSAndroid Build Coastguard Worker 
TEST(LocaleTest,ScriptEqualTest)222*834a2baaSAndroid Build Coastguard Worker TEST(LocaleTest, ScriptEqualTest) {
223*834a2baaSAndroid Build Coastguard Worker     EXPECT_TRUE(createLocale("en").isEqualScript(createLocale("en")));
224*834a2baaSAndroid Build Coastguard Worker     EXPECT_TRUE(createLocale("en-Latn").isEqualScript(createLocale("en")));
225*834a2baaSAndroid Build Coastguard Worker     EXPECT_TRUE(createLocale("jp-Latn").isEqualScript(createLocale("en-Latn")));
226*834a2baaSAndroid Build Coastguard Worker     EXPECT_TRUE(createLocale("en-Jpan").isEqualScript(createLocale("en-Jpan")));
227*834a2baaSAndroid Build Coastguard Worker 
228*834a2baaSAndroid Build Coastguard Worker     EXPECT_FALSE(createLocale("en-Jpan").isEqualScript(createLocale("en-Hira")));
229*834a2baaSAndroid Build Coastguard Worker     EXPECT_FALSE(createLocale("en-Jpan").isEqualScript(createLocale("en-Hani")));
230*834a2baaSAndroid Build Coastguard Worker }
231*834a2baaSAndroid Build Coastguard Worker 
TEST(LocaleTest,ScriptMatchTest)232*834a2baaSAndroid Build Coastguard Worker TEST(LocaleTest, ScriptMatchTest) {
233*834a2baaSAndroid Build Coastguard Worker     const bool SUPPORTED = true;
234*834a2baaSAndroid Build Coastguard Worker     const bool NOT_SUPPORTED = false;
235*834a2baaSAndroid Build Coastguard Worker 
236*834a2baaSAndroid Build Coastguard Worker     struct TestCase {
237*834a2baaSAndroid Build Coastguard Worker         const std::string baseScript;
238*834a2baaSAndroid Build Coastguard Worker         const std::string requestedScript;
239*834a2baaSAndroid Build Coastguard Worker         bool isSupported;
240*834a2baaSAndroid Build Coastguard Worker     } testCases[] = {
241*834a2baaSAndroid Build Coastguard Worker             // Same scripts
242*834a2baaSAndroid Build Coastguard Worker             {"en-Latn", "Latn", SUPPORTED},
243*834a2baaSAndroid Build Coastguard Worker             {"ja-Jpan", "Jpan", SUPPORTED},
244*834a2baaSAndroid Build Coastguard Worker             {"ja-Hira", "Hira", SUPPORTED},
245*834a2baaSAndroid Build Coastguard Worker             {"ja-Kana", "Kana", SUPPORTED},
246*834a2baaSAndroid Build Coastguard Worker             {"ja-Hrkt", "Hrkt", SUPPORTED},
247*834a2baaSAndroid Build Coastguard Worker             {"zh-Hans", "Hans", SUPPORTED},
248*834a2baaSAndroid Build Coastguard Worker             {"zh-Hant", "Hant", SUPPORTED},
249*834a2baaSAndroid Build Coastguard Worker             {"zh-Hani", "Hani", SUPPORTED},
250*834a2baaSAndroid Build Coastguard Worker             {"ko-Kore", "Kore", SUPPORTED},
251*834a2baaSAndroid Build Coastguard Worker             {"ko-Hang", "Hang", SUPPORTED},
252*834a2baaSAndroid Build Coastguard Worker             {"zh-Hanb", "Hanb", SUPPORTED},
253*834a2baaSAndroid Build Coastguard Worker 
254*834a2baaSAndroid Build Coastguard Worker             // Japanese supports Hiragana, Katakanara, etc.
255*834a2baaSAndroid Build Coastguard Worker             {"ja-Jpan", "Hira", SUPPORTED},
256*834a2baaSAndroid Build Coastguard Worker             {"ja-Jpan", "Kana", SUPPORTED},
257*834a2baaSAndroid Build Coastguard Worker             {"ja-Jpan", "Hrkt", SUPPORTED},
258*834a2baaSAndroid Build Coastguard Worker             {"ja-Hrkt", "Hira", SUPPORTED},
259*834a2baaSAndroid Build Coastguard Worker             {"ja-Hrkt", "Kana", SUPPORTED},
260*834a2baaSAndroid Build Coastguard Worker 
261*834a2baaSAndroid Build Coastguard Worker             // Chinese supports Han.
262*834a2baaSAndroid Build Coastguard Worker             {"zh-Hans", "Hani", SUPPORTED},
263*834a2baaSAndroid Build Coastguard Worker             {"zh-Hant", "Hani", SUPPORTED},
264*834a2baaSAndroid Build Coastguard Worker             {"zh-Hanb", "Hani", SUPPORTED},
265*834a2baaSAndroid Build Coastguard Worker 
266*834a2baaSAndroid Build Coastguard Worker             // Hanb supports Bopomofo.
267*834a2baaSAndroid Build Coastguard Worker             {"zh-Hanb", "Bopo", SUPPORTED},
268*834a2baaSAndroid Build Coastguard Worker 
269*834a2baaSAndroid Build Coastguard Worker             // Korean supports Hangul.
270*834a2baaSAndroid Build Coastguard Worker             {"ko-Kore", "Hang", SUPPORTED},
271*834a2baaSAndroid Build Coastguard Worker 
272*834a2baaSAndroid Build Coastguard Worker             // Different scripts
273*834a2baaSAndroid Build Coastguard Worker             {"ja-Jpan", "Latn", NOT_SUPPORTED},
274*834a2baaSAndroid Build Coastguard Worker             {"en-Latn", "Jpan", NOT_SUPPORTED},
275*834a2baaSAndroid Build Coastguard Worker             {"ja-Jpan", "Hant", NOT_SUPPORTED},
276*834a2baaSAndroid Build Coastguard Worker             {"zh-Hant", "Jpan", NOT_SUPPORTED},
277*834a2baaSAndroid Build Coastguard Worker             {"ja-Jpan", "Hans", NOT_SUPPORTED},
278*834a2baaSAndroid Build Coastguard Worker             {"zh-Hans", "Jpan", NOT_SUPPORTED},
279*834a2baaSAndroid Build Coastguard Worker             {"ja-Jpan", "Kore", NOT_SUPPORTED},
280*834a2baaSAndroid Build Coastguard Worker             {"ko-Kore", "Jpan", NOT_SUPPORTED},
281*834a2baaSAndroid Build Coastguard Worker             {"zh-Hans", "Hant", NOT_SUPPORTED},
282*834a2baaSAndroid Build Coastguard Worker             {"zh-Hant", "Hans", NOT_SUPPORTED},
283*834a2baaSAndroid Build Coastguard Worker             {"zh-Hans", "Kore", NOT_SUPPORTED},
284*834a2baaSAndroid Build Coastguard Worker             {"ko-Kore", "Hans", NOT_SUPPORTED},
285*834a2baaSAndroid Build Coastguard Worker             {"zh-Hant", "Kore", NOT_SUPPORTED},
286*834a2baaSAndroid Build Coastguard Worker             {"ko-Kore", "Hant", NOT_SUPPORTED},
287*834a2baaSAndroid Build Coastguard Worker 
288*834a2baaSAndroid Build Coastguard Worker             // Hiragana doesn't support Japanese, etc.
289*834a2baaSAndroid Build Coastguard Worker             {"ja-Hira", "Jpan", NOT_SUPPORTED},
290*834a2baaSAndroid Build Coastguard Worker             {"ja-Kana", "Jpan", NOT_SUPPORTED},
291*834a2baaSAndroid Build Coastguard Worker             {"ja-Hrkt", "Jpan", NOT_SUPPORTED},
292*834a2baaSAndroid Build Coastguard Worker             {"ja-Hani", "Jpan", NOT_SUPPORTED},
293*834a2baaSAndroid Build Coastguard Worker             {"ja-Hira", "Hrkt", NOT_SUPPORTED},
294*834a2baaSAndroid Build Coastguard Worker             {"ja-Kana", "Hrkt", NOT_SUPPORTED},
295*834a2baaSAndroid Build Coastguard Worker             {"ja-Hani", "Hrkt", NOT_SUPPORTED},
296*834a2baaSAndroid Build Coastguard Worker             {"ja-Hani", "Hira", NOT_SUPPORTED},
297*834a2baaSAndroid Build Coastguard Worker             {"ja-Hani", "Kana", NOT_SUPPORTED},
298*834a2baaSAndroid Build Coastguard Worker 
299*834a2baaSAndroid Build Coastguard Worker             // Kanji doesn't support Chinese, etc.
300*834a2baaSAndroid Build Coastguard Worker             {"zh-Hani", "Hant", NOT_SUPPORTED},
301*834a2baaSAndroid Build Coastguard Worker             {"zh-Hani", "Hans", NOT_SUPPORTED},
302*834a2baaSAndroid Build Coastguard Worker             {"zh-Hani", "Hanb", NOT_SUPPORTED},
303*834a2baaSAndroid Build Coastguard Worker 
304*834a2baaSAndroid Build Coastguard Worker             // Hangul doesn't support Korean, etc.
305*834a2baaSAndroid Build Coastguard Worker             {"ko-Hang", "Kore", NOT_SUPPORTED},
306*834a2baaSAndroid Build Coastguard Worker             {"ko-Hani", "Kore", NOT_SUPPORTED},
307*834a2baaSAndroid Build Coastguard Worker             {"ko-Hani", "Hang", NOT_SUPPORTED},
308*834a2baaSAndroid Build Coastguard Worker             {"ko-Hang", "Hani", NOT_SUPPORTED},
309*834a2baaSAndroid Build Coastguard Worker 
310*834a2baaSAndroid Build Coastguard Worker             // Han with botomofo doesn't support simplified Chinese, etc.
311*834a2baaSAndroid Build Coastguard Worker             {"zh-Hanb", "Hant", NOT_SUPPORTED},
312*834a2baaSAndroid Build Coastguard Worker             {"zh-Hanb", "Hans", NOT_SUPPORTED},
313*834a2baaSAndroid Build Coastguard Worker             {"zh-Hanb", "Jpan", NOT_SUPPORTED},
314*834a2baaSAndroid Build Coastguard Worker             {"zh-Hanb", "Kore", NOT_SUPPORTED},
315*834a2baaSAndroid Build Coastguard Worker     };
316*834a2baaSAndroid Build Coastguard Worker 
317*834a2baaSAndroid Build Coastguard Worker     for (const auto& testCase : testCases) {
318*834a2baaSAndroid Build Coastguard Worker         uint32_t script = HB_TAG(testCase.requestedScript[0], testCase.requestedScript[1],
319*834a2baaSAndroid Build Coastguard Worker                                  testCase.requestedScript[2], testCase.requestedScript[3]);
320*834a2baaSAndroid Build Coastguard Worker         if (testCase.isSupported) {
321*834a2baaSAndroid Build Coastguard Worker             EXPECT_TRUE(createLocale(testCase.baseScript).supportsScript(script))
322*834a2baaSAndroid Build Coastguard Worker                     << testCase.baseScript << " should support " << testCase.requestedScript;
323*834a2baaSAndroid Build Coastguard Worker         } else {
324*834a2baaSAndroid Build Coastguard Worker             EXPECT_FALSE(createLocale(testCase.baseScript).supportsScript(script))
325*834a2baaSAndroid Build Coastguard Worker                     << testCase.baseScript << " shouldn't support " << testCase.requestedScript;
326*834a2baaSAndroid Build Coastguard Worker         }
327*834a2baaSAndroid Build Coastguard Worker     }
328*834a2baaSAndroid Build Coastguard Worker }
329*834a2baaSAndroid Build Coastguard Worker 
TEST(LocaleListTest,basicTests)330*834a2baaSAndroid Build Coastguard Worker TEST(LocaleListTest, basicTests) {
331*834a2baaSAndroid Build Coastguard Worker     LocaleList emptyLocales;
332*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ(0u, emptyLocales.size());
333*834a2baaSAndroid Build Coastguard Worker 
334*834a2baaSAndroid Build Coastguard Worker     Locale english = createLocale("en");
335*834a2baaSAndroid Build Coastguard Worker     const LocaleList& singletonLocales = createLocaleList("en");
336*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ(1u, singletonLocales.size());
337*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ(english, singletonLocales[0]);
338*834a2baaSAndroid Build Coastguard Worker 
339*834a2baaSAndroid Build Coastguard Worker     Locale french = createLocale("fr");
340*834a2baaSAndroid Build Coastguard Worker     const LocaleList& twoLocales = createLocaleList("en,fr");
341*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ(2u, twoLocales.size());
342*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ(english, twoLocales[0]);
343*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ(french, twoLocales[1]);
344*834a2baaSAndroid Build Coastguard Worker }
345*834a2baaSAndroid Build Coastguard Worker 
TEST(LocaleListTest,unsupportedLocaleuageTests)346*834a2baaSAndroid Build Coastguard Worker TEST(LocaleListTest, unsupportedLocaleuageTests) {
347*834a2baaSAndroid Build Coastguard Worker     const LocaleList& oneUnsupported = createLocaleList("abcd-example");
348*834a2baaSAndroid Build Coastguard Worker     EXPECT_TRUE(oneUnsupported.empty());
349*834a2baaSAndroid Build Coastguard Worker 
350*834a2baaSAndroid Build Coastguard Worker     const LocaleList& twoUnsupporteds = createLocaleList("abcd-example,abcd-example");
351*834a2baaSAndroid Build Coastguard Worker     EXPECT_TRUE(twoUnsupporteds.empty());
352*834a2baaSAndroid Build Coastguard Worker 
353*834a2baaSAndroid Build Coastguard Worker     Locale english = createLocale("en");
354*834a2baaSAndroid Build Coastguard Worker     const LocaleList& firstUnsupported = createLocaleList("abcd-example,en");
355*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ(1u, firstUnsupported.size());
356*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ(english, firstUnsupported[0]);
357*834a2baaSAndroid Build Coastguard Worker 
358*834a2baaSAndroid Build Coastguard Worker     const LocaleList& lastUnsupported = createLocaleList("en,abcd-example");
359*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ(1u, lastUnsupported.size());
360*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ(english, lastUnsupported[0]);
361*834a2baaSAndroid Build Coastguard Worker }
362*834a2baaSAndroid Build Coastguard Worker 
TEST(LocaleListTest,repeatedLocaleuageTests)363*834a2baaSAndroid Build Coastguard Worker TEST(LocaleListTest, repeatedLocaleuageTests) {
364*834a2baaSAndroid Build Coastguard Worker     Locale english = createLocale("en");
365*834a2baaSAndroid Build Coastguard Worker     Locale french = createLocale("fr");
366*834a2baaSAndroid Build Coastguard Worker     Locale canadianFrench = createLocale("fr-CA");
367*834a2baaSAndroid Build Coastguard Worker     Locale englishInLatn = createLocale("en-Latn");
368*834a2baaSAndroid Build Coastguard Worker     ASSERT_TRUE(english == englishInLatn);
369*834a2baaSAndroid Build Coastguard Worker 
370*834a2baaSAndroid Build Coastguard Worker     const LocaleList& locales = createLocaleList("en,en-Latn");
371*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ(1u, locales.size());
372*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ(english, locales[0]);
373*834a2baaSAndroid Build Coastguard Worker 
374*834a2baaSAndroid Build Coastguard Worker     const LocaleList& fr = createLocaleList("fr,fr-FR,fr-Latn-FR");
375*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ(1u, fr.size());
376*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ(french, fr[0]);
377*834a2baaSAndroid Build Coastguard Worker 
378*834a2baaSAndroid Build Coastguard Worker     // ICU appends FR to fr. The third language is dropped which is same as the first language.
379*834a2baaSAndroid Build Coastguard Worker     const LocaleList& fr2 = createLocaleList("fr,fr-CA,fr-FR");
380*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ(2u, fr2.size());
381*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ(french, fr2[0]);
382*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ(canadianFrench, fr2[1]);
383*834a2baaSAndroid Build Coastguard Worker 
384*834a2baaSAndroid Build Coastguard Worker     // The order should be kept.
385*834a2baaSAndroid Build Coastguard Worker     const LocaleList& locales2 = createLocaleList("en,fr,en-Latn");
386*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ(2u, locales2.size());
387*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ(english, locales2[0]);
388*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ(french, locales2[1]);
389*834a2baaSAndroid Build Coastguard Worker }
390*834a2baaSAndroid Build Coastguard Worker 
TEST(LocaleListTest,identifierTest)391*834a2baaSAndroid Build Coastguard Worker TEST(LocaleListTest, identifierTest) {
392*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ(createLocale("en-Latn-US"), createLocale("en-Latn-US"));
393*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ(createLocale("zh-Hans-CN"), createLocale("zh-Hans-CN"));
394*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ(createLocale("en-Zsye-US"), createLocale("en-Zsye-US"));
395*834a2baaSAndroid Build Coastguard Worker 
396*834a2baaSAndroid Build Coastguard Worker     EXPECT_NE(createLocale("en-Latn-US"), createLocale("en-Latn-GB"));
397*834a2baaSAndroid Build Coastguard Worker     EXPECT_NE(createLocale("en-Latn-US"), createLocale("en-Zsye-US"));
398*834a2baaSAndroid Build Coastguard Worker     EXPECT_NE(createLocale("es-Latn-US"), createLocale("en-Latn-US"));
399*834a2baaSAndroid Build Coastguard Worker     EXPECT_NE(createLocale("zh-Hant-HK"), createLocale("zh-Hant-TW"));
400*834a2baaSAndroid Build Coastguard Worker }
401*834a2baaSAndroid Build Coastguard Worker 
TEST(LocaleListTest,undEmojiTests)402*834a2baaSAndroid Build Coastguard Worker TEST(LocaleListTest, undEmojiTests) {
403*834a2baaSAndroid Build Coastguard Worker     Locale emoji = createLocale("und-Zsye");
404*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ(EmojiStyle::EMOJI, emoji.getEmojiStyle());
405*834a2baaSAndroid Build Coastguard Worker 
406*834a2baaSAndroid Build Coastguard Worker     Locale und = createLocale("und");
407*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ(EmojiStyle::EMPTY, und.getEmojiStyle());
408*834a2baaSAndroid Build Coastguard Worker     EXPECT_FALSE(emoji == und);
409*834a2baaSAndroid Build Coastguard Worker 
410*834a2baaSAndroid Build Coastguard Worker     Locale undExample = createLocale("und-example");
411*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ(EmojiStyle::EMPTY, undExample.getEmojiStyle());
412*834a2baaSAndroid Build Coastguard Worker     EXPECT_FALSE(emoji == undExample);
413*834a2baaSAndroid Build Coastguard Worker }
414*834a2baaSAndroid Build Coastguard Worker 
TEST(LocaleListTest,subtagEmojiTest)415*834a2baaSAndroid Build Coastguard Worker TEST(LocaleListTest, subtagEmojiTest) {
416*834a2baaSAndroid Build Coastguard Worker     std::string subtagEmojiStrings[] = {
417*834a2baaSAndroid Build Coastguard Worker             // Duplicate subtag case.
418*834a2baaSAndroid Build Coastguard Worker             "und-Latn-u-em-emoji-u-em-text",
419*834a2baaSAndroid Build Coastguard Worker 
420*834a2baaSAndroid Build Coastguard Worker             // Strings that contain language.
421*834a2baaSAndroid Build Coastguard Worker             "und-u-em-emoji", "en-u-em-emoji",
422*834a2baaSAndroid Build Coastguard Worker 
423*834a2baaSAndroid Build Coastguard Worker             // Strings that contain the script.
424*834a2baaSAndroid Build Coastguard Worker             "und-Jpan-u-em-emoji", "en-Latn-u-em-emoji", "und-Zsym-u-em-emoji",
425*834a2baaSAndroid Build Coastguard Worker             "und-Zsye-u-em-emoji", "en-Zsym-u-em-emoji", "en-Zsye-u-em-emoji",
426*834a2baaSAndroid Build Coastguard Worker 
427*834a2baaSAndroid Build Coastguard Worker             // Strings that contain the country.
428*834a2baaSAndroid Build Coastguard Worker             "und-US-u-em-emoji", "en-US-u-em-emoji", "es-419-u-em-emoji", "und-Latn-US-u-em-emoji",
429*834a2baaSAndroid Build Coastguard Worker             "en-Zsym-US-u-em-emoji", "en-Zsye-US-u-em-emoji", "es-Zsye-419-u-em-emoji",
430*834a2baaSAndroid Build Coastguard Worker 
431*834a2baaSAndroid Build Coastguard Worker             // Strings that contain the variant.
432*834a2baaSAndroid Build Coastguard Worker             "de-Latn-DE-1901-u-em-emoji",
433*834a2baaSAndroid Build Coastguard Worker     };
434*834a2baaSAndroid Build Coastguard Worker 
435*834a2baaSAndroid Build Coastguard Worker     for (const auto& subtagEmojiString : subtagEmojiStrings) {
436*834a2baaSAndroid Build Coastguard Worker         SCOPED_TRACE("Test for \"" + subtagEmojiString + "\"");
437*834a2baaSAndroid Build Coastguard Worker         Locale subtagEmoji = createLocale(subtagEmojiString);
438*834a2baaSAndroid Build Coastguard Worker         EXPECT_EQ(EmojiStyle::EMOJI, subtagEmoji.getEmojiStyle());
439*834a2baaSAndroid Build Coastguard Worker     }
440*834a2baaSAndroid Build Coastguard Worker }
441*834a2baaSAndroid Build Coastguard Worker 
TEST(LocaleListTest,subtagTextTest)442*834a2baaSAndroid Build Coastguard Worker TEST(LocaleListTest, subtagTextTest) {
443*834a2baaSAndroid Build Coastguard Worker     std::string subtagTextStrings[] = {
444*834a2baaSAndroid Build Coastguard Worker             // Duplicate subtag case.
445*834a2baaSAndroid Build Coastguard Worker             "und-Latn-u-em-text-u-em-emoji",
446*834a2baaSAndroid Build Coastguard Worker 
447*834a2baaSAndroid Build Coastguard Worker             // Strings that contain language.
448*834a2baaSAndroid Build Coastguard Worker             "und-u-em-text", "en-u-em-text",
449*834a2baaSAndroid Build Coastguard Worker 
450*834a2baaSAndroid Build Coastguard Worker             // Strings that contain the script.
451*834a2baaSAndroid Build Coastguard Worker             "und-Latn-u-em-text", "en-Jpan-u-em-text", "und-Zsym-u-em-text", "und-Zsye-u-em-text",
452*834a2baaSAndroid Build Coastguard Worker             "en-Zsym-u-em-text", "en-Zsye-u-em-text",
453*834a2baaSAndroid Build Coastguard Worker 
454*834a2baaSAndroid Build Coastguard Worker             // Strings that contain the country.
455*834a2baaSAndroid Build Coastguard Worker             "und-US-u-em-text", "en-US-u-em-text", "es-419-u-em-text", "und-Latn-US-u-em-text",
456*834a2baaSAndroid Build Coastguard Worker             "en-Zsym-US-u-em-text", "en-Zsye-US-u-em-text", "es-Zsye-419-u-em-text",
457*834a2baaSAndroid Build Coastguard Worker 
458*834a2baaSAndroid Build Coastguard Worker             // Strings that contain the variant.
459*834a2baaSAndroid Build Coastguard Worker             "de-Latn-DE-1901-u-em-text",
460*834a2baaSAndroid Build Coastguard Worker     };
461*834a2baaSAndroid Build Coastguard Worker 
462*834a2baaSAndroid Build Coastguard Worker     for (const auto& subtagTextString : subtagTextStrings) {
463*834a2baaSAndroid Build Coastguard Worker         SCOPED_TRACE("Test for \"" + subtagTextString + "\"");
464*834a2baaSAndroid Build Coastguard Worker         Locale subtagText = createLocale(subtagTextString);
465*834a2baaSAndroid Build Coastguard Worker         EXPECT_EQ(EmojiStyle::TEXT, subtagText.getEmojiStyle());
466*834a2baaSAndroid Build Coastguard Worker     }
467*834a2baaSAndroid Build Coastguard Worker }
468*834a2baaSAndroid Build Coastguard Worker 
469*834a2baaSAndroid Build Coastguard Worker // TODO: add more "und" language cases whose language and script are
470*834a2baaSAndroid Build Coastguard Worker //       unexpectedly translated to en-Latn by ICU.
TEST(LocaleListTest,subtagDefaultTest)471*834a2baaSAndroid Build Coastguard Worker TEST(LocaleListTest, subtagDefaultTest) {
472*834a2baaSAndroid Build Coastguard Worker     std::string subtagDefaultStrings[] = {
473*834a2baaSAndroid Build Coastguard Worker             // Duplicate subtag case.
474*834a2baaSAndroid Build Coastguard Worker             "en-Latn-u-em-default-u-em-emoji", "en-Latn-u-em-default-u-em-text",
475*834a2baaSAndroid Build Coastguard Worker 
476*834a2baaSAndroid Build Coastguard Worker             // Strings that contain language.
477*834a2baaSAndroid Build Coastguard Worker             "und-u-em-default", "en-u-em-default",
478*834a2baaSAndroid Build Coastguard Worker 
479*834a2baaSAndroid Build Coastguard Worker             // Strings that contain the script.
480*834a2baaSAndroid Build Coastguard Worker             "en-Latn-u-em-default", "en-Zsym-u-em-default", "en-Zsye-u-em-default",
481*834a2baaSAndroid Build Coastguard Worker 
482*834a2baaSAndroid Build Coastguard Worker             // Strings that contain the country.
483*834a2baaSAndroid Build Coastguard Worker             "en-US-u-em-default", "en-Latn-US-u-em-default", "es-Latn-419-u-em-default",
484*834a2baaSAndroid Build Coastguard Worker             "en-Zsym-US-u-em-default", "en-Zsye-US-u-em-default", "es-Zsye-419-u-em-default",
485*834a2baaSAndroid Build Coastguard Worker 
486*834a2baaSAndroid Build Coastguard Worker             // Strings that contain the variant.
487*834a2baaSAndroid Build Coastguard Worker             "de-Latn-DE-1901-u-em-default",
488*834a2baaSAndroid Build Coastguard Worker     };
489*834a2baaSAndroid Build Coastguard Worker 
490*834a2baaSAndroid Build Coastguard Worker     for (const auto& subtagDefaultString : subtagDefaultStrings) {
491*834a2baaSAndroid Build Coastguard Worker         SCOPED_TRACE("Test for \"" + subtagDefaultString + "\"");
492*834a2baaSAndroid Build Coastguard Worker         Locale subtagDefault = createLocale(subtagDefaultString);
493*834a2baaSAndroid Build Coastguard Worker         EXPECT_EQ(EmojiStyle::DEFAULT, subtagDefault.getEmojiStyle());
494*834a2baaSAndroid Build Coastguard Worker     }
495*834a2baaSAndroid Build Coastguard Worker }
496*834a2baaSAndroid Build Coastguard Worker 
TEST(LocaleListTest,subtagEmptyTest)497*834a2baaSAndroid Build Coastguard Worker TEST(LocaleListTest, subtagEmptyTest) {
498*834a2baaSAndroid Build Coastguard Worker     std::string subtagEmptyStrings[] = {
499*834a2baaSAndroid Build Coastguard Worker             "und",
500*834a2baaSAndroid Build Coastguard Worker             "jp",
501*834a2baaSAndroid Build Coastguard Worker             "en-US",
502*834a2baaSAndroid Build Coastguard Worker             "en-Latn",
503*834a2baaSAndroid Build Coastguard Worker             "en-Latn-US",
504*834a2baaSAndroid Build Coastguard Worker             "en-Latn-US-u-em",
505*834a2baaSAndroid Build Coastguard Worker             "en-Latn-US-u-em-defaultemoji",
506*834a2baaSAndroid Build Coastguard Worker             "de-Latn-DE-1901",
507*834a2baaSAndroid Build Coastguard Worker     };
508*834a2baaSAndroid Build Coastguard Worker 
509*834a2baaSAndroid Build Coastguard Worker     for (const auto& subtagEmptyString : subtagEmptyStrings) {
510*834a2baaSAndroid Build Coastguard Worker         SCOPED_TRACE("Test for \"" + subtagEmptyString + "\"");
511*834a2baaSAndroid Build Coastguard Worker         Locale subtagEmpty = createLocale(subtagEmptyString);
512*834a2baaSAndroid Build Coastguard Worker         EXPECT_EQ(EmojiStyle::EMPTY, subtagEmpty.getEmojiStyle());
513*834a2baaSAndroid Build Coastguard Worker     }
514*834a2baaSAndroid Build Coastguard Worker }
515*834a2baaSAndroid Build Coastguard Worker 
TEST(LocaleListTest,registerLocaleListTest)516*834a2baaSAndroid Build Coastguard Worker TEST(LocaleListTest, registerLocaleListTest) {
517*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ(0UL, registerLocaleList(""));
518*834a2baaSAndroid Build Coastguard Worker     EXPECT_NE(0UL, registerLocaleList("en"));
519*834a2baaSAndroid Build Coastguard Worker     EXPECT_NE(0UL, registerLocaleList("jp"));
520*834a2baaSAndroid Build Coastguard Worker     EXPECT_NE(0UL, registerLocaleList("en,zh-Hans"));
521*834a2baaSAndroid Build Coastguard Worker 
522*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ(registerLocaleList("en"), registerLocaleList("en"));
523*834a2baaSAndroid Build Coastguard Worker     EXPECT_NE(registerLocaleList("en"), registerLocaleList("jp"));
524*834a2baaSAndroid Build Coastguard Worker     EXPECT_NE(registerLocaleList("de"), registerLocaleList("de-1901"));
525*834a2baaSAndroid Build Coastguard Worker 
526*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ(registerLocaleList("en,zh-Hans"), registerLocaleList("en,zh-Hans"));
527*834a2baaSAndroid Build Coastguard Worker     EXPECT_NE(registerLocaleList("en,zh-Hans"), registerLocaleList("zh-Hans,en"));
528*834a2baaSAndroid Build Coastguard Worker     EXPECT_NE(registerLocaleList("en,zh-Hans"), registerLocaleList("jp"));
529*834a2baaSAndroid Build Coastguard Worker     EXPECT_NE(registerLocaleList("en,zh-Hans"), registerLocaleList("en"));
530*834a2baaSAndroid Build Coastguard Worker     EXPECT_NE(registerLocaleList("en,zh-Hans"), registerLocaleList("en,zh-Hant"));
531*834a2baaSAndroid Build Coastguard Worker     EXPECT_NE(registerLocaleList("de,de-1901"), registerLocaleList("de-1901,de"));
532*834a2baaSAndroid Build Coastguard Worker }
533*834a2baaSAndroid Build Coastguard Worker 
534*834a2baaSAndroid Build Coastguard Worker // The test font has following glyphs.
535*834a2baaSAndroid Build Coastguard Worker // U+82A6
536*834a2baaSAndroid Build Coastguard Worker // U+82A6 U+FE00 (VS1)
537*834a2baaSAndroid Build Coastguard Worker // U+82A6 U+E0100 (VS17)
538*834a2baaSAndroid Build Coastguard Worker // U+82A6 U+E0101 (VS18)
539*834a2baaSAndroid Build Coastguard Worker // U+82A6 U+E0102 (VS19)
540*834a2baaSAndroid Build Coastguard Worker // U+845B
541*834a2baaSAndroid Build Coastguard Worker // U+845B U+FE00 (VS2)
542*834a2baaSAndroid Build Coastguard Worker // U+845B U+E0101 (VS18)
543*834a2baaSAndroid Build Coastguard Worker // U+845B U+E0102 (VS19)
544*834a2baaSAndroid Build Coastguard Worker // U+845B U+E0103 (VS20)
545*834a2baaSAndroid Build Coastguard Worker // U+537F
546*834a2baaSAndroid Build Coastguard Worker // U+717D U+FE02 (VS3)
547*834a2baaSAndroid Build Coastguard Worker // U+717D U+E0102 (VS19)
548*834a2baaSAndroid Build Coastguard Worker // U+717D U+E0103 (VS20)
549*834a2baaSAndroid Build Coastguard Worker const char kVsTestFont[] = "VariationSelectorTest-Regular.ttf";
550*834a2baaSAndroid Build Coastguard Worker 
551*834a2baaSAndroid Build Coastguard Worker class FontFamilyTest : public testing::Test {
552*834a2baaSAndroid Build Coastguard Worker public:
SetUp()553*834a2baaSAndroid Build Coastguard Worker     virtual void SetUp() override {
554*834a2baaSAndroid Build Coastguard Worker         if (access(getTestFontPath(kVsTestFont).c_str(), R_OK) != 0) {
555*834a2baaSAndroid Build Coastguard Worker             FAIL() << "Unable to read " << kVsTestFont << ". "
556*834a2baaSAndroid Build Coastguard Worker                    << "Please prepare the test data directory. "
557*834a2baaSAndroid Build Coastguard Worker                    << "For more details, please see how_to_run.txt.";
558*834a2baaSAndroid Build Coastguard Worker         }
559*834a2baaSAndroid Build Coastguard Worker     }
560*834a2baaSAndroid Build Coastguard Worker };
561*834a2baaSAndroid Build Coastguard Worker 
562*834a2baaSAndroid Build Coastguard Worker // Asserts that the font family has glyphs for and only for specified codepoint
563*834a2baaSAndroid Build Coastguard Worker // and variationSelector pairs.
expectVSGlyphs(FontFamily * family,uint32_t codepoint,const std::set<uint32_t> & vs)564*834a2baaSAndroid Build Coastguard Worker void expectVSGlyphs(FontFamily* family, uint32_t codepoint, const std::set<uint32_t>& vs) {
565*834a2baaSAndroid Build Coastguard Worker     for (uint32_t i = 0xFE00; i <= 0xE01EF; ++i) {
566*834a2baaSAndroid Build Coastguard Worker         // Move to variation selectors supplements after variation selectors.
567*834a2baaSAndroid Build Coastguard Worker         if (i == 0xFF00) {
568*834a2baaSAndroid Build Coastguard Worker             i = 0xE0100;
569*834a2baaSAndroid Build Coastguard Worker         }
570*834a2baaSAndroid Build Coastguard Worker         if (vs.find(i) == vs.end()) {
571*834a2baaSAndroid Build Coastguard Worker             EXPECT_FALSE(family->hasGlyph(codepoint, i))
572*834a2baaSAndroid Build Coastguard Worker                     << "Glyph for U+" << std::hex << codepoint << " U+" << i;
573*834a2baaSAndroid Build Coastguard Worker         } else {
574*834a2baaSAndroid Build Coastguard Worker             EXPECT_TRUE(family->hasGlyph(codepoint, i))
575*834a2baaSAndroid Build Coastguard Worker                     << "Glyph for U+" << std::hex << codepoint << " U+" << i;
576*834a2baaSAndroid Build Coastguard Worker         }
577*834a2baaSAndroid Build Coastguard Worker     }
578*834a2baaSAndroid Build Coastguard Worker }
579*834a2baaSAndroid Build Coastguard Worker 
expectVSGlyphsForVsTestFont(FontFamily * family)580*834a2baaSAndroid Build Coastguard Worker void expectVSGlyphsForVsTestFont(FontFamily* family) {
581*834a2baaSAndroid Build Coastguard Worker     const uint32_t kVS1 = 0xFE00;
582*834a2baaSAndroid Build Coastguard Worker     const uint32_t kVS2 = 0xFE01;
583*834a2baaSAndroid Build Coastguard Worker     const uint32_t kVS3 = 0xFE02;
584*834a2baaSAndroid Build Coastguard Worker     const uint32_t kVS17 = 0xE0100;
585*834a2baaSAndroid Build Coastguard Worker     const uint32_t kVS18 = 0xE0101;
586*834a2baaSAndroid Build Coastguard Worker     const uint32_t kVS19 = 0xE0102;
587*834a2baaSAndroid Build Coastguard Worker     const uint32_t kVS20 = 0xE0103;
588*834a2baaSAndroid Build Coastguard Worker 
589*834a2baaSAndroid Build Coastguard Worker     const uint32_t kSupportedChar1 = 0x82A6;
590*834a2baaSAndroid Build Coastguard Worker     EXPECT_TRUE(family->getCoverage().get(kSupportedChar1));
591*834a2baaSAndroid Build Coastguard Worker     expectVSGlyphs(family, kSupportedChar1, std::set<uint32_t>({kVS1, kVS17, kVS18, kVS19}));
592*834a2baaSAndroid Build Coastguard Worker 
593*834a2baaSAndroid Build Coastguard Worker     const uint32_t kSupportedChar2 = 0x845B;
594*834a2baaSAndroid Build Coastguard Worker     EXPECT_TRUE(family->getCoverage().get(kSupportedChar2));
595*834a2baaSAndroid Build Coastguard Worker     expectVSGlyphs(family, kSupportedChar2, std::set<uint32_t>({kVS2, kVS18, kVS19, kVS20}));
596*834a2baaSAndroid Build Coastguard Worker 
597*834a2baaSAndroid Build Coastguard Worker     const uint32_t kNoVsSupportedChar = 0x537F;
598*834a2baaSAndroid Build Coastguard Worker     EXPECT_TRUE(family->getCoverage().get(kNoVsSupportedChar));
599*834a2baaSAndroid Build Coastguard Worker     expectVSGlyphs(family, kNoVsSupportedChar, std::set<uint32_t>());
600*834a2baaSAndroid Build Coastguard Worker 
601*834a2baaSAndroid Build Coastguard Worker     const uint32_t kVsOnlySupportedChar = 0x717D;
602*834a2baaSAndroid Build Coastguard Worker     EXPECT_FALSE(family->getCoverage().get(kVsOnlySupportedChar));
603*834a2baaSAndroid Build Coastguard Worker     expectVSGlyphs(family, kVsOnlySupportedChar, std::set<uint32_t>({kVS3, kVS19, kVS20}));
604*834a2baaSAndroid Build Coastguard Worker 
605*834a2baaSAndroid Build Coastguard Worker     const uint32_t kNotSupportedChar = 0x845C;
606*834a2baaSAndroid Build Coastguard Worker     EXPECT_FALSE(family->getCoverage().get(kNotSupportedChar));
607*834a2baaSAndroid Build Coastguard Worker     expectVSGlyphs(family, kNotSupportedChar, std::set<uint32_t>());
608*834a2baaSAndroid Build Coastguard Worker }
609*834a2baaSAndroid Build Coastguard Worker 
TEST_F(FontFamilyTest,hasVariationSelectorTest)610*834a2baaSAndroid Build Coastguard Worker TEST_F(FontFamilyTest, hasVariationSelectorTest) {
611*834a2baaSAndroid Build Coastguard Worker     std::shared_ptr<FontFamily> family = buildFontFamily(kVsTestFont);
612*834a2baaSAndroid Build Coastguard Worker     expectVSGlyphsForVsTestFont(family.get());
613*834a2baaSAndroid Build Coastguard Worker }
614*834a2baaSAndroid Build Coastguard Worker 
TEST_F(FontFamilyTest,hasVSTableTest)615*834a2baaSAndroid Build Coastguard Worker TEST_F(FontFamilyTest, hasVSTableTest) {
616*834a2baaSAndroid Build Coastguard Worker     struct TestCase {
617*834a2baaSAndroid Build Coastguard Worker         const std::string fontPath;
618*834a2baaSAndroid Build Coastguard Worker         bool hasVSTable;
619*834a2baaSAndroid Build Coastguard Worker     } testCases[] = {
620*834a2baaSAndroid Build Coastguard Worker             {"Ja.ttf", true},      {"ZhHant.ttf", true}, {"ZhHans.ttf", true},
621*834a2baaSAndroid Build Coastguard Worker             {"Italic.ttf", false}, {"Bold.ttf", false},  {"BoldItalic.ttf", false},
622*834a2baaSAndroid Build Coastguard Worker     };
623*834a2baaSAndroid Build Coastguard Worker 
624*834a2baaSAndroid Build Coastguard Worker     for (const auto& testCase : testCases) {
625*834a2baaSAndroid Build Coastguard Worker         SCOPED_TRACE(testCase.hasVSTable ? "Font " + testCase.fontPath +
626*834a2baaSAndroid Build Coastguard Worker                                                    " should have a variation sequence table."
627*834a2baaSAndroid Build Coastguard Worker                                          : "Font " + testCase.fontPath +
628*834a2baaSAndroid Build Coastguard Worker                                                    " shouldn't have a variation sequence table.");
629*834a2baaSAndroid Build Coastguard Worker 
630*834a2baaSAndroid Build Coastguard Worker         std::shared_ptr<FontFamily> family = buildFontFamily(testCase.fontPath);
631*834a2baaSAndroid Build Coastguard Worker         EXPECT_EQ(testCase.hasVSTable, family->hasVSTable());
632*834a2baaSAndroid Build Coastguard Worker     }
633*834a2baaSAndroid Build Coastguard Worker }
634*834a2baaSAndroid Build Coastguard Worker 
TEST_F(FontFamilyTest,createFamilyWithVariationCtorTest)635*834a2baaSAndroid Build Coastguard Worker TEST_F(FontFamilyTest, createFamilyWithVariationCtorTest) {
636*834a2baaSAndroid Build Coastguard Worker     // This font has 'wdth' and 'wght' axes.
637*834a2baaSAndroid Build Coastguard Worker     const char kMultiAxisFont[] = "MultiAxis.ttf";
638*834a2baaSAndroid Build Coastguard Worker     const char kNoAxisFont[] = "Regular.ttf";
639*834a2baaSAndroid Build Coastguard Worker 
640*834a2baaSAndroid Build Coastguard Worker     std::shared_ptr<FontFamily> multiAxisFamily = buildFontFamily(kMultiAxisFont);
641*834a2baaSAndroid Build Coastguard Worker     std::shared_ptr<FontFamily> noAxisFamily = buildFontFamily(kNoAxisFont);
642*834a2baaSAndroid Build Coastguard Worker 
643*834a2baaSAndroid Build Coastguard Worker     {
644*834a2baaSAndroid Build Coastguard Worker         // Do not ceate new instance if none of variations are specified.
645*834a2baaSAndroid Build Coastguard Worker         EXPECT_EQ(nullptr, FontFamily::create(multiAxisFamily, std::vector<FontVariation>()));
646*834a2baaSAndroid Build Coastguard Worker         EXPECT_EQ(nullptr, FontFamily::create(noAxisFamily, std::vector<FontVariation>()));
647*834a2baaSAndroid Build Coastguard Worker     }
648*834a2baaSAndroid Build Coastguard Worker     {
649*834a2baaSAndroid Build Coastguard Worker         // New instance should be used for supported variation.
650*834a2baaSAndroid Build Coastguard Worker         std::vector<FontVariation> variations = {{MakeTag('w', 'd', 't', 'h'), 1.0f}};
651*834a2baaSAndroid Build Coastguard Worker         std::shared_ptr<FontFamily> newFamily = FontFamily::create(multiAxisFamily, variations);
652*834a2baaSAndroid Build Coastguard Worker         EXPECT_NE(nullptr, newFamily.get());
653*834a2baaSAndroid Build Coastguard Worker         EXPECT_NE(multiAxisFamily.get(), newFamily.get());
654*834a2baaSAndroid Build Coastguard Worker         EXPECT_EQ(nullptr, FontFamily::create(noAxisFamily, variations));
655*834a2baaSAndroid Build Coastguard Worker     }
656*834a2baaSAndroid Build Coastguard Worker     {
657*834a2baaSAndroid Build Coastguard Worker         // New instance should be used for supported variation. (multiple variations case)
658*834a2baaSAndroid Build Coastguard Worker         std::vector<FontVariation> variations = {{MakeTag('w', 'd', 't', 'h'), 1.0f},
659*834a2baaSAndroid Build Coastguard Worker                                                  {MakeTag('w', 'g', 'h', 't'), 1.0f}};
660*834a2baaSAndroid Build Coastguard Worker         std::shared_ptr<FontFamily> newFamily = FontFamily::create(multiAxisFamily, variations);
661*834a2baaSAndroid Build Coastguard Worker         EXPECT_NE(nullptr, newFamily.get());
662*834a2baaSAndroid Build Coastguard Worker         EXPECT_NE(multiAxisFamily.get(), newFamily.get());
663*834a2baaSAndroid Build Coastguard Worker         EXPECT_EQ(nullptr, FontFamily::create(noAxisFamily, variations));
664*834a2baaSAndroid Build Coastguard Worker     }
665*834a2baaSAndroid Build Coastguard Worker     {
666*834a2baaSAndroid Build Coastguard Worker         // Do not ceate new instance if none of variations are supported.
667*834a2baaSAndroid Build Coastguard Worker         std::vector<FontVariation> variations = {{MakeTag('Z', 'Z', 'Z', 'Z'), 1.0f}};
668*834a2baaSAndroid Build Coastguard Worker         EXPECT_EQ(nullptr, FontFamily::create(multiAxisFamily, variations));
669*834a2baaSAndroid Build Coastguard Worker         EXPECT_EQ(nullptr, FontFamily::create(noAxisFamily, variations));
670*834a2baaSAndroid Build Coastguard Worker     }
671*834a2baaSAndroid Build Coastguard Worker     {
672*834a2baaSAndroid Build Coastguard Worker         // At least one axis is supported, should create new instance.
673*834a2baaSAndroid Build Coastguard Worker         std::vector<FontVariation> variations = {{MakeTag('w', 'd', 't', 'h'), 1.0f},
674*834a2baaSAndroid Build Coastguard Worker                                                  {MakeTag('Z', 'Z', 'Z', 'Z'), 1.0f}};
675*834a2baaSAndroid Build Coastguard Worker         std::shared_ptr<FontFamily> newFamily = FontFamily::create(multiAxisFamily, variations);
676*834a2baaSAndroid Build Coastguard Worker         EXPECT_NE(nullptr, newFamily.get());
677*834a2baaSAndroid Build Coastguard Worker         EXPECT_NE(multiAxisFamily.get(), newFamily.get());
678*834a2baaSAndroid Build Coastguard Worker         EXPECT_EQ(nullptr, FontFamily::create(noAxisFamily, variations));
679*834a2baaSAndroid Build Coastguard Worker     }
680*834a2baaSAndroid Build Coastguard Worker }
681*834a2baaSAndroid Build Coastguard Worker 
TEST_F(FontFamilyTest,createFamilyWithVariationTest)682*834a2baaSAndroid Build Coastguard Worker TEST_F(FontFamilyTest, createFamilyWithVariationTest) {
683*834a2baaSAndroid Build Coastguard Worker     // This font has 'wdth' and 'wght' axes.
684*834a2baaSAndroid Build Coastguard Worker     const char kMultiAxisFont[] = "MultiAxis.ttf";
685*834a2baaSAndroid Build Coastguard Worker     const char kNoAxisFont[] = "Regular.ttf";
686*834a2baaSAndroid Build Coastguard Worker 
687*834a2baaSAndroid Build Coastguard Worker     std::shared_ptr<FontFamily> multiAxisFamily = buildFontFamily(kMultiAxisFont);
688*834a2baaSAndroid Build Coastguard Worker     std::shared_ptr<FontFamily> noAxisFamily = buildFontFamily(kNoAxisFont);
689*834a2baaSAndroid Build Coastguard Worker 
690*834a2baaSAndroid Build Coastguard Worker     {
691*834a2baaSAndroid Build Coastguard Worker         // Do not ceate new instance if none of variations are specified.
692*834a2baaSAndroid Build Coastguard Worker         EXPECT_EQ(nullptr,
693*834a2baaSAndroid Build Coastguard Worker                   multiAxisFamily->createFamilyWithVariation(std::vector<FontVariation>()));
694*834a2baaSAndroid Build Coastguard Worker         EXPECT_EQ(nullptr, noAxisFamily->createFamilyWithVariation(std::vector<FontVariation>()));
695*834a2baaSAndroid Build Coastguard Worker     }
696*834a2baaSAndroid Build Coastguard Worker     {
697*834a2baaSAndroid Build Coastguard Worker         // New instance should be used for supported variation.
698*834a2baaSAndroid Build Coastguard Worker         std::vector<FontVariation> variations = {{MakeTag('w', 'd', 't', 'h'), 1.0f}};
699*834a2baaSAndroid Build Coastguard Worker         std::shared_ptr<FontFamily> newFamily(
700*834a2baaSAndroid Build Coastguard Worker                 multiAxisFamily->createFamilyWithVariation(variations));
701*834a2baaSAndroid Build Coastguard Worker         EXPECT_NE(nullptr, newFamily.get());
702*834a2baaSAndroid Build Coastguard Worker         EXPECT_NE(multiAxisFamily.get(), newFamily.get());
703*834a2baaSAndroid Build Coastguard Worker         EXPECT_EQ(nullptr, noAxisFamily->createFamilyWithVariation(variations));
704*834a2baaSAndroid Build Coastguard Worker     }
705*834a2baaSAndroid Build Coastguard Worker     {
706*834a2baaSAndroid Build Coastguard Worker         // New instance should be used for supported variation. (multiple variations case)
707*834a2baaSAndroid Build Coastguard Worker         std::vector<FontVariation> variations = {{MakeTag('w', 'd', 't', 'h'), 1.0f},
708*834a2baaSAndroid Build Coastguard Worker                                                  {MakeTag('w', 'g', 'h', 't'), 1.0f}};
709*834a2baaSAndroid Build Coastguard Worker         std::shared_ptr<FontFamily> newFamily(
710*834a2baaSAndroid Build Coastguard Worker                 multiAxisFamily->createFamilyWithVariation(variations));
711*834a2baaSAndroid Build Coastguard Worker         EXPECT_NE(nullptr, newFamily.get());
712*834a2baaSAndroid Build Coastguard Worker         EXPECT_NE(multiAxisFamily.get(), newFamily.get());
713*834a2baaSAndroid Build Coastguard Worker         EXPECT_EQ(nullptr, noAxisFamily->createFamilyWithVariation(variations));
714*834a2baaSAndroid Build Coastguard Worker     }
715*834a2baaSAndroid Build Coastguard Worker     {
716*834a2baaSAndroid Build Coastguard Worker         // Do not ceate new instance if none of variations are supported.
717*834a2baaSAndroid Build Coastguard Worker         std::vector<FontVariation> variations = {{MakeTag('Z', 'Z', 'Z', 'Z'), 1.0f}};
718*834a2baaSAndroid Build Coastguard Worker         EXPECT_EQ(nullptr, multiAxisFamily->createFamilyWithVariation(variations));
719*834a2baaSAndroid Build Coastguard Worker         EXPECT_EQ(nullptr, noAxisFamily->createFamilyWithVariation(variations));
720*834a2baaSAndroid Build Coastguard Worker     }
721*834a2baaSAndroid Build Coastguard Worker     {
722*834a2baaSAndroid Build Coastguard Worker         // At least one axis is supported, should create new instance.
723*834a2baaSAndroid Build Coastguard Worker         std::vector<FontVariation> variations = {{MakeTag('w', 'd', 't', 'h'), 1.0f},
724*834a2baaSAndroid Build Coastguard Worker                                                  {MakeTag('Z', 'Z', 'Z', 'Z'), 1.0f}};
725*834a2baaSAndroid Build Coastguard Worker         std::shared_ptr<FontFamily> newFamily(
726*834a2baaSAndroid Build Coastguard Worker                 multiAxisFamily->createFamilyWithVariation(variations));
727*834a2baaSAndroid Build Coastguard Worker         EXPECT_NE(nullptr, newFamily.get());
728*834a2baaSAndroid Build Coastguard Worker         EXPECT_NE(multiAxisFamily.get(), newFamily.get());
729*834a2baaSAndroid Build Coastguard Worker         EXPECT_EQ(nullptr, noAxisFamily->createFamilyWithVariation(variations));
730*834a2baaSAndroid Build Coastguard Worker     }
731*834a2baaSAndroid Build Coastguard Worker }
732*834a2baaSAndroid Build Coastguard Worker 
TEST_F(FontFamilyTest,coverageTableSelectionTest)733*834a2baaSAndroid Build Coastguard Worker TEST_F(FontFamilyTest, coverageTableSelectionTest) {
734*834a2baaSAndroid Build Coastguard Worker     // This font supports U+0061. The cmap subtable is format 4 and its platform ID is 0 and
735*834a2baaSAndroid Build Coastguard Worker     // encoding ID is 1.
736*834a2baaSAndroid Build Coastguard Worker     const char kUnicodeEncoding1Font[] = "UnicodeBMPOnly.ttf";
737*834a2baaSAndroid Build Coastguard Worker 
738*834a2baaSAndroid Build Coastguard Worker     // This font supports U+0061. The cmap subtable is format 4 and its platform ID is 0 and
739*834a2baaSAndroid Build Coastguard Worker     // encoding ID is 3.
740*834a2baaSAndroid Build Coastguard Worker     const char kUnicodeEncoding3Font[] = "UnicodeBMPOnly2.ttf";
741*834a2baaSAndroid Build Coastguard Worker 
742*834a2baaSAndroid Build Coastguard Worker     // This font has both cmap format 4 subtable which platform ID is 0 and encoding ID is 1
743*834a2baaSAndroid Build Coastguard Worker     // and cmap format 14 subtable which platform ID is 0 and encoding ID is 10.
744*834a2baaSAndroid Build Coastguard Worker     // U+0061 is listed in both subtable but U+1F926 is only listed in latter.
745*834a2baaSAndroid Build Coastguard Worker     const char kUnicodeEncoding4Font[] = "UnicodeUCS4.ttf";
746*834a2baaSAndroid Build Coastguard Worker 
747*834a2baaSAndroid Build Coastguard Worker     std::shared_ptr<FontFamily> unicodeEnc1Font = buildFontFamily(kUnicodeEncoding1Font);
748*834a2baaSAndroid Build Coastguard Worker     std::shared_ptr<FontFamily> unicodeEnc3Font = buildFontFamily(kUnicodeEncoding3Font);
749*834a2baaSAndroid Build Coastguard Worker     std::shared_ptr<FontFamily> unicodeEnc4Font = buildFontFamily(kUnicodeEncoding4Font);
750*834a2baaSAndroid Build Coastguard Worker 
751*834a2baaSAndroid Build Coastguard Worker     EXPECT_TRUE(unicodeEnc1Font->hasGlyph(0x0061, 0));
752*834a2baaSAndroid Build Coastguard Worker     EXPECT_TRUE(unicodeEnc3Font->hasGlyph(0x0061, 0));
753*834a2baaSAndroid Build Coastguard Worker     EXPECT_TRUE(unicodeEnc4Font->hasGlyph(0x0061, 0));
754*834a2baaSAndroid Build Coastguard Worker 
755*834a2baaSAndroid Build Coastguard Worker     EXPECT_TRUE(unicodeEnc4Font->hasGlyph(0x1F926, 0));
756*834a2baaSAndroid Build Coastguard Worker }
757*834a2baaSAndroid Build Coastguard Worker 
TEST_F(FontFamilyTest,childCoverageTest)758*834a2baaSAndroid Build Coastguard Worker TEST_F(FontFamilyTest, childCoverageTest) {
759*834a2baaSAndroid Build Coastguard Worker     // MultiAxis.ttf only supports U+0061.
760*834a2baaSAndroid Build Coastguard Worker     std::shared_ptr<FontFamily> parentFont = buildFontFamily("MultiAxis.ttf");
761*834a2baaSAndroid Build Coastguard Worker 
762*834a2baaSAndroid Build Coastguard Worker     EXPECT_TRUE(parentFont->hasGlyph(0x0061, 0));
763*834a2baaSAndroid Build Coastguard Worker 
764*834a2baaSAndroid Build Coastguard Worker     std::shared_ptr<FontFamily> childFont = FontFamily::create(
765*834a2baaSAndroid Build Coastguard Worker             parentFont, std::vector<FontVariation>{FontVariation(MakeTag('w', 'g', 'h', 't'), 0)});
766*834a2baaSAndroid Build Coastguard Worker 
767*834a2baaSAndroid Build Coastguard Worker     EXPECT_NE(nullptr, childFont.get());
768*834a2baaSAndroid Build Coastguard Worker     EXPECT_TRUE(childFont->hasGlyph(0x0061, 0));
769*834a2baaSAndroid Build Coastguard Worker }
770*834a2baaSAndroid Build Coastguard Worker 
slantToString(FontStyle::Slant slant)771*834a2baaSAndroid Build Coastguard Worker const char* slantToString(FontStyle::Slant slant) {
772*834a2baaSAndroid Build Coastguard Worker     if (slant == FontStyle::Slant::ITALIC) {
773*834a2baaSAndroid Build Coastguard Worker         return "ITALIC";
774*834a2baaSAndroid Build Coastguard Worker     } else {
775*834a2baaSAndroid Build Coastguard Worker         return "UPRIGHT";
776*834a2baaSAndroid Build Coastguard Worker     }
777*834a2baaSAndroid Build Coastguard Worker }
778*834a2baaSAndroid Build Coastguard Worker 
fontStyleToString(const FontStyle & style)779*834a2baaSAndroid Build Coastguard Worker std::string fontStyleToString(const FontStyle& style) {
780*834a2baaSAndroid Build Coastguard Worker     char buf[64] = {};
781*834a2baaSAndroid Build Coastguard Worker     snprintf(buf, sizeof(buf), "FontStyle(weight=%d, slant=%s)", style.weight(),
782*834a2baaSAndroid Build Coastguard Worker              slantToString(style.slant()));
783*834a2baaSAndroid Build Coastguard Worker     return buf;
784*834a2baaSAndroid Build Coastguard Worker }
785*834a2baaSAndroid Build Coastguard Worker 
TEST_F(FontFamilyTest,closestMatch)786*834a2baaSAndroid Build Coastguard Worker TEST_F(FontFamilyTest, closestMatch) {
787*834a2baaSAndroid Build Coastguard Worker     constexpr char kTestFont[] = "Ascii.ttf";
788*834a2baaSAndroid Build Coastguard Worker 
789*834a2baaSAndroid Build Coastguard Worker     constexpr FontStyle::Weight THIN = FontStyle::Weight::THIN;
790*834a2baaSAndroid Build Coastguard Worker     constexpr FontStyle::Weight LIGHT = FontStyle::Weight::LIGHT;
791*834a2baaSAndroid Build Coastguard Worker     constexpr FontStyle::Weight NORMAL = FontStyle::Weight::NORMAL;
792*834a2baaSAndroid Build Coastguard Worker     constexpr FontStyle::Weight MEDIUM = FontStyle::Weight::MEDIUM;
793*834a2baaSAndroid Build Coastguard Worker     constexpr FontStyle::Weight BOLD = FontStyle::Weight::BOLD;
794*834a2baaSAndroid Build Coastguard Worker     constexpr FontStyle::Weight BLACK = FontStyle::Weight::BLACK;
795*834a2baaSAndroid Build Coastguard Worker 
796*834a2baaSAndroid Build Coastguard Worker     constexpr FontStyle::Slant UPRIGHT = FontStyle::Slant::UPRIGHT;
797*834a2baaSAndroid Build Coastguard Worker     constexpr FontStyle::Slant ITALIC = FontStyle::Slant::ITALIC;
798*834a2baaSAndroid Build Coastguard Worker 
799*834a2baaSAndroid Build Coastguard Worker     const std::vector<FontStyle> STANDARD_SET = {
800*834a2baaSAndroid Build Coastguard Worker             FontStyle(NORMAL, UPRIGHT),  // 0
801*834a2baaSAndroid Build Coastguard Worker             FontStyle(BOLD, UPRIGHT),    // 1
802*834a2baaSAndroid Build Coastguard Worker             FontStyle(NORMAL, ITALIC),   // 2
803*834a2baaSAndroid Build Coastguard Worker             FontStyle(BOLD, ITALIC),     // 3
804*834a2baaSAndroid Build Coastguard Worker     };
805*834a2baaSAndroid Build Coastguard Worker 
806*834a2baaSAndroid Build Coastguard Worker     const std::vector<FontStyle> FULL_SET = {
807*834a2baaSAndroid Build Coastguard Worker             FontStyle(THIN, UPRIGHT),    // 0
808*834a2baaSAndroid Build Coastguard Worker             FontStyle(LIGHT, UPRIGHT),   // 1
809*834a2baaSAndroid Build Coastguard Worker             FontStyle(NORMAL, UPRIGHT),  // 2
810*834a2baaSAndroid Build Coastguard Worker             FontStyle(MEDIUM, UPRIGHT),  // 3
811*834a2baaSAndroid Build Coastguard Worker             FontStyle(BOLD, UPRIGHT),    // 4
812*834a2baaSAndroid Build Coastguard Worker             FontStyle(BLACK, UPRIGHT),   // 5
813*834a2baaSAndroid Build Coastguard Worker             FontStyle(THIN, ITALIC),     // 6
814*834a2baaSAndroid Build Coastguard Worker             FontStyle(LIGHT, ITALIC),    // 7
815*834a2baaSAndroid Build Coastguard Worker             FontStyle(NORMAL, ITALIC),   // 8
816*834a2baaSAndroid Build Coastguard Worker             FontStyle(MEDIUM, ITALIC),   // 9
817*834a2baaSAndroid Build Coastguard Worker             FontStyle(BOLD, ITALIC),     // 10
818*834a2baaSAndroid Build Coastguard Worker             FontStyle(BLACK, ITALIC),    // 11
819*834a2baaSAndroid Build Coastguard Worker     };
820*834a2baaSAndroid Build Coastguard Worker     struct TestCase {
821*834a2baaSAndroid Build Coastguard Worker         FontStyle wantedStyle;
822*834a2baaSAndroid Build Coastguard Worker         std::vector<FontStyle> familyStyles;
823*834a2baaSAndroid Build Coastguard Worker         size_t expectedIndex;
824*834a2baaSAndroid Build Coastguard Worker     } testCases[] = {
825*834a2baaSAndroid Build Coastguard Worker             {FontStyle(), {FontStyle()}, 0},
826*834a2baaSAndroid Build Coastguard Worker 
827*834a2baaSAndroid Build Coastguard Worker             // Exact matches
828*834a2baaSAndroid Build Coastguard Worker             {FontStyle(BOLD), {FontStyle(NORMAL), FontStyle(BOLD)}, 1},
829*834a2baaSAndroid Build Coastguard Worker             {FontStyle(BOLD), {FontStyle(LIGHT), FontStyle(BOLD)}, 1},
830*834a2baaSAndroid Build Coastguard Worker             {FontStyle(LIGHT), {FontStyle(NORMAL), FontStyle(LIGHT)}, 1},
831*834a2baaSAndroid Build Coastguard Worker             {FontStyle(LIGHT), {FontStyle(BOLD), FontStyle(LIGHT)}, 1},
832*834a2baaSAndroid Build Coastguard Worker             {FontStyle(NORMAL), {FontStyle(NORMAL), FontStyle(LIGHT)}, 0},
833*834a2baaSAndroid Build Coastguard Worker             {FontStyle(NORMAL), {FontStyle(NORMAL), FontStyle(BOLD)}, 0},
834*834a2baaSAndroid Build Coastguard Worker             {FontStyle(LIGHT), {FontStyle(LIGHT), FontStyle(NORMAL), FontStyle(BOLD)}, 0},
835*834a2baaSAndroid Build Coastguard Worker             {FontStyle(NORMAL), {FontStyle(LIGHT), FontStyle(NORMAL), FontStyle(BOLD)}, 1},
836*834a2baaSAndroid Build Coastguard Worker             {FontStyle(BOLD), {FontStyle(LIGHT), FontStyle(NORMAL), FontStyle(BOLD)}, 2},
837*834a2baaSAndroid Build Coastguard Worker 
838*834a2baaSAndroid Build Coastguard Worker             {FontStyle(UPRIGHT), {FontStyle(UPRIGHT), FontStyle(ITALIC)}, 0},
839*834a2baaSAndroid Build Coastguard Worker             {FontStyle(ITALIC), {FontStyle(UPRIGHT), FontStyle(ITALIC)}, 1},
840*834a2baaSAndroid Build Coastguard Worker 
841*834a2baaSAndroid Build Coastguard Worker             {FontStyle(NORMAL, UPRIGHT), STANDARD_SET, 0},
842*834a2baaSAndroid Build Coastguard Worker             {FontStyle(BOLD, UPRIGHT), STANDARD_SET, 1},
843*834a2baaSAndroid Build Coastguard Worker             {FontStyle(NORMAL, ITALIC), STANDARD_SET, 2},
844*834a2baaSAndroid Build Coastguard Worker             {FontStyle(BOLD, ITALIC), STANDARD_SET, 3},
845*834a2baaSAndroid Build Coastguard Worker 
846*834a2baaSAndroid Build Coastguard Worker             {FontStyle(NORMAL, UPRIGHT), FULL_SET, 2},
847*834a2baaSAndroid Build Coastguard Worker             {FontStyle(BOLD, UPRIGHT), FULL_SET, 4},
848*834a2baaSAndroid Build Coastguard Worker             {FontStyle(NORMAL, ITALIC), FULL_SET, 8},
849*834a2baaSAndroid Build Coastguard Worker             {FontStyle(BOLD, ITALIC), FULL_SET, 10},
850*834a2baaSAndroid Build Coastguard Worker 
851*834a2baaSAndroid Build Coastguard Worker             // TODO: Add fallback expectations. (b/68814338)
852*834a2baaSAndroid Build Coastguard Worker     };
853*834a2baaSAndroid Build Coastguard Worker 
854*834a2baaSAndroid Build Coastguard Worker     for (const TestCase& testCase : testCases) {
855*834a2baaSAndroid Build Coastguard Worker         std::vector<std::shared_ptr<MinikinFont>> dummyFonts;
856*834a2baaSAndroid Build Coastguard Worker         std::vector<std::shared_ptr<Font>> fonts;
857*834a2baaSAndroid Build Coastguard Worker         for (auto familyStyle : testCase.familyStyles) {
858*834a2baaSAndroid Build Coastguard Worker             std::shared_ptr<MinikinFont> dummyFont(
859*834a2baaSAndroid Build Coastguard Worker                     new FreeTypeMinikinFontForTest(getTestFontPath(kTestFont)));
860*834a2baaSAndroid Build Coastguard Worker             dummyFonts.push_back(dummyFont);
861*834a2baaSAndroid Build Coastguard Worker             fonts.push_back(Font::Builder(dummyFont).setStyle(familyStyle).build());
862*834a2baaSAndroid Build Coastguard Worker         }
863*834a2baaSAndroid Build Coastguard Worker 
864*834a2baaSAndroid Build Coastguard Worker         std::shared_ptr<FontFamily> family = FontFamily::create(std::move(fonts));
865*834a2baaSAndroid Build Coastguard Worker         FakedFont closest = family->getClosestMatch(testCase.wantedStyle);
866*834a2baaSAndroid Build Coastguard Worker 
867*834a2baaSAndroid Build Coastguard Worker         size_t idx = dummyFonts.size();
868*834a2baaSAndroid Build Coastguard Worker         for (size_t i = 0; i < dummyFonts.size(); i++) {
869*834a2baaSAndroid Build Coastguard Worker             if (dummyFonts[i].get() == closest.font->baseTypeface().get()) {
870*834a2baaSAndroid Build Coastguard Worker                 idx = i;
871*834a2baaSAndroid Build Coastguard Worker                 break;
872*834a2baaSAndroid Build Coastguard Worker             }
873*834a2baaSAndroid Build Coastguard Worker         }
874*834a2baaSAndroid Build Coastguard Worker         ASSERT_NE(idx, dummyFonts.size()) << "The selected font is unknown.";
875*834a2baaSAndroid Build Coastguard Worker         EXPECT_EQ(testCase.expectedIndex, idx)
876*834a2baaSAndroid Build Coastguard Worker                 << "Input Style: " << fontStyleToString(testCase.wantedStyle) << std::endl
877*834a2baaSAndroid Build Coastguard Worker                 << "Actual Families' Style: " << fontStyleToString(testCase.familyStyles[idx])
878*834a2baaSAndroid Build Coastguard Worker                 << std::endl
879*834a2baaSAndroid Build Coastguard Worker                 << "Expected Families' Style: "
880*834a2baaSAndroid Build Coastguard Worker                 << fontStyleToString(testCase.familyStyles[testCase.expectedIndex]) << std::endl;
881*834a2baaSAndroid Build Coastguard Worker     }
882*834a2baaSAndroid Build Coastguard Worker }
883*834a2baaSAndroid Build Coastguard Worker 
writeToBuffer(const std::vector<std::shared_ptr<FontFamily>> & families)884*834a2baaSAndroid Build Coastguard Worker std::vector<uint8_t> writeToBuffer(const std::vector<std::shared_ptr<FontFamily>>& families) {
885*834a2baaSAndroid Build Coastguard Worker     BufferWriter fakeWriter(nullptr);
886*834a2baaSAndroid Build Coastguard Worker     FontFamily::writeVector(&fakeWriter, families);
887*834a2baaSAndroid Build Coastguard Worker     std::vector<uint8_t> buffer(fakeWriter.size());
888*834a2baaSAndroid Build Coastguard Worker     BufferWriter writer(buffer.data());
889*834a2baaSAndroid Build Coastguard Worker     FontFamily::writeVector(&writer, families);
890*834a2baaSAndroid Build Coastguard Worker     return buffer;
891*834a2baaSAndroid Build Coastguard Worker }
892*834a2baaSAndroid Build Coastguard Worker 
expectFontFamilyEquals(const std::shared_ptr<FontFamily> & expected,const std::shared_ptr<FontFamily> & actual)893*834a2baaSAndroid Build Coastguard Worker void expectFontFamilyEquals(const std::shared_ptr<FontFamily>& expected,
894*834a2baaSAndroid Build Coastguard Worker                             const std::shared_ptr<FontFamily>& actual) {
895*834a2baaSAndroid Build Coastguard Worker     ASSERT_EQ(expected->localeListId(), actual->localeListId());
896*834a2baaSAndroid Build Coastguard Worker     ASSERT_EQ(expected->variant(), actual->variant());
897*834a2baaSAndroid Build Coastguard Worker     ASSERT_EQ(expected->getNumFonts(), actual->getNumFonts());
898*834a2baaSAndroid Build Coastguard Worker     ASSERT_EQ(expected->getSupportedAxesCount(), actual->getSupportedAxesCount());
899*834a2baaSAndroid Build Coastguard Worker     for (size_t i = 0; i < expected->getSupportedAxesCount(); i++) {
900*834a2baaSAndroid Build Coastguard Worker         ASSERT_EQ(expected->getSupportedAxisAt(i), actual->getSupportedAxisAt(i));
901*834a2baaSAndroid Build Coastguard Worker     }
902*834a2baaSAndroid Build Coastguard Worker     ASSERT_EQ(expected->isColorEmojiFamily(), actual->isColorEmojiFamily());
903*834a2baaSAndroid Build Coastguard Worker     ASSERT_EQ(expected->isCustomFallback(), actual->isCustomFallback());
904*834a2baaSAndroid Build Coastguard Worker     ASSERT_EQ(expected->hasVSTable(), actual->hasVSTable());
905*834a2baaSAndroid Build Coastguard Worker }
906*834a2baaSAndroid Build Coastguard Worker 
getHeapSize()907*834a2baaSAndroid Build Coastguard Worker size_t getHeapSize() {
908*834a2baaSAndroid Build Coastguard Worker     struct mallinfo info = mallinfo();
909*834a2baaSAndroid Build Coastguard Worker     return info.uordblks;
910*834a2baaSAndroid Build Coastguard Worker }
911*834a2baaSAndroid Build Coastguard Worker 
TEST_F(FontFamilyTest,bufferTest)912*834a2baaSAndroid Build Coastguard Worker TEST_F(FontFamilyTest, bufferTest) {
913*834a2baaSAndroid Build Coastguard Worker     FreeTypeMinikinFontForTestFactory::init();
914*834a2baaSAndroid Build Coastguard Worker     size_t baseHeapSize = getHeapSize();
915*834a2baaSAndroid Build Coastguard Worker     {
916*834a2baaSAndroid Build Coastguard Worker         constexpr char kMultiAxisFont[] = "MultiAxis.ttf";
917*834a2baaSAndroid Build Coastguard Worker         std::vector<std::shared_ptr<FontFamily>> original = {
918*834a2baaSAndroid Build Coastguard Worker                 // Font with variation selectors
919*834a2baaSAndroid Build Coastguard Worker                 buildFontFamily(kVsTestFont),
920*834a2baaSAndroid Build Coastguard Worker                 // Font with axes
921*834a2baaSAndroid Build Coastguard Worker                 buildFontFamily(kMultiAxisFont),
922*834a2baaSAndroid Build Coastguard Worker         };
923*834a2baaSAndroid Build Coastguard Worker         std::vector<uint8_t> buffer = writeToBuffer(original);
924*834a2baaSAndroid Build Coastguard Worker         BufferReader reader(buffer.data());
925*834a2baaSAndroid Build Coastguard Worker         std::vector<std::shared_ptr<FontFamily>> copied = FontFamily::readVector(&reader);
926*834a2baaSAndroid Build Coastguard Worker         ASSERT_EQ(2u, copied.size());
927*834a2baaSAndroid Build Coastguard Worker         expectFontFamilyEquals(original[0], copied[0]);
928*834a2baaSAndroid Build Coastguard Worker         expectVSGlyphsForVsTestFont(copied[0].get());
929*834a2baaSAndroid Build Coastguard Worker         expectFontFamilyEquals(original[1], copied[1]);
930*834a2baaSAndroid Build Coastguard Worker         std::vector<uint8_t> newBuffer = writeToBuffer(copied);
931*834a2baaSAndroid Build Coastguard Worker         ASSERT_EQ(buffer, newBuffer);
932*834a2baaSAndroid Build Coastguard Worker     }
933*834a2baaSAndroid Build Coastguard Worker     // Test that there is no leak after all FontFamily is destructed.
934*834a2baaSAndroid Build Coastguard Worker     EXPECT_EQ(baseHeapSize, getHeapSize());
935*834a2baaSAndroid Build Coastguard Worker }
936*834a2baaSAndroid Build Coastguard Worker 
937*834a2baaSAndroid Build Coastguard Worker }  // namespace minikin
938