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 <cstddef>
17 #include <fstream>
18
19 #include "gtest/gtest.h"
20
21 #include "text/typeface.h"
22 #include "utils/memory_stream.h"
23
24 using namespace testing;
25 using namespace testing::ext;
26
HB_TAG(char c1,char c2,char c3,char c4)27 constexpr uint32_t HB_TAG(char c1, char c2, char c3, char c4)
28 {
29 const uint32_t c1_shift = static_cast<uint32_t>(c1) & 0xFF;
30 const uint32_t c2_shift = static_cast<uint32_t>(c2) & 0xFF;
31 const uint32_t c3_shift = static_cast<uint32_t>(c3) & 0xFF;
32 const uint32_t c4_shift = static_cast<uint32_t>(c4) & 0xFF;
33 return (c1_shift << 24) | // 24 is the shift for the first byte
34 (c2_shift << 16) | // 16 is the shift for the second byte
35 (c3_shift << 8) | // 8 is the shift for the third byte
36 c4_shift;
37 }
38
39 namespace OHOS {
40 namespace Rosen {
41 namespace Drawing {
42 class TypefaceTest : public testing::Test {
43 public:
44 static void SetUpTestCase();
45 static void TearDownTestCase();
46
47 inline static std::unique_ptr<char[]> ttfData_;
48 inline static size_t ttfLen_;
49 std::string familyName_ = { 0x48, 0x61, 0x72, 0x6D, 0x6F, 0x6E, 0x79, 0x4F, 0x53, 0x20, 0x53, 0x61, 0x6E, 0x73 };
50 };
51
SetUpTestCase()52 void TypefaceTest::SetUpTestCase()
53 {
54 // ttf file path
55 std::string ttfName = { 0x2F, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x2F, 0x66, 0x6F, 0x6E, 0x74, 0x73, 0x2F, 0x48,
56 0x61, 0x72, 0x6D, 0x6F, 0x6E, 0x79, 0x4F, 0x53, 0x5F, 0x53, 0x61, 0x6E, 0x73, 0x2E, 0x74, 0x74, 0x66 };
57 std::ifstream ttfFile(ttfName, std::ios::in | std::ios::binary);
58 ASSERT_TRUE(ttfFile.is_open());
59 ttfFile.seekg(0, std::ios::end);
60 ttfLen_ = ttfFile.tellg();
61 if (ttfLen_ >= INT_MAX) {
62 ASSERT_TRUE(false);
63 }
64 ttfFile.seekg(0, std::ios::beg);
65 ttfData_.reset(new char[ttfLen_]);
66 ASSERT_NE(ttfData_, nullptr);
67 ttfFile.read(ttfData_.get(), ttfLen_);
68 ttfFile.close();
69 }
70
TearDownTestCase()71 void TypefaceTest::TearDownTestCase()
72 {
73 ttfData_.reset();
74 }
75
76 /**
77 * @tc.name: MakeFromStream001
78 * @tc.desc: Test MakeFromStream
79 * @tc.type: FUNC
80 * @tc.require:I91EDT
81 */
82 HWTEST_F(TypefaceTest, MakeFromStream001, TestSize.Level1)
83 {
84 auto stream = std::make_unique<MemoryStream>(ttfData_.get(), ttfLen_);
85 ASSERT_NE(stream, nullptr);
86 auto typeface = Typeface::MakeFromStream(std::move(stream));
87 ASSERT_NE(typeface, nullptr);
88 EXPECT_EQ(typeface->GetFamilyName(), familyName_);
89 }
90
91 /**
92 * @tc.name: MakeFromStream002
93 * @tc.desc: Test MakeFromStream
94 * @tc.type: FUNC
95 * @tc.require:I91EDT
96 */
97 HWTEST_F(TypefaceTest, MakeFromStream002, TestSize.Level1)
98 {
99 auto stream = std::make_unique<MemoryStream>(ttfData_.get(), ttfLen_);
100 ASSERT_NE(stream, nullptr);
101 FontArguments args;
102 args.SetCollectionIndex(0);
103 auto typeface = Typeface::MakeFromStream(std::move(stream), args);
104 ASSERT_NE(typeface, nullptr);
105 EXPECT_EQ(typeface->GetFamilyName(), familyName_);
106 auto typeface2 = Typeface::MakeFromStream(nullptr, args);
107 ASSERT_EQ(typeface2, nullptr);
108 }
109
110 /**
111 * @tc.name: MakeFromName001
112 * @tc.desc: Test MakeFromName
113 * @tc.type: FUNC
114 * @tc.require:I91EDT
115 */
116 HWTEST_F(TypefaceTest, MakeFromName001, TestSize.Level1)
117 {
118 FontStyle style;
119 std::string familyName = "Arial";
120 std::string resultFamilyName = { 0x0048, 0x0061, 0x0072, 0x006D, 0x006F, 0x006E, 0x0079, 0x004F, 0x0053, 0x002D,
121 0x0053, 0x0061, 0x006E, 0x0073 };
122 auto typeface = Typeface::MakeFromName(familyName.c_str(), style);
123 ASSERT_NE(typeface, nullptr);
124 EXPECT_EQ(typeface->GetFamilyName(), resultFamilyName);
125 }
126
127 /**
128 * @tc.name: MakeClone001
129 * @tc.desc: Test MakeClone
130 * @tc.type: FUNC
131 * @tc.require:I91EDT
132 */
133 HWTEST_F(TypefaceTest, MakeClone001, TestSize.Level1)
134 {
135 auto stream = std::make_unique<MemoryStream>(ttfData_.get(), ttfLen_);
136 ASSERT_NE(stream, nullptr);
137
138 auto typeface = Typeface::MakeFromStream(std::move(stream));
139 ASSERT_NE(typeface, nullptr);
140 FontArguments arg;
141 auto clonedTypeface = typeface->MakeClone(arg);
142 ASSERT_NE(clonedTypeface, nullptr);
143 EXPECT_EQ(clonedTypeface->GetHash(), typeface->GetHash());
144 }
145
146 /**
147 * @tc.name: GetTableSize001
148 * @tc.desc: Test GetTableSize
149 * @tc.type: FUNC
150 * @tc.require:I91EDT
151 */
152 HWTEST_F(TypefaceTest, GetTableSize001, TestSize.Level1)
153 {
154 auto stream = std::make_unique<MemoryStream>(ttfData_.get(), ttfLen_);
155 ASSERT_NE(stream, nullptr);
156
157 auto typeface = Typeface::MakeFromStream(std::move(stream));
158 ASSERT_NE(typeface, nullptr);
159 // 'cmap' table size is 2516
160 EXPECT_EQ(typeface->GetTableSize(HB_TAG('c', 'm', 'a', 'p')), 2516);
161 }
162
163 /**
164 * @tc.name: Serialize001
165 * @tc.desc: Test Serialize
166 * @tc.type: FUNC
167 * @tc.require:I91EDT
168 */
169 HWTEST_F(TypefaceTest, Serialize001, TestSize.Level1)
170 {
171 auto stream = std::make_unique<MemoryStream>(ttfData_.get(), ttfLen_);
172 ASSERT_NE(stream, nullptr);
173
174 auto typeface = Typeface::MakeFromStream(std::move(stream));
175 ASSERT_NE(typeface, nullptr);
176 auto serialized = typeface->Serialize();
177 ASSERT_NE(serialized, nullptr);
178 EXPECT_EQ(serialized->GetSize(), typeface->GetSize());
179 }
180
181 /**
182 * @tc.name: Deserialize001
183 * @tc.desc: Test Deserialize
184 * @tc.type: FUNC
185 * @tc.require:I91EDT
186 */
187 HWTEST_F(TypefaceTest, Deserialize001, TestSize.Level1)
188 {
189 auto stream = std::make_unique<MemoryStream>(ttfData_.get(), ttfLen_);
190 ASSERT_NE(stream, nullptr);
191
192 auto typeface = Typeface::MakeFromStream(std::move(stream));
193 ASSERT_NE(typeface, nullptr);
194 auto serialized = typeface->Serialize();
195 ASSERT_NE(serialized, nullptr);
196 auto deserialized = Typeface::Deserialize(serialized->GetData(), serialized->GetSize());
197 ASSERT_NE(deserialized, nullptr);
198 EXPECT_EQ(deserialized->GetFamilyName(), familyName_);
199 }
200
201 /**
202 * @tc.name: SetHash001
203 * @tc.desc: Test Set Hash
204 * @tc.type: FUNC
205 * @tc.require:I91EDT
206 */
207 HWTEST_F(TypefaceTest, SetHash001, TestSize.Level1)
208 {
209 auto stream = std::make_unique<MemoryStream>(ttfData_.get(), ttfLen_);
210 ASSERT_NE(stream, nullptr);
211
212 auto typeface = Typeface::MakeFromStream(std::move(stream));
213 ASSERT_NE(typeface, nullptr);
214 uint32_t hash = 1;
215 typeface->SetHash(hash);
216 }
217
218 /**
219 * @tc.name: NullTests001
220 * @tc.desc: Test nullptr
221 * @tc.type: FUNC
222 * @tc.require:I91EDT
223 */
224 HWTEST_F(TypefaceTest, NullTests001, TestSize.Level1)
225 {
226 auto typeface = std::make_shared<Typeface>(nullptr);
227 ASSERT_NE(typeface, nullptr);
228 EXPECT_EQ(typeface->GetFamilyName(), "");
229 EXPECT_EQ(typeface->GetTableSize(0), 0);
230 EXPECT_EQ(typeface->GetTableData(0, 0, 0, nullptr), 0);
231 EXPECT_EQ(typeface->GetItalic(), false);
232 EXPECT_EQ(typeface->GetUniqueID(), 0);
233 EXPECT_EQ(typeface->Serialize(), nullptr);
234 char data[10] = { 0 };
235 EXPECT_EQ(Typeface::Deserialize(data, 10), nullptr);
236 EXPECT_EQ(typeface->GetFontStyle(), FontStyle());
237 EXPECT_EQ(typeface->GetUnitsPerEm(), 0);
238 EXPECT_EQ(typeface->IsCustomTypeface(), false);
239 EXPECT_EQ(typeface->IsThemeTypeface(), false);
240 EXPECT_EQ(typeface->GetHash(), 0);
241 uint32_t hash = 1;
242 typeface->SetHash(hash);
243 EXPECT_EQ(typeface->GetSize(), 0);
244 FontArguments arg;
245 EXPECT_EQ(typeface->MakeClone(arg), nullptr);
246 }
247 } // namespace Drawing
248 } // namespace Rosen
249 } // namespace OHOS