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