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