Bidirectional conversion table for multiline.
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-toolkit-internal / utc-Dali-LogicalModel.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
20 #include <stdlib.h>
21
22 #include <dali-toolkit-test-suite-utils.h>
23 #include <dali-toolkit/internal/text/text-run-container.h>
24 #include <dali-toolkit/dali-toolkit.h>
25 #include <toolkit-text-model.h>
26
27
28 using namespace Dali;
29 using namespace Toolkit;
30 using namespace Text;
31
32 // Tests the following functions.
33 //
34 // void CreateParagraphInfo( CharacterIndex startIndex,
35 //                           Length numberOfCharacters );
36 // void FindParagraphs( CharacterIndex index,
37 //                      Length numberOfCharacters,
38 //                      Vector<ParagraphRunIndex>& paragraphs );
39 // bool FetchBidirectionalLineInfo( CharacterIndex characterIndex )
40 // CharacterIndex GetLogicalCharacterIndex( CharacterIndex visualCharacterIndex ) const;
41 // CharacterIndex GetLogicalCursorIndex( CharacterIndex visualCursorIndex ) const;
42
43 //////////////////////////////////////////////////////////
44
45 namespace
46 {
47 struct CreateParagraphData
48 {
49   std::string    description;                    ///< Description of the test.
50   std::string    text;                           ///< Input text.
51   CharacterIndex index;                          ///< The first character index.
52   Length         numberOfCharacters;             ///< The number of characters.
53   unsigned int   numberOfParagraphs;             ///< The expected number of paragraphs.
54   unsigned int*  indices;                        ///< The expected paragraph info indices.
55   unsigned int*  numberOfCharactersPerParagraph; ///< The expected number of characters of each paragraph.
56 };
57
58 struct FindParagraphData
59 {
60   std::string    description;        ///< Description of the test.
61   std::string    text;               ///< Input text.
62   CharacterIndex index;              ///< The first character index.
63   Length         numberOfCharacters; ///< The number of characters.
64   unsigned int   numberOfParagraphs; ///< The expected number of paragraphs.
65   unsigned int*  paragraphs;         ///< The expected paragraph info.
66 };
67
68 struct FetchBidirectionalLineInfoData
69 {
70   std::string   description;    ///< Description of the test.
71   std::string   text;           ///< Input text.
72   unsigned int  numberOfTests;  ///< The number of tests.
73   unsigned int* characterIndex; ///< The logical character index.
74   bool*         fetched;        ///< Whether the expected bidi line exists.
75   unsigned int* bidiLineIndex;  ///< Index to the expected bidi line.
76 };
77
78 struct GetLogicalCharacterIndexData
79 {
80   std::string   description;        ///< Description of the test.
81   std::string   text;               ///< Input text.
82   Size          textArea;           ///< The text area.
83   unsigned int  numberOfIndices;    ///< The number of characters to set.
84   unsigned int* visualToLogical;    ///< The expected visual to logical conversion table.
85   unsigned int* cachedBidiLine;     ///< The cached bidi line index for each character.
86 };
87
88 struct GetLogicalCursorIndexData
89 {
90   std::string    description;        ///< Description of the test.
91   std::string    text;               ///< Input text.
92   Size           textArea;           ///< The text area.
93   unsigned int   numberOfIndices;    ///< The number of characters to set.
94   unsigned int*  visualCursorIndex;  ///< The given cursor visual index.
95   unsigned int*  characterIndex;     ///< Index to the first logical character of the line.
96   unsigned int*  logicalCursorIndex; ///< The expected cursor logical index.
97   unsigned int*  cachedBidiLine;     ///< The cached bidi line index for each character.
98 };
99
100 bool CreateParagraphTest( const CreateParagraphData& data )
101 {
102   // 1) Create the model.
103   LogicalModelPtr logicalModel = LogicalModel::New();
104   VisualModelPtr visualModel = VisualModel::New();
105   Size textArea(100.f, 60.f);
106   Size layoutSize;
107
108   Vector<FontDescriptionRun> fontDescriptionRuns;
109   LayoutOptions options;
110   CreateTextModel( data.text,
111                    textArea,
112                    fontDescriptionRuns,
113                    options,
114                    layoutSize,
115                    logicalModel,
116                    visualModel );
117
118   // 2) Clear the paragraphs.
119   Vector<ParagraphRun>& paragraphs = logicalModel->mParagraphInfo;
120   ClearCharacterRuns( data.index,
121                       data.index + data.numberOfCharacters - 1u,
122                       paragraphs );
123
124   // 3) Call the LogicalModel::CreateParagraphInfo() method
125   logicalModel->CreateParagraphInfo( data.index,
126                                      data.numberOfCharacters );
127
128   // 4) Compare the results.
129   if( data.numberOfParagraphs != paragraphs.Count() )
130   {
131     std::cout << "  Different number of paragraphs : " << paragraphs.Count() << ", expected : " << data.numberOfParagraphs << std::endl;
132     return false;
133   }
134
135   unsigned int index = 0u;
136   for( Vector<ParagraphRun>::ConstIterator it = paragraphs.Begin(),
137          endIt = paragraphs.End();
138        it != endIt;
139        ++it, ++index )
140   {
141     const ParagraphRun& paragraph( *it );
142
143     if( data.indices[index] != paragraph.characterRun.characterIndex )
144     {
145       std::cout << "  Different character index for paragraph : " << index << ", " << paragraph.characterRun.characterIndex << ", expected : " << data.indices[index] << std::endl;
146       return false;
147     }
148     if( data.numberOfCharactersPerParagraph[index] != paragraph.characterRun.numberOfCharacters )
149     {
150       std::cout << "  Different number of characters for paragraph : " << index << ", " << paragraph.characterRun.numberOfCharacters << ", expected : " << data.numberOfCharactersPerParagraph[index] << std::endl;
151       return false;
152     }
153   }
154
155   return true;
156 }
157
158 bool FindParagraphTest( const FindParagraphData& data )
159 {
160   // 1) Create the model.
161   LogicalModelPtr logicalModel = LogicalModel::New();
162   VisualModelPtr visualModel = VisualModel::New();
163   Size textArea(100.f, 60.f);
164   Size layoutSize;
165
166   Vector<FontDescriptionRun> fontDescriptionRuns;
167   LayoutOptions options;
168   CreateTextModel( data.text,
169                    textArea,
170                    fontDescriptionRuns,
171                    options,
172                    layoutSize,
173                    logicalModel,
174                    visualModel );
175
176   // 2) Find the paragraphs.
177   Vector<ParagraphRunIndex> paragraphs;
178   logicalModel->FindParagraphs( data.index, data.numberOfCharacters, paragraphs );
179
180   // 3) compare the results.
181   if( data.numberOfParagraphs != paragraphs.Count() )
182   {
183     return false;
184   }
185
186   unsigned int index = 0u;
187   for( Vector<ParagraphRunIndex>::ConstIterator it = paragraphs.Begin(),
188          endIt = paragraphs.End();
189        it != endIt;
190        ++it, ++index )
191   {
192     const ParagraphRunIndex paragraphIndex = *it;
193
194     if( paragraphIndex != data.paragraphs[index] )
195     {
196       return false;
197     }
198   }
199
200   return true;
201 }
202
203 bool FetchBidirectionalLineInfoTest( const FetchBidirectionalLineInfoData& data )
204 {
205   std::cout << "  testing : " << data.description << std::endl;
206   // Create the model.
207   LogicalModelPtr logicalModel = LogicalModel::New();
208   VisualModelPtr visualModel = VisualModel::New();
209   Size textArea( 100.f, 300.f );
210   Size layoutSize;
211
212   // Create the model with the whole text.
213   const Vector<FontDescriptionRun> fontDescriptions;
214   const LayoutOptions options;
215   CreateTextModel( data.text,
216                    textArea,
217                    fontDescriptions,
218                    options,
219                    layoutSize,
220                    logicalModel,
221                    visualModel );
222
223   for( unsigned int index = 0; index < data.numberOfTests; ++index )
224   {
225     const bool fetched = logicalModel->FetchBidirectionalLineInfo( data.characterIndex[index] );
226
227     if( fetched != data.fetched[index] )
228     {
229       std::cout << "  Different fetched result : " << fetched << ", expected : " << data.fetched[index] << std::endl;
230       return false;
231     }
232
233     if( fetched )
234     {
235       if( logicalModel->mBidirectionalLineIndex != data.bidiLineIndex[index] )
236       {
237         std::cout << "  Different bidi line index : " << logicalModel->mBidirectionalLineIndex << ", expected : " << data.bidiLineIndex << std::endl;
238         return false;
239       }
240     }
241   }
242
243   return true;
244 }
245
246 bool GetLogicalCharacterIndexTest( const GetLogicalCharacterIndexData& data )
247 {
248   std::cout << "  testing : " << data.description << std::endl;
249   // Create the model.
250   LogicalModelPtr logicalModel = LogicalModel::New();
251   VisualModelPtr visualModel = VisualModel::New();
252   Size layoutSize;
253
254   // Create the model with the whole text.
255   const Vector<FontDescriptionRun> fontDescriptions;
256   const LayoutOptions options;
257   CreateTextModel( data.text,
258                    data.textArea,
259                    fontDescriptions,
260                    options,
261                    layoutSize,
262                    logicalModel,
263                    visualModel );
264
265   for( unsigned int index = 0u; index < data.numberOfIndices; ++index )
266   {
267     // Check the current cached bidi line index. (Check it before call the GetLogicalCharacterIndex() method )
268     if( data.cachedBidiLine[index] != logicalModel->mBidirectionalLineIndex )
269     {
270       std::cout << "  index : " << index << ", different cached bidi index : " << logicalModel->mBidirectionalLineIndex << ", expected : " << data.cachedBidiLine[index] << std::endl;
271       return false;
272     }
273
274     const bool fetched = logicalModel->FetchBidirectionalLineInfo( index );
275     const Character logicalIndex = fetched ? logicalModel->GetLogicalCharacterIndex( index ) : index;
276
277     if( data.visualToLogical[index] != logicalIndex )
278     {
279       std::cout << "  visual index : " << index << ", different logical index : " << logicalIndex << ", expected : " << data.visualToLogical[index] << std::endl;
280       return false;
281     }
282   }
283   return true;
284 }
285
286 bool GetLogicalCursorIndexTest( const GetLogicalCursorIndexData& data )
287 {
288   std::cout << "  testing : " << data.description << std::endl;
289   // Create the model.
290   LogicalModelPtr logicalModel = LogicalModel::New();
291   VisualModelPtr visualModel = VisualModel::New();
292   Size layoutSize;
293
294   // Create the model with the whole text.
295   const Vector<FontDescriptionRun> fontDescriptions;
296   const LayoutOptions options;
297   CreateTextModel( data.text,
298                    data.textArea,
299                    fontDescriptions,
300                    options,
301                    layoutSize,
302                    logicalModel,
303                    visualModel );
304
305   for( unsigned int index = 0u; index < data.numberOfIndices; ++index )
306   {
307     const bool fetched = logicalModel->FetchBidirectionalLineInfo( data.characterIndex[index] );
308
309     if( logicalModel->mBidirectionalLineIndex != data.cachedBidiLine[index] )
310     {
311       std::cout << "  test : " << index << ", different cached line index : " << logicalModel->mBidirectionalLineIndex << ", expected : " << data.cachedBidiLine[index] << std::endl;
312       return false;
313     }
314
315     const CharacterIndex visualCharacterIndex = data.visualCursorIndex[index];
316     const CharacterIndex logicalCursorIndex = fetched ? logicalModel->GetLogicalCursorIndex( visualCharacterIndex ) : visualCharacterIndex;
317
318     if( logicalCursorIndex != data.logicalCursorIndex[index] )
319     {
320       std::cout << "  test : " << index << ", visual index : " << visualCharacterIndex << ", different logical cursor index : " << logicalCursorIndex << ", expected : " << data.logicalCursorIndex[index] << std::endl;
321       return false;
322     }
323   }
324
325   return true;
326 }
327
328 } // namespace
329
330 //////////////////////////////////////////////////////////
331 //
332 // UtcDaliCreateParagraph
333 // UtcDaliFindParagraph
334 // UtcDaliFetchBidirectionalLineInfo
335 // UtcDaliGetLogicalCharacterIndex
336 // UtcDaliGetLogicalCursorIndex
337 //
338 //////////////////////////////////////////////////////////
339
340 int UtcDaliCreateParagraph(void)
341 {
342   tet_infoline(" UtcDaliCreateParagraph");
343
344   unsigned int paragraphsIndices01[] = { 0u };
345   unsigned int paragraphsNumberOfCharacters01[] = { 0u };
346   unsigned int paragraphsIndices02[] = { 0u, 12u, 17u };
347   unsigned int paragraphsNumberOfCharacters02[] = { 12u, 5u, 1u };
348   unsigned int paragraphsIndices03[] = { 0u, 12u, 17u, 34u };
349   unsigned int paragraphsNumberOfCharacters03[] = { 12u, 5u, 17u ,1u };
350
351   struct CreateParagraphData data[] =
352   {
353     {
354       "Zero characters",
355       "",
356       0u,
357       0u,
358       0u,
359       paragraphsIndices01,
360       paragraphsNumberOfCharacters01,
361     },
362     {
363       "Some paragraphs",
364       "Hello world\ndemo\n\n",
365       0u,
366       18u,
367       3u,
368       paragraphsIndices02,
369       paragraphsNumberOfCharacters02,
370     },
371     {
372       "Some paragraphs. Update the initial paragraphs.",
373       "Hello world\ndemo\nhello world demo\n\n",
374       0u,
375       17u,
376       4u,
377       paragraphsIndices03,
378       paragraphsNumberOfCharacters03,
379     },
380     {
381       "Some paragraphs. Update the mid paragraphs.",
382       "Hello world\ndemo\nhello world demo\n\n",
383       12u,
384       5u,
385       4u,
386       paragraphsIndices03,
387       paragraphsNumberOfCharacters03,
388     },
389     {
390       "Some paragraphs. Update the final paragraphs.",
391       "Hello world\ndemo\nhello world demo\n\n",
392       17u,
393       18u,
394       4u,
395       paragraphsIndices03,
396       paragraphsNumberOfCharacters03,
397     },
398   };
399   const unsigned int numberOfTests = 5u;
400
401   for( unsigned int index = 0u; index < numberOfTests; ++index )
402   {
403     ToolkitTestApplication application;
404     if( !CreateParagraphTest( data[index] ) )
405     {
406       tet_result(TET_FAIL);
407     }
408   }
409
410   tet_result(TET_PASS);
411   END_TEST;
412 }
413
414 int UtcDaliFindParagraph(void)
415 {
416   tet_infoline(" UtcDaliFindParagraph");
417
418   unsigned int paragraphs01[] = {};
419   unsigned int paragraphs02[] = { 0u, 1u, 2u };
420   unsigned int paragraphs03[] = { 0u };
421   unsigned int paragraphs04[] = { 1u };
422   unsigned int paragraphs05[] = { 0u, 1u, 2u };
423
424   struct FindParagraphData data[] =
425   {
426     {
427       "Zero characters",
428       "",
429       0u,
430       100u,
431       0u,
432       paragraphs01,
433     },
434     {
435       "Some paragraphs",
436       "Hello world\ndemo\n\n",
437       0u,
438       18u,
439       3u,
440       paragraphs02
441     },
442     {
443       "Some paragraphs",
444       "Hello world\ndemo\n\n",
445       0u,
446       12u,
447       1u,
448       paragraphs03
449     },
450     {
451       "Some paragraphs",
452       "Hello world\ndemo\n\n",
453       12u,
454       5u,
455       1u,
456       paragraphs04
457     },
458     {
459       "Some paragraphs",
460       "Hello world\ndemo\n\n",
461       3u,
462       15u,
463       3u,
464       paragraphs05
465     },
466   };
467   const unsigned int numberOfTests = 5u;
468
469   for( unsigned int index = 0u; index < numberOfTests; ++index )
470   {
471     ToolkitTestApplication application;
472     if( !FindParagraphTest( data[index] ) )
473     {
474       tet_result(TET_FAIL);
475     }
476   }
477
478   tet_result(TET_PASS);
479   END_TEST;
480 }
481
482 int UtcDaliFetchBidirectionalLineInfo(void)
483 {
484   tet_infoline(" UtcDaliFetchBidirectionalLineInfo");
485
486   unsigned int logicalIndex01[] = { 0u };
487   bool fetched01[] = { false };
488   unsigned int bidiLine01[] = { 0u };
489
490   unsigned int logicalIndex02[] = { 3u };
491   bool fetched02[] = { false };
492   unsigned int bidiLine02[] = { 0u };
493
494   unsigned int logicalIndex03[] = { 0u, 11u, 12u, 21u, 22u, 33u, 34u, 43u, 44u, 54u};
495   bool fetched03[] = { false, false, true, true, false, false, true, true, false, false };
496   unsigned int bidiLine03[] = { 0u, 0u, 0u, 0u, 0u, 0u, 1u, 1u, 0u, 0u };
497
498   struct FetchBidirectionalLineInfoData data[] =
499   {
500     {
501       "Void text",
502       "",
503       1u,
504       logicalIndex01,
505       fetched01,
506       bidiLine01
507     },
508     {
509       "LTR text",
510       "Hello world",
511       1u,
512       logicalIndex02,
513       fetched02,
514       bidiLine02
515     },
516     {
517       "Bidi text",
518       "Hello world\nשלום עולם\nhello world\nשלום עולם\nhello world",
519       10u,
520       logicalIndex03,
521       fetched03,
522       bidiLine03
523     }
524   };
525   const unsigned int numberOfTests = 3u;
526
527   for( unsigned int index = 0u; index < numberOfTests; ++index )
528   {
529     ToolkitTestApplication application;
530     if( !FetchBidirectionalLineInfoTest( data[index] ) )
531     {
532       tet_result(TET_FAIL);
533     }
534   }
535
536   tet_result(TET_PASS);
537   END_TEST;
538 }
539
540 int UtcDaliGetLogicalCharacterIndex(void)
541 {
542   tet_infoline(" UtcDaliSetVisualToLogicalMap");
543
544   unsigned int visualToLogical01[] = {};
545   unsigned int  cachedBidiLine01[] = {};
546   unsigned int visualToLogical02[] = { 0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 9u, 10u };
547   unsigned int  cachedBidiLine02[] = { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,  0u };
548   unsigned int visualToLogical03[] = { 12u, 11u, 10u, 9u, 8u, 7u, 6u, 5u, 4u, 3u, 2u, 1u, 0u };
549   unsigned int  cachedBidiLine03[] = {  0u,  0u,  0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u };
550
551   unsigned int visualToLogical04[] = { 0u,  1u,  2u,  3u,  4u,  5u,  6u,  7u,  8u,  9u, 10u, 11u, 12u, 25u, 24u, 23u, 22u, 21u, 20u, 19u, 18u, 17u, 16u, 15u, 14u, 13u, 26u, 27u, 28u, 29u, 30u, 31u, 32u, 33u, 34u, 35u, 36u, 37u, 38u, 39u, 81u, 80u, 79u, 78u, 77u, 76u, 75u, 74u, 73u, 72u, 71u, 70u, 69u, 68u, 67u, 66u, 55u, 56u, 57u, 58u, 59u, 60u, 61u, 62u, 63u, 64u, 65u, 54u, 53u, 52u, 51u, 50u, 49u, 48u, 47u, 46u, 45u, 44u, 43u, 42u, 41u, 40u, 95u, 94u, 93u, 92u, 91u, 90u, 89u, 88u, 87u, 86u, 85u, 84u, 83u, 82u, 96u, 97u, 98u, 99u, 100u, 101u, 102u, 103u, 104u, 105u, 106u };
552   unsigned int  cachedBidiLine04[] = { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
553                                        0u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u,
554                                        1u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u };
555
556 // size 300, 300
557 // LO   H  e  l  l  o  _  w  o  r  l  d  ,  _  م  ر  ح  ب   ا  _  ب  ا  ل  ع   ا  ل  م  ,   _  h  e  l  l  o  _  w  o  r  l  d \n
558 //      0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
559 // VO   H  e  l  l  o  _  w  o  r  l  d  ,  _  م  ل  ا  ع   ل  ا  ب  _  ا   ب  ح  ر  م  ,   _  h  e  l  l  o  _  w  o  r  l  d \n
560 //      0  1  2  3  4  5  6  7  8  9 10 11 12 25 24 23 22 21 20 19 18 17 16 15 14 13 26 27 28 29 30 31 32 33 34 35 36 37 38 39
561
562 // LO   م  ر  ح  ب   ا  _  ب  ا  ل  ع   ا  ل  م  ,  _  h  e  l  l  o  _  w  o  r  l  d   ,  _  م  ر  ح  ب   ا  _  ب  ا  ل  ع   ا  ل  م  \n
563 //     40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
564 // VO  \n  م  ل  ا   ع  ل  ا  ب  _  ا   ب  ح  ر  م  _  ,  h  e  l  l  o  _  w  o  r  l  d   _  ,  م  ل  ا   ع  ل  ا  ب  _  ا   ب  ح  ر  م
565 //     81 80 79 78 77 76 75 74 73 72 71 70 69 68 67 66 55 56 57 58 59 60 61 62 63 64 65 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40
566
567 // LO   م  ر  ح  ب   ا  _  ب  ا  ل  ع   ا  ل  م  \n
568 //     82 83 84 85 86 87 88 89 90 91 92 93 94 95
569 // VO  \n  م  ل  ا  ع  ل   ا  ب  _  ا   ب  ح  ر  م
570 //     95 94 93 92 91 90 89 88 87 86 85 84 83 82
571
572
573 // LO   h   e   l   l   o   _   w   o   r   l   d
574 //     96  97  98  99 100 101 102 103 104 105 106
575 // VO   h   e   l   l   o   _   w   o   r   l   d
576 //     96  97  98  99 100 101 102 103 104 105 106
577
578   unsigned int visualToLogical05[] = { 0u,  1u,  2u,  3u,  4u,  5u,  6u,  7u,  8u,  9u, 10u, 11u, 12u, 25u, 24u, 23u, 22u, 21u, 20u, 19u, 18u, 17u, 16u, 15u, 14u, 13u, 26u, 27u, 28u, 29u, 30u, 31u, 32u, 33u, 34u, 35u, 36u, 37u, 38u, 39u, 67u, 66u, 55u, 56u, 57u, 58u, 59u, 60u, 61u, 62u, 63u, 64u, 65u, 54u, 53u, 52u, 51u, 50u, 49u, 48u, 47u, 46u, 45u, 44u, 43u, 42u, 41u, 40u, 81u, 80u, 79u, 78u, 77u, 76u, 75u, 74u, 73u, 72u, 71u, 70u, 69u, 68u, 95u, 94u, 93u, 92u, 91u, 90u, 89u, 88u, 87u, 86u, 85u, 84u, 83u, 82u, 96u, 97u, 98u, 99u, 100u, 101u, 102u, 103u, 104u, 105u, 106u };
579   unsigned int  cachedBidiLine05[] = { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u };
580
581 // size 300, 300
582 // LO   H  e  l  l  o  _  w  o  r  l  d  ,  _  م  ر  ح  ب   ا  _  ب  ا  ل  ع   ا  ل  م  ,   _
583 //      0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
584 // VO   H  e  l  l  o  _  w  o  r  l  d  ,  _  م  ل  ا  ع   ل  ا  ب  _  ا   ب  ح  ر  م  ,   _
585 //      0  1  2  3  4  5  6  7  8  9 10 11 12 25 24 23 22 21 20 19 18 17 16 15 14 13 26 27
586
587 // LO    h  e  l  l  o  _  w  o  r  l  d \n
588 //      28 29 30 31 32 33 34 35 36 37 38 39
589 // VO    h  e  l  l  o  _  w  o  r  l  d \n
590 //      28 29 30 31 32 33 34 35 36 37 38 39
591
592 // LO   م  ر  ح  ب   ا  _  ب  ا  ل  ع   ا  ل  م  ,  _  h  e  l  l  o  _  w  o  r  l  d   ,  _
593 //     40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
594 // VO  _  ,  h  e  l  l  o  _  w  o  r  l  d   _  ,  م  ل  ا   ع  ل  ا  ب  _  ا   ب  ح  ر  م
595 //     67 66 55 56 57 58 59 60 61 62 63 64 65 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40
596
597 // LO   م  ر  ح  ب   ا  _  ب  ا  ل  ع   ا  ل  م  \n
598 //     68 69 70 71 72 73 74 75 76 77 78 79 80 81
599 // VO  \n  م  ل  ا   ع  ل  ا  ب  _  ا   ب  ح  ر  م
600 //     81 80 79 78 77 76 75 74 73 72 71 70 69 68
601
602 // LO   م  ر  ح  ب   ا  _  ب  ا  ل  ع   ا  ل  م  \n
603 //     82 83 84 85 86 87 88 89 90 91 92 93 94 95
604 // VO  \n  م  ل  ا  ع  ل   ا  ب  _  ا   ب  ح  ر  م
605 //     95 94 93 92 91 90 89 88 87 86 85 84 83 82
606
607
608 // LO   h   e   l   l   o   _   w   o   r   l   d
609 //     96  97  98  99 100 101 102 103 104 105 106
610 // VO   h   e   l   l   o   _   w   o   r   l   d
611 //     96  97  98  99 100 101 102 103 104 105 106
612
613   unsigned int visualToLogical06[] = { 0u,  1u,  2u,  3u,  4u,  5u,  6u,  7u,  8u,  9u, 10u, 11u, 12u, 25u, 24u, 23u, 22u, 21u, 20u, 19u, 18u, 17u, 16u, 15u, 14u, 13u, 26u, 27u, 28u, 29u, 30u, 31u, 32u, 33u, 34u, 35u, 36u, 37u, 38u, 39u, 54u, 53u, 52u, 51u, 50u, 49u, 48u, 47u, 46u, 45u, 44u, 43u, 42u, 41u, 40u, 67u, 66u, 55u, 56u, 57u, 58u, 59u, 60u, 61u, 62u, 63u, 64u, 65u, 81u, 80u, 79u, 78u, 77u, 76u, 75u, 74u, 73u, 72u, 71u, 70u, 69u, 68u, 95u, 94u, 93u, 92u, 91u, 90u, 89u, 88u, 87u, 86u, 85u, 84u, 83u, 82u, 96u, 97u, 98u, 99u, 100u, 101u, 102u, 103u, 104u, 105u, 106u };
614   unsigned int  cachedBidiLine06[] = { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
615                                        0u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u,
616                                        1u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u,
617                                        2u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u,
618                                        3u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u,
619                                        4u, 5u, 5u, 5u, 5u, 5u, 5u, 5u, 5u, 5u, 5u, 5u, 5u, 5u,
620                                        5u, 6u, 6u, 6u, 6u, 6u, 6u, 6u, 6u, 6u, 6u, 6u, 6u, 6u,
621                                        6u, 6u, 6u, 6u, 6u, 6u, 6u, 6u, 6u, 6u, 6u };
622
623 // size 100, 600
624 // LO   H  e  l  l  o  _  w  o  r  l  d  ,  _
625 //      0  1  2  3  4  5  6  7  8  9 10 11 12
626 // VO   H  e  l  l  o  _  w  o  r  l  d  ,  _
627 //      0  1  2  3  4  5  6  7  8  9 10 11 12
628
629 // LO    م  ر  ح  ب   ا  _  ب  ا  ل  ع   ا  ل  م  ,   _
630 //      13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
631 // VO    م  ل  ا  ع   ل  ا  ب  _  ا   ب  ح  ر  م  ,   _
632 //      25 24 23 22 21 20 19 18 17 16 15 14 13 26 27
633
634 // LO    h  e  l  l  o  _  w  o  r  l  d \n
635 //      28 29 30 31 32 33 34 35 36 37 38 39
636 // VO    h  e  l  l  o  _  w  o  r  l  d \n
637 //      28 29 30 31 32 33 34 35 36 37 38 39
638
639 // LO   م  ر  ح  ب   ا  _  ب  ا  ل  ع   ا  ل  م  ,  _
640 //     40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
641 // VO   _  ,  م  ل  ا   ع  ل  ا  ب  _  ا   ب  ح  ر  م
642 //     54 53 52 51 50 49 48 47 46 45 44 43 42 41 40
643
644 // LO   h  e  l  l  o  _  w  o  r  l  d   ,  _
645 //     55 56 57 58 59 60 61 62 63 64 65 66 67
646 // VO   _  ,  h  e  l  l  o  _  w  o  r  l  d
647 //     67 66 55 56 57 58 59 60 61 62 63 64 65
648
649 // LO   م  ر  ح  ب   ا  _  ب  ا  ل  ع   ا  ل  م  \n
650 //     68 69 70 71 72 73 74 75 76 77 78 79 80 81
651 // VO  \n  م  ل  ا   ع  ل  ا  ب  _  ا   ب  ح  ر  م
652 //     81 80 79 78 77 76 75 74 73 72 71 70 69 68
653
654 // LO   م  ر  ح  ب   ا  _  ب  ا  ل  ع   ا  ل  م  \n
655 //     82 83 84 85 86 87 88 89 90 91 92 93 94 95
656 // VO  \n  م  ل  ا  ع  ل   ا  ب  _  ا   ب  ح  ر  م
657 //     95 94 93 92 91 90 89 88 87 86 85 84 83 82
658
659
660 // LO   h   e   l   l   o   _   w   o   r   l   d
661 //     96  97  98  99 100 101 102 103 104 105 106
662 // VO   h   e   l   l   o   _   w   o   r   l   d
663 //     96  97  98  99 100 101 102 103 104 105 106
664
665   struct GetLogicalCharacterIndexData data[] =
666   {
667     {
668       "Zero characters text",
669       "",
670       Size( 300.f, 300.f ),
671       0u,
672       visualToLogical01,
673       cachedBidiLine01
674     },
675     {
676       "Left to right text only",
677       "Hello world",
678       Size( 300.f, 300.f ),
679       11u,
680       visualToLogical02,
681       cachedBidiLine02
682     },
683     {
684       "Right to left text only",
685       "مرحبا بالعالم",
686       Size( 300.f, 300.f ),
687       13u,
688       visualToLogical03,
689       cachedBidiLine03
690     },
691     {
692       "Mix of left to right and right to left text.",
693       "Hello world, مرحبا بالعالم, hello world\nمرحبا بالعالم, hello world, مرحبا بالعالم\nمرحبا بالعالم\nhello world",
694       Size( 300.f, 300.f ),
695       107u,
696       visualToLogical04,
697       cachedBidiLine04
698     },
699     {
700       "Mix of left to right and right to left text.",
701       "Hello world, مرحبا بالعالم, hello world\nمرحبا بالعالم, hello world, مرحبا بالعالم\nمرحبا بالعالم\nhello world",
702       Size( 200.f, 400.f ),
703       107u,
704       visualToLogical05,
705       cachedBidiLine05
706     },
707     {
708       "Mix of left to right and right to left text.",
709       "Hello world, مرحبا بالعالم, hello world\nمرحبا بالعالم, hello world, مرحبا بالعالم\nمرحبا بالعالم\nhello world",
710       Size( 100.f, 600.f ),
711       107u,
712       visualToLogical06,
713       cachedBidiLine06
714     },
715   };
716   const unsigned int numberOfTests = 6u;
717
718   for( unsigned int index = 0u; index < numberOfTests; ++index )
719   {
720     ToolkitTestApplication application;
721     if( !GetLogicalCharacterIndexTest( data[index] ) )
722     {
723       tet_result(TET_FAIL);
724     }
725   }
726
727   tet_result(TET_PASS);
728   END_TEST;
729 }
730
731 int UtcDaliGetLogicalCursorIndex(void)
732 {
733   tet_infoline(" UtcDaliGetLogicalCursorIndex");
734
735   unsigned int visualIndex01[] = { 10u };
736   unsigned int characterIndex01[] = { 0u };
737   unsigned int logicalIndex01[] = { 10u };
738   unsigned int bidirectionalLineIndex01[] = { 0u };
739
740   //  0           11
741   //   Hello world  \n
742   // 12    16
743   //   demo
744   unsigned int visualIndex02[] = { 0u, 16u, 11u, 12u };
745   unsigned int characterIndex02[] = { 0u, 0u, 0u, 0u };
746   unsigned int logicalIndex02[] = { 0u, 16u, 11u, 12u };
747   unsigned int bidirectionalLineIndex02[] = { 0u, 0u, 0u, 0u };
748
749
750 // LO     H  e  l  l  o  _  w  o  r  l  d  \n
751 //       0  1  2  3  4  5  6  7  8  9 10 11  12
752 // VO     H  e  l  l  o  _  w  o  r  l  d  \n
753
754 // LO         ש  ל  ו  ם  _  ע  ו  ל  ם \n
755 //          12 13 14 15 16 17 18 19 20 21  22
756 // VO     \n  ם  ל  ו  ע _  ם  ו  ל  ש
757
758 // LO      h  e  l  l  o  _  w  o  r  l  d  _  ש  ל  ו  ם  _  ע ו  ל  ם  \n
759 //       22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43  44
760 // VO      h  e  l  l  o  _  w  o  r  l  d  _  ם  ל  ו  ע  _  ם  ו  ל  ש  \n
761
762 // LO      ש  ל  ו  ם  _  ע  ו  ל  ם  _  h  e  l  l  o  _  w  o  r   l  d \n
763 //       44 45 46 47 48 49 50 51  52 52 54 55 56 57 58 59 60 61 62 63  64 65 66
764 // VO      \n h  e  l  l  o  _  w   o  r  l  d  _  ם  ל  ו  ע  _  ם  ו  ל  ש
765
766   unsigned int visualIndex03[] = {  0u,  1u,  2u,  3u,  4u,  5u,  6u,  7u,  8u,  9u, 10u, 11u,
767                                    13u, 14u, 15u, 16u, 17u, 18u, 19u, 20u, 21u, 22u,
768                                    22u, 23u, 24u, 25u, 26u, 27u, 28u, 29u, 30u, 31u, 32u, 33u, 34u, 35u, 36u, 37u, 38u, 39u, 40u, 41u, 42u, 43u,
769                                    45u, 46u, 47u, 48u, 49u, 50u, 51u, 52u, 53u, 54u, 55u, 56u, 57u, 58u, 59u, 60u, 61u, 62u, 63u, 64u, 65u, 66u };
770
771   unsigned int characterIndex03[] = {  0u,  0u,  0u,  0u,  0u,  0u,  0u,  0u,  0u,  0u,  0u,  0u,
772                                       12u, 12u, 12u, 12u, 12u, 12u, 12u, 12u, 12u, 12u,
773                                       22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u,
774                                       44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u};
775
776   unsigned int logicalIndex03[] = {  0u,  1u,  2u,  3u,  4u,  5u,  6u,  7u,  8u,  9u, 10u, 11u,
777                                     21u, 20u, 19u, 18u, 17u, 16u, 15u, 14u, 13u, 12u,
778                                     22u, 23u, 24u, 25u, 26u, 27u, 28u, 29u, 30u, 31u, 32u, 33u, 34u, 42u, 41u, 40u, 39u, 38u, 37u, 36u, 35u, 43u,
779                                     65u, 55u, 56u, 57u, 58u, 59u, 60u, 61u, 62u, 63u, 64u, 54u, 53u, 52u, 51u, 50u, 49u, 48u, 47u, 46u, 45u, 44u };
780
781   unsigned int bidirectionalLineIndex03[] = { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
782                                               0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
783                                               1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u,
784                                               2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u };
785
786
787 // LO     ש  ל  ו  ם  _  ע  ו  ל  ם \n
788 //       0  1  2  3  4  5  6  7  8  9 10
789 // VO  \n ם  ל  ו  ע  _  ם  ו  ל  ש
790
791 //      h  e  l  l  o  _  w  o  r  l  d  \n
792 // LO 10 11 12 13 14 15 16 17 18 19 20 21 22
793 //      h  e  l  l  o  _  w  o  r  l  d  \n
794
795 //         ש  ל  ו  ם  _  ע  ו  ל  ם _  h  e  l  l  o  _  w  o  r  l  d  \n
796 // LO    22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
797 //     \n  h  e  l  l  o  _  w  o  r  l  d  _  ם  ל  ו  ע  _  ם  ו  ל  ש
798
799 //      h  e  l  l  o  _  w  o  r  l  d  _  ש  ל  ו  ם  _  ע  ו  ל  ם \n
800 // LO 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
801 //      h  e  l  l  o  _  w  o  r  l  d  _  ם  ל  ו  ע  _  ם  ו  ל  ש \n
802
803   unsigned int  visualIndex04[] = {  1u,  2u,  3u,  4u,  5u,  6u,  7u,  8u,  9u, 10u,
804                                     10u, 12u, 13u, 14u, 15u, 16u, 17u, 18u, 19u, 20u, 21u,
805                                     23u, 24u, 25u, 26u, 27u, 28u, 29u, 30u, 31u, 32u, 33u, 34u, 35u, 36u, 37u, 38u, 39u, 40u, 41u, 42u, 43u, 44u,
806                                     44u, 45u, 46u, 47u, 48u, 49u, 50u, 51u, 52u, 53u, 54u, 55u, 56u, 57u, 58u, 59u, 60u, 61u, 62u, 63u, 64u, 65u };
807
808   unsigned int characterIndex04[] = {  0u,  0u,  0u,  0u,  0u,  0u,  0u,  0u,  0u,  0u,
809                                       10u, 10u, 10u, 10u, 10u, 10u, 10u, 10u, 10u, 10u, 10u,
810                                       22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u,
811                                       44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u };
812
813   unsigned int logicalIndex04[] = {  9u,  8u,  7u,  6u,  5u,  4u,  3u,  2u,  1u,  0u,
814                                     10u, 12u, 13u, 14u, 15u, 16u, 17u, 18u, 19u, 20u, 21u,
815                                     43u, 33u, 34u, 35u, 36u, 37u, 38u, 39u, 40u, 41u, 42u, 32u, 31u, 30u, 29u, 28u, 27u, 26u, 25u, 24u, 23u, 22u,
816                                     44u, 45u, 46u, 47u, 48u, 49u, 50u, 51u, 52u, 53u, 54u, 55u, 56u, 64u, 63u, 62u, 61u, 60u, 59u, 58u, 57u, 65u };
817
818   unsigned int bidirectionalLineIndex04[] = { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
819                                               0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
820                                               1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u,
821                                               2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u };
822
823
824 // LO   A  B  C  D  E  F  G  H  I  J  K
825 //     0  1  2  3  4  5  6  7  8  9 10 11
826 // LO   L  M  N
827 //    11 12 13 14
828
829   unsigned int  visualIndex05[] = {  0u,  1u,  2u,  3u,  4u,  5u,  6u,  7u,  8u,  9u, 10u,
830                                     11u, 12u, 13u, 14u };
831
832   unsigned int characterIndex05[] = { 0u,  0u,  0u,  0u,  0u,  0u,  0u,  0u,  0u,  0u,  0u,
833                                       11u, 11u, 11u, 11u };
834
835   unsigned int logicalIndex05[] = { 0u,  1u,  2u,  3u,  4u,  5u,  6u,  7u,  8u,  9u, 10u,
836                                     11u, 12u, 13u, 14u };
837
838   unsigned int bidirectionalLineIndex05[] = { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
839                                               0u, 0u, 0u, 0u };
840
841 // LO      ק  ר  א  ט  ו  ן  ם  פ  ש  ד  ג
842 //        0  1  2  3  4  5  6  7  8  9  10 11
843 // VO      ג  ד  ש  פ  ם  ן  ו  ט  א  ר  ק
844
845 // LO      כ  ע  י  ח  ל
846 //       11 12 13 14 15 16
847 // VO      ל  ח  י  ע  כ
848
849   unsigned int  visualIndex06[] = {  1u,  2u,  3u,  4u,  5u,  6u,  7u,  8u,  9u, 10u, 11u,
850                                     11u, 12u, 13u, 14u, 15u, 16u };
851
852   unsigned int characterIndex06[] = {  0u,  0u,  0u,  0u,  0u,  0u,  0u,  0u,  0u,  0u,  0u,
853                                       12u, 12u, 12u, 12u, 12u, 12u };
854
855   unsigned int logicalIndex06[] = { 10u,  9u,  8u,  7u,  6u,  5u,  4u,  3u,  2u,  1u,  0u,
856                                     16u, 15u, 14u, 13u, 12u, 11u };
857
858   unsigned int bidirectionalLineIndex06[] = { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
859                                               1u, 1u, 1u, 1u, 1u, 1u };
860
861   struct GetLogicalCursorIndexData data[] =
862   {
863     {
864       "Zero characters text",
865       "",
866       Size( 300.f, 300.f ),
867       1u,
868       visualIndex01,
869       characterIndex01,
870       logicalIndex01,
871       bidirectionalLineIndex01,
872     },
873     {
874       "All left to right text 01.",
875       "Hello world\ndemo",
876       Size( 300.f, 300.f ),
877       4u,
878       visualIndex02,
879       characterIndex02,
880       logicalIndex02,
881       bidirectionalLineIndex02,
882     },
883     {
884       "bidirectional text 01.",
885       "Hello world\nשלום עולם\nhello world שלום עולם\nשלום עולם hello world\n",
886       Size( 300.f, 300.f ),
887       65u,
888       visualIndex03,
889       characterIndex03,
890       logicalIndex03,
891       bidirectionalLineIndex03,
892     },
893     {
894       "bidirectional text 02.",
895       "שלום עולם\nhello world\nשלום עולם hello world\nhello world שלום עולם\n",
896       Size( 300.f, 300.f ),
897       65u,
898       visualIndex04,
899       characterIndex04,
900       logicalIndex04,
901       bidirectionalLineIndex04,
902     },
903     {
904       "long line 01.",
905       "ABCDEFGHIJKLMN",
906       Size( 100.f, 300.f ),
907       13u,
908       visualIndex05,
909       characterIndex05,
910       logicalIndex05,
911       bidirectionalLineIndex05,
912     },
913     {
914       "bidirectional text 03.",
915       "קראטוןםפשדגכעיחל",
916       Size( 100.f, 300.f ),
917       15u,
918       visualIndex06,
919       characterIndex06,
920       logicalIndex06,
921       bidirectionalLineIndex06,
922     },
923   };
924   const unsigned int numberOfTests = 6u;
925
926   for( unsigned int index = 0u; index < numberOfTests; ++index )
927   {
928     ToolkitTestApplication application;
929     if( !GetLogicalCursorIndexTest( data[index] ) )
930     {
931       tet_result(TET_FAIL);
932     }
933   }
934
935   tet_result(TET_PASS);
936   END_TEST;
937 }