[dali_1.1.24] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-toolkit-internal / utc-Dali-BidirectionalSupport.cpp
1 /*
2  * Copyright (c) 2016 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
21 #include <dali/devel-api/text-abstraction/bidirectional-support.h>
22 #include <dali-toolkit/internal/text/bidirectional-support.h>
23 #include <dali-toolkit/internal/text/character-set-conversion.h>
24 #include <dali-toolkit/internal/text/text-run-container.h>
25 #include <dali-toolkit-test-suite-utils.h>
26 #include <dali-toolkit/dali-toolkit.h>
27 #include <toolkit-text-model.h>
28
29 using namespace Dali;
30 using namespace Toolkit;
31 using namespace Text;
32
33 // Tests the following functions.
34 //
35 // void SetBidirectionalInfo( const Vector<Character>& text,
36 //                            const Vector<ScriptRun>& scripts,
37 //                            const Vector<LineBreakInfo>& lineBreakInfo,
38 //                            CharacterIndex startIndex,
39 //                            Length numberOfCharacters,
40 //                            Vector<BidirectionalParagraphInfoRun>& bidirectionalInfo )
41 // void ReorderLines( const Vector<BidirectionalParagraphInfoRun>& bidirectionalInfo,
42 //                    CharacterIndex startIndex,
43 //                    Length numberOfCharacters,
44 //                    Vector<LineRun>& lineRuns,
45 //                    Vector<BidirectionalLineInfoRun>& lineInfoRuns )
46 // bool GetMirroredText( const Vector<Character>& text,
47 //                       Vector<CharacterDirection>& directions,
48 //                       const Vector<BidirectionalParagraphInfoRun>& bidirectionalInfo,
49 //                       CharacterIndex startIndex,
50 //                       Length numberOfCharacters,
51 //                       Vector<Character>& mirroredText )
52 // void GetCharactersDirection( const Vector<BidirectionalParagraphInfoRun>& bidirectionalInfo,
53 //                              CharacterIndex startIndex,
54 //                              Length numberOfCharacters,
55 //                              Vector<CharacterDirection>& directions )
56
57 //////////////////////////////////////////////////////////
58
59 namespace
60 {
61
62 struct SetBidirectionalInfoData
63 {
64   std::string   description;                 ///< Description of the test.
65   std::string   text;                        ///< Input text.
66   unsigned int  startIndex;                  ///< The index from where the model is updated.
67   unsigned int  numberOfCharacters;          ///< The number of characters to update.
68   unsigned int  numberOfParagraphs;          ///< The expected number of bidirectional paragraphs.
69   unsigned int* indices;                     ///< The expected indices to the first character of each paragraph.
70   unsigned int* numberOfParagraphCharacters; ///< The expected number of characters of each paragraph.
71   bool*         directions;                  ///< The expected direction of each paragraph.
72 };
73
74 struct BidiLineData
75 {
76   unsigned int  characterIndex;
77   unsigned int  numberOfCharacters;
78   unsigned int* visualToLogical;
79 };
80
81 struct ReorderLinesData
82 {
83   std::string   description;        ///< Description of the test.
84   std::string   text;               ///< Input text.
85   unsigned int  startIndex;         ///< The index from where the model is updated.
86   unsigned int  numberOfCharacters; ///< The number of characters.
87   unsigned int  numberOfLineInfo;   ///< The number or reordered lines.
88   BidiLineData* bidiLineData;       ///< The bidirectional line info.
89 };
90
91 struct GetMirroredTextData
92 {
93   std::string  description;        ///< Description of the test.
94   std::string  text;               ///< Input text.
95   unsigned int startIndex;         ///< The index from where the model is updated.
96   unsigned int numberOfCharacters; ///< The number of the characters.
97   std::string  mirroredText;       ///< The expected result.
98 };
99
100 struct GetCharactersDirectionData
101 {
102   std::string  description;         ///< Description of the test.
103   std::string  text;                ///< Input text.
104   unsigned int startIndex;          ///< The index from where the model is updated.
105   unsigned int numberOfCharacters;  ///< The number of characters.
106   bool*        directions;          ///< The expected directions.
107 };
108
109 bool SetBidirectionalInfoTest( const SetBidirectionalInfoData& data )
110 {
111   // 1) Create the model.
112   LogicalModelPtr logicalModel = LogicalModel::New();
113   VisualModelPtr visualModel = VisualModel::New();
114   Size textArea(100.f, 60.f);
115   Size layoutSize;
116
117   // Create the model.
118   CreateTextModel( data.text,
119                    textArea,
120                    layoutSize,
121                    logicalModel,
122                    visualModel );
123
124   // 2) Clear the bidirectional paragraph info data.
125   Vector<BidirectionalParagraphInfoRun>& bidirectionalInfo = logicalModel->mBidirectionalParagraphInfo;
126   if( 0u != data.numberOfCharacters )
127   {
128     ClearCharacterRuns( data.startIndex,
129                         data.startIndex + data.numberOfCharacters - 1u,
130                         bidirectionalInfo );
131   }
132
133   // 3) Call the SetBidirectionalInfo() function.
134   SetBidirectionalInfo( logicalModel->mText,
135                         logicalModel->mScriptRuns,
136                         logicalModel->mLineBreakInfo,
137                         data.startIndex,
138                         data.numberOfCharacters,
139                         bidirectionalInfo );
140
141   // 4) Compare with the expected results.
142   TextAbstraction::BidirectionalSupport bidirectionalSupport = TextAbstraction::BidirectionalSupport::Get();
143
144   if( data.numberOfParagraphs != bidirectionalInfo.Count() )
145   {
146     // Different number of expected bidirectional paragraphs.
147     std::cout << "  Different number of bidi paragraphs : " << bidirectionalInfo.Count() << ", expected : " << data.numberOfParagraphs << std::endl;
148     return false;
149   }
150
151   for( unsigned int index = 0u; index < data.numberOfParagraphs; ++index )
152   {
153     const BidirectionalParagraphInfoRun& run = bidirectionalInfo[index];
154
155     const CharacterDirection direction = bidirectionalSupport.GetParagraphDirection( run.bidirectionalInfoIndex );
156     if( direction != data.directions[index] )
157     {
158       std::cout << "  Different direction" << std::endl;
159       std::cout << "        paragraph : " << index << std::endl;
160       std::cout << "            index : " << run.characterRun.characterIndex << ", num chars : " << run.characterRun.numberOfCharacters << ", direction : " << direction << std::endl;
161       std::cout << "  expected, index : " << data.indices[index] << ", num chars : " << data.numberOfParagraphCharacters[index] << ", direction : " << data.directions[index] << std::endl;
162       return false;
163     }
164
165     if( run.characterRun.characterIndex != data.indices[index] )
166     {
167       std::cout << "  Different index" << std::endl;
168       std::cout << "        paragraph : " << index << std::endl;
169       std::cout << "            index : " << run.characterRun.characterIndex << ", num chars : " << run.characterRun.numberOfCharacters << ", direction : " << direction << std::endl;
170       std::cout << "  expected, index : " << data.indices[index] << ", num chars : " << data.numberOfParagraphCharacters[index] << ", direction : " << data.directions[index] << std::endl;
171       return false;
172     }
173     if( run.characterRun.numberOfCharacters != data.numberOfParagraphCharacters[index] )
174     {
175       std::cout << "  Different number of characters" << std::endl;
176       std::cout << "        paragraph : " << index << std::endl;
177       std::cout << "            index : " << run.characterRun.characterIndex << ", num chars : " << run.characterRun.numberOfCharacters << ", direction : " << direction << std::endl;
178       std::cout << "  expected, index : " << data.indices[index] << ", num chars : " << data.numberOfParagraphCharacters[index] << ", direction : " << data.directions[index] << std::endl;
179       return false;
180     }
181   }
182
183   return true;
184 }
185
186 /**
187  * @brief Frees previously allocated bidirectional resources.
188  *
189  * @param[in] bidirectionalLineInfo Bidirectional info per line.
190  * @param[in] startIndex Index to the first line with bidirectional info to be freed.
191  * @param[in] endIndex Index to the last line with bidirectional info to be freed.
192  */
193 void FreeBidirectionalLineInfoResources( Vector<BidirectionalLineInfoRun> bidirectionalLineInfo,
194                                          uint32_t startIndex,
195                                          uint32_t endIndex )
196 {
197   // Free the allocated memory used to store the conversion table in the bidirectional line info run.
198   for( Vector<BidirectionalLineInfoRun>::Iterator it = bidirectionalLineInfo.Begin() + startIndex,
199          endIt = bidirectionalLineInfo.Begin() + endIndex;
200        it != endIt;
201        ++it )
202   {
203     BidirectionalLineInfoRun& bidiLineInfo = *it;
204
205     free( bidiLineInfo.visualToLogicalMap );
206   }
207 }
208
209 bool ReorderLinesTest( const ReorderLinesData& data )
210 {
211   // 1) Create the model.
212   LogicalModelPtr logicalModel = LogicalModel::New();
213   VisualModelPtr visualModel = VisualModel::New();
214   Size textArea(100.f, 300.f);
215   Size layoutSize;
216
217   // Create the model.
218   CreateTextModel( data.text,
219                    textArea,
220                    layoutSize,
221                    logicalModel,
222                    visualModel );
223
224   // 2) Clear the bidirectional line info data.
225   uint32_t startRemoveIndex = logicalModel->mBidirectionalLineInfo.Count();
226   uint32_t endRemoveIndex = startRemoveIndex;
227   ClearCharacterRuns( data.startIndex,
228                       data.startIndex + data.numberOfCharacters - 1u,
229                       logicalModel->mBidirectionalLineInfo,
230                       startRemoveIndex,
231                       endRemoveIndex );
232
233   // Index to the first index to be removed.
234
235   FreeBidirectionalLineInfoResources( logicalModel->mBidirectionalLineInfo, startRemoveIndex, endRemoveIndex );
236   BidirectionalLineInfoRun* bidiLineBuffer = logicalModel->mBidirectionalLineInfo.Begin();
237   logicalModel->mBidirectionalLineInfo.Erase( bidiLineBuffer + startRemoveIndex,
238                                               bidiLineBuffer + endRemoveIndex );
239
240   // 3) Call the function ReorderLines()
241
242   ReorderLines( logicalModel->mBidirectionalParagraphInfo,
243                 data.startIndex,
244                 data.numberOfCharacters,
245                 visualModel->mLines,
246                 logicalModel->mBidirectionalLineInfo );
247
248   // 4) Compare the results.
249
250   if( data.numberOfLineInfo != logicalModel->mBidirectionalLineInfo.Count() )
251   {
252     // Different number of bidirectional lines.
253     std::cout << "  different number of bidi lines : " << logicalModel->mBidirectionalLineInfo.Count() << ", expected : " << data.numberOfLineInfo << std::endl;
254     for( unsigned int index = 0u; index < logicalModel->mBidirectionalLineInfo.Count(); ++index )
255     {
256       const BidirectionalLineInfoRun& run = logicalModel->mBidirectionalLineInfo[index];
257       const BidiLineData& bidiLineData = data.bidiLineData[index];
258
259       std::cout << "  bidi line : " << index << ", index : " << run.characterRun.characterIndex << ", num chars : " << run.characterRun.numberOfCharacters << std::endl;
260       std::cout << "                      expected index : " << bidiLineData.characterIndex << ", num chars : " << bidiLineData.numberOfCharacters << std::endl;
261     }
262     return false;
263   }
264
265   for( unsigned int index = 0u; index < data.numberOfLineInfo; ++index )
266   {
267     const BidirectionalLineInfoRun& run = logicalModel->mBidirectionalLineInfo[index];
268     const BidiLineData& bidiLineData = data.bidiLineData[index];
269
270     if( bidiLineData.characterIndex != run.characterRun.characterIndex )
271     {
272       std::cout << "  bidi line : " << index << ", index : " << run.characterRun.characterIndex << ", num chars : " << run.characterRun.numberOfCharacters << std::endl;
273       std::cout << "                      expected index : " << bidiLineData.characterIndex << ", num chars : " << bidiLineData.numberOfCharacters << std::endl;
274       return false;
275     }
276     if( bidiLineData.numberOfCharacters != run.characterRun.numberOfCharacters )
277     {
278       std::cout << "  bidi line : " << index << ", index : " << run.characterRun.characterIndex << ", num chars : " << run.characterRun.numberOfCharacters << std::endl;
279       std::cout << "                      expected index : " << bidiLineData.characterIndex << ", num chars : " << bidiLineData.numberOfCharacters << std::endl;
280       return false;
281     }
282
283     for( unsigned int i = 0u; i < run.characterRun.numberOfCharacters; ++i )
284     {
285       if( bidiLineData.visualToLogical[i] != run.visualToLogicalMap[i] )
286       {
287         std::cout << "           v2l : ";
288         for( unsigned int i = 0u; i < run.characterRun.numberOfCharacters; ++i )
289         {
290           std::cout << run.visualToLogicalMap[i] << " ";
291         }
292         std::cout << std::endl;
293         std::cout << "  expected v2l : ";
294         for( unsigned int i = 0u; i < run.characterRun.numberOfCharacters; ++i )
295         {
296           std::cout << bidiLineData.visualToLogical[i] << " ";
297         }
298         std::cout << std::endl;
299
300         return false;
301       }
302     }
303   }
304
305   return true;
306 }
307
308 bool GetMirroredTextTest( const GetMirroredTextData& data )
309 {
310   // 1) Create the model.
311   LogicalModelPtr logicalModel = LogicalModel::New();
312   VisualModelPtr visualModel = VisualModel::New();
313   Size textArea(100.f, 60.f);
314   Size layoutSize;
315
316   // Create the model.
317   CreateTextModel( data.text,
318                    textArea,
319                    layoutSize,
320                    logicalModel,
321                    visualModel );
322
323   // 2) Call the GetMirroredText() function for the whole text
324   Vector<Character> mirroredText;
325   bool mirrored = false;
326   mirrored = GetMirroredText( logicalModel->mText,
327                               logicalModel->mCharacterDirections,
328                               logicalModel->mBidirectionalParagraphInfo,
329                               0u,
330                               logicalModel->mText.Count(),
331                               mirroredText );
332
333   // 3) Call the GetMirroredText() function for the given index + number of characters
334   mirrored = GetMirroredText( logicalModel->mText,
335                               logicalModel->mCharacterDirections,
336                               logicalModel->mBidirectionalParagraphInfo,
337                               data.startIndex,
338                               data.numberOfCharacters,
339                               mirroredText );
340
341   // 4) Compare the results.
342
343   // Convert to utf8
344   std::string mirroredString;
345   Utf32ToUtf8( mirroredText.Begin(),
346                mirroredText.Count(),
347                mirroredString );
348
349   if( !mirrored && ( mirroredString != data.text ) )
350   {
351     std::cout << "  No mirrored text and mirroredString != data.text." << std::endl;
352     std::cout << "  mirrored string : [" << mirroredString << "]" << std::endl;
353     std::cout << "             text : [" << data.text << "]" << std::endl;
354     return false;
355   }
356
357   if( mirrored && ( mirroredString == data.text ) )
358   {
359     std::cout << "  Mirrored text and mirroredString == data.text." << std::endl;
360     std::cout << "  mirrored string : [" << mirroredString << "]" << std::endl;
361     std::cout << "             text : [" << data.text << "]" << std::endl;
362     return false;
363   }
364
365   if( mirrored && ( mirroredString != data.mirroredText ) )
366   {
367     std::cout << "  Mirrored text and mirroredString != data.mirroredText." << std::endl;
368     std::cout << "  mirrored string : [" << mirroredString << "]" << std::endl;
369     std::cout << "             text : [" << data.mirroredText << "]" << std::endl;
370     return false;
371   }
372
373   return true;
374 }
375
376 bool GetCharactersDirectionTest( const GetCharactersDirectionData& data )
377 {
378   // 1) Create the model.
379   LogicalModelPtr logicalModel = LogicalModel::New();
380   VisualModelPtr visualModel = VisualModel::New();
381   Size textArea(100.f, 60.f);
382   Size layoutSize;
383
384   // Create the model.
385   CreateTextModel( data.text,
386                    textArea,
387                    layoutSize,
388                    logicalModel,
389                    visualModel );
390
391   Vector<BidirectionalParagraphInfoRun>& bidirectionalInfo = logicalModel->mBidirectionalParagraphInfo;
392
393   // 2) Clear the direction info data.
394   Vector<CharacterDirection>& directions = logicalModel->mCharacterDirections;
395
396   directions.Erase( directions.Begin() + data.startIndex,
397                     directions.Begin() + data.startIndex + data.numberOfCharacters );
398
399   // 3) Call GetCharactersDirection() function.
400
401   GetCharactersDirection( bidirectionalInfo,
402                           logicalModel->mText.Count(),
403                           data.startIndex,
404                           data.numberOfCharacters,
405                           directions );
406
407   for( unsigned int index = 0u; index < logicalModel->mText.Count(); ++index )
408   {
409     if( data.directions[index] != directions[index] )
410     {
411       return false;
412     }
413   }
414
415   return true;
416 }
417
418 } // namespace
419
420 //////////////////////////////////////////////////////////
421
422 int UtcDaliSetBidirectionalInfo(void)
423 {
424   ToolkitTestApplication application;
425   tet_infoline(" UtcDaliSetBidirectionalInfo");
426
427   unsigned int indices01[] = {};
428   unsigned int numberOfCharacters01[] = {};
429   bool         direction01[] = {};
430   unsigned int indices02[] = {};
431   unsigned int numberOfCharacters02[] = {};
432   bool         direction02[] = {};
433   unsigned int indices03[] = { 17u, 48u };
434   unsigned int numberOfCharacters03[] = { 14u, 14u };
435   bool         direction03[] = { true, true };
436   unsigned int indices04[] = { 17u, 31u, 79u };
437   unsigned int numberOfCharacters04[] = { 14u, 48u, 31u };
438   bool         direction04[] = { true, false, true };
439   unsigned int indices05[] = { 17u, 41u, 117u };
440   unsigned int numberOfCharacters05[] = { 24u, 76u, 49u };
441   bool         direction05[] = { true, false, true };
442   unsigned int indices06[] = { 17u, 48u };
443   unsigned int numberOfCharacters06[] = { 14u, 14u };
444   bool         direction06[] = { true, true };
445   unsigned int indices07[] = { 17u, 31u, 79u };
446   unsigned int numberOfCharacters07[] = { 14u, 48u, 31u };
447   bool         direction07[] = { true, false, true };
448   unsigned int indices08[] = { 17u, 41u, 117u };
449   unsigned int numberOfCharacters08[] = { 24u, 76u, 49u };
450   bool         direction08[] = { true, false, true };
451
452   struct SetBidirectionalInfoData data[] =
453   {
454     {
455       "Zero characters",
456       "",
457       0u,
458       0u,
459       0u,
460       indices01,
461       numberOfCharacters01,
462       direction01
463     },
464     {
465       "Some left to right paragraphs",
466       "Hello world\ndemo\n\n",
467       0u,
468       18u,
469       0u,
470       indices02,
471       numberOfCharacters02,
472       direction02
473     },
474     {
475       "A mix of left to right and right to left paragraphs.",
476       "Hello world demo\nمرحبا بالعالم\nhello world demo\nمرحبا بالعالم\nhello world demo",
477       0u,
478       78u,
479       2u,
480       indices03,
481       numberOfCharacters03,
482       direction03
483     },
484     {
485       "A mix of left to right and right to left paragraphs. Paragraphs also contain a mix of bidirectional text.",
486       "Hello world demo\nمرحبا بالعالم\nhello world demo مرحبا بالعالم hello world demo\nمرحبا hello world demo بالعالم\nhello world demo",
487       0u,
488       126u,
489       3u,
490       indices04,
491       numberOfCharacters04,
492       direction04
493     },
494     {
495       "A mix of left to right and right to left paragraphs. Paragraphs also contain a mix of bidirectional text and a mix of right to left scripts.",
496       "Hello world demo\nمرحبا שלום עולם بالعالم\nhello world שלום بالعالم עולם demo مرحبا שלום עולם بالعالم hello world demo\nمرحبا hello שלום بالعالم עולם world demo بالعالم\nhello world demo",
497       0u,
498       182u,
499       3u,
500       indices05,
501       numberOfCharacters05,
502       direction05
503     },
504     {
505       "A mix of left to right and right to left paragraphs. Updates a left to right paragraph.",
506       "Hello world demo\nمرحبا بالعالم\nhello world demo\nمرحبا بالعالم\nhello world demo",
507       31u,
508       17u,
509       2u,
510       indices06,
511       numberOfCharacters06,
512       direction06
513     },
514     {
515       "A mix of left to right and right to left paragraphs. Paragraphs also contain a mix of bidirectional text.",
516       "Hello world demo\nمرحبا بالعالم\nhello world demo مرحبا بالعالم hello world demo\nمرحبا hello world demo بالعالم\nhello world demo",
517       0u,
518       126u,
519       3u,
520       indices07,
521       numberOfCharacters07,
522       direction07
523     },
524     {
525       "A mix of left to right and right to left paragraphs. Paragraphs also contain a mix of bidirectional text and a mix of right to left scripts. Updates initial paragraphs.",
526       "Hello world demo\nمرحبا שלום עולם بالعالم\nhello world שלום بالعالم עולם demo مرحبا שלום עולם بالعالم hello world demo\nمرحبا hello שלום بالعالم עולם world demo بالعالم\nhello world demo",
527       0u,
528       41u,
529       3u,
530       indices08,
531       numberOfCharacters08,
532       direction08
533     },
534     {
535       "A mix of left to right and right to left paragraphs. Paragraphs also contain a mix of bidirectional text and a mix of right to left scripts. Updates mid paragraphs.",
536       "Hello world demo\nمرحبا שלום עולם بالعالم\nhello world שלום بالعالم עולם demo مرحبا שלום עולם بالعالم hello world demo\nمرحبا hello שלום بالعالم עולם world demo بالعالم\nhello world demo",
537       41u,
538       76u,
539       3u,
540       indices08,
541       numberOfCharacters08,
542       direction08
543     },
544     {
545       "A mix of left to right and right to left paragraphs. Paragraphs also contain a mix of bidirectional text and a mix of right to left scripts. Updates from character 85",
546       "Hello world demo\nمرحبا שלום עולם بالعالم\nhello world שלום بالعالم עולם demo مرحبا שלום עולם بالعالم hello world demo\nمرحبا hello שלום بالعالم עולם world demo بالعالم\nhello world demo",
547       117u,
548       65u,
549       3u,
550       indices08,
551       numberOfCharacters08,
552       direction08
553     },
554   };
555   const unsigned int numberOfTests = 10u;
556
557   for( unsigned int index = 0u; index < numberOfTests; ++index )
558   {
559     if( !SetBidirectionalInfoTest( data[index] ) )
560     {
561       tet_result(TET_FAIL);
562     }
563   }
564
565   tet_result(TET_PASS);
566   END_TEST;
567 }
568
569 int UtcDaliReorderLines(void)
570 {
571   ToolkitTestApplication application;
572   tet_infoline(" UtcDaliSetBidirectionalInfo");
573
574   unsigned int visualToLogical0301[] = { 0u, 1u, 2u, 3u, 4u, 5u, 9u, 8u, 7u, 6u, 10u };
575   unsigned int visualToLogical0302[] = { 3u, 2u, 1u, 0u, 4u, 5u, 6u, 7u, 8u, 9u, 10u };
576   unsigned int visualToLogical0303[] = { 0u, 1u, 2u, 3u, 4u };
577   unsigned int visualToLogical0304[] = { 12u, 11u, 10u, 9u, 8u, 7u, 6u, 5u, 4u, 3u, 2u, 1u, 0u };
578   unsigned int visualToLogical0305[] = { 10u, 9u, 8u, 7u, 6u, 5u, 4u, 3u, 2u, 1u, 0u };
579   unsigned int visualToLogical0306[] = { 9u, 8u, 7u, 6u, 5u, 4u, 3u, 2u, 1u, 0u };
580   unsigned int visualToLogical0307[] = { 13u, 8u, 9u, 10u, 11u, 12u, 7u, 6u, 5u, 4u, 3u, 2u, 1u, 0u };
581   unsigned int visualToLogical0308[] = { 5u, 0u, 1u, 2u, 3u, 4u };
582   unsigned int visualToLogical0309[] = { 0u, 1u, 2u, 3u, 4u, 5u, 9u, 8u, 7u, 6u, 10u };
583   unsigned int visualToLogical0310[] = { 3u, 2u, 1u, 0u, 4u, 5u, 6u, 7u, 8u, 9u, 10u };
584   unsigned int visualToLogical0311[] = { 0u, 1u, 2u, 3u, 4u };
585   unsigned int visualToLogical0312[] = { 12u, 11u, 10u, 9u, 8u, 7u, 6u, 5u, 4u, 3u, 2u, 1u, 0u };
586   unsigned int visualToLogical0313[] = { 10u, 9u, 8u, 7u, 6u, 5u, 4u, 3u, 2u, 1u, 0u };
587   unsigned int visualToLogical0314[] = { 9u, 8u, 7u, 6u, 5u, 4u, 3u, 2u, 1u, 0u };
588   unsigned int visualToLogical0315[] = { 13u, 8u, 9u, 10u, 11u, 12u, 7u, 6u, 5u, 4u, 3u, 2u, 1u, 0u };
589   unsigned int visualToLogical0316[] = { 0u, 1u, 2u, 3u, 4u };
590
591   BidiLineData bidiLine01[] = {};
592   BidiLineData bidiLine02[] = {};
593   BidiLineData bidiLine03[] = {
594     {
595       17u,
596       11u,
597       visualToLogical0301
598     },
599     {
600       28u,
601       11u,
602       visualToLogical0302
603     },
604     {
605       39u,
606       5u,
607       visualToLogical0303
608     },
609     {
610       44u,
611       13u,
612       visualToLogical0304
613     },
614     {
615       57u,
616       11u,
617       visualToLogical0305
618     },
619     {
620       68u,
621       10u,
622       visualToLogical0306
623     },
624     {
625       78u,
626       14u,
627       visualToLogical0307
628     },
629     {
630       92u,
631       6u,
632       visualToLogical0308
633     },
634     {
635       115u,
636       11u,
637       visualToLogical0309
638     },
639     {
640       126u,
641       11u,
642       visualToLogical0310
643     },
644     {
645       137u,
646       5u,
647       visualToLogical0311
648     },
649     {
650       142u,
651       13u,
652       visualToLogical0312
653     },
654     {
655       155u,
656       11u,
657       visualToLogical0313
658     },
659     {
660       166u,
661       10u,
662       visualToLogical0314
663     },
664     {
665       176u,
666       14u,
667       visualToLogical0315
668     },
669     {
670       190u,
671       5u,
672       visualToLogical0316
673     },
674   };
675
676   struct ReorderLinesData data[] =
677   {
678     {
679       "Zero characters.",
680       "",
681       0u,
682       0u,
683       0u,
684       bidiLine01
685     },
686     {
687       "Left to right text only.",
688       "Hello world demo\nhello world demo\nhello world demo.",
689       0u,
690       51u,
691       0u,
692       bidiLine02
693     },
694     {
695       "Bidirectional paragraphs.",
696       "Hello world demo\nhello שלום עולם world demo\nשלום بالعالم עולם مرحبا שלום עולם بالعالم hello world\nHello world demo\nhello שלום עולם world demo\nשלום بالعالم עולם مرحبا שלום עולם بالعالم hello world",
697       0u,
698       195u,
699       16u,
700       bidiLine03
701     },
702     {
703       "Bidirectional paragraphs. Update initial paragraphs.",
704       "Hello world demo\nhello שלום עולם world demo\nשלום بالعالم עולם مرحبا שלום עולם بالعالم hello world\nHello world demo\nhello שלום עולם world demo\nשלום بالعالم עולם مرحبا שלום עולם بالعالم hello world",
705       0u,
706       44u,
707       16u,
708       bidiLine03
709     },
710     {
711       "Bidirectional paragraphs. Update middle paragraphs.",
712       "Hello world demo\nhello שלום עולם world demo\nשלום بالعالم עולם مرحبا שלום עולם بالعالم hello world\nHello world demo\nhello שלום עולם world demo\nשלום بالعالم עולם مرحبا שלום עולם بالعالم hello world",
713       44u,
714       54u,
715       16u,
716       bidiLine03
717     },
718     {
719       "Bidirectional paragraphs. Update final paragraphs.",
720       "Hello world demo\nhello שלום עולם world demo\nשלום بالعالم עולם مرحبا שלום עולם بالعالم hello world\nHello world demo\nhello שלום עולם world demo\nשלום بالعالم עולם مرحبا שלום עולם بالعالم hello world",
721       142u,
722       53u,
723       16u,
724       bidiLine03
725     },
726   };
727   const unsigned int numberOfTests = 6u;
728
729   for( unsigned int index = 0u; index < numberOfTests; ++index )
730   {
731     if( !ReorderLinesTest( data[index] ) )
732     {
733       tet_result(TET_FAIL);
734     }
735   }
736
737   tet_result(TET_PASS);
738   END_TEST;
739 }
740
741 int UtcDaliGetMirroredText(void)
742 {
743   ToolkitTestApplication application;
744   tet_infoline(" UtcDaliGetMirroredText");
745
746   struct GetMirroredTextData data[] =
747   {
748     {
749       "Zero characters.",
750       "",
751       0u,
752       0u,
753       ""
754     },
755     {
756       "Left to right characters only.",
757       "Hello world\nhello world demo.",
758       0u,
759       29u,
760       "Hello world\nhello world demo."
761     },
762     {
763       "Right to left characters but with no characters to mirror.",
764       "שלום עולם\nمرحبا بالعالم",
765       0u,
766       23u,
767       "שלום עולם\nمرحبا بالعالم"
768     },
769     {
770       "Right to left characters with some characters to mirror.",
771       "שלום עולם\n(مرحبا بالعالم)",
772       0u,
773       25u,
774       "שלום עולם\n)مرحبا بالعالم("
775     },
776     {
777       "Right to left characters with some characters to mirror. Update last paragraph.",
778       "שלום עולם\n(مرحبا بالعالم)",
779       10u,
780       15u,
781       "שלום עולם\n)مرحبا بالعالم("
782     },
783     {
784       "Mix of bidirectional text. With more paragraphs.",
785       "Hello world demo\nhello world\nhello world (مرحبا بالعالم שלום) עולם\nשלום مرحبا بالعالم עולם (hello) مرحبا بالعالم world"
786       " مرحبا بالعالم שלום עולם hello world hello world\nبالعالم שלום (hello) world demo (עולם)\nשלום (مرحبا بالعالم עולם) (hello)",
787       0u,
788       239u,
789       "Hello world demo\nhello world\nhello world (مرحبا بالعالم שלום( עולם\nשלום مرحبا بالعالم עולם )hello( مرحبا بالعالم world"
790       " مرحبا بالعالم שלום עולם hello world hello world\nبالعالم שלום )hello) world demo )עולם(\nשלום )مرحبا بالعالم עולם( )hello("
791     },
792     {
793       "Mix of bidirectional text. With more paragraphs. Update middle paragraphs.",
794       "Hello world demo\nhello world\nhello world (مرحبا بالعالم שלום) עולם\nשלום مرحبا بالعالم עולם (hello) مرحبا بالعالم world"
795       " مرحبا بالعالم שלום עולם hello world hello world\nبالعالم שלום (hello) world demo (עולם)\nשלום (مرحبا بالعالم עולם) (hello)",
796       29u,
797       38u,
798       "Hello world demo\nhello world\nhello world (مرحبا بالعالم שלום( עולם\nשלום مرحبا بالعالم עולם (hello) مرحبا بالعالم world"
799       " مرحبا بالعالم שלום עולם hello world hello world\nبالعالم שלום (hello) world demo (עולם)\nשלום (مرحبا بالعالم עולם) (hello)"
800     },
801     {
802       "Mix of bidirectional text. With more paragraphs. Update middle paragraphs (2).",
803       "Hello world demo\nhello world\nhello world (مرحبا بالعالم שלום) עולם\nשלום مرحبا بالعالم עולם (hello) مرحبا بالعالم world"
804       " مرحبا بالعالم שלום עולם hello world hello world\nبالعالم שלום (hello) world demo (עולם)\nשלום (مرحبا بالعالم עולם) (hello)",
805       67u,
806       100u,
807       "Hello world demo\nhello world\nhello world (مرحبا بالعالم שלום) עולם\nשלום مرحبا بالعالم עולם )hello( مرحبا بالعالم world"
808       " مرحبا بالعالم שלום עולם hello world hello world\nبالعالم שלום (hello) world demo (עולם)\nשלום (مرحبا بالعالم עולם) (hello)"
809     },
810   };
811   const unsigned int numberOfTests = 8u;
812
813   for( unsigned int index = 0u; index < numberOfTests; ++index )
814   {
815     if( !GetMirroredTextTest( data[index] ) )
816     {
817       tet_result(TET_FAIL);
818     }
819   }
820
821   tet_result(TET_PASS);
822   END_TEST;
823 }
824
825 int UtcDaliGetCharactersDirection(void)
826 {
827   ToolkitTestApplication application;
828   tet_infoline(" UtcDaliGetCharactersDirection");
829
830   bool directions01[] = {};
831   bool directions02[] = {
832     false, false, false, false, false, false, false, false, false, false,
833     false, false, false, false, false, false, false, false, false, false,
834     false, false, false, false, false, false, false, false };
835   bool directions03[] = {
836     true,  true,  true,  true,  true,  true,  true,  true,  true,  true,
837     true,  true,  true,  true,  true,  true,  true,  true,  true };
838   bool directions04[] = {
839     false, false, false, false, false, false, false, false, false, false,
840     false, false, false, false, false, false, false, false, false, false,
841     false, false, false, false, true,  true,  true,  true,  true,  true,
842     true,  true,  true,  false, true,  true,  true,  true,  true,  true,
843     true,  true,  true,  true,  false, false, false, false, false, false,
844     false, false, false, false, false };
845   bool directions05[] = {
846     false, false, false, false, false, false, false, false, false, false,
847     false, false, false, false, false, false, false, false, false, false,
848     false, false, false, false, false, false, false, false, false, false,
849     false, false, false, false, false, false, false, false, false, false,
850     false, true,  true,  true,  true,  true,  true,  true,  true,  true,
851     true,  true,  true,  true,  true,  true,  true,  true,  true,  true,
852     true,  true,  true,  true,  false, true,  true,  true,  true,  true,
853     true,  true,  true,  true,  true,  true,  true,  true,  true,  true,
854     true,  true,  true,  true,  true,  true,  true,  true,  true,  false,
855     false, false, false, false, true,  true,  true,  true,  true,  true,
856     true,  true,  true,  true,  true,  true,  true,  true,  true,  false,
857     false, false, false, false, true,  true,  true,  true,  true,  true,
858     true,  true,  true,  true,  true,  true,  true,  true,  true,  true,
859     true,  true,  true,  true,  true,  true,  true,  true,  true,  false,
860     false, false, false, false, false, false, false, false, false, false,
861     false, false, false, false, false, false, false, false, false, false,
862     false, false, true,  true,  true,  true,  true,  true,  true,  true,
863     true,  true,  true,  true,  true,  true,  false, false, false, false,
864     false, false, false, false, false, false, false, false, false, false,
865     false, false, true,  true,  true,  true,  true,  true,  true,  true,
866     true,  true,  true,  true,  true,  true,  true,  true,  true,  true,
867     true,  true,  true,  true,  true,  true,  true,  true,  true,  true,
868     true,  true,  false, false, false, false, false };
869
870   struct GetCharactersDirectionData data[] =
871   {
872     {
873       "Zero characters",
874       "",
875       0u,
876       0u,
877       directions01
878     },
879     {
880       "Left to right characters only",
881       "Hello world\nhello world demo",
882       0u,
883       28u,
884       directions02
885     },
886     {
887       "Right to left characters only",
888       "שלום עולם\nשלום עולם",
889       0u,
890       19u,
891       directions03
892     },
893     {
894       "Mix of bidirectional text",
895       "Hello world\nhello world שלום עולם\nשלום עולם hello world",
896       0u,
897       55u,
898       directions04
899     },
900     {
901       "Mix of bidirectional text. With more paragraphs.",
902       "Hello world demo\nhello world\nhello world مرحبا بالعالم שלום עולם\nשלום مرحبا بالعالم עולם hello مرحبا بالعالم world"
903       " مرحبا بالعالم שלום עולם hello world hello world\nبالعالم שלום hello world demo עולם\nשלום مرحبا بالعالم עולם hello",
904       0u,
905       227u,
906       directions05
907     },
908     {
909       "Mix of bidirectional text. With more paragraphs. Update first paragraph.",
910       "Hello world demo\nhello world\nhello world مرحبا بالعالم שלום עולם\nשלום مرحبا بالعالم עולם hello مرحبا بالعالم world"
911       " مرحبا بالعالم שלום עולם hello world hello world\nبالعالم שלום hello world demo עולם\nשלום مرحبا بالعالم עולם hello",
912       0u,
913       17u,
914       directions05
915     },
916     {
917       "Mix of bidirectional text. With more paragraphs. Update from character 29",
918       "Hello world demo\nhello world\nhello world مرحبا بالعالم שלום עולם\nשלום مرحبا بالعالم עולם hello مرحبا بالعالم world"
919       " مرحبا بالعالم שלום עולם hello world hello world\nبالعالم שלום hello world demo עולם\nשלום مرحبا بالعالم עולם hello",
920       29u,
921       134u,
922       directions05
923     },
924     {
925       "Mix of bidirectional text. With more paragraphs. Update from character 163",
926       "Hello world demo\nhello world\nhello world مرحبا بالعالم שלום עולם\nשלום مرحبا بالعالم עולם hello مرحبا بالعالم world"
927       " مرحبا بالعالم שלום עולם hello world hello world\nبالعالم שלום hello world demo עולם\nשלום مرحبا بالعالم עולם hello",
928       163u,
929       35u,
930       directions05
931     }
932   };
933   const unsigned int numberOfTests = 8u;
934
935   for( unsigned int index = 0u; index < numberOfTests; ++index )
936   {
937     if( !GetCharactersDirectionTest( data[index] ) )
938     {
939       tet_result(TET_FAIL);
940     }
941   }
942
943   tet_result(TET_PASS);
944   END_TEST;
945 }