c75f7545b4e0ef989c4515c9b9ae598b97e004f2
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-toolkit-internal / utc-Dali-TextEditor-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 <stdlib.h>
19 #include <iostream>
20
21 #include <dali-toolkit-test-suite-utils.h>
22 #include <dali-toolkit/dali-toolkit.h>
23
24 #include <dali-toolkit/internal/controls/text-controls/text-editor-impl.h>
25 #include <dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager.h>
26 #include <dali-toolkit/internal/text/text-controller-impl.h>
27 #include <dali-toolkit/internal/text/text-controller.h>
28
29 using namespace Dali;
30 using namespace Toolkit;
31 using namespace Text;
32
33 int UtcDaliTextEditorSelectText(void)
34 {
35   ToolkitTestApplication application;
36   tet_infoline("UtcDaliTextEditorSelectText");
37
38   // Create a text editor
39   TextEditor textEditor = TextEditor::New();
40   textEditor.SetProperty(Actor::Property::SIZE, Vector2(400.f, 60.f));
41   textEditor.SetProperty(TextEditor::Property::TEXT, "Hello World");
42
43   // Add the text editor to the stage
44   application.GetScene().Add(textEditor);
45
46   application.SendNotification();
47   application.Render();
48
49   Toolkit::Internal::TextEditor& textEditorImpl = GetImpl(textEditor);
50
51   application.SendNotification();
52   application.Render();
53
54   // Highlight the whole text
55   textEditorImpl.SelectWholeText();
56
57   application.SendNotification();
58   application.Render();
59
60   std::string selectedText = textEditorImpl.GetSelectedText();
61   DALI_TEST_CHECK(selectedText == "Hello World");
62
63   // Select None
64   textEditorImpl.SelectNone();
65
66   application.SendNotification();
67   application.Render();
68
69   selectedText = textEditorImpl.GetSelectedText();
70   DALI_TEST_CHECK(selectedText == "");
71
72   END_TEST;
73 }
74
75 int UtcDaliTextEditorMarkupUnderline(void)
76 {
77   ToolkitTestApplication application;
78   tet_infoline(" UtcDaliTextEditorMarkupUnderline ");
79
80   TextEditor textEditor = TextEditor::New();
81
82   application.GetScene().Add(textEditor);
83
84   textEditor.SetProperty(TextEditor::Property::TEXT, "<u>ABC</u>EF<u>GH</u>");
85   textEditor.SetProperty(TextEditor ::Property::ENABLE_MARKUP, true);
86
87   application.SendNotification();
88   application.Render();
89
90   uint32_t expectedNumberOfUnderlineRuns = 2u;
91
92   Toolkit::Internal::TextEditor& textEditorImpl        = GetImpl(textEditor);
93   const Text::Length             numberOfUnderlineRuns = textEditorImpl.GetTextController()->GetTextModel()->GetNumberOfUnderlineRuns();
94
95   DALI_TEST_EQUALS(numberOfUnderlineRuns, expectedNumberOfUnderlineRuns, TEST_LOCATION);
96
97   Vector<UnderlinedGlyphRun> underlineRuns;
98   underlineRuns.Resize(numberOfUnderlineRuns);
99   textEditorImpl.GetTextController()->GetTextModel()->GetUnderlineRuns(underlineRuns.Begin(), 0u, numberOfUnderlineRuns);
100
101   //ABC are underlined
102   DALI_TEST_EQUALS(underlineRuns[0u].glyphRun.glyphIndex, 0u, TEST_LOCATION);
103   DALI_TEST_EQUALS(underlineRuns[0u].glyphRun.numberOfGlyphs, 3u, TEST_LOCATION);
104
105   //GH are underlined
106   DALI_TEST_EQUALS(underlineRuns[1u].glyphRun.glyphIndex, 5u, TEST_LOCATION);
107   DALI_TEST_EQUALS(underlineRuns[1u].glyphRun.numberOfGlyphs, 2u, TEST_LOCATION);
108
109   END_TEST;
110 }
111
112 int UtcDaliTextEditorMarkupUnderlineAttributes(void)
113 {
114   ToolkitTestApplication application;
115   tet_infoline(" UtcDaliTextEditorMarkupUnderlineAttributes ");
116
117   TextEditor textEditor = TextEditor::New();
118
119   application.GetScene().Add(textEditor);
120
121   std::string testText =
122     "start<u>ABC1</u>then"
123     "<u type='solid'>ABC2</u>then"
124     "<u type='dashed'>ABC3</u>then"
125     "<u type='double'>ABC4</u>then"
126     "<u color='green'>ABC5</u>then"
127     "<u height='5.0f'>ABC6</u>then"
128     "<u type='dashed' dash-gap='3.0f'>ABC7</u>then"
129     "<u type='dashed' dash-width='4.0f'>ABC8</u>then"
130     "<u color='blue' type='dashed' height='4.0f' dash-gap='2.0f' dash-width='3.0f'>ABC9</u>end";
131
132   textEditor.SetProperty(TextEditor::Property::TEXT, testText);
133   textEditor.SetProperty(TextEditor ::Property::ENABLE_MARKUP, true);
134
135   application.SendNotification();
136   application.Render();
137
138   const uint32_t expectedNumberOfUnderlineRuns = 9u;
139
140   Toolkit::Internal::TextEditor& textEditorImpl        = GetImpl(textEditor);
141   const Text::Length             numberOfUnderlineRuns = textEditorImpl.GetTextController()->GetTextModel()->GetNumberOfUnderlineRuns();
142
143   DALI_TEST_EQUALS(numberOfUnderlineRuns, expectedNumberOfUnderlineRuns, TEST_LOCATION);
144
145   Vector<UnderlinedGlyphRun> underlineRuns;
146   underlineRuns.Resize(numberOfUnderlineRuns);
147   textEditorImpl.GetTextController()->GetTextModel()->GetUnderlineRuns(underlineRuns.Begin(), 0u, numberOfUnderlineRuns);
148
149   struct DataOfCase
150   {
151     std::string              title;
152     GlyphIndex               glyphIndex;
153     Length                   numberOfGlyphs;
154     UnderlineStyleProperties properties;
155   };
156   DataOfCase data[] =
157     {
158       //<u>ABC1</u>
159       {"<u>ABC1</u>",
160        5u,
161        4u,
162        {
163          Text::Underline::SOLID,
164          Color::BLACK,
165          0u,
166          1u,
167          2u,
168          false,
169          false,
170          false,
171          false,
172          false,
173        }},
174
175       //<u type='solid'>ABC2</u>
176       {"<u type='solid'>ABC2</u>",
177        13u,
178        4u,
179        {
180          Text::Underline::SOLID,
181          Color::BLACK,
182          0u,
183          1u,
184          2u,
185          true,
186          false,
187          false,
188          false,
189          false,
190        }},
191
192       //<u type='dashed'>ABC3</u>
193       {"<u type='dashed'>ABC3</u>",
194        21u,
195        4u,
196        {
197          Text::Underline::DASHED,
198          Color::BLACK,
199          0u,
200          1u,
201          2u,
202          true,
203          false,
204          false,
205          false,
206          false,
207        }},
208
209       //<u type='double'>ABC4</u>
210       {"<u type='double'>ABC4</u>",
211        29u,
212        4u,
213        {
214          Text::Underline::DOUBLE,
215          Color::BLACK,
216          0u,
217          1u,
218          2u,
219          true,
220          false,
221          false,
222          false,
223          false,
224        }},
225
226       //<u color='green'>ABC5</u>
227       {"<u color='green'>ABC5</u>",
228        37u,
229        4u,
230        {
231          Text::Underline::SOLID,
232          Color::GREEN,
233          0u,
234          1u,
235          2u,
236          false,
237          true,
238          false,
239          false,
240          false,
241        }},
242
243       //<u height='5.0f'>ABC6</u>
244       {"<u height='5.0f'>ABC6</u>",
245        45u,
246        4u,
247        {
248          Text::Underline::SOLID,
249          Color::BLACK,
250          5u,
251          1u,
252          2u,
253          false,
254          false,
255          true,
256          false,
257          false,
258        }},
259
260       //<u type='dashed' dash-gap='3.0f'>ABC7</u>
261       {"<u type='dashed' dash-gap='3.0f'>ABC7</u>",
262        53u,
263        4u,
264        {
265          Text::Underline::DASHED,
266          Color::BLACK,
267          0u,
268          3u,
269          2u,
270          true,
271          false,
272          false,
273          true,
274          false,
275        }},
276
277       //<u type='dashed' dash-width='4.0f'>ABC8</u>
278       {"<u type='dashed' dash-width='4.0f'>ABC8</u>",
279        61u,
280        4u,
281        {
282          Text::Underline::DASHED,
283          Color::BLACK,
284          0u,
285          1u,
286          4u,
287          true,
288          false,
289          false,
290          false,
291          true,
292        }},
293
294       //<u color='blue' type='dashed' height='4.0f' dash-gap='2.0f' dash-width='3.0f'>
295       {"<u color='blue' type='dashed' height='4.0f' dash-gap='2.0f' dash-width='3.0f'>",
296        69u,
297        4u,
298        {
299          Text::Underline::DASHED,
300          Color::BLUE,
301          4u,
302          2u,
303          3u,
304          true,
305          true,
306          true,
307          true,
308          true,
309        }},
310
311     };
312
313   for(uint32_t i = 0; i < expectedNumberOfUnderlineRuns; i++)
314   {
315     tet_infoline(data[i].title.c_str());
316     DALI_TEST_EQUALS(underlineRuns[i].glyphRun.glyphIndex, data[i].glyphIndex, TEST_LOCATION);
317     DALI_TEST_EQUALS(underlineRuns[i].glyphRun.numberOfGlyphs, data[i].numberOfGlyphs, TEST_LOCATION);
318     DALI_TEST_CHECK(data[i].properties == underlineRuns[i].properties);
319   }
320
321   END_TEST;
322 }
323
324 int UtcDaliTextEditorMarkupSpanUnderline(void)
325 {
326   ToolkitTestApplication application;
327   tet_infoline(" UtcDaliTextEditorMarkupSpanUnderline ");
328
329   TextEditor textEditor = TextEditor::New();
330
331   application.GetScene().Add(textEditor);
332
333   std::string testText =
334     "start<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red'>ABC1</span>then"
335     "<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-type='solid'>ABC2</span>then"
336     "<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-type='dashed'>ABC3</span>then"
337     "<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-type='double'>ABC4</span>then"
338     "<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-color='green'>ABC5</span>then"
339     "<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-height='5.0f'>ABC6</span>then"
340     "<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-type='dashed' u-dash-gap='3.0f'>ABC7</span>then"
341     "<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-type='dashed' u-dash-width='4.0f'>ABC8</span>then"
342     "<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-color='blue' u-type='dashed' u-height='4.0f' u-dash-gap='2.0f' u-dash-width='3.0f'>ABC9</span>end";
343
344   textEditor.SetProperty(TextEditor::Property::TEXT, testText);
345   textEditor.SetProperty(TextEditor ::Property::ENABLE_MARKUP, true);
346
347   application.SendNotification();
348   application.Render();
349
350   const uint32_t expectedNumberOfUnderlineRuns = 8u;
351
352   Toolkit::Internal::TextEditor& textEditorImpl        = GetImpl(textEditor);
353   const Text::Length             numberOfUnderlineRuns = textEditorImpl.GetTextController()->GetTextModel()->GetNumberOfUnderlineRuns();
354
355   DALI_TEST_EQUALS(numberOfUnderlineRuns, expectedNumberOfUnderlineRuns, TEST_LOCATION);
356
357   Vector<UnderlinedGlyphRun> underlineRuns;
358   underlineRuns.Resize(numberOfUnderlineRuns);
359   textEditorImpl.GetTextController()->GetTextModel()->GetUnderlineRuns(underlineRuns.Begin(), 0u, numberOfUnderlineRuns);
360
361   struct DataOfCase
362   {
363     std::string              title;
364     GlyphIndex               glyphIndex;
365     Length                   numberOfGlyphs;
366     UnderlineStyleProperties properties;
367   };
368   DataOfCase data[] =
369     {
370       //<u type='solid'>ABC2</u>
371       {"<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-type='solid'>ABC2</span>",
372        13u,
373        4u,
374        {
375          Text::Underline::SOLID,
376          Color::BLACK,
377          0u,
378          1u,
379          2u,
380          true,
381          false,
382          false,
383          false,
384          false,
385        }},
386
387       //<u type='dashed'>ABC3</u>
388       {"<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-type='dashed'>ABC3</span>",
389        21u,
390        4u,
391        {
392          Text::Underline::DASHED,
393          Color::BLACK,
394          0u,
395          1u,
396          2u,
397          true,
398          false,
399          false,
400          false,
401          false,
402        }},
403
404       //<u type='double'>ABC4</u>
405       {"<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-type='double'>ABC4</span>",
406        29u,
407        4u,
408        {
409          Text::Underline::DOUBLE,
410          Color::BLACK,
411          0u,
412          1u,
413          2u,
414          true,
415          false,
416          false,
417          false,
418          false,
419        }},
420
421       //<u color='green'>ABC5</u>
422       {"<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-color='green'>ABC5</span>",
423        37u,
424        4u,
425        {
426          Text::Underline::SOLID,
427          Color::GREEN,
428          0u,
429          1u,
430          2u,
431          false,
432          true,
433          false,
434          false,
435          false,
436        }},
437
438       //<u height='5.0f'>ABC6</u>
439       {"<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-height='5.0f'>ABC6</span>",
440        45u,
441        4u,
442        {
443          Text::Underline::SOLID,
444          Color::BLACK,
445          5u,
446          1u,
447          2u,
448          false,
449          false,
450          true,
451          false,
452          false,
453        }},
454
455       //<u type='dashed' dash-gap='3.0f'>ABC7</u>
456       {"<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-type='dashed' u-dash-gap='3.0f'>ABC7</span>",
457        53u,
458        4u,
459        {
460          Text::Underline::DASHED,
461          Color::BLACK,
462          0u,
463          3u,
464          2u,
465          true,
466          false,
467          false,
468          true,
469          false,
470        }},
471
472       //<u type='dashed' dash-width='4.0f'>ABC8</u>
473       {"<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-type='dashed' u-dash-width='4.0f'>ABC8</span>",
474        61u,
475        4u,
476        {
477          Text::Underline::DASHED,
478          Color::BLACK,
479          0u,
480          1u,
481          4u,
482          true,
483          false,
484          false,
485          false,
486          true,
487        }},
488
489       //<u color='blue' type='dashed' height='4.0f' dash-gap='2.0f' dash-width='3.0f'>
490       {"<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-color='blue' u-type='dashed' u-height='4.0f' u-dash-gap='2.0f' u-dash-width='3.0f'>ABC9</span>",
491        69u,
492        4u,
493        {
494          Text::Underline::DASHED,
495          Color::BLUE,
496          4u,
497          2u,
498          3u,
499          true,
500          true,
501          true,
502          true,
503          true,
504        }},
505
506     };
507
508   for(uint32_t i = 0; i < expectedNumberOfUnderlineRuns; i++)
509   {
510     tet_infoline(data[i].title.c_str());
511     DALI_TEST_EQUALS(underlineRuns[i].glyphRun.glyphIndex, data[i].glyphIndex, TEST_LOCATION);
512     DALI_TEST_EQUALS(underlineRuns[i].glyphRun.numberOfGlyphs, data[i].numberOfGlyphs, TEST_LOCATION);
513     DALI_TEST_CHECK(data[i].properties == underlineRuns[i].properties);
514   }
515
516   END_TEST;
517 }
518
519 int UtcDaliTextEditorMarkupNestedUnderlineTags(void)
520 {
521   ToolkitTestApplication application;
522   tet_infoline(" UtcDaliTextEditorMarkupNestedUnderlineTags ");
523
524   TextEditor textEditor = TextEditor::New();
525
526   application.GetScene().Add(textEditor);
527
528   std::string testText = "start<u height='5.0f' color='green' >AB<u color='blue' >XYZ</u>CDE</u>end";
529
530   textEditor.SetProperty(TextEditor::Property::TEXT, testText);
531   textEditor.SetProperty(TextEditor ::Property::ENABLE_MARKUP, true);
532
533   application.SendNotification();
534   application.Render();
535
536   const uint32_t expectedNumberOfUnderlineRuns = 2u;
537
538   Toolkit::Internal::TextEditor& textEditorImpl        = GetImpl(textEditor);
539   const Text::Length             numberOfUnderlineRuns = textEditorImpl.GetTextController()->GetTextModel()->GetNumberOfUnderlineRuns();
540
541   DALI_TEST_EQUALS(numberOfUnderlineRuns, expectedNumberOfUnderlineRuns, TEST_LOCATION);
542
543   Vector<UnderlinedGlyphRun> underlineRuns;
544   underlineRuns.Resize(numberOfUnderlineRuns);
545   textEditorImpl.GetTextController()->GetTextModel()->GetUnderlineRuns(underlineRuns.Begin(), 0u, numberOfUnderlineRuns);
546
547   struct DataOfCase
548   {
549     std::string              title;
550     GlyphIndex               glyphIndex;
551     Length                   numberOfGlyphs;
552     UnderlineStyleProperties properties;
553   };
554   DataOfCase data[] =
555     {
556       //Outter
557       {"<u height='5.0f' color='green' >AB<u color='blue' >XYZ</u>CDE</u>",
558        5u,
559        8u,
560        {
561          Text::Underline::SOLID,
562          Color::GREEN,
563          5u,
564          1u,
565          2u,
566          false,
567          true,
568          true,
569          false,
570          false,
571        }},
572
573       //Inner
574       {"<u color='blue' >XYZ</u>",
575        7u,
576        3u,
577        {
578          Text::Underline::SOLID,
579          Color::BLUE,
580          5u,
581          1u,
582          2u,
583          false,
584          true,
585          true,
586          false,
587          false,
588        }},
589
590     };
591
592   for(uint32_t i = 0; i < expectedNumberOfUnderlineRuns; i++)
593   {
594     tet_infoline(data[i].title.c_str());
595     DALI_TEST_EQUALS(underlineRuns[i].glyphRun.glyphIndex, data[i].glyphIndex, TEST_LOCATION);
596     DALI_TEST_EQUALS(underlineRuns[i].glyphRun.numberOfGlyphs, data[i].numberOfGlyphs, TEST_LOCATION);
597     DALI_TEST_CHECK(data[i].properties == underlineRuns[i].properties);
598   }
599
600   END_TEST;
601 }
602
603 int UtcDaliTextEditorFontPointSizeLargerThanAtlas(void)
604 {
605   ToolkitTestApplication application;
606   tet_infoline(" UtcDaliTextEditorFontPointSizeLargerThanAtlas ");
607
608   // Create a text editor
609   TextEditor textEditor = TextEditor::New();
610   //Set size to avoid automatic eliding
611   textEditor.SetProperty(Actor::Property::SIZE, Vector2(1025, 1025));
612   //Set very large font-size using point-size
613   textEditor.SetProperty(TextEditor::Property::POINT_SIZE, 1000);
614   //Specify font-family
615   textEditor.SetProperty(TextEditor::Property::FONT_FAMILY, "DejaVu Sans");
616   //Set text to check if appear or not
617   textEditor.SetProperty(TextEditor::Property::TEXT, "A");
618
619   application.GetScene().Add(textEditor);
620
621   application.SendNotification();
622   application.Render();
623
624   //Check if Glyph is added to AtlasGlyphManger or not
625   int countAtlas = AtlasGlyphManager::Get().GetMetrics().mAtlasMetrics.mAtlasCount;
626   DALI_TEST_EQUALS(countAtlas, 1, TEST_LOCATION);
627
628   END_TEST;
629 }
630
631 int UtcDaliTextEditorFontPointSizeLargerThanAtlasPlaceholderCase(void)
632 {
633   ToolkitTestApplication application;
634   tet_infoline(" UtcDaliTextEditorFontPointSizeLargerThanAtlasPlaceholderCase ");
635
636   //Set Map of placeholder: text, font-family and point-size
637   Property::Map placeholderMapSet;
638   placeholderMapSet["text"]       = "A";
639   placeholderMapSet["fontFamily"] = "DejaVu Sans";
640   placeholderMapSet["pixelSize"]  = 1000.0f;
641
642   // Create a text editor
643   TextEditor textEditor = TextEditor::New();
644   //Set size to avoid automatic eliding
645   textEditor.SetProperty(Actor::Property::SIZE, Vector2(1025, 1025));
646   //Set placeholder
647   textEditor.SetProperty(TextEditor::Property::PLACEHOLDER, placeholderMapSet);
648
649   application.GetScene().Add(textEditor);
650
651   application.SendNotification();
652   application.Render();
653
654   //Check if Glyph is added to AtlasGlyphManger or not
655   int countAtlas = AtlasGlyphManager::Get().GetMetrics().mAtlasMetrics.mAtlasCount;
656   DALI_TEST_EQUALS(countAtlas, 1, TEST_LOCATION);
657
658   END_TEST;
659 }
660
661 int UtcDaliTextEditorBackgroundTag(void)
662 {
663   ToolkitTestApplication application;
664   tet_infoline("UtcDaliTextEditorBackgroundTag\n");
665
666   TextEditor editor = TextEditor::New();
667   DALI_TEST_CHECK(editor);
668
669   editor.SetProperty(TextEditor ::Property::ENABLE_MARKUP, true);
670   editor.SetProperty(TextEditor::Property::TEXT, "H<background color='red'>e</background> Worl<background color='yellow'>d</background>");
671   application.GetScene().Add(editor);
672   application.SendNotification();
673   application.Render();
674
675   Toolkit::Internal::TextEditor& editorImpl                   = GetImpl(editor);
676   const ColorIndex* const        backgroundColorIndicesBuffer = editorImpl.GetTextController()->GetTextModel()->GetBackgroundColorIndices();
677
678   DALI_TEST_CHECK(backgroundColorIndicesBuffer);
679
680   //default color
681   DALI_TEST_EQUALS(backgroundColorIndicesBuffer[0], 0u, TEST_LOCATION);
682
683   //red color
684   DALI_TEST_EQUALS(backgroundColorIndicesBuffer[1], 1u, TEST_LOCATION);
685
686   //yellow color
687   DALI_TEST_EQUALS(backgroundColorIndicesBuffer[7], 2u, TEST_LOCATION);
688
689   END_TEST;
690 }
691
692 int UtcDaliTextEditorTextWithSpan(void)
693 {
694   ToolkitTestApplication application;
695   tet_infoline("UtcDaliTextEditorTextWithSpan\n");
696
697   TextEditor editor = TextEditor::New();
698   DALI_TEST_CHECK(editor);
699
700   editor.SetProperty(TextEditor ::Property::ENABLE_MARKUP, true);
701   editor.SetProperty(TextEditor::Property::TEXT, "Hello Span");
702   application.GetScene().Add(editor);
703
704   application.SendNotification();
705   application.Render();
706
707   Vector3 originalSize = editor.GetNaturalSize();
708   editor.SetProperty(TextEditor::Property::TEXT, "H<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red'>ello</span> Span");
709
710   application.SendNotification();
711   application.Render();
712
713   Vector3 spanSize = editor.GetNaturalSize();
714
715   DALI_TEST_GREATER(spanSize.width, originalSize.width, TEST_LOCATION);
716
717   Toolkit::Internal::TextEditor& editorImpl          = GetImpl(editor);
718   const ColorIndex* const        colorIndicesBuffer1 = editorImpl.GetTextController()->GetTextModel()->GetColorIndices();
719
720   DALI_TEST_CHECK(colorIndicesBuffer1);
721
722   //default color
723   DALI_TEST_EQUALS(colorIndicesBuffer1[0], 0u, TEST_LOCATION);
724
725   //span color
726   DALI_TEST_EQUALS(colorIndicesBuffer1[1], 1u, TEST_LOCATION);
727
728   //default color
729   DALI_TEST_EQUALS(colorIndicesBuffer1[6], 0u, TEST_LOCATION);
730
731   editor.SetProperty(TextEditor::Property::TEXT, "<span font-size='45'>H</span>ello <span text-color='red'>S</span>pan");
732
733   application.SendNotification();
734   application.Render();
735
736   const ColorIndex* const colorIndicesBuffer2 = editorImpl.GetTextController()->GetTextModel()->GetColorIndices();
737
738   DALI_TEST_CHECK(colorIndicesBuffer2);
739
740   //default color
741   DALI_TEST_EQUALS(colorIndicesBuffer2[0], 0u, TEST_LOCATION);
742
743   //default color
744   DALI_TEST_EQUALS(colorIndicesBuffer2[1], 0u, TEST_LOCATION);
745
746   //span color
747   DALI_TEST_EQUALS(colorIndicesBuffer2[6], 1u, TEST_LOCATION);
748
749   //default color
750   DALI_TEST_EQUALS(colorIndicesBuffer2[7], 0u, TEST_LOCATION);
751
752   END_TEST;
753 }
754
755 int UtcDaliTextEditorControlBackgroundColor(void)
756 {
757   ToolkitTestApplication application;
758   tet_infoline(" UtcDaliTextEditorControlBackgroundColor\n");
759
760   TextEditor editor = TextEditor::New();
761   DALI_TEST_CHECK(editor);
762
763   Vector4 backgroundColor;
764
765   editor.SetProperty(TextEditor::Property::TEXT, "Background Color");
766   application.GetScene().Add(editor);
767   application.SendNotification();
768   application.Render();
769
770   Toolkit::Internal::TextEditor& editorImpl     = GetImpl(editor);
771   ControllerPtr                  controller     = editorImpl.GetTextController();
772   Controller::Impl&              controllerImpl = Controller::Impl::GetImplementation(*controller.Get());
773
774   // Default color is transparent
775   controllerImpl.mEditableControlInterface->GetControlBackgroundColor(backgroundColor);
776   DALI_TEST_EQUALS(backgroundColor, Color::TRANSPARENT, TEST_LOCATION);
777
778   // Set background color to red
779   editor.SetBackgroundColor(Color::RED);
780   application.SendNotification();
781   application.Render();
782
783   // Should be red
784   controllerImpl.mEditableControlInterface->GetControlBackgroundColor(backgroundColor);
785   DALI_TEST_EQUALS(backgroundColor, Color::RED, TEST_LOCATION);
786
787   END_TEST;
788 }
789
790 int UtcDaliTextEditorTextPositionWithMinLineAndBigFont(void)
791 {
792   ToolkitTestApplication application;
793   tet_infoline(" UtcDaliTextEditorTextPositionWithMinLine ");
794
795   TextEditor textEditor = TextEditor::New();
796
797   textEditor.SetProperty(TextEditor::Property::TEXT, "<span font-size='45'>H</span>\ni");
798   textEditor.SetProperty(DevelTextEditor::Property::MIN_LINE_SIZE, 50);
799   textEditor.SetProperty(TextEditor ::Property::ENABLE_MARKUP, true);
800
801   application.GetScene().Add(textEditor);
802
803   application.SendNotification();
804   application.Render();
805
806   Toolkit::Internal::TextEditor& textEditorImpl = GetImpl(textEditor);
807   Text::ViewInterface&           view           = textEditorImpl.GetTextController()->GetView();
808
809   Length numberOfGlyphs = view.GetNumberOfGlyphs();
810
811   DALI_TEST_EQUALS(numberOfGlyphs, 3u, Math::MACHINE_EPSILON_1000, TEST_LOCATION);
812
813   Vector<GlyphInfo> glyphs;
814   glyphs.Resize(numberOfGlyphs);
815
816   Vector<Vector2> positions;
817   positions.Resize(numberOfGlyphs);
818
819   float alignmentOffset = 0u;
820   numberOfGlyphs        = view.GetGlyphs(glyphs.Begin(),
821                                   positions.Begin(),
822                                   alignmentOffset,
823                                   0u,
824                                   numberOfGlyphs);
825
826   DALI_TEST_EQUALS(positions[2].y, 165.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION);
827
828   END_TEST;
829 }
830
831 int UtcDaliTextEditorMarkupStrikethrough(void)
832 {
833   ToolkitTestApplication application;
834   tet_infoline(" UtcDaliTextEditorMarkupStrikethrough ");
835
836   TextEditor textEditor = TextEditor::New();
837
838   application.GetScene().Add(textEditor);
839
840   textEditor.SetProperty(TextEditor::Property::TEXT, "<s>ABC</s>EF<s color='red'>GH</s>");
841   textEditor.SetProperty(TextEditor ::Property::ENABLE_MARKUP, true);
842
843   application.SendNotification();
844   application.Render();
845
846   uint32_t expectedNumberOfStrikethroughGlyphs = 2u;
847
848   Toolkit::Internal::TextEditor& textEditorImpl            = GetImpl(textEditor);
849   const Text::Length             numberOfStrikethroughRuns = textEditorImpl.GetTextController()->GetTextModel()->GetNumberOfStrikethroughRuns();
850
851   DALI_TEST_EQUALS(numberOfStrikethroughRuns, expectedNumberOfStrikethroughGlyphs, TEST_LOCATION);
852
853   Vector<StrikethroughGlyphRun> strikethroughRuns;
854   strikethroughRuns.Resize(numberOfStrikethroughRuns);
855   textEditorImpl.GetTextController()->GetTextModel()->GetStrikethroughRuns(strikethroughRuns.Begin(), 0u, numberOfStrikethroughRuns);
856
857   //ABC have strikethrough
858   DALI_TEST_EQUALS(strikethroughRuns[0u].glyphRun.glyphIndex, 0u, TEST_LOCATION);
859   DALI_TEST_EQUALS(strikethroughRuns[0u].glyphRun.numberOfGlyphs, 3u, TEST_LOCATION);
860   DALI_TEST_CHECK(!strikethroughRuns[0u].isColorSet);
861
862   //GH have strikethrough
863   DALI_TEST_EQUALS(strikethroughRuns[1u].glyphRun.glyphIndex, 5u, TEST_LOCATION);
864   DALI_TEST_EQUALS(strikethroughRuns[1u].glyphRun.numberOfGlyphs, 2u, TEST_LOCATION);
865   DALI_TEST_CHECK(strikethroughRuns[1u].isColorSet);
866
867   END_TEST;
868 }
869
870 int UtcDaliTextEditorMarkupStrikethroughNoEndTag(void)
871 {
872   ToolkitTestApplication application;
873   tet_infoline(" UtcDaliTextEditorMarkupStrikethroughNoEndTag ");
874
875   TextEditor textEditor = TextEditor::New();
876
877   application.GetScene().Add(textEditor);
878
879   textEditor.SetProperty(TextEditor::Property::TEXT, "<s>ABC");
880   textEditor.SetProperty(TextEditor ::Property::ENABLE_MARKUP, true);
881
882   application.SendNotification();
883   application.Render();
884
885   uint32_t expectedNumberOfStrikethroughGlyphs = 0u;
886
887   Toolkit::Internal::TextEditor& textEditorImpl            = GetImpl(textEditor);
888   Text::Length                   numberOfStrikethroughRuns = textEditorImpl.GetTextController()->GetTextModel()->GetNumberOfStrikethroughRuns();
889
890   DALI_TEST_EQUALS(numberOfStrikethroughRuns, expectedNumberOfStrikethroughGlyphs, TEST_LOCATION);
891
892   END_TEST;
893 }
894
895 int UtcDaliTextEditorMarkupParagraphTag(void)
896
897 {
898   ToolkitTestApplication application;
899   tet_infoline(" UtcDaliTextEditorMarkupParagraphTag ");
900
901   TextEditor textEditor = TextEditor::New();
902   application.GetScene().Add(textEditor);
903
904   textEditor.SetProperty(TextEditor::Property::TEXT, "text one <p>Paragraph two</p> text three <p>Paragraph four</p> text five");
905   textEditor.SetProperty(TextEditor ::Property::ENABLE_MARKUP, true);
906
907   application.SendNotification();
908   application.Render();
909
910   uint32_t expectedNumberOfBoundedParagraphRuns = 2u;
911
912   Toolkit::Internal::TextEditor& textEditorImpl               = GetImpl(textEditor);
913   const Text::Length             numberOfBoundedParagraphRuns = textEditorImpl.GetTextController()->GetTextModel()->GetNumberOfBoundedParagraphRuns();
914   DALI_TEST_EQUALS(numberOfBoundedParagraphRuns, expectedNumberOfBoundedParagraphRuns, TEST_LOCATION);
915
916   const Vector<BoundedParagraphRun>& boundedParagraphRuns = textEditorImpl.GetTextController()->GetTextModel()->GetBoundedParagraphRuns();
917
918   //<p>Paragraph two</p>
919   DALI_TEST_EQUALS(boundedParagraphRuns[0u].characterRun.characterIndex, 10u, TEST_LOCATION);
920   DALI_TEST_EQUALS(boundedParagraphRuns[0u].characterRun.numberOfCharacters, 14u, TEST_LOCATION);
921
922   //<p>Paragraph four</p>
923   DALI_TEST_EQUALS(boundedParagraphRuns[1u].characterRun.characterIndex, 37u, TEST_LOCATION);
924   DALI_TEST_EQUALS(boundedParagraphRuns[1u].characterRun.numberOfCharacters, 15u, TEST_LOCATION);
925
926   END_TEST;
927 }
928
929 int UtcDaliTextEditorMarkupParagraphTagAlignAttribute(void)
930 {
931   ToolkitTestApplication application;
932   tet_infoline(" UtcDaliTextEditorMarkupParagraphTagAlignAttribute ");
933
934   // Apply alignment for each type on property level on three paragraphs and in-between text.
935   // Apply align in markup on the three paragraphs (each one a type).
936   // Using the same text to gain similar results from both the property level and the markup.
937   // Compare line alignment between the property level and the markup.
938
939   std::string textAlignOnPropertyLevel = "text outside<p>Paragraph end</p>text outside<p>Paragraph center</p>text outside<p>Paragraph begin</p><p>Paragraph property alignment</p>";
940   std::string textAlignInMarkup        = "text outside<p align='end'>Paragraph end</p>text outside<p align='center'>Paragraph center</p>text outside<p align='begin' >Paragraph begin</p><p>Paragraph property alignment</p>";
941
942   //Set size to avoid automatic eliding
943   Vector2 controllerSize = Vector2(1025, 1025);
944
945   TextEditor textEditorBeginAlign  = TextEditor::New();
946   TextEditor textEditorCenterAlign = TextEditor::New();
947   TextEditor textEditorEndAlign    = TextEditor::New();
948   TextEditor textEditorMultiAlign  = TextEditor::New();
949
950   application.GetScene().Add(textEditorBeginAlign);
951   application.GetScene().Add(textEditorCenterAlign);
952   application.GetScene().Add(textEditorEndAlign);
953   application.GetScene().Add(textEditorMultiAlign);
954
955   textEditorBeginAlign.SetProperty(TextEditor::Property::TEXT, textAlignOnPropertyLevel);
956   textEditorBeginAlign.SetProperty(TextEditor ::Property::ENABLE_MARKUP, true);
957   textEditorBeginAlign.SetProperty(DevelTextEditor::Property::ELLIPSIS, false);
958   textEditorBeginAlign.SetProperty(TextEditor::Property::HORIZONTAL_ALIGNMENT, Dali::Toolkit::Text::HorizontalAlignment::BEGIN);
959   textEditorBeginAlign.SetProperty(Actor::Property::SIZE, controllerSize);
960
961   textEditorCenterAlign.SetProperty(TextEditor::Property::TEXT, textAlignOnPropertyLevel);
962   textEditorCenterAlign.SetProperty(TextEditor ::Property::ENABLE_MARKUP, true);
963   textEditorCenterAlign.SetProperty(DevelTextEditor::Property::ELLIPSIS, false);
964   textEditorCenterAlign.SetProperty(TextEditor::Property::HORIZONTAL_ALIGNMENT, Dali::Toolkit::Text::HorizontalAlignment::CENTER);
965   textEditorCenterAlign.SetProperty(Actor::Property::SIZE, controllerSize);
966
967   textEditorEndAlign.SetProperty(TextEditor::Property::TEXT, textAlignOnPropertyLevel);
968   textEditorEndAlign.SetProperty(TextEditor ::Property::ENABLE_MARKUP, true);
969   textEditorEndAlign.SetProperty(DevelTextEditor::Property::ELLIPSIS, false);
970   textEditorEndAlign.SetProperty(TextEditor::Property::HORIZONTAL_ALIGNMENT, Dali::Toolkit::Text::HorizontalAlignment::END);
971   textEditorEndAlign.SetProperty(Actor::Property::SIZE, controllerSize);
972
973   textEditorMultiAlign.SetProperty(TextEditor::Property::TEXT, textAlignInMarkup);
974   textEditorMultiAlign.SetProperty(TextEditor ::Property::ENABLE_MARKUP, true);
975   textEditorMultiAlign.SetProperty(DevelTextEditor::Property::ELLIPSIS, false);
976   textEditorMultiAlign.SetProperty(TextEditor::Property::HORIZONTAL_ALIGNMENT, Dali::Toolkit::Text::HorizontalAlignment::CENTER);
977   textEditorMultiAlign.SetProperty(Actor::Property::SIZE, controllerSize);
978
979   application.SendNotification();
980   application.Render();
981
982   uint32_t expectedNumberOfBoundedParagraphRuns = 4u;
983   uint32_t expectedNumberOfLines                = 7u;
984
985   Toolkit::Internal::TextEditor& textEditorMultiAlignImpl  = GetImpl(textEditorMultiAlign);
986   Toolkit::Internal::TextEditor& textEditorBeginAlignImpl  = GetImpl(textEditorBeginAlign);
987   Toolkit::Internal::TextEditor& textEditorCenterAlignImpl = GetImpl(textEditorCenterAlign);
988   Toolkit::Internal::TextEditor& textEditorEndAlignImpl    = GetImpl(textEditorEndAlign);
989
990   const Text::Length numberOfBoundedParagraphRuns = textEditorMultiAlignImpl.GetTextController()->GetTextModel()->GetNumberOfBoundedParagraphRuns();
991   DALI_TEST_EQUALS(numberOfBoundedParagraphRuns, expectedNumberOfBoundedParagraphRuns, TEST_LOCATION);
992
993   DALI_TEST_EQUALS(textEditorMultiAlignImpl.GetTextController()->GetTextModel()->GetNumberOfLines(), expectedNumberOfLines, TEST_LOCATION);
994   DALI_TEST_CHECK(textEditorMultiAlignImpl.GetTextController()->GetTextModel()->GetLines());
995
996   DALI_TEST_EQUALS(textEditorBeginAlignImpl.GetTextController()->GetTextModel()->GetNumberOfLines(), expectedNumberOfLines, TEST_LOCATION);
997   DALI_TEST_CHECK(textEditorBeginAlignImpl.GetTextController()->GetTextModel()->GetLines());
998
999   DALI_TEST_EQUALS(textEditorCenterAlignImpl.GetTextController()->GetTextModel()->GetNumberOfLines(), expectedNumberOfLines, TEST_LOCATION);
1000   DALI_TEST_CHECK(textEditorCenterAlignImpl.GetTextController()->GetTextModel()->GetLines());
1001
1002   DALI_TEST_EQUALS(textEditorEndAlignImpl.GetTextController()->GetTextModel()->GetNumberOfLines(), expectedNumberOfLines, TEST_LOCATION);
1003   DALI_TEST_CHECK(textEditorEndAlignImpl.GetTextController()->GetTextModel()->GetLines());
1004
1005   const uint32_t LINE_INDEX_ALIGN_END    = 1u;
1006   const uint32_t LINE_INDEX_ALIGN_CENTER = 3u;
1007   const uint32_t LINE_INDEX_ALIGN_BEGIN  = 5u;
1008   const uint32_t LINE_INDEX_OUTSIDE_1    = 0u;
1009   const uint32_t LINE_INDEX_OUTSIDE_2    = 2u;
1010   const uint32_t LINE_INDEX_OUTSIDE_3    = 4u;
1011   const uint32_t LINE_INDEX_PARAGRAPH    = 6u;
1012
1013   //<p align='end'>Paragraph end</p>
1014   const LineRun& lineEndFromMultiAlign = *(textEditorMultiAlignImpl.GetTextController()->GetTextModel()->GetLines() + LINE_INDEX_ALIGN_END);
1015   const LineRun& lineEndFromEndAlign   = *(textEditorEndAlignImpl.GetTextController()->GetTextModel()->GetLines() + LINE_INDEX_ALIGN_END);
1016   tet_infoline(" UtcDaliTextEditorMarkupParagraphTagAlignAttribute - <p align='end'>Paragraph end</p>");
1017   DALI_TEST_EQUALS(lineEndFromMultiAlign.alignmentOffset, lineEndFromEndAlign.alignmentOffset, TEST_LOCATION);
1018   DALI_TEST_EQUALS(lineEndFromMultiAlign.width, lineEndFromEndAlign.width, TEST_LOCATION);
1019
1020   //<p align='center'>Paragraph center</p>
1021   const LineRun& lineCenterFromMultiAlign = *(textEditorMultiAlignImpl.GetTextController()->GetTextModel()->GetLines() + LINE_INDEX_ALIGN_CENTER);
1022   const LineRun& lineEndFromCenterAlign   = *(textEditorCenterAlignImpl.GetTextController()->GetTextModel()->GetLines() + LINE_INDEX_ALIGN_CENTER);
1023   tet_infoline(" UtcDaliTextEditorMarkupParagraphTagAlignAttribute - <p align='center'>Paragraph center</p>");
1024   DALI_TEST_EQUALS(lineCenterFromMultiAlign.alignmentOffset, lineEndFromCenterAlign.alignmentOffset, TEST_LOCATION);
1025   DALI_TEST_EQUALS(lineCenterFromMultiAlign.width, lineEndFromCenterAlign.width, TEST_LOCATION);
1026
1027   //<p align='begin' >Paragraph begin</p>
1028   const LineRun& lineBeginFromMultiAlign = *(textEditorMultiAlignImpl.GetTextController()->GetTextModel()->GetLines() + LINE_INDEX_ALIGN_BEGIN);
1029   const LineRun& lineEndFromBeginAlign   = *(textEditorBeginAlignImpl.GetTextController()->GetTextModel()->GetLines() + LINE_INDEX_ALIGN_BEGIN);
1030   tet_infoline(" UtcDaliTextEditorMarkupParagraphTagAlignAttribute - <p align='begin' >Paragraph begin</p>");
1031   DALI_TEST_EQUALS(lineBeginFromMultiAlign.alignmentOffset, lineEndFromBeginAlign.alignmentOffset, TEST_LOCATION);
1032   DALI_TEST_EQUALS(lineBeginFromMultiAlign.width, lineEndFromBeginAlign.width, TEST_LOCATION);
1033
1034   //text outside
1035   const LineRun& lineOutsideOneFromMultiAlign  = *(textEditorMultiAlignImpl.GetTextController()->GetTextModel()->GetLines() + LINE_INDEX_OUTSIDE_1);
1036   const LineRun& lineOutsideOneFromCenterAlign = *(textEditorCenterAlignImpl.GetTextController()->GetTextModel()->GetLines() + LINE_INDEX_OUTSIDE_1);
1037   tet_infoline(" UtcDaliTextEditorMarkupParagraphTagAlignAttribute - text outside one");
1038   DALI_TEST_EQUALS(lineOutsideOneFromMultiAlign.alignmentOffset, lineOutsideOneFromCenterAlign.alignmentOffset, TEST_LOCATION);
1039   DALI_TEST_EQUALS(lineOutsideOneFromMultiAlign.width, lineOutsideOneFromCenterAlign.width, TEST_LOCATION);
1040
1041   const LineRun& lineOutsideTwoFromMultiAlign  = *(textEditorMultiAlignImpl.GetTextController()->GetTextModel()->GetLines() + LINE_INDEX_OUTSIDE_2);
1042   const LineRun& lineOutsideTwoFromCenterAlign = *(textEditorCenterAlignImpl.GetTextController()->GetTextModel()->GetLines() + LINE_INDEX_OUTSIDE_2);
1043   tet_infoline(" UtcDaliTextEditorMarkupParagraphTagAlignAttribute - text outside two");
1044   DALI_TEST_EQUALS(lineOutsideTwoFromMultiAlign.alignmentOffset, lineOutsideTwoFromCenterAlign.alignmentOffset, TEST_LOCATION);
1045   DALI_TEST_EQUALS(lineOutsideTwoFromMultiAlign.width, lineOutsideTwoFromCenterAlign.width, TEST_LOCATION);
1046
1047   const LineRun& lineOutsideThreeFromMultiAlign  = *(textEditorMultiAlignImpl.GetTextController()->GetTextModel()->GetLines() + LINE_INDEX_OUTSIDE_3);
1048   const LineRun& lineOutsideThreeFromCenterAlign = *(textEditorCenterAlignImpl.GetTextController()->GetTextModel()->GetLines() + LINE_INDEX_OUTSIDE_3);
1049   tet_infoline(" UtcDaliTextEditorMarkupParagraphTagAlignAttribute - text outside three");
1050   DALI_TEST_EQUALS(lineOutsideThreeFromMultiAlign.alignmentOffset, lineOutsideThreeFromCenterAlign.alignmentOffset, TEST_LOCATION);
1051   DALI_TEST_EQUALS(lineOutsideThreeFromMultiAlign.width, lineOutsideThreeFromCenterAlign.width, TEST_LOCATION);
1052
1053   const LineRun& lineParagraphFromMultiAlign  = *(textEditorMultiAlignImpl.GetTextController()->GetTextModel()->GetLines() + LINE_INDEX_PARAGRAPH);
1054   const LineRun& lineParagraphFromCenterAlign = *(textEditorCenterAlignImpl.GetTextController()->GetTextModel()->GetLines() + LINE_INDEX_PARAGRAPH);
1055   tet_infoline(" UtcDaliTextEditorMarkupParagraphTagAlignAttribute - <p>Paragraph property alignment</p>");
1056   DALI_TEST_EQUALS(lineParagraphFromMultiAlign.alignmentOffset, lineParagraphFromCenterAlign.alignmentOffset, TEST_LOCATION);
1057   DALI_TEST_EQUALS(lineParagraphFromMultiAlign.width, lineParagraphFromCenterAlign.width, TEST_LOCATION);
1058
1059   END_TEST;
1060 }