[dali_2.3.19] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-toolkit-internal / utc-Dali-VisualModel.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/dali-toolkit.h>
24 #include <toolkit-text-utils.h>
25
26
27 using namespace Dali;
28 using namespace Toolkit;
29 using namespace Text;
30
31 // Tests the following functions.
32 //
33 // void CreateCharacterToGlyphTable( CharacterIndex startIndex,
34 //                                   Length numberOfCharacters )
35 //
36 // void CreateGlyphsPerCharacterTable( CharacterIndex startIndex,
37 //                                     Length numberOfCharacters )
38
39
40 //////////////////////////////////////////////////////////
41
42 namespace
43 {
44
45 struct SetGlyphsPerCharacterData
46 {
47   std::string   description;             ///< Description of the test.
48   std::string   text;                    ///< Input text.
49   unsigned int  startIndex;              ///< The start index from where the glyphs per character table is set.
50   unsigned int  numberOfCharacters;      ///< The number of characters to set.
51   unsigned int  totalNumberOfCharacters; ///< The total number of characters.
52   unsigned int* glyphsPerCharacter;      ///< The number of glyphs per character.
53 };
54
55 struct SetCharacterToGlyphData
56 {
57   std::string   description;             ///< Description of the test.
58   std::string   text;                    ///< Input text.
59   unsigned int  startIndex;              ///< The start index from where the character to glyph table is set.
60   unsigned int  numberOfCharacters;      ///< The number of characters to set.
61   unsigned int  totalNumberOfCharacters; ///< The total number of characters.
62   unsigned int* glyphsIndices;           ///< The glyph indices.
63 };
64
65 bool SetGlyphsPerCharacterTest( const SetGlyphsPerCharacterData& data )
66 {
67   // 1) Create the model.
68   ModelPtr textModel;
69   MetricsPtr metrics;
70   Size textArea(100.f, 60.f);
71   Size layoutSize;
72
73   const Vector<FontDescriptionRun> fontDescriptions;
74   const LayoutOptions options;
75   CreateTextModel( data.text,
76                    textArea,
77                    fontDescriptions,
78                    options,
79                    layoutSize,
80                    textModel,
81                    metrics,
82                    false );
83
84   LogicalModelPtr logicalModel = textModel->mLogicalModel;
85   VisualModelPtr visualModel = textModel->mVisualModel;
86
87   Vector<GlyphIndex>& charactersToGlyph = visualModel->mCharactersToGlyph;
88   Vector<Length>& glyphsPerCharacter = visualModel->mGlyphsPerCharacter;
89
90   // 2) Clear the model.
91
92   GlyphIndex startGlyphIndex = 0u;
93   if( 0u != charactersToGlyph.Count() )
94   {
95     // The number of glyphs to be removed.
96     const Length numberOfGlyphs = charactersToGlyph[data.startIndex + data.numberOfCharacters - 1u] + glyphsPerCharacter[data.startIndex + data.numberOfCharacters - 1u] - charactersToGlyph[data.startIndex];
97     startGlyphIndex = charactersToGlyph[data.startIndex];
98
99     charactersToGlyph.Erase( charactersToGlyph.Begin() + data.startIndex,
100                              charactersToGlyph.Begin() + data.startIndex + data.numberOfCharacters );
101     glyphsPerCharacter.Erase( glyphsPerCharacter.Begin() + data.startIndex,
102                               glyphsPerCharacter.Begin() + data.startIndex + data.numberOfCharacters );
103
104     // Update the character to glyph indices.
105     for( Vector<GlyphIndex>::Iterator it = charactersToGlyph.Begin() + data.startIndex,
106            endIt = charactersToGlyph.End();
107          it != endIt;
108          ++it )
109     {
110       *it -= numberOfGlyphs;
111     }
112   }
113
114   // 3) Call the CreateGlyphsPerCharacterTable() function
115   visualModel->CreateGlyphsPerCharacterTable( data.startIndex,
116                                               startGlyphIndex,
117                                               data.numberOfCharacters );
118
119   // 4) Compare the results.
120   if( data.totalNumberOfCharacters != glyphsPerCharacter.Count() )
121   {
122     std::cout << "  Different number of characters : " << glyphsPerCharacter.Count() << ", expected : " << data.totalNumberOfCharacters << std::endl;
123     return false;
124   }
125
126   for( unsigned int i = 0u; i < data.totalNumberOfCharacters; ++i )
127   {
128     if( data.glyphsPerCharacter[i] != glyphsPerCharacter[i] )
129     {
130       std::cout << "  Different number of glyphs for index " << i << std::endl;
131       for( unsigned int j = 0; j < data.totalNumberOfCharacters; ++j )
132       {
133         std::cout << glyphsPerCharacter[j] << " ";
134       }
135       std::cout << std::endl;
136       std::cout << "  expected" << std::endl;
137       for( unsigned int j = 0; j < data.totalNumberOfCharacters; ++j )
138       {
139         std::cout << data.glyphsPerCharacter[j] << " ";
140       }
141       std::cout << std::endl;
142       return false;
143     }
144   }
145
146   return true;
147 }
148
149 bool SetCharacterToGlyphTest( const SetCharacterToGlyphData& data )
150 {
151   // 1) Create the model.
152   ModelPtr textModel;
153   MetricsPtr metrics;
154   Size textArea(100.f, 60.f);
155   Size layoutSize;
156
157   const Vector<FontDescriptionRun> fontDescriptions;
158   const LayoutOptions options;
159   CreateTextModel( data.text,
160                    textArea,
161                    fontDescriptions,
162                    options,
163                    layoutSize,
164                    textModel,
165                    metrics,
166                    false );
167
168   LogicalModelPtr logicalModel = textModel->mLogicalModel;
169   VisualModelPtr visualModel = textModel->mVisualModel;
170
171   Vector<GlyphIndex>& charactersToGlyph = visualModel->mCharactersToGlyph;
172   Vector<Length>& glyphsPerCharacter = visualModel->mGlyphsPerCharacter;
173
174   // 2) Clear the model.
175
176   GlyphIndex startGlyphIndex = 0u;
177   if( 0u != charactersToGlyph.Count() )
178   {
179     // The number of glyphs to be removed.
180     const Length numberOfGlyphs = charactersToGlyph[data.startIndex + data.numberOfCharacters - 1u] + glyphsPerCharacter[data.startIndex + data.numberOfCharacters - 1u] - charactersToGlyph[data.startIndex];
181     startGlyphIndex = charactersToGlyph[data.startIndex];
182
183     charactersToGlyph.Erase( charactersToGlyph.Begin() + data.startIndex,
184                              charactersToGlyph.Begin() + data.startIndex + data.numberOfCharacters );
185
186     // Update the character to glyph indices.
187     for( Vector<GlyphIndex>::Iterator it = charactersToGlyph.Begin() + data.startIndex,
188            endIt = charactersToGlyph.End();
189          it != endIt;
190          ++it )
191     {
192       *it -= numberOfGlyphs;
193     }
194   }
195
196   // 3) Call the CreateCharacterToGlyphTable() function
197   visualModel->CreateCharacterToGlyphTable( data.startIndex,
198                                             startGlyphIndex,
199                                             data.numberOfCharacters );
200
201   // 4) Compare the results.
202   if( data.totalNumberOfCharacters != charactersToGlyph.Count() )
203   {
204     std::cout << "  Different number of character : " << charactersToGlyph.Count() << ", expected : " << data.totalNumberOfCharacters << std::endl;
205     return false;
206   }
207
208   for( unsigned int i = 0u; i < data.totalNumberOfCharacters; ++i )
209   {
210     if( data.glyphsIndices[i] != charactersToGlyph[i] )
211     {
212       std::cout << "  Different number of character to glyph index " << i << std::endl;
213       for( unsigned int j = 0; j < data.totalNumberOfCharacters; ++j )
214       {
215         std::cout << charactersToGlyph[j] << " ";
216       }
217       std::cout << std::endl;
218       std::cout << "  expected" << std::endl;
219       for( unsigned int j = 0; j < data.totalNumberOfCharacters; ++j )
220       {
221         std::cout << data.glyphsIndices[j] << " ";
222       }
223       std::cout << std::endl;
224       return false;
225     }
226   }
227
228   return true;
229 }
230
231 } // namespace
232
233 //////////////////////////////////////////////////////////
234
235 int UtcDaliSetGlyphsPerCharacter(void)
236 {
237   tet_infoline(" UtcDaliSetGlyphsPerCharacter");
238
239   Length glyphsPerCharacter02[] = { 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u };
240   Length glyphsPerCharacter03[] = { 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 0u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u };
241   Length glyphsPerCharacter04[] = { 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 0u, 1u,
242                                     1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u,
243                                     1u, 1u, 1u, 1u, 0u, 1u, 0u, 2u, 1u, 0u,
244                                     2u, 0u, 2u, 0u, 2u, 1u, 1u, 0u, 0u, 0u,
245                                     2u, 1u, 1u, 1u, 1u, 1u, 0u, 0u, 2u, 1u,
246                                     0u, 2u, 1u, 1u };
247
248   struct SetGlyphsPerCharacterData data[] =
249   {
250     {
251       "Zero characters text",
252       "",
253       0u,
254       0u,
255       0u,
256       NULL
257     },
258     {
259       "Simple 1 to 1 text",
260       "Hello world",
261       0u,
262       11u,
263       11u,
264       glyphsPerCharacter02,
265     },
266     {
267       "Text with different number of glyphs and characters.",
268       "Hello different world",
269       0u,
270       21u,
271       21u,
272       glyphsPerCharacter03,
273     },
274     {
275       "Text paragraphs with different number of glyphs and characters. Update initial paragraphs.",
276       "Hello different world\nनमस्ते दुनिया\nမင်္ဂလာပါကမ္ဘာလောက",
277       0u,
278       22u,
279       54u,
280       glyphsPerCharacter04,
281     },
282     {
283       "Text paragraphs with different number of glyphs and characters. Update mid paragraphs.",
284       "Hello different world\nनमस्ते दुनिया\nမင်္ဂလာပါကမ္ဘာလောက",
285       22u,
286       14u,
287       54u,
288       glyphsPerCharacter04,
289     },
290     {
291       "Text paragraphs with different number of glyphs and characters. Update final paragraphs.",
292       "Hello different world\nनमस्ते दुनिया\nမင်္ဂလာပါကမ္ဘာလောက",
293       36u,
294       18u,
295       54u,
296       glyphsPerCharacter04,
297     },
298   };
299   const unsigned int numberOfTests = 6u;
300
301   for( unsigned int index = 0u; index < numberOfTests; ++index )
302   {
303     ToolkitTestApplication application;
304     if( !SetGlyphsPerCharacterTest( data[index] ) )
305     {
306       tet_result(TET_FAIL);
307     }
308   }
309
310   tet_result(TET_PASS);
311   END_TEST;
312 }
313
314 int UtcDaliSetCharacterToGlyph(void)
315 {
316   tet_infoline(" UtcDaliSetGlyphsPerCharacter");
317
318   GlyphIndex glyphIndices02[] = { 0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 9u, 10u };
319   GlyphIndex glyphIndices03[] = { 0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 8u, 9u, 10u, 11u, 12u, 13u, 14u, 15u, 16u, 17u, 18u, 19u };
320   GlyphIndex glyphIndices04[] = { 0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 8u, 9u, 10u, 11u, 12u, 13u, 14u, 15u, 16u, 17u, 18u, 19u, 20u,
321                                   21u, 22u, 23u, 23u, 24u, 24u, 26u, 27u, 27u, 29u, 29u, 31u, 31u, 33u,
322                                   34u, 35u, 35u, 35u, 35u, 37u, 38u, 39u, 40u, 41u, 42u, 42u, 42u, 44u, 45u, 45u, 47u, 48u };
323
324   struct SetCharacterToGlyphData data[] =
325   {
326     {
327       "Zero characters text",
328       "",
329       0u,
330       0u,
331       0u,
332       NULL
333     },
334     {
335       "Simple 1 to 1 text",
336       "Hello world",
337       0u,
338       11u,
339       11u,
340       glyphIndices02,
341     },
342     {
343       "Text with different number of glyphs and characters.",
344       "Hello different world",
345       0u,
346       21u,
347       21u,
348       glyphIndices03,
349     },
350     {
351       "Text paragraphs with different number of glyphs and characters. Update initial paragraphs.",
352       "Hello different world\nनमस्ते दुनिया\nမင်္ဂလာပါကမ္ဘာလောက",
353       0u,
354       22u,
355       54u,
356       glyphIndices04,
357     },
358     {
359       "Text paragraphs with different number of glyphs and characters. Update mid paragraphs.",
360       "Hello different world\nनमस्ते दुनिया\nမင်္ဂလာပါကမ္ဘာလောက",
361       22u,
362       14u,
363       54u,
364       glyphIndices04,
365     },
366     {
367       "Text paragraphs with different number of glyphs and characters. Update final paragraphs.",
368       "Hello different world\nनमस्ते दुनिया\nမင်္ဂလာပါကမ္ဘာလောက",
369       36u,
370       18u,
371       54u,
372       glyphIndices04,
373     },
374   };
375
376   const unsigned int numberOfTests = 6u;
377
378   for( unsigned int index = 0u; index < numberOfTests; ++index )
379   {
380     ToolkitTestApplication application;
381     if( !SetCharacterToGlyphTest( data[index] ) )
382     {
383       tet_result(TET_FAIL);
384     }
385   }
386
387   tet_result(TET_PASS);
388   END_TEST;
389 }