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