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_TRUE(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_TRUE(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_TRUE(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     ASSERT_GE(familyCount, 0);
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     ASSERT_TRUE(familyName.length() > 0);
120 }
121 
122 /**
123  * @tc.name:CreateStyleSet001
124  * @tc.desc: Test CreateStyleSet
125  * @tc.type: FUNC
126  * @tc.require: I91F9L
127  */
128 HWTEST_F(FontMgrTest, CreateStyleSet001, TestSize.Level1)
129 {
130     std::shared_ptr<FontMgr> FontMgr = FontMgr::CreateDefaultFontMgr();
131     ASSERT_TRUE(FontMgr != nullptr);
132     FontStyleSet* fontStyleSet = FontMgr->CreateStyleSet(0);
133     ASSERT_TRUE(fontStyleSet != nullptr);
134 }
135 
136 const char* TTF_FILE_PATH = "/system/fonts/Roboto-Regular.ttf";
137 // The ttf font file fullname is the utf16BE format content corresponding to "Noto Sans Regular"
138 const uint8_t TTF_FULLNAME[] = {0x0, 0x4e, 0x0, 0x6f, 0x0, 0x74, 0x0, 0x6f, 0x0, 0x20, 0x0, 0x53,
139                                 0x0, 0x61, 0x0, 0x6e, 0x0, 0x73, 0x0, 0x20, 0x0, 0x52, 0x0, 0x65,
140                                 0x0, 0x67, 0x0, 0x75, 0x0, 0x6c, 0x0, 0x61, 0x0, 0x72};
141 const char* OTF_FILE_PATH = "/data/fonts/Igiari-2.otf";
142 // The otf font file fullname is the utf16BE format content corresponding to "Igiari"
143 const uint8_t OTF_FULLNAME[] = {0x0, 0x49, 0x0, 0x67, 0x0, 0x69, 0x0, 0x61, 0x0, 0x72, 0x0, 0x69};
144 const char* TTC_FILE_PATH = "/system/fonts/NotoSerifCJK-Regular.ttc";
145 // The ttc font file fullname is the utf16BE format content corresponding to "Noto Serif CJK JP"
146 const uint8_t TTC_FULLNAME[] = {0x0, 0x4e, 0x0, 0x6f, 0x0, 0x74, 0x0, 0x6f, 0x0, 0x20, 0x0, 0x53,
147                                 0x0, 0x65, 0x0, 0x72, 0x0, 0x69, 0x0, 0x66, 0x0, 0x20, 0x0, 0x43,
148                                 0x0, 0x4a, 0x0, 0x4b, 0x0, 0x20, 0x0, 0x4a, 0x0, 0x50};
149 const char* ERRORPATH_FILE_PATH = "/system/fonts/error_path.ttf";
150 const char* ERRORFORMAT_FILE_PATH = "/system/etc/fontconfig.json";
151 const char* JSON_CONFIG_PATH = "/data/fonts/install_fontconfig.json";
152 const char* ERROR_JSON_CONFIG_PATH = "/data/fonts/error_path.json";
153 const char* CONFIG_FIRST_FONT_PATH = "/data/fonts/Igiari-2.otf";
154 /**
155  * @tc.name:GetFontFullName001
156  * @tc.desc: Check the validity of the TTF file and obtain the full name
157  * @tc.type: FUNC
158  * @tc.require: I91F9L
159  */
160 HWTEST_F(FontMgrTest, GetFontFullName001, TestSize.Level1)
161 {
162     std::shared_ptr<FontMgr> fontMgr = FontMgr::CreateDefaultFontMgr();
163     EXPECT_NE(fontMgr, nullptr);
164     std::vector<FontByteArray> fullnameVec;
165     std::string fontPath = TTF_FILE_PATH;
166     int fd = open(fontPath.c_str(), O_RDONLY);
167     if (fd != -1) {
168         int ret = fontMgr->GetFontFullName(fd, fullnameVec);
169         close(fd);
170         EXPECT_TRUE(ret == 0 && fullnameVec.size() > 0);
171         EXPECT_EQ(fullnameVec[0].strLen, sizeof(TTF_FULLNAME));
172         EXPECT_EQ(memcmp(fullnameVec[0].strData.get(), TTF_FULLNAME, fullnameVec[0].strLen), 0);
173     }
174 }
175 
176 /**
177  * @tc.name:GetFontFullName002
178  * @tc.desc: Check the validity of the OTF file and obtain the full name
179  * @tc.type: FUNC
180  * @tc.require: I91F9L
181  */
182 HWTEST_F(FontMgrTest, GetFontFullName002, TestSize.Level1)
183 {
184     std::shared_ptr<FontMgr> fontMgr = FontMgr::CreateDefaultFontMgr();
185     EXPECT_NE(fontMgr, nullptr);
186     std::vector<FontByteArray> fullnameVec;
187     std::string fontPath = OTF_FILE_PATH;
188     int fd = open(fontPath.c_str(), O_RDONLY);
189     if (fd != -1) {
190         int ret = fontMgr->GetFontFullName(fd, fullnameVec);
191         close(fd);
192         EXPECT_TRUE(ret == 0 && fullnameVec.size() > 0);
193         EXPECT_EQ(fullnameVec[0].strLen, sizeof(OTF_FULLNAME));
194         EXPECT_EQ(memcmp(fullnameVec[0].strData.get(), OTF_FULLNAME, fullnameVec[0].strLen), 0);
195     }
196 }
197 
198 /**
199  * @tc.name:GetFontFullName003
200  * @tc.desc: Check the validity of the TTC file and obtain the full name
201  * @tc.type: FUNC
202  * @tc.require: I91F9L
203  */
204 HWTEST_F(FontMgrTest, GetFontFullName003, TestSize.Level1)
205 {
206     std::shared_ptr<FontMgr> fontMgr = FontMgr::CreateDefaultFontMgr();
207     EXPECT_NE(fontMgr, nullptr);
208     std::vector<FontByteArray> fullnameVec;
209     std::string fontPath = TTC_FILE_PATH;
210     int fd = open(fontPath.c_str(), O_RDONLY);
211     if (fd != -1) {
212         int ret = fontMgr->GetFontFullName(fd, fullnameVec);
213         close(fd);
214         EXPECT_TRUE(ret == 0 && fullnameVec.size() > 0);
215         EXPECT_EQ(fullnameVec[0].strLen, sizeof(TTC_FULLNAME));
216         EXPECT_EQ(memcmp(fullnameVec[0].strData.get(), TTC_FULLNAME, fullnameVec[0].strLen), 0);
217     }
218 }
219 
220 /**
221  * @tc.name:GetFontFullName004
222  * @tc.desc: Enter an incorrect path and return the corresponding error reason code
223  * @tc.type: FUNC
224  * @tc.require: I91F9L
225  */
226 HWTEST_F(FontMgrTest, GetFontFullName004, TestSize.Level1)
227 {
228     std::shared_ptr<FontMgr> fontMgr = FontMgr::CreateDefaultFontMgr();
229     EXPECT_NE(fontMgr, nullptr);
230     std::vector<FontByteArray> fullnameVec;
231     std::string fontPath = ERRORPATH_FILE_PATH;
232     int fd = open(fontPath.c_str(), O_RDONLY);
233     int ret = fontMgr->GetFontFullName(fd, fullnameVec);
234     if (fd != -1) {
235         close(fd);
236     }
237     EXPECT_EQ(ret, ERROR_TYPE_OTHER);
238 }
239 /**
240  * @tc.name:GetFontFullName005
241  * @tc.desc: Enter an empty path and return the corresponding error reason code
242  * @tc.type: FUNC
243  * @tc.require: I91F9L
244  */
245 HWTEST_F(FontMgrTest, GetFontFullName005, TestSize.Level1)
246 {
247     std::shared_ptr<FontMgr> fontMgr = FontMgr::CreateDefaultFontMgr();
248     EXPECT_NE(fontMgr, nullptr);
249     std::vector<FontByteArray> fullnameVec;
250     std::string filepath = "";
251     int fd = open(filepath.c_str(), O_RDONLY);
252     int ret = fontMgr->GetFontFullName(fd, fullnameVec);
253     if (fd != -1) {
254         close(fd);
255     }
256     EXPECT_EQ(ret, ERROR_TYPE_OTHER);
257 }
258 /**
259  * @tc.name:GetFontFullName006
260  * @tc.desc: Enter the file path of an incorrectly formatted font file and return the corresponding error reason code
261  * @tc.type: FUNC
262  * @tc.require: I91F9L
263  */
264 HWTEST_F(FontMgrTest, GetFontFullName006, TestSize.Level1)
265 {
266     std::shared_ptr<FontMgr> fontMgr = FontMgr::CreateDefaultFontMgr();
267     EXPECT_NE(fontMgr, nullptr);
268     std::vector<FontByteArray> fullnameVec;
269     std::string fontPath = ERRORFORMAT_FILE_PATH;
270     int fd = open(fontPath.c_str(), O_RDONLY);
271     int ret = fontMgr->GetFontFullName(fd, fullnameVec);
272     if (fd != -1) {
273         close(fd);
274     }
275     EXPECT_EQ(ret, ERROR_TYPE_OTHER);
276 }
277 
278 /**
279  * @tc.name:ParseInstallFontConfig001
280  * @tc.desc: Enter the path of a properly formatted JSON configuration file and parse it successfully
281  * @tc.type: FUNC
282  * @tc.require: I91F9L
283  */
284 HWTEST_F(FontMgrTest, ParseInstallFontConfig001, TestSize.Level1)
285 {
286     std::shared_ptr<FontMgr> fontMgr = FontMgr::CreateDynamicFontMgr();
287     EXPECT_NE(fontMgr, nullptr);
288     std::vector<std::string> fontPathVec;
289     std::string configPath = JSON_CONFIG_PATH;
290     std::ifstream configFile(configPath, std::ios::in);
291     if (configFile.is_open()) {
292         configFile.close();
293         int ret = fontMgr->ParseInstallFontConfig(configPath, fontPathVec);
294         EXPECT_TRUE(ret == 0 && fontPathVec.size() > 0);
295         EXPECT_EQ(fontPathVec[0], CONFIG_FIRST_FONT_PATH);
296     }
297 }
298 /**
299  * @tc.name:ParseInstallFontConfig002
300  * @tc.desc: Enter the path of a valid JSON configuration file and fail to parse it
301  * @tc.type: FUNC
302  * @tc.require: I91F9L
303  */
304 HWTEST_F(FontMgrTest, ParseInstallFontConfig002, TestSize.Level1)
305 {
306     std::shared_ptr<FontMgr> fontMgr = FontMgr::CreateDynamicFontMgr();
307     EXPECT_NE(fontMgr, nullptr);
308     std::vector<std::string> fontPathVec;
309     std::string configPath = ERROR_JSON_CONFIG_PATH;
310     int ret = fontMgr->ParseInstallFontConfig(configPath, fontPathVec);
311     EXPECT_EQ(ret, ERROR_PARSE_CONFIG_FAILED);
312 }
313 /**
314  * @tc.name:ParseInstallFontConfig003
315  * @tc.desc: Enter an empty file path and fail to parse
316  * @tc.type: FUNC
317  * @tc.require: I91F9L
318  */
319 HWTEST_F(FontMgrTest, ParseInstallFontConfig003, TestSize.Level1)
320 {
321     std::shared_ptr<FontMgr> fontMgr = FontMgr::CreateDynamicFontMgr();
322     EXPECT_NE(fontMgr, nullptr);
323     std::vector<std::string> fontPathVec;
324     std::string configPath = "";
325     int ret = fontMgr->ParseInstallFontConfig(configPath, fontPathVec);
326     EXPECT_EQ(ret, ERROR_PARSE_CONFIG_FAILED);
327 }
328 } // namespace Drawing
329 } // namespace Rosen
330 } // namespace OHOS
331