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