[dali_1.0.50] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-toolkit-internal / utc-Dali-Text-MultiLanguage.cpp
1 /*
2  * Copyright (c) 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     0u,
175     11u,
176     TextAbstraction::LATIN
177   };
178   scriptRuns01.PushBack( scriptRun0100 );
179
180   // Mix of LTR '\n'and RTL
181   Vector<ScriptRun> scriptRuns02;
182   ScriptRun scriptRun0200 =
183   {
184     0u,
185     12u,
186     TextAbstraction::LATIN
187   };
188   ScriptRun scriptRun0201 =
189   {
190     12u,
191     13u,
192     TextAbstraction::ARABIC
193   };
194   scriptRuns02.PushBack( scriptRun0200 );
195   scriptRuns02.PushBack( scriptRun0201 );
196
197   // Mix of RTL '\n'and LTR
198   Vector<ScriptRun> scriptRuns03;
199   ScriptRun scriptRun0300 =
200   {
201     0u,
202     14u,
203     TextAbstraction::ARABIC
204   };
205   ScriptRun scriptRun0301 =
206   {
207     14u,
208     11u,
209     TextAbstraction::LATIN
210   };
211   scriptRuns03.PushBack( scriptRun0300 );
212   scriptRuns03.PushBack( scriptRun0301 );
213
214   // White spaces. At the beginning of the text.
215   Vector<ScriptRun> scriptRuns04;
216   ScriptRun scriptRun0400 =
217   {
218     0u,
219     16u,
220     TextAbstraction::LATIN
221   };
222   scriptRuns04.PushBack( scriptRun0400 );
223
224   // White spaces. At the end of the text.
225   Vector<ScriptRun> scriptRuns05;
226   ScriptRun scriptRun0500 =
227   {
228     0u,
229     16u,
230     TextAbstraction::LATIN
231   };
232   scriptRuns05.PushBack( scriptRun0500 );
233
234   // White spaces. At the middle of the text.
235   Vector<ScriptRun> scriptRuns06;
236   ScriptRun scriptRun0600 =
237   {
238     0u,
239     16u,
240     TextAbstraction::LATIN
241   };
242   scriptRuns06.PushBack( scriptRun0600 );
243
244   // White spaces between different scripts.
245   Vector<ScriptRun> scriptRuns07;
246   ScriptRun scriptRun0700 =
247   {
248     0u,
249     8u,
250     TextAbstraction::LATIN
251   };
252   ScriptRun scriptRun0701 =
253   {
254     8u,
255     5u,
256     TextAbstraction::HANGUL
257   };
258   scriptRuns07.PushBack( scriptRun0700 );
259   scriptRuns07.PushBack( scriptRun0701 );
260
261   // White spaces between different scripts and differetn directions. Starting LTR.
262   Vector<ScriptRun> scriptRuns08;
263   ScriptRun scriptRun0800 =
264   {
265     0u,
266     18u,
267     TextAbstraction::LATIN
268   };
269   ScriptRun scriptRun0801 =
270   {
271     18u,
272     14u,
273     TextAbstraction::ARABIC
274   };
275   ScriptRun scriptRun0802 =
276   {
277     32u,
278     18u,
279     TextAbstraction::HANGUL
280   };
281   scriptRuns08.PushBack( scriptRun0800 );
282   scriptRuns08.PushBack( scriptRun0801 );
283   scriptRuns08.PushBack( scriptRun0802 );
284
285   // White spaces between different scripts and differetn directions. Starting RTL.
286   Vector<ScriptRun> scriptRuns09;
287   ScriptRun scriptRun0900 =
288   {
289     0u,
290     21u,
291     TextAbstraction::ARABIC
292   };
293   ScriptRun scriptRun0901 =
294   {
295     21u,
296     16u,
297     TextAbstraction::LATIN
298   };
299   ScriptRun scriptRun0902 =
300   {
301     37u,
302     10u,
303     TextAbstraction::HANGUL
304   };
305   ScriptRun scriptRun0903 =
306   {
307     47u,
308     20u,
309     TextAbstraction::ARABIC
310   };
311   scriptRuns09.PushBack( scriptRun0900 );
312   scriptRuns09.PushBack( scriptRun0901 );
313   scriptRuns09.PushBack( scriptRun0902 );
314   scriptRuns09.PushBack( scriptRun0903 );
315
316   // Paragraphs with different directions.
317   Vector<ScriptRun> scriptRuns10;
318   ScriptRun scriptRun1000 =
319   {
320     0u,
321     20u,
322     TextAbstraction::ARABIC
323   };
324   ScriptRun scriptRun1001 =
325   {
326     20u,
327     12u,
328     TextAbstraction::HEBREW
329   };
330   ScriptRun scriptRun1002 =
331   {
332     32u,
333     17u,
334     TextAbstraction::ARABIC
335   };
336   ScriptRun scriptRun1003 =
337   {
338     49u,
339     18u,
340     TextAbstraction::LATIN
341   };
342   ScriptRun scriptRun1004 =
343   {
344     67u,
345     14u,
346     TextAbstraction::HANGUL
347   };
348   ScriptRun scriptRun1005 =
349   {
350     81u,
351     19u,
352     TextAbstraction::ARABIC
353   };
354   ScriptRun scriptRun1006 =
355   {
356     100u,
357     13u,
358     TextAbstraction::LATIN
359   };
360   ScriptRun scriptRun1007 =
361   {
362     113u,
363     16u,
364     TextAbstraction::HEBREW
365   };
366   ScriptRun scriptRun1008 =
367   {
368     129u,
369     20u,
370     TextAbstraction::LATIN
371   };
372   ScriptRun scriptRun1009 =
373   {
374     149u,
375     14u,
376     TextAbstraction::ARABIC
377   };
378   ScriptRun scriptRun1010 =
379   {
380     163u,
381     35u,
382     TextAbstraction::HANGUL
383   };
384   scriptRuns10.PushBack( scriptRun1000 );
385   scriptRuns10.PushBack( scriptRun1001 );
386   scriptRuns10.PushBack( scriptRun1002 );
387   scriptRuns10.PushBack( scriptRun1003 );
388   scriptRuns10.PushBack( scriptRun1004 );
389   scriptRuns10.PushBack( scriptRun1005 );
390   scriptRuns10.PushBack( scriptRun1006 );
391   scriptRuns10.PushBack( scriptRun1007 );
392   scriptRuns10.PushBack( scriptRun1008 );
393   scriptRuns10.PushBack( scriptRun1009 );
394   scriptRuns10.PushBack( scriptRun1010 );
395
396   // Paragraphs with no scripts mixed with paragraphs with scripts.
397   Vector<ScriptRun> scriptRuns11;
398   ScriptRun scriptRun1100 =
399   {
400     0u,
401     31u,
402     TextAbstraction::LATIN
403   };
404   ScriptRun scriptRun1101 =
405   {
406     31u,
407     21u,
408     TextAbstraction::HEBREW
409   };
410   scriptRuns11.PushBack( scriptRun1100 );
411   scriptRuns11.PushBack( scriptRun1101 );
412
413   // Paragraphs with no scripts.
414   Vector<ScriptRun> scriptRuns12;
415   ScriptRun scriptRun1200 =
416   {
417     0u,
418     11u,
419     TextAbstraction::LATIN
420   };
421   scriptRuns12.PushBack( scriptRun1200 );
422
423   const ScriptsData data[] =
424   {
425     {
426       "void text",
427       "",
428       scriptRuns00,
429     },
430     {
431       "Easy latin script",
432       "Hello world",
433       scriptRuns01,
434     },
435     {
436       "Mix of LTR '\\n'and RTL",
437       "Hello world\nمرحبا بالعالم",
438       scriptRuns02,
439     },
440     {
441       "Mix of RTL '\\n'and LTR",
442       "مرحبا بالعالم\nHello world",
443       scriptRuns03,
444     },
445     {
446       "White spaces. At the beginning of the text.",
447       "    Hello world.",
448       scriptRuns04,
449     },
450     {
451       "White spaces. At the end of the text.",
452       "Hello world.    ",
453       scriptRuns05,
454     },
455     {
456       "White spaces. At the middle of the text.",
457       "Hello     world.",
458       scriptRuns06,
459     },
460     {
461       "White spaces between different scripts.",
462       "  Hel   세계   ",
463       scriptRuns07,
464     },
465     {
466       "White spaces between different scripts and differetn directions. Starting LTR.",
467       "  Hello   world   مرحبا  بالعالم     안녕하세요   세계   ",
468       scriptRuns08,
469     },
470     {
471       "White spaces between different scripts and differetn directions. Starting RTL.",
472       "   مرحبا  بالعالم    Hello   world   안녕하세요   세계   مرحبا  بالعالم   ",
473       scriptRuns09
474     },
475     {
476       "Paragraphs with different directions.",
477       "   مرحبا  بالعالم   שלום עולם   مرحبا  بالعالم  \n "
478       " Hello   world   안녕하세요   세계   \n "
479       "  مرحبا  بالعالم  Hello   world    שלום עולם  \n  "
480       " Hello   world    مرحبا  بالعالم    안녕하세요   세계   \n "
481       "   안녕하세요   세계   ",
482       scriptRuns10
483     },
484     {
485       "Paragraphs with no scripts mixed with paragraphs with scripts.",
486       "  \n  \n   Hello   world  \n  \n  \n   שלום עולם  \n \n \n  ",
487       scriptRuns11
488     },
489     {
490       "Paragraphs with no scripts.",
491       "  \n  \n  \n  ",
492       scriptRuns12
493     }
494   };
495   const unsigned int numberOfTests = 13u;
496
497   for( unsigned int index = 0u; index < numberOfTests; ++index )
498   {
499     if( !ScriptsTest( data[index] ) )
500     {
501       tet_result(TET_FAIL);
502     }
503   }
504
505   tet_result(TET_PASS);
506   END_TEST;
507 }
508
509 int UtcDaliTextMultiLanguageValidateFonts01(void)
510 {
511   ToolkitTestApplication application;
512   tet_infoline(" UtcDaliTextMultiLanguageValidateFonts");
513
514   const ValidateFontsData data[] =
515   {
516     {
517       "void text",
518       "",
519     },
520     {
521       "Easy latin script",
522       "Hello world",
523     },
524   };
525   const unsigned int numberOfTests = 2u;
526
527   for( unsigned int index = 0u; index < numberOfTests; ++index )
528   {
529     if( !ValidateFontTest( data[index] ) )
530     {
531       tet_result(TET_FAIL);
532     }
533   }
534
535   tet_result(TET_PASS);
536   END_TEST;
537 }