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