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