Sync UTC with text shape method.
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-toolkit-internal / utc-Dali-BidirectionalSupport.cpp
1 /*
2  * Copyright (c) 2022 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 <stdlib.h>
19 #include <iostream>
20
21 #include <dali-toolkit-test-suite-utils.h>
22 #include <dali-toolkit/dali-toolkit.h>
23 #include <dali-toolkit/internal/text/bidirectional-support.h>
24 #include <dali-toolkit/internal/text/character-set-conversion.h>
25 #include <dali-toolkit/internal/text/text-run-container.h>
26 #include <dali/devel-api/text-abstraction/bidirectional-support.h>
27 #include <toolkit-text-utils.h>
28
29 using namespace Dali;
30 using namespace Toolkit;
31 using namespace Text;
32
33 // Tests the following functions.
34 //
35 // void SetBidirectionalInfo( const Vector<Character>& text,
36 //                            const Vector<ScriptRun>& scripts,
37 //                            const Vector<LineBreakInfo>& lineBreakInfo,
38 //                            CharacterIndex startIndex,
39 //                            Length numberOfCharacters,
40 //                            Vector<BidirectionalParagraphInfoRun>& bidirectionalInfo )
41 // bool GetMirroredText( const Vector<Character>& text,
42 //                       Vector<CharacterDirection>& directions,
43 //                       const Vector<BidirectionalParagraphInfoRun>& bidirectionalInfo,
44 //                       CharacterIndex startIndex,
45 //                       Length numberOfCharacters,
46 //                       Vector<Character>& mirroredText )
47 // void GetCharactersDirection( const Vector<BidirectionalParagraphInfoRun>& bidirectionalInfo,
48 //                              Length totalNumberOfCharacters,
49 //                              CharacterIndex startIndex,
50 //                              Length numberOfCharacters,
51 //                              Vector<CharacterDirection>& directions )
52
53 //////////////////////////////////////////////////////////
54
55 namespace
56 {
57 struct SetBidirectionalInfoData
58 {
59   std::string   description;                 ///< Description of the test.
60   std::string   text;                        ///< Input text.
61   unsigned int  startIndex;                  ///< The index from where the model is updated.
62   unsigned int  numberOfCharacters;          ///< The number of characters to update.
63   unsigned int  numberOfParagraphs;          ///< The expected number of bidirectional paragraphs.
64   unsigned int* indices;                     ///< The expected indices to the first character of each paragraph.
65   unsigned int* numberOfParagraphCharacters; ///< The expected number of characters of each paragraph.
66   bool*         directions;                  ///< The expected direction of each paragraph.
67 };
68
69 struct BidiLineData
70 {
71   unsigned int  characterIndex;
72   unsigned int  numberOfCharacters;
73   unsigned int* visualToLogical;
74 };
75
76 struct GetMirroredTextData
77 {
78   std::string  description;        ///< Description of the test.
79   std::string  text;               ///< Input text.
80   unsigned int startIndex;         ///< The index from where the model is updated.
81   unsigned int numberOfCharacters; ///< The number of the characters.
82   std::string  mirroredText;       ///< The expected result.
83 };
84
85 struct GetCharactersDirectionData
86 {
87   std::string  description;            ///< Description of the test.
88   std::string  text;                   ///< Input text.
89   unsigned int startIndex;             ///< The index from where the model is updated.
90   unsigned int numberOfCharacters;     ///< The number of characters.
91   bool*        directions;             ///< The expected directions.
92   bool         markupProcessorEnabled; ///< Enable markup processor to use markup text.
93 };
94
95 bool SetBidirectionalInfoTest(const SetBidirectionalInfoData& data)
96 {
97   // 1) Create the model.
98   ModelPtr   textModel;
99   MetricsPtr metrics;
100   Size       textArea(100.f, 60.f);
101   Size       layoutSize;
102
103   // Create the model.
104   const Vector<FontDescriptionRun> fontDescriptions;
105   const LayoutOptions              options;
106   CreateTextModel(data.text,
107                   textArea,
108                   fontDescriptions,
109                   options,
110                   layoutSize,
111                   textModel,
112                   metrics,
113                   false,
114                   LineWrap::WORD,
115                   false,
116                   Toolkit::DevelText::EllipsisPosition::END,
117                   0.0f, // lineSpacing
118                   0.0f  // characterSpacing
119   );
120
121   LogicalModelPtr logicalModel = textModel->mLogicalModel;
122   VisualModelPtr  visualModel  = textModel->mVisualModel;
123
124   // 2) Clear the bidirectional paragraph info data.
125   Vector<BidirectionalParagraphInfoRun>& bidirectionalInfo = logicalModel->mBidirectionalParagraphInfo;
126   if(0u != data.numberOfCharacters)
127   {
128     ClearCharacterRuns(data.startIndex,
129                        data.startIndex + data.numberOfCharacters - 1u,
130                        bidirectionalInfo);
131   }
132
133   // 3) Call the SetBidirectionalInfo() function.
134   SetBidirectionalInfo(logicalModel->mText,
135                        logicalModel->mScriptRuns,
136                        logicalModel->mLineBreakInfo,
137                        data.startIndex,
138                        data.numberOfCharacters,
139                        bidirectionalInfo);
140
141   // 4) Compare with the expected results.
142   TextAbstraction::BidirectionalSupport bidirectionalSupport = TextAbstraction::BidirectionalSupport::Get();
143
144   if(data.numberOfParagraphs != bidirectionalInfo.Count())
145   {
146     // Different number of expected bidirectional paragraphs.
147     std::cout << "  Different number of bidi paragraphs : " << bidirectionalInfo.Count() << ", expected : " << data.numberOfParagraphs << std::endl;
148     return false;
149   }
150
151   for(unsigned int index = 0u; index < data.numberOfParagraphs; ++index)
152   {
153     const BidirectionalParagraphInfoRun& run = bidirectionalInfo[index];
154
155     const CharacterDirection direction = bidirectionalSupport.GetParagraphDirection(run.bidirectionalInfoIndex);
156     if(direction != data.directions[index])
157     {
158       std::cout << "  Different direction" << std::endl;
159       std::cout << "        paragraph : " << index << std::endl;
160       std::cout << "            index : " << run.characterRun.characterIndex << ", num chars : " << run.characterRun.numberOfCharacters << ", direction : " << direction << std::endl;
161       std::cout << "  expected, index : " << data.indices[index] << ", num chars : " << data.numberOfParagraphCharacters[index] << ", direction : " << data.directions[index] << std::endl;
162       return false;
163     }
164
165     if(run.characterRun.characterIndex != data.indices[index])
166     {
167       std::cout << "  Different index" << std::endl;
168       std::cout << "        paragraph : " << index << std::endl;
169       std::cout << "            index : " << run.characterRun.characterIndex << ", num chars : " << run.characterRun.numberOfCharacters << ", direction : " << direction << std::endl;
170       std::cout << "  expected, index : " << data.indices[index] << ", num chars : " << data.numberOfParagraphCharacters[index] << ", direction : " << data.directions[index] << std::endl;
171       return false;
172     }
173     if(run.characterRun.numberOfCharacters != data.numberOfParagraphCharacters[index])
174     {
175       std::cout << "  Different number of characters" << std::endl;
176       std::cout << "        paragraph : " << index << std::endl;
177       std::cout << "            index : " << run.characterRun.characterIndex << ", num chars : " << run.characterRun.numberOfCharacters << ", direction : " << direction << std::endl;
178       std::cout << "  expected, index : " << data.indices[index] << ", num chars : " << data.numberOfParagraphCharacters[index] << ", direction : " << data.directions[index] << std::endl;
179       return false;
180     }
181   }
182
183   return true;
184 }
185
186 bool GetMirroredTextTest(const GetMirroredTextData& data)
187 {
188   // 1) Create the model.
189   ModelPtr   textModel;
190   MetricsPtr metrics;
191   Size       textArea(100.f, 60.f);
192   Size       layoutSize;
193
194   // Create the model.
195   const Vector<FontDescriptionRun> fontDescriptions;
196   const LayoutOptions              options;
197   CreateTextModel(data.text,
198                   textArea,
199                   fontDescriptions,
200                   options,
201                   layoutSize,
202                   textModel,
203                   metrics,
204                   false,
205                   LineWrap::WORD,
206                   false,
207                   Toolkit::DevelText::EllipsisPosition::END,
208                   0.0f, // lineSpacing
209                   0.0f  // characterSpacing
210   );
211
212   LogicalModelPtr logicalModel = textModel->mLogicalModel;
213   VisualModelPtr  visualModel  = textModel->mVisualModel;
214
215   // 2) Call the GetMirroredText() function for the whole text
216   Vector<Character> mirroredText;
217   bool              mirrored = false;
218   mirrored                   = GetMirroredText(logicalModel->mText,
219                              logicalModel->mCharacterDirections,
220                              logicalModel->mBidirectionalParagraphInfo,
221                              0u,
222                              logicalModel->mText.Count(),
223                              mirroredText);
224
225   // 3) Call the GetMirroredText() function for the given index + number of characters
226   mirrored = GetMirroredText(logicalModel->mText,
227                              logicalModel->mCharacterDirections,
228                              logicalModel->mBidirectionalParagraphInfo,
229                              data.startIndex,
230                              data.numberOfCharacters,
231                              mirroredText);
232
233   // 4) Compare the results.
234
235   // Convert to utf8
236   std::string mirroredString;
237   Utf32ToUtf8(mirroredText.Begin(),
238               mirroredText.Count(),
239               mirroredString);
240
241   if(!mirrored && (mirroredString != data.text))
242   {
243     std::cout << "  No mirrored text and mirroredString != data.text." << std::endl;
244     std::cout << "  mirrored string : [" << mirroredString << "]" << std::endl;
245     std::cout << "             text : [" << data.text << "]" << std::endl;
246     return false;
247   }
248
249   if(mirrored && (mirroredString == data.text))
250   {
251     std::cout << "  Mirrored text and mirroredString == data.text." << std::endl;
252     std::cout << "  mirrored string : [" << mirroredString << "]" << std::endl;
253     std::cout << "             text : [" << data.text << "]" << std::endl;
254     return false;
255   }
256
257   if(mirrored && (mirroredString != data.mirroredText))
258   {
259     std::cout << "  Mirrored text and mirroredString != data.mirroredText." << std::endl;
260     std::cout << "  mirrored string : [" << mirroredString << "]" << std::endl;
261     std::cout << "             text : [" << data.mirroredText << "]" << std::endl;
262     return false;
263   }
264
265   return true;
266 }
267
268 bool GetCharactersDirectionTest(const GetCharactersDirectionData& data)
269 {
270   // 1) Create the model.
271   ModelPtr   textModel;
272   MetricsPtr metrics;
273   Size       textArea(100.f, 60.f);
274   Size       layoutSize;
275
276   // Create the model.
277   const Vector<FontDescriptionRun> fontDescriptions;
278   const LayoutOptions              options;
279   CreateTextModel(data.text,
280                   textArea,
281                   fontDescriptions,
282                   options,
283                   layoutSize,
284                   textModel,
285                   metrics,
286                   data.markupProcessorEnabled,
287                   LineWrap::WORD,
288                   false,
289                   Toolkit::DevelText::EllipsisPosition::END,
290                   0.0f, // lineSpacing
291                   0.0f  // characterSpacing
292   );
293
294   LogicalModelPtr logicalModel = textModel->mLogicalModel;
295   VisualModelPtr  visualModel  = textModel->mVisualModel;
296
297   Vector<BidirectionalParagraphInfoRun>& bidirectionalInfo = logicalModel->mBidirectionalParagraphInfo;
298
299   // 2) Clear the direction info data.
300   Vector<CharacterDirection>& directions = logicalModel->mCharacterDirections;
301
302   if(directions.Count() >= data.startIndex + data.numberOfCharacters)
303   {
304     directions.Erase(directions.Begin() + data.startIndex,
305                      directions.Begin() + data.startIndex + data.numberOfCharacters);
306   }
307
308   // 3) Call GetCharactersDirection() function.
309
310   GetCharactersDirection(bidirectionalInfo,
311                          logicalModel->mText.Count(),
312                          data.startIndex,
313                          data.numberOfCharacters,
314                          directions);
315
316   for(unsigned int index = 0u; index < logicalModel->mText.Count(); ++index)
317   {
318     if(data.directions[index] != directions[index])
319     {
320       return false;
321     }
322   }
323
324   return true;
325 }
326
327 } // namespace
328
329 //////////////////////////////////////////////////////////
330
331 int UtcDaliSetBidirectionalInfo(void)
332 {
333   tet_infoline(" UtcDaliSetBidirectionalInfo");
334
335   unsigned int indices01[]            = {};
336   unsigned int numberOfCharacters01[] = {};
337   bool         direction01[]          = {};
338   unsigned int indices02[]            = {};
339   unsigned int numberOfCharacters02[] = {};
340   bool         direction02[]          = {};
341   unsigned int indices03[]            = {17u, 48u};
342   unsigned int numberOfCharacters03[] = {14u, 14u};
343   bool         direction03[]          = {true, true};
344   unsigned int indices04[]            = {17u, 31u, 79u};
345   unsigned int numberOfCharacters04[] = {14u, 48u, 31u};
346   bool         direction04[]          = {true, false, true};
347   unsigned int indices05[]            = {17u, 41u, 117u};
348   unsigned int numberOfCharacters05[] = {24u, 76u, 49u};
349   bool         direction05[]          = {true, false, true};
350   unsigned int indices06[]            = {17u, 48u};
351   unsigned int numberOfCharacters06[] = {14u, 14u};
352   bool         direction06[]          = {true, true};
353   unsigned int indices07[]            = {17u, 31u, 79u};
354   unsigned int numberOfCharacters07[] = {14u, 48u, 31u};
355   bool         direction07[]          = {true, false, true};
356   unsigned int indices08[]            = {17u, 41u, 117u};
357   unsigned int numberOfCharacters08[] = {24u, 76u, 49u};
358   bool         direction08[]          = {true, false, true};
359
360   struct SetBidirectionalInfoData data[] =
361     {
362       {"Zero characters",
363        "",
364        0u,
365        0u,
366        0u,
367        indices01,
368        numberOfCharacters01,
369        direction01},
370
371       {"Some left to right paragraphs",
372        "Hello world\ndemo\n\n",
373        0u,
374        18u,
375        0u,
376        indices02,
377        numberOfCharacters02,
378        direction02},
379
380       {"A mix of left to right and right to left paragraphs.",
381        "Hello world demo\nمرحبا بالعالم\nhello world demo\nمرحبا بالعالم\nhello world demo",
382        0u,
383        78u,
384        2u,
385        indices03,
386        numberOfCharacters03,
387        direction03},
388
389       {"A mix of left to right and right to left paragraphs. Paragraphs also contain a mix of bidirectional text.",
390        "Hello world demo\nمرحبا بالعالم\nhello world demo مرحبا بالعالم hello world demo\nمرحبا hello world demo بالعالم\nhello world demo",
391        0u,
392        126u,
393        3u,
394        indices04,
395        numberOfCharacters04,
396        direction04},
397
398       {"A mix of left to right and right to left paragraphs. Paragraphs also contain a mix of bidirectional text and a mix of right to left scripts.",
399        "Hello world demo\nمرحبا שלום עולם بالعالم\nhello world שלום بالعالم עולם demo مرحبا שלום עולם بالعالم hello world demo\nمرحبا hello שלום بالعالم עולם world demo بالعالم\nhello world demo",
400        0u,
401        182u,
402        3u,
403        indices05,
404        numberOfCharacters05,
405        direction05},
406
407       {"A mix of left to right and right to left paragraphs. Updates a left to right paragraph.",
408        "Hello world demo\nمرحبا بالعالم\nhello world demo\nمرحبا بالعالم\nhello world demo",
409        31u,
410        17u,
411        2u,
412        indices06,
413        numberOfCharacters06,
414        direction06},
415
416       {"A mix of left to right and right to left paragraphs. Paragraphs also contain a mix of bidirectional text.",
417        "Hello world demo\nمرحبا بالعالم\nhello world demo مرحبا بالعالم hello world demo\nمرحبا hello world demo بالعالم\nhello world demo",
418        0u,
419        126u,
420        3u,
421        indices07,
422        numberOfCharacters07,
423        direction07},
424
425       {"A mix of left to right and right to left paragraphs. Paragraphs also contain a mix of bidirectional text and a mix of right to left scripts. Updates initial paragraphs.",
426        "Hello world demo\nمرحبا שלום עולם بالعالم\nhello world שלום بالعالم עולם demo مرحبا שלום עולם بالعالم hello world demo\nمرحبا hello שלום بالعالم עולם world demo بالعالم\nhello world demo",
427        0u,
428        41u,
429        3u,
430        indices08,
431        numberOfCharacters08,
432        direction08},
433
434       {"A mix of left to right and right to left paragraphs. Paragraphs also contain a mix of bidirectional text and a mix of right to left scripts. Updates mid paragraphs.",
435        "Hello world demo\nمرحبا שלום עולם بالعالم\nhello world שלום بالعالم עולם demo مرحبا שלום עולם بالعالم hello world demo\nمرحبا hello שלום بالعالم עולם world demo بالعالم\nhello world demo",
436        41u,
437        76u,
438        3u,
439        indices08,
440        numberOfCharacters08,
441        direction08},
442
443       {"A mix of left to right and right to left paragraphs. Paragraphs also contain a mix of bidirectional text and a mix of right to left scripts. Updates from character 85",
444        "Hello world demo\nمرحبا שלום עולם بالعالم\nhello world שלום بالعالم עולם demo مرحبا שלום עולם بالعالم hello world demo\nمرحبا hello שלום بالعالم עולם world demo بالعالم\nhello world demo",
445        117u,
446        65u,
447        3u,
448        indices08,
449        numberOfCharacters08,
450        direction08},
451     };
452   const unsigned int numberOfTests = 10u;
453
454   for(unsigned int index = 0u; index < numberOfTests; ++index)
455   {
456     ToolkitTestApplication application;
457     if(!SetBidirectionalInfoTest(data[index]))
458     {
459       tet_result(TET_FAIL);
460     }
461   }
462
463   tet_result(TET_PASS);
464   END_TEST;
465 }
466
467 int UtcDaliGetMirroredText(void)
468 {
469   tet_infoline(" UtcDaliGetMirroredText");
470
471   struct GetMirroredTextData data[] =
472     {
473       {"Zero characters.",
474        "",
475        0u,
476        0u,
477        ""},
478
479       {"Left to right characters only.",
480        "Hello world\nhello world demo.",
481        0u,
482        29u,
483        "Hello world\nhello world demo."},
484
485       {"Right to left characters but with no characters to mirror.",
486        "שלום עולם\nمرحبا بالعالم",
487        0u,
488        23u,
489        "שלום עולם\nمرحبا بالعالم"},
490
491       {"Right to left characters with some characters to mirror.",
492        "שלום עולם\n(مرحبا بالعالم)",
493        0u,
494        25u,
495        "שלום עולם\n)مرحبا بالعالم("},
496
497       {"Right to left characters with some characters to mirror. Update last paragraph.",
498        "שלום עולם\n(مرحبا بالعالم)",
499        10u,
500        15u,
501        "שלום עולם\n)مرحبا بالعالم("},
502
503       {"Mix of bidirectional text. With more paragraphs.",
504        "Hello world demo\nhello world\nhello world (مرحبا بالعالم שלום) עולם\nשלום مرحبا بالعالم עולם (hello) مرحبا بالعالم world"
505        " مرحبا بالعالم שלום עולם hello world hello world\nبالعالم שלום (hello) world demo (עולם)\nשלום (مرحبا بالعالم עולם) (hello)",
506        0u,
507        239u,
508        "Hello world demo\nhello world\nhello world (مرحبا بالعالم שלום( עולם\nשלום مرحبا بالعالم עולם )hello( مرحبا بالعالم world"
509        " مرحبا بالعالم שלום עולם hello world hello world\nبالعالم שלום )hello) world demo )עולם(\nשלום )مرحبا بالعالم עולם( )hello("},
510
511       {"Mix of bidirectional text. With more paragraphs. Update middle paragraphs.",
512        "Hello world demo\nhello world\nhello world (مرحبا بالعالم שלום) עולם\nשלום مرحبا بالعالم עולם (hello) مرحبا بالعالم world"
513        " مرحبا بالعالم שלום עולם hello world hello world\nبالعالم שלום (hello) world demo (עולם)\nשלום (مرحبا بالعالم עולם) (hello)",
514        29u,
515        38u,
516        "Hello world demo\nhello world\nhello world (مرحبا بالعالم שלום( עולם\nשלום مرحبا بالعالم עולם (hello) مرحبا بالعالم world"
517        " مرحبا بالعالم שלום עולם hello world hello world\nبالعالم שלום (hello) world demo (עולם)\nשלום (مرحبا بالعالم עולם) (hello)"},
518
519       {"Mix of bidirectional text. With more paragraphs. Update middle paragraphs (2).",
520        "Hello world demo\nhello world\nhello world (مرحبا بالعالم שלום) עולם\nשלום مرحبا بالعالم עולם (hello) مرحبا بالعالم world"
521        " مرحبا بالعالم שלום עולם hello world hello world\nبالعالم שלום (hello) world demo (עולם)\nשלום (مرحبا بالعالم עולם) (hello)",
522        67u,
523        100u,
524        "Hello world demo\nhello world\nhello world (مرحبا بالعالم שלום) עולם\nשלום مرحبا بالعالم עולם )hello( مرحبا بالعالم world"
525        " مرحبا بالعالم שלום עולם hello world hello world\nبالعالم שלום (hello) world demo (עולם)\nשלום (مرحبا بالعالم עולם) (hello)"},
526     };
527   const unsigned int numberOfTests = 8u;
528
529   for(unsigned int index = 0u; index < numberOfTests; ++index)
530   {
531     ToolkitTestApplication application;
532     if(!GetMirroredTextTest(data[index]))
533     {
534       tet_result(TET_FAIL);
535     }
536   }
537
538   tet_result(TET_PASS);
539   END_TEST;
540 }
541
542 int UtcDaliGetCharactersDirection(void)
543 {
544   tet_infoline(" UtcDaliGetCharactersDirection");
545
546   bool directions01[] = {};
547   bool directions02[] = {
548     false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false};
549   bool directions03[] = {
550     true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true};
551   bool directions04[] = {
552     false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, true, true, true, true, true, true, true, false, true, true, true, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false, false, false, false};
553   bool directions05[] = {
554     false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, false, false, false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, false, false, false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, false, false, false, false};
555
556   bool directions06[] = {
557     true, true, true, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false};
558
559   struct GetCharactersDirectionData data[] =
560     {
561       {"Zero characters",
562        "",
563        0u,
564        0u,
565        directions01,
566        false},
567
568       {"Left to right characters only",
569        "Hello world\nhello world demo",
570        0u,
571        28u,
572        directions02,
573        false},
574
575       {"Right to left characters only",
576        "שלום עולם\nשלום עולם",
577        0u,
578        19u,
579        directions03,
580        false},
581
582       {"Mix of bidirectional text",
583        "Hello world\nhello world שלום עולם\nשלום עולם hello world",
584        0u,
585        55u,
586        directions04,
587        false},
588
589       {"Mix of bidirectional text. With more paragraphs.",
590        "Hello world demo\nhello world\nhello world مرحبا بالعالم שלום עולם\nשלום مرحبا بالعالم עולם hello مرحبا بالعالم world"
591        " مرحبا بالعالم שלום עולם hello world hello world\nبالعالم שלום hello world demo עולם\nשלום مرحبا بالعالم עולם hello",
592        0u,
593        227u,
594        directions05,
595        false},
596
597       {"Mix of bidirectional text. With more paragraphs. Update first paragraph.",
598        "Hello world demo\nhello world\nhello world مرحبا بالعالم שלום עולם\nשלום مرحبا بالعالم עולם hello مرحبا بالعالم world"
599        " مرحبا بالعالم שלום עולם hello world hello world\nبالعالم שלום hello world demo עולם\nשלום مرحبا بالعالم עולם hello",
600        0u,
601        17u,
602        directions05,
603        false},
604
605       {"Mix of bidirectional text. With more paragraphs. Update from character 29",
606        "Hello world demo\nhello world\nhello world مرحبا بالعالم שלום עולם\nשלום مرحبا بالعالم עולם hello مرحبا بالعالم world"
607        " مرحبا بالعالم שלום עולם hello world hello world\nبالعالم שלום hello world demo עולם\nשלום مرحبا بالعالم עולם hello",
608        29u,
609        134u,
610        directions05,
611        false},
612
613       {"Mix of bidirectional text. With more paragraphs. Update from character 163",
614        "Hello world demo\nhello world\nhello world مرحبا بالعالم שלום עולם\nשלום مرحبا بالعالم עולם hello مرحبا بالعالم world"
615        " مرحبا بالعالم שלום עולם hello world hello world\nبالعالم שלום hello world demo עולם\nשלום مرحبا بالعالم עולם hello",
616        163u,
617        35u,
618        directions05,
619        false},
620
621       {"Mix of bidirectional text. With brackets and LRM",
622        "שלום עולם &lrm;(hello)[world]&lrm;",
623        0u,
624        26u,
625        directions06,
626        true}};
627
628   const unsigned int numberOfTests = 9u;
629
630   for(unsigned int index = 0u; index < numberOfTests; ++index)
631   {
632     ToolkitTestApplication application;
633     if(!GetCharactersDirectionTest(data[index]))
634     {
635       tet_result(TET_FAIL);
636     }
637   }
638
639   tet_result(TET_PASS);
640   END_TEST;
641 }