[dali_2.3.42] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-toolkit-internal / utc-Dali-Text-MultiLanguage.cpp
1 /*
2  * Copyright (c) 2024 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 <iostream>
19 #include <stdlib.h>
20 #include <unistd.h>
21
22 #include <dali/devel-api/text-abstraction/font-client.h>
23 #include <dali-toolkit/internal/text/character-set-conversion.h>
24 #include <dali-toolkit/internal/text/logical-model-impl.h>
25 #include <dali-toolkit/internal/text/multi-language-helper-functions.h>
26 #include <dali-toolkit/internal/text/multi-language-support.h>
27 #include <dali-toolkit/internal/text/multi-language-support-impl.h>
28 #include <dali-toolkit/internal/text/segmentation.h>
29 #include <dali-toolkit/internal/text/text-run-container.h>
30 #include <dali-toolkit-test-suite-utils.h>
31 #include <dali-toolkit/dali-toolkit.h>
32
33 using namespace Dali;
34 using namespace Toolkit;
35 using namespace Text;
36
37
38 // Tests the following functions with different scripts.
39 //
40 // void MergeFontDescriptions(const Vector<FontDescriptionRun>&       fontDescriptions,
41 //                            const TextAbstraction::FontDescription& defaultFontDescription,
42 //                            TextAbstraction::PointSize26Dot6        defaultPointSize,
43 //                            float                                   fontSizeScale,
44 //                            CharacterIndex                          characterIndex,
45 //                            TextAbstraction::FontDescription&       fontDescription,
46 //                            TextAbstraction::PointSize26Dot6&       fontPointSize,
47 //                            bool&                                   isDefaultFont);
48 //
49 // Script GetScript(Length                                  index,
50 //                  Vector<ScriptRun>::ConstIterator&       scriptRunIt,
51 //                  const Vector<ScriptRun>::ConstIterator& scriptRunEndIt);
52 //
53 // Constructor, destructor and MultilanguageSupport::Get()
54 //
55 // void MultilanguageSupport::SetScripts(const Vector<Character>& text,
56 //                                       CharacterIndex           startIndex,
57 //                                       Length                   numberOfCharacters,
58 //                                       Vector<ScriptRun>&       scripts);
59 //
60 // void MultilanguageSupport::ValidateFonts(const Vector<Character>&                text,
61 //                                          const Vector<ScriptRun>&                scripts,
62 //                                          const Vector<FontDescriptionRun>&       fontDescriptions,
63 //                                          const TextAbstraction::FontDescription& defaultFontDescription,
64 //                                          TextAbstraction::PointSize26Dot6        defaultFontPointSize,
65 //                                          float                                   fontSizeScale,
66 //                                          CharacterIndex                          startIndex,
67 //                                          Length                                  numberOfCharacters,
68 //                                          Vector<FontRun>&                        fonts);
69
70 //////////////////////////////////////////////////////////
71
72 namespace
73 {
74
75 const std::string DEFAULT_FONT_DIR( "/resources/fonts" );
76 const unsigned int EMOJI_FONT_SIZE = 3840u; // 60 * 64
77 const unsigned int NON_DEFAULT_FONT_SIZE = 40u;
78
79 struct MergeFontDescriptionsData
80 {
81   std::string description;                                 ///< Description of the experiment.
82   Vector<FontDescriptionRun> fontDescriptionRuns;          ///< The font description runs.
83   TextAbstraction::FontDescription defaultFontDescription; ///< The default font description.
84   TextAbstraction::PointSize26Dot6 defaultPointSize;       ///< The default point size.
85   float        fontSizeScale;                              ///< The font's size scale.
86   unsigned int startIndex;                                 ///< The start index.
87   unsigned int numberOfCharacters;                         ///< The number of characters.
88   Vector<FontId> expectedFontIds;                          ///< The expected font ids.
89   Vector<bool> expectedIsDefault;                          ///< The expected font ids.
90 };
91
92 struct ScriptsData
93 {
94   std::string description;         ///< Description of the experiment.
95   std::string text;                ///< Input text.
96   unsigned int index;              ///< The index of the first character to update the script.
97   unsigned int numberOfCharacters; ///< The numbers of characters to update the script.
98   Vector<ScriptRun> scriptRuns;    ///< Expected script runs.
99 };
100
101 struct ValidateFontsData
102 {
103   std::string                description;         ///< Description of the experiment.
104   std::string                text;                ///< Input text.
105   std::string                defaultFont;         ///< The default font.
106   unsigned int               defaultFontSize;     ///< The default font size.
107   float                      fontSizeScale;       ///< The font's size scale.
108   unsigned int               index;               ///< The index of the first character to update the script.
109   unsigned int               numberOfCharacters;  ///< The numbers of characters to update the script.
110   Vector<FontDescriptionRun> fontDescriptionRuns; ///< The font description runs.
111   Vector<FontRun>            fontRuns;            ///< The expected font runs.
112 };
113
114 //////////////////////////////////////////////////////////
115 bool MergeFontDescriptionsTest( const MergeFontDescriptionsData& data )
116 {
117   TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
118
119   Vector<FontId> fontIds;
120   fontIds.Resize( data.startIndex + data.numberOfCharacters, 0u );
121   Vector<bool> isDefaultFont;
122   isDefaultFont.Resize( data.startIndex + data.numberOfCharacters, true );
123
124   for( unsigned int index = data.startIndex; index < data.startIndex + data.numberOfCharacters; ++index )
125   {
126     TextAbstraction::FontDescription fontDescription;
127     TextAbstraction::PointSize26Dot6 fontPointSize = TextAbstraction::FontClient::DEFAULT_POINT_SIZE;
128
129     MergeFontDescriptions( data.fontDescriptionRuns,
130                            data.defaultFontDescription,
131                            data.defaultPointSize,
132                            data.fontSizeScale,
133                            index,
134                            fontDescription,
135                            fontPointSize,
136                            isDefaultFont[index] );
137
138     if( !isDefaultFont[index] )
139     {
140       fontIds[index] = fontClient.GetFontId( fontDescription, fontPointSize );
141     }
142   }
143
144   if( fontIds.Count() != data.expectedFontIds.Count() )
145   {
146     std::cout << data.description << " Different number of font ids : " << fontIds.Count() << ", expected : " << data.expectedFontIds.Count() << std::endl;
147     return false;
148   }
149
150   for( unsigned int index = 0u; index < fontIds.Count(); ++index )
151   {
152     if( fontIds[index] != data.expectedFontIds[index] )
153     {
154       std::cout << data.description << " Different font id at index : " << index << ", font id : " << fontIds[index] << ", expected : " << data.expectedFontIds[index] << std::endl;
155       std::cout << "           font ids : ";
156       for( unsigned int i=0;i<fontIds.Count();++i)
157       {
158         std::cout << fontIds[i] << " ";
159       }
160       std::cout << std::endl;
161       std::cout << "  expected font ids : ";
162       for( unsigned int i=0;i<data.expectedFontIds.Count();++i)
163       {
164         std::cout << data.expectedFontIds[i] << " ";
165       }
166       std::cout << std::endl;
167       return false;
168     }
169
170     if( isDefaultFont[index] != data.expectedIsDefault[index] )
171     {
172       std::cout << data.description << " Different 'is font default' at index : " << index << ", is font default : " << isDefaultFont[index] << ", expected : " << data.expectedIsDefault[index] << std::endl;
173       return false;
174     }
175   }
176
177   return true;
178 }
179
180 bool ScriptsTest( const ScriptsData& data )
181 {
182   MultilanguageSupport multilanguageSupport = MultilanguageSupport::Get();
183
184   // 1) Convert to utf32
185   Vector<Character> utf32;
186   utf32.Resize( data.text.size() );
187
188   const uint32_t numberOfCharacters = ( data.text.size() == 0 ) ? 0 :
189     Utf8ToUtf32( reinterpret_cast<const uint8_t* const>( data.text.c_str() ),
190                  data.text.size(),
191                  &utf32[0u] );
192
193   utf32.Resize( numberOfCharacters );
194
195   // 2) Set the script info.
196   Vector<ScriptRun> scripts;
197   multilanguageSupport.SetScripts( utf32,
198                                    0u,
199                                    numberOfCharacters,
200                                    scripts );
201
202   if( ( 0u != data.index ) ||
203       ( numberOfCharacters != data.numberOfCharacters ) )
204   {
205     // 3) Clear the scripts.
206     ClearCharacterRuns( data.index,
207                         data.index + data.numberOfCharacters - 1u,
208                         scripts );
209
210     multilanguageSupport.SetScripts( utf32,
211                                      data.index,
212                                      data.numberOfCharacters,
213                                      scripts );
214   }
215
216   // 4) Compare the results.
217
218   tet_printf( "Testing %s\n", data.description.c_str() );
219   if( scripts.Count() != data.scriptRuns.Count() )
220   {
221     tet_printf("ScriptsTest FAIL: different number of scripts. %d, should be %d\n", scripts.Count(), data.scriptRuns.Count() );
222     for( Vector<ScriptRun>::ConstIterator it = scripts.Begin(); it != scripts.End(); ++it)
223     {
224       const ScriptRun& run = *it;
225
226       std::cout << "  index : " << run.characterRun.characterIndex << ", num chars : " << run.characterRun.numberOfCharacters << ", script : [" << TextAbstraction::ScriptName[run.script] << "]" << std::endl;
227     }
228     return false;
229   }
230
231   for( unsigned int index = 0u; index < scripts.Count(); ++index )
232   {
233     const ScriptRun& scriptRun1 = scripts[index];
234     const ScriptRun& scriptRun2 = data.scriptRuns[index];
235
236     if( scriptRun1.characterRun.characterIndex != scriptRun2.characterRun.characterIndex )
237     {
238       tet_printf("ScriptsTest FAIL: different character index. %d, should be %d\n", scriptRun1.characterRun.characterIndex, scriptRun2.characterRun.characterIndex );
239       return false;
240     }
241
242     if( scriptRun1.characterRun.numberOfCharacters != scriptRun2.characterRun.numberOfCharacters )
243     {
244       tet_printf("ScriptsTest FAIL: different number of characters. %d, should be %d\n", scriptRun1.characterRun.numberOfCharacters, scriptRun2.characterRun.numberOfCharacters );
245       return false;
246     }
247
248     if( scriptRun1.script != scriptRun2.script )
249     {
250       tet_printf("ScriptsTest FAIL: script index: %u, different script. %s, should be %s\n", index, TextAbstraction::ScriptName[scriptRun1.script], TextAbstraction::ScriptName[scriptRun2.script] );
251       return false;
252     }
253   }
254
255   return true;
256 }
257
258 bool ValidateFontTest( const ValidateFontsData& data )
259 {
260   MultilanguageSupport multilanguageSupport = MultilanguageSupport::Get();
261   TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
262
263   // 1) Convert to utf32
264   Vector<Character> utf32;
265   utf32.Resize( data.text.size() );
266
267   const uint32_t numberOfCharacters = (data.text.size() == 0 ) ? 0 :
268     Utf8ToUtf32( reinterpret_cast<const uint8_t* const>( data.text.c_str() ),
269                                                    data.text.size(),
270                                                    &utf32[0u] );
271   utf32.Resize( numberOfCharacters );
272
273   // 2) Set the script info.
274   Vector<ScriptRun> scripts;
275   multilanguageSupport.SetScripts( utf32,
276                                    0u,
277                                    numberOfCharacters,
278                                    scripts );
279
280   char* pathNamePtr = get_current_dir_name();
281   const std::string pathName( pathNamePtr );
282   free( pathNamePtr );
283
284   // Get the default font id.
285   const FontId defaultFontId = fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + data.defaultFont,
286                                                      data.defaultFontSize );
287   TextAbstraction::FontDescription defaultFontDescription;
288   fontClient.GetDescription( defaultFontId, defaultFontDescription );
289
290   const TextAbstraction::PointSize26Dot6 defaultPointSize = fontClient.GetPointSize( defaultFontId );
291
292   Vector<FontRun> fontRuns;
293
294   // 3) Validate the fonts.
295   multilanguageSupport.ValidateFonts( fontClient,
296                                       utf32,
297                                       scripts,
298                                       data.fontDescriptionRuns,
299                                       defaultFontDescription,
300                                       defaultPointSize,
301                                       data.fontSizeScale,
302                                       0u,
303                                       numberOfCharacters,
304                                       fontRuns );
305
306   if( ( 0u != data.index ) ||
307       ( numberOfCharacters != data.numberOfCharacters ) )
308   {
309     // 4) Clear the fonts.
310     ClearCharacterRuns( data.index,
311                         data.index + data.numberOfCharacters - 1u,
312                         fontRuns );
313
314     multilanguageSupport.ValidateFonts( fontClient,
315                                         utf32,
316                                         scripts,
317                                         data.fontDescriptionRuns,
318                                         defaultFontDescription,
319                                         defaultPointSize,
320                                         data.fontSizeScale,
321                                         data.index,
322                                         data.numberOfCharacters,
323                                         fontRuns );
324   }
325
326   // 5) Compare the results.
327   if( data.fontRuns.Count() != fontRuns.Count() )
328   {
329     std::cout << "  Different number of font runs : " << fontRuns.Count() << ", expected : " << data.fontRuns.Count() << std::endl;
330     return false;
331   }
332
333
334   for( unsigned int index = 0; index < data.fontRuns.Count(); ++index )
335   {
336     const FontRun& run = fontRuns[index];
337     const FontRun& expectedRun = data.fontRuns[index];
338
339     if( run.characterRun.characterIndex != expectedRun.characterRun.characterIndex )
340     {
341       std::cout << "  character run : " << index << ", index : " << run.characterRun.characterIndex << ", expected : " << expectedRun.characterRun.characterIndex << std::endl;
342       return false;
343     }
344     if( run.characterRun.numberOfCharacters != expectedRun.characterRun.numberOfCharacters )
345     {
346       std::cout << "  character run : " << index << ", num chars : " << run.characterRun.numberOfCharacters << ", expected : " << expectedRun.characterRun.numberOfCharacters << std::endl;
347       return false;
348     }
349     if( run.fontId != expectedRun.fontId )
350     {
351       std::cout << "  character run : " << index << ", font : " << run.fontId << ", expected : " << expectedRun.fontId << std::endl;
352       return false;
353     }
354   }
355
356   return true;
357 }
358
359 } // namespace
360
361 int UtcDaliTextGetScript(void)
362 {
363   ToolkitTestApplication application;
364   tet_infoline(" UtcDaliTextGetScript");
365
366   Script script = TextAbstraction::LATIN;
367
368   // Text with no scripts.
369   Vector<ScriptRun> scriptRuns;
370   Vector<ScriptRun>::ConstIterator scriptRunIt = scriptRuns.Begin();
371   script = GetScript( 0u,
372                       scriptRunIt,
373                       scriptRuns.End() );
374
375   DALI_TEST_CHECK( TextAbstraction::UNKNOWN == script );
376
377   const unsigned int numberOfCharacters = 7u;
378   // Add scripts.
379   ScriptRun scriptRun01 =
380   {
381     {
382       0u,
383       2u,
384     },
385     TextAbstraction::LATIN
386   };
387   ScriptRun scriptRun02 =
388   {
389     {
390       2u,
391       2u,
392     },
393     TextAbstraction::HEBREW
394   };
395   ScriptRun scriptRun03 =
396   {
397     {
398       4u,
399       2u,
400     },
401     TextAbstraction::ARABIC
402   };
403   scriptRuns.PushBack( scriptRun01 );
404   scriptRuns.PushBack( scriptRun02 );
405   scriptRuns.PushBack( scriptRun03 );
406
407   // Expected results
408   TextAbstraction::Script expectedScripts[]=
409   {
410     TextAbstraction::LATIN,
411     TextAbstraction::LATIN,
412     TextAbstraction::HEBREW,
413     TextAbstraction::HEBREW,
414     TextAbstraction::ARABIC,
415     TextAbstraction::ARABIC,
416     TextAbstraction::UNKNOWN
417   };
418
419   scriptRunIt = scriptRuns.Begin();
420   for( unsigned int index = 0u; index < numberOfCharacters; ++index )
421   {
422     script = GetScript( index,
423                         scriptRunIt,
424                         scriptRuns.End() );
425
426     DALI_TEST_CHECK( expectedScripts[index] == script );
427   }
428   DALI_TEST_CHECK( scriptRunIt == scriptRuns.End() );
429
430   tet_result(TET_PASS);
431   END_TEST;
432 }
433
434 int UtcDaliTextMergeFontDescriptions(void)
435 {
436   ToolkitTestApplication application;
437   tet_infoline(" UtcDaliTextMergeFontDescriptions");
438
439   // Load some fonts.
440
441   char* pathNamePtr = get_current_dir_name();
442   const std::string pathName( pathNamePtr );
443   free( pathNamePtr );
444
445   TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
446   fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/dejavu/DejaVuSans.ttf" );
447   fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/dejavu/DejaVuSerif.ttf" );
448   fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/dejavu/DejaVuSerif.ttf", NON_DEFAULT_FONT_SIZE );
449   fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/dejavu/DejaVuSerif-Bold.ttf" );
450   fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/dejavu/DejaVuSerif-Italic.ttf" );
451
452   // To test the font width as GetFontId() with the font file path can't cache the width property.
453   TextAbstraction::FontDescription widthDescription;
454   widthDescription.path = "";
455   widthDescription.family = "DejaVu Serif";
456   widthDescription.weight = TextAbstraction::FontWeight::NORMAL;
457   widthDescription.width = TextAbstraction::FontWidth::EXPANDED;
458   widthDescription.slant = TextAbstraction::FontSlant::NORMAL;
459   fontClient.GetFontId( widthDescription );
460
461   // Test.
462
463   TextAbstraction::FontDescription defaultFontDescription01;
464   Vector<FontDescriptionRun> fontDescriptionRuns01;
465   Vector<FontId> expectedFontIds01;
466   Vector<bool> expectedIsFontDefault01;
467
468   TextAbstraction::FontDescription defaultFontDescription02;
469   Vector<FontDescriptionRun> fontDescriptionRuns02;
470   Vector<FontId> expectedFontIds02;
471   expectedFontIds02.PushBack( 0u );
472   expectedFontIds02.PushBack( 0u );
473   Vector<bool> expectedIsFontDefault02;
474   expectedIsFontDefault02.PushBack( true );
475   expectedIsFontDefault02.PushBack( true );
476
477   TextAbstraction::FontDescription defaultFontDescription03;
478   defaultFontDescription03.family = "DejaVu Serif";
479   Vector<FontDescriptionRun> fontDescriptionRuns03;
480
481   FontDescriptionRun fontDescription0301 =
482   {
483     {
484       0u,
485       2u
486     },
487     const_cast<char*>( "DejaVu Sans" ),
488     11u,
489     TextAbstraction::FontWeight::NONE,
490     TextAbstraction::FontWidth::NONE,
491     TextAbstraction::FontSlant::NONE,
492     TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
493     true,
494     false,
495     false,
496     false,
497     false
498   };
499   FontDescriptionRun fontDescription0302 =
500   {
501     {
502       2u,
503       2u
504     },
505     NULL,
506     0u,
507     TextAbstraction::FontWeight::NONE,
508     TextAbstraction::FontWidth::NONE,
509     TextAbstraction::FontSlant::ITALIC,
510     TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
511     false,
512     false,
513     false,
514     true,
515     false
516   };
517   FontDescriptionRun fontDescription0303 =
518   {
519     {
520       4u,
521       2u
522     },
523     NULL,
524     0u,
525     TextAbstraction::FontWeight::BOLD,
526     TextAbstraction::FontWidth::NONE,
527     TextAbstraction::FontSlant::NONE,
528     TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
529     false,
530     true,
531     false,
532     false,
533     false
534   };
535   FontDescriptionRun fontDescription0304 =
536   {
537     {
538       6u,
539       2u
540     },
541     NULL,
542     0u,
543     TextAbstraction::FontWeight::NONE,
544     TextAbstraction::FontWidth::NONE,
545     TextAbstraction::FontSlant::NONE,
546     NON_DEFAULT_FONT_SIZE,
547     false,
548     false,
549     false,
550     false,
551     true
552   };
553   FontDescriptionRun fontDescription0305 =
554   {
555     {
556       8u,
557       2u
558     },
559     NULL,
560     0u,
561     TextAbstraction::FontWeight::NONE,
562     TextAbstraction::FontWidth::EXPANDED,
563     TextAbstraction::FontSlant::NONE,
564     TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
565     false,
566     false,
567     true,
568     false,
569     false
570   };
571
572   fontDescriptionRuns03.PushBack( fontDescription0301 );
573   fontDescriptionRuns03.PushBack( fontDescription0302 );
574   fontDescriptionRuns03.PushBack( fontDescription0303 );
575   fontDescriptionRuns03.PushBack( fontDescription0304 );
576   fontDescriptionRuns03.PushBack( fontDescription0305 );
577
578   Vector<FontId> expectedFontIds03;
579   expectedFontIds03.PushBack( 1u );
580   expectedFontIds03.PushBack( 1u );
581   expectedFontIds03.PushBack( 5u );
582   expectedFontIds03.PushBack( 5u );
583   expectedFontIds03.PushBack( 4u );
584   expectedFontIds03.PushBack( 4u );
585   expectedFontIds03.PushBack( 3u );
586   expectedFontIds03.PushBack( 3u );
587   expectedFontIds03.PushBack( 6u );
588   expectedFontIds03.PushBack( 6u );
589   Vector<bool> expectedIsFontDefault03;
590   expectedIsFontDefault03.PushBack( false );
591   expectedIsFontDefault03.PushBack( false );
592   expectedIsFontDefault03.PushBack( false );
593   expectedIsFontDefault03.PushBack( false );
594   expectedIsFontDefault03.PushBack( false );
595   expectedIsFontDefault03.PushBack( false );
596   expectedIsFontDefault03.PushBack( false );
597   expectedIsFontDefault03.PushBack( false );
598   expectedIsFontDefault03.PushBack( false );
599   expectedIsFontDefault03.PushBack( false );
600
601   const MergeFontDescriptionsData data[] =
602   {
603     {
604       "void text.",
605       fontDescriptionRuns01,
606       defaultFontDescription01,
607       TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
608       1.0f,
609       0u,
610       0u,
611       expectedFontIds01,
612       expectedIsFontDefault01
613     },
614     {
615       "No description runs.",
616       fontDescriptionRuns02,
617       defaultFontDescription02,
618       TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
619       1.0f,
620       0u,
621       2u,
622       expectedFontIds02,
623       expectedIsFontDefault02
624     },
625     {
626       "Some description runs.",
627       fontDescriptionRuns03,
628       defaultFontDescription03,
629       TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
630       1.0f,
631       0u,
632       10u,
633       expectedFontIds03,
634       expectedIsFontDefault03
635     }
636   };
637   const unsigned int numberOfTests = 3u;
638
639   for( unsigned int index = 0u; index < numberOfTests; ++index )
640   {
641     if( !MergeFontDescriptionsTest( data[index] ) )
642     {
643       tet_result(TET_FAIL);
644     }
645   }
646
647   tet_result(TET_PASS);
648   END_TEST;
649 }
650
651 int UtcDaliTextMultiLanguageConstructor(void)
652 {
653   ToolkitTestApplication application;
654   tet_infoline(" UtcDaliTextMultiLanguageConstructor");
655
656   MultilanguageSupport multilanguageSupport;
657   DALI_TEST_CHECK( !multilanguageSupport );
658
659   MultilanguageSupport multilanguageSupport1 = MultilanguageSupport::Get();
660   DALI_TEST_CHECK( multilanguageSupport1 );
661
662   // To increase coverage.
663   MultilanguageSupport multilanguageSupport2 = MultilanguageSupport::Get();
664   DALI_TEST_CHECK( multilanguageSupport2 );
665
666   DALI_TEST_CHECK( multilanguageSupport1 == multilanguageSupport2 );
667
668   tet_result(TET_PASS);
669   END_TEST;
670 }
671
672 int UtcDaliTextMultiLanguageSetScripts(void)
673 {
674   ToolkitTestApplication application;
675   tet_infoline(" UtcDaliTextMultiLanguageSetScripts" );
676
677   // Void text.
678   Vector<ScriptRun> scriptRuns00;
679
680   // Hello world.
681   Vector<ScriptRun> scriptRuns01;
682   ScriptRun scriptRun0100 =
683   {
684     {
685       0u,
686       11u,
687     },
688     TextAbstraction::LATIN
689   };
690   scriptRuns01.PushBack( scriptRun0100 );
691
692   // Mix of LTR '\n'and RTL
693   Vector<ScriptRun> scriptRuns02;
694   ScriptRun scriptRun0200 =
695   {
696     {
697       0u,
698       12u,
699     },
700     TextAbstraction::LATIN
701   };
702   ScriptRun scriptRun0201 =
703   {
704     {
705       12u,
706       13u,
707     },
708     TextAbstraction::ARABIC
709   };
710   scriptRuns02.PushBack( scriptRun0200 );
711   scriptRuns02.PushBack( scriptRun0201 );
712
713   // Mix of RTL '\n'and LTR
714   Vector<ScriptRun> scriptRuns03;
715   ScriptRun scriptRun0300 =
716   {
717     {
718       0u,
719       14u,
720     },
721     TextAbstraction::ARABIC
722   };
723   ScriptRun scriptRun0301 =
724   {
725     {
726       14u,
727       11u,
728     },
729     TextAbstraction::LATIN
730   };
731   scriptRuns03.PushBack( scriptRun0300 );
732   scriptRuns03.PushBack( scriptRun0301 );
733
734   // White spaces. At the beginning of the text.
735   Vector<ScriptRun> scriptRuns04;
736   ScriptRun scriptRun0400 =
737   {
738     {
739       0u,
740       15u,
741     },
742     TextAbstraction::LATIN
743   };
744   scriptRuns04.PushBack( scriptRun0400 );
745
746   // White spaces. At the end of the text.
747   Vector<ScriptRun> scriptRuns05;
748   ScriptRun scriptRun0500 =
749   {
750     {
751       0u,
752       15u,
753     },
754     TextAbstraction::LATIN
755   };
756   scriptRuns05.PushBack( scriptRun0500 );
757
758   // White spaces. At the middle of the text.
759   Vector<ScriptRun> scriptRuns06;
760   ScriptRun scriptRun0600 =
761   {
762     {
763       0u,
764       15u,
765     },
766     TextAbstraction::LATIN
767   };
768   scriptRuns06.PushBack( scriptRun0600 );
769
770   // White spaces between different scripts.
771   Vector<ScriptRun> scriptRuns07;
772   ScriptRun scriptRun0700 =
773   {
774     {
775       0u,
776       8u,
777     },
778     TextAbstraction::LATIN
779   };
780   ScriptRun scriptRun0701 =
781   {
782     {
783       8u,
784       5u,
785     },
786     TextAbstraction::HANGUL
787   };
788   scriptRuns07.PushBack( scriptRun0700 );
789   scriptRuns07.PushBack( scriptRun0701 );
790
791   // White spaces between different scripts and differetn directions. Starting LTR.
792   Vector<ScriptRun> scriptRuns08;
793   ScriptRun scriptRun0800 =
794   {
795     {
796       0u,
797       18u,
798     },
799     TextAbstraction::LATIN
800   };
801   ScriptRun scriptRun0801 =
802   {
803     {
804       18u,
805       14u,
806     },
807     TextAbstraction::ARABIC
808   };
809   ScriptRun scriptRun0802 =
810   {
811     {
812       32u,
813       18u,
814     },
815     TextAbstraction::HANGUL
816   };
817   scriptRuns08.PushBack( scriptRun0800 );
818   scriptRuns08.PushBack( scriptRun0801 );
819   scriptRuns08.PushBack( scriptRun0802 );
820
821   // White spaces between different scripts and differetn directions. Starting RTL.
822   Vector<ScriptRun> scriptRuns09;
823   ScriptRun scriptRun0900 =
824   {
825     {
826       0u,
827       21u,
828     },
829     TextAbstraction::ARABIC
830   };
831   ScriptRun scriptRun0901 =
832   {
833     {
834       21u,
835       16u,
836     },
837     TextAbstraction::LATIN
838   };
839   ScriptRun scriptRun0902 =
840   {
841     {
842       37u,
843       10u,
844     },
845     TextAbstraction::HANGUL
846   };
847   ScriptRun scriptRun0903 =
848   {
849     {
850       47u,
851       20u,
852     },
853     TextAbstraction::ARABIC
854   };
855   scriptRuns09.PushBack( scriptRun0900 );
856   scriptRuns09.PushBack( scriptRun0901 );
857   scriptRuns09.PushBack( scriptRun0902 );
858   scriptRuns09.PushBack( scriptRun0903 );
859
860   // Paragraphs with different directions.
861   Vector<ScriptRun> scriptRuns10;
862   ScriptRun scriptRun1000 =
863   {
864     {
865       0u,
866       20u,
867     },
868     TextAbstraction::ARABIC
869   };
870   ScriptRun scriptRun1001 =
871   {
872     {
873       20u,
874       12u,
875     },
876     TextAbstraction::HEBREW
877   };
878   ScriptRun scriptRun1002 =
879   {
880     {
881       32u,
882       17u,
883     },
884     TextAbstraction::ARABIC
885   };
886   ScriptRun scriptRun1003 =
887   {
888     {
889       49u,
890       18u,
891     },
892     TextAbstraction::LATIN
893   };
894   ScriptRun scriptRun1004 =
895   {
896     {
897       67u,
898       14u,
899     },
900     TextAbstraction::HANGUL
901   };
902   ScriptRun scriptRun1005 =
903   {
904     {
905       81u,
906       19u,
907     },
908     TextAbstraction::ARABIC
909   };
910   ScriptRun scriptRun1006 =
911   {
912     {
913       100u,
914       13u,
915     },
916     TextAbstraction::LATIN
917   };
918   ScriptRun scriptRun1007 =
919   {
920     {
921       113u,
922       16u,
923     },
924     TextAbstraction::HEBREW
925   };
926   ScriptRun scriptRun1008 =
927   {
928     {
929       129u,
930       20u,
931     },
932     TextAbstraction::LATIN
933   };
934   ScriptRun scriptRun1009 =
935   {
936     {
937       149u,
938       14u,
939     },
940     TextAbstraction::ARABIC
941   };
942   ScriptRun scriptRun1010 =
943   {
944     {
945       163u,
946       18u,
947     },
948     TextAbstraction::HANGUL
949   };
950   ScriptRun scriptRun1011 =
951   {
952     {
953       181u,
954       17u,
955     },
956     TextAbstraction::HANGUL
957   };
958   scriptRuns10.PushBack( scriptRun1000 );
959   scriptRuns10.PushBack( scriptRun1001 );
960   scriptRuns10.PushBack( scriptRun1002 );
961   scriptRuns10.PushBack( scriptRun1003 );
962   scriptRuns10.PushBack( scriptRun1004 );
963   scriptRuns10.PushBack( scriptRun1005 );
964   scriptRuns10.PushBack( scriptRun1006 );
965   scriptRuns10.PushBack( scriptRun1007 );
966   scriptRuns10.PushBack( scriptRun1008 );
967   scriptRuns10.PushBack( scriptRun1009 );
968   scriptRuns10.PushBack( scriptRun1010 );
969   scriptRuns10.PushBack( scriptRun1011 );
970
971   // Paragraphs with no scripts mixed with paragraphs with scripts.
972   Vector<ScriptRun> scriptRuns11;
973   ScriptRun scriptRun1100 =
974   {
975     {
976       0u,
977       3u,
978     },
979     TextAbstraction::UNKNOWN
980   };
981   ScriptRun scriptRun1101 =
982   {
983     {
984       3u,
985       3u,
986     },
987     TextAbstraction::UNKNOWN
988   };
989   ScriptRun scriptRun1102 =
990   {
991     {
992       6u,
993       19u,
994     },
995     TextAbstraction::LATIN
996   };
997   ScriptRun scriptRun1103 =
998   {
999     {
1000       25u,
1001       3u,
1002     },
1003     TextAbstraction::UNKNOWN
1004   };
1005   ScriptRun scriptRun1104 =
1006   {
1007     {
1008       28u,
1009       3u,
1010     },
1011     TextAbstraction::UNKNOWN
1012   };
1013   ScriptRun scriptRun1105 =
1014   {
1015     {
1016       31u,
1017       15u,
1018     },
1019     TextAbstraction::HEBREW
1020   };
1021   ScriptRun scriptRun1106 =
1022   {
1023     {
1024       46u,
1025       2u,
1026     },
1027     TextAbstraction::UNKNOWN
1028   };
1029   ScriptRun scriptRun1107 =
1030   {
1031     {
1032       48u,
1033       2u,
1034     },
1035     TextAbstraction::UNKNOWN
1036   };
1037   ScriptRun scriptRun1108 =
1038   {
1039     {
1040       50u,
1041       2u,
1042     },
1043     TextAbstraction::UNKNOWN
1044   };
1045   scriptRuns11.PushBack( scriptRun1100 );
1046   scriptRuns11.PushBack( scriptRun1101 );
1047   scriptRuns11.PushBack( scriptRun1102 );
1048   scriptRuns11.PushBack( scriptRun1103 );
1049   scriptRuns11.PushBack( scriptRun1104 );
1050   scriptRuns11.PushBack( scriptRun1105 );
1051   scriptRuns11.PushBack( scriptRun1106 );
1052   scriptRuns11.PushBack( scriptRun1107 );
1053   scriptRuns11.PushBack( scriptRun1108 );
1054
1055   // Paragraphs with no scripts.
1056   Vector<ScriptRun> scriptRuns12;
1057   ScriptRun scriptRun1200 =
1058   {
1059     {
1060       0u,
1061       3u,
1062     },
1063     TextAbstraction::UNKNOWN
1064   };
1065   ScriptRun scriptRun1201 =
1066   {
1067     {
1068       3u,
1069       3u,
1070     },
1071     TextAbstraction::UNKNOWN
1072   };
1073   ScriptRun scriptRun1202 =
1074   {
1075     {
1076       6u,
1077       3u,
1078     },
1079     TextAbstraction::UNKNOWN
1080   };
1081   ScriptRun scriptRun1203 =
1082   {
1083     {
1084       9u,
1085       2u,
1086     },
1087     TextAbstraction::UNKNOWN
1088   };
1089   scriptRuns12.PushBack( scriptRun1200 );
1090   scriptRuns12.PushBack( scriptRun1201 );
1091   scriptRuns12.PushBack( scriptRun1202 );
1092   scriptRuns12.PushBack( scriptRun1203 );
1093
1094   Vector<ScriptRun> scriptRuns13;
1095   ScriptRun scriptRun1301 =
1096   {
1097     {
1098       0u,
1099       4u,
1100     },
1101     TextAbstraction::UNKNOWN
1102   };
1103   scriptRuns13.PushBack( scriptRun1301 );
1104
1105   const ScriptsData data[] =
1106   {
1107     {
1108       "void text",
1109       "",
1110       0u,
1111       0u,
1112       scriptRuns00,
1113     },
1114     {
1115       "Easy latin script",
1116       "Hello world",
1117       0u,
1118       11u,
1119       scriptRuns01,
1120     },
1121     {
1122       "Mix of LTR '\\n'and RTL",
1123       "Hello world\nمرحبا بالعالم",
1124       0u,
1125       25u,
1126       scriptRuns02,
1127     },
1128     {
1129       "Update mix of LTR '\\n'and RTL. Update LTR",
1130       "Hello world\nمرحبا بالعالم",
1131       0u,
1132       12u,
1133       scriptRuns02,
1134     },
1135     {
1136       "Update mix of LTR '\\n'and RTL. Update RTL",
1137       "Hello world\nمرحبا بالعالم",
1138       12u,
1139       13u,
1140       scriptRuns02,
1141     },
1142     {
1143       "Mix of RTL '\\n'and LTR",
1144       "مرحبا بالعالم\nHello world",
1145       0u,
1146       25u,
1147       scriptRuns03,
1148     },
1149     {
1150       "Update mix of RTL '\\n'and LTR. Update RTL",
1151       "مرحبا بالعالم\nHello world",
1152       0u,
1153       14u,
1154       scriptRuns03,
1155     },
1156     {
1157       "Update mix of RTL '\\n'and LTR. Update LTR",
1158       "مرحبا بالعالم\nHello world",
1159       14u,
1160       11u,
1161       scriptRuns03,
1162     },
1163     {
1164       "White spaces. At the beginning of the text.",
1165       "    Hello world",
1166       0u,
1167       15u,
1168       scriptRuns04,
1169     },
1170     {
1171       "White spaces. At the end of the text.",
1172       "Hello world    ",
1173       0u,
1174       15u,
1175       scriptRuns05,
1176     },
1177     {
1178       "White spaces. At the middle of the text.",
1179       "Hello     world",
1180       0u,
1181       15u,
1182       scriptRuns06,
1183     },
1184     {
1185       "White spaces between different scripts.",
1186       "  Hel   세계   ",
1187       0u,
1188       13u,
1189       scriptRuns07,
1190     },
1191     {
1192       "White spaces between different scripts and differetn directions. Starting LTR.",
1193       "  Hello   world   مرحبا  بالعالم     안녕하세요   세계   ",
1194       0u,
1195       50u,
1196       scriptRuns08,
1197     },
1198     {
1199       "White spaces between different scripts and differetn directions. Starting RTL.",
1200       "   مرحبا  بالعالم    Hello   world   안녕하세요   세계   مرحبا  بالعالم   ",
1201       0u,
1202       67u,
1203       scriptRuns09
1204     },
1205     {
1206       "Paragraphs with different directions.",
1207       "   مرحبا  بالعالم   שלום עולם   مرحبا  بالعالم  \n "
1208       " Hello   world   안녕하세요   세계   \n "
1209       "  مرحبا  بالعالم  Hello   world    שלום עולם  \n  "
1210       " Hello   world    مرحبا  بالعالم    안녕하세요   세계   \n "
1211       "   안녕하세요   세계   ",
1212       0u,
1213       198u,
1214       scriptRuns10
1215     },
1216     {
1217       "Update paragraphs with different directions. Update initial paragraphs.",
1218       "   مرحبا  بالعالم   שלום עולם   مرحبا  بالعالم  \n "
1219       " Hello   world   안녕하세요   세계   \n "
1220       "  مرحبا  بالعالم  Hello   world    שלום עולם  \n  "
1221       " Hello   world    مرحبا  بالعالم    안녕하세요   세계   \n "
1222       "   안녕하세요   세계   ",
1223       0u,
1224       81u,
1225       scriptRuns10
1226     },
1227     {
1228       "Update paragraphs with different directions. Update middle paragraphs.",
1229       "   مرحبا  بالعالم   שלום עולם   مرحبا  بالعالم  \n "
1230       " Hello   world   안녕하세요   세계   \n "
1231       "  مرحبا  بالعالم  Hello   world    שלום עולם  \n  "
1232       " Hello   world    مرحبا  بالعالم    안녕하세요   세계   \n "
1233       "   안녕하세요   세계   ",
1234       49u,
1235       80u,
1236       scriptRuns10
1237     },
1238     {
1239       "Update paragraphs with different directions. Update final paragraphs.",
1240       "   مرحبا  بالعالم   שלום עולם   مرحبا  بالعالم  \n "
1241       " Hello   world   안녕하세요   세계   \n "
1242       "  مرحبا  بالعالم  Hello   world    שלום עולם  \n  "
1243       " Hello   world    مرحبا  بالعالم    안녕하세요   세계   \n "
1244       "   안녕하세요   세계   ",
1245       129u,
1246       69u,
1247       scriptRuns10
1248     },
1249     {
1250       "Paragraphs with no scripts mixed with paragraphs with scripts.",
1251       "  \n  \n   Hello   world  \n  \n  \n   שלום עולם  \n \n \n  ",
1252       0u,
1253       52u,
1254       scriptRuns11
1255     },
1256     {
1257       "Paragraphs with no scripts.",
1258       "  \n  \n  \n  ",
1259       0u,
1260       11u,
1261       scriptRuns12
1262     },
1263     {
1264       "Update paragraphs with no scripts. Update initial paragraphs.",
1265       "  \n  \n  \n  ",
1266       0u,
1267       3u,
1268       scriptRuns12
1269     },
1270     {
1271       "Update paragraphs with no scripts. Update middle paragraphs.",
1272       "  \n  \n  \n  ",
1273       3u,
1274       6u,
1275       scriptRuns12
1276     },
1277     {
1278       "Update paragraphs with no scripts. Update final paragraphs.",
1279       "  \n  \n  \n  ",
1280       9u,
1281       2u,
1282       scriptRuns12
1283     },
1284     {
1285       "Unknown scripts.",
1286       "ᚩᚯᚱᚸ", // Runic script not currentlu supported.
1287       0u,
1288       4u,
1289       scriptRuns13
1290     }
1291   };
1292   const unsigned int numberOfTests = 24u;
1293
1294   for( unsigned int index = 0u; index < numberOfTests; ++index )
1295   {
1296     if( !ScriptsTest( data[index] ) )
1297     {
1298       tet_result(TET_FAIL);
1299     }
1300   }
1301
1302   tet_result(TET_PASS);
1303   END_TEST;
1304 }
1305
1306 int UtcDaliTextMultiLanguageValidateFonts01(void)
1307 {
1308   ToolkitTestApplication application;
1309   tet_infoline(" UtcDaliTextMultiLanguageValidateFonts");
1310
1311   TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
1312
1313   char* pathNamePtr = get_current_dir_name();
1314   const std::string pathName( pathNamePtr );
1315   free( pathNamePtr );
1316
1317   const PointSize26Dot6 pointSize01 = static_cast<PointSize26Dot6>( 21.f * 64.f );
1318   const PointSize26Dot6 pointSize02 = static_cast<PointSize26Dot6>( 35.f * 64.f );
1319
1320   // Load some fonts.
1321   fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/tizen/TizenSansArabicRegular.ttf" );
1322   fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/tizen/TizenSansHebrewRegular.ttf" );
1323   fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/tizen/BreezeColorEmoji.ttf", EMOJI_FONT_SIZE );
1324   fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/tizen/TizenSansRegular.ttf", pointSize01 );
1325   fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/tizen/TizenSansRegular.ttf", pointSize02 );
1326   fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/tizen/TizenSansHebrewRegular.ttf", pointSize01 );
1327   fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/tizen/TizenSansHebrewRegular.ttf", pointSize02 );
1328
1329   // Font id 1 --> TizenSansArabicRegular.ttf
1330   // Font id 2 --> TizenSansHebrewRegular.ttf
1331   // Font id 3 --> BreezeColorEmoji.ttf
1332   // Font id 4 --> TizenSansRegular.ttf, size 8
1333   // Font id 5 --> TizenSansRegular.ttf, size 16
1334   // Font id 6 --> TizenSansHebrewRegular.ttf, size 8
1335   // Font id 7 --> TizenSansHebrewRegular.ttf, size 16
1336   // Font id 8 --> (default)
1337
1338   Vector<FontRun> fontRuns01;
1339   Vector<FontDescriptionRun> fontDescriptions01;
1340
1341   FontRun fontRun0201 =
1342   {
1343     {
1344       0u,
1345       11u
1346     },
1347     8u
1348   };
1349   Vector<FontRun> fontRuns02;
1350   fontRuns02.PushBack( fontRun0201 );
1351
1352   FontDescriptionRun fontDescription0201 =
1353   {
1354     {
1355       0u,
1356       11u
1357     },
1358     const_cast<char*>( "TizenSans" ),
1359     9u,
1360     TextAbstraction::FontWeight::NORMAL,
1361     TextAbstraction::FontWidth::NORMAL,
1362     TextAbstraction::FontSlant::NORMAL,
1363     0u,
1364     true,
1365     false,
1366     false,
1367     false,
1368     false
1369   };
1370   Vector<FontDescriptionRun> fontDescriptions02;
1371   fontDescriptions02.PushBack( fontDescription0201 );
1372
1373   FontRun fontRun0301 =
1374   {
1375     {
1376       0u,
1377       12u
1378     },
1379     8u
1380   };
1381   FontRun fontRun0302 =
1382   {
1383     {
1384       12u,
1385       12u
1386     },
1387     8u
1388   };
1389   FontRun fontRun0303 =
1390   {
1391     {
1392       24u,
1393       4u
1394     },
1395     8u
1396   };
1397   Vector<FontRun> fontRuns03;
1398   fontRuns03.PushBack( fontRun0301 );
1399   fontRuns03.PushBack( fontRun0302 );
1400   fontRuns03.PushBack( fontRun0303 );
1401
1402   Vector<FontDescriptionRun> fontDescriptions03;
1403
1404   FontRun fontRun0701 =
1405   {
1406     {
1407       0u,
1408       4u
1409     },
1410     2u
1411   };
1412   FontRun fontRun0702 =
1413   {
1414     {
1415       4u,
1416       1u
1417     },
1418     8u
1419   };
1420   FontRun fontRun0703 =
1421   {
1422     {
1423       5u,
1424       4u
1425     },
1426     2u
1427   };
1428   Vector<FontRun> fontRuns07;
1429   fontRuns07.PushBack( fontRun0701 );
1430   fontRuns07.PushBack( fontRun0702 );
1431   fontRuns07.PushBack( fontRun0703 );
1432
1433   FontDescriptionRun fontDescription0701 =
1434   {
1435     {
1436       0u,
1437       4u
1438     },
1439     const_cast<char*>( "TizenSansHebrew" ),
1440     15u,
1441     TextAbstraction::FontWeight::NORMAL,
1442     TextAbstraction::FontWidth::NORMAL,
1443     TextAbstraction::FontSlant::NORMAL,
1444     0u,
1445     true,
1446     false,
1447     false,
1448     false,
1449     false
1450   };
1451   FontDescriptionRun fontDescription0702 =
1452   {
1453     {
1454       5u,
1455       4u
1456     },
1457     const_cast<char*>( "TizenSansHebrew" ),
1458     15u,
1459     TextAbstraction::FontWeight::NORMAL,
1460     TextAbstraction::FontWidth::NORMAL,
1461     TextAbstraction::FontSlant::NORMAL,
1462     0u,
1463     true,
1464     false,
1465     false,
1466     false,
1467     false
1468   };
1469   Vector<FontDescriptionRun> fontDescriptions07;
1470   fontDescriptions07.PushBack( fontDescription0701 );
1471   fontDescriptions07.PushBack( fontDescription0702 );
1472
1473   FontRun fontRun0801 =
1474   {
1475     {
1476       0u,
1477       9u
1478     },
1479     2u
1480   };
1481   Vector<FontRun> fontRuns08;
1482   fontRuns08.PushBack( fontRun0801 );
1483
1484   Vector<FontDescriptionRun> fontDescriptions08;
1485
1486   FontRun fontRun0901 =
1487   {
1488     {
1489       0u,
1490       4u
1491     },
1492     3u
1493   };
1494   Vector<FontRun> fontRuns09;
1495   fontRuns09.PushBack( fontRun0901 );
1496
1497   Vector<FontDescriptionRun> fontDescriptions09;
1498   FontDescriptionRun fontDescription0901 =
1499   {
1500     {
1501       0u,
1502       4u
1503     },
1504     const_cast<char*>( "BreezeColorEmoji" ),
1505     16u,
1506     TextAbstraction::FontWeight::NORMAL,
1507     TextAbstraction::FontWidth::NORMAL,
1508     TextAbstraction::FontSlant::NORMAL,
1509     EMOJI_FONT_SIZE,
1510     true,
1511     false,
1512     false,
1513     false,
1514     true
1515   };
1516   fontDescriptions09.PushBack( fontDescription0901 );
1517
1518   FontRun fontRun1001 =
1519   {
1520     {
1521       0u,
1522       13u
1523     },
1524     4u
1525   };
1526   FontRun fontRun1002 =
1527   {
1528     {
1529       13u,
1530       9u
1531     },
1532     6u
1533   };
1534   FontRun fontRun1003 =
1535   {
1536     {
1537       22u,
1538       15u
1539     },
1540     5u
1541   };
1542   FontRun fontRun1004 =
1543   {
1544     {
1545       37u,
1546       9u
1547     },
1548     7u
1549   };
1550   Vector<FontRun> fontRuns10;
1551   fontRuns10.PushBack( fontRun1001 );
1552   fontRuns10.PushBack( fontRun1002 );
1553   fontRuns10.PushBack( fontRun1003 );
1554   fontRuns10.PushBack( fontRun1004 );
1555
1556   FontDescriptionRun fontDescription1001 =
1557   {
1558     {
1559       0u,
1560       13u
1561     },
1562     const_cast<char*>( "TizenSans" ),
1563     9u,
1564     TextAbstraction::FontWeight::NORMAL,
1565     TextAbstraction::FontWidth::NORMAL,
1566     TextAbstraction::FontSlant::NORMAL,
1567     pointSize01,
1568     true,
1569     false,
1570     false,
1571     false,
1572     true
1573   };
1574   FontDescriptionRun fontDescription1002 =
1575   {
1576     {
1577       13u,
1578       9u
1579     },
1580     const_cast<char*>( "TizenSansHebrew" ),
1581     15u,
1582     TextAbstraction::FontWeight::NORMAL,
1583     TextAbstraction::FontWidth::NORMAL,
1584     TextAbstraction::FontSlant::NORMAL,
1585     pointSize01,
1586     true,
1587     false,
1588     false,
1589     false,
1590     true
1591   };
1592   FontDescriptionRun fontDescription1003 =
1593   {
1594     {
1595       22u,
1596       15u
1597     },
1598     const_cast<char*>( "TizenSans" ),
1599     9u,
1600     TextAbstraction::FontWeight::NORMAL,
1601     TextAbstraction::FontWidth::NORMAL,
1602     TextAbstraction::FontSlant::NORMAL,
1603     pointSize02,
1604     true,
1605     false,
1606     false,
1607     false,
1608     true
1609   };
1610   FontDescriptionRun fontDescription1004 =
1611   {
1612     {
1613       37u,
1614       9u
1615     },
1616     const_cast<char*>( "TizenSansHebrew" ),
1617     15u,
1618     TextAbstraction::FontWeight::NORMAL,
1619     TextAbstraction::FontWidth::NORMAL,
1620     TextAbstraction::FontSlant::NORMAL,
1621     pointSize02,
1622     true,
1623     false,
1624     false,
1625     false,
1626     true
1627   };
1628   Vector<FontDescriptionRun> fontDescriptions10;
1629   fontDescriptions10.PushBack( fontDescription1001 );
1630   fontDescriptions10.PushBack( fontDescription1002 );
1631   fontDescriptions10.PushBack( fontDescription1003 );
1632   fontDescriptions10.PushBack( fontDescription1004 );
1633
1634   FontRun fontRun1101 =
1635   {
1636     {
1637       0u,
1638       22u
1639     },
1640     5u
1641   };
1642   Vector<FontRun> fontRuns11;
1643   fontRuns11.PushBack( fontRun1101 );
1644
1645   FontDescriptionRun fontDescription1101 =
1646   {
1647     {
1648       0,
1649       22u
1650     },
1651     const_cast<char*>( "TizenSans" ),
1652     9u,
1653     TextAbstraction::FontWeight::NORMAL,
1654     TextAbstraction::FontWidth::NORMAL,
1655     TextAbstraction::FontSlant::NORMAL,
1656     pointSize02,
1657     true,
1658     false,
1659     false,
1660     false,
1661     true
1662   };
1663   Vector<FontDescriptionRun> fontDescriptions11;
1664   fontDescriptions11.PushBack( fontDescription1101 );
1665
1666   FontRun fontRun1201 =
1667   {
1668     {
1669       0u,
1670       6u
1671     },
1672     8u
1673   };
1674   FontRun fontRun1202 =
1675   {
1676     {
1677       6u,
1678       1u
1679     },
1680     9u
1681   };
1682   FontRun fontRun1203 =
1683   {
1684     {
1685       7u,
1686       5u
1687     },
1688     8u
1689   };
1690   Vector<FontRun> fontRuns12;
1691   fontRuns12.PushBack( fontRun1201 );
1692   fontRuns12.PushBack( fontRun1202 );
1693   fontRuns12.PushBack( fontRun1203 );
1694
1695   FontDescriptionRun fontDescription1201 =
1696   {
1697     {
1698       0u,
1699       6u
1700     },
1701     const_cast<char*>( "TizenSans" ),
1702     9u,
1703     TextAbstraction::FontWeight::NORMAL,
1704     TextAbstraction::FontWidth::NORMAL,
1705     TextAbstraction::FontSlant::NORMAL,
1706     0u,
1707     true,
1708     false,
1709     false,
1710     false,
1711     false
1712   };
1713   FontDescriptionRun fontDescription1202 =
1714   {
1715     {
1716       6u,
1717       1u
1718     },
1719     const_cast<char*>( "TizenSans" ),
1720     9u,
1721     TextAbstraction::FontWeight::NORMAL,
1722     TextAbstraction::FontWidth::NORMAL,
1723     TextAbstraction::FontSlant::NORMAL,
1724     0u,
1725     true,
1726     false,
1727     false,
1728     false,
1729     false
1730   };
1731   FontDescriptionRun fontDescription1203 =
1732   {
1733     {
1734       7u,
1735       5u
1736     },
1737     const_cast<char*>( "TizenSans" ),
1738     9u,
1739     TextAbstraction::FontWeight::NORMAL,
1740     TextAbstraction::FontWidth::NORMAL,
1741     TextAbstraction::FontSlant::NORMAL,
1742     0u,
1743     true,
1744     false,
1745     false,
1746     false,
1747     false
1748   };
1749   Vector<FontDescriptionRun> fontDescriptions12;
1750   fontDescriptions12.PushBack( fontDescription1201 );
1751   fontDescriptions12.PushBack( fontDescription1202 );
1752   fontDescriptions12.PushBack( fontDescription1203 );
1753
1754   const ValidateFontsData data[] =
1755   {
1756     {
1757       "void text.",
1758       "",
1759       "/tizen/TizenSansRegular.ttf",
1760       TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
1761       1.0f,
1762       0u,
1763       0u,
1764       fontDescriptions01,
1765       fontRuns01
1766     },
1767     {
1768       "Easy latin script.",
1769       "Hello world",
1770       "/tizen/TizenSansRegular.ttf",
1771       TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
1772       1.0f,
1773       0u,
1774       11u,
1775       fontDescriptions02,
1776       fontRuns02
1777     },
1778     {
1779       "Different paragraphs.",
1780       "Hello world\nhello world\ndemo",
1781       "/tizen/TizenSansRegular.ttf",
1782       TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
1783       1.0f,
1784       0u,
1785       28u,
1786       fontDescriptions03,
1787       fontRuns03
1788     },
1789     {
1790       "Different paragraphs. Update the initial paragraph.",
1791       "Hello world\nhello world\ndemo",
1792       "/tizen/TizenSansRegular.ttf",
1793       TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
1794       1.0f,
1795       0u,
1796       12u,
1797       fontDescriptions03,
1798       fontRuns03
1799     },
1800     {
1801       "Different paragraphs. Update the middle paragraph.",
1802       "Hello world\nhello world\ndemo",
1803       "/tizen/TizenSansRegular.ttf",
1804       TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
1805       1.0f,
1806       12u,
1807       12u,
1808       fontDescriptions03,
1809       fontRuns03
1810     },
1811     {
1812       "Different paragraphs. Update the final paragraph.",
1813       "Hello world\nhello world\ndemo",
1814       "/tizen/TizenSansRegular.ttf",
1815       TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
1816       1.0f,
1817       24u,
1818       4u,
1819       fontDescriptions03,
1820       fontRuns03
1821     },
1822     {
1823       "Hebrew text. Default font: latin",
1824       "שלום עולם",
1825       "/tizen/TizenSansRegular.ttf",
1826       TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
1827       1.0f,
1828       0u,
1829       9u,
1830       fontDescriptions07,
1831       fontRuns07
1832     },
1833     {
1834       "Hebrew text. Default font: hebrew",
1835       "שלום עולם",
1836       "/tizen/TizenSansHebrewRegular.ttf",
1837       TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
1838       1.0f,
1839       0u,
1840       9u,
1841       fontDescriptions08,
1842       fontRuns08
1843     },
1844     {
1845       "Emojis",
1846       "\xF0\x9F\x98\x81\xF0\x9F\x98\x82\xF0\x9F\x98\x83\xF0\x9F\x98\x84",
1847       "/tizen/BreezeColorEmoji.ttf",
1848       EMOJI_FONT_SIZE,
1849       1.0f,
1850       0u,
1851       4u,
1852       fontDescriptions09,
1853       fontRuns09
1854     },
1855     {
1856       "Mix text. Default font: latin. Different font sizes",
1857       "Hello world, שלום עולם, hello world, שלום עולם",
1858       "/tizen/TizenSansRegular.ttf",
1859       TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
1860       1.0f,
1861       0u,
1862       46u,
1863       fontDescriptions10,
1864       fontRuns10
1865     },
1866     {
1867       "Unknown script -> changed to LATIN",
1868       "WRC – The Official App",
1869       "/tizen/TizenSansRegular.ttf",
1870       TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
1871       1.0f,
1872       0u,
1873       22u,
1874       fontDescriptions11,
1875       fontRuns11
1876     },
1877     {
1878       "Common script.",
1879       "Hello \tworld",
1880       "/tizen/TizenSansRegular.ttf",
1881       TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
1882       1.0f,
1883       0u,
1884       12u,
1885       fontDescriptions12,
1886       fontRuns12
1887     },
1888   };
1889   const unsigned int numberOfTests = 12u;
1890
1891   for( unsigned int index = 0u; index < numberOfTests; ++index )
1892   {
1893     if( !ValidateFontTest( data[index] ) )
1894     {
1895       tet_result(TET_FAIL);
1896     }
1897   }
1898
1899   tet_result(TET_PASS);
1900   END_TEST;
1901 }
1902
1903 int UtcDaliTextMultiLanguageLocaleChange(void)
1904 {
1905   ToolkitTestApplication application;
1906   tet_infoline(" UtcDaliTextMultiLanguageLocaleChange");
1907
1908   Adaptor &adaptor = application.GetAdaptor();
1909   MultilanguageSupport multilanguageSupport = MultilanguageSupport::Get();
1910
1911   std::string newLocale = "multi_TEST";
1912   adaptor.LocaleChangedSignal().Emit(newLocale);
1913
1914   application.SendNotification();
1915   application.Render();
1916
1917   DALI_TEST_EQUALS(newLocale.data(), GetImplementation(multilanguageSupport).GetLocale(), TEST_LOCATION);
1918
1919   END_TEST;
1920 }