Merge "support strikethrough markup tag" into devel/master
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-toolkit-internal / utc-Dali-TextField-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-field-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 UtcDaliTextFieldMultipleBackgroundText(void)
34 {
35   ToolkitTestApplication application;
36   tet_infoline("UtcDaliTextFieldMultipleBackgroundText");
37
38   // Create a text field
39   TextField textField = TextField::New();
40   textField.SetProperty(Actor::Property::SIZE, Vector2(400.f, 60.f));
41   textField.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
42   textField.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
43
44   // Add the text field to the stage
45   application.GetScene().Add(textField);
46
47   application.SendNotification();
48   application.Render();
49
50   Toolkit::Internal::TextField& textFieldImpl  = GetImpl(textField);
51   ControllerPtr                 controller     = textFieldImpl.GetTextController();
52   Controller::Impl&             controllerImpl = Controller::Impl::GetImplementation(*controller.Get());
53
54   // Add multiple background colors for the text.
55   ColorRun backgroundColorRun1;
56   backgroundColorRun1.characterRun.characterIndex     = 0u;
57   backgroundColorRun1.characterRun.numberOfCharacters = 1u;
58   backgroundColorRun1.color                           = Color::RED;
59   controllerImpl.mModel->mLogicalModel->mBackgroundColorRuns.PushBack(backgroundColorRun1);
60
61   ColorRun backgroundColorRun2;
62   backgroundColorRun2.characterRun.characterIndex     = 5u;
63   backgroundColorRun2.characterRun.numberOfCharacters = 8u;
64   backgroundColorRun2.color                           = Color::CYAN;
65   controllerImpl.mModel->mLogicalModel->mBackgroundColorRuns.PushBack(backgroundColorRun2);
66
67   ColorRun backgroundColorRun3;
68   backgroundColorRun3.characterRun.characterIndex     = 23u;
69   backgroundColorRun3.characterRun.numberOfCharacters = 6u;
70   backgroundColorRun3.color                           = Color::GREEN;
71   controllerImpl.mModel->mLogicalModel->mBackgroundColorRuns.PushBack(backgroundColorRun3);
72
73   // Check the case where there is only one character in the text
74   controller->SetText("S");
75
76   application.SendNotification();
77   application.Render();
78
79   // The offscreen root actor should have one child: the renderable.
80   Actor stencil = textField.GetChildAt(0u);
81   DALI_TEST_CHECK(stencil.GetChildCount() == 1u);
82
83   // The renderable actor should have two children: the text and the background.
84   Actor renderableActor = stencil.GetChildAt(0u);
85   DALI_TEST_CHECK(renderableActor.GetChildCount() == 2u);
86
87   // Check that the background is created
88   Actor backgroundActor = renderableActor.GetChildAt(0u);
89   DALI_TEST_CHECK(backgroundActor);
90   DALI_TEST_CHECK(backgroundActor.GetProperty<std::string>(Dali::Actor::Property::NAME) == "TextBackgroundColorActor");
91
92   // Change the text to contain more characters
93   controller->SetText("Text Multiple Background Test");
94
95   application.SendNotification();
96   application.Render();
97
98   // Highlight the whole text
99   textFieldImpl.SelectWholeText();
100
101   application.SendNotification();
102   application.Render();
103
104   // Now the offscreen root actor should have three children: the renderable, the highlight, and the background.
105   DALI_TEST_CHECK(stencil.GetChildCount() == 3u);
106   // The renderable actor should have one child only: the text
107   DALI_TEST_CHECK(renderableActor.GetChildCount() == 1u);
108
109   // The background should now be lowered below the highlight
110   backgroundActor = stencil.GetChildAt(0u);
111   DALI_TEST_CHECK(backgroundActor);
112   DALI_TEST_CHECK(backgroundActor.GetProperty<std::string>(Dali::Actor::Property::NAME) == "TextBackgroundColorActor");
113
114   END_TEST;
115 }
116
117 int UtcDaliTextFieldSelectText(void)
118 {
119   ToolkitTestApplication application;
120   tet_infoline("UtcDaliTextFieldSelectText");
121
122   // Create a text field
123   TextField textField = TextField::New();
124   textField.SetProperty(Actor::Property::SIZE, Vector2(400.f, 60.f));
125   textField.SetProperty(TextField::Property::TEXT, "Hello World");
126
127   // Add the text field to the stage
128   application.GetScene().Add(textField);
129
130   application.SendNotification();
131   application.Render();
132
133   Toolkit::Internal::TextField& textFieldImpl = GetImpl(textField);
134
135   application.SendNotification();
136   application.Render();
137
138   // Highlight the whole text
139   textFieldImpl.SelectWholeText();
140
141   application.SendNotification();
142   application.Render();
143
144   DALI_TEST_CHECK(textFieldImpl.GetSelectedText() == "Hello World");
145
146   // Select None
147   textFieldImpl.SelectNone();
148
149   application.SendNotification();
150   application.Render();
151
152   DALI_TEST_CHECK(textFieldImpl.GetSelectedText() == "");
153
154   END_TEST;
155 }
156
157 int UtcDaliTextFieldMarkupUnderline(void)
158 {
159   ToolkitTestApplication application;
160   tet_infoline(" UtcDaliTextFieldMarkupUnderline ");
161
162   TextField textField = TextField::New();
163
164   application.GetScene().Add(textField);
165
166   textField.SetProperty(TextField::Property::TEXT, "<u>ABC</u>EF<u>GH</u>");
167   textField.SetProperty(TextField ::Property::ENABLE_MARKUP, true);
168
169   application.SendNotification();
170   application.Render();
171
172   uint32_t expectedNumberOfUnderlinedGlyphs = 5u;
173
174   Toolkit::Internal::TextField& textFieldImpl         = GetImpl(textField);
175   const Text::Length            numberOfUnderlineRuns = textFieldImpl.GetTextController()->GetTextModel()->GetNumberOfUnderlineRuns();
176
177   DALI_TEST_EQUALS(numberOfUnderlineRuns, expectedNumberOfUnderlinedGlyphs, TEST_LOCATION);
178
179   Vector<GlyphRun> underlineRuns;
180   underlineRuns.Resize(numberOfUnderlineRuns);
181   textFieldImpl.GetTextController()->GetTextModel()->GetUnderlineRuns(underlineRuns.Begin(), 0u, numberOfUnderlineRuns);
182
183   //ABC are underlined
184   DALI_TEST_EQUALS(underlineRuns[0u].glyphIndex, 0u, TEST_LOCATION);
185   DALI_TEST_EQUALS(underlineRuns[1u].glyphIndex, 1u, TEST_LOCATION);
186   DALI_TEST_EQUALS(underlineRuns[2u].glyphIndex, 2u, TEST_LOCATION);
187
188   //GH are underlined
189   DALI_TEST_EQUALS(underlineRuns[3u].glyphIndex, 5u, TEST_LOCATION);
190   DALI_TEST_EQUALS(underlineRuns[4u].glyphIndex, 6u, TEST_LOCATION);
191
192   END_TEST;
193 }
194
195 int UtcDaliTextFieldFontPointSizeLargerThanAtlas(void)
196 {
197   ToolkitTestApplication application;
198   tet_infoline(" UtcDaliTextFieldFontPointSizeLargerThanAtlas ");
199
200   // Create a Text field
201   TextField textField = TextField::New();
202   //Set size to avoid automatic eliding
203   textField.SetProperty(Actor::Property::SIZE, Vector2(1025, 1025));
204   //Set very large font-size using point-size
205   textField.SetProperty(TextField::Property::POINT_SIZE, 1000);
206   //Specify font-family
207   textField.SetProperty(TextField::Property::FONT_FAMILY, "DejaVu Sans");
208   //Set text to check if appear or not
209   textField.SetProperty(TextField::Property::TEXT, "A");
210
211   application.GetScene().Add(textField);
212
213   application.SendNotification();
214   application.Render();
215
216   //Check if Glyph is added to AtlasGlyphManger or not
217   int countAtlas = AtlasGlyphManager::Get().GetMetrics().mAtlasMetrics.mAtlasCount;
218   DALI_TEST_EQUALS(countAtlas, 1, TEST_LOCATION);
219
220   END_TEST;
221 }
222
223 int UtcDaliTextFieldFontPointSizeLargerThanAtlasPlaceholderCase(void)
224 {
225   ToolkitTestApplication application;
226   tet_infoline(" UtcDaliTextFieldFontPointSizeLargerThanAtlasPlaceholderCase ");
227
228   //Set Map of placeholder: text, font-family and point-size
229   Property::Map placeholderMapSet;
230   placeholderMapSet["text"]       = "A";
231   placeholderMapSet["fontFamily"] = "DejaVu Sans";
232   placeholderMapSet["pixelSize"]  = 1000.0f;
233
234   // Create a text editor
235   TextField textField = TextField::New();
236   //Set size to avoid automatic eliding
237   textField.SetProperty(Actor::Property::SIZE, Vector2(1025, 1025));
238   //Set placeholder
239   textField.SetProperty(TextField::Property::PLACEHOLDER, placeholderMapSet);
240
241   application.GetScene().Add(textField);
242
243   application.SendNotification();
244   application.Render();
245
246   //Check if Glyph is added to AtlasGlyphManger or not
247   int countAtlas = AtlasGlyphManager::Get().GetMetrics().mAtlasMetrics.mAtlasCount;
248   DALI_TEST_EQUALS(countAtlas, 1, TEST_LOCATION);
249
250   END_TEST;
251 }
252
253 int UtcDaliTextFieldBackgroundTag(void)
254 {
255   ToolkitTestApplication application;
256   tet_infoline("UtcDaliTextFieldBackgroundTag\n");
257
258   TextField field = TextField::New();
259   DALI_TEST_CHECK(field);
260
261   field.SetProperty(TextField ::Property::ENABLE_MARKUP, true);
262   field.SetProperty(TextField::Property::TEXT, "H<background color='red'>e</background> Worl<background color='yellow'>d</background>");
263   application.GetScene().Add(field);
264   application.SendNotification();
265   application.Render();
266
267   Toolkit::Internal::TextField& fieldImpl                    = GetImpl(field);
268   const ColorIndex* const       backgroundColorIndicesBuffer = fieldImpl.GetTextController()->GetTextModel()->GetBackgroundColorIndices();
269
270   DALI_TEST_CHECK(backgroundColorIndicesBuffer);
271
272   //default color
273   DALI_TEST_EQUALS(backgroundColorIndicesBuffer[0], 0u, TEST_LOCATION);
274
275   //red color
276   DALI_TEST_EQUALS(backgroundColorIndicesBuffer[1], 1u, TEST_LOCATION);
277
278   //yellow color
279   DALI_TEST_EQUALS(backgroundColorIndicesBuffer[7], 2u, TEST_LOCATION);
280
281   END_TEST;
282 }
283
284 int UtcDaliToolkitTextFieldEllipsisInternalAPIs(void)
285 {
286   ToolkitTestApplication application;
287   tet_infoline(" UtcDaliToolkitTextFieldEllipsisInternalAPIs ");
288   TextField textField = TextField::New();
289
290   Toolkit::Internal::TextField& textFieldImpl = GetImpl(textField);
291   Text::ViewInterface&          view          = textFieldImpl.GetTextController()->GetView();
292
293   tet_infoline(" UtcDaliToolkitTextFieldEllipsisInternalAPIs - ELLIPSIS Disabled");
294   textField.SetProperty(DevelTextField::Property::ELLIPSIS, false);
295   DALI_TEST_EQUALS(textField.GetProperty<bool>(DevelTextField::Property::ELLIPSIS), false, TEST_LOCATION);
296   DALI_TEST_CHECK(!(view.IsTextElideEnabled()));
297
298   tet_infoline(" UtcDaliToolkitTextFieldEllipsisInternalAPIs - ELLIPSIS Enabled");
299   textField.SetProperty(DevelTextField::Property::ELLIPSIS, true);
300   DALI_TEST_EQUALS(textField.GetProperty<bool>(DevelTextField::Property::ELLIPSIS), true, TEST_LOCATION);
301   DALI_TEST_CHECK(view.IsTextElideEnabled());
302
303   tet_infoline(" UtcDaliToolkitTextFieldEllipsisInternalAPIs - GetStartIndexOfElidedGlyphs Default");
304   DALI_TEST_EQUALS(view.GetStartIndexOfElidedGlyphs(), 0u, TEST_LOCATION);
305
306   tet_infoline(" UtcDaliToolkitTextFieldEllipsisInternalAPIs - GetEndIndexOfElidedGlyphs Default");
307   DALI_TEST_EQUALS(view.GetEndIndexOfElidedGlyphs(), 0u, TEST_LOCATION);
308
309   tet_infoline(" UtcDaliToolkitTextFieldEllipsisInternalAPIs - GetFirstMiddleIndexOfElidedGlyphs Default");
310   DALI_TEST_EQUALS(view.GetFirstMiddleIndexOfElidedGlyphs(), 0u, TEST_LOCATION);
311
312   tet_infoline(" UtcDaliToolkitTextFieldEllipsisInternalAPIs - GetSecondMiddleIndexOfElidedGlyphs Default");
313   DALI_TEST_EQUALS(view.GetSecondMiddleIndexOfElidedGlyphs(), 0u, TEST_LOCATION);
314
315   END_TEST;
316 }
317 int UtcDaliTextFieldTextWithSpan(void)
318 {
319   ToolkitTestApplication application;
320   tet_infoline("UtcDaliTextFieldTextWithSpan\n");
321
322   TextField field = TextField::New();
323   DALI_TEST_CHECK(field);
324
325   field.SetProperty(TextField ::Property::ENABLE_MARKUP, true);
326   field.SetProperty(TextField::Property::TEXT, "Hello Span");
327   application.GetScene().Add(field);
328
329   application.SendNotification();
330   application.Render();
331
332   Vector3 originalSize = field.GetNaturalSize();
333   field.SetProperty(TextField::Property::TEXT, "H<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red'>ello</span> Span");
334
335   application.SendNotification();
336   application.Render();
337
338   Vector3 spanSize = field.GetNaturalSize();
339
340   DALI_TEST_GREATER(spanSize.width, originalSize.width, TEST_LOCATION);
341
342   Toolkit::Internal::TextField& fieldImpl           = GetImpl(field);
343   const ColorIndex* const       colorIndicesBuffer1 = fieldImpl.GetTextController()->GetTextModel()->GetColorIndices();
344
345   DALI_TEST_CHECK(colorIndicesBuffer1);
346
347   //default color
348   DALI_TEST_EQUALS(colorIndicesBuffer1[0], 0u, TEST_LOCATION);
349
350   //span color
351   DALI_TEST_EQUALS(colorIndicesBuffer1[1], 1u, TEST_LOCATION);
352
353   //default color
354   DALI_TEST_EQUALS(colorIndicesBuffer1[6], 0u, TEST_LOCATION);
355
356   field.SetProperty(TextField::Property::TEXT, "<span font-size='45'>H</span>ello <span text-color='red'>S</span>pan");
357
358   application.SendNotification();
359   application.Render();
360
361   const ColorIndex* const colorIndicesBuffer2 = fieldImpl.GetTextController()->GetTextModel()->GetColorIndices();
362
363   DALI_TEST_CHECK(colorIndicesBuffer2);
364
365   //default color
366   DALI_TEST_EQUALS(colorIndicesBuffer2[0], 0u, TEST_LOCATION);
367
368   //default color
369   DALI_TEST_EQUALS(colorIndicesBuffer2[1], 0u, TEST_LOCATION);
370
371   //span color
372   DALI_TEST_EQUALS(colorIndicesBuffer2[6], 1u, TEST_LOCATION);
373
374   //default color
375   DALI_TEST_EQUALS(colorIndicesBuffer2[7], 0u, TEST_LOCATION);
376
377   END_TEST;
378 }
379
380 int UtcDaliTextFieldControlBackgroundColor(void)
381 {
382   ToolkitTestApplication application;
383   tet_infoline(" UtcDaliTextFieldControlBackgroundColor\n");
384
385   TextField field = TextField::New();
386   DALI_TEST_CHECK(field);
387
388   Vector4 backgroundColor;
389
390   field.SetProperty(TextField::Property::TEXT, "Background Color");
391   application.GetScene().Add(field);
392   application.SendNotification();
393   application.Render();
394
395   Toolkit::Internal::TextField& fieldImpl      = GetImpl(field);
396   ControllerPtr                 controller     = fieldImpl.GetTextController();
397   Controller::Impl&             controllerImpl = Controller::Impl::GetImplementation(*controller.Get());
398
399   // Default color is transparent
400   controllerImpl.mEditableControlInterface->GetControlBackgroundColor(backgroundColor);
401   DALI_TEST_EQUALS(backgroundColor, Color::TRANSPARENT, TEST_LOCATION);
402
403   // Set background color to red
404   field.SetBackgroundColor(Color::RED);
405   application.SendNotification();
406   application.Render();
407
408   // Should be red
409   controllerImpl.mEditableControlInterface->GetControlBackgroundColor(backgroundColor);
410   DALI_TEST_EQUALS(backgroundColor, Color::RED, TEST_LOCATION);
411
412   END_TEST;
413 }
414
415 int UtcDaliTextFieldMarkupStrikethrough(void)
416 {
417   ToolkitTestApplication application;
418   tet_infoline(" UtcDaliTextFieldMarkupStrikethrough ");
419
420   TextField textField = TextField::New();
421
422   application.GetScene().Add(textField);
423
424   textField.SetProperty(TextField::Property::TEXT, "<s>ABC</s>EF<s color='red'>GH</s>");
425   textField.SetProperty(TextField ::Property::ENABLE_MARKUP, true);
426
427   application.SendNotification();
428   application.Render();
429
430   uint32_t expectedNumberOfStrikethroughGlyphs = 2u;
431
432   Toolkit::Internal::TextField& textFieldImpl             = GetImpl(textField);
433   const Text::Length            numberOfStrikethroughRuns = textFieldImpl.GetTextController()->GetTextModel()->GetNumberOfStrikethroughRuns();
434
435   DALI_TEST_EQUALS(numberOfStrikethroughRuns, expectedNumberOfStrikethroughGlyphs, TEST_LOCATION);
436
437   Vector<StrikethroughGlyphRun> strikethroughRuns;
438   strikethroughRuns.Resize(numberOfStrikethroughRuns);
439   textFieldImpl.GetTextController()->GetTextModel()->GetStrikethroughRuns(strikethroughRuns.Begin(), 0u, numberOfStrikethroughRuns);
440
441   //ABC have strikethrough
442   DALI_TEST_EQUALS(strikethroughRuns[0u].glyphRun.glyphIndex, 0u, TEST_LOCATION);
443   DALI_TEST_EQUALS(strikethroughRuns[0u].glyphRun.numberOfGlyphs, 3u, TEST_LOCATION);
444   DALI_TEST_CHECK(!strikethroughRuns[0u].isColorSet);
445
446   //GH have strikethrough
447   DALI_TEST_EQUALS(strikethroughRuns[1u].glyphRun.glyphIndex, 5u, TEST_LOCATION);
448   DALI_TEST_EQUALS(strikethroughRuns[1u].glyphRun.numberOfGlyphs, 2u, TEST_LOCATION);
449   DALI_TEST_CHECK(strikethroughRuns[1u].isColorSet);
450
451   END_TEST;
452 }