[dali_2.3.21] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-toolkit-internal / utc-Dali-Text-ViewModel.cpp
1 /*
2  * Copyright (c) 2023 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/text/spannable-string.h>
25 #include <dali-toolkit/internal/text/controller/text-controller.h>
26 #include <dali-toolkit/internal/text/font-description-run.h>
27 #include <dali-toolkit/internal/text/rendering/text-typesetter.h>
28 #include <dali-toolkit/internal/text/rendering/view-model.h>
29 #include <toolkit-text-utils.h>
30
31 using namespace Dali;
32 using namespace Toolkit;
33 using namespace Text;
34
35 namespace
36 {
37 const std::string DEFAULT_FONT_DIR("/resources/fonts");
38
39 const Size  CONTROL_SIZE(200.f, 400.f);
40 const Size  CONTROL_SMALL_SIZE(50.f, 100.f);
41 const char* LOREM_IPSUM =
42   "Lorem ipsum dolor sit amet, aeque definiebas ea mei, posse iracundia ne cum.\n"
43   "Usu ne nisl maiorum iudicabit, veniam epicurei oporteat eos an.\n"
44   "Ne nec nulla regione albucius, mea doctus delenit ad!\n"
45   "Et everti blandit adversarium mei, eam porro neglegentur suscipiantur an.\n"
46   "Quidam corpora at duo. An eos possim scripserit?\n\n"
47   "Aťqui dicant sěnťenťíae aň vel!\n"
48   "Vis viris médiocrem elaboraret ét, verear civibus moderatius ex duo!\n"
49   "Án veri laborě iňtěgré quó, mei aď poššit lobortis, mei prompťa čonsťitůťó eů.\n"
50   "Aliquip sanctůs delicáta quí ěá, et natum aliquam est?\n"
51   "Asšúm sapěret usu ůť.\n"
52   "Síť ut apeirián laboramúš percipitur, sůas hařum ín éos?\n";
53 const Vector2 LOREM_SCROLL_POSITION(0.f, -265.f);
54 const Length  LOREM_NUMBER_OF_LINES             = 35u;
55 const Length  LOREM_NUMBER_OF_LINES_ELIDED      = 21u;
56 const Length  LOREM_NUMBER_OF_GLYPHS            = 632u;
57 const Length  LOREM_NUMBER_OF_GLYPHS_ELIDED     = 393u;
58 const Length  LOREM_NUMBER_OF_CHARACTERS        = 633u;
59 const Length  LOREM_NUMBER_OF_CHARACTERS_ELIDED = 633u;
60
61 // The expected layout size for UtcDaliTextViewModelGetLayoutSize
62 const Size LAYOUT_SIZE(182.f, 48.f);
63
64 // The expected color indices for UtcDaliTextViewModelGetColors
65 const ColorIndex COLOR_INDICES[]  = {0u, 0u, 0u, 0u, 0u, 0u, 1u, 1u, 1u, 2u, 2u, 2u, 2u, 2u, 1u, 1u, 1u, 1u, 1u, 3u, 1u, 1u, 1u, 0u, 0u, 0u, 0u};
66 const Length     NUMBER_OF_COLORS = 3u;
67 const Vector4    COLORS[]         = {Color::RED, Color::BLUE, Color::GREEN};
68
69 struct ElideData
70 {
71   std::string  description;
72   std::string  text;
73   Vector2      size;
74   unsigned int numberOfLines;
75   unsigned int numberOfGlyphs;
76   float*       positions;
77 };
78
79 bool ElideTest(const ElideData& data)
80 {
81   std::cout << "  testing : " << data.description << std::endl;
82
83   // Load some fonts.
84   TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
85   fontClient.SetDpi(93u, 93u);
86
87   char*             pathNamePtr = get_current_dir_name();
88   const std::string pathName(pathNamePtr);
89   free(pathNamePtr);
90
91   fontClient.GetFontId(pathName + DEFAULT_FONT_DIR + "/tizen/TizenSansRegular.ttf");
92   fontClient.GetFontId(pathName + DEFAULT_FONT_DIR + "/tizen/TizenSansHebrewRegular.ttf");
93   fontClient.GetFontId(pathName + DEFAULT_FONT_DIR + "/tizen/TizenSansArabicRegular.ttf");
94
95   // Creates a text controller.
96   ControllerPtr controller = Controller::New();
97
98   // Tests the rendering controller has been created.
99   TypesetterPtr typesetter = Typesetter::New(controller->GetTextModel());
100   DALI_TEST_CHECK(typesetter);
101
102   // Tests the view model has been created.
103   ViewModel* model = typesetter->GetViewModel();
104   DALI_TEST_CHECK(NULL != model);
105
106   // Configures the text controller similarly to the text-label.
107   ConfigureTextLabel(controller);
108
109   // Sets a text and relais-out.
110   controller->SetMarkupProcessorEnabled(true);
111
112   controller->SetText(data.text);
113   controller->Relayout(data.size);
114
115   // Elide the glyphs.
116   model->ElideGlyphs();
117
118   if(data.numberOfLines != model->GetNumberOfLines())
119   {
120     std::cout << "  different number of lines : " << model->GetNumberOfLines() << ", expected : " << data.numberOfLines << std::endl;
121     return false;
122   }
123
124   if(data.numberOfGlyphs != model->GetNumberOfGlyphs())
125   {
126     std::cout << "  different number of glyphs : " << model->GetNumberOfGlyphs() << ", expected : " << data.numberOfGlyphs << std::endl;
127     return false;
128   }
129
130   const Vector2* const layoutBuffer  = model->GetLayout();
131   const Length         numberOfLines = model->GetNumberOfLines();
132
133   if(numberOfLines != 0u)
134   {
135     const LineRun& lastLine               = *(model->GetLines() + numberOfLines - 1u);
136     const Length   numberOfLastLineGlyphs = data.numberOfGlyphs - lastLine.glyphRun.glyphIndex;
137
138     std::cout << "  last line alignment offset : " << floor(lastLine.alignmentOffset) << std::endl;
139
140     for(unsigned int index = 0u; index < numberOfLastLineGlyphs; ++index)
141     {
142       if(*(data.positions + index) != floor(lastLine.alignmentOffset + (*(layoutBuffer + lastLine.glyphRun.glyphIndex + index)).x))
143       {
144         std::cout << "  different layout :";
145         for(unsigned int i = 0; i < numberOfLastLineGlyphs; ++i)
146         {
147           std::cout << " " << floor(lastLine.alignmentOffset + (*(layoutBuffer + lastLine.glyphRun.glyphIndex + i)).x);
148         }
149         std::cout << std::endl;
150         std::cout << "          expected :";
151         for(unsigned int i = 0; i < numberOfLastLineGlyphs; ++i)
152         {
153           std::cout << " " << *(data.positions + i);
154         }
155         std::cout << std::endl;
156         return false;
157       }
158     }
159   }
160
161   return true;
162 }
163
164 } // namespace
165
166 int UtcDaliTextViewModel(void)
167 {
168   tet_infoline(" UtcDaliTextViewModel");
169   ToolkitTestApplication application;
170
171   // Creates a text controller.
172   ControllerPtr controller = Controller::New();
173
174   // Tests the rendering controller has been created.
175   TypesetterPtr typesetter = Typesetter::New(controller->GetTextModel());
176   DALI_TEST_CHECK(typesetter);
177
178   // Tests the view model has been created.
179   ViewModel* model = typesetter->GetViewModel();
180   DALI_TEST_CHECK(NULL != model);
181
182   tet_result(TET_PASS);
183   END_TEST;
184 }
185
186 int UtcDaliTextViewModelGetControlSize(void)
187 {
188   tet_infoline(" UtcDaliTextViewModelGetControlSize");
189   ToolkitTestApplication application;
190
191   // Creates a text controller.
192   ControllerPtr controller = Controller::New();
193
194   // Tests the rendering controller has been created.
195   TypesetterPtr typesetter = Typesetter::New(controller->GetTextModel());
196   DALI_TEST_CHECK(typesetter);
197
198   // Tests the view model has been created.
199   ViewModel* model = typesetter->GetViewModel();
200   DALI_TEST_CHECK(NULL != model);
201
202   // Configures the text controller similarly to the text-editor.
203   ConfigureTextEditor(controller);
204
205   // The text has not been laid-out. The stored control's size should be zero.
206   DALI_TEST_EQUALS(Size::ZERO, model->GetControlSize(), TEST_LOCATION);
207
208   // Sets a text and relais-out.
209   controller->SetText("Hello world");
210   controller->Relayout(CONTROL_SIZE);
211
212   // The control's size should be stored now.
213   DALI_TEST_EQUALS(CONTROL_SIZE, model->GetControlSize(), TEST_LOCATION);
214
215   tet_result(TET_PASS);
216   END_TEST;
217 }
218
219 int UtcDaliTextViewModelGetLayoutSize(void)
220 {
221   tet_infoline(" UtcDaliTextViewModelGetLayoutSize");
222   ToolkitTestApplication application;
223
224   // Load some fonts.
225   TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
226   fontClient.SetDpi(93u, 93u);
227
228   char*             pathNamePtr = get_current_dir_name();
229   const std::string pathName(pathNamePtr);
230   free(pathNamePtr);
231
232   fontClient.GetFontId(pathName + DEFAULT_FONT_DIR + "/tizen/TizenSansRegular.ttf");
233
234   // Creates a text controller.
235   ControllerPtr controller = Controller::New();
236
237   // Tests the rendering controller has been created.
238   TypesetterPtr typesetter = Typesetter::New(controller->GetTextModel());
239   DALI_TEST_CHECK(typesetter);
240
241   // Tests the view model has been created.
242   ViewModel* model = typesetter->GetViewModel();
243   DALI_TEST_CHECK(NULL != model);
244
245   // Configures the text controller similarly to the text-editor.
246   ConfigureTextEditor(controller);
247
248   // The text has not been laid-out. The stored control's size should be zero.
249   DALI_TEST_EQUALS(Size::ZERO, model->GetLayoutSize(), TEST_LOCATION);
250
251   // Sets a text and relais-out.
252   controller->SetMarkupProcessorEnabled(true);
253   controller->SetText("<font family='TizenSansRegular' size='10'>Lorem ipsum dolor sit amet, aeque definiebas ea mei, posse iracundia ne cum.</font>");
254   controller->Relayout(CONTROL_SIZE);
255
256   // The control's size should be stored now.
257   DALI_TEST_EQUALS(LAYOUT_SIZE, model->GetLayoutSize(), TEST_LOCATION);
258
259   tet_result(TET_PASS);
260   END_TEST;
261 }
262
263 int UtcDaliTextViewModelGetScrollPosition(void)
264 {
265   tet_infoline(" UtcDaliTextViewModelGetScrollPosition");
266   ToolkitTestApplication application;
267
268   // Creates a text controller.
269   ControllerPtr controller = Controller::New();
270
271   // Tests the rendering controller has been created.
272   TypesetterPtr typesetter = Typesetter::New(controller->GetTextModel());
273   DALI_TEST_CHECK(typesetter);
274
275   // Tests the view model has been created.
276   ViewModel* model = typesetter->GetViewModel();
277   DALI_TEST_CHECK(NULL != model);
278
279   // Configures the text controller similarly to the text-editor.
280   ConfigureTextEditor(controller);
281
282   // No text has been set. The scroll position should be zero.
283   DALI_TEST_EQUALS(Vector2::ZERO, model->GetScrollPosition(), TEST_LOCATION);
284
285   // Gains the keyboard focus, sets a big text and relais-out.
286   controller->KeyboardFocusGainEvent();
287   controller->SetText(LOREM_IPSUM);
288   controller->Relayout(CONTROL_SIZE);
289
290   // The text should be scrolled to the end.
291   DALI_TEST_EQUALS(LOREM_SCROLL_POSITION, model->GetScrollPosition(), TEST_LOCATION);
292
293   tet_result(TET_PASS);
294   END_TEST;
295 }
296
297 int UtcDaliTextViewModelGetAlignment(void)
298 {
299   tet_infoline(" UtcDaliTextViewModelGetAlignment");
300   ToolkitTestApplication application;
301
302   // Creates a text controller.
303   ControllerPtr controller = Controller::New();
304
305   // Tests the rendering controller has been created.
306   TypesetterPtr typesetter = Typesetter::New(controller->GetTextModel());
307   DALI_TEST_CHECK(typesetter);
308
309   // Tests the view model has been created.
310   ViewModel* model = typesetter->GetViewModel();
311   DALI_TEST_CHECK(NULL != model);
312
313   DALI_TEST_EQUALS(Text::HorizontalAlignment::BEGIN, model->GetHorizontalAlignment(), TEST_LOCATION);
314   DALI_TEST_EQUALS(Text::VerticalAlignment::TOP, model->GetVerticalAlignment(), TEST_LOCATION);
315
316   controller->SetHorizontalAlignment(Text::HorizontalAlignment::CENTER);
317   controller->SetVerticalAlignment(Text::VerticalAlignment::CENTER);
318
319   DALI_TEST_EQUALS(Text::HorizontalAlignment::CENTER, model->GetHorizontalAlignment(), TEST_LOCATION);
320   DALI_TEST_EQUALS(Text::VerticalAlignment::CENTER, model->GetVerticalAlignment(), TEST_LOCATION);
321
322   tet_result(TET_PASS);
323   END_TEST;
324 }
325
326 int UtcDaliTextViewModelIsTextElideEnabled(void)
327 {
328   tet_infoline(" UtcDaliTextViewModelIsTextElideEnabled");
329   ToolkitTestApplication application;
330
331   // Creates a text controller.
332   ControllerPtr controller = Controller::New();
333
334   // Tests the rendering controller has been created.
335   TypesetterPtr typesetter = Typesetter::New(controller->GetTextModel());
336   DALI_TEST_CHECK(typesetter);
337
338   // Tests the view model has been created.
339   ViewModel* model = typesetter->GetViewModel();
340   DALI_TEST_CHECK(NULL != model);
341
342   // Configures the text controller similarly to the text-editor.
343   ConfigureTextEditor(controller);
344
345   // Elide text should be disabled.
346   DALI_TEST_CHECK(!model->IsTextElideEnabled());
347
348   // Configures the text controller similarly to the text-label.
349   ConfigureTextLabel(controller);
350
351   // Elide text should be enabled.
352   DALI_TEST_CHECK(model->IsTextElideEnabled());
353
354   tet_result(TET_PASS);
355   END_TEST;
356 }
357
358 int UtcDaliTextViewModelGetCharacters(void)
359 {
360   tet_infoline(" UtcDaliTextViewModelGetLines");
361   ToolkitTestApplication application;
362
363   // Creates a text controller.
364   ControllerPtr controller = Controller::New();
365
366   // Tests the rendering controller has been created.
367   TypesetterPtr typesetter = Typesetter::New(controller->GetTextModel());
368   DALI_TEST_CHECK(typesetter);
369
370   // Tests the view model has been created.
371   ViewModel* model = typesetter->GetViewModel();
372   DALI_TEST_CHECK(NULL != model);
373
374   // Configures the text controller similarly to the text-editor.
375   ConfigureTextEditor(controller);
376
377   // The number of characters should be zero.
378   DALI_TEST_EQUALS(0u, model->GetNumberOfCharacters(), TEST_LOCATION);
379
380   // Sets a text and relais-out.
381   controller->SetText(LOREM_IPSUM);
382   controller->Relayout(CONTROL_SIZE);
383
384   DALI_TEST_EQUALS(LOREM_NUMBER_OF_CHARACTERS, model->GetNumberOfCharacters(), TEST_LOCATION);
385   // Configures the text controller similarly to the text-label.
386   ConfigureTextLabel(controller);
387
388   // Relais-out for the text-label configuration.
389   controller->Relayout(Size(100.f, 100.f)); // Change the size to force a relayout.
390   controller->Relayout(CONTROL_SIZE);
391
392   DALI_TEST_EQUALS(LOREM_NUMBER_OF_CHARACTERS_ELIDED, model->GetNumberOfCharacters(), TEST_LOCATION);
393
394   tet_result(TET_PASS);
395   END_TEST;
396 }
397
398 int UtcDaliTextViewModelGetLines(void)
399 {
400   tet_infoline(" UtcDaliTextViewModelGetLines");
401   ToolkitTestApplication application;
402
403   // Creates a text controller.
404   ControllerPtr controller = Controller::New();
405
406   // Tests the rendering controller has been created.
407   TypesetterPtr typesetter = Typesetter::New(controller->GetTextModel());
408   DALI_TEST_CHECK(typesetter);
409
410   // Tests the view model has been created.
411   ViewModel* model = typesetter->GetViewModel();
412   DALI_TEST_CHECK(NULL != model);
413
414   // Configures the text controller similarly to the text-editor.
415   ConfigureTextEditor(controller);
416
417   // The number of lines should be zero.
418   DALI_TEST_EQUALS(0u, model->GetNumberOfLines(), TEST_LOCATION);
419   DALI_TEST_CHECK(NULL == model->GetLines());
420
421   // Sets a text and relais-out.
422   controller->SetText(LOREM_IPSUM);
423   controller->Relayout(CONTROL_SIZE);
424
425   DALI_TEST_EQUALS(LOREM_NUMBER_OF_LINES, model->GetNumberOfLines(), TEST_LOCATION);
426   DALI_TEST_CHECK(NULL != model->GetLines());
427
428   // Configures the text controller similarly to the text-label.
429   ConfigureTextLabel(controller);
430
431   // Relais-out for the text-label configuration.
432   controller->Relayout(Size(100.f, 100.f)); // Change the size to force a relayout.
433   controller->Relayout(CONTROL_SIZE);
434
435   DALI_TEST_EQUALS(LOREM_NUMBER_OF_LINES_ELIDED, model->GetNumberOfLines(), TEST_LOCATION);
436   DALI_TEST_CHECK(NULL != model->GetLines());
437
438   tet_result(TET_PASS);
439   END_TEST;
440 }
441
442 int UtcDaliTextViewModelGetGlyphsLayout(void)
443 {
444   tet_infoline(" UtcDaliTextViewModelGetGlyphsLayout");
445   ToolkitTestApplication application;
446
447   // Creates a text controller.
448   ControllerPtr controller = Controller::New();
449
450   // Tests the rendering controller has been created.
451   TypesetterPtr typesetter = Typesetter::New(controller->GetTextModel());
452   DALI_TEST_CHECK(typesetter);
453
454   // Tests the view model has been created.
455   ViewModel* model = typesetter->GetViewModel();
456   DALI_TEST_CHECK(NULL != model);
457
458   // Configures the text controller similarly to the text-editor.
459   ConfigureTextEditor(controller);
460
461   // The number of glyphs should be zero.
462   DALI_TEST_EQUALS(0u, model->GetNumberOfGlyphs(), TEST_LOCATION);
463   DALI_TEST_CHECK(NULL == model->GetGlyphs());
464   DALI_TEST_CHECK(NULL == model->GetLayout());
465
466   // Sets a text and relais-out.
467   controller->SetText(LOREM_IPSUM);
468   controller->Relayout(CONTROL_SIZE);
469
470   DALI_TEST_EQUALS(LOREM_NUMBER_OF_GLYPHS, model->GetNumberOfGlyphs(), TEST_LOCATION);
471   DALI_TEST_CHECK(NULL != model->GetGlyphs());
472   DALI_TEST_CHECK(NULL != model->GetLayout());
473
474   // Configures the text controller similarly to the text-label.
475   ConfigureTextLabel(controller);
476
477   // Relais-out for the text-label configuration.
478   controller->Relayout(Size(100.f, 100.f)); // Change the size to force a relayout.
479   controller->Relayout(CONTROL_SIZE);
480
481   // Elide the glyphs.
482   model->ElideGlyphs();
483
484   DALI_TEST_EQUALS(LOREM_NUMBER_OF_GLYPHS_ELIDED, model->GetNumberOfGlyphs(), TEST_LOCATION);
485   DALI_TEST_CHECK(NULL != model->GetGlyphs());
486   DALI_TEST_CHECK(NULL != model->GetLayout());
487
488   tet_result(TET_PASS);
489   END_TEST;
490 }
491
492 int UtcDaliTextViewModelGetColors(void)
493 {
494   tet_infoline(" UtcDaliTextViewModelGetColors");
495   ToolkitTestApplication application;
496
497   // Creates a text controller.
498   ControllerPtr controller = Controller::New();
499
500   // Tests the rendering controller has been created.
501   TypesetterPtr typesetter = Typesetter::New(controller->GetTextModel());
502   DALI_TEST_CHECK(typesetter);
503
504   // Tests the view model has been created.
505   ViewModel* model = typesetter->GetViewModel();
506   DALI_TEST_CHECK(NULL != model);
507
508   // Configures the text controller similarly to the text-label.
509   ConfigureTextLabel(controller);
510
511   // Sets a text and relais-out.
512   controller->SetMarkupProcessorEnabled(true);
513   controller->SetText("Lorem <color value='red'>ips<color value='blue'>um do</color>lor s<color value='green'>i</color>t a</color>met.");
514   controller->Relayout(CONTROL_SIZE);
515
516   DALI_TEST_EQUALS(Color::BLACK, model->GetDefaultColor(), TEST_LOCATION);
517
518   const ColorIndex* const colorIndicesBuffer = model->GetColorIndices();
519
520   const Length numberOfGlyphs = model->GetNumberOfGlyphs();
521   for(ColorIndex index = 0u; index < numberOfGlyphs; ++index)
522   {
523     DALI_TEST_EQUALS(COLOR_INDICES[index], *(colorIndicesBuffer + index), TEST_LOCATION);
524   }
525
526   const Vector4* const colors = model->GetColors();
527   for(unsigned int index = 0u; index < NUMBER_OF_COLORS; ++index)
528   {
529     DALI_TEST_EQUALS(COLORS[index], *(colors + index), TEST_LOCATION);
530   }
531
532   tet_result(TET_PASS);
533   END_TEST;
534 }
535
536 int UtcDaliTextViewModelElideText01(void)
537 {
538   tet_infoline(" UtcDaliTextViewModelElideText01");
539   ToolkitTestApplication application;
540
541   // Creates a text controller.
542   ControllerPtr controller = Controller::New();
543
544   // Tests the rendering controller has been created.
545   TypesetterPtr typesetter = Typesetter::New(controller->GetTextModel());
546   DALI_TEST_CHECK(typesetter);
547
548   // Tests the view model has been created.
549   ViewModel* model = typesetter->GetViewModel();
550   DALI_TEST_CHECK(NULL != model);
551
552   // Configures the text controller similarly to the text-editor.
553   ConfigureTextEditor(controller);
554
555   // The number of glyphs should be zero.
556   DALI_TEST_EQUALS(0u, model->GetNumberOfGlyphs(), TEST_LOCATION);
557   DALI_TEST_EQUALS(0u, model->GetNumberOfLines(), TEST_LOCATION);
558   DALI_TEST_CHECK(NULL == model->GetGlyphs());
559   DALI_TEST_CHECK(NULL == model->GetLayout());
560
561   // Sets a text and relais-out.
562   controller->SetText(LOREM_IPSUM);
563   controller->Relayout(CONTROL_SIZE);
564
565   // Keep the pointers to the glyphs and layout.
566   // As the text is not elided with this configuration, the pointers shoud be the same after calling the ElideGlyphs() method.
567   const GlyphInfo* const glyphsModel  = model->GetGlyphs();
568   const Vector2*         layoutsModel = model->GetLayout();
569
570   // Elide the glyphs. Text shouldn't be elided with this configuration.
571   model->ElideGlyphs();
572
573   DALI_TEST_CHECK(glyphsModel == model->GetGlyphs());
574   DALI_TEST_CHECK(layoutsModel == model->GetLayout());
575
576   DALI_TEST_EQUALS(LOREM_NUMBER_OF_GLYPHS, model->GetNumberOfGlyphs(), TEST_LOCATION);
577   DALI_TEST_EQUALS(LOREM_NUMBER_OF_LINES, model->GetNumberOfLines(), TEST_LOCATION);
578
579   // Configures the text controller similarly to the text-label.
580   ConfigureTextLabel(controller);
581
582   // Clear the text and relais-out.
583   controller->SetText("");
584   controller->Relayout(CONTROL_SIZE);
585
586   DALI_TEST_EQUALS(0u, model->GetNumberOfGlyphs(), TEST_LOCATION);
587   DALI_TEST_EQUALS(0u, model->GetNumberOfLines(), TEST_LOCATION);
588
589   // Elide the glyphs. Should not add the ellipsis glyph.
590   model->ElideGlyphs();
591
592   DALI_TEST_EQUALS(0u, model->GetNumberOfGlyphs(), TEST_LOCATION);
593
594   // Sets a text that doesn't need to be elided.
595   controller->SetText("Hello\n");
596   controller->Relayout(CONTROL_SIZE);
597
598   // Elide the glyphs.
599   model->ElideGlyphs();
600
601   DALI_TEST_EQUALS(6u, model->GetNumberOfGlyphs(), TEST_LOCATION);
602   DALI_TEST_EQUALS(2u, model->GetNumberOfLines(), TEST_LOCATION);
603
604   // Sets a text and relais-out.
605   controller->SetText(LOREM_IPSUM);
606   controller->Relayout(CONTROL_SIZE);
607
608   // Elide the glyphs.
609   model->ElideGlyphs();
610
611   DALI_TEST_EQUALS(LOREM_NUMBER_OF_GLYPHS_ELIDED, model->GetNumberOfGlyphs(), TEST_LOCATION);
612   DALI_TEST_EQUALS(LOREM_NUMBER_OF_LINES_ELIDED, model->GetNumberOfLines(), TEST_LOCATION);
613   const GlyphInfo* const glyphs  = model->GetGlyphs();
614   const Vector2*         layouts = model->GetLayout();
615   DALI_TEST_CHECK(NULL != glyphs);
616   DALI_TEST_CHECK(NULL != layouts);
617
618   // When the ellipsis is enabled, at least a glyph has to be rendered.
619   // Even if the given width is too narrow for rendering an ellipsis glyph.
620   controller->SetText("…");
621   Vector3 sizeEllipsis = controller->GetNaturalSize();
622   controller->SetText("A");
623   Vector3 sizeA     = controller->GetNaturalSize();
624   float   testWidth = sizeA.width < sizeEllipsis.width ? sizeA.width : sizeEllipsis.width - 1.0;
625
626   controller->SetText("AB");
627   Vector3 sizeAB = controller->GetNaturalSize();
628
629   controller->Relayout(Size(testWidth, sizeAB.height));
630
631   // Elide the glyphs.
632   model->ElideGlyphs();
633   DALI_TEST_EQUALS(1u, model->GetNumberOfGlyphs(), TEST_LOCATION);
634   DALI_TEST_EQUALS(1u, model->GetNumberOfLines(), TEST_LOCATION);
635
636   tet_result(TET_PASS);
637   END_TEST;
638 }
639
640 int UtcDaliTextViewModelElideText02(void)
641 {
642   tet_infoline(" UtcDaliTextViewModelElideText02");
643
644   Size textSize00(100.f, 100.f);
645
646   Size  textSize01(80.f, 100.f);
647   float positions01[] = {0.0f, 8.0f, 16.0f, 26.0f, 34.0f, 42.0f, 46.0f, 56.0f, 64.0f};
648
649   Size  textSize02(80.f, 100.f);
650   float positions02[] = {69.0f, 63.0f, 59.0f, 51.0f, 47.0f, 43.0f, 34.0f, 26.0f, 7.0f};
651
652   Size  textSize03(80.f, 100.f);
653   float positions03[] = {78.0f, 72.0f, 66.0f, 62.0f, 57.0f, 50.0f, 45.0f, 41.0f, 39.0f, 33.0f, 29.0f, 23.0f, 3.0f};
654
655   Size  textSize04(80.f, 10.f);
656   float positions04[] = {1.f};
657
658   struct ElideData data[] =
659     {
660       {"void text",
661        "",
662        textSize00,
663        0u,
664        0u,
665        NULL},
666       {"Latin script",
667        "<font family='TizenSans'>Lorem ipsum dolor sit amet, aeque definiebas ea mei, posse iracundia ne cum.</font>",
668        textSize01,
669        5u,
670        36u,
671        positions01},
672       {"Hebrew script",
673        "<font family='TizenSansHebrew'>צעד על לשון המלצת לאחרונה, אם לכאן שנורו סרבול מדע, קרן דת שפות להפוך.</font>",
674        textSize02,
675        5u,
676        44u,
677        positions02},
678       {"Arabic script",
679        "<font family='TizenSansArabic'>عل النفط ديسمبر الإمداد بال, بين وترك شعار هو. لمّ من المبرمة النفط بالسيطرة, أم يتم تحرّك وبغطاء, عدم في لإعادة وإقامة رجوعهم.</font>",
680        textSize03,
681        5u,
682        66u,
683        positions03},
684       {"Small control size, no line fits.",
685        "<font family='TizenSans'>Lorem ipsum dolor sit amet, aeque definiebas ea mei, posse iracundia ne cum.</font>",
686        textSize04,
687        1u,
688        1u,
689        positions04}};
690   const unsigned int numberOfTests = 5u;
691
692   for(unsigned int index = 0u; index < numberOfTests; ++index)
693   {
694     ToolkitTestApplication application;
695     if(!ElideTest(data[index]))
696     {
697       tet_result(TET_FAIL);
698     }
699   }
700
701   tet_result(TET_PASS);
702   END_TEST;
703 }
704
705 int UtcDaliTextViewModelGetFontRuns(void)
706 {
707   tet_infoline(" UtcDaliTextViewModelGetFontRuns");
708   ToolkitTestApplication application;
709
710   // Load some fonts.
711   TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
712   fontClient.SetDpi(93u, 93u);
713
714   char*             pathNamePtr = get_current_dir_name();
715   const std::string pathName(pathNamePtr);
716   free(pathNamePtr);
717
718   fontClient.GetFontId(pathName + DEFAULT_FONT_DIR + "/tizen/TizenSansRegular.ttf");
719
720   // Creates a text controller.
721   ControllerPtr controller = Controller::New();
722
723   // Tests the rendering controller has been created.
724   TypesetterPtr typesetter = Typesetter::New(controller->GetTextModel());
725   DALI_TEST_CHECK(typesetter);
726
727   // Tests the view model has been created.
728   ViewModel* model = typesetter->GetViewModel();
729   DALI_TEST_CHECK(NULL != model);
730
731   // Configures the text controller similarly to the text-editor.
732   ConfigureTextEditor(controller);
733
734   // Sets a text and relais-out.
735   controller->SetMarkupProcessorEnabled(true);
736   controller->SetText("<font family='TizenSansRegular' size='10'>Hello </font>Hello<font family='TizenSansRegular' size='15'>Hello</font>");
737   controller->Relayout(CONTROL_SIZE);
738
739   const Vector<FontRun>& validFonts = model->GetFontRuns();
740
741   // The font-runs should be equal to number of segments have different fonts.
742   DALI_TEST_EQUALS(validFonts.Count(), 3u, TEST_LOCATION);
743
744   tet_result(TET_PASS);
745   END_TEST;
746 }
747
748 int UtcDaliTextViewModelGetFontDescriptionRuns(void)
749 {
750   tet_infoline(" UtcDaliTextViewModelGetFontDescriptionRuns");
751   ToolkitTestApplication application;
752
753   // Load some fonts.
754   TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
755   fontClient.SetDpi(93u, 93u);
756
757   char*             pathNamePtr = get_current_dir_name();
758   const std::string pathName(pathNamePtr);
759   free(pathNamePtr);
760
761   fontClient.GetFontId(pathName + DEFAULT_FONT_DIR + "/tizen/TizenSansRegular.ttf");
762
763   // Creates a text controller.
764   ControllerPtr controller = Controller::New();
765
766   // Tests the rendering controller has been created.
767   TypesetterPtr typesetter = Typesetter::New(controller->GetTextModel());
768   DALI_TEST_CHECK(typesetter);
769
770   // Tests the view model has been created.
771   ViewModel* model = typesetter->GetViewModel();
772   DALI_TEST_CHECK(NULL != model);
773
774   // Configures the text controller similarly to the text-editor.
775   ConfigureTextEditor(controller);
776
777   // Sets a text and relais-out.
778   controller->SetMarkupProcessorEnabled(true);
779   controller->SetText("<font family='TizenSansRegular' size='10'>Hello </font>Hello<font family='TizenSansRegular' size='15'>Hello</font>");
780   controller->Relayout(CONTROL_SIZE);
781
782   const Vector<FontDescriptionRun>& validFonts = model->GetFontDescriptionRuns();
783
784   // The font-description-runs should be equal number of the used fonts.
785   DALI_TEST_EQUALS(validFonts.Count(), 2u, TEST_LOCATION);
786
787   tet_result(TET_PASS);
788   END_TEST;
789 }