[dali_1.3.36] 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) 2016 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 #include <iostream>
19 #include <stdlib.h>
20
21 #include <dali-toolkit/internal/text/shaper.h>
22 #include <dali-toolkit-test-suite-utils.h>
23 #include <dali-toolkit/dali-toolkit.h>
24 #include <toolkit-text-utils.h>
25
26 using namespace Dali;
27 using namespace Toolkit;
28 using namespace Text;
29
30 // Tests the following function.
31 // void ShapeText( const Vector<Character>& text,
32 //                 const Vector<LineBreakInfo>& lineBreakInfo,
33 //                 const Vector<ScriptRun>& scripts,
34 //                 const Vector<FontRun>& fonts,
35 //                 CharacterIndex startCharacterIndex,
36 //                 GlyphIndex startGlyphIndex,
37 //                 Length numberOfCharacters,
38 //                 Vector<GlyphInfo>& glyphs,
39 //                 Vector<CharacterIndex>& glyphToCharacterMap,
40 //                 Vector<Length>& charactersPerGlyph,
41 //                 Vector<GlyphIndex>& newParagraphGlyphs );
42
43 //////////////////////////////////////////////////////////
44
45 namespace
46 {
47
48 struct GlyphInfoData
49 {
50   FontId fontId;     ///< Identifies the font containing the glyph
51   GlyphIndex index;  ///< Uniquely identifies a glyph for a given FontId
52   float width;       ///< The width of the glyph
53   float height;      ///< The height of the glyph
54   float xBearing;    ///< The distance from the cursor position to the leftmost border of the glyph
55   float yBearing;    ///< The distance from the baseline to the topmost border of the glyph
56   float advance;     ///< The distance to move the cursor for this glyph
57   float scaleFactor; ///< The scaling applied (fixed-size fonts only)
58   bool softwareItalic; ///< Whether glyph needs software support to draw italic style
59   bool softwareBold;   ///< Whether glyph needs software support to draw bold style
60 };
61
62 bool IsEqualGlyph ( const GlyphInfoData& glyphData, const GlyphInfo& glyph )
63 {
64   if( glyphData.fontId != glyph.fontId )
65   {
66     return false;
67   }
68   if( glyphData.index != glyph.index )
69   {
70     return false;
71   }
72   if( fabsf( glyphData.width - glyph.width ) > Math::MACHINE_EPSILON_1000 )
73   {
74     return false;
75   }
76   if( fabsf( glyphData.height - glyph.height ) > Math::MACHINE_EPSILON_1000 )
77   {
78     return false;
79   }
80   if( fabsf( glyphData.xBearing - glyph.xBearing ) > Math::MACHINE_EPSILON_1000 )
81   {
82     return false;
83   }
84   if( fabsf( glyphData.yBearing - glyph.yBearing ) > Math::MACHINE_EPSILON_1000 )
85   {
86     return false;
87   }
88   if( fabsf( glyphData.advance - glyph.advance ) > Math::MACHINE_EPSILON_1000 )
89   {
90     return false;
91   }
92   if( fabsf( glyphData.scaleFactor - glyph.scaleFactor ) > Math::MACHINE_EPSILON_1000 )
93   {
94     return false;
95   }
96   if( glyphData.softwareItalic != glyph.softwareItalic )
97   {
98     return false;
99   }
100   if( glyphData.softwareBold != glyph.softwareBold )
101   {
102     return false;
103   }
104
105   return true;
106 }
107
108 struct ShapeInfoData
109 {
110   std::string     description;                        ///< Description of the test.
111   std::string     text;                               ///< input text.
112   uint32_t        index;                              ///< The index from where to start to query the break info.
113   uint32_t        numberOfCharacters;                 ///< The requested number of characters.
114   uint32_t        expectedNumberOfGlyphs;             ///< The expected number of glyphs.
115   GlyphInfoData*  glyphs;                             ///< The glyphs.
116   CharacterIndex* characterIndices;                   ///< The character index for each glyph.
117   Length*         charactersPerGlyph;                 ///< The characters per glyph.
118   uint32_t        expectedNumberOfNewParagraphGlyphs; ///< The expected number of glyphs.
119   GlyphIndex*     newParagraphGlyphs;                 ///< Indices to the new paragraphs glyphs.
120   Vector<FontDescriptionRun> fontDescriptions;        ///< Fonts which is used for text.
121 };
122
123 bool ShapeInfoTest( const ShapeInfoData& data )
124 {
125   // 1) Create the model.
126   LogicalModelPtr logicalModel;
127   VisualModelPtr visualModel;
128   MetricsPtr metrics;
129   Size textArea(100.f, 60.f);
130   Size layoutSize;
131
132   const Vector<FontDescriptionRun> fontDescriptions;
133   const LayoutOptions options;
134   CreateTextModel( data.text,
135                    textArea,
136                    data.fontDescriptions,
137                    options,
138                    layoutSize,
139                    logicalModel,
140                    visualModel,
141                    metrics );
142
143   // 2) Clear the model.
144
145   Vector<GlyphInfo>& glyphs = visualModel->mGlyphs;
146   Vector<CharacterIndex>& glyphToCharacter = visualModel->mGlyphsToCharacters;
147   Vector<Length>& charactersPerGlyph = visualModel->mCharactersPerGlyph;
148   Vector<GlyphIndex>& charactersToGlyph = visualModel->mCharactersToGlyph;
149   Vector<Length>& glyphsPerCharacter = visualModel->mGlyphsPerCharacter;
150
151   // Get the glyph index.
152   GlyphIndex glyphIndex = 0u;
153   if( 0u != visualModel->mCharactersToGlyph.Count() )
154   {
155     glyphIndex = *( visualModel->mCharactersToGlyph.Begin() + data.index );
156
157     const CharacterIndex lastCharacterIndex = data.index + data.numberOfCharacters - 1u;
158     const Length numberOfGlyphs = *( visualModel->mCharactersToGlyph.Begin() + lastCharacterIndex ) + *( visualModel->mGlyphsPerCharacter.Begin() + lastCharacterIndex ) - glyphIndex;
159
160     // Erase the glyph info from the text model.
161     // Got from the ShapeText() function.
162     glyphs.Erase( glyphs.Begin() + glyphIndex, glyphs.Begin() + glyphIndex + numberOfGlyphs );
163     glyphToCharacter.Erase( glyphToCharacter.Begin() + glyphIndex, glyphToCharacter.Begin() + glyphIndex + numberOfGlyphs );
164     charactersPerGlyph.Erase( charactersPerGlyph.Begin() + glyphIndex, charactersPerGlyph.Begin() + glyphIndex + numberOfGlyphs );
165
166     // Got from the VisualModel::CreateCharacterToGlyphTable() and the VisualModel::CreateGlyphsPerCharacterTable() methods.
167     charactersToGlyph.Erase( charactersToGlyph.Begin() + data.index,
168                              charactersToGlyph.Begin() + data.index + data.numberOfCharacters );
169     glyphsPerCharacter.Erase( glyphsPerCharacter.Begin() + data.index,
170                               glyphsPerCharacter.Begin() + data.index + data.numberOfCharacters );
171
172     // Update the glyph to character indices.
173     for( Vector<CharacterIndex>::Iterator it = glyphToCharacter.Begin() + glyphIndex,
174            endIt = glyphToCharacter.End();
175          it != endIt;
176          ++it )
177     {
178       CharacterIndex& index = *it;
179       index -= data.numberOfCharacters;
180     }
181
182   }
183
184   // Reset the metrics got from the model as the ShapeText() function doesn't retrieve them.
185   for( Vector<GlyphInfo>::Iterator it = glyphs.Begin(),
186          endIt = glyphs.End();
187        it != endIt;
188        ++it )
189   {
190     GlyphInfo& info = *it;
191     info.width = 0.f;
192     info.height = 0.f;
193     info.xBearing = 0.f;
194     info.yBearing = 0.f;
195     info.scaleFactor = 0.f;
196   }
197
198   // 3) Call the ShapeText() function.
199
200   Vector<GlyphIndex> newParagraphGlyphs;
201
202   ShapeText( logicalModel->mText,
203              logicalModel->mLineBreakInfo,
204              logicalModel->mScriptRuns,
205              logicalModel->mFontRuns,
206              data.index,
207              glyphIndex,
208              data.numberOfCharacters,
209              glyphs,
210              glyphToCharacter,
211              charactersPerGlyph,
212              newParagraphGlyphs );
213
214   // Clear the advance of the new paragraph glyphs.
215   for( Vector<GlyphIndex>::Iterator it = newParagraphGlyphs.Begin(),
216          endIt = newParagraphGlyphs.End();
217        it != endIt;
218        ++it )
219   {
220     GlyphInfo& info = *( glyphs.Begin() + *it );
221     info.advance = 0.f;
222   }
223
224   // 4) Compare the results.
225
226   if( data.expectedNumberOfGlyphs != glyphs.Count() )
227   {
228     std::cout << "  Different number of glyphs : " << glyphs.Count() << ", expected : " << data.expectedNumberOfGlyphs << std::endl;
229     return false;
230   }
231
232   for( unsigned int index = 0u; index < data.expectedNumberOfGlyphs; ++index )
233   {
234     if( !IsEqualGlyph( data.glyphs[index], glyphs[index] ) )
235     {
236       std::cout << "  different glyph info, index : " << index << std::endl;
237       return false;
238     }
239   }
240
241   for( unsigned int index = 0u; index < data.expectedNumberOfGlyphs; ++index )
242   {
243     if( data.characterIndices[index] != glyphToCharacter[index] )
244     {
245       std::cout << "  different character index, index : " << index << std::endl;
246       return false;
247     }
248   }
249
250   for( unsigned int index = 0u; index < data.expectedNumberOfGlyphs; ++index )
251   {
252     if( data.charactersPerGlyph[index] != charactersPerGlyph[index] )
253     {
254       std::cout << "  different character per glyph, index : " << index << std::endl;
255       return false;
256     }
257   }
258
259   if( data.expectedNumberOfNewParagraphGlyphs != newParagraphGlyphs.Count() )
260   {
261     std::cout << "  Different number of new paragraph glyphs : " << newParagraphGlyphs.Count() << ", expected : " << data.expectedNumberOfNewParagraphGlyphs << std::endl;
262     return false;
263   }
264
265   for( unsigned int index = 0u; index < data.expectedNumberOfNewParagraphGlyphs; ++index )
266   {
267     if( data.newParagraphGlyphs[index] != newParagraphGlyphs[index] )
268     {
269       std::cout << "  different new paragraph glyph, index : " << index << std::endl;
270       return false;
271     }
272   }
273
274   return true;
275 }
276
277 } // namespace
278
279 //////////////////////////////////////////////////////////
280
281 int UtcDaliTextShape(void)
282 {
283   tet_infoline(" UtcDaliTextShape");
284
285   struct GlyphInfoData glyphs02[] =
286   {
287     { 1u, 43u, 0.f, 0.f, 0.f, 0.f, 12.f, 0.f },
288     { 1u, 72u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
289     { 1u, 79u, 0.f, 0.f, 0.f, 0.f,  4.f, 0.f },
290     { 1u, 79u, 0.f, 0.f, 0.f, 0.f,  4.f, 0.f },
291     { 1u, 82u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
292     { 1u,  3u, 0.f, 0.f, 0.f, 0.f,  5.f, 0.f },
293     { 1u, 90u, 0.f, 0.f, 0.f, 0.f, 13.f, 0.f },
294     { 1u, 82u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
295     { 1u, 85u, 0.f, 0.f, 0.f, 0.f,  6.f, 0.f },
296     { 1u, 79u, 0.f, 0.f, 0.f, 0.f,  4.f, 0.f },
297     { 1u, 71u, 0.f, 0.f, 0.f, 0.f, 10.f, 0.f },
298   };
299
300   CharacterIndex characterIndices02[] = { 0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 9u, 10u };
301   Length charactersPerGlyph02[] = { 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u };
302
303   struct GlyphInfoData glyphs03[] =
304   {
305     { 1u, 43u, 0.f, 0.f, 0.f, 0.f, 12.f, 0.f },
306     { 1u, 72u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
307     { 1u, 79u, 0.f, 0.f, 0.f, 0.f,  4.f, 0.f },
308     { 1u, 79u, 0.f, 0.f, 0.f, 0.f,  4.f, 0.f },
309     { 1u, 82u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
310     { 1u,  3u, 0.f, 0.f, 0.f, 0.f,  5.f, 0.f },
311     { 1u, 90u, 0.f, 0.f, 0.f, 0.f, 13.f, 0.f },
312     { 1u, 82u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
313     { 1u, 85u, 0.f, 0.f, 0.f, 0.f,  6.f, 0.f },
314     { 1u, 79u, 0.f, 0.f, 0.f, 0.f,  4.f, 0.f },
315     { 1u, 71u, 0.f, 0.f, 0.f, 0.f, 10.f, 0.f },
316     { 1u,  0u, 0.f, 0.f, 0.f, 0.f,  0.f, 0.f },
317     { 1u, 71u, 0.f, 0.f, 0.f, 0.f, 10.f, 0.f },
318     { 1u, 72u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
319     { 1u, 80u, 0.f, 0.f, 0.f, 0.f, 15.f, 0.f },
320     { 1u, 82u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
321     { 1u,  0u, 0.f, 0.f, 0.f, 0.f,  0.f, 0.f },
322   };
323
324   CharacterIndex characterIndices03[] = { 0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 9u, 10u, 11u, 12u, 13u, 14u, 15u, 16u };
325   Length charactersPerGlyph03[] = { 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u };
326   CharacterIndex newParagraphGlyphs03[] = { 11u, 16u };
327
328   struct GlyphInfoData glyphs04[] =
329   {
330     { 2u, 160u, 0.f, 0.f, 0.f, 0.f,  5.f, 0.f },
331     { 2u, 123u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
332     { 2u, 153u, 0.f, 0.f, 0.f, 0.f,  5.f, 0.f },
333     { 2u, 160u, 0.f, 0.f, 0.f, 0.f,  5.f, 0.f },
334     { 2u, 150u, 0.f, 0.f, 0.f, 0.f, 14.f, 0.f },
335     { 2u, 153u, 0.f, 0.f, 0.f, 0.f,  5.f, 0.f },
336     { 2u, 160u, 0.f, 0.f, 0.f, 0.f,  5.f, 0.f },
337     { 2u, 151u, 0.f, 0.f, 0.f, 0.f, 12.f, 0.f },
338     { 2u, 153u, 0.f, 0.f, 0.f, 0.f,  5.f, 0.f },
339     { 2u, 160u, 0.f, 0.f, 0.f, 0.f,  5.f, 0.f },
340     { 2u, 147u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
341     { 2u, 153u, 0.f, 0.f, 0.f, 0.f,  5.f, 0.f },
342   };
343
344   CharacterIndex characterIndices04[] = { 0u, 0u, 0u, 2u, 2u, 2u, 4u, 4u, 4u, 6u, 6u, 6u };
345   Length charactersPerGlyph04[] = { 0u, 0u, 2u, 0u, 0u, 2u, 0u, 0u, 2u, 0u, 0u, 2u };
346
347   struct GlyphInfoData glyphs05[] =
348   {
349     { 1u, 47u, 0.f, 0.f, 0.f, 0.f,  8.f, 0.f },
350     { 1u, 82u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
351     { 1u, 85u, 0.f, 0.f, 0.f, 0.f,  6.f, 0.f },
352     { 1u, 72u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
353     { 1u, 80u, 0.f, 0.f, 0.f, 0.f, 15.f, 0.f },
354     { 1u,  3u, 0.f, 0.f, 0.f, 0.f,  5.f, 0.f },
355     { 1u, 76u, 0.f, 0.f, 0.f, 0.f,  4.f, 0.f },
356     { 1u, 83u, 0.f, 0.f, 0.f, 0.f, 10.f, 0.f },
357     { 1u, 86u, 0.f, 0.f, 0.f, 0.f,  8.f, 0.f },
358     { 1u, 88u, 0.f, 0.f, 0.f, 0.f, 10.f, 0.f },
359     { 1u, 80u, 0.f, 0.f, 0.f, 0.f, 15.f, 0.f },
360     { 1u,  3u, 0.f, 0.f, 0.f, 0.f,  5.f, 0.f },
361     { 1u, 71u, 0.f, 0.f, 0.f, 0.f, 10.f, 0.f },
362     { 1u, 82u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
363     { 1u, 79u, 0.f, 0.f, 0.f, 0.f,  4.f, 0.f },
364     { 1u, 82u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
365     { 1u, 85u, 0.f, 0.f, 0.f, 0.f,  6.f, 0.f },
366     { 1u,  3u, 0.f, 0.f, 0.f, 0.f,  5.f, 0.f },
367     { 1u, 86u, 0.f, 0.f, 0.f, 0.f,  8.f, 0.f },
368     { 1u, 76u, 0.f, 0.f, 0.f, 0.f,  4.f, 0.f },
369     { 1u, 87u, 0.f, 0.f, 0.f, 0.f,  6.f, 0.f },
370     { 1u,  3u, 0.f, 0.f, 0.f, 0.f,  5.f, 0.f },
371     { 1u, 68u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
372     { 1u, 80u, 0.f, 0.f, 0.f, 0.f, 15.f, 0.f },
373     { 1u, 72u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
374     { 1u, 87u, 0.f, 0.f, 0.f, 0.f,  6.f, 0.f },
375     { 1u,  0u, 0.f, 0.f, 0.f, 0.f,  0.f, 0.f },
376     { 1u, 68u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
377     { 1u, 72u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
378     { 1u, 84u, 0.f, 0.f, 0.f, 0.f, 10.f, 0.f },
379     { 1u, 88u, 0.f, 0.f, 0.f, 0.f, 10.f, 0.f },
380     { 1u, 72u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
381     { 1u,  3u, 0.f, 0.f, 0.f, 0.f,  5.f, 0.f },
382     { 1u, 71u, 0.f, 0.f, 0.f, 0.f, 10.f, 0.f },
383     { 1u, 72u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
384     { 1u, 5034u, 0.f, 0.f, 0.f, 0.f, 10.f, 0.f },
385     { 1u, 81u, 0.f, 0.f, 0.f, 0.f, 10.f, 0.f },
386     { 1u, 76u, 0.f, 0.f, 0.f, 0.f,  4.f, 0.f },
387     { 1u, 72u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
388     { 1u, 69u, 0.f, 0.f, 0.f, 0.f, 10.f, 0.f },
389     { 1u, 68u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
390     { 1u, 86u, 0.f, 0.f, 0.f, 0.f,  8.f, 0.f },
391     { 1u,  3u, 0.f, 0.f, 0.f, 0.f,  5.f, 0.f },
392     { 1u, 72u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
393     { 1u, 68u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
394     { 1u,  3u, 0.f, 0.f, 0.f, 0.f,  5.f, 0.f },
395     { 1u, 80u, 0.f, 0.f, 0.f, 0.f, 15.f, 0.f },
396     { 1u, 72u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
397     { 1u, 76u, 0.f, 0.f, 0.f, 0.f,  4.f, 0.f },
398     { 1u,  0u, 0.f, 0.f, 0.f, 0.f,  0.f, 0.f },
399     { 1u, 83u, 0.f, 0.f, 0.f, 0.f, 10.f, 0.f },
400     { 1u, 82u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
401     { 1u, 86u, 0.f, 0.f, 0.f, 0.f,  8.f, 0.f },
402     { 1u, 86u, 0.f, 0.f, 0.f, 0.f,  8.f, 0.f },
403     { 1u, 72u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
404     { 1u,  3u, 0.f, 0.f, 0.f, 0.f,  5.f, 0.f },
405     { 1u, 76u, 0.f, 0.f, 0.f, 0.f,  4.f, 0.f },
406     { 1u, 85u, 0.f, 0.f, 0.f, 0.f,  6.f, 0.f },
407     { 1u, 68u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
408     { 1u, 70u, 0.f, 0.f, 0.f, 0.f,  8.f, 0.f },
409     { 1u, 88u, 0.f, 0.f, 0.f, 0.f, 10.f, 0.f },
410     { 1u, 81u, 0.f, 0.f, 0.f, 0.f, 10.f, 0.f },
411     { 1u, 71u, 0.f, 0.f, 0.f, 0.f, 10.f, 0.f },
412     { 1u, 76u, 0.f, 0.f, 0.f, 0.f,  4.f, 0.f },
413     { 1u, 68u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
414     { 1u,  3u, 0.f, 0.f, 0.f, 0.f,  5.f, 0.f },
415     { 1u, 81u, 0.f, 0.f, 0.f, 0.f, 10.f, 0.f },
416     { 1u, 72u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
417     { 1u,  3u, 0.f, 0.f, 0.f, 0.f,  5.f, 0.f },
418     { 1u, 70u, 0.f, 0.f, 0.f, 0.f,  8.f, 0.f },
419     { 1u, 88u, 0.f, 0.f, 0.f, 0.f, 10.f, 0.f },
420     { 1u, 80u, 0.f, 0.f, 0.f, 0.f, 15.f, 0.f },
421     { 1u, 17u, 0.f, 0.f, 0.f, 0.f,  5.f, 0.f },
422     { 1u,  0u, 0.f, 0.f, 0.f, 0.f,  0.f, 0.f },
423   };
424
425   CharacterIndex characterIndices05[] = {  0u,  1u,  2u,  3u,  4u,  5u,  6u,  7u,  8u,  9u,
426                                           10u, 11u, 12u, 13u, 14u, 15u, 16u, 17u, 18u, 19u,
427                                           20u, 21u, 22u, 23u, 24u, 25u, 26u, 27u, 28u, 29u,
428                                           30u, 31u, 32u, 33u, 34u, 35u, 37u, 38u, 39u, 40u,
429                                           41u, 42u, 43u, 44u, 45u, 46u, 47u, 48u, 49u, 50u,
430                                           51u, 52u, 53u, 54u, 55u, 56u, 57u, 58u, 59u, 60u,
431                                           61u, 62u, 63u, 64u, 65u, 66u, 67u, 68u, 69u, 70u,
432                                           71u, 72u, 73u, 74u };
433   Length charactersPerGlyph05[] = { 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u,
434                                     1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u,
435                                     1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u,
436                                     1u, 1u, 1u, 1u, 1u, 2u, 1u, 1u, 1u, 1u,
437                                     1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u,
438                                     1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u,
439                                     1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u,
440                                     1u, 1u, 1u, 1u };
441   CharacterIndex newParagraphGlyphs05[] = { 26u };
442   CharacterIndex newParagraphGlyphs06[] = { 49u };
443   CharacterIndex newParagraphGlyphs07[] = { 73u };
444
445   struct ShapeInfoData data[] =
446   {
447     {
448       "Zero characters",
449       "",
450       0u,
451       0u,
452       0u,
453       NULL,
454       NULL,
455       NULL,
456       0u,
457       NULL
458     },
459     {
460       "Latin script",
461       "Hello world",
462       0u,
463       11u,
464       11u,
465       glyphs02,
466       characterIndices02,
467       charactersPerGlyph02,
468       0u,
469       NULL
470     },
471     {
472       "Latin script. Some paragraphs.",
473       "Hello world\ndemo\n",
474       0u,
475       17u,
476       17u,
477       glyphs03,
478       characterIndices03,
479       charactersPerGlyph03,
480       2u,
481       newParagraphGlyphs03
482     },
483     {
484       "Malayalam script. More glyphs than characters.",
485       "ജോസോഹോവോ",
486       0u,
487       8u,
488       12u,
489       glyphs04,
490       characterIndices04,
491       charactersPerGlyph04,
492       0u,
493       NULL
494     },
495     {
496       "Latin script with some paragraphs. Update initial paragraph.",
497       "Lorem ipsum dolor sit amet\naeque definiebas ea mei\nposse iracundia ne cum.\n",
498       0u,
499       27u,
500       74u,
501       glyphs05,
502       characterIndices05,
503       charactersPerGlyph05,
504       1u,
505       newParagraphGlyphs05
506     },
507     {
508       "Latin script with some paragraphs. Update mid paragraph.",
509       "Lorem ipsum dolor sit amet\naeque definiebas ea mei\nposse iracundia ne cum.\n",
510       27u,
511       24u,
512       74u,
513       glyphs05,
514       characterIndices05,
515       charactersPerGlyph05,
516       1u,
517       newParagraphGlyphs06
518     },
519     {
520       "Latin script with some paragraphs. Update final paragraph.",
521       "Lorem ipsum dolor sit amet\naeque definiebas ea mei\nposse iracundia ne cum.\n",
522       51u,
523       24u,
524       74u,
525       glyphs05,
526       characterIndices05,
527       charactersPerGlyph05,
528       1u,
529       newParagraphGlyphs07
530     },
531   };
532   const unsigned int numberOfTests = 7u;
533
534   for( unsigned int index = 0u; index < numberOfTests; ++index )
535   {
536     ToolkitTestApplication application;
537     if( !ShapeInfoTest( data[index] ) )
538     {
539       tet_result(TET_FAIL);
540     }
541   }
542
543   tet_result(TET_PASS);
544   END_TEST;
545 }
546
547 int UtcDaliTextSoftwareStyling(void)
548 {
549   tet_infoline(" UtcDaliTextSoftwareStyling");
550
551   struct GlyphInfoData glyphs01[] =
552   {
553     { 2u, 14750u, 0.f, 0.f, 0.f, 0.f, 16.f, 0.f, true, true },
554     { 2u, 9802u, 0.f, 0.f, 0.f, 0.f,  16.f, 0.f, true, true },
555     { 2u, 12811u, 0.f, 0.f, 0.f, 0.f,  16.f, 0.f, true, true },
556   };
557   struct GlyphInfoData glyphs02[] =
558   {
559     { 2u, 14750u, 0.f, 0.f, 0.f, 0.f, 16.f, 0.f, false, false },
560     { 2u, 9802u, 0.f, 0.f, 0.f, 0.f,  16.f, 0.f, false, true },
561     { 2u, 12811u, 0.f, 0.f, 0.f, 0.f,  16.f, 0.f, true, false },
562   };
563
564   CharacterIndex characterIndices[] = { 0u, 1u, 2u };
565   Length charactersPerGlyph[] = { 1u, 1u, 1u };
566
567   Vector<FontDescriptionRun> fontDescriptions01;
568   Vector<FontDescriptionRun> fontDescriptions02;
569
570   FontDescriptionRun fontDescriptionRun01 =
571   {
572     {
573       0u,
574       3u
575     },
576     NULL,
577     0u,
578     TextAbstraction::FontWeight::BOLD,
579     TextAbstraction::FontWidth::NONE,
580     TextAbstraction::FontSlant::ITALIC,
581     TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
582     false,
583     true,
584     false,
585     true,
586     false
587   };
588   fontDescriptions01.PushBack(fontDescriptionRun01);
589
590   FontDescriptionRun fontDescriptionRun02 =
591   {
592     {
593       0u,
594       1u
595     },
596     NULL,
597     0u,
598     TextAbstraction::FontWeight::NONE,
599     TextAbstraction::FontWidth::NONE,
600     TextAbstraction::FontSlant::NONE,
601     TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
602     false,
603     false,
604     false,
605     false,
606     false
607   };
608   FontDescriptionRun fontDescriptionRun03 =
609   {
610     {
611       1u,
612       1u
613     },
614     NULL,
615     0u,
616     TextAbstraction::FontWeight::BOLD,
617     TextAbstraction::FontWidth::NONE,
618     TextAbstraction::FontSlant::NONE,
619     TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
620     false,
621     true,
622     false,
623     false,
624     false
625   };
626   FontDescriptionRun fontDescriptionRun04 =
627   {
628     {
629       2u,
630       1u
631     },
632     NULL,
633     0u,
634     TextAbstraction::FontWeight::NONE,
635     TextAbstraction::FontWidth::NONE,
636     TextAbstraction::FontSlant::ITALIC,
637     TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
638     false,
639     false,
640     false,
641     true,
642     false
643   };
644
645   fontDescriptions02.PushBack(fontDescriptionRun02);
646   fontDescriptions02.PushBack(fontDescriptionRun03);
647   fontDescriptions02.PushBack(fontDescriptionRun04);
648
649
650   struct ShapeInfoData data[] =
651   {
652     {
653       "Chiness script. Characters have same font description",
654       "未取得",
655       0u,
656       3u,
657       3u,
658       glyphs01,
659       characterIndices,
660       charactersPerGlyph,
661       0u,
662       NULL,
663       fontDescriptions01
664     },
665     {
666       "Chiness script. Each character has different font description.",
667       "未取得",
668       0u,
669       3u,
670       3u,
671       glyphs02,
672       characterIndices,
673       charactersPerGlyph,
674       0u,
675       NULL,
676       fontDescriptions02
677     }
678   };
679
680   const unsigned int numberOfTests = 2u;
681
682   for( unsigned int index = 0u; index < numberOfTests; ++index )
683   {
684     ToolkitTestApplication application;
685     if( !ShapeInfoTest( data[index] ) )
686     {
687       tet_result(TET_FAIL);
688     }
689   }
690
691   tet_result(TET_PASS);
692   END_TEST;
693 }