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