8ad3b15af2f19167acd9b3d0e860ffb1a44186b3
[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
20 #include <stdlib.h>
21 #include <dali-toolkit/internal/text/character-set-conversion.h>
22 #include <dali-toolkit/internal/text/segmentation.h>
23 #include <dali-toolkit/internal/text/multi-language-support.h>
24 #include <dali-toolkit/internal/text/logical-model-impl.h>
25 #include <dali-toolkit-test-suite-utils.h>
26 #include <dali-toolkit/dali-toolkit.h>
27
28
29 using namespace Dali;
30 using namespace Toolkit;
31 using namespace Text;
32
33 // Tests the following functions with different scripts.
34 // Constructor, destructor and MultilanguageSupport::Get()
35 // void MultilanguageSupport::SetScripts( const Vector<Character>& text, const Vector<LineBreakInfo>& lineBreakInfo, Vector<ScriptRun>& scripts );
36 // void MultilanguageSupport::ValidateFonts( const Vector<Character>& text, const Vector<ScriptRun>& scripts, Vector<FontRun>& fonts );
37
38 //////////////////////////////////////////////////////////
39
40 namespace
41 {
42
43 struct ScriptsData
44 {
45   std::string description;      ///< Description of the experiment.
46   std::string text;             ///< Input text.
47   Vector<ScriptRun> scriptRuns; ///< Expected script runs.
48 };
49
50 struct ValidateFontsData
51 {
52   std::string description;  ///< Description of the experiment.
53   std::string text;         ///< Input text.
54 };
55
56 //////////////////////////////////////////////////////////
57
58 bool ScriptsTest( const ScriptsData& data )
59 {
60   MultilanguageSupport multilanguageSupport = MultilanguageSupport::Get();
61
62   // 1) Convert to utf32
63   Vector<Character> utf32;
64   utf32.Resize( data.text.size() );
65
66   const uint32_t numberOfCharacters = Utf8ToUtf32( reinterpret_cast<const uint8_t* const>( data.text.c_str() ),
67                                                    data.text.size(),
68                                                    &utf32[0u] );
69   utf32.Resize( numberOfCharacters );
70
71   // 2) Set the script info.
72   Vector<ScriptRun> scripts;
73   multilanguageSupport.SetScripts( utf32,
74                                    scripts );
75
76   // 3) Compare the results.
77
78   tet_printf( "Testing %s\n", data.description.c_str() );
79   if( scripts.Count() != data.scriptRuns.Count() )
80   {
81     tet_printf("ScriptsTest FAIL: different number of scripts. %d, should be %d\n", scripts.Count(), data.scriptRuns.Count() );
82     return false;
83   }
84
85   for( unsigned int index = 0u; index < scripts.Count(); ++index )
86   {
87     const ScriptRun& scriptRun1 = scripts[index];
88     const ScriptRun& scriptRun2 = data.scriptRuns[index];
89
90     if( scriptRun1.characterRun.characterIndex != scriptRun2.characterRun.characterIndex )
91     {
92       tet_printf("ScriptsTest FAIL: different character index. %d, should be %d\n", scriptRun1.characterRun.characterIndex, scriptRun2.characterRun.characterIndex );
93       return false;
94     }
95
96     if( scriptRun1.characterRun.numberOfCharacters != scriptRun2.characterRun.numberOfCharacters )
97     {
98       tet_printf("ScriptsTest FAIL: different number of characters. %d, should be %d\n", scriptRun1.characterRun.numberOfCharacters, scriptRun2.characterRun.numberOfCharacters );
99       return false;
100     }
101
102     if( scriptRun1.script != scriptRun2.script )
103     {
104       tet_printf("ScriptsTest FAIL: different script. %s, should be %s\n", TextAbstraction::ScriptName[scriptRun1.script], TextAbstraction::ScriptName[scriptRun2.script] );
105       return false;
106     }
107   }
108
109   return true;
110 }
111
112 bool ValidateFontTest( const ValidateFontsData& data )
113 {
114   MultilanguageSupport multilanguageSupport = MultilanguageSupport::Get();
115
116   // 1) Convert to utf32
117   Vector<Character> utf32;
118   utf32.Resize( data.text.size() );
119
120   const uint32_t numberOfCharacters = Utf8ToUtf32( reinterpret_cast<const uint8_t* const>( data.text.c_str() ),
121                                                    data.text.size(),
122                                                    &utf32[0u] );
123   utf32.Resize( numberOfCharacters );
124
125   // 2) Set the script info.
126   Vector<ScriptRun> scripts;
127   multilanguageSupport.SetScripts( utf32,
128                                    scripts );
129
130   Vector<FontRun> fonts;
131   // 3) Validate the fonts
132   multilanguageSupport.ValidateFonts( utf32,
133                                       scripts,
134                                       fonts );
135
136   return true;
137 }
138
139 } // namespace
140
141 int UtcDaliTextMultiLanguageConstructor(void)
142 {
143   ToolkitTestApplication application;
144   tet_infoline(" UtcDaliTextMultiLanguageConstructor");
145
146   MultilanguageSupport multilanguageSupport;
147   DALI_TEST_CHECK( !multilanguageSupport );
148
149   MultilanguageSupport multilanguageSupport1 = MultilanguageSupport::Get();
150   DALI_TEST_CHECK( multilanguageSupport1 );
151
152   // To increase coverage.
153   MultilanguageSupport multilanguageSupport2 = MultilanguageSupport::Get();
154   DALI_TEST_CHECK( multilanguageSupport2 );
155
156   DALI_TEST_CHECK( multilanguageSupport1 == multilanguageSupport2 );
157
158   tet_result(TET_PASS);
159   END_TEST;
160 }
161
162 int UtcDaliTextMultiLanguageSetScripts(void)
163 {
164   ToolkitTestApplication application;
165   tet_infoline(" UtcDaliTextMultiLanguageSetScripts" );
166
167   // Void text.
168   Vector<ScriptRun> scriptRuns00;
169
170   // Hello world.
171   Vector<ScriptRun> scriptRuns01;
172   ScriptRun scriptRun0100 =
173   {
174     {
175       0u,
176       11u,
177     },
178     TextAbstraction::LATIN
179   };
180   scriptRuns01.PushBack( scriptRun0100 );
181
182   // Mix of LTR '\n'and RTL
183   Vector<ScriptRun> scriptRuns02;
184   ScriptRun scriptRun0200 =
185   {
186     {
187       0u,
188       12u,
189     },
190     TextAbstraction::LATIN
191   };
192   ScriptRun scriptRun0201 =
193   {
194     {
195       12u,
196       13u,
197     },
198     TextAbstraction::ARABIC
199   };
200   scriptRuns02.PushBack( scriptRun0200 );
201   scriptRuns02.PushBack( scriptRun0201 );
202
203   // Mix of RTL '\n'and LTR
204   Vector<ScriptRun> scriptRuns03;
205   ScriptRun scriptRun0300 =
206   {
207     {
208       0u,
209       14u,
210     },
211     TextAbstraction::ARABIC
212   };
213   ScriptRun scriptRun0301 =
214   {
215     {
216       14u,
217       11u,
218     },
219     TextAbstraction::LATIN
220   };
221   scriptRuns03.PushBack( scriptRun0300 );
222   scriptRuns03.PushBack( scriptRun0301 );
223
224   // White spaces. At the beginning of the text.
225   Vector<ScriptRun> scriptRuns04;
226   ScriptRun scriptRun0400 =
227   {
228     {
229       0u,
230       16u,
231     },
232     TextAbstraction::LATIN
233   };
234   scriptRuns04.PushBack( scriptRun0400 );
235
236   // White spaces. At the end of the text.
237   Vector<ScriptRun> scriptRuns05;
238   ScriptRun scriptRun0500 =
239   {
240     {
241       0u,
242       16u,
243     },
244     TextAbstraction::LATIN
245   };
246   scriptRuns05.PushBack( scriptRun0500 );
247
248   // White spaces. At the middle of the text.
249   Vector<ScriptRun> scriptRuns06;
250   ScriptRun scriptRun0600 =
251   {
252     {
253       0u,
254       16u,
255     },
256     TextAbstraction::LATIN
257   };
258   scriptRuns06.PushBack( scriptRun0600 );
259
260   // White spaces between different scripts.
261   Vector<ScriptRun> scriptRuns07;
262   ScriptRun scriptRun0700 =
263   {
264     {
265       0u,
266       8u,
267     },
268     TextAbstraction::LATIN
269   };
270   ScriptRun scriptRun0701 =
271   {
272     {
273       8u,
274       5u,
275     },
276     TextAbstraction::HANGUL
277   };
278   scriptRuns07.PushBack( scriptRun0700 );
279   scriptRuns07.PushBack( scriptRun0701 );
280
281   // White spaces between different scripts and differetn directions. Starting LTR.
282   Vector<ScriptRun> scriptRuns08;
283   ScriptRun scriptRun0800 =
284   {
285     {
286       0u,
287       18u,
288     },
289     TextAbstraction::LATIN
290   };
291   ScriptRun scriptRun0801 =
292   {
293     {
294       18u,
295       14u,
296     },
297     TextAbstraction::ARABIC
298   };
299   ScriptRun scriptRun0802 =
300   {
301     {
302       32u,
303       18u,
304     },
305     TextAbstraction::HANGUL
306   };
307   scriptRuns08.PushBack( scriptRun0800 );
308   scriptRuns08.PushBack( scriptRun0801 );
309   scriptRuns08.PushBack( scriptRun0802 );
310
311   // White spaces between different scripts and differetn directions. Starting RTL.
312   Vector<ScriptRun> scriptRuns09;
313   ScriptRun scriptRun0900 =
314   {
315     {
316       0u,
317       21u,
318     },
319     TextAbstraction::ARABIC
320   };
321   ScriptRun scriptRun0901 =
322   {
323     {
324       21u,
325       16u,
326     },
327     TextAbstraction::LATIN
328   };
329   ScriptRun scriptRun0902 =
330   {
331     {
332       37u,
333       10u,
334     },
335     TextAbstraction::HANGUL
336   };
337   ScriptRun scriptRun0903 =
338   {
339     {
340       47u,
341       20u,
342     },
343     TextAbstraction::ARABIC
344   };
345   scriptRuns09.PushBack( scriptRun0900 );
346   scriptRuns09.PushBack( scriptRun0901 );
347   scriptRuns09.PushBack( scriptRun0902 );
348   scriptRuns09.PushBack( scriptRun0903 );
349
350   // Paragraphs with different directions.
351   Vector<ScriptRun> scriptRuns10;
352   ScriptRun scriptRun1000 =
353   {
354     {
355       0u,
356       20u,
357     },
358     TextAbstraction::ARABIC
359   };
360   ScriptRun scriptRun1001 =
361   {
362     {
363       20u,
364       12u,
365     },
366     TextAbstraction::HEBREW
367   };
368   ScriptRun scriptRun1002 =
369   {
370     {
371       32u,
372       17u,
373     },
374     TextAbstraction::ARABIC
375   };
376   ScriptRun scriptRun1003 =
377   {
378     {
379       49u,
380       18u,
381     },
382     TextAbstraction::LATIN
383   };
384   ScriptRun scriptRun1004 =
385   {
386     {
387       67u,
388       14u,
389     },
390     TextAbstraction::HANGUL
391   };
392   ScriptRun scriptRun1005 =
393   {
394     {
395       81u,
396       19u,
397     },
398     TextAbstraction::ARABIC
399   };
400   ScriptRun scriptRun1006 =
401   {
402     {
403       100u,
404       13u,
405     },
406     TextAbstraction::LATIN
407   };
408   ScriptRun scriptRun1007 =
409   {
410     {
411       113u,
412       16u,
413     },
414     TextAbstraction::HEBREW
415   };
416   ScriptRun scriptRun1008 =
417   {
418     {
419       129u,
420       20u,
421     },
422     TextAbstraction::LATIN
423   };
424   ScriptRun scriptRun1009 =
425   {
426     {
427       149u,
428       14u,
429     },
430     TextAbstraction::ARABIC
431   };
432   ScriptRun scriptRun1010 =
433   {
434     {
435       163u,
436       35u,
437     },
438     TextAbstraction::HANGUL
439   };
440   scriptRuns10.PushBack( scriptRun1000 );
441   scriptRuns10.PushBack( scriptRun1001 );
442   scriptRuns10.PushBack( scriptRun1002 );
443   scriptRuns10.PushBack( scriptRun1003 );
444   scriptRuns10.PushBack( scriptRun1004 );
445   scriptRuns10.PushBack( scriptRun1005 );
446   scriptRuns10.PushBack( scriptRun1006 );
447   scriptRuns10.PushBack( scriptRun1007 );
448   scriptRuns10.PushBack( scriptRun1008 );
449   scriptRuns10.PushBack( scriptRun1009 );
450   scriptRuns10.PushBack( scriptRun1010 );
451
452   // Paragraphs with no scripts mixed with paragraphs with scripts.
453   Vector<ScriptRun> scriptRuns11;
454   ScriptRun scriptRun1100 =
455   {
456     {
457       0u,
458       31u,
459     },
460     TextAbstraction::LATIN
461   };
462   ScriptRun scriptRun1101 =
463   {
464     {
465       31u,
466       21u,
467     },
468     TextAbstraction::HEBREW
469   };
470   scriptRuns11.PushBack( scriptRun1100 );
471   scriptRuns11.PushBack( scriptRun1101 );
472
473   // Paragraphs with no scripts.
474   Vector<ScriptRun> scriptRuns12;
475   ScriptRun scriptRun1200 =
476   {
477     {
478       0u,
479       11u,
480     },
481     TextAbstraction::LATIN
482   };
483   scriptRuns12.PushBack( scriptRun1200 );
484
485   const ScriptsData data[] =
486   {
487     {
488       "void text",
489       "",
490       scriptRuns00,
491     },
492     {
493       "Easy latin script",
494       "Hello world",
495       scriptRuns01,
496     },
497     {
498       "Mix of LTR '\\n'and RTL",
499       "Hello world\nمرحبا بالعالم",
500       scriptRuns02,
501     },
502     {
503       "Mix of RTL '\\n'and LTR",
504       "مرحبا بالعالم\nHello world",
505       scriptRuns03,
506     },
507     {
508       "White spaces. At the beginning of the text.",
509       "    Hello world.",
510       scriptRuns04,
511     },
512     {
513       "White spaces. At the end of the text.",
514       "Hello world.    ",
515       scriptRuns05,
516     },
517     {
518       "White spaces. At the middle of the text.",
519       "Hello     world.",
520       scriptRuns06,
521     },
522     {
523       "White spaces between different scripts.",
524       "  Hel   세계   ",
525       scriptRuns07,
526     },
527     {
528       "White spaces between different scripts and differetn directions. Starting LTR.",
529       "  Hello   world   مرحبا  بالعالم     안녕하세요   세계   ",
530       scriptRuns08,
531     },
532     {
533       "White spaces between different scripts and differetn directions. Starting RTL.",
534       "   مرحبا  بالعالم    Hello   world   안녕하세요   세계   مرحبا  بالعالم   ",
535       scriptRuns09
536     },
537     {
538       "Paragraphs with different directions.",
539       "   مرحبا  بالعالم   שלום עולם   مرحبا  بالعالم  \n "
540       " Hello   world   안녕하세요   세계   \n "
541       "  مرحبا  بالعالم  Hello   world    שלום עולם  \n  "
542       " Hello   world    مرحبا  بالعالم    안녕하세요   세계   \n "
543       "   안녕하세요   세계   ",
544       scriptRuns10
545     },
546     {
547       "Paragraphs with no scripts mixed with paragraphs with scripts.",
548       "  \n  \n   Hello   world  \n  \n  \n   שלום עולם  \n \n \n  ",
549       scriptRuns11
550     },
551     {
552       "Paragraphs with no scripts.",
553       "  \n  \n  \n  ",
554       scriptRuns12
555     }
556   };
557   const unsigned int numberOfTests = 13u;
558
559   for( unsigned int index = 0u; index < numberOfTests; ++index )
560   {
561     if( !ScriptsTest( data[index] ) )
562     {
563       tet_result(TET_FAIL);
564     }
565   }
566
567   tet_result(TET_PASS);
568   END_TEST;
569 }
570
571 int UtcDaliTextMultiLanguageValidateFonts01(void)
572 {
573   ToolkitTestApplication application;
574   tet_infoline(" UtcDaliTextMultiLanguageValidateFonts");
575
576   const ValidateFontsData data[] =
577   {
578     {
579       "void text",
580       "",
581     },
582     {
583       "Easy latin script",
584       "Hello world",
585     },
586   };
587   const unsigned int numberOfTests = 2u;
588
589   for( unsigned int index = 0u; index < numberOfTests; ++index )
590   {
591     if( !ValidateFontTest( data[index] ) )
592     {
593       tet_result(TET_FAIL);
594     }
595   }
596
597   tet_result(TET_PASS);
598   END_TEST;
599 }