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 #include <cstddef>
16
17 #include "gtest/gtest.h"
18 #include "font_collection.h"
19 #include "modules/skparagraph/src/ParagraphImpl.h"
20 #include "ohos/init_data.h"
21 #include "paragraph_builder.h"
22 #include "paragraph_impl.h"
23 #include "paragraph_style.h"
24 #include "text_style.h"
25
26 using namespace testing;
27 using namespace testing::ext;
28 using namespace OHOS::Rosen;
29 using namespace OHOS::Rosen::Drawing;
30 using namespace OHOS::Rosen::SPText;
31
32 namespace txt {
33 namespace skt = skia::textlayout;
34 class ParagraphTest : public testing::Test {
35 public:
36 void SetUp() override;
37 void TearDown() override;
38
39 static bool AnimationFunc(const std::shared_ptr<TextEngine::SymbolAnimationConfig>& symbolAnimationConfig);
40 static skia::textlayout::ParagraphImpl* GetParagraphSkiaImpl(const std::shared_ptr<Paragraph>& paragraph);
41 static ParagraphImpl* GetParagraphImpl(const std::shared_ptr<Paragraph>& paragraph);
42 void PrepareMiddleEllipsis(size_t& maxLines, const std::u16string& str, const std::u16string& text);
43
44 protected:
45 std::shared_ptr<Paragraph> paragraph_;
46 std::shared_ptr<Paragraph> paragraphMiddleEllipsis_;
47 int layoutWidth_ = 50;
48 std::u16string text_ = u"text";
49 };
50
SetUp()51 void ParagraphTest::SetUp()
52 {
53 SetHwIcuDirectory();
54 ParagraphStyle paragraphStyle;
55 std::shared_ptr<FontCollection> fontCollection = std::make_shared<FontCollection>();
56 ASSERT_NE(fontCollection, nullptr);
57 fontCollection->SetupDefaultFontManager();
58 std::shared_ptr<ParagraphBuilder> paragraphBuilder = ParagraphBuilder::Create(paragraphStyle, fontCollection);
59 ASSERT_NE(paragraphBuilder, nullptr);
60 paragraphBuilder->AddText(text_);
61 // 50 just for test
62 PlaceholderRun placeholderRun(50, 50, PlaceholderAlignment::BASELINE, SPText::TextBaseline::ALPHABETIC, 0.0);
63 paragraphBuilder->AddPlaceholder(placeholderRun);
64 paragraph_ = paragraphBuilder->Build();
65 ASSERT_NE(paragraph_, nullptr);
66 // 50 just for test
67 paragraph_->Layout(layoutWidth_);
68 paragraph_->MeasureText();
69 }
70
TearDown()71 void ParagraphTest::TearDown()
72 {
73 paragraph_.reset();
74 }
75
GetParagraphImpl(const std::shared_ptr<Paragraph> & paragraph)76 ParagraphImpl* ParagraphTest::GetParagraphImpl(const std::shared_ptr<Paragraph>& paragraph)
77 {
78 return static_cast<ParagraphImpl*>(paragraph.get());
79 }
80
GetParagraphSkiaImpl(const std::shared_ptr<Paragraph> & paragraph)81 skia::textlayout::ParagraphImpl* ParagraphTest::GetParagraphSkiaImpl(const std::shared_ptr<Paragraph>& paragraph)
82 {
83 return static_cast<skia::textlayout::ParagraphImpl*>(GetParagraphImpl(paragraph)->paragraph_.get());
84 }
85
AnimationFunc(const std::shared_ptr<TextEngine::SymbolAnimationConfig> & symbolAnimationConfig)86 bool ParagraphTest::AnimationFunc(const std::shared_ptr<TextEngine::SymbolAnimationConfig>& symbolAnimationConfig)
87 {
88 return true;
89 }
90
91 /*
92 * @tc.name: ParagraphTest001
93 * @tc.desc: test for GetMaxWidth
94 * @tc.type: FUNC
95 */
96 HWTEST_F(ParagraphTest, ParagraphTest001, TestSize.Level0)
97 {
98 EXPECT_EQ(paragraph_->GetMaxWidth(), layoutWidth_);
99 EXPECT_EQ(paragraph_->GetHeight(), 19);
100 EXPECT_EQ(static_cast<int>(paragraph_->GetLongestLine()), 44);
101 EXPECT_EQ(static_cast<int>(paragraph_->GetMinIntrinsicWidth()), 78);
102 EXPECT_EQ(static_cast<int>(paragraph_->GetMaxIntrinsicWidth()), 78);
103 EXPECT_EQ(static_cast<int>(paragraph_->GetAlphabeticBaseline()), 14);
104 EXPECT_EQ(static_cast<int>(paragraph_->GetIdeographicBaseline()), 18);
105 EXPECT_EQ(paragraph_->GetGlyphsBoundsTop(), -11);
106 EXPECT_EQ(paragraph_->GetGlyphsBoundsBottom(), 1);
107 EXPECT_EQ(paragraph_->GetGlyphsBoundsLeft(), 0);
108 EXPECT_EQ(static_cast<int>(paragraph_->GetGlyphsBoundsRight()), 36);
109 EXPECT_TRUE(paragraph_->DidExceedMaxLines());
110 EXPECT_EQ(paragraph_->GetLineCount(), 1);
111 EXPECT_EQ(paragraph_->GetUnresolvedGlyphsCount(), 0);
112 EXPECT_EQ(paragraph_->GetRectsForRange(0, text_.size(), RectHeightStyle::MAX, RectWidthStyle::TIGHT).size(), 1);
113 EXPECT_EQ(paragraph_->GetRectsForPlaceholders().size(), 0);
114 EXPECT_EQ(paragraph_->GetGlyphPositionAtCoordinate(0.0, 0.0).affinity, OHOS::Rosen::SPText::Affinity::DOWNSTREAM);
115 EXPECT_EQ(paragraph_->GetGlyphPositionAtCoordinate(0.0, 0.0).position, 0.0);
116 EXPECT_EQ(paragraph_->GetWordBoundary(0).start, 0);
117 EXPECT_EQ(paragraph_->GetActualTextRange(0, false).start, 0);
118 EXPECT_EQ(paragraph_->GetActualTextRange(-1, false).start, 0);
119 EXPECT_EQ(paragraph_->GetActualTextRange(paragraph_->GetLineCount(), false).start, 0);
120 EXPECT_EQ(paragraph_->GetActualTextRange(paragraph_->GetLineCount(), false).end, 0);
121 EXPECT_EQ(paragraph_->GetLineMetrics().size(), 1);
122 EXPECT_EQ(static_cast<int>(paragraph_->GetLongestLineWithIndent()), 44);
123 }
124
125 /*
126 * @tc.name: ParagraphTest002
127 * @tc.desc: test for SetIndents
128 * @tc.type: FUNC
129 */
130 HWTEST_F(ParagraphTest, ParagraphTest002, TestSize.Level0)
131 {
132 // 0.5 just for test
133 std::vector<float> indents = { 0.5, 1 };
134 paragraph_->SetIndents(indents);
135 EXPECT_EQ(paragraph_->DetectIndents(0), 0.5);
136 EXPECT_EQ(paragraph_->DetectIndents(indents.size()), 1);
137 }
138
139 /*
140 * @tc.name: ParagraphTest003
141 * @tc.desc: test for MarkDirty
142 * @tc.type: FUNC
143 */
144 HWTEST_F(ParagraphTest, ParagraphTest003, TestSize.Level0)
145 {
146 paragraph_->MarkDirty();
147 auto paragraphImpl = GetParagraphSkiaImpl(paragraph_);
148 EXPECT_EQ(paragraphImpl->fState, skia::textlayout::kIndexed);
149 }
150
151 /*
152 * @tc.name: ParagraphTest004
153 * @tc.desc: test for UpdateFontSize
154 * @tc.type: FUNC
155 */
156 HWTEST_F(ParagraphTest, ParagraphTest004, TestSize.Level0)
157 {
158 // 2 24.0 just for test
159 paragraph_->UpdateFontSize(0, text_.size(), 24.0);
160 auto paragraphImpl = GetParagraphSkiaImpl(paragraph_);
161 ASSERT_GT(paragraphImpl->fTextStyles.size(), 0);
162 EXPECT_EQ(paragraphImpl->fTextStyles.at(0).fStyle.getFontSize(), 24);
163 }
164
165 /*
166 * @tc.name: ParagraphTest005
167 * @tc.desc: test for Paint
168 * @tc.type: FUNC
169 */
170 HWTEST_F(ParagraphTest, ParagraphTest005, TestSize.Level0)
171 {
172 SkCanvas skCanvas;
173 // redundancy because it has been checked in setup
174 ASSERT_NE(paragraph_, nullptr);
175 paragraph_->Paint(&skCanvas, 0.0, 0.0);
176 Canvas canvas;
177 paragraph_->Paint(&canvas, 0.0, 0.0);
178 Path path;
179 paragraph_->Paint(&canvas, &path, 0.0, 0.0);
180 }
181
182 /*
183 * @tc.name: ParagraphTest006
184 * @tc.desc: test for GetLineMetricsAt
185 * @tc.type: FUNC
186 */
187 HWTEST_F(ParagraphTest, ParagraphTest006, TestSize.Level0)
188 {
189 skia::textlayout::LineMetrics lineMetrics;
190 auto metrics = paragraph_->MeasureText();
191 ASSERT_TRUE(paragraph_->GetLineMetricsAt(0, &lineMetrics));
192 EXPECT_EQ(lineMetrics.fAscent, -metrics.fAscent);
193 EXPECT_EQ(lineMetrics.fDescent, metrics.fDescent);
194 }
195
196 /*
197 * @tc.name: ParagraphTest007
198 * @tc.desc: test for SetAnimation
199 * @tc.type: FUNC
200 */
201 HWTEST_F(ParagraphTest, ParagraphTest007, TestSize.Level0)
202 {
203 std::function<bool(const std::shared_ptr<TextEngine::SymbolAnimationConfig>&)> animationFunc =
204 ParagraphTest::AnimationFunc;
205 paragraph_->SetAnimation(animationFunc);
206 auto paragraphImpl = GetParagraphImpl(paragraph_);
207 EXPECT_TRUE(paragraphImpl->animationFunc_(nullptr));
208 }
209
210 /*
211 * @tc.name: ParagraphTest008
212 * @tc.desc: test for SetParagraghId
213 * @tc.type: FUNC
214 */
215 HWTEST_F(ParagraphTest, ParagraphTest008, TestSize.Level0)
216 {
217 paragraph_->SetParagraghId(1);
218 auto paragraphImpl = GetParagraphImpl(paragraph_);
219 EXPECT_EQ(paragraphImpl->id_, 1);
220 }
221
222 /*
223 * @tc.name: ParagraphTest009
224 * @tc.desc: test for GetFontMetricsResult
225 * @tc.type: FUNC
226 */
227 HWTEST_F(ParagraphTest, ParagraphTest009, TestSize.Level0)
228 {
229 SPText::TextStyle textStyle;
230 auto fontMetrics = paragraph_->GetFontMetricsResult(textStyle);
231 EXPECT_EQ(static_cast<int>(fontMetrics.fTop), -14);
232 }
233
234 /*
235 * @tc.name: ParagraphTest010
236 * @tc.desc: test for GetLineFontMetrics
237 * @tc.type: FUNC
238 */
239 HWTEST_F(ParagraphTest, ParagraphTest010, TestSize.Level0)
240 {
241 size_t charNumber = 1;
242 std::vector<Drawing::FontMetrics> fontMetrics;
243 ASSERT_TRUE(paragraph_->GetLineFontMetrics(1, charNumber, fontMetrics));
244 ASSERT_GT(fontMetrics.size(), 0);
245 auto metrics = paragraph_->MeasureText();
246 EXPECT_EQ(metrics.fAscent, fontMetrics.at(0).fAscent);
247 EXPECT_EQ(metrics.fDescent, fontMetrics.at(0).fDescent);
248 }
249
250 /*
251 * @tc.name: ParagraphTest011
252 * @tc.desc: test for CloneSelf
253 * @tc.type: FUNC
254 */
255 HWTEST_F(ParagraphTest, ParagraphTest011, TestSize.Level0)
256 {
257 auto paragraphClone = paragraph_->CloneSelf();
258 EXPECT_EQ(paragraphClone->GetHeight(), paragraph_->GetHeight());
259 EXPECT_EQ(paragraphClone->GetMaxWidth(), paragraph_->GetMaxWidth());
260 EXPECT_EQ(paragraphClone->GetMinIntrinsicWidth(), paragraph_->GetMinIntrinsicWidth());
261 EXPECT_EQ(paragraphClone->GetGlyphsBoundsBottom(), paragraph_->GetGlyphsBoundsBottom());
262 EXPECT_EQ(paragraphClone->GetGlyphsBoundsLeft(), paragraph_->GetGlyphsBoundsLeft());
263 EXPECT_EQ(paragraphClone->GetLongestLine(), paragraph_->GetLongestLine());
264 EXPECT_EQ(paragraphClone->GetLongestLineWithIndent(), paragraph_->GetLongestLineWithIndent());
265 }
266
267 /*
268 * @tc.name: ParagraphTest012
269 * @tc.desc: test for SkStyleToTextStyle
270 * @tc.type: FUNC
271 */
272 HWTEST_F(ParagraphTest, ParagraphTest012, TestSize.Level0)
273 {
274 skt::TextStyle skStyle;
275 skStyle.setBackgroundPaintID(-1);
276 skStyle.addShadow(skia::textlayout::TextShadow());
277 skStyle.setColor(0xFF0000FF); // used for testing. Set the color to blue.
278 skStyle.setDecorationColor(0xFF000000); // used for testing. Set the color to black.
279 skStyle.setDecorationThicknessMultiplier(2.0f);
280 skStyle.setFontFamilies({ SkString("sans-serif") });
281 skStyle.setFontSize(12.0f);
282 skStyle.setHeight(1.5f);
283 SPText::TextStyle txt = paragraph_->SkStyleToTextStyle(skStyle);
284 EXPECT_EQ(txt.color, skStyle.getColor());
285 EXPECT_EQ(txt.decorationColor, skStyle.fDecoration.fColor);
286 EXPECT_EQ(txt.decorationThicknessMultiplier, skStyle.fDecoration.fThicknessMultiplier);
287 EXPECT_EQ(txt.fontSize, skStyle.getFontSize());
288 EXPECT_EQ(txt.height, skStyle.getHeight());
289 ASSERT_GT(txt.fontFamilies.size(), 0);
290 EXPECT_EQ(txt.fontFamilies.back(), std::string(skStyle.fFontFamilies.back().c_str()));
291 }
292
293 /*
294 * @tc.name: ParagraphTest013
295 * @tc.desc: test for UpdateColor
296 * @tc.type: FUNC
297 */
298 HWTEST_F(ParagraphTest, ParagraphTest013, TestSize.Level0)
299 {
300 RSColor color(255, 0, 0, 255);
301 std::u16string text = u"text";
302 paragraph_->UpdateColor(0, text.length(), color);
303 auto paragraphImpl = GetParagraphImpl(paragraph_);
304 for (auto p: paragraphImpl->paints_) {
305 EXPECT_EQ(p.color, color);
306 }
307 }
308
309 /*
310 * @tc.name: ParagraphTest014
311 * @tc.desc: test for SkStyleToTextStyle
312 * @tc.type: FUNC
313 */
314 HWTEST_F(ParagraphTest, ParagraphTest014, TestSize.Level0)
315 {
316 auto metrics = paragraph_->GetLineMetrics();
317 for (auto skLineMetrics : metrics) {
318 for (const auto& [index, styleMetrics] : skLineMetrics.fLineMetrics) {
319 OHOS::Rosen::SPText::TextStyle spTextStyle = paragraph_->SkStyleToTextStyle(*styleMetrics.text_style);
320 EXPECT_EQ(spTextStyle.color, styleMetrics.text_style->fColor);
321 EXPECT_EQ(spTextStyle.decorationColor, styleMetrics.text_style->fDecoration.fColor);
322 }
323 }
324 }
325
326 /*
327 * @tc.name: ParagraphHyphenTest001
328 * @tc.desc: test for text break work with hyphen strategy in en-gb env.
329 * @tc.type: FUNC
330 */
331 HWTEST_F(ParagraphTest, ParagraphHyphenTest001, TestSize.Level0)
332 {
333 OHOS::Rosen::SPText::TextStyle style;
334 style.fontSize = 50;
335 ParagraphStyle paragraphStyle;
336 paragraphStyle.maxLines = 10;
337 paragraphStyle.locale = "en-gb";
338 paragraphStyle.wordBreakType = OHOS::Rosen::SPText::WordBreakType::BREAK_HYPHEN;
339 std::shared_ptr<FontCollection> fontCollection = std::make_shared<FontCollection>();
340 ASSERT_NE(fontCollection, nullptr);
341 fontCollection->SetupDefaultFontManager();
342 std::shared_ptr<ParagraphBuilder> paragraphBuilder = ParagraphBuilder::Create(paragraphStyle, fontCollection);
343 ASSERT_NE(paragraphBuilder, nullptr);
344 std::u16string text = u"British English is the official language of the United Kingdom. It has some differences in "
345 u"spelling, pronunciation, and vocabulary compared to American English.";
346 paragraphBuilder->PushStyle(style);
347 paragraphBuilder->AddText(text);
348 std::shared_ptr<Paragraph> paragraph = paragraphBuilder->Build();
349 ASSERT_NE(paragraph, nullptr);
350 paragraph->Layout(687);
351 std::vector<std::unique_ptr<SPText::TextLineBase>> textLines = paragraph->GetTextLines();
352 ASSERT_EQ(textLines.size(), 6);
353 //expect lines 2,3,4 to have hyphenation breakpoints,
354 //and the last charater of each line to have a hyphen glyphid of 800
355 size_t breakArr[3] = {2, 3, 4};
356 for (std::size_t i = 0; i < 3; i++) {
357 ASSERT_NE(textLines.at(breakArr[i]), nullptr);
358 std::vector<std::unique_ptr<SPText::Run>> runs = textLines.at(breakArr[i])->GetGlyphRuns();
359 ASSERT_NE(runs.back(), nullptr);
360 std::vector<uint16_t> glyphs = runs.back()->GetGlyphs();
361 EXPECT_EQ(glyphs.back(), 800);
362 }
363 }
364
365 /*
366 * @tc.name: ParagraphHyphenTest002
367 * @tc.desc: test for text break work with hyphen strategy in en-gb env, and text word ends with special chars.
368 * @tc.type: FUNC
369 */
370 HWTEST_F(ParagraphTest, ParagraphHyphenTest002, TestSize.Level0)
371 {
372 ParagraphStyle paragraphStyle;
373 paragraphStyle.maxLines = 10;
374 paragraphStyle.fontSize = 72;
375 paragraphStyle.locale = "en-gb";
376 paragraphStyle.breakStrategy = OHOS::Rosen::SPText::BreakStrategy::HIGH_QUALITY;
377 paragraphStyle.wordBreakType = OHOS::Rosen::SPText::WordBreakType::BREAK_HYPHEN;
378 std::shared_ptr<FontCollection> fontCollection = std::make_shared<FontCollection>();
379 ASSERT_NE(fontCollection, nullptr);
380 fontCollection->SetupDefaultFontManager();
381 std::shared_ptr<ParagraphBuilder> paragraphBuilder = ParagraphBuilder::Create(paragraphStyle, fontCollection);
382 ASSERT_NE(paragraphBuilder, nullptr);
383 std::u16string text = u"Special character =========== Special character a---------- Special character ab,,,,,,,,,,";
384 paragraphBuilder->AddText(text);
385 std::shared_ptr<Paragraph> paragraph = paragraphBuilder->Build();
386 ASSERT_NE(paragraph, nullptr);
387 paragraph->Layout(560);
388 std::vector<std::unique_ptr<SPText::TextLineBase>> textLines = paragraph->GetTextLines();
389 EXPECT_EQ(textLines.size(), 7);
390 //expect lines 0,2,4 to have hyphenation breakpoints,
391 //and the last charater of each line to have a hyphen glyphid of 800
392 size_t breakArr[3] = {0, 2, 4};
393 for (size_t i = 0; i < 3; i++) {
394 ASSERT_NE(textLines.at(breakArr[i]), nullptr);
395 std::vector<std::unique_ptr<SPText::Run>> runs = textLines.at(breakArr[i])->GetGlyphRuns();
396 ASSERT_NE(runs.back(), nullptr);
397 std::vector<uint16_t> glyphs = runs.back()->GetGlyphs();
398 EXPECT_EQ(glyphs.back(), 800);
399 }
400 }
401
402 /*
403 * @tc.name: ParagraphTest016
404 * @tc.desc: test for combin follow liga
405 * @tc.type: FUNC
406 */
407 HWTEST_F(ParagraphTest, ParagraphTest016, TestSize.Level0)
408 {
409 OHOS::Rosen::SPText::TextStyle style;
410 style.fontSize = 30;
411 ParagraphStyle paragraphStyle;
412 paragraphStyle.spTextStyle = style;
413 std::shared_ptr<FontCollection> fontCollection = std::make_shared<FontCollection>();
414 ASSERT_NE(fontCollection, nullptr);
415 fontCollection->SetupDefaultFontManager();
416 std::shared_ptr<ParagraphBuilder> paragraphBuilder = ParagraphBuilder::Create(paragraphStyle, fontCollection);
417 ASSERT_NE(paragraphBuilder, nullptr);
418 std::u16string text = u"brt゙゙";
419 paragraphBuilder->PushStyle(style);
420 paragraphBuilder->AddText(text);
421 std::shared_ptr<Paragraph> paragraph = paragraphBuilder->Build();
422 ASSERT_NE(paragraph, nullptr);
423 paragraph->Layout(100);
424 std::vector<std::unique_ptr<SPText::TextLineBase>> textLines = paragraph->GetTextLines();
425 ASSERT_EQ(textLines.size(), 1);
426 std::unique_ptr<SPText::TextLineBase>& textLine = textLines.at(0);
427 std::vector<std::unique_ptr<SPText::Run>> runs = textLine->GetGlyphRuns();
428 ASSERT_EQ(runs.size(), 2);
429 // 'a' will hit HM Sans
430 std::vector<uint16_t> glyphs1 = runs.at(0)->GetGlyphs();
431 ASSERT_EQ(glyphs1.size(), 1);
432 EXPECT_EQ(glyphs1.at(0), 217);
433 // 'rt゙゙' will hit cjk
434 std::vector<uint16_t> glyphs2 = runs.at(1)->GetGlyphs();
435 ASSERT_EQ(glyphs2.size(), 4);
436 EXPECT_EQ(glyphs2.at(0), 83);
437 EXPECT_EQ(glyphs2.at(1), 85);
438 EXPECT_EQ(glyphs2.at(2), 1546);
439 EXPECT_EQ(glyphs2.at(3), 1546);
440 }
441
PrepareMiddleEllipsis(size_t & maxLines,const std::u16string & str,const std::u16string & text)442 void ParagraphTest::PrepareMiddleEllipsis(size_t& maxLines, const std::u16string& str, const std::u16string& text)
443 {
444 ParagraphStyle paragraphStyle;
445 paragraphStyle.maxLines = maxLines;
446 paragraphStyle.ellipsis = str;
447 paragraphStyle.ellipsisModal = OHOS::Rosen::SPText::EllipsisModal::MIDDLE;
448 std::shared_ptr<FontCollection> fontCollection = std::make_shared<FontCollection>();
449 ASSERT_NE(fontCollection, nullptr);
450 fontCollection->SetupDefaultFontManager();
451 std::shared_ptr<ParagraphBuilder> paragraphBuilder = ParagraphBuilder::Create(paragraphStyle, fontCollection);
452 ASSERT_NE(paragraphBuilder, nullptr);
453 OHOS::Rosen::SPText::TextStyle style;
454 style.fontSize = 30; // 30 default fontsize
455 paragraphBuilder->PushStyle(style);
456 paragraphBuilder->AddText(text);
457 paragraphMiddleEllipsis_ = paragraphBuilder->Build();
458 ASSERT_NE(paragraphMiddleEllipsis_, nullptr);
459 }
460
461 /*
462 * @tc.name: ParagraphTestMiddleEllipsis001
463 * @tc.desc: test for Middle Ellipsis 001, English word
464 * @tc.type: FUNC
465 */
466 HWTEST_F(ParagraphTest, ParagraphTestMiddleEllipsis001, TestSize.Level0)
467 {
468 size_t maxLines = 1;
469 PrepareMiddleEllipsis(maxLines, u"...", u"Hello World");
470 paragraphMiddleEllipsis_->Layout(100);
471 OHOS::Rosen::SPText::Range<size_t> range = paragraphMiddleEllipsis_->GetEllipsisTextRange();
472 EXPECT_EQ(range.start, 2);
473 EXPECT_EQ(range.end, 8);
474 EXPECT_FALSE(paragraphMiddleEllipsis_->CanPaintAllText());
475 paragraphMiddleEllipsis_->Layout(500);
476
477 OHOS::Rosen::SPText::ParagraphImpl* paragraphImpl = GetParagraphImpl(paragraphMiddleEllipsis_);
478 ASSERT_NE(paragraphImpl, nullptr);
479 std::unique_ptr<skt::Paragraph> temp = nullptr;
480 paragraphImpl->paragraph_.swap(temp);
481 EXPECT_FALSE(paragraphImpl->CanPaintAllText());
482 paragraphImpl->paragraph_.swap(temp);
483 EXPECT_TRUE(paragraphMiddleEllipsis_->CanPaintAllText());
484 }
485
486 /*
487 * @tc.name: ParagraphTestMiddleEllipsis002
488 * @tc.desc: test for Middle Ellipsis 002,Burmese combin
489 * @tc.type: FUNC
490 */
491 HWTEST_F(ParagraphTest, ParagraphTestMiddleEllipsis002, TestSize.Level0)
492 {
493 size_t maxLines = 1;
494 PrepareMiddleEllipsis(maxLines, u"...", u"ျမင့္ေသာ ႏွလုံးခုန္ႏႈန္း သတ္မွတ္ခ်က္");
495 paragraphMiddleEllipsis_->Layout(200);
496 OHOS::Rosen::SPText::Range<size_t> range = paragraphMiddleEllipsis_->GetEllipsisTextRange();
497 EXPECT_EQ(range.start, 5);
498 EXPECT_EQ(range.end, 30);
499 }
500
501 /*
502 * @tc.name: ParagraphTestMiddleEllipsis003
503 * @tc.desc: test for Middle Ellipsis 003,emoji
504 * @tc.type: FUNC
505 */
506 HWTEST_F(ParagraphTest, ParagraphTestMiddleEllipsis003, TestSize.Level0)
507 {
508 size_t maxLines = 1;
509 PrepareMiddleEllipsis(maxLines, u"...", u" MM abc 中文 123");
510 paragraphMiddleEllipsis_->Layout(200);
511 OHOS::Rosen::SPText::Range<size_t> range = paragraphMiddleEllipsis_->GetEllipsisTextRange();
512 EXPECT_EQ(range.start, 5);
513 EXPECT_EQ(range.end, 13);
514 }
515
516 /*
517 * @tc.name: ParagraphTestMiddleEllipsis004
518 * @tc.desc: test for Middle Ellipsis 004,chinese & number & English
519 * @tc.type: FUNC
520 */
521 HWTEST_F(ParagraphTest, ParagraphTestMiddleEllipsis004, TestSize.Level0)
522 {
523 size_t maxLines = 1;
524 PrepareMiddleEllipsis(maxLines, u"...", u"你好 123 Hello ");
525 paragraphMiddleEllipsis_->Layout(200);
526 OHOS::Rosen::SPText::Range<size_t> range = paragraphMiddleEllipsis_->GetEllipsisTextRange();
527 EXPECT_EQ(range.start, 5);
528 EXPECT_EQ(range.end, 15);
529 }
530
531 /*
532 * @tc.name: ParagraphTestMiddleEllipsis005
533 * @tc.desc: test for Middle Ellipsis 005,Tibetan
534 * @tc.type: FUNC
535 */
536 HWTEST_F(ParagraphTest, ParagraphTestMiddleEllipsis005, TestSize.Level0)
537 {
538 size_t maxLines = 1;
539 PrepareMiddleEllipsis(maxLines, u"...", u"བོད་སྐད་ནི་སྒྲ་གཉིས་ཀྱི་བྱུས་དང་སྤྱི་ཚད་ཁུར་སྒྲ་སེམས་བཞིན་ཡོད།");
540 paragraphMiddleEllipsis_->Layout(200);
541 OHOS::Rosen::SPText::Range<size_t> range = paragraphMiddleEllipsis_->GetEllipsisTextRange();
542 EXPECT_EQ(range.start, 11);
543 EXPECT_EQ(range.end, 53);
544 }
545
546 /*
547 * @tc.name: ParagraphTestMiddleEllipsis006
548 * @tc.desc: test for Middle Ellipsis 006,Empty ellipsis,Empty String
549 * @tc.type: FUNC
550 */
551 HWTEST_F(ParagraphTest, ParagraphTestMiddleEllipsis006, TestSize.Level0)
552 {
553 size_t maxLines = 1;
554 PrepareMiddleEllipsis(maxLines, u"", u"");
555 paragraphMiddleEllipsis_->Layout(200);
556 OHOS::Rosen::SPText::Range<size_t> range = paragraphMiddleEllipsis_->GetEllipsisTextRange();
557 EXPECT_EQ(range.start, std::numeric_limits<size_t>::max());
558 EXPECT_EQ(range.end, std::numeric_limits<size_t>::max());
559 }
560
561 /*
562 * @tc.name: ParagraphTestMiddleEllipsis007
563 * @tc.desc: test for Middle Ellipsis 007,maxLines != 1
564 * @tc.type: FUNC
565 */
566 HWTEST_F(ParagraphTest, ParagraphTestMiddleEllipsis007, TestSize.Level0)
567 {
568 size_t maxLines = 2;
569 PrepareMiddleEllipsis(maxLines, u"...", u"Hello World");
570 paragraphMiddleEllipsis_->Layout(100);
571 OHOS::Rosen::SPText::Range<size_t> range = paragraphMiddleEllipsis_->GetEllipsisTextRange();
572 EXPECT_EQ(range.start, std::numeric_limits<size_t>::max());
573 EXPECT_EQ(range.end, std::numeric_limits<size_t>::max());
574 EXPECT_TRUE(paragraphMiddleEllipsis_->CanPaintAllText());
575 ParagraphStyle paragraphStyle;
576 paragraphStyle.wordBreakType = OHOS::Rosen::SPText::WordBreakType::BREAK_WORD;
577 paragraphStyle.relayoutChangeBitmap.set(static_cast<size_t>(RelayoutParagraphStyleAttribute::WORD_BREAKTYPE));
578 std::vector<OHOS::Rosen::SPText::TextStyle> relayoutTextStyles;
579 OHOS::Rosen::SPText::TextStyle textStyle;
580 relayoutTextStyles.push_back(textStyle);
581 paragraphMiddleEllipsis_->Relayout(50, paragraphStyle, relayoutTextStyles);
582 EXPECT_FALSE(paragraphMiddleEllipsis_->CanPaintAllText());
583 }
584
585 /*
586 * @tc.name: ParagraphTestMiddleEllipsis008
587 * @tc.desc: test for Middle Ellipsis 008, uygurqa
588 * @tc.type: FUNC
589 */
590 HWTEST_F(ParagraphTest, ParagraphTestMiddleEllipsis008, TestSize.Level0)
591 {
592 size_t maxLines = 1;
593 PrepareMiddleEllipsis(maxLines, u"...", u"ياخشىمۇ سىز؟ ھەركىمگە قۇتلۇق كۈنىمىز بولسۇن!");
594 paragraphMiddleEllipsis_->Layout(100);
595 OHOS::Rosen::SPText::Range<size_t> range = paragraphMiddleEllipsis_->GetEllipsisTextRange();
596 EXPECT_EQ(range.start, 3);
597 EXPECT_EQ(range.end, 41);
598 }
599
600 /*
601 * @tc.name: ParagraphTestMiddleEllipsis009
602 * @tc.desc: test for Middle Ellipsis 009, long tail space
603 * @tc.type: FUNC
604 */
605 HWTEST_F(ParagraphTest, ParagraphTestMiddleEllipsis009, TestSize.Level0)
606 {
607 size_t maxLines = 1;
608 PrepareMiddleEllipsis(maxLines, u"...", u"Hello Wolrd ");
609 paragraphMiddleEllipsis_->Layout(100);
610 OHOS::Rosen::SPText::Range<size_t> range = paragraphMiddleEllipsis_->GetEllipsisTextRange();
611 EXPECT_EQ(range.start, 2);
612 EXPECT_EQ(range.end, 23);
613 }
614
615 /*
616 * @tc.name: ParagraphTestMiddleEllipsis010
617 * @tc.desc: test for Middle Ellipsis 010, empty text
618 * @tc.type: FUNC
619 */
620 HWTEST_F(ParagraphTest, ParagraphTestMiddleEllipsis010, TestSize.Level0)
621 {
622 size_t maxLines = 1;
623 PrepareMiddleEllipsis(maxLines, u"...", u"");
624 paragraphMiddleEllipsis_->Layout(1);
625 OHOS::Rosen::SPText::Range<size_t> range = paragraphMiddleEllipsis_->GetEllipsisTextRange();
626 EXPECT_EQ(range.start, std::numeric_limits<size_t>::max());
627 EXPECT_EQ(range.end, std::numeric_limits<size_t>::max());
628 }
629
630 /*
631 * @tc.name: ParagraphTestMiddleEllipsis011
632 * @tc.desc: test for Middle Ellipsis 011, empty ellipsis
633 * @tc.type: FUNC
634 */
635 HWTEST_F(ParagraphTest, ParagraphTestMiddleEllipsis011, TestSize.Level0)
636 {
637 size_t maxLines = 1;
638 PrepareMiddleEllipsis(maxLines, u"", u"Hello World");
639 paragraphMiddleEllipsis_->Layout(1);
640 OHOS::Rosen::SPText::Range<size_t> range = paragraphMiddleEllipsis_->GetEllipsisTextRange();
641 EXPECT_EQ(range.start, std::numeric_limits<size_t>::max());
642 EXPECT_EQ(range.end, std::numeric_limits<size_t>::max());
643 }
644
645 /*
646 * @tc.name: ParagraphTestMiddleEllipsis012
647 * @tc.desc: test for Middle Ellipsis 012, add placeholder
648 * @tc.type: FUNC
649 */
650 HWTEST_F(ParagraphTest, ParagraphTestMiddleEllipsis012, TestSize.Level0)
651 {
652 size_t maxLines = 1;
653 ParagraphStyle paragraphStyle;
654 paragraphStyle.maxLines = maxLines;
655 paragraphStyle.ellipsis = u"...";
656 paragraphStyle.ellipsisModal = OHOS::Rosen::SPText::EllipsisModal::MIDDLE;
657 std::shared_ptr<FontCollection> fontCollection = std::make_shared<FontCollection>();
658 ASSERT_NE(fontCollection, nullptr);
659 fontCollection->SetupDefaultFontManager();
660 std::shared_ptr<ParagraphBuilder> paragraphBuilder = ParagraphBuilder::Create(paragraphStyle, fontCollection);
661 ASSERT_NE(paragraphBuilder, nullptr);
662 OHOS::Rosen::SPText::TextStyle style;
663 style.fontSize = 30; // 30 default fontsize
664 PlaceholderRun placeholderRun(50, 50, PlaceholderAlignment::BASELINE, SPText::TextBaseline::ALPHABETIC, 0.0);
665 paragraphBuilder->AddPlaceholder(placeholderRun);
666 paragraphBuilder->PushStyle(style);
667 paragraphBuilder->AddText(u"Hello World");
668 PlaceholderRun placeholderRun2(150, 150, PlaceholderAlignment::BASELINE, SPText::TextBaseline::ALPHABETIC, 0.0);
669 paragraphBuilder->AddPlaceholder(placeholderRun2);
670 paragraphMiddleEllipsis_ = paragraphBuilder->Build();
671 ASSERT_NE(paragraphMiddleEllipsis_, nullptr);
672 paragraphMiddleEllipsis_->Layout(100);
673 OHOS::Rosen::SPText::Range<size_t> range = paragraphMiddleEllipsis_->GetEllipsisTextRange();
674 EXPECT_EQ(range.start, 1);
675 EXPECT_EQ(range.end, 13);
676 }
677
678 /*
679 * @tc.name: ParagraphTestMiddleEllipsis013
680 * @tc.desc: test for Middle Ellipsis 013, \n
681 * @tc.type: FUNC
682 */
683 HWTEST_F(ParagraphTest, ParagraphTestMiddleEllipsis013, TestSize.Level0)
684 {
685 size_t maxLines = 1;
686 PrepareMiddleEllipsis(maxLines, u"...", u"A\nB");
687 paragraphMiddleEllipsis_->Layout(1);
688 OHOS::Rosen::SPText::Range<size_t> range = paragraphMiddleEllipsis_->GetEllipsisTextRange();
689 EXPECT_EQ(range.start, 0);
690 EXPECT_EQ(range.end, 2);
691 }
692
693 /*
694 * @tc.name: ParagraphTestMiddleEllipsis014
695 * @tc.desc: test for Middle Ellipsis 014, \n
696 * @tc.type: FUNC
697 */
698 HWTEST_F(ParagraphTest, ParagraphTestMiddleEllipsis014, TestSize.Level0)
699 {
700 size_t maxLines = 1;
701 PrepareMiddleEllipsis(maxLines, u"...", u"\nB");
702 paragraphMiddleEllipsis_->Layout(1);
703 OHOS::Rosen::SPText::Range<size_t> range = paragraphMiddleEllipsis_->GetEllipsisTextRange();
704 EXPECT_EQ(range.start, std::numeric_limits<size_t>::max());
705 EXPECT_EQ(range.end, std::numeric_limits<size_t>::max());
706 }
707
708 /*
709 * @tc.name: ParagraphTestMiddleEllipsis015
710 * @tc.desc: test for Middle Ellipsis 015, get glyph position
711 * @tc.type: FUNC
712 */
713 HWTEST_F(ParagraphTest, ParagraphTestMiddleEllipsis015, TestSize.Level0)
714 {
715 size_t maxLines = 1;
716 PrepareMiddleEllipsis(maxLines, u"...", u"你好世界 Hello World");
717 paragraphMiddleEllipsis_->Layout(280);
718 EXPECT_EQ(paragraphMiddleEllipsis_->GetGlyphPositionAtCoordinate(50, 0.0).position, 2.0);
719 EXPECT_EQ(paragraphMiddleEllipsis_->GetGlyphPositionAtCoordinate(150, 0.0).position, 7.0);
720 EXPECT_EQ(paragraphMiddleEllipsis_->GetGlyphPositionAtCoordinate(270, 0.0).position, 16.0);
721 }
722
ProcessRelayout(std::shared_ptr<Paragraph> paragraph,std::optional<RSBrush> brush)723 OHOS::Rosen::SPText::ParagraphImpl* ProcessRelayout(std::shared_ptr<Paragraph> paragraph, std::optional<RSBrush> brush)
724 {
725 std::vector<OHOS::Rosen::SPText::TextStyle> textStyles;
726 ParagraphStyle paragraphStyle;
727 OHOS::Rosen::SPText::TextStyle changeTextStyle;
728 changeTextStyle.foreground = SPText::PaintRecord(brush, Drawing::Pen());
729 changeTextStyle.relayoutChangeBitmap.set(static_cast<size_t>(RelayoutTextStyleAttribute::FOREGROUND_BRUSH));
730 textStyles.push_back(changeTextStyle);
731 paragraph->Relayout(200, paragraphStyle, textStyles);
732 return ParagraphTest::GetParagraphImpl(paragraph);
733 }
734
735 /*
736 * @tc.name: ParagraphTestRelayoutBrush001
737 * @tc.desc: test for relayout foreground brush with multiple textstyle
738 * @tc.type: FUNC
739 */
740 HWTEST_F(ParagraphTest, ParagraphTestRelayoutBrush001, TestSize.Level0)
741 {
742 ParagraphStyle paragraphStyle;
743 auto fontCollection = std::make_shared<FontCollection>();
744 ASSERT_NE(fontCollection, nullptr);
745 fontCollection->SetupDefaultFontManager();
746 std::unique_ptr<ParagraphBuilder> paragraphBuilder = ParagraphBuilder::Create(paragraphStyle, fontCollection);
747 ASSERT_NE(paragraphBuilder, nullptr);
748
749 OHOS::Rosen::SPText::TextStyle style;
750 style.foreground = SPText::PaintRecord(Drawing::Brush(Drawing::Color::COLOR_DKGRAY), Drawing::Pen());
751 paragraphBuilder->PushStyle(style);
752 paragraphBuilder->AddText(text_);
753 OHOS::Rosen::SPText::TextStyle style1;
754 paragraphBuilder->PushStyle(style1);
755 paragraphBuilder->AddText(text_);
756 std::shared_ptr<Paragraph> paragraph = paragraphBuilder->Build();
757 ASSERT_NE(paragraph, nullptr);
758 paragraph->Layout(200);
759
760 Drawing::Brush brush(Drawing::Color::COLOR_MAGENTA);
761 OHOS::Rosen::SPText::ParagraphImpl* paragraphImpl = ProcessRelayout(paragraph, brush);
762 EXPECT_EQ(paragraphImpl->paints_.size(), 3);
763 EXPECT_EQ(paragraphImpl->paints_[1].brush.value().GetColor(), Drawing::Color::COLOR_MAGENTA);
764 EXPECT_EQ(paragraphImpl->paints_[2].brush.value().GetColor(), Drawing::Color::COLOR_MAGENTA);
765 EXPECT_EQ(paragraphImpl->paints_[2].pen.has_value(), false);
766
767 auto skiaTextStyles = paragraphImpl->paragraph_->exportTextStyles();
768 EXPECT_EQ(skiaTextStyles.size(), 2);
769 EXPECT_EQ(skiaTextStyles[0].fStyle.hasForeground(), true);
770 EXPECT_EQ(skiaTextStyles[1].fStyle.hasForeground(), true);
771 EXPECT_EQ(std::get<int>(skiaTextStyles[1].fStyle.getForegroundPaintOrID()), 2);
772 }
773
774 /*
775 * @tc.name: ParagraphTestRelayoutBrush002
776 * @tc.desc: test for relayout foreground brush with symbol textstyle
777 * @tc.type: FUNC
778 */
779 HWTEST_F(ParagraphTest, ParagraphTestRelayoutBrush002, TestSize.Level0)
780 {
781 ParagraphStyle paragraphStyle;
782 auto fontCollection = std::make_shared<FontCollection>();
783 ASSERT_NE(fontCollection, nullptr);
784 fontCollection->SetupDefaultFontManager();
785 std::unique_ptr<ParagraphBuilder> paragraphBuilder = ParagraphBuilder::Create(paragraphStyle, fontCollection);
786 ASSERT_NE(paragraphBuilder, nullptr);
787
788 OHOS::Rosen::SPText::TextStyle style;
789 style.foreground = SPText::PaintRecord(Drawing::Brush(Drawing::Color::COLOR_DKGRAY), Drawing::Pen());
790 paragraphBuilder->PushStyle(style);
791 paragraphBuilder->AddText(text_);
792 OHOS::Rosen::SPText::TextStyle style1;
793 style1.isSymbolGlyph = true;
794 RSSColor symbolColor = {1.0, 0, 0, 0};
795 style1.symbol.SetRenderColor(symbolColor);
796 paragraphBuilder->PushStyle(style1);
797 paragraphBuilder->AddText(text_);
798 std::shared_ptr<Paragraph> paragraph = paragraphBuilder->Build();
799 ASSERT_NE(paragraph, nullptr);
800 paragraph->Layout(200);
801
802 Drawing::Brush brush(Drawing::Color::COLOR_MAGENTA);
803 OHOS::Rosen::SPText::ParagraphImpl* paragraphImpl = ProcessRelayout(paragraph, brush);
804 EXPECT_EQ(paragraphImpl->paints_.size(), 3);
805 EXPECT_EQ(paragraphImpl->paints_[1].brush.value().GetColor(), Drawing::Color::COLOR_MAGENTA);
806 EXPECT_EQ(paragraphImpl->paints_[2].brush.has_value(), false);
807 }
808
809 /*
810 * @tc.name: ParagraphTestRelayoutBrush003
811 * @tc.desc: test for relayout foreground with nullopt
812 * @tc.type: FUNC
813 */
814 HWTEST_F(ParagraphTest, ParagraphTestRelayoutBrush003, TestSize.Level0)
815 {
816 ParagraphStyle paragraphStyle;
817 auto fontCollection = std::make_shared<FontCollection>();
818 ASSERT_NE(fontCollection, nullptr);
819 fontCollection->SetupDefaultFontManager();
820 std::unique_ptr<ParagraphBuilder> paragraphBuilder = ParagraphBuilder::Create(paragraphStyle, fontCollection);
821 ASSERT_NE(paragraphBuilder, nullptr);
822
823 OHOS::Rosen::SPText::TextStyle style;
824 style.foreground = SPText::PaintRecord(Drawing::Brush(Drawing::Color::COLOR_DKGRAY), Drawing::Pen());
825 paragraphBuilder->PushStyle(style);
826 paragraphBuilder->AddText(text_);
827 OHOS::Rosen::SPText::TextStyle style1;
828 paragraphBuilder->PushStyle(style1);
829 paragraphBuilder->AddText(text_);
830 std::shared_ptr<Paragraph> paragraph = paragraphBuilder->Build();
831 ASSERT_NE(paragraph, nullptr);
832 paragraph->Layout(200);
833
834 OHOS::Rosen::SPText::ParagraphImpl* paragraphImpl = ProcessRelayout(paragraph, std::nullopt);
835
836 EXPECT_EQ(paragraphImpl->paints_.size(), 3);
837 EXPECT_EQ(paragraphImpl->paints_[0].brush.has_value(), false);
838 EXPECT_EQ(paragraphImpl->paints_[1].brush.has_value(), false);
839 }
840
841 /*
842 * @tc.name: ParagraphTestTextEffect001
843 * @tc.desc: test for text effect state
844 * @tc.type: FUNC
845 */
846 HWTEST_F(ParagraphTest, ParagraphTestTextEffect001, TestSize.Level0)
847 {
848 Canvas canvas;
849 paragraph_->Paint(&canvas, 0.0, 0.0);
850 OHOS::Rosen::SPText::ParagraphImpl* paragraphImpl = GetParagraphImpl(paragraph_);
851 ASSERT_NE(paragraphImpl, nullptr);
852 std::unique_ptr<skt::Paragraph> temp = nullptr;
853 paragraphImpl->paragraph_.swap(temp);
854 EXPECT_EQ(paragraphImpl->GetTextBlobRecordInfo().size(), 0);
855 paragraphImpl->SetSkipTextBlobDrawing(true);
856 EXPECT_FALSE(paragraphImpl->HasSkipTextBlobDrawing());
857
858 paragraphImpl->paragraph_.swap(temp);
859 EXPECT_NE(paragraphImpl->GetTextBlobRecordInfo().size(), 0);
860 paragraphImpl->SetSkipTextBlobDrawing(true);
861 EXPECT_TRUE(paragraphImpl->HasSkipTextBlobDrawing());
862 }
863 } // namespace txt