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