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