1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <algorithm>
17 #include <codecvt>
18 #include <cstddef>
19 #include <fcntl.h>
20 #include <fstream>
21 #include <locale>
22 #include <sys/stat.h>
23
24 #include "gtest/gtest.h"
25 #include "impl_factory.h"
26 #include "impl_interface/font_mgr_impl.h"
27
28 #include "text/font_mgr.h"
29
30 using namespace testing;
31 using namespace testing::ext;
32
33 namespace OHOS {
34 namespace Rosen {
35 namespace Drawing {
36 class FontMgrTest : public testing::Test {
37 public:
38 static void SetUpTestCase();
39 static void TearDownTestCase();
40 void SetUp() override;
41 void TearDown() override;
42 };
43
SetUpTestCase()44 void FontMgrTest::SetUpTestCase() {}
TearDownTestCase()45 void FontMgrTest::TearDownTestCase() {}
SetUp()46 void FontMgrTest::SetUp() {}
TearDown()47 void FontMgrTest::TearDown() {}
48
49 /**
50 * @tc.name:LoadDynamicFont002
51 * @tc.desc: Test LoadDynamicFont
52 * @tc.type: FUNC
53 * @tc.require: I91F9L
54 */
55 HWTEST_F(FontMgrTest, LoadDynamicFont002, TestSize.Level1)
56 {
57 std::shared_ptr<FontMgr> FontMgr = FontMgr::CreateDynamicFontMgr();
58 std::vector<uint8_t> emptyFontData;
59 Typeface* typeface = FontMgr->LoadDynamicFont("EmptyFont", emptyFontData.data(), emptyFontData.size());
60 ASSERT_EQ(typeface, nullptr);
61 }
62
63 /**
64 *
65 * @tc.name:MatchFamilyStyleCharacter001
66 * @tc.desc: Test MatchFamilyStyleCharacter
67 * @tc.type: FUNC
68 * @tc.require: I91F9L
69 */
70 HWTEST_F(FontMgrTest, MatchFamilyStyleCharacter001, TestSize.Level1)
71 {
72 std::shared_ptr<FontMgr> FontMgr = FontMgr::CreateDefaultFontMgr();
73 FontStyle fontStyle;
74 const char* bcp47[] = { "en-US" };
75 int bcp47Count = 1;
76 int32_t character = 'A';
77 Typeface* typeface = FontMgr->MatchFamilyStyleCharacter("serif", fontStyle, bcp47, bcp47Count, character);
78 ASSERT_NE(typeface, nullptr);
79 }
80
81 /**
82 * @tc.name:MatchFamily002
83 * @tc.desc: Test MatchFamily
84 * @tc.type: FUNC
85 * @tc.require: I91F9L
86 */
87 HWTEST_F(FontMgrTest, MatchFamily002, TestSize.Level1)
88 {
89 std::shared_ptr<FontMgr> FontMgr = FontMgr::CreateDefaultFontMgr();
90 const char* familyName = "serif";
91 FontStyleSet* fontStyleSet = FontMgr->MatchFamily(familyName);
92 ASSERT_NE(fontStyleSet, nullptr);
93 }
94
95 /**
96 * @tc.name:CountFamilies001
97 * @tc.desc: Test CountFamilies
98 * @tc.type: FUNC
99 * @tc.require: I91F9L
100 */
101 HWTEST_F(FontMgrTest, CountFamilies001, TestSize.Level1)
102 {
103 std::shared_ptr<FontMgr> FontMgr = FontMgr::CreateDefaultFontMgr();
104 int familyCount = FontMgr->CountFamilies();
105 EXPECT_EQ(familyCount, 9);
106 }
107
108 /**
109 * @tc.name:GetFamilyName001
110 * @tc.desc: Test GetFamilyName
111 * @tc.type: FUNC
112 * @tc.require: I91F9L
113 */
114 HWTEST_F(FontMgrTest, GetFamilyName001, TestSize.Level1)
115 {
116 std::shared_ptr<FontMgr> FontMgr = FontMgr::CreateDefaultFontMgr();
117 std::string familyName;
118 FontMgr->GetFamilyName(0, familyName);
119 std::string result = { 0x48, 0x61, 0x72, 0x6d, 0x6f, 0x6e, 0x79, 0x4f, 0x53, 0x2d, 0x53, 0x61, 0x6e, 0x73 };
120 EXPECT_EQ(familyName, result);
121 }
122
123 /**
124 * @tc.name:CreateStyleSet001
125 * @tc.desc: Test CreateStyleSet
126 * @tc.type: FUNC
127 * @tc.require: I91F9L
128 */
129 HWTEST_F(FontMgrTest, CreateStyleSet001, TestSize.Level1)
130 {
131 std::shared_ptr<FontMgr> FontMgr = FontMgr::CreateDefaultFontMgr();
132 ASSERT_NE(FontMgr, nullptr);
133 FontStyleSet* fontStyleSet = FontMgr->CreateStyleSet(0);
134 ASSERT_NE(fontStyleSet, nullptr);
135 }
136
137 /**
138 * @tc.name:MatchFallbackc001
139 * @tc.desc: Test fallback typeface
140 * @tc.type: FUNC
141 * @tc.require: I91F9L
142 */
143 HWTEST_F(FontMgrTest, MatchFallbackc001, TestSize.Level1)
144 {
145 const char* ja = "Noto Sans CJK JP";
146 const char* hmSymbol = "HM Symbol";
147 std::shared_ptr<FontMgr> fontMgr = FontMgr::CreateDefaultFontMgr();
148 auto typeface = fontMgr->MatchFamilyStyleCharacter(nullptr, {}, nullptr, 0, u'❶');
149 ASSERT_NE(typeface, nullptr);
150 EXPECT_EQ(typeface->GetFamilyName(), ja);
151 delete typeface;
152
153 // 0xF0000 is edge case of ulUnicodeRange
154 typeface = fontMgr->MatchFamilyStyleCharacter(nullptr, {}, nullptr, 0, 0xF0000);
155 ASSERT_NE(typeface, nullptr);
156 EXPECT_EQ(typeface->GetFamilyName(), hmSymbol);
157 delete typeface;
158
159 typeface = fontMgr->MatchFamilyStyleCharacter(nullptr, {}, nullptr, 0, u'✿');
160 ASSERT_NE(typeface, nullptr);
161 EXPECT_EQ(typeface->GetFamilyName(), ja);
162 delete typeface;
163
164 typeface = fontMgr->MatchFamilyStyleCharacter(nullptr, {}, nullptr, 0, u'♲');
165 ASSERT_NE(typeface, nullptr);
166 EXPECT_EQ(typeface->GetFamilyName(), ja);
167 delete typeface;
168
169 typeface = fontMgr->MatchFamilyStyleCharacter(nullptr, {}, nullptr, 0, u'❀');
170 ASSERT_NE(typeface, nullptr);
171 EXPECT_EQ(typeface->GetFamilyName(), ja);
172 delete typeface;
173 }
174
175 const char* TTF_FILE_PATH = "/system/fonts/Roboto-Regular.ttf";
176 // The ttf font file fullname is the utf16BE format content corresponding to "Noto Sans Regular"
177 const uint8_t TTF_FULLNAME[] = {0x0, 0x4e, 0x0, 0x6f, 0x0, 0x74, 0x0, 0x6f, 0x0, 0x20, 0x0, 0x53,
178 0x0, 0x61, 0x0, 0x6e, 0x0, 0x73, 0x0, 0x20, 0x0, 0x52, 0x0, 0x65,
179 0x0, 0x67, 0x0, 0x75, 0x0, 0x6c, 0x0, 0x61, 0x0, 0x72};
180 const char* OTF_FILE_PATH = "/data/fonts/Igiari-2.otf";
181 // The otf font file fullname is the utf16BE format content corresponding to "Igiari"
182 const uint8_t OTF_FULLNAME[] = {0x0, 0x49, 0x0, 0x67, 0x0, 0x69, 0x0, 0x61, 0x0, 0x72, 0x0, 0x69};
183 const char* TTC_FILE_PATH = "/system/fonts/NotoSerifCJK-Regular.ttc";
184 // The ttc font file fullname is the utf16BE format content corresponding to "Noto Serif CJK JP"
185 const uint8_t TTC_FULLNAME[] = {0x0, 0x4e, 0x0, 0x6f, 0x0, 0x74, 0x0, 0x6f, 0x0, 0x20, 0x0, 0x53,
186 0x0, 0x65, 0x0, 0x72, 0x0, 0x69, 0x0, 0x66, 0x0, 0x20, 0x0, 0x43,
187 0x0, 0x4a, 0x0, 0x4b, 0x0, 0x20, 0x0, 0x4a, 0x0, 0x50};
188 const char* ERRORPATH_FILE_PATH = "/system/fonts/error_path.ttf";
189 const char* ERRORFORMAT_FILE_PATH = "/system/etc/fontconfig.json";
190 const char* JSON_CONFIG_PATH = "/data/fonts/install_fontconfig.json";
191 const char* ERROR_JSON_CONFIG_PATH = "/data/fonts/error_path.json";
192 const char* CONFIG_FIRST_FONT_PATH = "/data/fonts/Igiari-2.otf";
193 /**
194 * @tc.name:GetFontFullName001
195 * @tc.desc: Check the validity of the TTF file and obtain the full name
196 * @tc.type: FUNC
197 * @tc.require: I91F9L
198 */
199 HWTEST_F(FontMgrTest, GetFontFullName001, TestSize.Level1)
200 {
201 std::shared_ptr<FontMgr> fontMgr = FontMgr::CreateDefaultFontMgr();
202 EXPECT_NE(fontMgr, nullptr);
203 std::vector<FontByteArray> fullnameVec;
204 std::string fontPath = TTF_FILE_PATH;
205 int fd = open(fontPath.c_str(), O_RDONLY);
206 if (fd != -1) {
207 int ret = fontMgr->GetFontFullName(fd, fullnameVec);
208 close(fd);
209 EXPECT_TRUE(ret == 0 && fullnameVec.size() > 0);
210 EXPECT_EQ(fullnameVec[0].strLen, sizeof(TTF_FULLNAME));
211 EXPECT_EQ(memcmp(fullnameVec[0].strData.get(), TTF_FULLNAME, fullnameVec[0].strLen), 0);
212 }
213 }
214
215 /**
216 * @tc.name:GetFontFullName002
217 * @tc.desc: Check the validity of the OTF file and obtain the full name
218 * @tc.type: FUNC
219 * @tc.require: I91F9L
220 */
221 HWTEST_F(FontMgrTest, GetFontFullName002, TestSize.Level1)
222 {
223 std::shared_ptr<FontMgr> fontMgr = FontMgr::CreateDefaultFontMgr();
224 EXPECT_NE(fontMgr, nullptr);
225 std::vector<FontByteArray> fullnameVec;
226 std::string fontPath = OTF_FILE_PATH;
227 int fd = open(fontPath.c_str(), O_RDONLY);
228 if (fd != -1) {
229 int ret = fontMgr->GetFontFullName(fd, fullnameVec);
230 close(fd);
231 EXPECT_TRUE(ret == 0 && fullnameVec.size() > 0);
232 EXPECT_EQ(fullnameVec[0].strLen, sizeof(OTF_FULLNAME));
233 EXPECT_EQ(memcmp(fullnameVec[0].strData.get(), OTF_FULLNAME, fullnameVec[0].strLen), 0);
234 }
235 }
236
237 /**
238 * @tc.name:GetFontFullName003
239 * @tc.desc: Check the validity of the TTC file and obtain the full name
240 * @tc.type: FUNC
241 * @tc.require: I91F9L
242 */
243 HWTEST_F(FontMgrTest, GetFontFullName003, TestSize.Level1)
244 {
245 std::shared_ptr<FontMgr> fontMgr = FontMgr::CreateDefaultFontMgr();
246 EXPECT_NE(fontMgr, nullptr);
247 std::vector<FontByteArray> fullnameVec;
248 std::string fontPath = TTC_FILE_PATH;
249 int fd = open(fontPath.c_str(), O_RDONLY);
250 if (fd != -1) {
251 int ret = fontMgr->GetFontFullName(fd, fullnameVec);
252 close(fd);
253 EXPECT_TRUE(ret == 0 && fullnameVec.size() > 0);
254 EXPECT_EQ(fullnameVec[0].strLen, sizeof(TTC_FULLNAME));
255 EXPECT_EQ(memcmp(fullnameVec[0].strData.get(), TTC_FULLNAME, fullnameVec[0].strLen), 0);
256 }
257 }
258
259 /**
260 * @tc.name:GetFontFullName004
261 * @tc.desc: Enter an incorrect path and return the corresponding error reason code
262 * @tc.type: FUNC
263 * @tc.require: I91F9L
264 */
265 HWTEST_F(FontMgrTest, GetFontFullName004, TestSize.Level1)
266 {
267 std::shared_ptr<FontMgr> fontMgr = FontMgr::CreateDefaultFontMgr();
268 EXPECT_NE(fontMgr, nullptr);
269 std::vector<FontByteArray> fullnameVec;
270 std::string fontPath = ERRORPATH_FILE_PATH;
271 int fd = open(fontPath.c_str(), O_RDONLY);
272 int ret = fontMgr->GetFontFullName(fd, fullnameVec);
273 if (fd != -1) {
274 close(fd);
275 }
276 EXPECT_EQ(ret, ERROR_TYPE_OTHER);
277 }
278 /**
279 * @tc.name:GetFontFullName005
280 * @tc.desc: Enter an empty path and return the corresponding error reason code
281 * @tc.type: FUNC
282 * @tc.require: I91F9L
283 */
284 HWTEST_F(FontMgrTest, GetFontFullName005, TestSize.Level1)
285 {
286 std::shared_ptr<FontMgr> fontMgr = FontMgr::CreateDefaultFontMgr();
287 EXPECT_NE(fontMgr, nullptr);
288 std::vector<FontByteArray> fullnameVec;
289 std::string filepath = "";
290 int fd = open(filepath.c_str(), O_RDONLY);
291 int ret = fontMgr->GetFontFullName(fd, fullnameVec);
292 if (fd != -1) {
293 close(fd);
294 }
295 EXPECT_EQ(ret, ERROR_TYPE_OTHER);
296 }
297 /**
298 * @tc.name:GetFontFullName006
299 * @tc.desc: Enter the file path of an incorrectly formatted font file and return the corresponding error reason code
300 * @tc.type: FUNC
301 * @tc.require: I91F9L
302 */
303 HWTEST_F(FontMgrTest, GetFontFullName006, TestSize.Level1)
304 {
305 std::shared_ptr<FontMgr> fontMgr = FontMgr::CreateDefaultFontMgr();
306 EXPECT_NE(fontMgr, nullptr);
307 std::vector<FontByteArray> fullnameVec;
308 std::string fontPath = ERRORFORMAT_FILE_PATH;
309 int fd = open(fontPath.c_str(), O_RDONLY);
310 int ret = fontMgr->GetFontFullName(fd, fullnameVec);
311 if (fd != -1) {
312 close(fd);
313 }
314 EXPECT_EQ(ret, ERROR_TYPE_OTHER);
315 }
316
317 /**
318 * @tc.name:ParseInstallFontConfig001
319 * @tc.desc: Enter the path of a properly formatted JSON configuration file and parse it successfully
320 * @tc.type: FUNC
321 * @tc.require: I91F9L
322 */
323 HWTEST_F(FontMgrTest, ParseInstallFontConfig001, TestSize.Level1)
324 {
325 std::shared_ptr<FontMgr> fontMgr = FontMgr::CreateDynamicFontMgr();
326 EXPECT_NE(fontMgr, nullptr);
327 std::vector<std::string> fontPathVec;
328 std::string configPath = JSON_CONFIG_PATH;
329 std::ifstream configFile(configPath, std::ios::in);
330 if (configFile.is_open()) {
331 configFile.close();
332 int ret = fontMgr->ParseInstallFontConfig(configPath, fontPathVec);
333 EXPECT_TRUE(ret == 0 && fontPathVec.size() > 0);
334 EXPECT_EQ(fontPathVec[0], CONFIG_FIRST_FONT_PATH);
335 }
336 }
337 /**
338 * @tc.name:ParseInstallFontConfig002
339 * @tc.desc: Enter the path of a valid JSON configuration file and fail to parse it
340 * @tc.type: FUNC
341 * @tc.require: I91F9L
342 */
343 HWTEST_F(FontMgrTest, ParseInstallFontConfig002, TestSize.Level1)
344 {
345 std::shared_ptr<FontMgr> fontMgr = FontMgr::CreateDynamicFontMgr();
346 EXPECT_NE(fontMgr, nullptr);
347 std::vector<std::string> fontPathVec;
348 std::string configPath = ERROR_JSON_CONFIG_PATH;
349 int ret = fontMgr->ParseInstallFontConfig(configPath, fontPathVec);
350 EXPECT_EQ(ret, ERROR_PARSE_CONFIG_FAILED);
351 }
352 /**
353 * @tc.name:ParseInstallFontConfig003
354 * @tc.desc: Enter an empty file path and fail to parse
355 * @tc.type: FUNC
356 * @tc.require: I91F9L
357 */
358 HWTEST_F(FontMgrTest, ParseInstallFontConfig003, TestSize.Level1)
359 {
360 std::shared_ptr<FontMgr> fontMgr = FontMgr::CreateDynamicFontMgr();
361 EXPECT_NE(fontMgr, nullptr);
362 std::vector<std::string> fontPathVec;
363 std::string configPath = "";
364 int ret = fontMgr->ParseInstallFontConfig(configPath, fontPathVec);
365 EXPECT_EQ(ret, ERROR_PARSE_CONFIG_FAILED);
366 }
367 } // namespace Drawing
368 } // namespace Rosen
369 } // namespace OHOS
370