Merge "Sync UTC harness" into devel/master
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-toolkit-internal / utc-Dali-Text-TextSpannable.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 <unistd.h>
20 #include <iostream>
21
22 #include <dali-toolkit-test-suite-utils.h>
23 #include <dali-toolkit/dali-toolkit.h>
24 #include <dali-toolkit/devel-api/controls/text-controls/text-spannable.h>
25 #include <dali-toolkit/devel-api/text/spannable-string.h>
26 #include <dali-toolkit/devel-api/text/spans/font-span.h>
27 #include <dali-toolkit/devel-api/text/spans/foreground-color-span.h>
28 #include <dali-toolkit/devel-api/text/spans/underline-span.h>
29 #include <dali-toolkit/devel-api/text/text-enumerations-devel.h>
30 #include <dali-toolkit/internal/controls/text-controls/text-editor-impl.h>
31 #include <dali-toolkit/internal/controls/text-controls/text-field-impl.h>
32 #include <dali-toolkit/internal/controls/text-controls/text-label-impl.h>
33 #include <dali-toolkit/internal/text/controller/text-controller.h>
34 #include <dali-toolkit/internal/text/font-description-run.h>
35 #include <dali-toolkit/internal/text/rendering/text-typesetter.h>
36 #include <dali-toolkit/internal/text/rendering/view-model.h>
37 #include <dali-toolkit/internal/text/text-view.h>
38 #include <dali-toolkit/public-api/text/text-enumerations.h>
39 #include <toolkit-text-utils.h>
40 #include <dali-toolkit/devel-api/text/spans/character-spacing-span.h>
41
42
43 using namespace Dali;
44 using namespace Toolkit;
45
46 namespace
47 {
48 const std::string DEFAULT_FONT_DIR("/resources/fonts");
49 const float       PIXEL_FORMAT_64_FACTOR = 64.f; ///< 64.f is used to convert from point size to 26.6 pixel format.
50 } // namespace
51
52 Text::SpannableString CreateSpannableStringForForegroundColorSpan()
53 {
54   Text::SpannableString spannableString = Text::SpannableString::New("Hello مرحبا");
55   DALI_TEST_CHECK(spannableString);
56
57   auto isAddedGreen = spannableString.AttachSpan(
58     Text::ForegroundColorSpan::New(Color::GREEN),
59     Text::Range::New(5u, 7u));
60   DALI_TEST_CHECK(isAddedGreen);
61
62   return spannableString;
63 }
64
65 Text::SpannableString CreateSpannableStringForFontSpan()
66 {
67   Text::SpannableString spannableString = Text::SpannableString::New("Hello World");
68   DALI_TEST_CHECK(spannableString);
69
70   auto isAddedFontSpan = spannableString.AttachSpan(
71     Text::FontSpan::New("TizenSans",
72                         45.0f,
73                         Dali::TextAbstraction::FontWeight::BOLD,
74                         Dali::TextAbstraction::FontWidth::SEMI_CONDENSED,
75                         Dali::TextAbstraction::FontSlant::OBLIQUE),
76     Text::Range::New(5u, 7u));
77   DALI_TEST_CHECK(isAddedFontSpan);
78
79   return spannableString;
80 }
81
82 Text::SpannableString CreateSpannableStringForUnderlineSpan()
83 {
84   Text::SpannableString spannableString = Text::SpannableString::New("Hello World");
85   DALI_TEST_CHECK(spannableString);
86
87   auto isAddedUnderlineSpan = spannableString.AttachSpan(
88     Text::UnderlineSpan::NewDashed(Color::GREEN, 5.0f, 2.0f, 3.0f),
89     Text::Range::New(5u, 7u));
90   DALI_TEST_CHECK(isAddedUnderlineSpan);
91
92   return spannableString;
93 }
94
95 Text::SpannableString CreateSpannableStringForCharacterSpacing()
96 {
97   Text::SpannableString spannableString = Text::SpannableString::New("Hello World");
98   DALI_TEST_CHECK(spannableString);
99
100   auto isCharacterSpacingSpan = spannableString.AttachSpan(
101   Text::CharacterSpacingSpan::New(5.2f),
102   Text::Range::New(5u, 7u));
103   DALI_TEST_CHECK(isCharacterSpacingSpan);
104
105   return spannableString;
106 }
107
108 void CheckColorIndices(const Text::ColorIndex* const colorIndicesBuffer,
109                        uint32_t                      numberOfIndices,
110                        std::vector<uint32_t>         indicesToCheck,
111                        std::vector<uint32_t>         expectedValues)
112 {
113   DALI_TEST_CHECK(colorIndicesBuffer);
114
115   for(uint32_t i = 0u; i < numberOfIndices; i++)
116   {
117     DALI_TEST_EQUALS(colorIndicesBuffer[indicesToCheck[i]], expectedValues[i], TEST_LOCATION);
118   }
119 }
120
121 int UtcDaliToolkitTextLabelSetSpannedText(void)
122 {
123   ToolkitTestApplication application;
124   tet_infoline(" UtcDaliToolkitTextLabelSetSpannedText");
125
126   TextLabel textLabel = TextLabel::New();
127   DALI_TEST_CHECK(textLabel);
128   application.GetScene().Add(textLabel);
129
130   Text::SpannableString spannableString = CreateSpannableStringForForegroundColorSpan();
131
132   Text::SetSpannedText(textLabel, spannableString);
133
134   application.SendNotification();
135   application.Render();
136
137   Toolkit::Internal::TextLabel& labelImpl          = GetImpl(textLabel);
138   const Text::ColorIndex* const colorIndicesBuffer = labelImpl.GetTextController()->GetTextModel()->GetColorIndices();
139
140   CheckColorIndices(colorIndicesBuffer, 4u, {0u, 5u, 7u, 10u}, {0u, 1u, 1u, 0u});
141
142   END_TEST;
143 }
144
145 int UtcDaliToolkitTextEditorSetSpannedText(void)
146 {
147   ToolkitTestApplication application;
148   tet_infoline(" UtcDaliToolkitTextEditorSetSpannedText");
149
150   TextEditor textEditor = TextEditor::New();
151   DALI_TEST_CHECK(textEditor);
152   application.GetScene().Add(textEditor);
153
154   Text::SpannableString spannableString = CreateSpannableStringForForegroundColorSpan();
155
156   Text::SetSpannedText(textEditor, spannableString);
157
158   application.SendNotification();
159   application.Render();
160
161   Toolkit::Internal::TextEditor& labelImpl          = GetImpl(textEditor);
162   const Text::ColorIndex* const  colorIndicesBuffer = labelImpl.GetTextController()->GetTextModel()->GetColorIndices();
163
164   CheckColorIndices(colorIndicesBuffer, 4u, {0u, 5u, 7u, 10u}, {0u, 1u, 1u, 0u});
165
166   END_TEST;
167 }
168
169 int UtcDaliToolkitTextFieldSetSpannedText(void)
170 {
171   ToolkitTestApplication application;
172   tet_infoline(" UtcDaliToolkitTextFieldSetSpannedText");
173
174   TextField textField = TextField::New();
175   DALI_TEST_CHECK(textField);
176   application.GetScene().Add(textField);
177
178   Text::SpannableString spannableString = CreateSpannableStringForForegroundColorSpan();
179
180   Text::SetSpannedText(textField, spannableString);
181
182   application.SendNotification();
183   application.Render();
184
185   Toolkit::Internal::TextField& labelImpl          = GetImpl(textField);
186   const Text::ColorIndex* const colorIndicesBuffer = labelImpl.GetTextController()->GetTextModel()->GetColorIndices();
187
188   CheckColorIndices(colorIndicesBuffer, 4u, {0u, 5u, 7u, 10u}, {0u, 1u, 1u, 0u});
189
190   END_TEST;
191 }
192
193 int UtcDaliToolkitTextLabelSetSpannedText_FontSpan(void)
194 {
195   ToolkitTestApplication application;
196   tet_infoline(" UtcDaliToolkitTextLabelSetSpannedText_FontSpan ");
197
198   // Load some fonts to get the same metrics on different platforms.
199   TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
200   fontClient.SetDpi(96u, 96u);
201
202   char*             pathNamePtr = get_current_dir_name();
203   const std::string pathName(pathNamePtr);
204   free(pathNamePtr);
205
206   fontClient.GetFontId(pathName + DEFAULT_FONT_DIR + "/tizen/TizenSansRegular.ttf");
207
208   TextLabel textLabel = TextLabel::New();
209   DALI_TEST_CHECK(textLabel);
210   application.GetScene().Add(textLabel);
211
212   Text::SpannableString spannableString = CreateSpannableStringForFontSpan();
213
214   Text::SetSpannedText(textLabel, spannableString);
215
216   application.SendNotification();
217   application.Render();
218
219   Toolkit::Internal::TextLabel&               labelImpl     = GetImpl(textLabel);
220   const Vector<Dali::Toolkit::Text::FontRun>& validFontRuns = labelImpl.GetTextController()->GetTextModel()->GetFontRuns();
221
222   DALI_TEST_EQUALS(validFontRuns.Count(), 3u, TEST_LOCATION);
223
224   DALI_TEST_EQUALS(validFontRuns[0].fontId, validFontRuns[2].fontId, TEST_LOCATION);
225   DALI_TEST_NOT_EQUALS(validFontRuns[0].fontId, validFontRuns[1].fontId, Math::MACHINE_EPSILON_100, TEST_LOCATION);
226
227   DALI_TEST_EQUALS(validFontRuns[1].characterRun.characterIndex, 5u, TEST_LOCATION);
228   DALI_TEST_EQUALS(validFontRuns[1].characterRun.GetEndCharacterIndex(), 7u, TEST_LOCATION);
229   DALI_TEST_EQUALS(validFontRuns[1].isItalicRequired, true, TEST_LOCATION);
230   DALI_TEST_EQUALS(validFontRuns[1].isBoldRequired, true, TEST_LOCATION);
231
232   TextAbstraction::FontDescription spanFontDescription;
233
234   float expectedPointSize = 45.0f * PIXEL_FORMAT_64_FACTOR;
235   float fontPointSize     = fontClient.GetPointSize(validFontRuns[1].fontId);
236   DALI_TEST_EQUALS(fontPointSize, expectedPointSize, TEST_LOCATION);
237
238   const Vector<Dali::Toolkit::Text::FontDescriptionRun>& validFontDescriptionRuns = labelImpl.GetTextController()->GetTextModel()->GetFontDescriptionRuns();
239   DALI_TEST_EQUALS(validFontDescriptionRuns.Count(), 1u, TEST_LOCATION);
240   std::string familyName = validFontDescriptionRuns[0].familyName;
241
242   DALI_TEST_EQUALS(familyName, "TizenSans", TEST_LOCATION);
243   DALI_TEST_EQUALS(validFontDescriptionRuns[0].size, expectedPointSize, TEST_LOCATION);
244   DALI_TEST_EQUALS(validFontDescriptionRuns[0].weight, Dali::TextAbstraction::FontWeight::BOLD, TEST_LOCATION);
245   DALI_TEST_EQUALS(validFontDescriptionRuns[0].width, Dali::TextAbstraction::FontWidth::SEMI_CONDENSED, TEST_LOCATION);
246   DALI_TEST_EQUALS(validFontDescriptionRuns[0].slant, Dali::TextAbstraction::FontSlant::OBLIQUE, TEST_LOCATION);
247
248   END_TEST;
249 }
250
251 int UtcDaliTextModelIsSpannedTextPlaced(void)
252
253 {
254   tet_infoline(" UtcDaliTextModelIsSpannedTextPlaced");
255
256   ToolkitTestApplication application;
257
258   // Create spanned-text and set it
259   Text::SpannableString spannedText = Text::SpannableString::New("Hello مرحبا");
260   DALI_TEST_CHECK(spannedText);
261
262   // Creates a text controller.
263   Dali::Toolkit::Text::ControllerPtr         controllerTextEditor = Dali::Toolkit::Text::Controller::New();
264   const Dali::Toolkit::Text::ModelInterface* modelEditor          = controllerTextEditor->GetTextModel();
265
266   // Tests the rendering controller has been created.
267   Dali::Toolkit::Text::TypesetterPtr typesetterEditor = Dali::Toolkit::Text::Typesetter::New(controllerTextEditor->GetTextModel());
268   DALI_TEST_CHECK(typesetterEditor);
269
270   // Tests the view model has been created.
271   Dali::Toolkit::Text::ViewModel* viewModelEditor = typesetterEditor->GetViewModel();
272   DALI_TEST_CHECK(viewModelEditor);
273
274   // Configures the text controller similarly to the text-editor.
275   Dali::Toolkit::Text::ConfigureTextEditor(controllerTextEditor);
276
277   DALI_TEST_EQUALS(false, modelEditor->IsSpannedTextPlaced(), TEST_LOCATION);
278   DALI_TEST_EQUALS(false, viewModelEditor->IsSpannedTextPlaced(), TEST_LOCATION);
279
280   controllerTextEditor->SetSpannedText(spannedText);
281
282   DALI_TEST_EQUALS(true, modelEditor->IsSpannedTextPlaced(), TEST_LOCATION);
283   DALI_TEST_EQUALS(true, viewModelEditor->IsSpannedTextPlaced(), TEST_LOCATION);
284
285   // Creates a text controller.
286   Dali::Toolkit::Text::ControllerPtr         controllerTextLabel = Dali::Toolkit::Text::Controller::New();
287   const Dali::Toolkit::Text::ModelInterface* modelLabel          = controllerTextLabel->GetTextModel();
288
289   // Tests the rendering controller has been created.
290   Dali::Toolkit::Text::TypesetterPtr typesetterLabel = Dali::Toolkit::Text::Typesetter::New(controllerTextLabel->GetTextModel());
291   DALI_TEST_CHECK(typesetterLabel);
292
293   // Tests the view model has been created.
294   Dali::Toolkit::Text::ViewModel* viewModelLabel = typesetterLabel->GetViewModel();
295   DALI_TEST_CHECK(viewModelLabel);
296
297   // Configures the text controller similarly to the text-label.
298   Dali::Toolkit::Text::ConfigureTextLabel(controllerTextLabel);
299
300   DALI_TEST_EQUALS(false, modelLabel->IsSpannedTextPlaced(), TEST_LOCATION);
301   DALI_TEST_EQUALS(false, viewModelLabel->IsSpannedTextPlaced(), TEST_LOCATION);
302
303   controllerTextLabel->SetSpannedText(spannedText);
304
305   DALI_TEST_EQUALS(true, modelLabel->IsSpannedTextPlaced(), TEST_LOCATION);
306   DALI_TEST_EQUALS(true, viewModelLabel->IsSpannedTextPlaced(), TEST_LOCATION);
307
308   // Creates a text controller.
309   Dali::Toolkit::Text::ControllerPtr         controllerTextField = Dali::Toolkit::Text::Controller::New();
310   const Dali::Toolkit::Text::ModelInterface* modelField          = controllerTextField->GetTextModel();
311
312   // Tests the rendering controller has been created.
313   Dali::Toolkit::Text::TypesetterPtr typesetterField = Dali::Toolkit::Text::Typesetter::New(controllerTextField->GetTextModel());
314   DALI_TEST_CHECK(typesetterField);
315
316   // Tests the view model has been created.
317   Dali::Toolkit::Text::ViewModel* viewModelField = typesetterField->GetViewModel();
318   DALI_TEST_CHECK(viewModelField);
319
320   // Configures the text controller similarly to the text-field.
321   Dali::Toolkit::Text::ConfigureTextField(controllerTextField);
322
323   DALI_TEST_EQUALS(false, modelField->IsSpannedTextPlaced(), TEST_LOCATION);
324   DALI_TEST_EQUALS(false, viewModelField->IsSpannedTextPlaced(), TEST_LOCATION);
325
326   controllerTextField->SetSpannedText(spannedText);
327
328   DALI_TEST_EQUALS(true, modelField->IsSpannedTextPlaced(), TEST_LOCATION);
329   DALI_TEST_EQUALS(true, viewModelField->IsSpannedTextPlaced(), TEST_LOCATION);
330
331   tet_result(TET_PASS);
332
333   END_TEST;
334 }
335
336 int UtcDaliToolkitTextLabelSetSpannedText_UnderlineSpan(void)
337 {
338   ToolkitTestApplication application;
339   tet_infoline(" UtcDaliToolkitTextLabelSetSpannedText_UnderlineSpan ");
340
341   Dali::Toolkit::Text::UnderlineStyleProperties expectedProperties = {
342     Text::Underline::DASHED,
343     Color::GREEN,
344     5u,
345     2u,
346     3u,
347     true,
348     true,
349     true,
350     true,
351     true};
352
353   TextLabel textLabel = TextLabel::New();
354   DALI_TEST_CHECK(textLabel);
355   application.GetScene().Add(textLabel);
356
357   Text::SpannableString spannableString = CreateSpannableStringForUnderlineSpan();
358
359   Text::SetSpannedText(textLabel, spannableString);
360
361   application.SendNotification();
362   application.Render();
363
364   Toolkit::Internal::TextLabel& labelImpl             = GetImpl(textLabel);
365   const Text::Length            numberOfUnderlineRuns = labelImpl.GetTextController()->GetTextModel()->GetNumberOfUnderlineRuns();
366
367   DALI_TEST_EQUALS(numberOfUnderlineRuns, 1u, TEST_LOCATION);
368
369   Vector<Dali::Toolkit::Text::UnderlinedGlyphRun> underlineRuns;
370
371   underlineRuns.Resize(numberOfUnderlineRuns);
372
373   labelImpl.GetTextController()->GetTextModel()->GetUnderlineRuns(underlineRuns.Begin(), 0u, numberOfUnderlineRuns);
374
375   DALI_TEST_EQUALS(underlineRuns[0].glyphRun.glyphIndex, 5u, TEST_LOCATION);
376   DALI_TEST_EQUALS(underlineRuns[0].glyphRun.numberOfGlyphs, 3u, TEST_LOCATION);
377   DALI_TEST_CHECK(underlineRuns[0].properties == expectedProperties);
378
379   END_TEST;
380 }
381
382 int UtcDaliToolkitTextLabelSetSpannedText_CharacterSpacingSpan(void)
383 {
384   ToolkitTestApplication application;
385   tet_infoline("UtcDaliToolkitTextLabelSetSpannedText_CharacterSpacingSpan");
386
387   TextLabel textLabel = TextLabel::New();
388   DALI_TEST_CHECK(textLabel);
389   application.GetScene().Add(textLabel);
390
391   Text::SpannableString spannableString = CreateSpannableStringForCharacterSpacing();
392   Text::SetSpannedText(textLabel, spannableString);
393
394   application.SendNotification();
395   application.Render();
396
397   Toolkit::Internal::TextLabel& labelImpl   = GetImpl(textLabel);
398   const Vector<Dali::Toolkit::Text::CharacterSpacingGlyphRun> characterSpacing = labelImpl.GetTextController()->GetTextModel()->GetCharacterSpacingGlyphRuns();
399   DALI_TEST_EQUALS(1, characterSpacing.Count(), TEST_LOCATION);
400   END_TEST;
401 }