• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 <gtest/gtest.h>
17 
18 #include "font_collection.h"
19 #include "measurer.h"
20 #include "mock/mock_any_span.h"
21 #include "mock/mock_measurer.h"
22 #include "param_test_macros.h"
23 #include "texgine_exception.h"
24 #include "texgine/font_providers.h"
25 #include "texgine_text_blob.h"
26 #include "texgine_text_blob_builder.h"
27 #include "texgine/typography_types.h"
28 #include "text_shaper.h"
29 #include "typeface.h"
30 
31 using namespace testing;
32 using namespace testing::ext;
33 
34 namespace OHOS {
35 namespace Rosen {
36 namespace TextEngine {
37 struct MockVars {
38     std::vector<uint16_t> catchedBufferGlyphs;
39     std::vector<float> catchedBufferPos;
40     std::vector<std::string> catchedGenerateFontCollectionFamilies;
41 
42     std::shared_ptr<TexgineTextBlob> retvalTextBlobBuilderMake = nullptr;
43     std::shared_ptr<FontCollection> retvalGenerateFontCollection =
44         std::make_shared<FontCollection>(std::vector<std::shared_ptr<VariantFontStyleSet>>{});
45     std::unique_ptr<MockMeasurer> retvalMeasurerCreate = std::make_unique<MockMeasurer>();
46 } g_tsMockvars;
47 
InitTsMockVars(struct MockVars && vars)48 void InitTsMockVars(struct MockVars &&vars)
49 {
50     g_tsMockvars = std::move(vars);
51 }
52 
AllocRunPos(const TexgineFont & font,int count)53 std::shared_ptr<TexgineTextBlobBuilder::RunBuffer> TexgineTextBlobBuilder::AllocRunPos(const TexgineFont& font,
54     int count)
55 {
56     static std::shared_ptr<TexgineTextBlobBuilder::RunBuffer> buffer =
57         std::make_shared<TexgineTextBlobBuilder::RunBuffer>();
58     g_tsMockvars.catchedBufferGlyphs.resize(count);
59     g_tsMockvars.catchedBufferPos.resize(count * 2);
60     buffer->glyphs = g_tsMockvars.catchedBufferGlyphs.data();
61     buffer->pos = g_tsMockvars.catchedBufferPos.data();
62     return buffer;
63 }
64 
Make()65 std::shared_ptr<TexgineTextBlob> TexgineTextBlobBuilder::Make()
66 {
67     return g_tsMockvars.retvalTextBlobBuilderMake;
68 }
69 
GenerateFontCollection(const std::vector<std::string> & families) const70 std::shared_ptr<FontCollection> FontProviders::GenerateFontCollection(
71     const std::vector<std::string> &families) const noexcept(true)
72 {
73     g_tsMockvars.catchedGenerateFontCollectionFamilies = families;
74     return g_tsMockvars.retvalGenerateFontCollection;
75 }
76 
Create(const std::vector<uint16_t> & text,const FontCollection & fontCollection)77 std::unique_ptr<Measurer> Measurer::Create(const std::vector<uint16_t> &text,
78     const FontCollection &fontCollection)
79 {
80     return std::move(g_tsMockvars.retvalMeasurerCreate);
81 }
82 
83 struct TextSpanInfo {
84     CharGroups cgs_ = CharGroups::CreateEmpty();
85 };
86 
87 class ControllerForTest {
88 public:
GenerateTextSpan(TextSpanInfo info)89     static std::shared_ptr<TextSpan> GenerateTextSpan(TextSpanInfo info)
90     {
91         auto ts = std::make_shared<TextSpan>();
92         ts->cgs_ = info.cgs_;
93         return ts;
94     }
95 };
96 
GenerateTextSpan(TextSpanInfo info)97 auto GenerateTextSpan(TextSpanInfo info)
98 {
99     return ControllerForTest::GenerateTextSpan(info);
100 }
101 
102 class TextShaperTest : public testing::TestWithParam<std::shared_ptr<TextSpan>> {
103 public:
SetUpTestCase()104     static void SetUpTestCase()
105     {
106         // {1, 1, 0, 0.1, 0.1} is {code point, advanceX, advanceY, offsetX, offsetY}
107         cgs1_.PushBack({ .glyphs = { {1, 1, 0, 0.1, 0.1}, {2, 1, 0, 0.2, 0.2} }, .visibleWidth = 2 });
108         cgs2_.PushBack({ .glyphs = { {1, 1, 0, 0.1, 0.1} }, .visibleWidth = 1 });
109         cgs2_.PushBack({ .glyphs = { {2, 1, 0, 0.2, 0.2} }, .visibleWidth = 1 });
110     }
111 
112     static inline CharGroups cgs1_ = CharGroups::CreateEmpty();
113     static inline CharGroups cgs2_ = CharGroups::CreateEmpty();
114     static inline std::shared_ptr<TypographyStyle> ysNormal_ = std::make_shared<TypographyStyle>();
115     static inline std::shared_ptr<TypographyStyle> ysNoProvider_ = std::make_shared<TypographyStyle>();
116 };
117 
118 /**
119  * @tc.name: DoShape1
120  * @tc.desc: Verify the DoShape
121  * @tc.type:FUNC
122  */
123 HWTEST_F(TextShaperTest, DoShape1, TestSize.Level1)
124 {
125     TextShaper shaper;
126     auto fp = FontProviders::Create();
127     std::shared_ptr<TextSpan> tsNullptr;
128     auto tsNormal = TextSpan::MakeFromText("normal");
129     ASSERT_EXCEPTION(ExceptionType::INVALID_ARGUMENT, shaper.DoShape(tsNullptr, {}, {}, fp));
130     ASSERT_EXCEPTION(ExceptionType::INVALID_ARGUMENT, shaper.DoShape(tsNormal, {}, {}, nullptr));
131 }
132 
133 /**
134  * @tc.name: DoShape2
135  * @tc.desc: Verify the DoShape
136  * @tc.type:FUNC
137  */
138 HWTEST_F(TextShaperTest, DoShape2, TestSize.Level1)
139 {
140     InitTsMockVars({});
141     EXPECT_CALL(*g_tsMockvars.retvalMeasurerCreate, Measure).Times(1).WillOnce(testing::Return(0));
142     TypographyStyle ys;
143     ys.fontFamilies = {"Roboto"};
144     auto span = GenerateTextSpan({.cgs_ = cgs1_});
145 
146     EXPECT_NO_THROW({
147         TextShaper shaper;
148         shaper.DoShape(span, {}, ys, FontProviders::Create());
149         ASSERT_EQ(ys.fontFamilies, g_tsMockvars.catchedGenerateFontCollectionFamilies);
150     });
151 }
152 
153 /**
154  * @tc.name: DoShape3
155  * @tc.desc: Verify the DoShape
156  * @tc.type:FUNC
157  */
158 HWTEST_F(TextShaperTest, DoShape3, TestSize.Level1)
159 {
160     InitTsMockVars({});
161     EXPECT_CALL(*g_tsMockvars.retvalMeasurerCreate, Measure).Times(1).WillOnce(testing::Return(0));
162     TextStyle style = {.fontFamilies = {"Sans"}};
163     auto span = GenerateTextSpan({.cgs_ = cgs1_});
164 
165     EXPECT_NO_THROW({
166         TextShaper shaper;
167         shaper.DoShape(span, style, {}, FontProviders::Create());
168         ASSERT_EQ(style.fontFamilies , g_tsMockvars.catchedGenerateFontCollectionFamilies);
169     });
170 }
171 
172 /**
173  * @tc.name: DoShape4
174  * @tc.desc: Verify the DoShape
175  * @tc.type:FUNC
176  */
177 HWTEST_F(TextShaperTest, DoShape4, TestSize.Level1)
178 {
179     InitTsMockVars({.retvalGenerateFontCollection = nullptr});
180     auto span = GenerateTextSpan({});
181 
182     EXPECT_NO_THROW({
183         TextShaper shaper;
184         auto ret = shaper.DoShape(span, {}, {}, FontProviders::Create());
185         ASSERT_EQ(ret, 1);
186     });
187 }
188 
189 /**
190  * @tc.name: DoShape5
191  * @tc.desc: Verify the DoShape
192  * @tc.type:FUNC
193  */
194 HWTEST_F(TextShaperTest, DoShape5, TestSize.Level1)
195 {
196     InitTsMockVars({});
197     EXPECT_CALL(*g_tsMockvars.retvalMeasurerCreate, Measure).Times(1).WillOnce(testing::Return(1));
198     auto span = GenerateTextSpan({.cgs_ = cgs1_});
199 
200     EXPECT_NO_THROW({
201         TextShaper shaper;
202         auto ret = shaper.DoShape(span, {}, {}, FontProviders::Create());
203         ASSERT_EQ(ret, 1);
204     });
205 }
206 
207 /**
208  * @tc.name: DoShape6
209  * @tc.desc: Verify the DoShape
210  * @tc.type:FUNC
211  */
212 HWTEST_F(TextShaperTest, DoShape6, TestSize.Level1)
213 {
214     InitTsMockVars({});
215     EXPECT_CALL(*g_tsMockvars.retvalMeasurerCreate, Measure).Times(1).WillOnce(testing::Return(0));
216     auto span = GenerateTextSpan({.cgs_ = cgs1_});
217 
218     EXPECT_NO_THROW({
219         TextShaper shaper;
220         auto ret = shaper.DoShape(span, {}, {}, FontProviders::Create());
221         ASSERT_EQ(ret, 0);
222     });
223 }
224 
225 /**
226  * @tc.name: GenerateTextBlob1
227  * @tc.desc: Verify the GenerateTextBlob
228  * @tc.type:FUNC
229  */
230 HWTEST_F(TextShaperTest, GenerateTextBlob1, TestSize.Level1)
231 {
232     double spanWidth = 0.0;
233     std::vector<double> glyphWidths;
234     TextShaper shaper;
235     ASSERT_EXCEPTION(ExceptionType::API_FAILED, shaper.GenerateTextBlob({},
236         CharGroups::CreateEmpty(), spanWidth, glyphWidths));
237 }
238 
239 /**
240  * @tc.name: GenerateTextBlob2
241  * @tc.desc: Verify the GenerateTextBlob
242  * @tc.type:FUNC
243  */
244 HWTEST_F(TextShaperTest, GenerateTextBlob2, TestSize.Level1)
245 {
246     EXPECT_NO_THROW({
247         double spanWidth = 0.0;
248         std::vector<double> glyphWidths;
249         TextShaper shaper;
250         shaper.GenerateTextBlob({}, cgs1_, spanWidth, glyphWidths);
251         ASSERT_EQ(spanWidth, 2);
252         // 2.0 is glyph width
253         ASSERT_EQ(glyphWidths, (std::vector<double>{2.0}));
254         // {0.1, -0.1, 1.2, -0.2} is the position of code point in text blob
255         ASSERT_EQ(g_tsMockvars.catchedBufferPos, (std::vector<float>{0.1, -0.1, 1.2, -0.2}));
256         // {1, 2} is the glyph in text blob
257         ASSERT_EQ(g_tsMockvars.catchedBufferGlyphs, (std::vector<uint16_t>{1, 2}));
258     });
259 }
260 
261 /**
262  * @tc.name: GenerateTextBlob3
263  * @tc.desc: Verify the GenerateTextBlob
264  * @tc.type:FUNC
265  */
266 HWTEST_F(TextShaperTest, GenerateTextBlob3, TestSize.Level1)
267 {
268     EXPECT_NO_THROW({
269         double spanWidth = 0.0;
270         std::vector<double> glyphWidths;
271         TextShaper shaper;
272         shaper.GenerateTextBlob({}, cgs2_, spanWidth, glyphWidths);
273         ASSERT_EQ(spanWidth, 2);
274         ASSERT_EQ(glyphWidths, (std::vector<double>{1.0, 1.0}));
275         ASSERT_EQ(g_tsMockvars.catchedBufferPos, (std::vector<float>{0.1, -0.1, 1.2, -0.2}));
276         ASSERT_EQ(g_tsMockvars.catchedBufferGlyphs, (std::vector<uint16_t>{1, 2}));
277     });
278 }
279 
280 /**
281  * @tc.name: Shape1
282  * @tc.desc: Verify the Shape
283  * @tc.type:FUNC
284  */
285 HWTEST_F(TextShaperTest, Shape1, TestSize.Level1)
286 {
287     std::shared_ptr<TextSpan> tsNullptr = nullptr;
288     std::shared_ptr<AnySpan> asNullptr = nullptr;
289     TextShaper shaper;
290     ASSERT_EXCEPTION(ExceptionType::INVALID_ARGUMENT, shaper.Shape(tsNullptr, {}, FontProviders::Create()));
291     ASSERT_EXCEPTION(ExceptionType::INVALID_ARGUMENT, shaper.Shape(asNullptr, {}, FontProviders::Create()));
292 }
293 
294 /**
295  * @tc.name: Shape2
296  * @tc.desc: Verify the Shape
297  * @tc.type:FUNC
298  */
299 HWTEST_F(TextShaperTest, Shape2, TestSize.Level1)
300 {
301     InitTsMockVars({.retvalGenerateFontCollection = nullptr});
302 
303     EXPECT_NO_THROW({
304         std::shared_ptr<MockAnySpan> mas = std::make_shared<MockAnySpan>();
305         TextShaper shaper;
306         auto ret = shaper.Shape(mas, {}, FontProviders::Create());
307         ASSERT_EQ(ret, 0);
308     });
309 }
310 
311 /**
312  * @tc.name: Shape3
313  * @tc.desc: Verify the Shape
314  * @tc.type:FUNC
315  */
316 HWTEST_F(TextShaperTest, Shape3, TestSize.Level1)
317 {
318     InitTsMockVars({.retvalGenerateFontCollection = nullptr});
319 
320     EXPECT_NO_THROW({
321         TextShaper shaper;
322         auto ret = shaper.Shape(GenerateTextSpan({}), {}, FontProviders::Create());
323         ASSERT_EQ(ret, 1);
324     });
325 }
326 
327 /**
328  * @tc.name: Shape4
329  * @tc.desc: Verify the Shape
330  * @tc.type:FUNC
331  */
332 HWTEST_F(TextShaperTest, Shape4, TestSize.Level1)
333 {
334     InitTsMockVars({});
335     TextShaper shaper;
336     ASSERT_EXCEPTION(ExceptionType::INVALID_CHAR_GROUPS,
337         shaper.Shape(GenerateTextSpan({.cgs_ = {}}), {}, FontProviders::Create()));
338 
339     InitTsMockVars({});
340     EXPECT_CALL(*g_tsMockvars.retvalMeasurerCreate, Measure).Times(1).WillOnce(testing::Return(0));
341     cgs1_.Get(0).typeface = nullptr;
342 
343     ASSERT_EXCEPTION(ExceptionType::INVALID_ARGUMENT,
344         shaper.Shape(GenerateTextSpan({.cgs_ = cgs1_}), {}, FontProviders::Create()));
345 }
346 
347 /**
348  * @tc.name: Shape5
349  * @tc.desc: Verify the Shape
350  * @tc.type:FUNC
351  */
352 HWTEST_F(TextShaperTest, Shape5, TestSize.Level1)
353 {
354     InitTsMockVars({});
355     EXPECT_CALL(*g_tsMockvars.retvalMeasurerCreate, Measure).Times(1).WillOnce(testing::Return(0));
356     cgs1_.Get(0).typeface = std::make_unique<Typeface>(nullptr);
357 
358     EXPECT_NO_THROW({
359         TextShaper shaper;
360         auto ret = shaper.Shape(GenerateTextSpan({.cgs_ = cgs1_}), {}, FontProviders::Create());
361         ASSERT_EQ(ret, 1);
362     });
363 }
364 
365 /**
366  * @tc.name: Shape6
367  * @tc.desc: Verify the Shape
368  * @tc.type:FUNC
369  */
370 HWTEST_F(TextShaperTest, Shape6, TestSize.Level1)
371 {
372     InitTsMockVars({});
373     EXPECT_CALL(*g_tsMockvars.retvalMeasurerCreate, Measure).Times(1).WillOnce(testing::Return(0));
374     g_tsMockvars.retvalTextBlobBuilderMake = std::make_shared<TexgineTextBlob>();
375 
376     EXPECT_NO_THROW({
377         TextShaper shaper;
378         auto ret = shaper.Shape(GenerateTextSpan({.cgs_ = cgs1_}), {}, FontProviders::Create());
379         ASSERT_EQ(ret, 0);
380     });
381 }
382 } // namespace TextEngine
383 } // namespace Rosen
384 } // namespace OHOS
385