Move the toolkit-text-model into a folder in the internal side of the test cases.
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-toolkit-internal / utc-Dali-LogicalModel.cpp
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 #include <iostream>
19
20 #include <stdlib.h>
21
22 #include <dali-toolkit-test-suite-utils.h>
23 #include <dali-toolkit/internal/text/text-run-container.h>
24 #include <dali-toolkit/dali-toolkit.h>
25 #include <toolkit-text-model.h>
26
27
28 using namespace Dali;
29 using namespace Toolkit;
30 using namespace Text;
31
32 // Tests the following functions.
33 //
34 // void SetVisualToLogicalMap( const BidirectionalLineInfoRun* const bidirectionalInfo,
35 //                             Length numberOfRuns,
36 //                             CharacterIndex startIndex  )
37
38
39 //////////////////////////////////////////////////////////
40
41 namespace
42 {
43 struct CreateParagraphData
44 {
45   std::string    description;                    ///< Description of the test.
46   std::string    text;                           ///< Input text.
47   CharacterIndex index;                          ///< The first character index.
48   Length         numberOfCharacters;             ///< The number of characters.
49   unsigned int   numberOfParagraphs;             ///< The expected number of paragraphs.
50   unsigned int*  indices;                        ///< The expected paragraph info indices.
51   unsigned int*  numberOfCharactersPerParagraph; ///< The expected number of characters of each paragraph.
52 };
53
54 struct FindParagraphData
55 {
56   std::string    description;        ///< Description of the test.
57   std::string    text;               ///< Input text.
58   CharacterIndex index;              ///< The first character index.
59   Length         numberOfCharacters; ///< The number of characters.
60   unsigned int   numberOfParagraphs; ///< The expected number of paragraphs.
61   unsigned int*  paragraphs;         ///< The expected paragraph info.
62 };
63
64 struct SetVisualToLogicalMapData
65 {
66   std::string   description;                ///< Description of the test.
67   std::string   text;                       ///< Input text.
68   unsigned int  startIndex;                 ///< The start index from where the visual to logical conversion table is set.
69   unsigned int  numberOfCharacters;         ///< The number of characters to set.
70   Size          textArea;                   ///< The size of the area where the text is laid-out.
71   unsigned int  expectedNumberOfCharacters; ///< The expected number of characters.
72   unsigned int* visualToLogical;            ///< The expected visual to logical conversion table.
73 };
74
75 bool CreateParagraphTest( const CreateParagraphData& data )
76 {
77   // 1) Create the model.
78   LogicalModelPtr logicalModel = LogicalModel::New();
79   VisualModelPtr visualModel = VisualModel::New();
80   Size textArea(100.f, 60.f);
81   Size layoutSize;
82
83   Vector<FontDescriptionRun> fontDescriptionRuns;
84   LayoutOptions options;
85   CreateTextModel( data.text,
86                    textArea,
87                    fontDescriptionRuns,
88                    options,
89                    layoutSize,
90                    logicalModel,
91                    visualModel );
92
93   // 2) Clear the paragraphs.
94   Vector<ParagraphRun>& paragraphs = logicalModel->mParagraphInfo;
95   ClearCharacterRuns( data.index,
96                       data.index + data.numberOfCharacters - 1u,
97                       paragraphs );
98
99   // 3) Call the LogicalModel::CreateParagraphInfo() method
100   logicalModel->CreateParagraphInfo( data.index,
101                                      data.numberOfCharacters );
102
103   // 4) Compare the results.
104   if( data.numberOfParagraphs != paragraphs.Count() )
105   {
106     std::cout << "  Different number of paragraphs : " << paragraphs.Count() << ", expected : " << data.numberOfParagraphs << std::endl;
107     return false;
108   }
109
110   unsigned int index = 0u;
111   for( Vector<ParagraphRun>::ConstIterator it = paragraphs.Begin(),
112          endIt = paragraphs.End();
113        it != endIt;
114        ++it, ++index )
115   {
116     const ParagraphRun& paragraph( *it );
117
118     if( data.indices[index] != paragraph.characterRun.characterIndex )
119     {
120       std::cout << "  Different character index for paragraph : " << index << ", " << paragraph.characterRun.characterIndex << ", expected : " << data.indices[index] << std::endl;
121       return false;
122     }
123     if( data.numberOfCharactersPerParagraph[index] != paragraph.characterRun.numberOfCharacters )
124     {
125       std::cout << "  Different number of characters for paragraph : " << index << ", " << paragraph.characterRun.numberOfCharacters << ", expected : " << data.numberOfCharactersPerParagraph[index] << std::endl;
126       return false;
127     }
128   }
129
130   return true;
131 }
132
133 bool FindParagraphTest( const FindParagraphData& data )
134 {
135   // 1) Create the model.
136   LogicalModelPtr logicalModel = LogicalModel::New();
137   VisualModelPtr visualModel = VisualModel::New();
138   Size textArea(100.f, 60.f);
139   Size layoutSize;
140
141   Vector<FontDescriptionRun> fontDescriptionRuns;
142   LayoutOptions options;
143   CreateTextModel( data.text,
144                    textArea,
145                    fontDescriptionRuns,
146                    options,
147                    layoutSize,
148                    logicalModel,
149                    visualModel );
150
151   // 2) Find the paragraphs.
152   Vector<ParagraphRunIndex> paragraphs;
153   logicalModel->FindParagraphs( data.index, data.numberOfCharacters, paragraphs );
154
155   // 3) compare the results.
156   if( data.numberOfParagraphs != paragraphs.Count() )
157   {
158     return false;
159   }
160
161   unsigned int index = 0u;
162   for( Vector<ParagraphRunIndex>::ConstIterator it = paragraphs.Begin(),
163          endIt = paragraphs.End();
164        it != endIt;
165        ++it, ++index )
166   {
167     const ParagraphRunIndex paragraphIndex = *it;
168
169     if( paragraphIndex != data.paragraphs[index] )
170     {
171       return false;
172     }
173   }
174
175   return true;
176 }
177
178 bool SetVisualToLogicalMapTest( const SetVisualToLogicalMapData& data )
179 {
180   std::cout << "  testing : " << data.description << std::endl;
181   // Create the model.
182   LogicalModelPtr logicalModel = LogicalModel::New();
183   VisualModelPtr visualModel = VisualModel::New();
184   Size layoutSize;
185
186   // Create the model with the whole text.
187   const Vector<FontDescriptionRun> fontDescriptions;
188   const LayoutOptions options;
189   CreateTextModel( data.text,
190                    data.textArea,
191                    fontDescriptions,
192                    options,
193                    layoutSize,
194                    logicalModel,
195                    visualModel );
196
197   // Get the visual to logical map.
198   Vector<CharacterIndex>& visualToLogicalMap = logicalModel->mVisualToLogicalMap;
199
200   // Compare the results.
201   if( data.expectedNumberOfCharacters != visualToLogicalMap.Count() )
202   {
203     std::cout << "  differetn number of characters : " << visualToLogicalMap.Count() << ", expected : " << data.expectedNumberOfCharacters << std::endl;
204     return false;
205   }
206
207   for( unsigned int index = 0u; index < data.expectedNumberOfCharacters; ++index )
208   {
209     if( data.visualToLogical[index] != visualToLogicalMap[index] )
210     {
211       std::cout << "  different visualToLogical table : " << std::endl;
212       for( unsigned int i = 0; i < data.expectedNumberOfCharacters; ++i )
213       {
214         std::cout << visualToLogicalMap[i] << " ";
215       }
216       std::cout << std::endl;
217       std::cout << "                         expected : " << std::endl;
218       for( unsigned int i = 0; i < data.expectedNumberOfCharacters; ++i )
219       {
220         std::cout << data.visualToLogical[i] << " ";
221       }
222       std::cout << std::endl;
223       return false;
224     }
225   }
226
227   return true;
228 }
229
230 } // namespace
231
232 //////////////////////////////////////////////////////////
233 //
234 // UtcDaliCreateParagraph
235 // UtcDaliFindParagraph
236 // UtcDaliSetVisualToLogicalMap
237 //
238 //////////////////////////////////////////////////////////
239
240 int UtcDaliCreateParagraph(void)
241 {
242   ToolkitTestApplication application;
243   tet_infoline(" UtcDaliCreateParagraph");
244
245   unsigned int paragraphsIndices01[] = { 0u };
246   unsigned int paragraphsNumberOfCharacters01[] = { 0u };
247   unsigned int paragraphsIndices02[] = { 0u, 12u, 17u };
248   unsigned int paragraphsNumberOfCharacters02[] = { 12u, 5u, 1u };
249   unsigned int paragraphsIndices03[] = { 0u, 12u, 17u, 34u };
250   unsigned int paragraphsNumberOfCharacters03[] = { 12u, 5u, 17u ,1u };
251
252   struct CreateParagraphData data[] =
253   {
254     {
255       "Zero characters",
256       "",
257       0u,
258       0u,
259       0u,
260       paragraphsIndices01,
261       paragraphsNumberOfCharacters01,
262     },
263     {
264       "Some paragraphs",
265       "Hello world\ndemo\n\n",
266       0u,
267       18u,
268       3u,
269       paragraphsIndices02,
270       paragraphsNumberOfCharacters02,
271     },
272     {
273       "Some paragraphs. Update the initial paragraphs.",
274       "Hello world\ndemo\nhello world demo\n\n",
275       0u,
276       17u,
277       4u,
278       paragraphsIndices03,
279       paragraphsNumberOfCharacters03,
280     },
281     {
282       "Some paragraphs. Update the mid paragraphs.",
283       "Hello world\ndemo\nhello world demo\n\n",
284       12u,
285       5u,
286       4u,
287       paragraphsIndices03,
288       paragraphsNumberOfCharacters03,
289     },
290     {
291       "Some paragraphs. Update the final paragraphs.",
292       "Hello world\ndemo\nhello world demo\n\n",
293       17u,
294       18u,
295       4u,
296       paragraphsIndices03,
297       paragraphsNumberOfCharacters03,
298     },
299   };
300   const unsigned int numberOfTests = 5u;
301
302   for( unsigned int index = 0u; index < numberOfTests; ++index )
303   {
304     // ToolkitTestApplication application;
305     if( !CreateParagraphTest( data[index] ) )
306     {
307       tet_result(TET_FAIL);
308     }
309   }
310
311   tet_result(TET_PASS);
312   END_TEST;
313 }
314
315 int UtcDaliFindParagraph(void)
316 {
317   tet_infoline(" UtcDaliFindParagraph");
318
319   unsigned int paragraphs01[] = {};
320   unsigned int paragraphs02[] = { 0u, 1u, 2u };
321   unsigned int paragraphs03[] = { 0u };
322   unsigned int paragraphs04[] = { 1u };
323   unsigned int paragraphs05[] = { 0u, 1u, 2u };
324
325   struct FindParagraphData data[] =
326   {
327     {
328       "Zero characters",
329       "",
330       0u,
331       100u,
332       0u,
333       paragraphs01,
334     },
335     {
336       "Some paragraphs",
337       "Hello world\ndemo\n\n",
338       0u,
339       18u,
340       3u,
341       paragraphs02
342     },
343     {
344       "Some paragraphs",
345       "Hello world\ndemo\n\n",
346       0u,
347       12u,
348       1u,
349       paragraphs03
350     },
351     {
352       "Some paragraphs",
353       "Hello world\ndemo\n\n",
354       12u,
355       5u,
356       1u,
357       paragraphs04
358     },
359     {
360       "Some paragraphs",
361       "Hello world\ndemo\n\n",
362       3u,
363       15u,
364       3u,
365       paragraphs05
366     },
367   };
368   const unsigned int numberOfTests = 5u;
369
370   for( unsigned int index = 0u; index < numberOfTests; ++index )
371   {
372     ToolkitTestApplication application;
373     if( !FindParagraphTest( data[index] ) )
374     {
375       tet_result(TET_FAIL);
376     }
377   }
378
379   tet_result(TET_PASS);
380   END_TEST;
381 }
382
383 int UtcDaliSetVisualToLogicalMap(void)
384 {
385   tet_infoline(" UtcDaliSetVisualToLogicalMap");
386
387   unsigned int* visualToLogical01 = NULL;
388   unsigned int* visualToLogical02 = NULL;
389   unsigned int  visualToLogical03[] = { 12u, 11u, 10u, 9u, 8u, 7u, 6u, 5u, 4u, 3u, 2u, 1u, 0u };
390   unsigned int  visualToLogical04[] = { 0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 9u, 10u, 11u, 12u, 25u, 24u, 23u, 22u, 21u, 20u, 19u, 18u, 17u, 16u, 15u, 14u, 13u, };
391   unsigned int  visualToLogical05[] = { 0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 9u, 10u, 11u, 12u, 13u, 26u, 25u, 24u, 23u, 22u, 21u, 20u, 19u, 18u, 17u, 16u, 15u, 14u };
392   unsigned int  visualToLogical06[] = { 0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 9u, 10u, 11u, 12u, 25u, 24u, 23u, 22u, 21u, 20u, 19u, 18u, 17u, 16u, 15u, 14u, 13u, 26u, 27u, 28u, 29u, 30u, 31u, 32u, 33u, 34u, 35u, 36u, 37u, 38u, 39u, 54u, 53u, 52u, 51u, 50u, 49u, 48u, 47u, 46u, 45u, 44u, 43u, 42u, 41u, 40u, 67u, 66u, 55u, 56u, 57u, 58u, 59u, 60u, 61u, 62u, 63u, 64u, 65u, 81u, 80u, 79u, 78u, 77u, 76u, 75u, 74u, 73u, 72u, 71u, 70u, 69u, 68u, 95u, 94u, 93u, 92u, 91u, 90u, 89u, 88u, 87u, 86u, 85u, 84u, 83u, 82u, 96u, 97u, 98u, 99u, 100u, 101u, 102u, 103u, 104u, 105u, 106u };
393   unsigned int  visualToLogical07[] = { 0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 9u, 10u, 11u, 12u, 25u, 24u, 23u, 22u, 21u, 20u, 19u, 18u, 17u, 16u, 15u, 14u, 13u, 26u, 27u, 28u, 29u, 30u, 31u, 32u, 33u, 34u, 35u, 36u, 37u, 38u, 39u, 54u, 53u, 52u, 51u, 50u, 49u, 48u, 47u, 46u, 45u, 44u, 43u, 42u, 41u, 40u, 67u, 66u, 55u, 56u, 57u, 58u, 59u, 60u, 61u, 62u, 63u, 64u, 65u, 81u, 80u, 79u, 78u, 77u, 76u, 75u, 74u, 73u, 72u, 71u, 70u, 69u, 68u, 95u, 94u, 93u, 92u, 91u, 90u, 89u, 88u, 87u, 86u, 85u, 84u, 83u, 82u, 96u, 97u, 98u, 99u, 100u, 101u, 102u, 103u, 104u, 105u, 106u };
394   unsigned int  visualToLogical08[] = { 0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 9u, 10u, 11u, 12u, 25u, 24u, 23u, 22u, 21u, 20u, 19u, 18u, 17u, 16u, 15u, 14u, 13u, 26u, 27u, 28u, 29u, 30u, 31u, 32u, 33u, 34u, 35u, 36u, 37u, 38u, 39u, 54u, 53u, 52u, 51u, 50u, 49u, 48u, 47u, 46u, 45u, 44u, 43u, 42u, 41u, 40u, 67u, 66u, 55u, 56u, 57u, 58u, 59u, 60u, 61u, 62u, 63u, 64u, 65u, 81u, 80u, 79u, 78u, 77u, 76u, 75u, 74u, 73u, 72u, 71u, 70u, 69u, 68u, 95u, 94u, 93u, 92u, 91u, 90u, 89u, 88u, 87u, 86u, 85u, 84u, 83u, 82u, 96u, 97u, 98u, 99u, 100u, 101u, 102u, 103u, 104u, 105u, 106u };
395   unsigned int  visualToLogical09[] = { 0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 9u, 10u, 11u, 12u, 25u, 24u, 23u, 22u, 21u, 20u, 19u, 18u, 17u, 16u, 15u, 14u, 13u, 26u, 27u, 28u, 29u, 30u, 31u, 32u, 33u, 34u, 35u, 36u, 37u, 38u, 39u, 54u, 53u, 52u, 51u, 50u, 49u, 48u, 47u, 46u, 45u, 44u, 43u, 42u, 41u, 40u, 67u, 66u, 55u, 56u, 57u, 58u, 59u, 60u, 61u, 62u, 63u, 64u, 65u, 81u, 80u, 79u, 78u, 77u, 76u, 75u, 74u, 73u, 72u, 71u, 70u, 69u, 68u, 95u, 94u, 93u, 92u, 91u, 90u, 89u, 88u, 87u, 86u, 85u, 84u, 83u, 82u, 96u, 97u, 98u, 99u, 100u, 101u, 102u, 103u, 104u, 105u, 106u };
396
397   struct SetVisualToLogicalMapData data[] =
398   {
399     {
400       "Zero characters text",
401       "",
402       0u,
403       0u,
404       Size( 100.f, 300.f ),
405       0u,
406       visualToLogical01
407     },
408     {
409       "Left to right text only",
410       "Hello world",
411       0u,
412       11u,
413       Size( 100.f, 300.f ),
414       0u,
415       visualToLogical02
416     },
417     {
418       "Right to left text only",
419       "مرحبا بالعالم",
420       0u,
421       13u,
422       Size( 100.f, 300.f ),
423       13u,
424       visualToLogical03
425     },
426     {
427       "Mix of left to right and right to left text.",
428       "Hello world, مرحبا بالعالم",
429       0u,
430       26u,
431       Size( 100.f, 300.f ),
432       26u,
433       visualToLogical04
434     },
435     {
436       "Mix of left to right and right to left text.",
437       "Hello world, \nمرحبا بالعالم",
438       0u,
439       27u,
440       Size( 100.f, 300.f ),
441       27u,
442       visualToLogical05
443     },
444     {
445       "Mix of left to right and right to left text.",
446       "Hello world, مرحبا بالعالم, hello world\nمرحبا بالعالم, hello world, مرحبا بالعالم\nمرحبا بالعالم\nhello world",
447       0u,
448       107u,
449       Size( 100.f, 300.f ),
450       107u,
451       visualToLogical06
452     },
453     {
454       "Mix of left to right and right to left text. Updates from character index 5",
455       "Hello world, مرحبا بالعالم, hello world\nمرحبا بالعالم, hello world, مرحبا بالعالم\nمرحبا بالعالم\nhello world",
456       5u,
457       107u,
458       Size( 100.f, 300.f ),
459       107u,
460       visualToLogical07
461     },
462     {
463       "Mix of left to right and right to left text. Updates from character index 39",
464       "Hello world, مرحبا بالعالم, hello world\nمرحبا بالعالم, hello world, مرحبا بالعالم\nمرحبا بالعالم\nhello world",
465       39u,
466       107u,
467       Size( 100.f, 300.f ),
468       107u,
469       visualToLogical08
470     },
471     {
472       "Mix of left to right and right to left text. Updates from character index 70",
473       "Hello world, مرحبا بالعالم, hello world\nمرحبا بالعالم, hello world, مرحبا بالعالم\nمرحبا بالعالم\nhello world",
474       70u,
475       107u,
476       Size( 100.f, 300.f ),
477       107u,
478       visualToLogical09
479     }
480   };
481   const unsigned int numberOfTests = 9u;
482
483   for( unsigned int index = 0u; index < numberOfTests; ++index )
484   {
485     ToolkitTestApplication application;
486     if( !SetVisualToLogicalMapTest( data[index] ) )
487     {
488       tet_result(TET_FAIL);
489     }
490   }
491
492   tet_result(TET_PASS);
493   END_TEST;
494 }