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