Add bidirectional text tct.
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-toolkit-internal / utc-Dali-Text-Cursor.cpp
1 /*
2  * Copyright (c) 2017 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/cursor-helper-functions.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 // LineIndex GetClosestLine( VisualModelPtr visualModel,
35 //                           float visualY,
36 //                           bool& isLineHit )
37 // CharacterIndex GetClosestCursorIndex( VisualModelPtr visualModel,
38 //                                       LogicalModelPtr logicalModel,
39 //                                       MetricsPtr metrics,
40 //                                       float visualX,
41 //                                       float visualY,
42 //                                       CharacterHitTest::Mode mode,
43 //                                       bool& isCharacterHit )
44
45 //////////////////////////////////////////////////////////
46
47 namespace
48 {
49
50 struct GetClosestLineData
51 {
52   std::string    description;                    ///< Description of the test.
53   std::string    text;                           ///< Input text.
54   unsigned int   numberOfTests;                  ///< The number of tests.
55   float*         visualY;                        ///< The visual 'y' position for each test.
56   LineIndex*     lineIndex;                      ///< The expected line index for each test.
57   bool*          isLineHit;                      ///< The expected line hit value for each test.
58 };
59
60 struct GetClosestCursorIndexData
61 {
62   std::string             description;           ///< Description of the test.
63   std::string             text;                  ///< Input text.
64   unsigned int            numberOfTests;         ///< The number of tests.
65   float*                  visualX;               ///< The visual 'x' position for each test.
66   float*                  visualY;               ///< The visual 'y' position for each test.
67   CharacterHitTest::Mode* mode;                  ///< The type of hit test.
68   CharacterIndex*         logicalIndex;          ///< The expected logical cursor index for each test.
69   bool*                   isCharacterHit;        ///< The expected character hit value for each test.
70 };
71
72 struct GetCursorPositionData
73 {
74   std::string     description;                    ///< Description of the test.
75   std::string     text;                           ///< Input text.
76   unsigned int    numberOfTests;                  ///< The number of tests.
77   CharacterIndex* logicalIndex;                   ///< The logical cursor index for each test.
78   float*          visualX;                        ///< The expected visual 'x' position for each test.
79   float*          visualY;                        ///< The expected visual 'y' position for each test.
80 };
81
82 struct FindSelectionIndicesData
83 {
84   std::string     description;                    ///< Description of the test.
85   std::string     text;                           ///< Input text.
86   unsigned int    numberOfTests;                  ///< The number of tests.
87   float*          visualX;                        ///< The visual 'x' position for each test.
88   float*          visualY;                        ///< The visual 'y' position for each test.
89   bool*           found;                          ///< Whether selection indices are found.
90   CharacterIndex* startIndex;                     ///< The expected start cursor index for each test.
91   CharacterIndex* endIndex;                       ///< The expected end cursor index for each test.
92   CharacterIndex* noTextHitIndex;                 ///< The expected character index when there is no hit.
93 };
94
95 bool GetClosestLineTest( const GetClosestLineData& data )
96 {
97   std::cout << "  testing : " << data.description << std::endl;
98
99   // 1) Create the model.
100   LogicalModelPtr logicalModel;
101   VisualModelPtr visualModel;
102   MetricsPtr metrics;
103   Size textArea(400.f, 600.f);
104   Size layoutSize;
105
106   Vector<FontDescriptionRun> fontDescriptionRuns;
107   LayoutOptions options;
108   CreateTextModel( data.text,
109                    textArea,
110                    fontDescriptionRuns,
111                    options,
112                    layoutSize,
113                    logicalModel,
114                    visualModel,
115                    metrics,
116                    false );
117
118   for( unsigned int index = 0; index < data.numberOfTests; ++index )
119   {
120     bool isLineHit = false;
121     const LineIndex lineIndex = GetClosestLine( visualModel,
122                                                 data.visualY[index],
123                                                 isLineHit );
124
125     if( lineIndex != data.lineIndex[index] )
126     {
127       std::cout << "  test " << index << " failed. Different line index : " << lineIndex << ", expected : " << data.lineIndex[index] << std::endl;
128       return false;
129     }
130     if( isLineHit != data.isLineHit[index] )
131     {
132       std::cout << "  test " << index << " failed. Different line hit value : " << isLineHit << ", expected : " << data.isLineHit[index] << std::endl;
133       return false;
134     }
135   }
136
137   return true;
138 }
139
140 bool GetClosestCursorIndexTest( const GetClosestCursorIndexData& data )
141 {
142   std::cout << "  testing : " << data.description << std::endl;
143
144   // 1) Create the model.
145   LogicalModelPtr logicalModel;
146   VisualModelPtr visualModel;
147   MetricsPtr metrics;
148   Size textArea(400.f, 600.f);
149   Size layoutSize;
150
151   Vector<FontDescriptionRun> fontDescriptionRuns;
152   LayoutOptions options;
153   CreateTextModel( data.text,
154                    textArea,
155                    fontDescriptionRuns,
156                    options,
157                    layoutSize,
158                    logicalModel,
159                    visualModel,
160                    metrics,
161                    false );
162
163   for( unsigned int index = 0; index < data.numberOfTests; ++index )
164   {
165     bool isCharacterHit = false;
166     const CharacterIndex logicalCursorIndex = GetClosestCursorIndex( visualModel,
167                                                                      logicalModel,
168                                                                      metrics,
169                                                                      data.visualX[index],
170                                                                      data.visualY[index],
171                                                                      data.mode[index],
172                                                                      isCharacterHit );
173
174     if( logicalCursorIndex != data.logicalIndex[index] )
175     {
176       std::cout << "  test " << index << " failed. Different logical cursor index : " << logicalCursorIndex << ", expected : " << data.logicalIndex[index] << std::endl;
177       return false;
178     }
179     if( isCharacterHit != data.isCharacterHit[index] )
180     {
181       std::cout << "  test " << index << " failed. Different character hit value : " << isCharacterHit << ", expected : " << data.isCharacterHit[index] << std::endl;
182       return false;
183     }
184   }
185
186   return true;
187 }
188
189 bool GetCursorPositionTest( const GetCursorPositionData& data )
190 {
191   std::cout << "  testing : " << data.description << std::endl;
192
193   // 1) Create the model.
194   LogicalModelPtr logicalModel;
195   VisualModelPtr visualModel;
196   MetricsPtr metrics;
197   Size textArea(400.f, 600.f);
198   Size layoutSize;
199
200   Vector<FontDescriptionRun> fontDescriptionRuns;
201   LayoutOptions options;
202   CreateTextModel( data.text,
203                    textArea,
204                    fontDescriptionRuns,
205                    options,
206                    layoutSize,
207                    logicalModel,
208                    visualModel,
209                    metrics,
210                    false );
211
212   GetCursorPositionParameters parameters;
213   parameters.visualModel = visualModel;
214   parameters.logicalModel = logicalModel;
215   parameters.metrics = metrics;
216   parameters.isMultiline = true;
217
218   for( unsigned int index = 0; index < data.numberOfTests; ++index )
219   {
220     CursorInfo cursorInfo;
221     parameters.logical = data.logicalIndex[index];
222
223     GetCursorPosition( parameters,
224                        cursorInfo );
225
226     if( cursorInfo.primaryPosition.x != data.visualX[index] )
227     {
228       std::cout << "  test " << index << " failed. Different 'x' cursor position : " << cursorInfo.primaryPosition.x << ", expected : " << data.visualX[index] << std::endl;
229       return false;
230     }
231     if( cursorInfo.primaryPosition.y != data.visualY[index] )
232     {
233       std::cout << "  test " << index << " failed. Different 'y' cursor position : " << cursorInfo.primaryPosition.y << ", expected : " << data.visualY[index] << std::endl;
234        return false;
235     }
236   }
237
238   return true;
239 }
240
241 bool FindSelectionIndicesTest( const FindSelectionIndicesData& data )
242 {
243   std::cout << "  testing : " << data.description << std::endl;
244
245   // 1) Create the model.
246   LogicalModelPtr logicalModel;
247   VisualModelPtr visualModel;
248   MetricsPtr metrics;
249   Size textArea(400.f, 600.f);
250   Size layoutSize;
251
252   Vector<FontDescriptionRun> fontDescriptionRuns;
253   LayoutOptions options;
254   CreateTextModel( data.text,
255                    textArea,
256                    fontDescriptionRuns,
257                    options,
258                    layoutSize,
259                    logicalModel,
260                    visualModel,
261                    metrics,
262                    false );
263
264   for( unsigned int index = 0; index < data.numberOfTests; ++index )
265   {
266     CharacterIndex startIndex = 0;
267     CharacterIndex endIndex = 0;
268     CharacterIndex noTextHitIndex = 0;
269     const bool found = FindSelectionIndices( visualModel,
270                                              logicalModel,
271                                              metrics,
272                                              data.visualX[index],
273                                              data.visualY[index],
274                                              startIndex,
275                                              endIndex,
276                                              noTextHitIndex );
277
278     if( found != data.found[index] )
279     {
280       std::cout << "  test " << index << " failed. Different found value : " << found << ", expected : " <<  data.found[index] << std::endl;
281       return false;
282     }
283     if( startIndex != data.startIndex[index] )
284     {
285       std::cout << "  test " << index << " failed. Different start index : " << startIndex << ", expected : " << data.startIndex[index] << std::endl;
286       return false;
287     }
288     if( endIndex != data.endIndex[index] )
289     {
290       std::cout << "  test " << index << " failed. Different end index : " << endIndex << ", expected : " << data.endIndex[index] << std::endl;
291       return false;
292     }
293     if( noTextHitIndex != data.noTextHitIndex[index] )
294     {
295       std::cout << "  test " << index << " failed. Different no text hit index : " << noTextHitIndex << ", expected : " << data.noTextHitIndex[index] << std::endl;
296       return false;
297     }
298   }
299   return true;
300 }
301
302 } // namespace
303
304 //////////////////////////////////////////////////////////
305 //
306 // UtcDaliGetClosestLine
307 // UtcDaliGetClosestCursorIndex
308 //
309 //////////////////////////////////////////////////////////
310
311 int UtcDaliGetClosestLine(void)
312 {
313   tet_infoline(" UtcDaliGetClosestLine");
314
315   float visualY01[] = { -4.f, 3.f, 1000.f };
316   LineIndex lineIndices01[] = { 0, 0, 0 };
317   bool isLineHit01[] = { false, false, false };
318
319   float visualY02[] = { -4.f, 3.f, 1000.f };
320   LineIndex lineIndices02[] = { 0, 0, 0 };
321   bool isLineHit02[] = { false, true, false };
322
323   float visualY03[] = { -4.f, 11.f, 30.f, 51.f, 68.f, 87.f, 109.f, 130.f };
324   LineIndex lineIndices03[] = { 0, 0, 1u, 2u, 3u, 4u, 5u, 5u };
325   bool isLineHit03[] = { false, true, true, true, true, true, true, false };
326
327   struct GetClosestLineData data[] =
328   {
329     {
330       "void text.",
331       "",
332       3u,
333       visualY01,
334       lineIndices01,
335       isLineHit01
336     },
337     {
338       "Single line text.",
339       "hello world",
340       3u,
341       visualY02,
342       lineIndices02,
343       isLineHit02
344     },
345     {
346       "Multi-line text.",
347       "abcשנבdefגקכghiעיןjklחלךmnoצמםpqrפרףstuדאוvwxה"
348       "סתyzטזץabcשנבdefגקכghiעיןjklחלךmnoצמםpqrפרףstuד"
349       "אוvwxהסתyzטזץabcשנבdefגקכghiעיןjklחלךmnoצמםpqr"
350       "פרףstuדאוvwxהסתyzטזץabcשנבdefגקכghiעיןjklחלךmno"
351       "צמםpqrפרףstuדאוvwxהסתyzטזץabcשנבdefגקכghiעיןjkl"
352       "חלךmnoצמםpqrפרףstuדאוvwxהסתyzטזץ",
353       8u,
354       visualY03,
355       lineIndices03,
356       isLineHit03
357     }
358   };
359   const unsigned int numberOfTests = 3u;
360
361   for( unsigned int index = 0; index < numberOfTests; ++index )
362   {
363     ToolkitTestApplication application;
364     if( !GetClosestLineTest( data[index] ) )
365     {
366       tet_result(TET_FAIL);
367     }
368   }
369
370   tet_result(TET_PASS);
371   END_TEST;
372 }
373
374 int UtcDaliGetClosestCursorIndex(void)
375 {
376   tet_infoline(" UtcDaliGetClosestCursorIndex");
377
378   float visualX01[] = { -100.f };
379   float visualY01[] = { -100.f };
380   CharacterHitTest::Mode mode01[] = { CharacterHitTest::TAP };
381   CharacterIndex logicalIndex01[] = { 0 };
382   bool isCharacterHit01[] = { false };
383
384   float visualX02[] = { -100.f, 1000.f, 60.f, 79.f, 83.f, 148.f, 99.f };
385   float visualY02[] = { -100.f, 1000.f, 12.f, 12.f, 12.f, 12.f, 12.f };
386   CharacterHitTest::Mode mode02[] = { CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP };
387   CharacterIndex logicalIndex02[] = { 0, 21u, 7u, 10u, 11u, 13u, 20u };
388   bool isCharacterHit02[] = { false, false, true, true, true, true, true  };
389
390   float visualX03[] = { 19.f, 104.f, -2.f, 127.f };
391   float visualY03[] = { 12.f, 12.f, 12.f, 12.f };
392   CharacterHitTest::Mode mode03[] = { CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP };
393   CharacterIndex logicalIndex03[] = { 3u, 12u, 0, 18u };
394   bool isCharacterHit03[] = { true, true, false, false };
395
396   //  0     5 _ 6     11  12
397   //   Hello     world  \n
398   // 12    16 _ 17    21   22
399   //   שלום       עולם  \n
400   // 22         31_32      40  41
401   //   different     الأربعاء  \n
402   float visualX04[] = { -100.f, 40.f, 44.f, 85.f, 500.f,
403                          500.f, 367.f, 359.f, 329.f, -100.f,
404                         -100.f, 19.f, 64.f, 72.f, 104.f, 111.f, 500.f};
405   float visualY04[] = { -100.f, 12.f, 12.f, 12.f, 12.f,
406                           30.f, 30.f, 30.f, 30.f, 30.f,
407                           50.f, 50.f, 50.f, 50.f, 50.f, 50.f, 50.f };
408   CharacterHitTest::Mode mode04[] = { CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP,
409                                       CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP,
410                                       CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP };
411   CharacterIndex logicalIndex04[] = {    0,  5u,  6u, 11u, 11u,
412                                        12u, 16u, 17u, 21u, 21u,
413                                        22u, 25u, 31u, 32u, 34u, 40u, 40u,
414                                        41u };
415   bool isCharacterHit04[] = { false, true, true, false, false,
416                               false, true, true, true, false,
417                               false, true, true, true, true, true, false };
418
419   //   0           10           20            30           40      46
420   //    abcשנבdefג   קכghiעיןjk   lחלךmnoצמם   pqrפרףstuד   אוvwxה
421   //  46     50            60            70           80               93
422   //    סתyz   טזץabcשנבd    efגקכghiעי    ןjklחלךmno   צמםpqrפרףstuד
423   //  93       100           110          120         130          139
424   //    אוvwxהס   תyzטזץabcש   נבdefגקכgh   iעיןjklחלך   mnoצמםpqr
425   // 139           150           160           170          180       186
426   //    פרףstuדאוvw   xהסתyzטזץa   bcשנבdefגק    כghiעיןjkl    חלךmno
427   // 186     190           200           210          220            233
428   //    צמםp   qrפרףstuדא    וvwxהסתyzט   זץabcשנבde   fגקכghiעיןjkl
429   // 233        240            250           260     265
430   //    חלךmnoצ    מםpqrפרףst   uדאוvwxהסת    yzטזץ
431
432   float visualX05[] = { -100.f, 96.f, 155.f, 250.f, 344.f, 500.f,
433                         -100.f, 36.f, 124.f, 190.f, 280.f, 500.f,
434                         -100.f, 56.f, 158.f, 237.f, 303.f, 500.f,
435                         -100.f, 98.f, 184.f, 261.f, 337.f, 500.f,
436                         -100.f, 40.f, 113.f, 223.f, 302.f, 500.f,
437                         -100.f, 82.f, 160.f, 253.f, 500.f };
438   float visualY05[] = { -100.f, 12.f, 12.f, 12.f, 12.f, 12.f,
439                         30.f, 30.f, 30.f, 30.f, 30.f, 30.f,
440                         50.f, 50.f, 50.f, 50.f, 50.f, 50.f,
441                         67.f, 67.f, 67.f, 67.f, 67.f, 67.f,
442                         87.f, 87.f, 87.f, 87.f, 87.f, 87.f,
443                         107.f, 107.f, 107.f, 107.f, 107.f };
444   CharacterHitTest::Mode mode05[] = { CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP,
445                                       CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP,
446                                       CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP,
447                                       CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP,
448                                       CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP,
449                                       CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP };
450   CharacterIndex logicalIndex05[] = {    0,  10u,  20u,  30u,  40u,  45u,
451                                        46u,  50u,  60u,  70u,  80u,  92u,
452                                        93u, 100u, 110u, 120u, 130u, 138u,
453                                       139u, 150u, 160u, 170u, 180u, 185u,
454                                       186u, 190u, 200u, 210u, 220u, 232u,
455                                       233u, 240u, 250u, 260u, 265u };
456   bool isCharacterHit05[] = { false, true, true, true, true, false,
457                               false, true, true, true, true, false,
458                               false, true, true, true, true, false,
459                               false, true, true, true, true, false,
460                               false, true, true, true, true, false,
461                               false, true, true, true, false };
462
463   //   0            10           20           30           40        46
464   //    שנבabcגקכd    efעיןghiחל   ךjklצמםmno   פרףpqrדאוs   tuהסתv
465   //  46     50           60          70            80              93
466   //    wxטז   ץyzשנבabcג   קכdefעיןgh   iחלךjklצמם   mnoפרףpqrדאוs
467   //  93        100          110          120           130           139
468   //    tuהסתvw   xטזץyzשנבa   bcגקכdefעי    ןghiחלךjkl    צמםmnoפרף
469   // 139           150           160          170         180       186
470   //    pqrדאוstuהס   תvwxטזץyzש   נבabcגקכde   fעיןghiחלך   jklצמם
471   // 186    190          200           210           220            232
472   //    mnoפ   רףpqrדאוst   uהסתvwxטזץ   yzשנבabcגק    כdefעיןghiחל
473   // 232         240           250           260     265
474   //    ךjklצמםm   noפרףpqrדא    וstuהסתvwx   טזץyz
475
476   float visualX06[] = { 500.f, 307.f, 237.f, 148.f, 55.f, -100.f,
477                         500.f, 362.f, 276.f, 213.f, 121.f, -100.f,
478                         500.f, 344.f, 238.f, 167.f, 93.f, -100.f,
479                         500.f, 306.f, 216.f, 142.f, 58.f, -100.f,
480                         500.f, 355.f, 279.f, 182.f, 92.f, -100.f,
481                         500.f, 326.f, 238.f, 150.f, -100.f };
482   float visualY06[] = { -100.f, 12.f, 12.f, 12.f, 12.f, 12.f,
483                         30.f, 30.f, 30.f, 30.f, 30.f, 30.f,
484                         50.f, 50.f, 50.f, 50.f, 50.f, 50.f,
485                         67.f, 67.f, 67.f, 67.f, 67.f, 67.f,
486                         87.f, 87.f, 87.f, 87.f, 87.f, 87.f,
487                         107.f, 107.f, 107.f, 107.f, 107.f };
488   CharacterHitTest::Mode mode06[] = { CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP,
489                                       CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP,
490                                       CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP,
491                                       CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP,
492                                       CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP,
493                                       CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP, CharacterHitTest::TAP };
494   CharacterIndex logicalIndex06[] = {    0,  10u,  20u,  30u,  40u,  45u,
495                                        46u,  50u,  60u,  70u,  80u,  92u,
496                                        93u, 100u, 110u, 120u, 130u, 138u,
497                                       139u, 150u, 160u, 170u, 180u, 185u,
498                                       186u, 190u, 200u, 210u, 220u, 231u,
499                                       232u, 240u, 250u, 260u, 265u  };
500   bool isCharacterHit06[] = { false, true, true, true, true, false,
501                               false, true, true, true, true, false,
502                               false, true, true, true, true, false,
503                               false, true, true, true, true, false,
504                               false, true, true, true, true, false,
505                               false, true, true, true, false };
506
507   float visualX07[] = { 395.f };
508   float visualY07[] = { 12.f };
509   CharacterHitTest::Mode mode07[] = { CharacterHitTest::TAP };
510   CharacterIndex logicalIndex07[] = { 1u };
511   bool isCharacterHit07[] = { true };
512
513   float visualX08[] = { 7.f };
514   float visualY08[] = { 12.f };
515   CharacterHitTest::Mode mode08[] = { CharacterHitTest::TAP };
516   CharacterIndex logicalIndex08[] = { 1u };
517   bool isCharacterHit08[] = { true };
518
519   struct GetClosestCursorIndexData data[] =
520   {
521     {
522       "Void text.",
523       "",
524       1u,
525       visualX01,
526       visualY01,
527       mode01,
528       logicalIndex01,
529       isCharacterHit01
530     },
531     {
532       "Single line text.",
533       "Hello world שלום עולם",
534       7u,
535       visualX02,
536       visualY02,
537       mode02,
538       logicalIndex02,
539       isCharacterHit02
540     },
541     {
542       "Single line with ligatures",
543       "different الأربعاء",
544       4u,
545       visualX03,
546       visualY03,
547       mode03,
548       logicalIndex03,
549       isCharacterHit03
550     },
551     {
552       "Multiline. Single line paragraphs",
553       "Hello world\n"
554       "שלום עולם\n"
555       "different الأربعاء\n",
556       17u,
557       visualX04,
558       visualY04,
559       mode04,
560       logicalIndex04,
561       isCharacterHit04
562     },
563     {
564       "Multiline. Single bidirectional paragraph, starts LTR, wrapped lines",
565       "abcשנבdefגקכghiעיןjklחלךmnoצמםpqrפרףstuדאוvwxה"
566       "סתyzטזץabcשנבdefגקכghiעיןjklחלךmnoצמםpqrפרףstuד"
567       "אוvwxהסתyzטזץabcשנבdefגקכghiעיןjklחלךmnoצמםpqr"
568       "פרףstuדאוvwxהסתyzטזץabcשנבdefגקכghiעיןjklחלךmno"
569       "צמםpqrפרףstuדאוvwxהסתyzטזץabcשנבdefגקכghiעיןjkl"
570       "חלךmnoצמםpqrפרףstuדאוvwxהסתyzטזץ",
571       35u,
572       visualX05,
573       visualY05,
574       mode05,
575       logicalIndex05,
576       isCharacterHit05
577     },
578     {
579       "Multiline. Single bidirectional paragraph, starts RTL, wrapped lines",
580       "שנבabcגקכdefעיןghiחלךjklצמםmnoפרףpqrדאוstuהסתv"
581       "wxטזץyzשנבabcגקכdefעיןghiחלךjklצמםmnoפרףpqrדאוs"
582       "tuהסתvwxטזץyzשנבabcגקכdefעיןghiחלךjklצמםmnoפרף"
583       "pqrדאוstuהסתvwxטזץyzשנבabcגקכdefעיןghiחלךjklצמם"
584       "mnoפרףpqrדאוstuהסתvwxטזץyzשנבabcגקכdefעיןghiחל"
585       "ךjklצמםmnoפרףpqrדאוstuהסתvwxטזץyz",
586       35u,
587       visualX06,
588       visualY06,
589       mode06,
590       logicalIndex06,
591       isCharacterHit06
592     },
593     {
594       "Testing complex characters. Arabic ligatures",
595       "الأَبْجَدِيَّة العَرَبِيَّة",
596       1u,
597       visualX07,
598       visualY07,
599       mode07,
600       logicalIndex07,
601       isCharacterHit07
602     },
603     {
604       "Testing complex characters. Latin ligatures",
605       "fi ligature",
606       1u,
607       visualX08,
608       visualY08,
609       mode08,
610       logicalIndex08,
611       isCharacterHit08
612     }
613   };
614   const unsigned int numberOfTests = 8u;
615
616   for( unsigned int index = 0; index < numberOfTests; ++index )
617   {
618     ToolkitTestApplication application;
619     if( !GetClosestCursorIndexTest( data[index] ) )
620     {
621       tet_result(TET_FAIL);
622     }
623   }
624
625   tet_result(TET_PASS);
626   END_TEST;
627 }
628
629 int UtcDaliGetCursorPosition(void)
630 {
631   tet_infoline(" UtcDaliGetCursorPosition");
632
633   float visualX08[] = { 5.f };
634   float visualY08[] = { 0.f };
635   CharacterIndex logicalIndex08[] = { 1u };
636
637   struct GetCursorPositionData data[] =
638   {
639     {
640       "Testing complex characters. Latin ligatures",
641       "fi ligature",
642       1u,
643       logicalIndex08,
644       visualX08,
645       visualY08,
646     }
647   };
648   const unsigned int numberOfTests = 1u;
649
650   for( unsigned int index = 0; index < numberOfTests; ++index )
651   {
652     ToolkitTestApplication application;
653     if( !GetCursorPositionTest( data[index] ) )
654     {
655       tet_result(TET_FAIL);
656     }
657   }
658
659   tet_result(TET_PASS);
660   END_TEST;
661 }
662
663 int UtcDaliFindSelectionIndices(void)
664 {
665   tet_infoline(" UtcDaliFindSelectionIndices");
666
667   float visualX01[] = { -100.f };
668   float visualY01[] = { -100.f };
669   bool found01[] = { false };
670   CharacterIndex startIndex01[] = { 0 };
671   CharacterIndex endIndex01[] = { 0 };
672   CharacterIndex noHitText01[] = { 0 };
673
674   float visualX02[] = { -100.f, 1000.f, 1000.f };
675   float visualY02[] = { -100.f, 12.f, 1000.f };
676   bool found02[] = { false, false, false };
677   CharacterIndex startIndex02[] = { 0, 6u, 6u };
678   CharacterIndex endIndex02[] = { 5u, 11u, 11u };
679   CharacterIndex noHitText02[] = { 0, 11u, 11u };
680
681   float visualX03[] = { 70.f };
682   float visualY03[] = { 12.f };
683   bool found03[] = { true };
684   CharacterIndex startIndex03[] = { 6u };
685   CharacterIndex endIndex03[] = { 11u };
686   CharacterIndex noHitText03[] = { 0u };
687
688   float visualX04[] = { 132.f };
689   float visualY04[] = { 12.f };
690   bool found04[] = { true };
691   CharacterIndex startIndex04[] = { 12u };
692   CharacterIndex endIndex04[] = { 16u };
693   CharacterIndex noHitText04[] = { 0u };
694
695   float visualX05[] = { 1.f };
696   float visualY05[] = { 12.f };
697   bool found05[] = { true };
698   CharacterIndex startIndex05[] = { 0 };
699   CharacterIndex endIndex05[] = { 1u };
700   CharacterIndex noHitText05[] = { 0 };
701
702   float visualX06[] = { 10.f };
703   float visualY06[] = { 12.f };
704   bool found06[] = { true };
705   CharacterIndex startIndex06[] = { 0 };
706   CharacterIndex endIndex06[] = { 1u };
707   CharacterIndex noHitText06[] = { 0u };
708
709   struct FindSelectionIndicesData data[] =
710   {
711     {
712       "void text",
713       "",
714       1u,
715       visualX01,
716       visualY01,
717       found01,
718       startIndex01,
719       endIndex01,
720       noHitText01
721     },
722     {
723       "touch out of text's boundaries",
724       "Hello world",
725       3u,
726       visualX02,
727       visualY02,
728       found02,
729       startIndex02,
730       endIndex02,
731       noHitText02
732     },
733     {
734       "touch on the text",
735       "Hello world demo",
736       1u,
737       visualX03,
738       visualY03,
739       found03,
740       startIndex03,
741       endIndex03,
742       noHitText03
743     },
744     {
745       "touch on the new paragraph character at the end of line",
746       "Hello world demo\n",
747       1u,
748       visualX04,
749       visualY04,
750       found04,
751       startIndex04,
752       endIndex04,
753       noHitText04
754     },
755     {
756       "touch on a white space character. is the unique character of the line",
757       " ",
758       1u,
759       visualX05,
760       visualY05,
761       found05,
762       startIndex05,
763       endIndex05,
764       noHitText05
765     },
766     {
767       "touch on a white space character. is between two words",
768       "h ello",
769       1u,
770       visualX06,
771       visualY06,
772       found06,
773       startIndex06,
774       endIndex06,
775       noHitText06
776     },
777   };
778   const unsigned int numberOfTests = 6u;
779
780   for( unsigned int index = 0; index < numberOfTests; ++index )
781   {
782     ToolkitTestApplication application;
783     if( !FindSelectionIndicesTest( data[index] ) )
784     {
785       tet_result(TET_FAIL);
786     }
787   }
788
789   tet_result(TET_PASS);
790   END_TEST;
791 }