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