Support Markup Underline attributes
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-toolkit-internal / utc-Dali-TextLabel-internal.cpp
1 /*
2  * Copyright (c) 2022 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 #include <bits/stdint-uintn.h>
19 #include <stdlib.h>
20 #include <iostream>
21
22 #include <dali-toolkit-test-suite-utils.h>
23 #include <dali-toolkit/dali-toolkit.h>
24
25 #include <dali-toolkit/internal/controls/text-controls/text-label-impl.h>
26 #include <dali-toolkit/internal/text/rendering/text-typesetter.h>
27 #include <dali-toolkit/internal/text/rendering/view-model.h>
28 #include <dali-toolkit/internal/text/text-controller-impl.h>
29 #include <dali-toolkit/internal/text/text-controller.h>
30
31 using namespace Dali;
32 using namespace Toolkit;
33 using namespace Text;
34
35 int UtcDaliTextLabelMarkupUnderline(void)
36 {
37   ToolkitTestApplication application;
38   tet_infoline(" UtcDaliTextLabelMarkupUnderline ");
39
40   TextLabel textLabel = TextLabel::New();
41
42   application.GetScene().Add(textLabel);
43
44   textLabel.SetProperty(TextLabel::Property::TEXT, "<u>ABC</u>EF<u>GH</u>");
45   textLabel.SetProperty(TextLabel ::Property::ENABLE_MARKUP, true);
46
47   application.SendNotification();
48   application.Render();
49
50   uint32_t expectedNumberOfUnderlinedGlyphs = 5u;
51
52   Toolkit::Internal::TextLabel& textLabelImpl         = GetImpl(textLabel);
53   const Text::Length            numberOfUnderlineRuns = textLabelImpl.GetTextController()->GetTextModel()->GetNumberOfUnderlineRuns();
54
55   DALI_TEST_EQUALS(numberOfUnderlineRuns, expectedNumberOfUnderlinedGlyphs, TEST_LOCATION);
56
57   Vector<UnderlinedGlyphRun> underlineRuns;
58   underlineRuns.Resize(numberOfUnderlineRuns);
59   textLabelImpl.GetTextController()->GetTextModel()->GetUnderlineRuns(underlineRuns.Begin(), 0u, numberOfUnderlineRuns);
60
61   //ABC are underlined
62   DALI_TEST_EQUALS(underlineRuns[0u].glyphRun.glyphIndex, 0u, TEST_LOCATION);
63   DALI_TEST_EQUALS(underlineRuns[1u].glyphRun.glyphIndex, 1u, TEST_LOCATION);
64   DALI_TEST_EQUALS(underlineRuns[2u].glyphRun.glyphIndex, 2u, TEST_LOCATION);
65
66   //GH are underlined
67   DALI_TEST_EQUALS(underlineRuns[3u].glyphRun.glyphIndex, 5u, TEST_LOCATION);
68   DALI_TEST_EQUALS(underlineRuns[4u].glyphRun.glyphIndex, 6u, TEST_LOCATION);
69
70   END_TEST;
71 }
72
73 int UtcDaliTextLabelMarkupUnderlineAttributes(void)
74 {
75   ToolkitTestApplication application;
76   tet_infoline(" UtcDaliTextLabelMarkupUnderlineAttributes ");
77
78   TextLabel textLabel = TextLabel::New();
79
80   application.GetScene().Add(textLabel);
81
82   std::string testText =
83     "start<u>ABC1</u>then"
84     "<u type='solid'>ABC2</u>then"
85     "<u type='dashed'>ABC3</u>then"
86     "<u type='double'>ABC4</u>then"
87     "<u color='green'>ABC5</u>then"
88     "<u height='5.0f'>ABC6</u>then"
89     "<u type='dashed' dash-gap='3.0f'>ABC7</u>then"
90     "<u type='dashed' dash-width='4.0f'>ABC8</u>then"
91     "<u color='blue' type='dashed' height='4.0f' dash-gap='2.0f' dash-width='3.0f'>ABC9</u>end"
92
93     ;
94
95   textLabel.SetProperty(TextLabel::Property::TEXT, testText);
96   textLabel.SetProperty(TextLabel ::Property::ENABLE_MARKUP, true);
97
98   application.SendNotification();
99   application.Render();
100
101   const uint32_t NUMBER_OF_CASES                  = 9u;
102   uint32_t       expectedNumberOfUnderlinedGlyphs = 36u;
103
104   Toolkit::Internal::TextLabel& textLabelImpl         = GetImpl(textLabel);
105   const Text::Length            numberOfUnderlineRuns = textLabelImpl.GetTextController()->GetTextModel()->GetNumberOfUnderlineRuns();
106
107   DALI_TEST_EQUALS(numberOfUnderlineRuns, expectedNumberOfUnderlinedGlyphs, TEST_LOCATION);
108
109   Vector<UnderlinedGlyphRun> underlineRuns;
110   underlineRuns.Resize(numberOfUnderlineRuns);
111   textLabelImpl.GetTextController()->GetTextModel()->GetUnderlineRuns(underlineRuns.Begin(), 0u, numberOfUnderlineRuns);
112
113   struct DataOfCase
114   {
115     std::string              title;
116     uint32_t                 startIndex;
117     uint32_t                 endIndex;
118     GlyphIndex               startGlyphIndex;
119     GlyphIndex               endGlyphIndex;
120     UnderlineStyleProperties properties;
121   };
122   DataOfCase data[] =
123     {
124       //<u>ABC1</u>
125       {"<u>ABC1</u>",
126        0u,
127        3u,
128        5u,
129        8u,
130        {
131          Text::Underline::SOLID,
132          Color::BLACK,
133          0u,
134          1u,
135          2u,
136          false,
137          false,
138          false,
139          false,
140          false,
141        }},
142
143       //<u type='solid'>ABC2</u>
144       {"<u type='solid'>ABC2</u>",
145        4u,
146        7u,
147        13u,
148        16u,
149        {
150          Text::Underline::SOLID,
151          Color::BLACK,
152          0u,
153          1u,
154          2u,
155          true,
156          false,
157          false,
158          false,
159          false,
160        }},
161
162       //<u type='dashed'>ABC3</u>
163       {"<u type='dashed'>ABC3</u>",
164        8u,
165        11u,
166        21u,
167        24u,
168        {
169          Text::Underline::DASHED,
170          Color::BLACK,
171          0u,
172          1u,
173          2u,
174          true,
175          false,
176          false,
177          false,
178          false,
179        }},
180
181       //<u type='double'>ABC4</u>
182       {"<u type='double'>ABC4</u>",
183        12u,
184        15u,
185        29u,
186        32u,
187        {
188          Text::Underline::DOUBLE,
189          Color::BLACK,
190          0u,
191          1u,
192          2u,
193          true,
194          false,
195          false,
196          false,
197          false,
198        }},
199
200       //<u color='green'>ABC5</u>
201       {"<u color='green'>ABC5</u>",
202        16u,
203        19u,
204        37u,
205        40u,
206        {
207          Text::Underline::SOLID,
208          Color::GREEN,
209          0u,
210          1u,
211          2u,
212          false,
213          true,
214          false,
215          false,
216          false,
217        }},
218
219       //<u height='5.0f'>ABC6</u>
220       {"<u height='5.0f'>ABC6</u>",
221        20u,
222        23u,
223        45u,
224        48u,
225        {
226          Text::Underline::SOLID,
227          Color::BLACK,
228          5u,
229          1u,
230          2u,
231          false,
232          false,
233          true,
234          false,
235          false,
236        }},
237
238       //<u type='dashed' dash-gap='3.0f'>ABC7</u>
239       {"<u type='dashed' dash-gap='3.0f'>ABC7</u>",
240        24u,
241        27u,
242        53u,
243        56u,
244        {
245          Text::Underline::DASHED,
246          Color::BLACK,
247          0u,
248          3u,
249          2u,
250          true,
251          false,
252          false,
253          true,
254          false,
255        }},
256
257       //<u type='dashed' dash-width='4.0f'>ABC8</u>
258       {"<u type='dashed' dash-width='4.0f'>ABC8</u>",
259        28u,
260        31u,
261        61u,
262        64u,
263        {
264          Text::Underline::DASHED,
265          Color::BLACK,
266          0u,
267          1u,
268          4u,
269          true,
270          false,
271          false,
272          false,
273          true,
274        }},
275
276       //<u color='blue' type='dashed' height='4.0f' dash-gap='2.0f' dash-width='3.0f'>
277       {"<u color='blue' type='dashed' height='4.0f' dash-gap='2.0f' dash-width='3.0f'>",
278        32u,
279        35u,
280        69u,
281        72u,
282        {
283          Text::Underline::DASHED,
284          Color::BLUE,
285          4u,
286          2u,
287          3u,
288          true,
289          true,
290          true,
291          true,
292          true,
293        }},
294
295     };
296
297   for(uint32_t i = 0; i < NUMBER_OF_CASES; i++)
298   {
299     tet_infoline(data[i].title.c_str());
300     DALI_TEST_EQUALS(underlineRuns[data[i].startIndex].glyphRun.glyphIndex, data[i].startGlyphIndex, TEST_LOCATION);
301     DALI_TEST_EQUALS(underlineRuns[data[i].endIndex].glyphRun.glyphIndex, data[i].endGlyphIndex, TEST_LOCATION);
302
303     DALI_TEST_CHECK(data[i].properties == underlineRuns[data[i].startIndex].properties);
304     DALI_TEST_CHECK(data[i].properties == underlineRuns[data[i].endIndex].properties);
305   }
306
307   END_TEST;
308 }
309
310 int UtcDaliTextLabelBackgroundTag(void)
311 {
312   ToolkitTestApplication application;
313   tet_infoline("UtcDaliTextLabelBackgroundTag\n");
314
315   TextLabel label = TextLabel::New();
316   DALI_TEST_CHECK(label);
317
318   label.SetProperty(TextLabel ::Property::ENABLE_MARKUP, true);
319   label.SetProperty(TextLabel::Property::TEXT, "H<background color='red'>e</background> Worl<background color='yellow'>d</background>");
320   application.GetScene().Add(label);
321   application.SendNotification();
322   application.Render();
323
324   Toolkit::Internal::TextLabel& labelImpl                    = GetImpl(label);
325   const ColorIndex* const       backgroundColorIndicesBuffer = labelImpl.GetTextController()->GetTextModel()->GetBackgroundColorIndices();
326
327   DALI_TEST_CHECK(backgroundColorIndicesBuffer);
328
329   //default color
330   DALI_TEST_EQUALS(backgroundColorIndicesBuffer[0], 0u, TEST_LOCATION);
331
332   //red color
333   DALI_TEST_EQUALS(backgroundColorIndicesBuffer[1], 1u, TEST_LOCATION);
334
335   //yellow color
336   DALI_TEST_EQUALS(backgroundColorIndicesBuffer[7], 2u, TEST_LOCATION);
337
338   END_TEST;
339 }
340
341 int UtcDaliToolkitTextlabelEllipsisInternalAPIs(void)
342 {
343   ToolkitTestApplication application;
344   tet_infoline(" UtcDaliToolkitTextlabelEllipsisInternalAPIs ");
345   TextLabel textLabel = TextLabel::New();
346
347   Toolkit::Internal::TextLabel& textLabelImpl = GetImpl(textLabel);
348   const ModelInterface* const   textModel     = textLabelImpl.GetTextController()->GetTextModel();
349
350   tet_infoline(" UtcDaliToolkitTextlabelEllipsisInternalAPIs - ELLIPSIS Disabled");
351   textLabel.SetProperty(DevelTextLabel::Property::ELLIPSIS, false);
352   DALI_TEST_EQUALS(textLabel.GetProperty<bool>(DevelTextLabel::Property::ELLIPSIS), false, TEST_LOCATION);
353   DALI_TEST_CHECK(!(textModel->IsTextElideEnabled()));
354
355   tet_infoline(" UtcDaliToolkitTextlabelEllipsisInternalAPIs - ELLIPSIS Enabled");
356   textLabel.SetProperty(DevelTextLabel::Property::ELLIPSIS, true);
357   DALI_TEST_EQUALS(textLabel.GetProperty<bool>(DevelTextLabel::Property::ELLIPSIS), true, TEST_LOCATION);
358   DALI_TEST_CHECK(textModel->IsTextElideEnabled());
359
360   tet_infoline(" UtcDaliToolkitTextlabelEllipsisInternalAPIs - GetStartIndexOfElidedGlyphs Default");
361   DALI_TEST_EQUALS(textModel->GetStartIndexOfElidedGlyphs(), 0u, TEST_LOCATION);
362
363   tet_infoline(" UtcDaliToolkitTextlabelEllipsisInternalAPIs - GetEndIndexOfElidedGlyphs Default");
364   DALI_TEST_EQUALS(textModel->GetEndIndexOfElidedGlyphs(), 0u, TEST_LOCATION);
365
366   tet_infoline(" UtcDaliToolkitTextlabelEllipsisInternalAPIs - GetFirstMiddleIndexOfElidedGlyphs Default");
367   DALI_TEST_EQUALS(textModel->GetFirstMiddleIndexOfElidedGlyphs(), 0u, TEST_LOCATION);
368
369   tet_infoline(" UtcDaliToolkitTextlabelEllipsisInternalAPIs - GetSecondMiddleIndexOfElidedGlyphs Default");
370   DALI_TEST_EQUALS(textModel->GetSecondMiddleIndexOfElidedGlyphs(), 0u, TEST_LOCATION);
371
372   // Tests the rendering controller has been created.
373   TypesetterPtr typesetter = Typesetter::New(textModel);
374   DALI_TEST_CHECK(typesetter);
375
376   // Tests the view model has been created.
377   ViewModel* model = typesetter->GetViewModel();
378
379   tet_infoline(" UtcDaliToolkitTextlabelEllipsisInternalAPIs - IsTextElideEnabled ViewModel");
380   DALI_TEST_CHECK(model->IsTextElideEnabled());
381
382   tet_infoline(" UtcDaliToolkitTextlabelEllipsisInternalAPIs - GetStartIndexOfElidedGlyphs ViewModel");
383   DALI_TEST_EQUALS(model->GetStartIndexOfElidedGlyphs(), 0u, TEST_LOCATION);
384
385   tet_infoline(" UtcDaliToolkitTextlabelEllipsisInternalAPIs - GetEndIndexOfElidedGlyphs ViewModel");
386   DALI_TEST_EQUALS(model->GetEndIndexOfElidedGlyphs(), 0u, TEST_LOCATION);
387
388   tet_infoline(" UtcDaliToolkitTextlabelEllipsisInternalAPIs - GetFirstMiddleIndexOfElidedGlyphs ViewModel");
389   DALI_TEST_EQUALS(model->GetFirstMiddleIndexOfElidedGlyphs(), 0u, TEST_LOCATION);
390
391   tet_infoline(" UtcDaliToolkitTextlabelEllipsisInternalAPIs - GetSecondMiddleIndexOfElidedGlyphs ViewModel");
392   DALI_TEST_EQUALS(model->GetSecondMiddleIndexOfElidedGlyphs(), 0u, TEST_LOCATION);
393
394   END_TEST;
395 }
396 int UtcDaliTextLabelTextWithSpan(void)
397 {
398   ToolkitTestApplication application;
399   tet_infoline("UtcDaliTextLabelTextWithSpan\n");
400
401   TextLabel label = TextLabel::New();
402   DALI_TEST_CHECK(label);
403
404   label.SetProperty(TextLabel ::Property::ENABLE_MARKUP, true);
405   label.SetProperty(TextLabel::Property::TEXT, "Hello Span");
406   application.GetScene().Add(label);
407
408   application.SendNotification();
409   application.Render();
410
411   Vector3 originalSize = label.GetNaturalSize();
412   label.SetProperty(TextLabel::Property::TEXT, "H<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red'>ello</span> Span");
413
414   application.SendNotification();
415   application.Render();
416
417   Vector3 spanSize = label.GetNaturalSize();
418
419   DALI_TEST_GREATER(spanSize.width, originalSize.width, TEST_LOCATION);
420
421   Toolkit::Internal::TextLabel& labelImpl           = GetImpl(label);
422   const ColorIndex* const       colorIndicesBuffer1 = labelImpl.GetTextController()->GetTextModel()->GetColorIndices();
423
424   DALI_TEST_CHECK(colorIndicesBuffer1);
425
426   //default color
427   DALI_TEST_EQUALS(colorIndicesBuffer1[0], 0u, TEST_LOCATION);
428
429   //span color
430   DALI_TEST_EQUALS(colorIndicesBuffer1[1], 1u, TEST_LOCATION);
431
432   //default color
433   DALI_TEST_EQUALS(colorIndicesBuffer1[6], 0u, TEST_LOCATION);
434
435   label.SetProperty(TextLabel::Property::TEXT, "<span font-size='45'>H</span>ello <span text-color='red'>S</span>pan");
436
437   application.SendNotification();
438   application.Render();
439
440   const ColorIndex* const colorIndicesBuffer2 = labelImpl.GetTextController()->GetTextModel()->GetColorIndices();
441
442   DALI_TEST_CHECK(colorIndicesBuffer2);
443
444   //default color
445   DALI_TEST_EQUALS(colorIndicesBuffer2[0], 0u, TEST_LOCATION);
446
447   //default color
448   DALI_TEST_EQUALS(colorIndicesBuffer2[1], 0u, TEST_LOCATION);
449
450   //span color
451   DALI_TEST_EQUALS(colorIndicesBuffer2[6], 1u, TEST_LOCATION);
452
453   //default color
454   DALI_TEST_EQUALS(colorIndicesBuffer2[7], 0u, TEST_LOCATION);
455
456   END_TEST;
457 }
458
459 int UtcDaliTextLabelMarkupStrikethrough(void)
460 {
461   ToolkitTestApplication application;
462   tet_infoline(" UtcDaliTextLabelMarkupStrikethrough ");
463
464   TextLabel textLabel = TextLabel::New();
465
466   application.GetScene().Add(textLabel);
467
468   textLabel.SetProperty(TextLabel::Property::TEXT, "<s color='red'>ABC</s>EF<s color='green'>GH</s>");
469   textLabel.SetProperty(TextLabel ::Property::ENABLE_MARKUP, true);
470
471   application.SendNotification();
472   application.Render();
473
474   uint32_t expectedNumberOfStrikethroughGlyphs = 2u;
475
476   Toolkit::Internal::TextLabel& textLabelImpl             = GetImpl(textLabel);
477   const Text::Length            numberOfStrikethroughRuns = textLabelImpl.GetTextController()->GetTextModel()->GetNumberOfStrikethroughRuns();
478
479   DALI_TEST_EQUALS(numberOfStrikethroughRuns, expectedNumberOfStrikethroughGlyphs, TEST_LOCATION);
480
481   Vector<StrikethroughGlyphRun> strikethroughRuns;
482   strikethroughRuns.Resize(numberOfStrikethroughRuns);
483   textLabelImpl.GetTextController()->GetTextModel()->GetStrikethroughRuns(strikethroughRuns.Begin(), 0u, numberOfStrikethroughRuns);
484
485   //ABC have strikethrough
486   DALI_TEST_EQUALS(strikethroughRuns[0u].glyphRun.glyphIndex, 0u, TEST_LOCATION);
487   DALI_TEST_EQUALS(strikethroughRuns[0u].glyphRun.numberOfGlyphs, 3u, TEST_LOCATION);
488   DALI_TEST_CHECK(strikethroughRuns[0u].isColorSet);
489   DALI_TEST_EQUALS(strikethroughRuns[0u].color.r, 1u, TEST_LOCATION);
490   DALI_TEST_EQUALS(strikethroughRuns[0u].color.g, 0u, TEST_LOCATION);
491   DALI_TEST_EQUALS(strikethroughRuns[0u].color.b, 0u, TEST_LOCATION);
492
493   //GH have strikethrough
494   DALI_TEST_EQUALS(strikethroughRuns[1u].glyphRun.glyphIndex, 5u, TEST_LOCATION);
495   DALI_TEST_EQUALS(strikethroughRuns[1u].glyphRun.numberOfGlyphs, 2u, TEST_LOCATION);
496   DALI_TEST_CHECK(strikethroughRuns[1u].isColorSet);
497   DALI_TEST_EQUALS(strikethroughRuns[1u].color.r, 0u, TEST_LOCATION);
498   DALI_TEST_EQUALS(strikethroughRuns[1u].color.g, 1u, TEST_LOCATION);
499   DALI_TEST_EQUALS(strikethroughRuns[1u].color.b, 0u, TEST_LOCATION);
500
501   END_TEST;
502 }
503
504 int UtcDaliTextLabelMarkupStrikethroughNoEndTag(void)
505 {
506   ToolkitTestApplication application;
507   tet_infoline(" UtcDaliTextLabelMarkupStrikethroughNoEndTag ");
508
509   TextLabel textLabel = TextLabel::New();
510
511   application.GetScene().Add(textLabel);
512
513   textLabel.SetProperty(TextLabel::Property::TEXT, "<s>ABC");
514   textLabel.SetProperty(TextLabel ::Property::ENABLE_MARKUP, true);
515
516   application.SendNotification();
517   application.Render();
518
519   uint32_t expectedNumberOfStrikethroughGlyphs = 0u;
520
521   Toolkit::Internal::TextLabel& textLabelImpl             = GetImpl(textLabel);
522   Text::Length                  numberOfStrikethroughRuns = textLabelImpl.GetTextController()->GetTextModel()->GetNumberOfStrikethroughRuns();
523
524   DALI_TEST_EQUALS(numberOfStrikethroughRuns, expectedNumberOfStrikethroughGlyphs, TEST_LOCATION);
525
526   END_TEST;
527 }