Merge "Make to use DevelTexture::ApplyNativeFragmentShader in video-view" into devel...
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-toolkit-internal / utc-Dali-Text-Shaping.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 #include <stdlib.h>
20 #include <unistd.h>
21
22 #include <dali-toolkit/internal/text/shaper.h>
23 #include <dali-toolkit-test-suite-utils.h>
24 #include <dali-toolkit/dali-toolkit.h>
25 #include <toolkit-text-utils.h>
26
27 using namespace Dali;
28 using namespace Toolkit;
29 using namespace Text;
30
31 // Tests the following function.
32 // void ShapeText( const Vector<Character>& text,
33 //                 const Vector<LineBreakInfo>& lineBreakInfo,
34 //                 const Vector<ScriptRun>& scripts,
35 //                 const Vector<FontRun>& fonts,
36 //                 CharacterIndex startCharacterIndex,
37 //                 GlyphIndex startGlyphIndex,
38 //                 Length numberOfCharacters,
39 //                 Vector<GlyphInfo>& glyphs,
40 //                 Vector<CharacterIndex>& glyphToCharacterMap,
41 //                 Vector<Length>& charactersPerGlyph,
42 //                 Vector<GlyphIndex>& newParagraphGlyphs );
43
44 //////////////////////////////////////////////////////////
45
46 namespace
47 {
48 const std::string DEFAULT_FONT_DIR( "/resources/fonts" );
49
50 struct GlyphInfoData
51 {
52   FontId fontId;     ///< Identifies the font containing the glyph
53   GlyphIndex index;  ///< Uniquely identifies a glyph for a given FontId
54   float width;       ///< The width of the glyph
55   float height;      ///< The height of the glyph
56   float xBearing;    ///< The distance from the cursor position to the leftmost border of the glyph
57   float yBearing;    ///< The distance from the baseline to the topmost border of the glyph
58   float advance;     ///< The distance to move the cursor for this glyph
59   float scaleFactor; ///< The scaling applied (fixed-size fonts only)
60   bool isItalicRequired; ///< Whether the italic style is required.
61   bool isBoldRequired;   ///< Whether the bold style is required.
62 };
63
64 bool IsEqualGlyph ( const GlyphInfoData& glyphData, const GlyphInfo& glyph )
65 {
66   if( glyphData.fontId != glyph.fontId )
67   {
68     return false;
69   }
70   if( glyphData.index != glyph.index )
71   {
72     return false;
73   }
74   if( fabsf( glyphData.width - glyph.width ) > Math::MACHINE_EPSILON_1000 )
75   {
76     return false;
77   }
78   if( fabsf( glyphData.height - glyph.height ) > Math::MACHINE_EPSILON_1000 )
79   {
80     return false;
81   }
82   if( fabsf( glyphData.xBearing - glyph.xBearing ) > Math::MACHINE_EPSILON_1000 )
83   {
84     return false;
85   }
86   if( fabsf( glyphData.yBearing - glyph.yBearing ) > Math::MACHINE_EPSILON_1000 )
87   {
88     return false;
89   }
90   if( fabsf( glyphData.advance - floor(glyph.advance) ) > Math::MACHINE_EPSILON_1000 )
91   {
92     return false;
93   }
94   if( fabsf( glyphData.scaleFactor - glyph.scaleFactor ) > Math::MACHINE_EPSILON_1000 )
95   {
96     return false;
97   }
98   if( glyphData.isItalicRequired != glyph.isItalicRequired )
99   {
100     return false;
101   }
102   if( glyphData.isBoldRequired != glyph.isBoldRequired )
103   {
104     return false;
105   }
106
107   return true;
108 }
109
110 struct ShapeInfoData
111 {
112   std::string     description;                        ///< Description of the test.
113   std::string     text;                               ///< input text.
114   uint32_t        index;                              ///< The index from where to start to query the break info.
115   uint32_t        numberOfCharacters;                 ///< The requested number of characters.
116   uint32_t        expectedNumberOfGlyphs;             ///< The expected number of glyphs.
117   GlyphInfoData*  glyphs;                             ///< The glyphs.
118   CharacterIndex* characterIndices;                   ///< The character index for each glyph.
119   Length*         charactersPerGlyph;                 ///< The characters per glyph.
120   uint32_t        expectedNumberOfNewParagraphGlyphs; ///< The expected number of glyphs.
121   GlyphIndex*     newParagraphGlyphs;                 ///< Indices to the new paragraphs glyphs.
122   Vector<FontDescriptionRun> fontDescriptions;        ///< Fonts which is used for text.
123 };
124
125 bool ShapeInfoTest( const ShapeInfoData& data )
126 {
127   // 1) Create the model.
128   ModelPtr textModel;
129   MetricsPtr metrics;
130   Size textArea(100.f, 60.f);
131   Size layoutSize;
132
133   const Vector<FontDescriptionRun> fontDescriptions;
134   const LayoutOptions options;
135
136   CreateTextModel( data.text,
137                    textArea,
138                    data.fontDescriptions,
139                    options,
140                    layoutSize,
141                    textModel,
142                    metrics,
143                    false,
144                    LineWrap::WORD );
145
146   LogicalModelPtr logicalModel = textModel->mLogicalModel;
147   VisualModelPtr visualModel = textModel->mVisualModel;
148
149   // 2) Clear the model.
150
151   Vector<GlyphInfo>& glyphs = visualModel->mGlyphs;
152   Vector<CharacterIndex>& glyphToCharacter = visualModel->mGlyphsToCharacters;
153   Vector<Length>& charactersPerGlyph = visualModel->mCharactersPerGlyph;
154   Vector<GlyphIndex>& charactersToGlyph = visualModel->mCharactersToGlyph;
155   Vector<Length>& glyphsPerCharacter = visualModel->mGlyphsPerCharacter;
156
157   // Get the glyph index.
158   GlyphIndex glyphIndex = 0u;
159   if( 0u != visualModel->mCharactersToGlyph.Count() )
160   {
161     glyphIndex = *( visualModel->mCharactersToGlyph.Begin() + data.index );
162
163     const CharacterIndex lastCharacterIndex = data.index + data.numberOfCharacters - 1u;
164     const Length numberOfGlyphs = *( visualModel->mCharactersToGlyph.Begin() + lastCharacterIndex ) + *( visualModel->mGlyphsPerCharacter.Begin() + lastCharacterIndex ) - glyphIndex;
165
166     // Erase the glyph info from the text model.
167     // Got from the ShapeText() function.
168     glyphs.Erase( glyphs.Begin() + glyphIndex, glyphs.Begin() + glyphIndex + numberOfGlyphs );
169     glyphToCharacter.Erase( glyphToCharacter.Begin() + glyphIndex, glyphToCharacter.Begin() + glyphIndex + numberOfGlyphs );
170     charactersPerGlyph.Erase( charactersPerGlyph.Begin() + glyphIndex, charactersPerGlyph.Begin() + glyphIndex + numberOfGlyphs );
171
172     // Got from the VisualModel::CreateCharacterToGlyphTable() and the VisualModel::CreateGlyphsPerCharacterTable() methods.
173     charactersToGlyph.Erase( charactersToGlyph.Begin() + data.index,
174                              charactersToGlyph.Begin() + data.index + data.numberOfCharacters );
175     glyphsPerCharacter.Erase( glyphsPerCharacter.Begin() + data.index,
176                               glyphsPerCharacter.Begin() + data.index + data.numberOfCharacters );
177
178     // Update the glyph to character indices.
179     for( Vector<CharacterIndex>::Iterator it = glyphToCharacter.Begin() + glyphIndex,
180            endIt = glyphToCharacter.End();
181          it != endIt;
182          ++it )
183     {
184       CharacterIndex& index = *it;
185       index -= data.numberOfCharacters;
186     }
187
188   }
189
190   // Reset the metrics got from the model as the ShapeText() function doesn't retrieve them.
191   for( Vector<GlyphInfo>::Iterator it = glyphs.Begin(),
192          endIt = glyphs.End();
193        it != endIt;
194        ++it )
195   {
196     GlyphInfo& info = *it;
197     info.width = 0.f;
198     info.height = 0.f;
199     info.xBearing = 0.f;
200     info.yBearing = 0.f;
201     info.scaleFactor = 0.f;
202   }
203
204   // 3) Call the ShapeText() function.
205
206   Vector<GlyphIndex> newParagraphGlyphs;
207
208   ShapeText( logicalModel->mText,
209              logicalModel->mLineBreakInfo,
210              logicalModel->mScriptRuns,
211              logicalModel->mFontRuns,
212              data.index,
213              glyphIndex,
214              data.numberOfCharacters,
215              glyphs,
216              glyphToCharacter,
217              charactersPerGlyph,
218              newParagraphGlyphs );
219
220   // Clear the advance of the new paragraph glyphs.
221   for( Vector<GlyphIndex>::Iterator it = newParagraphGlyphs.Begin(),
222          endIt = newParagraphGlyphs.End();
223        it != endIt;
224        ++it )
225   {
226     GlyphInfo& info = *( glyphs.Begin() + *it );
227     info.advance = 0.f;
228   }
229
230   // 4) Compare the results.
231
232   if( data.expectedNumberOfGlyphs != glyphs.Count() )
233   {
234     std::cout << "  Different number of glyphs : " << glyphs.Count() << ", expected : " << data.expectedNumberOfGlyphs << std::endl;
235     return false;
236   }
237
238   for( unsigned int index = 0u; index < data.expectedNumberOfGlyphs; ++index )
239   {
240     if( !IsEqualGlyph( data.glyphs[index], glyphs[index] ) )
241     {
242       std::cout << "  different glyph info, index : " << index << std::endl;
243
244       const GlyphInfo& glyphInfo = glyphs[index];
245       std::cout << "            fontId : " << glyphInfo.fontId << std::endl;
246       std::cout << "             index : " << glyphInfo.index << std::endl;
247       std::cout << "             width : " << glyphInfo.width << std::endl;
248       std::cout << "            height : " << glyphInfo.height << std::endl;
249       std::cout << "          xBearing : " << glyphInfo.xBearing << std::endl;
250       std::cout << "          yBearing : " << glyphInfo.yBearing << std::endl;
251       std::cout << "           advance : " << floor(glyphInfo.advance) << std::endl;
252       std::cout << "       scaleFactor : " << glyphInfo.scaleFactor << std::endl;
253       std::cout << "  isItalicRequired : " << glyphInfo.isItalicRequired << std::endl;
254       std::cout << "    isBoldRequired : " << glyphInfo.isBoldRequired << std::endl;
255
256       std::cout << "  Expected : " << std::endl;
257       const GlyphInfoData& expectedGlyphInfo = data.glyphs[index];
258       std::cout << "            fontId : " << expectedGlyphInfo.fontId << std::endl;
259       std::cout << "             index : " << expectedGlyphInfo.index << std::endl;
260       std::cout << "             width : " << expectedGlyphInfo.width << std::endl;
261       std::cout << "            height : " << expectedGlyphInfo.height << std::endl;
262       std::cout << "          xBearing : " << expectedGlyphInfo.xBearing << std::endl;
263       std::cout << "          yBearing : " << expectedGlyphInfo.yBearing << std::endl;
264       std::cout << "           advance : " << expectedGlyphInfo.advance << std::endl;
265       std::cout << "       scaleFactor : " << expectedGlyphInfo.scaleFactor << std::endl;
266       std::cout << "  isItalicRequired : " << expectedGlyphInfo.isItalicRequired << std::endl;
267       std::cout << "    isBoldRequired : " << expectedGlyphInfo.isBoldRequired << std::endl;
268
269
270       return false;
271     }
272   }
273
274   for( unsigned int index = 0u; index < data.expectedNumberOfGlyphs; ++index )
275   {
276     if( data.characterIndices[index] != glyphToCharacter[index] )
277     {
278       std::cout << "  different character index, index : " << index << std::endl;
279       return false;
280     }
281   }
282
283   for( unsigned int index = 0u; index < data.expectedNumberOfGlyphs; ++index )
284   {
285     if( data.charactersPerGlyph[index] != charactersPerGlyph[index] )
286     {
287       std::cout << "  different character per glyph, index : " << index << std::endl;
288       return false;
289     }
290   }
291
292   if( data.expectedNumberOfNewParagraphGlyphs != newParagraphGlyphs.Count() )
293   {
294     std::cout << "  Different number of new paragraph glyphs : " << newParagraphGlyphs.Count() << ", expected : " << data.expectedNumberOfNewParagraphGlyphs << std::endl;
295     return false;
296   }
297
298   for( unsigned int index = 0u; index < data.expectedNumberOfNewParagraphGlyphs; ++index )
299   {
300     if( data.newParagraphGlyphs[index] != newParagraphGlyphs[index] )
301     {
302       std::cout << "  different new paragraph glyph, index : " << index << std::endl;
303       return false;
304     }
305   }
306
307   return true;
308 }
309
310 void LoadTextShapeFonts()
311 {
312   TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
313   fontClient.SetDpi( 96u, 96u );
314
315   char* pathNamePtr = get_current_dir_name();
316   const std::string pathName( pathNamePtr );
317   free( pathNamePtr );
318
319   fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/tizen/TizenSansRegular.ttf" );
320   fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/noto/NotoSansMalayalam-Regular.ttf" );
321 }
322
323 void LoadSoftwareStylingFonts()
324 {
325   TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
326   fontClient.SetDpi( 96u, 96u );
327
328   char* pathNamePtr = get_current_dir_name();
329   const std::string pathName( pathNamePtr );
330   free( pathNamePtr );
331
332   fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/roboto/Roboto-Regular.ttf" );
333   fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/roboto/Roboto-Bold.ttf" );
334   fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/roboto/Roboto-Italic.ttf" );
335   fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/roboto/Roboto-BoldItalic.ttf" );
336 }
337
338 } // namespace
339
340 //////////////////////////////////////////////////////////
341
342 int UtcDaliTextShape(void)
343 {
344   tet_infoline(" UtcDaliTextShape");
345
346   struct GlyphInfoData glyphs02[] =
347   {
348     { 1u, 276u, 0.f, 0.f, 0.f, 0.f, 11.f, 0.f },
349     { 1u, 299u, 0.f, 0.f, 0.f, 0.f,  8.f, 0.f },
350     { 1u, 306u, 0.f, 0.f, 0.f, 0.f,  4.f, 0.f },
351     { 1u, 306u, 0.f, 0.f, 0.f, 0.f,  4.f, 0.f },
352     { 1u, 309u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
353     { 1u,   3u, 0.f, 0.f, 0.f, 0.f,  4.f, 0.f },
354     { 1u, 317u, 0.f, 0.f, 0.f, 0.f, 11.f, 0.f },
355     { 1u, 309u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
356     { 1u, 312u, 0.f, 0.f, 0.f, 0.f,  6.f, 0.f },
357     { 1u, 306u, 0.f, 0.f, 0.f, 0.f,  4.f, 0.f },
358     { 1u, 298u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
359   };
360
361   CharacterIndex characterIndices02[] = { 0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 9u, 10u };
362   Length charactersPerGlyph02[] = { 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u };
363
364   struct GlyphInfoData glyphs03[] =
365   {
366     { 1u, 276u, 0.f, 0.f, 0.f, 0.f, 11.f, 0.f },
367     { 1u, 299u, 0.f, 0.f, 0.f, 0.f,  8.f, 0.f },
368     { 1u, 306u, 0.f, 0.f, 0.f, 0.f,  4.f, 0.f },
369     { 1u, 306u, 0.f, 0.f, 0.f, 0.f,  4.f, 0.f },
370     { 1u, 309u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
371     { 1u,   3u, 0.f, 0.f, 0.f, 0.f,  4.f, 0.f },
372     { 1u, 317u, 0.f, 0.f, 0.f, 0.f, 11.f, 0.f },
373     { 1u, 309u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
374     { 1u, 312u, 0.f, 0.f, 0.f, 0.f,  6.f, 0.f },
375     { 1u, 306u, 0.f, 0.f, 0.f, 0.f,  4.f, 0.f },
376     { 1u, 298u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
377     { 1u,   0u, 0.f, 0.f, 0.f, 0.f,  0.f, 0.f },
378     { 1u, 298u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
379     { 1u, 299u, 0.f, 0.f, 0.f, 0.f,  8.f, 0.f },
380     { 1u, 307u, 0.f, 0.f, 0.f, 0.f, 13.f, 0.f },
381     { 1u, 309u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
382     { 1u,   0u, 0.f, 0.f, 0.f, 0.f,  0.f, 0.f },
383   };
384
385   CharacterIndex characterIndices03[] = { 0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 9u, 10u, 11u, 12u, 13u, 14u, 15u, 16u };
386   Length charactersPerGlyph03[] = { 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u };
387   CharacterIndex newParagraphGlyphs03[] = { 11u, 16u };
388
389   struct GlyphInfoData glyphs04[] =
390   {
391     { 2u, 67u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
392     { 2u, 27u, 0.f, 0.f, 0.f, 0.f, 15.f, 0.f },
393     { 2u, 59u, 0.f, 0.f, 0.f, 0.f,  8.f, 0.f },
394     { 2u, 67u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
395     { 2u, 55u, 0.f, 0.f, 0.f, 0.f, 19.f, 0.f },
396     { 2u, 59u, 0.f, 0.f, 0.f, 0.f,  8.f, 0.f },
397     { 2u, 67u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
398     { 2u, 56u, 0.f, 0.f, 0.f, 0.f, 19.f, 0.f },
399     { 2u, 59u, 0.f, 0.f, 0.f, 0.f,  8.f, 0.f },
400     { 2u, 67u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
401     { 2u, 52u, 0.f, 0.f, 0.f, 0.f, 15.f, 0.f },
402     { 2u, 59u, 0.f, 0.f, 0.f, 0.f,  8.f, 0.f },
403   };
404
405   CharacterIndex characterIndices04[] = { 0u, 0u, 0u, 2u, 2u, 2u, 4u, 4u, 4u, 6u, 6u, 6u };
406   Length charactersPerGlyph04[] = { 0u, 0u, 2u, 0u, 0u, 2u, 0u, 0u, 2u, 0u, 0u, 2u };
407
408   struct GlyphInfoData glyphs05[] =
409   {
410     { 1u, 280u, 0.f, 0.f, 0.f, 0.f,  8.f, 0.f },
411     { 1u, 309u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
412     { 1u, 312u, 0.f, 0.f, 0.f, 0.f,  5.f, 0.f },
413     { 1u, 299u, 0.f, 0.f, 0.f, 0.f,  8.f, 0.f },
414     { 1u, 307u, 0.f, 0.f, 0.f, 0.f, 13.f, 0.f },
415     { 1u,  3u, 0.f, 0.f, 0.f, 0.f,  4.f, 0.f },
416     { 1u, 303u, 0.f, 0.f, 0.f, 0.f,  4.f, 0.f },
417     { 1u, 310u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
418     { 1u, 313u, 0.f, 0.f, 0.f, 0.f,  7.f, 0.f },
419     { 1u, 315u, 0.f, 0.f, 0.f, 0.f,  8.f, 0.f },
420     { 1u, 307u, 0.f, 0.f, 0.f, 0.f, 13.f, 0.f },
421     { 1u,  3u, 0.f, 0.f, 0.f, 0.f,  4.f, 0.f },
422     { 1u, 298u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
423     { 1u, 309u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
424     { 1u, 306u, 0.f, 0.f, 0.f, 0.f,  4.f, 0.f },
425     { 1u, 309u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
426     { 1u, 312u, 0.f, 0.f, 0.f, 0.f,  6.f, 0.f },
427     { 1u,  3u, 0.f, 0.f, 0.f, 0.f,  4.f, 0.f },
428     { 1u, 313u, 0.f, 0.f, 0.f, 0.f,  7.f, 0.f },
429     { 1u, 303u, 0.f, 0.f, 0.f, 0.f,  4.f, 0.f },
430     { 1u, 314u, 0.f, 0.f, 0.f, 0.f,  6.f, 0.f },
431     { 1u,  3u, 0.f, 0.f, 0.f, 0.f,  4.f, 0.f },
432     { 1u, 295u, 0.f, 0.f, 0.f, 0.f,  8.f, 0.f },
433     { 1u, 307u, 0.f, 0.f, 0.f, 0.f, 13.f, 0.f },
434     { 1u, 299u, 0.f, 0.f, 0.f, 0.f,  8.f, 0.f },
435     { 1u, 314u, 0.f, 0.f, 0.f, 0.f,  6.f, 0.f },
436     { 1u,  0u, 0.f, 0.f, 0.f, 0.f,  0.f, 0.f },
437     { 1u, 295u, 0.f, 0.f, 0.f, 0.f,  8.f, 0.f },
438     { 1u, 299u, 0.f, 0.f, 0.f, 0.f,  8.f, 0.f },
439     { 1u, 311u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
440     { 1u, 315u, 0.f, 0.f, 0.f, 0.f,  8.f, 0.f },
441     { 1u, 299u, 0.f, 0.f, 0.f, 0.f,  8.f, 0.f },
442     { 1u,  3u, 0.f, 0.f, 0.f, 0.f,  4.f, 0.f },
443     { 1u, 298u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
444     { 1u, 299u, 0.f, 0.f, 0.f, 0.f,  8.f, 0.f },
445     { 1u, 403u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
446     { 1u, 308u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
447     { 1u, 303u, 0.f, 0.f, 0.f, 0.f,  4.f, 0.f },
448     { 1u, 299u, 0.f, 0.f, 0.f, 0.f,  8.f, 0.f },
449     { 1u, 296u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
450     { 1u, 295u, 0.f, 0.f, 0.f, 0.f,  8.f, 0.f },
451     { 1u, 313u, 0.f, 0.f, 0.f, 0.f,  7.f, 0.f },
452     { 1u,  3u, 0.f, 0.f, 0.f, 0.f,  4.f, 0.f },
453     { 1u, 299u, 0.f, 0.f, 0.f, 0.f,  8.f, 0.f },
454     { 1u, 295u, 0.f, 0.f, 0.f, 0.f,  8.f, 0.f },
455     { 1u,  3u, 0.f, 0.f, 0.f, 0.f,  4.f, 0.f },
456     { 1u, 307u, 0.f, 0.f, 0.f, 0.f, 13.f, 0.f },
457     { 1u, 299u, 0.f, 0.f, 0.f, 0.f,  8.f, 0.f },
458     { 1u, 303u, 0.f, 0.f, 0.f, 0.f,  4.f, 0.f },
459     { 1u,  0u, 0.f, 0.f, 0.f, 0.f,  0.f, 0.f },
460     { 1u, 310u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
461     { 1u, 309u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
462     { 1u, 313u, 0.f, 0.f, 0.f, 0.f,  7.f, 0.f },
463     { 1u, 313u, 0.f, 0.f, 0.f, 0.f,  7.f, 0.f },
464     { 1u, 299u, 0.f, 0.f, 0.f, 0.f,  8.f, 0.f },
465     { 1u,  3u, 0.f, 0.f, 0.f, 0.f,  4.f, 0.f },
466     { 1u, 303u, 0.f, 0.f, 0.f, 0.f,  4.f, 0.f },
467     { 1u, 312u, 0.f, 0.f, 0.f, 0.f,  5.f, 0.f },
468     { 1u, 295u, 0.f, 0.f, 0.f, 0.f,  8.f, 0.f },
469     { 1u, 297u, 0.f, 0.f, 0.f, 0.f,  7.f, 0.f },
470     { 1u, 315u, 0.f, 0.f, 0.f, 0.f,  8.f, 0.f },
471     { 1u, 308u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
472     { 1u, 298u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
473     { 1u, 303u, 0.f, 0.f, 0.f, 0.f,  4.f, 0.f },
474     { 1u, 295u, 0.f, 0.f, 0.f, 0.f,  8.f, 0.f },
475     { 1u,  3u, 0.f, 0.f, 0.f, 0.f,  4.f, 0.f },
476     { 1u, 308u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
477     { 1u, 299u, 0.f, 0.f, 0.f, 0.f,  8.f, 0.f },
478     { 1u,  3u, 0.f, 0.f, 0.f, 0.f,  4.f, 0.f },
479     { 1u, 297u, 0.f, 0.f, 0.f, 0.f,  7.f, 0.f },
480     { 1u, 315u, 0.f, 0.f, 0.f, 0.f,  8.f, 0.f },
481     { 1u, 307u, 0.f, 0.f, 0.f, 0.f, 13.f, 0.f },
482     { 1u,  4u, 0.f, 0.f, 0.f, 0.f,  3.f, 0.f },
483     { 1u,  0u, 0.f, 0.f, 0.f, 0.f,  0.f, 0.f },
484   };
485
486   CharacterIndex characterIndices05[] = {  0u,  1u,  2u,  3u,  4u,  5u,  6u,  7u,  8u,  9u,
487                                           10u, 11u, 12u, 13u, 14u, 15u, 16u, 17u, 18u, 19u,
488                                           20u, 21u, 22u, 23u, 24u, 25u, 26u, 27u, 28u, 29u,
489                                           30u, 31u, 32u, 33u, 34u, 35u, 37u, 38u, 39u, 40u,
490                                           41u, 42u, 43u, 44u, 45u, 46u, 47u, 48u, 49u, 50u,
491                                           51u, 52u, 53u, 54u, 55u, 56u, 57u, 58u, 59u, 60u,
492                                           61u, 62u, 63u, 64u, 65u, 66u, 67u, 68u, 69u, 70u,
493                                           71u, 72u, 73u, 74u };
494   Length charactersPerGlyph05[] = { 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u,
495                                     1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u,
496                                     1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u,
497                                     1u, 1u, 1u, 1u, 1u, 2u, 1u, 1u, 1u, 1u,
498                                     1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u,
499                                     1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u,
500                                     1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u,
501                                     1u, 1u, 1u, 1u };
502   CharacterIndex newParagraphGlyphs05[] = { 26u };
503   CharacterIndex newParagraphGlyphs06[] = { 49u };
504   CharacterIndex newParagraphGlyphs07[] = { 73u };
505
506   Vector<FontDescriptionRun> fontDescriptions01;
507   Vector<FontDescriptionRun> fontDescriptions02;
508   Vector<FontDescriptionRun> fontDescriptions03;
509   Vector<FontDescriptionRun> fontDescriptions04;
510   Vector<FontDescriptionRun> fontDescriptions05;
511   Vector<FontDescriptionRun> fontDescriptions06;
512
513   const std::string fontFamily( "TizenSans" );
514   const std::string fontFamilyMalayalam( "Noto Sans Malayalam" );
515
516   FontDescriptionRun fontDescriptionRun01 =
517   {
518     {
519       0u,
520       11u
521     },
522     nullptr,
523     0u,
524     TextAbstraction::FontWeight::NONE,
525     TextAbstraction::FontWidth::NONE,
526     TextAbstraction::FontSlant::NONE,
527     TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
528     true,
529     false,
530     false,
531     false,
532     false
533   };
534   fontDescriptionRun01.familyLength = fontFamily.size();
535   fontDescriptionRun01.familyName = new char[fontDescriptionRun01.familyLength];
536   memcpy( fontDescriptionRun01.familyName, fontFamily.c_str(), fontDescriptionRun01.familyLength );
537
538   fontDescriptions01.PushBack( fontDescriptionRun01 );
539
540   FontDescriptionRun fontDescriptionRun02 =
541   {
542     {
543       0u,
544       17u
545     },
546     nullptr,
547     0u,
548     TextAbstraction::FontWeight::NONE,
549     TextAbstraction::FontWidth::NONE,
550     TextAbstraction::FontSlant::NONE,
551     TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
552     true,
553     false,
554     false,
555     false,
556     false
557   };
558   fontDescriptionRun02.familyLength = fontFamily.size();
559   fontDescriptionRun02.familyName = new char[fontDescriptionRun02.familyLength];
560   memcpy( fontDescriptionRun02.familyName, fontFamily.c_str(), fontDescriptionRun02.familyLength );
561
562   fontDescriptions02.PushBack( fontDescriptionRun02 );
563
564   FontDescriptionRun fontDescriptionRun03 =
565   {
566     {
567       0u,
568       8u
569     },
570     nullptr,
571     0u,
572     TextAbstraction::FontWeight::NONE,
573     TextAbstraction::FontWidth::NONE,
574     TextAbstraction::FontSlant::NONE,
575     TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
576     true,
577     false,
578     false,
579     false,
580     false
581   };
582   fontDescriptionRun03.familyLength = fontFamilyMalayalam.size();
583   fontDescriptionRun03.familyName = new char[fontDescriptionRun03.familyLength];
584   memcpy( fontDescriptionRun03.familyName, fontFamilyMalayalam.c_str(), fontDescriptionRun03.familyLength );
585
586   fontDescriptions03.PushBack( fontDescriptionRun03 );
587
588   FontDescriptionRun fontDescriptionRun04 =
589   {
590     {
591       0u,
592       75u
593     },
594     nullptr,
595     0u,
596     TextAbstraction::FontWeight::NONE,
597     TextAbstraction::FontWidth::NONE,
598     TextAbstraction::FontSlant::NONE,
599     TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
600     true,
601     false,
602     false,
603     false,
604     false
605   };
606   fontDescriptionRun04.familyLength = fontFamily.size();
607   fontDescriptionRun04.familyName = new char[fontDescriptionRun04.familyLength];
608   memcpy( fontDescriptionRun04.familyName, fontFamily.c_str(), fontDescriptionRun04.familyLength );
609
610   fontDescriptions04.PushBack( fontDescriptionRun04 );
611
612   FontDescriptionRun fontDescriptionRun05 =
613   {
614     {
615       0u,
616       75u
617     },
618     nullptr,
619     0u,
620     TextAbstraction::FontWeight::NONE,
621     TextAbstraction::FontWidth::NONE,
622     TextAbstraction::FontSlant::NONE,
623     TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
624     true,
625     false,
626     false,
627     false,
628     false
629   };
630   fontDescriptionRun05.familyLength = fontFamily.size();
631   fontDescriptionRun05.familyName = new char[fontDescriptionRun05.familyLength];
632   memcpy( fontDescriptionRun05.familyName, fontFamily.c_str(), fontDescriptionRun05.familyLength );
633
634   fontDescriptions05.PushBack( fontDescriptionRun05 );
635
636   FontDescriptionRun fontDescriptionRun06 =
637   {
638     {
639       0u,
640       75u
641     },
642     nullptr,
643     0u,
644     TextAbstraction::FontWeight::NONE,
645     TextAbstraction::FontWidth::NONE,
646     TextAbstraction::FontSlant::NONE,
647     TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
648     true,
649     false,
650     false,
651     false,
652     false
653   };
654   fontDescriptionRun06.familyLength = fontFamily.size();
655   fontDescriptionRun06.familyName = new char[fontDescriptionRun06.familyLength];
656   memcpy( fontDescriptionRun06.familyName, fontFamily.c_str(), fontDescriptionRun06.familyLength );
657
658   fontDescriptions06.PushBack( fontDescriptionRun06 );
659
660   struct ShapeInfoData data[] =
661   {
662     {
663       "Zero characters",
664       "",
665       0u,
666       0u,
667       0u,
668       nullptr,
669       nullptr,
670       nullptr,
671       0u,
672       nullptr
673     },
674     {
675       "Latin script",
676       "Hello world",
677       0u,
678       11u,
679       11u,
680       glyphs02,
681       characterIndices02,
682       charactersPerGlyph02,
683       0u,
684       nullptr,
685       fontDescriptions01
686     },
687     {
688       "Latin script. Some paragraphs.",
689       "Hello world\ndemo\n",
690       0u,
691       17u,
692       17u,
693       glyphs03,
694       characterIndices03,
695       charactersPerGlyph03,
696       2u,
697       newParagraphGlyphs03,
698       fontDescriptions02
699     },
700     {
701       "Malayalam script. More glyphs than characters.",
702       "ജോസോഹോവോ",
703       0u,
704       8u,
705       12u,
706       glyphs04,
707       characterIndices04,
708       charactersPerGlyph04,
709       0u,
710       nullptr,
711       fontDescriptions03
712     },
713     {
714       "Latin script with some paragraphs. Update initial paragraph.",
715       "Lorem ipsum dolor sit amet\naeque definiebas ea mei\nposse iracundia ne cum.\n",
716       0u,
717       27u,
718       74u,
719       glyphs05,
720       characterIndices05,
721       charactersPerGlyph05,
722       1u,
723       newParagraphGlyphs05,
724       fontDescriptions04
725     },
726     {
727       "Latin script with some paragraphs. Update mid paragraph.",
728       "Lorem ipsum dolor sit amet\naeque definiebas ea mei\nposse iracundia ne cum.\n",
729       27u,
730       24u,
731       74u,
732       glyphs05,
733       characterIndices05,
734       charactersPerGlyph05,
735       1u,
736       newParagraphGlyphs06,
737       fontDescriptions05
738     },
739     {
740       "Latin script with some paragraphs. Update final paragraph.",
741       "Lorem ipsum dolor sit amet\naeque definiebas ea mei\nposse iracundia ne cum.\n",
742       51u,
743       24u,
744       74u,
745       glyphs05,
746       characterIndices05,
747       charactersPerGlyph05,
748       1u,
749       newParagraphGlyphs07,
750       fontDescriptions06
751     },
752   };
753   const unsigned int numberOfTests = 7u;
754
755   for( unsigned int index = 0u; index < numberOfTests; ++index )
756   {
757     ToolkitTestApplication application;
758     LoadTextShapeFonts();
759
760     if( !ShapeInfoTest( data[index] ) )
761     {
762       tet_result(TET_FAIL);
763     }
764   }
765
766   tet_result(TET_PASS);
767   END_TEST;
768 }
769
770 int UtcDaliTextSoftwareStyling(void)
771 {
772   tet_infoline(" UtcDaliTextSoftwareStyling");
773
774   struct GlyphInfoData glyphs01[] =
775   {
776     { 4u, 38u, 0.f, 0.f, 0.f, 0.f, 10.f, 0.f, true, true },
777     { 4u, 39u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f, true, true },
778     { 4u, 40u, 0.f, 0.f, 0.f, 0.f, 10.f, 0.f, true, true },
779     { 4u, 41u, 0.f, 0.f, 0.f, 0.f, 10.f, 0.f, true, true },
780   };
781   struct GlyphInfoData glyphs02[] =
782   {
783     { 1u, 38u, 0.f, 0.f, 0.f, 0.f, 10.f, 0.f, false, false },
784     { 2u, 39u, 0.f, 0.f, 0.f, 0.f, 10.f, 0.f, false,  true },
785     { 3u, 40u, 0.f, 0.f, 0.f, 0.f, 10.f, 0.f, true,  false },
786     { 4u, 41u, 0.f, 0.f, 0.f, 0.f, 10.f, 0.f, true,   true },
787   };
788
789   CharacterIndex characterIndices[] = { 0u, 1u, 2u, 3u };
790   Length charactersPerGlyph[] = { 1u, 1u, 1u, 1u };
791
792   Vector<FontDescriptionRun> fontDescriptions01;
793   Vector<FontDescriptionRun> fontDescriptions02;
794
795   const std::string fontFamily( "Roboto" );
796
797   FontDescriptionRun fontDescriptionRun01 =
798   {
799     {
800       0u,
801       4u
802     },
803     nullptr,
804     0u,
805     TextAbstraction::FontWeight::BOLD,
806     TextAbstraction::FontWidth::NONE,
807     TextAbstraction::FontSlant::ITALIC,
808     TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
809     true,
810     true,
811     false,
812     true,
813     false
814   };
815   fontDescriptionRun01.familyLength = fontFamily.size();
816   fontDescriptionRun01.familyName = new char[fontDescriptionRun01.familyLength];
817   memcpy( fontDescriptionRun01.familyName, fontFamily.c_str(), fontDescriptionRun01.familyLength );
818
819   fontDescriptions01.PushBack(fontDescriptionRun01);
820
821   FontDescriptionRun fontDescriptionRun02 =
822   {
823     {
824       0u,
825       1u
826     },
827     nullptr,
828     0u,
829     TextAbstraction::FontWeight::NONE,
830     TextAbstraction::FontWidth::NONE,
831     TextAbstraction::FontSlant::NONE,
832     TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
833     true,
834     false,
835     false,
836     false,
837     false
838   };
839   fontDescriptionRun02.familyLength = fontFamily.size();
840   fontDescriptionRun02.familyName = new char[fontDescriptionRun02.familyLength];
841   memcpy( fontDescriptionRun02.familyName, fontFamily.c_str(), fontDescriptionRun02.familyLength );
842
843   FontDescriptionRun fontDescriptionRun03 =
844   {
845     {
846       1u,
847       1u
848     },
849     nullptr,
850     0u,
851     TextAbstraction::FontWeight::BOLD,
852     TextAbstraction::FontWidth::NONE,
853     TextAbstraction::FontSlant::NONE,
854     TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
855     true,
856     true,
857     false,
858     false,
859     false
860   };
861   fontDescriptionRun03.familyLength = fontFamily.size();
862   fontDescriptionRun03.familyName = new char[fontDescriptionRun03.familyLength];
863   memcpy( fontDescriptionRun03.familyName, fontFamily.c_str(), fontDescriptionRun03.familyLength );
864
865   FontDescriptionRun fontDescriptionRun04 =
866   {
867     {
868       2u,
869       1u
870     },
871     nullptr,
872     0u,
873     TextAbstraction::FontWeight::NONE,
874     TextAbstraction::FontWidth::NONE,
875     TextAbstraction::FontSlant::ITALIC,
876     TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
877     true,
878     false,
879     false,
880     true,
881     false
882   };
883   fontDescriptionRun04.familyLength = fontFamily.size();
884   fontDescriptionRun04.familyName = new char[fontDescriptionRun04.familyLength];
885   memcpy( fontDescriptionRun04.familyName, fontFamily.c_str(), fontDescriptionRun04.familyLength );
886
887   FontDescriptionRun fontDescriptionRun05 =
888   {
889     {
890       3u,
891       1u
892     },
893     nullptr,
894     0u,
895     TextAbstraction::FontWeight::BOLD,
896     TextAbstraction::FontWidth::NONE,
897     TextAbstraction::FontSlant::ITALIC,
898     TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
899     true,
900     true,
901     false,
902     true,
903     false
904   };
905   fontDescriptionRun05.familyLength = fontFamily.size();
906   fontDescriptionRun05.familyName = new char[fontDescriptionRun05.familyLength];
907   memcpy( fontDescriptionRun05.familyName, fontFamily.c_str(), fontDescriptionRun05.familyLength );
908
909   fontDescriptions02.PushBack(fontDescriptionRun02);
910   fontDescriptions02.PushBack(fontDescriptionRun03);
911   fontDescriptions02.PushBack(fontDescriptionRun04);
912   fontDescriptions02.PushBack(fontDescriptionRun05);
913
914
915   struct ShapeInfoData data[] =
916   {
917     {
918       "Latin script. Characters have same font description",
919       "ABCD",
920       0u,
921       4u,
922       4u,
923       glyphs01,
924       characterIndices,
925       charactersPerGlyph,
926       0u,
927       nullptr,
928       fontDescriptions01
929     },
930     {
931       "Latin script. Each character has different font description.",
932       "ABCD",
933       0u,
934       4u,
935       4u,
936       glyphs02,
937       characterIndices,
938       charactersPerGlyph,
939       0u,
940       nullptr,
941       fontDescriptions02
942     }
943   };
944
945   const unsigned int numberOfTests = 2u;
946
947   for( unsigned int index = 0u; index < numberOfTests; ++index )
948   {
949     ToolkitTestApplication application;
950     LoadSoftwareStylingFonts();
951
952     if( !ShapeInfoTest( data[index] ) )
953     {
954       tet_result(TET_FAIL);
955     }
956   }
957
958   tet_result(TET_PASS);
959   END_TEST;
960 }