[AT-SPI] Catch exception by reference
[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 #include <stdlib.h>
20 #include <unistd.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-utils.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 const std::string DEFAULT_FONT_DIR( "/resources/fonts" );
48
49 struct CreateParagraphData
50 {
51   std::string    description;                    ///< Description of the test.
52   std::string    text;                           ///< Input text.
53   CharacterIndex index;                          ///< The first character index.
54   Length         numberOfCharacters;             ///< The number of characters.
55   unsigned int   numberOfParagraphs;             ///< The expected number of paragraphs.
56   unsigned int*  indices;                        ///< The expected paragraph info indices.
57   unsigned int*  numberOfCharactersPerParagraph; ///< The expected number of characters of each paragraph.
58 };
59
60 struct FindParagraphData
61 {
62   std::string    description;        ///< Description of the test.
63   std::string    text;               ///< Input text.
64   CharacterIndex index;              ///< The first character index.
65   Length         numberOfCharacters; ///< The number of characters.
66   unsigned int   numberOfParagraphs; ///< The expected number of paragraphs.
67   unsigned int*  paragraphs;         ///< The expected paragraph info.
68 };
69
70 struct FetchBidirectionalLineInfoData
71 {
72   std::string   description;    ///< Description of the test.
73   std::string   text;           ///< Input text.
74   unsigned int  numberOfTests;  ///< The number of tests.
75   unsigned int* characterIndex; ///< The logical character index.
76   bool*         fetched;        ///< Whether the expected bidi line exists.
77   unsigned int* bidiLineIndex;  ///< Index to the expected bidi line.
78 };
79
80 struct GetLogicalCharacterIndexData
81 {
82   std::string   description;        ///< Description of the test.
83   std::string   text;               ///< Input text.
84   Size          textArea;           ///< The text area.
85   unsigned int  numberOfIndices;    ///< The number of characters to set.
86   unsigned int* visualToLogical;    ///< The expected visual to logical conversion table.
87   unsigned int* cachedBidiLine;     ///< The cached bidi line index for each character.
88 };
89
90 struct GetLogicalCursorIndexData
91 {
92   std::string         description;        ///< Description of the test.
93   std::string         text;               ///< Input text.
94   Size                textArea;           ///< The text area.
95   unsigned int        numberOfFonts;      ///< The number of fonts.
96   FontDescriptionRun* fontDescriptions;   ///< The font descriptions.
97   unsigned int        numberOfIndices;    ///< The number of characters to set.
98   unsigned int*       visualCursorIndex;  ///< The given cursor visual index.
99   unsigned int*       characterIndex;     ///< Index to the first logical character of the line.
100   unsigned int*       logicalCursorIndex; ///< The expected cursor logical index.
101   unsigned int*       cachedBidiLine;     ///< The cached bidi line index for each character.
102 };
103
104 bool CreateParagraphTest( const CreateParagraphData& data )
105 {
106   // 1) Create the model.
107   ModelPtr textModel;
108   MetricsPtr metrics;
109   Size textArea(100.f, 60.f);
110   Size layoutSize;
111
112   Vector<FontDescriptionRun> fontDescriptionRuns;
113   LayoutOptions options;
114   CreateTextModel( data.text,
115                    textArea,
116                    fontDescriptionRuns,
117                    options,
118                    layoutSize,
119                    textModel,
120                    metrics,
121                    false );
122
123   LogicalModelPtr logicalModel = textModel->mLogicalModel;
124   VisualModelPtr visualModel = textModel->mVisualModel;
125
126   // 2) Clear the paragraphs.
127   Vector<ParagraphRun>& paragraphs = logicalModel->mParagraphInfo;
128   ClearCharacterRuns( data.index,
129                       data.index + data.numberOfCharacters - 1u,
130                       paragraphs );
131
132   // 3) Call the LogicalModel::CreateParagraphInfo() method
133   logicalModel->CreateParagraphInfo( data.index,
134                                      data.numberOfCharacters );
135
136   // 4) Compare the results.
137   if( data.numberOfParagraphs != paragraphs.Count() )
138   {
139     std::cout << "  Different number of paragraphs : " << paragraphs.Count() << ", expected : " << data.numberOfParagraphs << std::endl;
140     return false;
141   }
142
143   unsigned int index = 0u;
144   for( Vector<ParagraphRun>::ConstIterator it = paragraphs.Begin(),
145          endIt = paragraphs.End();
146        it != endIt;
147        ++it, ++index )
148   {
149     const ParagraphRun& paragraph( *it );
150
151     if( data.indices[index] != paragraph.characterRun.characterIndex )
152     {
153       std::cout << "  Different character index for paragraph : " << index << ", " << paragraph.characterRun.characterIndex << ", expected : " << data.indices[index] << std::endl;
154       return false;
155     }
156     if( data.numberOfCharactersPerParagraph[index] != paragraph.characterRun.numberOfCharacters )
157     {
158       std::cout << "  Different number of characters for paragraph : " << index << ", " << paragraph.characterRun.numberOfCharacters << ", expected : " << data.numberOfCharactersPerParagraph[index] << std::endl;
159       return false;
160     }
161   }
162
163   return true;
164 }
165
166 bool FindParagraphTest( const FindParagraphData& data )
167 {
168   // 1) Create the model.
169   ModelPtr textModel;
170   MetricsPtr metrics;
171   Size textArea(100.f, 60.f);
172   Size layoutSize;
173
174   Vector<FontDescriptionRun> fontDescriptionRuns;
175   LayoutOptions options;
176   CreateTextModel( data.text,
177                    textArea,
178                    fontDescriptionRuns,
179                    options,
180                    layoutSize,
181                    textModel,
182                    metrics,
183                    false );
184
185   LogicalModelPtr logicalModel = textModel->mLogicalModel;
186   VisualModelPtr visualModel = textModel->mVisualModel;
187
188   // 2) Find the paragraphs.
189   Vector<ParagraphRunIndex> paragraphs;
190   logicalModel->FindParagraphs( data.index, data.numberOfCharacters, paragraphs );
191
192   // 3) compare the results.
193   if( data.numberOfParagraphs != paragraphs.Count() )
194   {
195     return false;
196   }
197
198   unsigned int index = 0u;
199   for( Vector<ParagraphRunIndex>::ConstIterator it = paragraphs.Begin(),
200          endIt = paragraphs.End();
201        it != endIt;
202        ++it, ++index )
203   {
204     const ParagraphRunIndex paragraphIndex = *it;
205
206     if( paragraphIndex != data.paragraphs[index] )
207     {
208       return false;
209     }
210   }
211
212   return true;
213 }
214
215 bool FetchBidirectionalLineInfoTest( const FetchBidirectionalLineInfoData& data )
216 {
217   std::cout << "  testing : " << data.description << std::endl;
218   // Create the model.
219   ModelPtr textModel;
220   MetricsPtr metrics;
221   Size textArea( 100.f, 300.f );
222   Size layoutSize;
223
224   // Create the model with the whole text.
225   const Vector<FontDescriptionRun> fontDescriptions;
226   const LayoutOptions options;
227   CreateTextModel( data.text,
228                    textArea,
229                    fontDescriptions,
230                    options,
231                    layoutSize,
232                    textModel,
233                    metrics,
234                    false );
235
236   LogicalModelPtr logicalModel = textModel->mLogicalModel;
237   VisualModelPtr visualModel = textModel->mVisualModel;
238
239   for( unsigned int index = 0; index < data.numberOfTests; ++index )
240   {
241     const bool fetched = logicalModel->FetchBidirectionalLineInfo( data.characterIndex[index] );
242
243     if( fetched != data.fetched[index] )
244     {
245       std::cout << "  Different fetched result : " << fetched << ", expected : " << data.fetched[index] << std::endl;
246       return false;
247     }
248
249     if( fetched )
250     {
251       if( logicalModel->mBidirectionalLineIndex != data.bidiLineIndex[index] )
252       {
253         std::cout << "  Different bidi line index : " << logicalModel->mBidirectionalLineIndex << ", expected : " << data.bidiLineIndex << std::endl;
254         return false;
255       }
256     }
257   }
258
259   return true;
260 }
261
262 bool GetLogicalCharacterIndexTest( const GetLogicalCharacterIndexData& data )
263 {
264   std::cout << "  testing : " << data.description << std::endl;
265   // Create the model.
266   ModelPtr textModel;
267   MetricsPtr metrics;
268   Size layoutSize;
269
270   // Create the model with the whole text.
271   const Vector<FontDescriptionRun> fontDescriptions;
272   const LayoutOptions options;
273   CreateTextModel( data.text,
274                    data.textArea,
275                    fontDescriptions,
276                    options,
277                    layoutSize,
278                    textModel,
279                    metrics,
280                    false );
281
282   LogicalModelPtr logicalModel = textModel->mLogicalModel;
283   VisualModelPtr visualModel = textModel->mVisualModel;
284
285   for( unsigned int index = 0u; index < data.numberOfIndices; ++index )
286   {
287     // Check the current cached bidi line index. (Check it before call the GetLogicalCharacterIndex() method )
288     if( data.cachedBidiLine[index] != logicalModel->mBidirectionalLineIndex )
289     {
290       std::cout << "  index : " << index << ", different cached bidi index : " << logicalModel->mBidirectionalLineIndex << ", expected : " << data.cachedBidiLine[index] << std::endl;
291       return false;
292     }
293
294     const bool fetched = logicalModel->FetchBidirectionalLineInfo( index );
295     const Character logicalIndex = fetched ? logicalModel->GetLogicalCharacterIndex( index ) : index;
296
297     if( data.visualToLogical[index] != logicalIndex )
298     {
299       std::cout << "  visual index : " << index << ", different logical index : " << logicalIndex << ", expected : " << data.visualToLogical[index] << std::endl;
300       return false;
301     }
302   }
303   return true;
304 }
305
306 bool GetLogicalCursorIndexTest( const GetLogicalCursorIndexData& data )
307 {
308   tet_printf( "  testing : %s\n", data.description.c_str() );
309
310   // Load some fonts.
311   TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
312   fontClient.SetDpi( 96u, 96u );
313
314   char* pathNamePtr = get_current_dir_name();
315   const std::string pathName( pathNamePtr );
316   free( pathNamePtr );
317
318   fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/tizen/TizenSansRegular.ttf" );
319   fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/tizen/TizenSansHebrewRegular.ttf" );
320
321   // Create the model.
322   ModelPtr textModel;
323   MetricsPtr metrics;
324   Size layoutSize;
325
326   // Create the model with the whole text.
327   Vector<FontDescriptionRun> fontDescriptionRuns;
328   if( 0u != data.numberOfFonts )
329   {
330     fontDescriptionRuns.Insert( fontDescriptionRuns.End(),
331                                 data.fontDescriptions,
332                                 data.fontDescriptions + data.numberOfFonts );
333   }
334
335   const LayoutOptions options;
336   CreateTextModel( data.text,
337                    data.textArea,
338                    fontDescriptionRuns,
339                    options,
340                    layoutSize,
341                    textModel,
342                    metrics,
343                    false );
344
345   LogicalModelPtr logicalModel = textModel->mLogicalModel;
346   VisualModelPtr visualModel = textModel->mVisualModel;
347
348   for( unsigned int index = 0u; index < data.numberOfIndices; ++index )
349   {
350     const bool fetched = logicalModel->FetchBidirectionalLineInfo( data.characterIndex[index] );
351     tet_printf("  fetched %d, line index %d, expected line index %d\n", fetched, logicalModel->mBidirectionalLineIndex, data.cachedBidiLine[index] );
352
353     if( logicalModel->mBidirectionalLineIndex != data.cachedBidiLine[index] )
354     {
355       tet_printf( "  test : %d, different cached line index : %d, expected : %d\n", index, logicalModel->mBidirectionalLineIndex, data.cachedBidiLine[index] );
356       return false;
357     }
358
359     const CharacterIndex visualCharacterIndex = data.visualCursorIndex[index];
360     const CharacterIndex logicalCursorIndex = fetched ? logicalModel->GetLogicalCursorIndex( visualCharacterIndex ) : visualCharacterIndex;
361     tet_printf("  visual index %d, logical index %d\n", visualCharacterIndex, logicalCursorIndex);
362
363     if( logicalCursorIndex != data.logicalCursorIndex[index] )
364     {
365       tet_printf( "  test : %d, visual index : %d, different logical cursor index :%d, expected : %d\n", index, visualCharacterIndex, logicalCursorIndex, data.logicalCursorIndex[index] );
366       return false;
367     }
368   }
369
370   return true;
371 }
372
373 } // namespace
374
375 //////////////////////////////////////////////////////////
376 //
377 // UtcDaliCreateParagraph
378 // UtcDaliFindParagraph
379 // UtcDaliFetchBidirectionalLineInfo
380 // UtcDaliGetLogicalCharacterIndex
381 // UtcDaliGetLogicalCursorIndex
382 //
383 //////////////////////////////////////////////////////////
384
385 int UtcDaliCreateParagraph(void)
386 {
387   tet_infoline(" UtcDaliCreateParagraph");
388
389   unsigned int paragraphsIndices01[] = { 0u };
390   unsigned int paragraphsNumberOfCharacters01[] = { 0u };
391   unsigned int paragraphsIndices02[] = { 0u, 12u, 17u };
392   unsigned int paragraphsNumberOfCharacters02[] = { 12u, 5u, 1u };
393   unsigned int paragraphsIndices03[] = { 0u, 12u, 17u, 34u };
394   unsigned int paragraphsNumberOfCharacters03[] = { 12u, 5u, 17u ,1u };
395
396   struct CreateParagraphData data[] =
397   {
398     {
399       "Zero characters",
400       "",
401       0u,
402       0u,
403       0u,
404       paragraphsIndices01,
405       paragraphsNumberOfCharacters01,
406     },
407     {
408       "Some paragraphs",
409       "Hello world\ndemo\n\n",
410       0u,
411       18u,
412       3u,
413       paragraphsIndices02,
414       paragraphsNumberOfCharacters02,
415     },
416     {
417       "Some paragraphs. Update the initial paragraphs.",
418       "Hello world\ndemo\nhello world demo\n\n",
419       0u,
420       17u,
421       4u,
422       paragraphsIndices03,
423       paragraphsNumberOfCharacters03,
424     },
425     {
426       "Some paragraphs. Update the mid paragraphs.",
427       "Hello world\ndemo\nhello world demo\n\n",
428       12u,
429       5u,
430       4u,
431       paragraphsIndices03,
432       paragraphsNumberOfCharacters03,
433     },
434     {
435       "Some paragraphs. Update the final paragraphs.",
436       "Hello world\ndemo\nhello world demo\n\n",
437       17u,
438       18u,
439       4u,
440       paragraphsIndices03,
441       paragraphsNumberOfCharacters03,
442     },
443   };
444   const unsigned int numberOfTests = 5u;
445
446   for( unsigned int index = 0u; index < numberOfTests; ++index )
447   {
448     ToolkitTestApplication application;
449     if( !CreateParagraphTest( data[index] ) )
450     {
451       tet_result(TET_FAIL);
452     }
453   }
454
455   tet_result(TET_PASS);
456   END_TEST;
457 }
458
459 int UtcDaliFindParagraph(void)
460 {
461   tet_infoline(" UtcDaliFindParagraph");
462
463   unsigned int paragraphs01[] = {};
464   unsigned int paragraphs02[] = { 0u, 1u, 2u };
465   unsigned int paragraphs03[] = { 0u };
466   unsigned int paragraphs04[] = { 1u };
467   unsigned int paragraphs05[] = { 0u, 1u, 2u };
468
469   struct FindParagraphData data[] =
470   {
471     {
472       "Zero characters",
473       "",
474       0u,
475       100u,
476       0u,
477       paragraphs01,
478     },
479     {
480       "Some paragraphs",
481       "Hello world\ndemo\n\n",
482       0u,
483       18u,
484       3u,
485       paragraphs02
486     },
487     {
488       "Some paragraphs",
489       "Hello world\ndemo\n\n",
490       0u,
491       12u,
492       1u,
493       paragraphs03
494     },
495     {
496       "Some paragraphs",
497       "Hello world\ndemo\n\n",
498       12u,
499       5u,
500       1u,
501       paragraphs04
502     },
503     {
504       "Some paragraphs",
505       "Hello world\ndemo\n\n",
506       3u,
507       15u,
508       3u,
509       paragraphs05
510     },
511   };
512   const unsigned int numberOfTests = 5u;
513
514   for( unsigned int index = 0u; index < numberOfTests; ++index )
515   {
516     ToolkitTestApplication application;
517     if( !FindParagraphTest( data[index] ) )
518     {
519       tet_result(TET_FAIL);
520     }
521   }
522
523   tet_result(TET_PASS);
524   END_TEST;
525 }
526
527 int UtcDaliFetchBidirectionalLineInfo(void)
528 {
529   tet_infoline(" UtcDaliFetchBidirectionalLineInfo");
530
531   unsigned int logicalIndex01[] = { 0u };
532   bool fetched01[] = { false };
533   unsigned int bidiLine01[] = { 0u };
534
535   unsigned int logicalIndex02[] = { 3u };
536   bool fetched02[] = { false };
537   unsigned int bidiLine02[] = { 0u };
538
539   unsigned int logicalIndex03[] = { 0u, 11u, 12u, 21u, 22u, 33u, 34u, 43u, 44u, 54u};
540   bool fetched03[] = { false, false, true, true, false, false, true, true, false, false };
541   unsigned int bidiLine03[] = { 0u, 0u, 0u, 0u, 0u, 0u, 1u, 1u, 0u, 0u };
542
543   struct FetchBidirectionalLineInfoData data[] =
544   {
545     {
546       "Void text",
547       "",
548       1u,
549       logicalIndex01,
550       fetched01,
551       bidiLine01
552     },
553     {
554       "LTR text",
555       "Hello world",
556       1u,
557       logicalIndex02,
558       fetched02,
559       bidiLine02
560     },
561     {
562       "Bidi text",
563       "Hello world\nשלום עולם\nhello world\nשלום עולם\nhello world",
564       10u,
565       logicalIndex03,
566       fetched03,
567       bidiLine03
568     }
569   };
570   const unsigned int numberOfTests = 3u;
571
572   for( unsigned int index = 0u; index < numberOfTests; ++index )
573   {
574     ToolkitTestApplication application;
575     if( !FetchBidirectionalLineInfoTest( data[index] ) )
576     {
577       tet_result(TET_FAIL);
578     }
579   }
580
581   tet_result(TET_PASS);
582   END_TEST;
583 }
584
585 int UtcDaliGetLogicalCharacterIndex(void)
586 {
587   tet_infoline(" UtcDaliSetVisualToLogicalMap");
588
589   unsigned int visualToLogical01[] = {};
590   unsigned int  cachedBidiLine01[] = {};
591   unsigned int visualToLogical02[] = { 0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 9u, 10u };
592   unsigned int  cachedBidiLine02[] = { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,  0u };
593   unsigned int visualToLogical03[] = { 12u, 11u, 10u, 9u, 8u, 7u, 6u, 5u, 4u, 3u, 2u, 1u, 0u };
594   unsigned int  cachedBidiLine03[] = {  0u,  0u,  0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u };
595
596   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 };
597   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,
598                                        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,
599                                        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 };
600
601 // size 300, 300
602 // LO   H  e  l  l  o  _  w  o  r  l  d  ,  _  م  ر  ح  ب   ا  _  ب  ا  ل  ع   ا  ل  م  ,   _  h  e  l  l  o  _  w  o  r  l  d \n
603 //      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
604 // VO   H  e  l  l  o  _  w  o  r  l  d  ,  _  م  ل  ا  ع   ل  ا  ب  _  ا   ب  ح  ر  م  ,   _  h  e  l  l  o  _  w  o  r  l  d \n
605 //      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
606
607 // LO   م  ر  ح  ب   ا  _  ب  ا  ل  ع   ا  ل  م  ,  _  h  e  l  l  o  _  w  o  r  l  d   ,  _  م  ر  ح  ب   ا  _  ب  ا  ل  ع   ا  ل  م  \n
608 //     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
609 // VO  \n  م  ل  ا   ع  ل  ا  ب  _  ا   ب  ح  ر  م  _  ,  h  e  l  l  o  _  w  o  r  l  d   _  ,  م  ل  ا   ع  ل  ا  ب  _  ا   ب  ح  ر  م
610 //     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
611
612 // LO   م  ر  ح  ب   ا  _  ب  ا  ل  ع   ا  ل  م  \n
613 //     82 83 84 85 86 87 88 89 90 91 92 93 94 95
614 // VO  \n  م  ل  ا  ع  ل   ا  ب  _  ا   ب  ح  ر  م
615 //     95 94 93 92 91 90 89 88 87 86 85 84 83 82
616
617
618 // LO   h   e   l   l   o   _   w   o   r   l   d
619 //     96  97  98  99 100 101 102 103 104 105 106
620 // VO   h   e   l   l   o   _   w   o   r   l   d
621 //     96  97  98  99 100 101 102 103 104 105 106
622
623   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 };
624   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 };
625
626 // size 300, 300
627 // LO   H  e  l  l  o  _  w  o  r  l  d  ,  _  م  ر  ح  ب   ا  _  ب  ا  ل  ع   ا  ل  م  ,   _
628 //      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
629 // VO   H  e  l  l  o  _  w  o  r  l  d  ,  _  م  ل  ا  ع   ل  ا  ب  _  ا   ب  ح  ر  م  ,   _
630 //      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
631
632 // LO    h  e  l  l  o  _  w  o  r  l  d \n
633 //      28 29 30 31 32 33 34 35 36 37 38 39
634 // VO    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
637 // LO   م  ر  ح  ب   ا  _  ب  ا  ل  ع   ا  ل  م  ,  _  h  e  l  l  o  _  w  o  r  l  d   ,  _
638 //     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
639 // VO  _  ,  h  e  l  l  o  _  w  o  r  l  d   _  ,  م  ل  ا   ع  ل  ا  ب  _  ا   ب  ح  ر  م
640 //     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
641
642 // LO   م  ر  ح  ب   ا  _  ب  ا  ل  ع   ا  ل  م  \n
643 //     68 69 70 71 72 73 74 75 76 77 78 79 80 81
644 // VO  \n  م  ل  ا   ع  ل  ا  ب  _  ا   ب  ح  ر  م
645 //     81 80 79 78 77 76 75 74 73 72 71 70 69 68
646
647 // LO   م  ر  ح  ب   ا  _  ب  ا  ل  ع   ا  ل  م  \n
648 //     82 83 84 85 86 87 88 89 90 91 92 93 94 95
649 // VO  \n  م  ل  ا  ع  ل   ا  ب  _  ا   ب  ح  ر  م
650 //     95 94 93 92 91 90 89 88 87 86 85 84 83 82
651
652
653 // LO   h   e   l   l   o   _   w   o   r   l   d
654 //     96  97  98  99 100 101 102 103 104 105 106
655 // VO   h   e   l   l   o   _   w   o   r   l   d
656 //     96  97  98  99 100 101 102 103 104 105 106
657
658   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 };
659   unsigned int  cachedBidiLine06[] = { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
660                                        0u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u,
661                                        1u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u,
662                                        2u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u,
663                                        3u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u,
664                                        4u, 5u, 5u, 5u, 5u, 5u, 5u, 5u, 5u, 5u, 5u, 5u, 5u, 5u,
665                                        5u, 6u, 6u, 6u, 6u, 6u, 6u, 6u, 6u, 6u, 6u, 6u, 6u, 6u,
666                                        6u, 6u, 6u, 6u, 6u, 6u, 6u, 6u, 6u, 6u, 6u };
667
668 // size 100, 600
669 // LO   H  e  l  l  o  _  w  o  r  l  d  ,  _
670 //      0  1  2  3  4  5  6  7  8  9 10 11 12
671 // VO   H  e  l  l  o  _  w  o  r  l  d  ,  _
672 //      0  1  2  3  4  5  6  7  8  9 10 11 12
673
674 // LO    م  ر  ح  ب   ا  _  ب  ا  ل  ع   ا  ل  م  ,   _
675 //      13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
676 // VO    م  ل  ا  ع   ل  ا  ب  _  ا   ب  ح  ر  م  ,   _
677 //      25 24 23 22 21 20 19 18 17 16 15 14 13 26 27
678
679 // LO    h  e  l  l  o  _  w  o  r  l  d \n
680 //      28 29 30 31 32 33 34 35 36 37 38 39
681 // VO    h  e  l  l  o  _  w  o  r  l  d \n
682 //      28 29 30 31 32 33 34 35 36 37 38 39
683
684 // LO   م  ر  ح  ب   ا  _  ب  ا  ل  ع   ا  ل  م  ,  _
685 //     40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
686 // VO   _  ,  م  ل  ا   ع  ل  ا  ب  _  ا   ب  ح  ر  م
687 //     54 53 52 51 50 49 48 47 46 45 44 43 42 41 40
688
689 // LO   h  e  l  l  o  _  w  o  r  l  d   ,  _
690 //     55 56 57 58 59 60 61 62 63 64 65 66 67
691 // VO   _  ,  h  e  l  l  o  _  w  o  r  l  d
692 //     67 66 55 56 57 58 59 60 61 62 63 64 65
693
694 // LO   م  ر  ح  ب   ا  _  ب  ا  ل  ع   ا  ل  م  \n
695 //     68 69 70 71 72 73 74 75 76 77 78 79 80 81
696 // VO  \n  م  ل  ا   ع  ل  ا  ب  _  ا   ب  ح  ر  م
697 //     81 80 79 78 77 76 75 74 73 72 71 70 69 68
698
699 // LO   م  ر  ح  ب   ا  _  ب  ا  ل  ع   ا  ل  م  \n
700 //     82 83 84 85 86 87 88 89 90 91 92 93 94 95
701 // VO  \n  م  ل  ا  ع  ل   ا  ب  _  ا   ب  ح  ر  م
702 //     95 94 93 92 91 90 89 88 87 86 85 84 83 82
703
704
705 // LO   h   e   l   l   o   _   w   o   r   l   d
706 //     96  97  98  99 100 101 102 103 104 105 106
707 // VO   h   e   l   l   o   _   w   o   r   l   d
708 //     96  97  98  99 100 101 102 103 104 105 106
709
710   struct GetLogicalCharacterIndexData data[] =
711   {
712     {
713       "Zero characters text",
714       "",
715       Size( 300.f, 300.f ),
716       0u,
717       visualToLogical01,
718       cachedBidiLine01
719     },
720     {
721       "Left to right text only",
722       "Hello world",
723       Size( 300.f, 300.f ),
724       11u,
725       visualToLogical02,
726       cachedBidiLine02
727     },
728     {
729       "Right to left text only",
730       "مرحبا بالعالم",
731       Size( 300.f, 300.f ),
732       13u,
733       visualToLogical03,
734       cachedBidiLine03
735     },
736     {
737       "Mix of left to right and right to left text.",
738       "Hello world, مرحبا بالعالم, hello world\nمرحبا بالعالم, hello world, مرحبا بالعالم\nمرحبا بالعالم\nhello world",
739       Size( 300.f, 300.f ),
740       107u,
741       visualToLogical04,
742       cachedBidiLine04
743     },
744     {
745       "Mix of left to right and right to left text.",
746       "Hello world, مرحبا بالعالم, hello world\nمرحبا بالعالم, hello world, مرحبا بالعالم\nمرحبا بالعالم\nhello world",
747       Size( 200.f, 400.f ),
748       107u,
749       visualToLogical05,
750       cachedBidiLine05
751     },
752     {
753       "Mix of left to right and right to left text.",
754       "Hello world, مرحبا بالعالم, hello world\nمرحبا بالعالم, hello world, مرحبا بالعالم\nمرحبا بالعالم\nhello world",
755       Size( 100.f, 600.f ),
756       107u,
757       visualToLogical06,
758       cachedBidiLine06
759     },
760   };
761   const unsigned int numberOfTests = 6u;
762
763   for( unsigned int index = 0u; index < numberOfTests; ++index )
764   {
765     ToolkitTestApplication application;
766     if( !GetLogicalCharacterIndexTest( data[index] ) )
767     {
768       tet_result(TET_FAIL);
769     }
770   }
771
772   tet_result(TET_PASS);
773   END_TEST;
774 }
775
776 int UtcDaliGetLogicalCursorIndex(void)
777 {
778   tet_infoline(" UtcDaliGetLogicalCursorIndex");
779
780   const std::string fontFamily( "TizenSans" );
781   const std::string fontFamilyHebrew( "TizenSansHebrew" );
782
783
784
785   unsigned int visualIndex01[] = { 10u };
786   unsigned int characterIndex01[] = { 0u };
787   unsigned int logicalIndex01[] = { 10u };
788   unsigned int bidirectionalLineIndex01[] = { 0u };
789
790   //  0           11
791   //   Hello world  \n
792   // 12    16
793   //   demo
794
795   // Set a known font description
796   FontDescriptionRun fontDescriptionRun02;
797   fontDescriptionRun02.characterRun.characterIndex = 0u;
798   fontDescriptionRun02.characterRun.numberOfCharacters = 11u;
799   fontDescriptionRun02.familyLength = fontFamily.size();
800   fontDescriptionRun02.familyName = new char[fontDescriptionRun02.familyLength];
801   memcpy( fontDescriptionRun02.familyName, fontFamily.c_str(), fontDescriptionRun02.familyLength );
802   fontDescriptionRun02.familyDefined = true;
803   fontDescriptionRun02.weightDefined = false;
804   fontDescriptionRun02.widthDefined = false;
805   fontDescriptionRun02.slantDefined = false;
806   fontDescriptionRun02.sizeDefined = false;
807
808   Vector<FontDescriptionRun> fontDescriptionRuns02;
809   fontDescriptionRuns02.PushBack( fontDescriptionRun02 );
810
811   unsigned int visualIndex02[] = { 0u, 16u, 11u, 12u };
812   unsigned int characterIndex02[] = { 0u, 0u, 0u, 0u };
813   unsigned int logicalIndex02[] = { 0u, 16u, 11u, 12u };
814   unsigned int bidirectionalLineIndex02[] = { 0u, 0u, 0u, 0u };
815
816 // LO     H  e  l  l  o  _  w  o  r  l  d  \n
817 //       0  1  2  3  4  5  6  7  8  9 10 11  12
818 // VO     H  e  l  l  o  _  w  o  r  l  d  \n
819
820 // LO         ש  ל  ו  ם  _  ע  ו  ל  ם \n
821 //          12 13 14 15 16 17 18 19 20 21  22
822 // VO     \n  ם  ל  ו  ע _  ם  ו  ל  ש
823
824 // LO      h  e  l  l  o  _  w  o  r  l  d  _  ש  ל  ו  ם  _  ע ו  ל  ם  \n
825 //       22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43  44
826 // VO      h  e  l  l  o  _  w  o  r  l  d  _  ם  ל  ו  ע  _  ם  ו  ל  ש  \n
827
828 // LO      ש  ל  ו  ם  _  ע  ו  ל  ם  _  h  e  l  l  o  _  w  o  r   l  d \n
829 //       44 45 46 47 48 49 50 51  52 52 54 55 56 57 58 59 60 61 62 63  64 65 66
830 // VO      \n h  e  l  l  o  _  w   o  r  l  d  _  ם  ל  ו  ע  _  ם  ו  ל  ש
831
832
833   // Set a known font description
834   FontDescriptionRun fontDescriptionRun0301;
835   fontDescriptionRun0301.characterRun.characterIndex = 0u;
836   fontDescriptionRun0301.characterRun.numberOfCharacters = 12u;
837   fontDescriptionRun0301.familyLength = fontFamily.size();
838   fontDescriptionRun0301.familyName = new char[fontDescriptionRun0301.familyLength];
839   memcpy( fontDescriptionRun0301.familyName, fontFamily.c_str(), fontDescriptionRun0301.familyLength );
840   fontDescriptionRun0301.familyDefined = true;
841   fontDescriptionRun0301.weightDefined = false;
842   fontDescriptionRun0301.widthDefined = false;
843   fontDescriptionRun0301.slantDefined = false;
844   fontDescriptionRun0301.sizeDefined = false;
845
846   // Set a known font description
847   FontDescriptionRun fontDescriptionRun0302;
848   fontDescriptionRun0302.characterRun.characterIndex = 12u;
849   fontDescriptionRun0302.characterRun.numberOfCharacters = 10u;
850   fontDescriptionRun0302.familyLength = fontFamilyHebrew.size();
851   fontDescriptionRun0302.familyName = new char[fontDescriptionRun0302.familyLength];
852   memcpy( fontDescriptionRun0302.familyName, fontFamilyHebrew.c_str(), fontDescriptionRun0302.familyLength );
853   fontDescriptionRun0302.familyDefined = true;
854   fontDescriptionRun0302.weightDefined = false;
855   fontDescriptionRun0302.widthDefined = false;
856   fontDescriptionRun0302.slantDefined = false;
857   fontDescriptionRun0302.sizeDefined = false;
858
859   // Set a known font description
860   FontDescriptionRun fontDescriptionRun0303;
861   fontDescriptionRun0303.characterRun.characterIndex = 22u;
862   fontDescriptionRun0303.characterRun.numberOfCharacters = 12u;
863   fontDescriptionRun0303.familyLength = fontFamily.size();
864   fontDescriptionRun0303.familyName = new char[fontDescriptionRun0303.familyLength];
865   memcpy( fontDescriptionRun0303.familyName, fontFamily.c_str(), fontDescriptionRun0303.familyLength );
866   fontDescriptionRun0303.familyDefined = true;
867   fontDescriptionRun0303.weightDefined = false;
868   fontDescriptionRun0303.widthDefined = false;
869   fontDescriptionRun0303.slantDefined = false;
870   fontDescriptionRun0303.sizeDefined = false;
871
872   // Set a known font description
873   FontDescriptionRun fontDescriptionRun0304;
874   fontDescriptionRun0304.characterRun.characterIndex = 34u;
875   fontDescriptionRun0304.characterRun.numberOfCharacters = 20u;
876   fontDescriptionRun0304.familyLength = fontFamilyHebrew.size();
877   fontDescriptionRun0304.familyName = new char[fontDescriptionRun0304.familyLength];
878   memcpy( fontDescriptionRun0304.familyName, fontFamilyHebrew.c_str(), fontDescriptionRun0304.familyLength );
879   fontDescriptionRun0304.familyDefined = true;
880   fontDescriptionRun0304.weightDefined = false;
881   fontDescriptionRun0304.widthDefined = false;
882   fontDescriptionRun0304.slantDefined = false;
883   fontDescriptionRun0304.sizeDefined = false;
884
885   // Set a known font description
886   FontDescriptionRun fontDescriptionRun0305;
887   fontDescriptionRun0305.characterRun.characterIndex = 54u;
888   fontDescriptionRun0305.characterRun.numberOfCharacters = 12u;
889   fontDescriptionRun0305.familyLength = fontFamily.size();
890   fontDescriptionRun0305.familyName = new char[fontDescriptionRun0305.familyLength];
891   memcpy( fontDescriptionRun0305.familyName, fontFamily.c_str(), fontDescriptionRun0305.familyLength );
892   fontDescriptionRun0305.familyDefined = true;
893   fontDescriptionRun0305.weightDefined = false;
894   fontDescriptionRun0305.widthDefined = false;
895   fontDescriptionRun0305.slantDefined = false;
896   fontDescriptionRun0305.sizeDefined = false;
897
898   Vector<FontDescriptionRun> fontDescriptionRuns03;
899   fontDescriptionRuns03.PushBack( fontDescriptionRun0301 );
900   fontDescriptionRuns03.PushBack( fontDescriptionRun0302 );
901   fontDescriptionRuns03.PushBack( fontDescriptionRun0303 );
902   fontDescriptionRuns03.PushBack( fontDescriptionRun0304 );
903   fontDescriptionRuns03.PushBack( fontDescriptionRun0305 );
904
905   unsigned int visualIndex03[] = {  0u,  1u,  2u,  3u,  4u,  5u,  6u,  7u,  8u,  9u, 10u, 11u,
906                                    13u, 14u, 15u, 16u, 17u, 18u, 19u, 20u, 21u, 22u,
907                                    22u, 23u, 24u, 25u, 26u, 27u, 28u, 29u, 30u, 31u, 32u, 33u, 34u, 35u, 36u, 37u, 38u, 39u, 40u, 41u, 42u, 43u,
908                                    45u, 46u, 47u, 48u, 49u, 50u, 51u, 52u, 53u, 54u, 55u, 56u, 57u, 58u, 59u, 60u, 61u, 62u, 63u, 64u, 65u, 66u };
909
910   unsigned int characterIndex03[] = {  0u,  0u,  0u,  0u,  0u,  0u,  0u,  0u,  0u,  0u,  0u,  0u,
911                                       12u, 12u, 12u, 12u, 12u, 12u, 12u, 12u, 12u, 12u,
912                                       22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u,
913                                       44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u};
914
915   unsigned int logicalIndex03[] = {  0u,  1u,  2u,  3u,  4u,  5u,  6u,  7u,  8u,  9u, 10u, 11u,
916                                     21u, 20u, 19u, 18u, 17u, 16u, 15u, 14u, 13u, 12u,
917                                     22u, 23u, 24u, 25u, 26u, 27u, 28u, 29u, 30u, 31u, 32u, 33u, 34u, 42u, 41u, 40u, 39u, 38u, 37u, 36u, 35u, 43u,
918                                     65u, 55u, 56u, 57u, 58u, 59u, 60u, 61u, 62u, 63u, 64u, 54u, 53u, 52u, 51u, 50u, 49u, 48u, 47u, 46u, 45u, 44u };
919
920   unsigned int bidirectionalLineIndex03[] = { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
921                                               0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
922                                               1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u,
923                                               2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u };
924
925
926 // LO     ש  ל  ו  ם  _  ע  ו  ל  ם \n
927 //       0  1  2  3  4  5  6  7  8  9 10
928 // VO  \n ם  ל  ו  ע  _  ם  ו  ל  ש
929
930 //      h  e  l  l  o  _  w  o  r  l  d  \n
931 // LO 10 11 12 13 14 15 16 17 18 19 20 21 22
932 //      h  e  l  l  o  _  w  o  r  l  d  \n
933
934 //         ש  ל  ו  ם  _  ע  ו  ל  ם _  h  e  l  l  o  _  w  o  r  l  d  \n
935 // LO    22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
936 //     \n  h  e  l  l  o  _  w  o  r  l  d  _  ם  ל  ו  ע  _  ם  ו  ל  ש
937
938 //      h  e  l  l  o  _  w  o  r  l  d  _  ש  ל  ו  ם  _  ע  ו  ל  ם \n
939 // LO 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
940 //      h  e  l  l  o  _  w  o  r  l  d  _  ם  ל  ו  ע  _  ם  ו  ל  ש \n
941
942   // Set a known font description
943   FontDescriptionRun fontDescriptionRun0401;
944   fontDescriptionRun0401.characterRun.characterIndex = 0u;
945   fontDescriptionRun0401.characterRun.numberOfCharacters = 10u;
946   fontDescriptionRun0401.familyLength = fontFamilyHebrew.size();
947   fontDescriptionRun0401.familyName = new char[fontDescriptionRun0401.familyLength];
948   memcpy( fontDescriptionRun0401.familyName, fontFamilyHebrew.c_str(), fontDescriptionRun0401.familyLength );
949   fontDescriptionRun0401.familyDefined = true;
950   fontDescriptionRun0401.weightDefined = false;
951   fontDescriptionRun0401.widthDefined = false;
952   fontDescriptionRun0401.slantDefined = false;
953   fontDescriptionRun0401.sizeDefined = false;
954
955   FontDescriptionRun fontDescriptionRun0402;
956   fontDescriptionRun0402.characterRun.characterIndex = 10u;
957   fontDescriptionRun0402.characterRun.numberOfCharacters = 12u;
958   fontDescriptionRun0402.familyLength = fontFamily.size();
959   fontDescriptionRun0402.familyName = new char[fontDescriptionRun0402.familyLength];
960   memcpy( fontDescriptionRun0402.familyName, fontFamily.c_str(), fontDescriptionRun0402.familyLength );
961   fontDescriptionRun0402.familyDefined = true;
962   fontDescriptionRun0402.weightDefined = false;
963   fontDescriptionRun0402.widthDefined = false;
964   fontDescriptionRun0402.slantDefined = false;
965   fontDescriptionRun0402.sizeDefined = false;
966
967   FontDescriptionRun fontDescriptionRun0403;
968   fontDescriptionRun0403.characterRun.characterIndex = 22u;
969   fontDescriptionRun0403.characterRun.numberOfCharacters = 10u;
970   fontDescriptionRun0403.familyLength = fontFamilyHebrew.size();
971   fontDescriptionRun0403.familyName = new char[fontDescriptionRun0403.familyLength];
972   memcpy( fontDescriptionRun0403.familyName, fontFamilyHebrew.c_str(), fontDescriptionRun0403.familyLength );
973   fontDescriptionRun0403.familyDefined = true;
974   fontDescriptionRun0403.weightDefined = false;
975   fontDescriptionRun0403.widthDefined = false;
976   fontDescriptionRun0403.slantDefined = false;
977   fontDescriptionRun0403.sizeDefined = false;
978
979   FontDescriptionRun fontDescriptionRun0404;
980   fontDescriptionRun0404.characterRun.characterIndex = 32u;
981   fontDescriptionRun0404.characterRun.numberOfCharacters = 24u;
982   fontDescriptionRun0404.familyLength = fontFamily.size();
983   fontDescriptionRun0404.familyName = new char[fontDescriptionRun0404.familyLength];
984   memcpy( fontDescriptionRun0404.familyName, fontFamily.c_str(), fontDescriptionRun0404.familyLength );
985   fontDescriptionRun0404.familyDefined = true;
986   fontDescriptionRun0404.weightDefined = false;
987   fontDescriptionRun0404.widthDefined = false;
988   fontDescriptionRun0404.slantDefined = false;
989   fontDescriptionRun0404.sizeDefined = false;
990
991   FontDescriptionRun fontDescriptionRun0405;
992   fontDescriptionRun0405.characterRun.characterIndex = 56u;
993   fontDescriptionRun0405.characterRun.numberOfCharacters = 10u;
994   fontDescriptionRun0405.familyLength = fontFamilyHebrew.size();
995   fontDescriptionRun0405.familyName = new char[fontDescriptionRun0405.familyLength];
996   memcpy( fontDescriptionRun0405.familyName, fontFamilyHebrew.c_str(), fontDescriptionRun0405.familyLength );
997   fontDescriptionRun0405.familyDefined = true;
998   fontDescriptionRun0405.weightDefined = false;
999   fontDescriptionRun0405.widthDefined = false;
1000   fontDescriptionRun0405.slantDefined = false;
1001   fontDescriptionRun0405.sizeDefined = false;
1002
1003   Vector<FontDescriptionRun> fontDescriptionRuns04;
1004   fontDescriptionRuns04.PushBack( fontDescriptionRun0401 );
1005   fontDescriptionRuns04.PushBack( fontDescriptionRun0402 );
1006   fontDescriptionRuns04.PushBack( fontDescriptionRun0403 );
1007   fontDescriptionRuns04.PushBack( fontDescriptionRun0404 );
1008   fontDescriptionRuns04.PushBack( fontDescriptionRun0405 );
1009
1010   unsigned int  visualIndex04[] = {  1u,  2u,  3u,  4u,  5u,  6u,  7u,  8u,  9u, 10u,
1011                                     10u, 12u, 13u, 14u, 15u, 16u, 17u, 18u, 19u, 20u, 21u,
1012                                     23u, 24u, 25u, 26u, 27u, 28u, 29u, 30u, 31u, 32u, 33u, 34u, 35u, 36u, 37u, 38u, 39u, 40u, 41u, 42u, 43u, 44u,
1013                                     44u, 45u, 46u, 47u, 48u, 49u, 50u, 51u, 52u, 53u, 54u, 55u, 56u, 57u, 58u, 59u, 60u, 61u, 62u, 63u, 64u, 65u };
1014
1015   unsigned int characterIndex04[] = {  0u,  0u,  0u,  0u,  0u,  0u,  0u,  0u,  0u,  0u,
1016                                       10u, 10u, 10u, 10u, 10u, 10u, 10u, 10u, 10u, 10u, 10u,
1017                                       22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u,
1018                                       44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u };
1019
1020   unsigned int logicalIndex04[] = {  9u,  8u,  7u,  6u,  5u,  4u,  3u,  2u,  1u,  0u,
1021                                     10u, 12u, 13u, 14u, 15u, 16u, 17u, 18u, 19u, 20u, 21u,
1022                                     43u, 33u, 34u, 35u, 36u, 37u, 38u, 39u, 40u, 41u, 42u, 32u, 31u, 30u, 29u, 28u, 27u, 26u, 25u, 24u, 23u, 22u,
1023                                     44u, 45u, 46u, 47u, 48u, 49u, 50u, 51u, 52u, 53u, 54u, 55u, 56u, 64u, 63u, 62u, 61u, 60u, 59u, 58u, 57u, 65u };
1024
1025   unsigned int bidirectionalLineIndex04[] = { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
1026                                               0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
1027                                               1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u,
1028                                               2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u };
1029
1030 // LO   A  B  C  D  E  F  G  H  I  J  K
1031 //     0  1  2  3  4  5  6  7  8  9 10 11
1032 // LO   L  M  N
1033 //    11 12 13 14
1034
1035   // Set a known font description
1036   FontDescriptionRun fontDescriptionRun0501;
1037   fontDescriptionRun0501.characterRun.characterIndex = 0u;
1038   fontDescriptionRun0501.characterRun.numberOfCharacters = 14u;
1039   fontDescriptionRun0501.familyLength = fontFamily.size();
1040   fontDescriptionRun0501.familyName = new char[fontDescriptionRun0501.familyLength];
1041   memcpy( fontDescriptionRun0501.familyName, fontFamily.c_str(), fontDescriptionRun0501.familyLength );
1042   fontDescriptionRun0501.familyDefined = true;
1043   fontDescriptionRun0501.weightDefined = false;
1044   fontDescriptionRun0501.widthDefined = false;
1045   fontDescriptionRun0501.slantDefined = false;
1046   fontDescriptionRun0501.sizeDefined = false;
1047
1048   Vector<FontDescriptionRun> fontDescriptionRuns05;
1049   fontDescriptionRuns05.PushBack( fontDescriptionRun0501 );
1050
1051   unsigned int  visualIndex05[] = {  0u,  1u,  2u,  3u,  4u,  5u,  6u,  7u,  8u,  9u, 10u,
1052                                     11u, 12u, 13u, 14u };
1053
1054   unsigned int characterIndex05[] = { 0u,  0u,  0u,  0u,  0u,  0u,  0u,  0u,  0u,  0u,  0u,
1055                                       11u, 11u, 11u, 11u };
1056
1057   unsigned int logicalIndex05[] = { 0u,  1u,  2u,  3u,  4u,  5u,  6u,  7u,  8u,  9u, 10u,
1058                                     11u, 12u, 13u, 14u };
1059
1060   unsigned int bidirectionalLineIndex05[] = { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
1061                                               0u, 0u, 0u, 0u };
1062
1063 // LO      ק  ר  א  ט  ו  ן  ם  פ  ש  ד  ג  כ
1064 //        0  1  2  3  4  5  6  7  8  9  10 11 12
1065 // VO      כ  ג  ד  ש  פ  ם  ן  ו  ט  א  ר  ק
1066
1067 // LO      ע  י  ח  ל
1068 //       12 13 14 15 16
1069 // VO      ל  ח  י  ע
1070
1071
1072   // Set a known font description
1073   FontDescriptionRun fontDescriptionRun0601;
1074   fontDescriptionRun0601.characterRun.characterIndex = 0u;
1075   fontDescriptionRun0601.characterRun.numberOfCharacters = 16u;
1076   fontDescriptionRun0601.familyLength = fontFamilyHebrew.size();
1077   fontDescriptionRun0601.familyName = new char[fontDescriptionRun0601.familyLength];
1078   memcpy( fontDescriptionRun0601.familyName, fontFamilyHebrew.c_str(), fontDescriptionRun0601.familyLength );
1079   fontDescriptionRun0601.familyDefined = true;
1080   fontDescriptionRun0601.weightDefined = false;
1081   fontDescriptionRun0601.widthDefined = false;
1082   fontDescriptionRun0601.slantDefined = false;
1083   fontDescriptionRun0601.sizeDefined = false;
1084
1085   Vector<FontDescriptionRun> fontDescriptionRuns06;
1086   fontDescriptionRuns06.PushBack( fontDescriptionRun0601 );
1087
1088   unsigned int  visualIndex06[] = {  0u,  1u,  2u,  3u,  4u,  5u,  6u,  7u,  8u,  9u, 10u, 11u, 12u,
1089                                     12u, 13u, 14u, 15u, 16u };
1090
1091   unsigned int characterIndex06[] = {  0u,  0u,  0u,  0u,  0u,  0u,  0u,  0u,  0u,  0u,  0u,  0u,  0u,
1092                                       12u, 12u, 12u, 12u, 12u };
1093
1094   unsigned int logicalIndex06[] = { 12u, 11u, 10u,  9u,  8u,  7u,  6u,  5u,  4u,  3u,  2u,  1u, 0u,
1095                                     16u, 15u, 14u, 13u, 12u };
1096
1097   unsigned int bidirectionalLineIndex06[] = { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
1098                                               1u, 1u, 1u, 1u, 1u, };
1099
1100   struct GetLogicalCursorIndexData data[] =
1101   {
1102     {
1103       "Zero characters text",
1104       "",
1105       Size( 300.f, 300.f ),
1106       0u,
1107       nullptr,
1108       1u,
1109       visualIndex01,
1110       characterIndex01,
1111       logicalIndex01,
1112       bidirectionalLineIndex01,
1113     },
1114     {
1115       "All left to right text 01.",
1116       "Hello world\ndemo",
1117       Size( 300.f, 300.f ),
1118       1u,
1119       fontDescriptionRuns02.Begin(),
1120       4u,
1121       visualIndex02,
1122       characterIndex02,
1123       logicalIndex02,
1124       bidirectionalLineIndex02,
1125     },
1126     {
1127       "bidirectional text 01.",
1128       "Hello world\nשלום עולם\nhello world שלום עולם\nשלום עולם hello world\n",
1129       Size( 300.f, 300.f ),
1130       5u,
1131       fontDescriptionRuns03.Begin(),
1132       65u,
1133       visualIndex03,
1134       characterIndex03,
1135       logicalIndex03,
1136       bidirectionalLineIndex03,
1137     },
1138     {
1139       "bidirectional text 02.",
1140       "שלום עולם\nhello world\nשלום עולם hello world\nhello world שלום עולם\n",
1141       Size( 300.f, 300.f ),
1142       5u,
1143       fontDescriptionRuns04.Begin(),
1144       65u,
1145       visualIndex04,
1146       characterIndex04,
1147       logicalIndex04,
1148       bidirectionalLineIndex04,
1149     },
1150     {
1151       "long line 01.",
1152       "ABCDEFGHIJKLMN",
1153       Size( 100.f, 300.f ),
1154       1u,
1155       fontDescriptionRuns05.Begin(),
1156       13u,
1157       visualIndex05,
1158       characterIndex05,
1159       logicalIndex05,
1160       bidirectionalLineIndex05,
1161     },
1162     {
1163       "bidirectional text 03.",
1164       "קראטוןםפשדגכעיחל",
1165       Size( 100.f, 300.f ),
1166       1u,
1167       fontDescriptionRuns06.Begin(),
1168       18u,
1169       visualIndex06,
1170       characterIndex06,
1171       logicalIndex06,
1172       bidirectionalLineIndex06,
1173     },
1174   };
1175   const unsigned int numberOfTests = 6u;
1176
1177   for( unsigned int index = 0u; index < numberOfTests; ++index )
1178   {
1179     ToolkitTestApplication application;
1180     if( !GetLogicalCursorIndexTest( data[index] ) )
1181     {
1182       tet_printf("Test %d failed : [%s]\n", index, data[index].description.c_str());
1183       tet_result(TET_FAIL);
1184     }
1185   }
1186
1187   tet_result(TET_PASS);
1188   END_TEST;
1189 }