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