Merge branch 'master' into tizen
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-toolkit-internal / utc-Dali-TextView.cpp
1 //
2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
3 //
4 // Licensed under the Flora License, Version 1.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://floralicense.org/license/
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 #include <iostream>
18 #include <stdlib.h>
19 #include <dali-toolkit-test-suite-utils.h>
20 #include <dali-toolkit/dali-toolkit.h>
21
22
23 // Internal headers are allowed here
24 #include <dali-toolkit/internal/controls/text-view/text-view-processor.h>
25 #include <dali-toolkit/internal/controls/text-view/text-view-line-processor.h>
26 #include <dali-toolkit/internal/controls/text-view/text-view-word-group-processor.h>
27 #include <dali-toolkit/internal/controls/text-view/text-view-word-processor.h>
28 #include <dali-toolkit/internal/controls/text-view/relayout-utilities.h>
29
30 using namespace Dali;
31 using namespace Dali::Toolkit;
32 using namespace Dali::Toolkit::Internal;
33
34 void dali_text_view_startup(void)
35 {
36   test_return_value = TET_UNDEF;
37 }
38
39 void dali_text_view_cleanup(void)
40 {
41   test_return_value = TET_PASS;
42 }
43
44
45 namespace
46 {
47
48 const Toolkit::Internal::TextView::LayoutParameters DEFAULT_LAYOUT_PARAMETERS;
49 const Toolkit::Internal::TextView::VisualParameters DEFAULT_VISUAL_PARAMETERS;
50
51 // Data structures used to create an 'experiment' in TET cases
52
53 struct SplitWordTest
54 {
55   std::string description;
56   std::string input;
57   std::size_t position;
58   std::string firstResult;
59   std::string lastResult;
60 };
61
62 struct SplitWordGroupTest
63 {
64   std::string description;
65   std::string input;
66   std::size_t wordPosition;
67   std::size_t position;
68   std::string firstResult;
69   std::string lastResult;
70 };
71
72 struct SplitLineTest
73 {
74   std::string description;
75   std::string input;
76   std::size_t groupPosition;
77   std::size_t wordPosition;
78   std::size_t position;
79   float       lineHeightOffset;
80   std::string firstResult;
81   std::string lastResult;
82 };
83
84 struct MergeWordsTest
85 {
86   std::string description;
87   std::string inputFirst;
88   std::string inputLast;
89   std::string result;
90 };
91
92 struct MergeWordGroupsTest
93 {
94   std::string description;
95   std::string inputFirst;
96   std::string inputLast;
97   std::string result;
98 };
99
100 struct MergeLinesTest
101 {
102   std::string description;
103   std::string inputFirst;
104   std::string inputLast;
105   float       lineHeightOffset;
106   std::string result;
107 };
108
109 struct RemoveCharactersFromWordTest
110 {
111   std::string description;
112   std::string input;
113   std::size_t position;
114   std::size_t numberOfCharacters;
115   std::string result;
116 };
117
118 struct RemoveWordsFromGroupTest
119 {
120   std::string description;
121   std::string input;
122   std::size_t wordIndex;
123   std::size_t numberOfWords;
124   std::string result;
125 };
126
127 struct RemoveGroupsFromLineTest
128 {
129   std::string description;
130   std::string input;
131   std::size_t groupIndex;
132   std::size_t numberOfGroups;
133   float       lineHeightOffset;
134   std::string result;
135 };
136
137 enum UpdateTextInfoOperation
138 {
139   Insert,
140   Remove,
141   Replace
142 };
143
144 struct UpdateTextInfoTest
145 {
146   std::string             description;
147   UpdateTextInfoOperation operation;
148   std::string             input;
149   std::size_t             position;
150   std::size_t             numberOfCharacters;
151   std::string             inputText;
152   float                   lineHeightOffset;
153   std::string             result;
154 };
155
156 // Useful Print functions when something goes wrong.
157
158 void Print( const TextViewProcessor::CharacterLayoutInfo& character )
159 {
160   std::cout << "             height : " << character.mHeight << std::endl;
161   std::cout << "            advance : " << character.mAdvance << std::endl;
162   std::cout << "            bearing : " << character.mBearing << std::endl;
163   std::cout << "          mPosition : " << character.mPosition << std::endl;
164   std::cout << "              mSize : " << character.mSize << std::endl;
165   std::cout << "          mAscender : " << character.mAscender << std::endl;
166
167   TextActor textActor = TextActor::DownCast( character.mGlyphActor );
168   if( textActor )
169   {
170     std::cout << "[" << textActor.GetText() << "]";
171   }
172   else
173   {
174     std::cout << "{" << character.mStyledText.mText.GetText() << "}";
175   }
176 }
177
178 void Print( const TextViewProcessor::WordLayoutInfo& word )
179 {
180   std::cout << "[";
181   std::cout << "              mSize : " << word.mSize << std::endl;
182   std::cout << "          mAscender : " << word.mAscender << std::endl;
183   std::cout << "              mType : " << word.mType << std::endl;
184   std::cout << "mNumberOfCharacters : " << word.mCharactersLayoutInfo.size() << std::endl;
185   std::cout << "[";
186   for( TextViewProcessor::CharacterLayoutInfoContainer::const_iterator it = word.mCharactersLayoutInfo.begin(), endIt = word.mCharactersLayoutInfo.end(); it != endIt; ++it )
187   {
188     Print( *it );
189   }
190   std::cout << "]"; std::cout << std::endl;
191   std::cout << "]"; std::cout << std::endl;
192 }
193
194 void Print( const TextViewProcessor::WordGroupLayoutInfo& wordGroup )
195 {
196   std::cout << "(";
197   std::cout << "              mSize : " << wordGroup.mSize << std::endl;
198   std::cout << "          mAscender : " << wordGroup.mAscender << std::endl;
199   std::cout << "         mDirection : " << wordGroup.mDirection << std::endl;
200   std::cout << "mNumberOfCharacters : " << wordGroup.mNumberOfCharacters << std::endl;
201   for( TextViewProcessor::WordLayoutInfoContainer::const_iterator it = wordGroup.mWordsLayoutInfo.begin(), endIt = wordGroup.mWordsLayoutInfo.end(); it != endIt; ++it )
202   {
203     Print( *it );
204   }
205   std::cout << ")"; std::cout << std::endl;
206 }
207
208 void Print( const TextViewProcessor::LineLayoutInfo& line )
209 {
210   std::cout << "<";
211   std::cout << "              mSize : " << line.mSize << std::endl;
212   std::cout << "          mAscender : " << line.mAscender << std::endl;
213   std::cout << "mNumberOfCharacters : " << line.mNumberOfCharacters << std::endl;
214   for( TextViewProcessor::WordGroupLayoutInfoContainer::const_iterator it = line.mWordGroupsLayoutInfo.begin(), endIt = line.mWordGroupsLayoutInfo.end(); it != endIt; ++it )
215   {
216     Print( *it );
217   }
218   std::cout << ">" << std::endl;
219 }
220
221 void Print( const TextViewProcessor::TextLayoutInfo& text )
222 {
223   std::cout << "||";
224   for( TextViewProcessor::LineLayoutInfoContainer::const_iterator it = text.mLinesLayoutInfo.begin(), endIt = text.mLinesLayoutInfo.end(); it != endIt; ++it )
225   {
226     Print( *it );
227   }
228   std::cout << "||" << std::endl;
229 }
230
231 void Print( const TextStyle& style )
232 {
233   std::cout << " font name : " << style.GetFontName() << std::endl;
234   std::cout << " : " << style.GetFontStyle() << std::endl;
235   std::cout << " : " << style.GetFontPointSize() << std::endl;
236   std::cout << " : " << style.GetWeight() << std::endl;
237   std::cout << " : " << style.GetTextColor() << std::endl;
238   std::cout << " : " << style.GetItalics() << std::endl;
239   std::cout << " : " << style.GetUnderline() << std::endl;
240   std::cout << " : " << style.GetShadow() << std::endl;
241   std::cout << " : " << style.GetShadowColor() << std::endl;
242   std::cout << " : " << style.GetShadowOffset() << std::endl;
243   std::cout << " : " << style.GetGlow() << std::endl;
244   std::cout << " : " << style.GetGlowColor() << std::endl;
245   std::cout << " : " << style.GetGlowIntensity() << std::endl;
246   std::cout << " : " << style.GetSmoothEdge() << std::endl;
247   std::cout << " : " << style.GetOutline() << std::endl;
248   std::cout << " : " << style.GetOutlineThickness() << std::endl;
249 }
250
251 // Test functions used to check if two data structures are equal.
252
253 bool TestEqual( float x, float y )
254 {
255   return ( fabsf( x - y ) < Math::MACHINE_EPSILON_1000 );
256 }
257
258 bool TestEqual( const TextViewProcessor::CharacterLayoutInfo& character1,
259                 const TextViewProcessor::CharacterLayoutInfo& character2 )
260 {
261   if( !TestEqual( character1.mHeight, character2.mHeight ) )
262   {
263     return false;
264   }
265   if( !TestEqual( character1.mAdvance, character2.mAdvance ) )
266   {
267     return false;
268   }
269   if( !TestEqual( character1.mBearing, character2.mBearing ) )
270   {
271     return false;
272   }
273
274   if( !TestEqual( character1.mPosition.x, character2.mPosition.x ) )
275   {
276     return false;
277   }
278   if( !TestEqual( character1.mPosition.y, character2.mPosition.y ) )
279   {
280     return false;
281   }
282
283   if( !TestEqual( character1.mSize.x, character2.mSize.x ) )
284   {
285     return false;
286   }
287   if( !TestEqual( character1.mSize.y, character2.mSize.y ) )
288   {
289     return false;
290   }
291
292   if( !TestEqual( character1.mAscender, character2.mAscender ) )
293   {
294     return false;
295   }
296
297   if( character1.mGlyphActor && !character2.mGlyphActor )
298   {
299     return false;
300   }
301
302   if( !character1.mGlyphActor && character2.mGlyphActor )
303   {
304     return false;
305   }
306
307   std::string text1;
308   std::string text2;
309   TextStyle style1;
310   TextStyle style2;
311
312   TextActor textActor1 = TextActor::DownCast( character1.mGlyphActor );
313   TextActor textActor2 = TextActor::DownCast( character2.mGlyphActor );
314   if( textActor1 )
315   {
316     text1 = textActor1.GetText();
317     style1 = textActor1.GetTextStyle();
318
319     text2 = textActor2.GetText();
320     style2 = textActor2.GetTextStyle();
321   }
322
323   if( text1 != text2 )
324   {
325     return false;
326   }
327
328   if( style1 != style2 )
329   {
330     return false;
331   }
332
333   text1 = character1.mStyledText.mText.GetText();
334   style1 = character1.mStyledText.mStyle;
335
336   text2 = character2.mStyledText.mText.GetText();
337   style2 = character2.mStyledText.mStyle;
338
339   if( text1 != text2 )
340   {
341     return false;
342   }
343
344   if( style1 != style2 )
345   {
346     return false;
347   }
348
349   return true;
350 }
351
352 bool TestEqual( const TextViewProcessor::WordLayoutInfo& word1,
353                 const TextViewProcessor::WordLayoutInfo& word2 )
354 {
355   if( !TestEqual( word1.mSize.x, word2.mSize.x ) )
356   {
357     return false;
358   }
359   if( !TestEqual( word1.mSize.y, word2.mSize.y ) )
360   {
361     return false;
362   }
363
364   if( !TestEqual( word1.mAscender, word2.mAscender ) )
365   {
366     return false;
367   }
368
369   if( word1.mType != word2.mType )
370   {
371     return false;
372   }
373
374   if( word1.mCharactersLayoutInfo.size() != word2.mCharactersLayoutInfo.size() )
375   {
376     return false;
377   }
378
379   for( TextViewProcessor::CharacterLayoutInfoContainer::const_iterator it1 = word1.mCharactersLayoutInfo.begin(), endIt1 = word1.mCharactersLayoutInfo.end(),
380          it2 = word2.mCharactersLayoutInfo.begin(), endIt2 = word2.mCharactersLayoutInfo.end();
381        ( it1 != endIt1 ) && ( it2 != endIt2 );
382        ++it1, ++it2 )
383   {
384     if( !TestEqual( *it1, *it2 ) )
385     {
386       return false;
387     }
388   }
389
390   return true;
391 }
392
393 bool TestEqual( const TextViewProcessor::WordGroupLayoutInfo& group1,
394                 const TextViewProcessor::WordGroupLayoutInfo& group2 )
395 {
396
397   if( group1.mNumberOfCharacters != group2.mNumberOfCharacters )
398   {
399     return false;
400   }
401
402   if( group1.mWordsLayoutInfo.size() != group2.mWordsLayoutInfo.size() )
403   {
404     return false;
405   }
406
407   if( !TestEqual( group1.mSize.x, group2.mSize.x ) )
408   {
409     return false;
410   }
411   if( !TestEqual( group1.mSize.y, group2.mSize.y ) )
412   {
413     return false;
414   }
415
416   if( !TestEqual( group1.mAscender, group2.mAscender ) )
417   {
418     return false;
419   }
420
421   if( group1.mDirection != group2.mDirection )
422   {
423     return false;
424   }
425
426   for( TextViewProcessor::WordLayoutInfoContainer::const_iterator it1 = group1.mWordsLayoutInfo.begin(), endIt1 = group1.mWordsLayoutInfo.end(),
427          it2 = group2.mWordsLayoutInfo.begin(), endIt2 = group2.mWordsLayoutInfo.end();
428        ( it1 != endIt1 ) && ( it2 != endIt2 );
429        ++it1, ++it2 )
430   {
431     if( !TestEqual( *it1, *it2 ) )
432     {
433       return false;
434     }
435   }
436
437   return true;
438 }
439
440 bool TestEqual( const TextViewProcessor::LineLayoutInfo& line1,
441                 const TextViewProcessor::LineLayoutInfo& line2 )
442 {
443   if( !TestEqual( line1.mSize.x, line2.mSize.x ) )
444   {
445     return false;
446   }
447   if( !TestEqual( line1.mSize.y, line2.mSize.y ) )
448   {
449     return false;
450   }
451
452   if( !TestEqual( line1.mAscender, line2.mAscender ) )
453   {
454     return false;
455   }
456
457   if( line1.mNumberOfCharacters != line2.mNumberOfCharacters )
458   {
459     return false;
460   }
461
462   if( line1.mWordGroupsLayoutInfo.size() != line2.mWordGroupsLayoutInfo.size() )
463   {
464     return false;
465   }
466
467   for( TextViewProcessor::WordGroupLayoutInfoContainer::const_iterator it1 = line1.mWordGroupsLayoutInfo.begin(), endIt1 = line1.mWordGroupsLayoutInfo.end(),
468          it2 = line2.mWordGroupsLayoutInfo.begin(), endIt2 = line2.mWordGroupsLayoutInfo.end();
469        ( it1 != endIt1 ) && ( it2 != endIt2 );
470        ++it1, ++it2 )
471   {
472     if( !TestEqual( *it1, *it2 ) )
473     {
474       return false;
475     }
476   }
477
478   return true;
479 }
480
481 bool TestEqual( const TextViewProcessor::TextLayoutInfo& text1,
482                 const TextViewProcessor::TextLayoutInfo& text2 )
483 {
484   if( !TestEqual( text1.mWholeTextSize.x, text2.mWholeTextSize.x ) )
485   {
486     return false;
487   }
488   if( !TestEqual( text1.mWholeTextSize.y, text2.mWholeTextSize.y ) )
489   {
490     return false;
491   }
492
493   if( !TestEqual( text1.mMaxWordWidth, text2.mMaxWordWidth ) )
494   {
495     return false;
496   }
497
498   if( text1.mNumberOfCharacters != text2.mNumberOfCharacters )
499   {
500     return false;
501   }
502
503   if( text1.mLinesLayoutInfo.size() != text2.mLinesLayoutInfo.size() )
504   {
505     return false;
506   }
507
508   for( TextViewProcessor::LineLayoutInfoContainer::const_iterator it1 = text1.mLinesLayoutInfo.begin(), endIt1 = text1.mLinesLayoutInfo.end(),
509          it2 = text2.mLinesLayoutInfo.begin(), endIt2 = text2.mLinesLayoutInfo.end();
510        ( it1 != endIt1 ) && ( it2 != endIt2 );
511        ++it1, ++it2 )
512   {
513     if( !TestEqual( *it1, *it2 ) )
514     {
515       return false;
516     }
517   }
518
519   return true;
520 }
521
522 /**
523  * Splits the \e input word in two by the given \e position and checks the results with \e firstResult and \e lastResult.
524  *
525  * If the test fails it prints a short description and the line where this function was called.
526  *
527  * @param description Short description of the experiment. i.e. "Split the word from the beginning. (position 0)".
528  * @param input The input word.
529  * @param position Where to split the word.
530  * @param firstResult First part of the split word.
531  * @param lastResult Last part of the split word.
532  * @param location Where this function has been called.
533  *
534  * @return \e true if the experiment is successful. Otherwise returns \e false.
535  */
536 bool TestSplitWord( const std::string& description, const std::string& input, const size_t position, const std::string& firstResult, const std::string& lastResult, const char* location )
537 {
538   tet_printf( "%s", description.c_str() );
539
540   // Create layout info for the input word.
541   Toolkit::Internal::TextView::RelayoutData relayoutData;
542   TextViewProcessor::TextLayoutInfo& inputLayout( relayoutData.mTextLayoutInfo );
543
544   MarkupProcessor::StyledTextArray inputStyledText;
545   MarkupProcessor::GetStyledTextArray( input, inputStyledText, true );
546
547   TextViewProcessor::CreateTextInfo( inputStyledText,
548                                      DEFAULT_LAYOUT_PARAMETERS,
549                                      relayoutData );
550
551   // Get the input word
552   TextViewProcessor::WordLayoutInfo inputWordLayout;
553
554   if( !inputLayout.mLinesLayoutInfo.empty() )
555   {
556     const TextViewProcessor::LineLayoutInfo& line( *inputLayout.mLinesLayoutInfo.begin() );
557     if( !line.mWordGroupsLayoutInfo.empty() )
558     {
559       const TextViewProcessor::WordGroupLayoutInfo& group( *line.mWordGroupsLayoutInfo.begin() );
560       if( !group.mWordsLayoutInfo.empty() )
561       {
562         inputWordLayout = *( *( *inputLayout.mLinesLayoutInfo.begin() ).mWordGroupsLayoutInfo.begin() ).mWordsLayoutInfo.begin();
563       }
564     }
565   }
566
567   // Create layout info for the first part of the result (after split the word)
568
569   Toolkit::Internal::TextView::RelayoutData firstRelayoutData;
570   TextViewProcessor::TextLayoutInfo& firstResultLayout( firstRelayoutData.mTextLayoutInfo );
571
572   MarkupProcessor::StyledTextArray firstResultStyledText;
573   MarkupProcessor::GetStyledTextArray( firstResult, firstResultStyledText, true );
574
575   TextViewProcessor::CreateTextInfo( firstResultStyledText,
576                                      DEFAULT_LAYOUT_PARAMETERS,
577                                      firstRelayoutData );
578
579   // Get the first result word
580   TextViewProcessor::WordLayoutInfo firstResultWordLayout;
581
582   if( !firstResultLayout.mLinesLayoutInfo.empty() )
583   {
584     const TextViewProcessor::LineLayoutInfo& line( *firstResultLayout.mLinesLayoutInfo.begin() );
585     if( !line.mWordGroupsLayoutInfo.empty() )
586     {
587       const TextViewProcessor::WordGroupLayoutInfo& group( *line.mWordGroupsLayoutInfo.begin() );
588       if( !group.mWordsLayoutInfo.empty() )
589       {
590         firstResultWordLayout = *( *( *firstResultLayout.mLinesLayoutInfo.begin() ).mWordGroupsLayoutInfo.begin() ).mWordsLayoutInfo.begin();
591       }
592     }
593   }
594
595   // Create layout info for the last part of the result (after split the word)
596
597   Toolkit::Internal::TextView::RelayoutData lastRelayoutData;
598   TextViewProcessor::TextLayoutInfo& lastResultLayout( lastRelayoutData.mTextLayoutInfo );
599
600   MarkupProcessor::StyledTextArray lastResultStyledText;
601   MarkupProcessor::GetStyledTextArray( lastResult, lastResultStyledText, true );
602
603   TextViewProcessor::CreateTextInfo( lastResultStyledText,
604                                      DEFAULT_LAYOUT_PARAMETERS,
605                                      lastRelayoutData );
606
607   // Get the last result word
608   TextViewProcessor::WordLayoutInfo lastResultWordLayout;
609
610   if( !lastResultLayout.mLinesLayoutInfo.empty() )
611   {
612     const TextViewProcessor::LineLayoutInfo& line( *lastResultLayout.mLinesLayoutInfo.begin() );
613     if( !line.mWordGroupsLayoutInfo.empty() )
614     {
615       const TextViewProcessor::WordGroupLayoutInfo& group( *line.mWordGroupsLayoutInfo.begin() );
616       if( !group.mWordsLayoutInfo.empty() )
617       {
618         lastResultWordLayout = *( *( *lastResultLayout.mLinesLayoutInfo.begin() ).mWordGroupsLayoutInfo.begin() ).mWordsLayoutInfo.begin();
619       }
620     }
621   }
622
623   // Split the word.
624
625   TextViewProcessor::WordLayoutInfo lastWordLayoutInfo;
626
627   SplitWord( position,
628              inputWordLayout,
629              lastWordLayoutInfo );
630
631   // Test results
632   if( !TestEqual( inputWordLayout, firstResultWordLayout ) )
633   {
634     tet_printf( "Fail. different layout info. %s", location );
635     return false;
636   }
637
638   if( !TestEqual( lastWordLayoutInfo, lastResultWordLayout ) )
639   {
640     tet_printf( "Fail. different layout info. %s", location );
641     return false;
642   }
643
644   return true;
645 }
646
647 /**
648  * Splits the \e input group of words in two by the given \e wordPosition and \e position and checks the results with \e firstResult and \e lastResult.
649  *
650  * If the test fails it prints a short description and the line where this function was called.
651  *
652  * @param description Short description of the experiment. i.e. "Split the group of words from the beginning. (wordPosition 0 and position 0)".
653  * @param input The input word.
654  * @param wordPosition Index to the word within the group where to split the group.
655  * @param position Where to split the word.
656  * @param firstResult First part of the split group of words.
657  * @param lastResult Last part of the split group of words.
658  * @param location Where this function has been called.
659  *
660  * @return \e true if the experiment is successful. Otherwise returns \e false.
661  */
662 bool TestSplitWordGroup( const std::string& description,
663                          const std::string& input,
664                          const size_t wordPosition,
665                          const size_t position,
666                          const std::string& firstResult,
667                          const std::string& lastResult,
668                          const char* location )
669 {
670   tet_printf( "%s", description.c_str() );
671
672   // Create layout info for the input group of words.
673   Toolkit::Internal::TextView::RelayoutData relayoutData;
674   TextViewProcessor::TextLayoutInfo& inputLayout( relayoutData.mTextLayoutInfo );
675
676   MarkupProcessor::StyledTextArray inputStyledText;
677   MarkupProcessor::GetStyledTextArray( input, inputStyledText, true );
678
679   TextViewProcessor::CreateTextInfo( inputStyledText,
680                                      DEFAULT_LAYOUT_PARAMETERS,
681                                      relayoutData );
682
683   // Get the input group of words
684   TextViewProcessor::WordGroupLayoutInfo inputWordGroupLayout;
685
686   if( !inputLayout.mLinesLayoutInfo.empty() )
687   {
688     const TextViewProcessor::LineLayoutInfo& line( *inputLayout.mLinesLayoutInfo.begin() );
689     if( !line.mWordGroupsLayoutInfo.empty() )
690     {
691       inputWordGroupLayout = *( *inputLayout.mLinesLayoutInfo.begin() ).mWordGroupsLayoutInfo.begin();
692     }
693   }
694
695   // Create layout info for the first part of the result (after split the group of words)
696
697   Toolkit::Internal::TextView::RelayoutData firstRelayoutData;
698   TextViewProcessor::TextLayoutInfo& firstResultLayout( firstRelayoutData.mTextLayoutInfo );
699
700   MarkupProcessor::StyledTextArray firstResultStyledText;
701   MarkupProcessor::GetStyledTextArray( firstResult, firstResultStyledText, true );
702
703   TextViewProcessor::CreateTextInfo( firstResultStyledText,
704                                      DEFAULT_LAYOUT_PARAMETERS,
705                                      firstRelayoutData );
706
707   // Get the first result group of words
708   TextViewProcessor::WordGroupLayoutInfo firstResultWordGroupLayout;
709
710   if( !firstResultLayout.mLinesLayoutInfo.empty() )
711   {
712     const TextViewProcessor::LineLayoutInfo& line( *firstResultLayout.mLinesLayoutInfo.begin() );
713     if( !line.mWordGroupsLayoutInfo.empty() )
714     {
715       firstResultWordGroupLayout = *( *firstResultLayout.mLinesLayoutInfo.begin() ).mWordGroupsLayoutInfo.begin();
716     }
717   }
718
719   // Create layout info for the last part of the result (after split the group of words)
720
721   Toolkit::Internal::TextView::RelayoutData lastRelayoutData;
722   TextViewProcessor::TextLayoutInfo& lastResultLayout( lastRelayoutData.mTextLayoutInfo );
723
724   MarkupProcessor::StyledTextArray lastResultStyledText;
725   MarkupProcessor::GetStyledTextArray( lastResult, lastResultStyledText, true );
726
727   TextViewProcessor::CreateTextInfo( lastResultStyledText,
728                                      DEFAULT_LAYOUT_PARAMETERS,
729                                      lastRelayoutData );
730
731   // Get the last result group of words
732   TextViewProcessor::WordGroupLayoutInfo lastResultWordGroupLayout;
733
734   if( !lastResultLayout.mLinesLayoutInfo.empty() )
735   {
736     const TextViewProcessor::LineLayoutInfo& line( *lastResultLayout.mLinesLayoutInfo.begin() );
737     if( !line.mWordGroupsLayoutInfo.empty() )
738     {
739       lastResultWordGroupLayout = *( *lastResultLayout.mLinesLayoutInfo.begin() ).mWordGroupsLayoutInfo.begin();
740     }
741   }
742
743   // Split the group of words.
744
745   TextViewProcessor::WordGroupLayoutInfo lastWordGroupLayoutInfo;
746
747   TextViewProcessor::TextInfoIndices indices( 0, 0, wordPosition, position );
748   SplitWordGroup( indices,
749                   inputWordGroupLayout,
750                   lastWordGroupLayoutInfo );
751
752   // Test results
753   if( !TestEqual( inputWordGroupLayout, firstResultWordGroupLayout ) )
754   {
755     tet_printf( "Fail. different layout info. %s", location );
756     return false;
757   }
758
759   if( !TestEqual( lastWordGroupLayoutInfo, lastResultWordGroupLayout ) )
760   {
761     tet_printf( "Fail. different layout info. %s", location );
762     return false;
763   }
764
765   return true;
766 }
767
768 /**
769  * Splits the \e input line in two by the given \e groupPosition, \e wordPosition and \e position and checks the results with \e firstResult and \e lastResult.
770  *
771  * If the test fails it prints a short description and the line where this function was called.
772  *
773  * @param description Short description of the experiment. i.e. "Split the line from the beginning. (groupPosition 0, wordPosition 0 and position 0)".
774  * @param input The input word.
775  * @param groupPosition Index to the group of words within the line where to split the line.
776  * @param wordPosition Index to the word within the group where to split the group.
777  * @param position Where to split the word.
778  * @param lineHeightOffset Offset between lines.
779  * @param firstResult First part of the split line.
780  * @param lastResult Last part of the split line.
781  * @param location Where this function has been called.
782  *
783  * @return \e true if the experiment is successful. Otherwise returns \e false.
784  */
785 bool TestSplitLine( const std::string& description,
786                     const std::string& input,
787                     const size_t groupPosition,
788                     const size_t wordPosition,
789                     const size_t position,
790                     const float lineHeightOffset,
791                     const std::string& firstResult,
792                     const std::string& lastResult,
793                     const char* location )
794 {
795   tet_printf( "%s", description.c_str() );
796
797   // Create layout info for the input line.
798   Toolkit::Internal::TextView::RelayoutData relayoutData;
799   TextViewProcessor::TextLayoutInfo& inputLayout( relayoutData.mTextLayoutInfo );
800
801   MarkupProcessor::StyledTextArray inputStyledText;
802   MarkupProcessor::GetStyledTextArray( input, inputStyledText, true );
803
804   TextViewProcessor::CreateTextInfo( inputStyledText,
805                                      Toolkit::Internal::TextView::LayoutParameters( Toolkit::TextView::SplitByNewLineChar,
806                                                                                     Toolkit::TextView::Original,
807                                                                                     Toolkit::TextView::Original,
808                                                                                     static_cast<Toolkit::Alignment::Type>( Toolkit::Alignment::HorizontalCenter | Toolkit::Alignment::VerticalCenter ),
809                                                                                     Toolkit::TextView::Center,
810                                                                                     PointSize( lineHeightOffset ),
811                                                                                     std::string( "..." ),
812                                                                                     true ),
813                                      relayoutData );
814
815   // Get the input line
816   TextViewProcessor::LineLayoutInfo inputLineLayout;
817
818   if( !inputLayout.mLinesLayoutInfo.empty() )
819   {
820     inputLineLayout = *inputLayout.mLinesLayoutInfo.begin();
821   }
822
823   // Create layout info for the first part of the result (after split the line)
824
825   Toolkit::Internal::TextView::RelayoutData firstRelayoutData;
826   TextViewProcessor::TextLayoutInfo& firstResultLayout( firstRelayoutData.mTextLayoutInfo );
827
828   MarkupProcessor::StyledTextArray firstResultStyledText;
829   MarkupProcessor::GetStyledTextArray( firstResult, firstResultStyledText, true );
830
831   TextViewProcessor::CreateTextInfo( firstResultStyledText,
832                                      Toolkit::Internal::TextView::LayoutParameters( Toolkit::TextView::SplitByNewLineChar,
833                                                                                     Toolkit::TextView::Original,
834                                                                                     Toolkit::TextView::Original,
835                                                                                     static_cast<Toolkit::Alignment::Type>( Toolkit::Alignment::HorizontalCenter | Toolkit::Alignment::VerticalCenter ),
836                                                                                     Toolkit::TextView::Center,
837                                                                                     PointSize( lineHeightOffset ),
838                                                                                     std::string( "..." ),
839                                                                                     true ),
840                                      firstRelayoutData );
841
842   // Get the first result line
843   TextViewProcessor::LineLayoutInfo firstResultLineLayout;
844
845   if( !firstResultLayout.mLinesLayoutInfo.empty() )
846   {
847     firstResultLineLayout = *firstResultLayout.mLinesLayoutInfo.begin();
848   }
849
850   // Create layout info for the last part of the result (after split the line)
851
852   Toolkit::Internal::TextView::RelayoutData lastRelayoutData;
853   TextViewProcessor::TextLayoutInfo& lastResultLayout( lastRelayoutData.mTextLayoutInfo );
854
855   MarkupProcessor::StyledTextArray lastResultStyledText;
856   MarkupProcessor::GetStyledTextArray( lastResult, lastResultStyledText, true );
857
858   TextViewProcessor::CreateTextInfo( lastResultStyledText,
859                                      Toolkit::Internal::TextView::LayoutParameters( Toolkit::TextView::SplitByNewLineChar,
860                                                                                     Toolkit::TextView::Original,
861                                                                                     Toolkit::TextView::Original,
862                                                                                     static_cast<Toolkit::Alignment::Type>( Toolkit::Alignment::HorizontalCenter | Toolkit::Alignment::VerticalCenter ),
863                                                                                     Toolkit::TextView::Center,
864                                                                                     PointSize( lineHeightOffset ),
865                                                                                     std::string( "..."),
866                                                                                     true ),
867                                      lastRelayoutData );
868
869   // Get the last result line
870   TextViewProcessor::LineLayoutInfo lastResultLineLayout;
871
872   if( !lastResultLayout.mLinesLayoutInfo.empty() )
873   {
874     lastResultLineLayout = *lastResultLayout.mLinesLayoutInfo.begin();
875   }
876
877   // Split the line.
878
879   TextViewProcessor::LineLayoutInfo lastLineLayoutInfo;
880
881   TextViewProcessor::TextInfoIndices indices( 0, groupPosition, wordPosition, position );
882   SplitLine( indices,
883              PointSize( lineHeightOffset ),
884              inputLineLayout,
885              lastLineLayoutInfo );
886
887   // Test results
888   if( !TestEqual( inputLineLayout, firstResultLineLayout ) )
889   {
890     tet_printf( "Fail. different layout info. %s", location );
891     return false;
892   }
893
894   if( !TestEqual( lastLineLayoutInfo, lastResultLineLayout ) )
895   {
896     tet_printf( "Fail. different layout info. %s", location );
897     return false;
898   }
899
900   return true;
901 }
902
903 /**
904  * Merges the \e inputFirst word and the \e inputLast word, and checks the results with \e result.
905  *
906  * If the test fails it prints a short description and the line where this function was called.
907  *
908  * @param description Short description of the experiment. i.e. "Merge two words with same style".
909  * @param inputFirst The first part of the word.
910  * @param inputLast The last part of the word.
911  * @param result The merged word.
912  * @param location Where this function has been called.
913  *
914  * @return \e true if the experiment is successful. Otherwise returns \e false.
915  */
916 bool TestMergeWords( const std::string& description, const std::string& inputFirst, const std::string& inputLast, const std::string& result, const char* location )
917 {
918   tet_printf( "%s", description.c_str() );
919
920   // Create layout info for the inputFirst word.
921   Toolkit::Internal::TextView::RelayoutData firstRelayoutData;
922   TextViewProcessor::TextLayoutInfo& inputFirstLayout( firstRelayoutData.mTextLayoutInfo );
923
924   MarkupProcessor::StyledTextArray inputFirstStyledText;
925   MarkupProcessor::GetStyledTextArray( inputFirst, inputFirstStyledText, true );
926
927   TextViewProcessor::CreateTextInfo( inputFirstStyledText,
928                                      DEFAULT_LAYOUT_PARAMETERS,
929                                      firstRelayoutData );
930
931   // Get the input word
932   TextViewProcessor::WordLayoutInfo inputFirstWordLayout;
933
934   if( !inputFirstLayout.mLinesLayoutInfo.empty() )
935   {
936     const TextViewProcessor::LineLayoutInfo& line( *inputFirstLayout.mLinesLayoutInfo.begin() );
937     if( !line.mWordGroupsLayoutInfo.empty() )
938     {
939       const TextViewProcessor::WordGroupLayoutInfo& group( *line.mWordGroupsLayoutInfo.begin() );
940       if( !group.mWordsLayoutInfo.empty() )
941       {
942         inputFirstWordLayout = *( *( *inputFirstLayout.mLinesLayoutInfo.begin() ).mWordGroupsLayoutInfo.begin() ).mWordsLayoutInfo.begin();
943       }
944     }
945   }
946
947   // Create layout info for the inputLast word.
948   Toolkit::Internal::TextView::RelayoutData lastRelayoutData;
949   TextViewProcessor::TextLayoutInfo& inputLastLayout( lastRelayoutData.mTextLayoutInfo );
950
951   MarkupProcessor::StyledTextArray inputLastStyledText;
952   MarkupProcessor::GetStyledTextArray( inputLast, inputLastStyledText, true );
953
954   TextViewProcessor::CreateTextInfo( inputLastStyledText,
955                                      DEFAULT_LAYOUT_PARAMETERS,
956                                      lastRelayoutData );
957
958   // Get the input word
959   TextViewProcessor::WordLayoutInfo inputLastWordLayout;
960
961   if( !inputLastLayout.mLinesLayoutInfo.empty() )
962   {
963     const TextViewProcessor::LineLayoutInfo& line( *inputLastLayout.mLinesLayoutInfo.begin() );
964     if( !line.mWordGroupsLayoutInfo.empty() )
965     {
966       const TextViewProcessor::WordGroupLayoutInfo& group( *line.mWordGroupsLayoutInfo.begin() );
967       if( !group.mWordsLayoutInfo.empty() )
968       {
969         inputLastWordLayout = *( *( *inputLastLayout.mLinesLayoutInfo.begin() ).mWordGroupsLayoutInfo.begin() ).mWordsLayoutInfo.begin();
970       }
971     }
972   }
973
974   // Create layout info for the result word.
975   Toolkit::Internal::TextView::RelayoutData resultRelayoutData;
976   TextViewProcessor::TextLayoutInfo& resultLayout( resultRelayoutData.mTextLayoutInfo );
977
978   MarkupProcessor::StyledTextArray resultStyledText;
979   MarkupProcessor::GetStyledTextArray( result, resultStyledText, true );
980
981   TextViewProcessor::CreateTextInfo( resultStyledText,
982                                      DEFAULT_LAYOUT_PARAMETERS,
983                                      resultRelayoutData );
984
985   // Get the result word
986   TextViewProcessor::WordLayoutInfo resultWordLayout;
987
988   if( !resultLayout.mLinesLayoutInfo.empty() )
989   {
990     const TextViewProcessor::LineLayoutInfo& line( *resultLayout.mLinesLayoutInfo.begin() );
991     if( !line.mWordGroupsLayoutInfo.empty() )
992     {
993       const TextViewProcessor::WordGroupLayoutInfo& group( *line.mWordGroupsLayoutInfo.begin() );
994       if( !group.mWordsLayoutInfo.empty() )
995       {
996         resultWordLayout = *( *( *resultLayout.mLinesLayoutInfo.begin() ).mWordGroupsLayoutInfo.begin() ).mWordsLayoutInfo.begin();
997       }
998     }
999   }
1000
1001   MergeWord( inputFirstWordLayout,
1002              inputLastWordLayout );
1003
1004   if( !TestEqual( inputFirstWordLayout, resultWordLayout ) )
1005   {
1006     tet_printf( "Fail. different layout info. %s", location );
1007     return false;
1008   }
1009
1010   return true;
1011 }
1012
1013 /**
1014  * Merges the \e inputFirst group of words and the \e inputLast group of words, and checks the results with \e result.
1015  *
1016  * If the test fails it prints a short description and the line where this function was called.
1017  *
1018  * @param description Short description of the experiment.
1019  * @param inputFirst The first part of the group of words.
1020  * @param inputLast The last part of the group of words.
1021  * @param result The merged group of word.
1022  * @param location Where this function has been called.
1023  *
1024  * @return \e true if the experiment is successful. Otherwise returns \e false.
1025  */
1026 bool TestMergeGroupsOfWords( const std::string& description, const std::string& inputFirst, const std::string& inputLast, const std::string& result, const char* location )
1027 {
1028   tet_printf( "%s", description.c_str() );
1029
1030   // Create layout info for the inputFirst group of word.
1031   Toolkit::Internal::TextView::RelayoutData firstRelayoutData;
1032   TextViewProcessor::TextLayoutInfo& inputFirstLayout( firstRelayoutData.mTextLayoutInfo );
1033
1034   MarkupProcessor::StyledTextArray inputFirstStyledText;
1035   MarkupProcessor::GetStyledTextArray( inputFirst, inputFirstStyledText, true );
1036
1037   TextViewProcessor::CreateTextInfo( inputFirstStyledText,
1038                                      DEFAULT_LAYOUT_PARAMETERS,
1039                                      firstRelayoutData );
1040
1041   // Get the input group of words.
1042   TextViewProcessor::WordGroupLayoutInfo inputFirstWordGroupLayout;
1043
1044   if( !inputFirstLayout.mLinesLayoutInfo.empty() )
1045   {
1046     const TextViewProcessor::LineLayoutInfo& line( *inputFirstLayout.mLinesLayoutInfo.begin() );
1047     if( !line.mWordGroupsLayoutInfo.empty() )
1048     {
1049       inputFirstWordGroupLayout = *( *inputFirstLayout.mLinesLayoutInfo.begin() ).mWordGroupsLayoutInfo.begin();
1050     }
1051   }
1052
1053   // Create layout info for the inputLast group of words.
1054   Toolkit::Internal::TextView::RelayoutData lastRelayoutData;
1055   TextViewProcessor::TextLayoutInfo& inputLastLayout( lastRelayoutData.mTextLayoutInfo );
1056
1057   MarkupProcessor::StyledTextArray inputLastStyledText;
1058   MarkupProcessor::GetStyledTextArray( inputLast, inputLastStyledText, true );
1059
1060   TextViewProcessor::CreateTextInfo( inputLastStyledText,
1061                                      DEFAULT_LAYOUT_PARAMETERS,
1062                                      lastRelayoutData );
1063
1064   // Get the input group of words
1065   TextViewProcessor::WordGroupLayoutInfo inputLastWordGroupLayout;
1066
1067   if( !inputLastLayout.mLinesLayoutInfo.empty() )
1068   {
1069     const TextViewProcessor::LineLayoutInfo& line( *inputLastLayout.mLinesLayoutInfo.begin() );
1070     if( !line.mWordGroupsLayoutInfo.empty() )
1071     {
1072       inputLastWordGroupLayout = *( *inputLastLayout.mLinesLayoutInfo.begin() ).mWordGroupsLayoutInfo.begin();
1073     }
1074   }
1075
1076   // Create layout info for the result group of words.
1077   Toolkit::Internal::TextView::RelayoutData resultRelayoutData;
1078   TextViewProcessor::TextLayoutInfo& resultLayout( resultRelayoutData.mTextLayoutInfo );
1079
1080   MarkupProcessor::StyledTextArray resultStyledText;
1081   MarkupProcessor::GetStyledTextArray( result, resultStyledText, true );
1082
1083   TextViewProcessor::CreateTextInfo( resultStyledText,
1084                                      DEFAULT_LAYOUT_PARAMETERS,
1085                                      resultRelayoutData );
1086
1087   // Get the result word
1088   TextViewProcessor::WordGroupLayoutInfo resultWordGroupLayout;
1089
1090   if( !resultLayout.mLinesLayoutInfo.empty() )
1091   {
1092     const TextViewProcessor::LineLayoutInfo& line( *resultLayout.mLinesLayoutInfo.begin() );
1093     if( !line.mWordGroupsLayoutInfo.empty() )
1094     {
1095       resultWordGroupLayout = *( *resultLayout.mLinesLayoutInfo.begin() ).mWordGroupsLayoutInfo.begin();
1096     }
1097   }
1098
1099   MergeWordGroup( inputFirstWordGroupLayout,
1100                   inputLastWordGroupLayout );
1101
1102   if( !TestEqual( inputFirstWordGroupLayout, resultWordGroupLayout ) )
1103   {
1104     tet_printf( "Fail. different layout info. %s", location );
1105     return false;
1106   }
1107
1108   return true;
1109 }
1110
1111 /**
1112  * Merges the \e inputFirst line and the \e inputLast line, and checks the results with \e result.
1113  *
1114  * If the test fails it prints a short description and the line where this function was called.
1115  *
1116  * @param description Short description of the experiment.
1117  * @param inputFirst The first part of the line.
1118  * @param inputLast The last part of the line.
1119  * @param lineHeightOffset Offset between lines.
1120  * @param result The merged line.
1121  * @param location Where this function has been called.
1122  *
1123  * @return \e true if the experiment is successful. Otherwise returns \e false.
1124  */
1125 bool TestMergeLines( const std::string& description, const std::string& inputFirst, const std::string& inputLast, const float lineHeightOffset, const std::string& result, const char* location )
1126 {
1127   tet_printf( "%s", description.c_str() );
1128
1129   // Create layout info for the inputFirst line.
1130   Toolkit::Internal::TextView::RelayoutData firstRelayoutData;
1131   TextViewProcessor::TextLayoutInfo& inputFirstLayout( firstRelayoutData.mTextLayoutInfo );
1132
1133   MarkupProcessor::StyledTextArray inputFirstStyledText;
1134   MarkupProcessor::GetStyledTextArray( inputFirst, inputFirstStyledText, true );
1135
1136   TextViewProcessor::CreateTextInfo( inputFirstStyledText,
1137                                      Toolkit::Internal::TextView::LayoutParameters( Toolkit::TextView::SplitByNewLineChar,
1138                                                                                     Toolkit::TextView::Original,
1139                                                                                     Toolkit::TextView::Original,
1140                                                                                     static_cast<Toolkit::Alignment::Type>( Toolkit::Alignment::HorizontalCenter | Toolkit::Alignment::VerticalCenter ),
1141                                                                                     Toolkit::TextView::Center,
1142                                                                                     PointSize( lineHeightOffset ),
1143                                                                                     std::string( "..." ),
1144                                                                                     true ),
1145                                      firstRelayoutData );
1146
1147   // Get the input word
1148   TextViewProcessor::LineLayoutInfo inputFirstLineLayout;
1149
1150   if( !inputFirstLayout.mLinesLayoutInfo.empty() )
1151   {
1152     inputFirstLineLayout = *inputFirstLayout.mLinesLayoutInfo.begin();
1153   }
1154
1155   // Create layout info for the inputLast line.
1156   Toolkit::Internal::TextView::RelayoutData lastRelayoutData;
1157   TextViewProcessor::TextLayoutInfo& inputLastLayout( lastRelayoutData.mTextLayoutInfo );
1158
1159   MarkupProcessor::StyledTextArray inputLastStyledText;
1160   MarkupProcessor::GetStyledTextArray( inputLast, inputLastStyledText, true );
1161
1162   TextViewProcessor::CreateTextInfo( inputLastStyledText,
1163                                      Toolkit::Internal::TextView::LayoutParameters( Toolkit::TextView::SplitByNewLineChar,
1164                                                                                     Toolkit::TextView::Original,
1165                                                                                     Toolkit::TextView::Original,
1166                                                                                     static_cast<Toolkit::Alignment::Type>( Toolkit::Alignment::HorizontalCenter | Toolkit::Alignment::VerticalCenter ),
1167                                                                                     Toolkit::TextView::Center,
1168                                                                                     PointSize( lineHeightOffset ),
1169                                                                                     std::string( "..." ),
1170                                                                                     true ),
1171                                      lastRelayoutData );
1172
1173   // Get the input word
1174   TextViewProcessor::LineLayoutInfo inputLastLineLayout;
1175
1176   if( !inputLastLayout.mLinesLayoutInfo.empty() )
1177   {
1178     inputLastLineLayout = *inputLastLayout.mLinesLayoutInfo.begin();
1179   }
1180
1181   // Create layout info for the result word.
1182   Toolkit::Internal::TextView::RelayoutData resultRelayoutData;
1183   TextViewProcessor::TextLayoutInfo& resultLayout( resultRelayoutData.mTextLayoutInfo );
1184
1185   MarkupProcessor::StyledTextArray resultStyledText;
1186   MarkupProcessor::GetStyledTextArray( result, resultStyledText, true );
1187
1188   TextViewProcessor::CreateTextInfo( resultStyledText,
1189                                      Toolkit::Internal::TextView::LayoutParameters( Toolkit::TextView::SplitByNewLineChar,
1190                                                                                     Toolkit::TextView::Original,
1191                                                                                     Toolkit::TextView::Original,
1192                                                                                     static_cast<Toolkit::Alignment::Type>( Toolkit::Alignment::HorizontalCenter | Toolkit::Alignment::VerticalCenter ),
1193                                                                                     Toolkit::TextView::Center,
1194                                                                                     PointSize( lineHeightOffset ),
1195                                                                                     std::string( "..." ),
1196                                                                                     true ),
1197                                      resultRelayoutData );
1198
1199   // Get the result word
1200   TextViewProcessor::LineLayoutInfo resultLineLayout;
1201
1202   if( !resultLayout.mLinesLayoutInfo.empty() )
1203   {
1204     resultLineLayout = *resultLayout.mLinesLayoutInfo.begin();
1205   }
1206
1207   MergeLine( inputFirstLineLayout,
1208              inputLastLineLayout );
1209
1210   if( !TestEqual( inputFirstLineLayout, resultLineLayout ) )
1211   {
1212     tet_printf( "Fail. different layout info. %s", location );
1213     return false;
1214   }
1215
1216   return true;
1217 }
1218
1219 /**
1220  * Removes from the \e input word the \e numberOfCharacters characters starting from the given \e position and checks the results with \e result.
1221  *
1222  * If the test fails it prints a short description and the line where this function was called.
1223  *
1224  * @param description Short description of the experiment. i.e. "Remove a whole group of characters. Merge".
1225  * @param input The input word.
1226  * @param position Where to start to remove characters
1227  * @param numberOfCharacters The number of characters to remove.
1228  * @param result The word without the removed characters.
1229  * @param location Where this function has been called.
1230  *
1231  * @return \e true if the experiment is successful. Otherwise returns \e false.
1232  */
1233 bool TestRemoveCharactersFromWord( const std::string& description, const std::string& input, const std::size_t position, const std::size_t numberOfCharacters, const std::string& result, const char* location )
1234 {
1235   tet_printf( "%s", description.c_str() );
1236
1237   // Create layout info for the input word.
1238   Toolkit::Internal::TextView::RelayoutData relayoutData;
1239   TextViewProcessor::TextLayoutInfo& inputLayout( relayoutData.mTextLayoutInfo );
1240
1241   MarkupProcessor::StyledTextArray inputStyledText;
1242   MarkupProcessor::GetStyledTextArray( input, inputStyledText, true );
1243
1244   TextViewProcessor::CreateTextInfo( inputStyledText,
1245                                      DEFAULT_LAYOUT_PARAMETERS,
1246                                      relayoutData );
1247
1248   // Get the input word
1249   TextViewProcessor::WordLayoutInfo inputWordLayout;
1250
1251   if( !inputLayout.mLinesLayoutInfo.empty() )
1252   {
1253     const TextViewProcessor::LineLayoutInfo& line( *inputLayout.mLinesLayoutInfo.begin() );
1254     if( !line.mWordGroupsLayoutInfo.empty() )
1255     {
1256       const TextViewProcessor::WordGroupLayoutInfo& group( *line.mWordGroupsLayoutInfo.begin() );
1257       if( !group.mWordsLayoutInfo.empty() )
1258       {
1259         inputWordLayout = *( *( *inputLayout.mLinesLayoutInfo.begin() ).mWordGroupsLayoutInfo.begin() ).mWordsLayoutInfo.begin();
1260       }
1261     }
1262   }
1263
1264   // Create layout info for the result word.
1265   Toolkit::Internal::TextView::RelayoutData resultRelayoutData;
1266   TextViewProcessor::TextLayoutInfo& resultLayout( resultRelayoutData.mTextLayoutInfo );
1267
1268   MarkupProcessor::StyledTextArray resultStyledText;
1269   MarkupProcessor::GetStyledTextArray( result, resultStyledText, true );
1270
1271   TextViewProcessor::CreateTextInfo( resultStyledText,
1272                                      DEFAULT_LAYOUT_PARAMETERS,
1273                                      resultRelayoutData );
1274
1275   // Get the result word
1276   TextViewProcessor::WordLayoutInfo resultWordLayout;
1277
1278   if( !resultLayout.mLinesLayoutInfo.empty() )
1279   {
1280     const TextViewProcessor::LineLayoutInfo& line( *resultLayout.mLinesLayoutInfo.begin() );
1281     if( !line.mWordGroupsLayoutInfo.empty() )
1282     {
1283       const TextViewProcessor::WordGroupLayoutInfo& group( *line.mWordGroupsLayoutInfo.begin() );
1284       if( !group.mWordsLayoutInfo.empty() )
1285       {
1286         resultWordLayout = *( *( *resultLayout.mLinesLayoutInfo.begin() ).mWordGroupsLayoutInfo.begin() ).mWordsLayoutInfo.begin();
1287       }
1288     }
1289   }
1290
1291   RemoveCharactersFromWord( position,
1292                             numberOfCharacters,
1293                             inputWordLayout );
1294
1295   if( !TestEqual( inputWordLayout, resultWordLayout ) )
1296   {
1297     tet_printf( "Fail. different layout info. %s", location );
1298     return false;
1299   }
1300
1301   return true;
1302 }
1303
1304 /**
1305  * Removes from the \e input group of words the \e numberOfWords words starting from the given \e wordIndex and checks the results with \e result.
1306  *
1307  * If the test fails it prints a short description and the line where this function was called.
1308  *
1309  * @param description Short description of the experiment.
1310  * @param input The input group of words.
1311  * @param wordIndex Where to start to remove words.
1312  * @param numberOfWords The number of words to remove.
1313  * @param result The group of words without the removed words.
1314  * @param location Where this function has been called.
1315  *
1316  * @return \e true if the experiment is successful. Otherwise returns \e false.
1317  */
1318 bool TestRemoveWordsFromGroup( const std::string& description, const std::string& input, const std::size_t wordIndex, const std::size_t numberOfWords, const std::string& result, const char* location )
1319 {
1320   tet_printf( "%s", description.c_str() );
1321
1322   // Create layout info for the input group of words.
1323   Toolkit::Internal::TextView::RelayoutData relayoutData;
1324   TextViewProcessor::TextLayoutInfo& inputLayout( relayoutData.mTextLayoutInfo );
1325
1326   MarkupProcessor::StyledTextArray inputStyledText;
1327   MarkupProcessor::GetStyledTextArray( input, inputStyledText, true );
1328
1329   TextViewProcessor::CreateTextInfo( inputStyledText,
1330                                      DEFAULT_LAYOUT_PARAMETERS,
1331                                      relayoutData );
1332
1333   // Get the input group of words
1334   TextViewProcessor::WordGroupLayoutInfo inputWordGroupLayout;
1335
1336   if( !inputLayout.mLinesLayoutInfo.empty() )
1337   {
1338     const TextViewProcessor::LineLayoutInfo& line( *inputLayout.mLinesLayoutInfo.begin() );
1339     if( !line.mWordGroupsLayoutInfo.empty() )
1340     {
1341       inputWordGroupLayout = *( *inputLayout.mLinesLayoutInfo.begin() ).mWordGroupsLayoutInfo.begin();
1342     }
1343   }
1344
1345   // Create layout info for the result group of words.
1346   Toolkit::Internal::TextView::RelayoutData resultRelayoutData;
1347   TextViewProcessor::TextLayoutInfo& resultLayout( resultRelayoutData.mTextLayoutInfo );
1348
1349   MarkupProcessor::StyledTextArray resultStyledText;
1350   MarkupProcessor::GetStyledTextArray( result, resultStyledText, true );
1351
1352   TextViewProcessor::CreateTextInfo( resultStyledText,
1353                                      DEFAULT_LAYOUT_PARAMETERS,
1354                                      resultRelayoutData );
1355
1356   // Get the result group of words.
1357   TextViewProcessor::WordGroupLayoutInfo resultWordGroupLayout;
1358
1359   if( !resultLayout.mLinesLayoutInfo.empty() )
1360   {
1361     const TextViewProcessor::LineLayoutInfo& line( *resultLayout.mLinesLayoutInfo.begin() );
1362     if( !line.mWordGroupsLayoutInfo.empty() )
1363     {
1364       resultWordGroupLayout = *( *resultLayout.mLinesLayoutInfo.begin() ).mWordGroupsLayoutInfo.begin();
1365     }
1366   }
1367
1368   RemoveWordsFromWordGroup( wordIndex,
1369                             numberOfWords,
1370                             inputWordGroupLayout );
1371
1372   if( !TestEqual( inputWordGroupLayout, resultWordGroupLayout ) )
1373   {
1374     tet_printf( "Fail. different layout info. %s", location );
1375     return false;
1376   }
1377
1378   return true;
1379 }
1380
1381
1382 /**
1383  * Removes from the \e input line the \e numberOfGroups groups of words starting from the given \e groupIndex and checks the results with \e result.
1384  *
1385  * If the test fails it prints a short description and the line where this function was called.
1386  *
1387  * @param description Short description of the experiment.
1388  * @param input The input line.
1389  * @param groupIndex Where to start to remove groups of words
1390  * @param numberOfGroups The number of groups of words to remove.
1391  * @param lineHeightOffset Offset between lines.
1392  * @param result The line without the removed groups of words.
1393  * @param location Where this function has been called.
1394  *
1395  * @return \e true if the experiment is successful. Otherwise returns \e false.
1396  */
1397 bool TestRemoveGroupsFromLine( const std::string& description, const std::string& input, const std::size_t groupIndex, const std::size_t numberOfGroups, const float lineHeightOffset, const std::string& result, const char* location )
1398 {
1399   tet_printf( "%s", description.c_str() );
1400
1401   // Create layout info for the input line.
1402   Toolkit::Internal::TextView::RelayoutData relayoutData;
1403   TextViewProcessor::TextLayoutInfo& inputLayout( relayoutData.mTextLayoutInfo );
1404
1405   MarkupProcessor::StyledTextArray inputStyledText;
1406   MarkupProcessor::GetStyledTextArray( input, inputStyledText, true );
1407
1408   TextViewProcessor::CreateTextInfo( inputStyledText,
1409                                      Toolkit::Internal::TextView::LayoutParameters( Toolkit::TextView::SplitByNewLineChar,
1410                                                                                     Toolkit::TextView::Original,
1411                                                                                     Toolkit::TextView::Original,
1412                                                                                     static_cast<Toolkit::Alignment::Type>( Toolkit::Alignment::HorizontalCenter | Toolkit::Alignment::VerticalCenter ),
1413                                                                                     Toolkit::TextView::Center,
1414                                                                                     PointSize( lineHeightOffset ),
1415                                                                                     std::string( "..." ),
1416                                                                                     true ),
1417                                      relayoutData );
1418
1419   // Get the input line
1420   TextViewProcessor::LineLayoutInfo inputLineLayout;
1421
1422   if( !inputLayout.mLinesLayoutInfo.empty() )
1423   {
1424     inputLineLayout = *inputLayout.mLinesLayoutInfo.begin();
1425   }
1426
1427   // Create layout info for the result line.
1428   Toolkit::Internal::TextView::RelayoutData resultRelayoutData;
1429   TextViewProcessor::TextLayoutInfo& resultLayout( resultRelayoutData.mTextLayoutInfo );
1430
1431   MarkupProcessor::StyledTextArray resultStyledText;
1432   MarkupProcessor::GetStyledTextArray( result, resultStyledText, true );
1433
1434   TextViewProcessor::CreateTextInfo( resultStyledText,
1435                                      Toolkit::Internal::TextView::LayoutParameters( Toolkit::TextView::SplitByNewLineChar,
1436                                                                                     Toolkit::TextView::Original,
1437                                                                                     Toolkit::TextView::Original,
1438                                                                                     static_cast<Toolkit::Alignment::Type>( Toolkit::Alignment::HorizontalCenter | Toolkit::Alignment::VerticalCenter ),
1439                                                                                     Toolkit::TextView::Center,
1440                                                                                     PointSize( lineHeightOffset ),
1441                                                                                     std::string( "..." ),
1442                                                                                     true ),
1443                                      resultRelayoutData );
1444
1445   // Get the result line
1446   TextViewProcessor::LineLayoutInfo resultLineLayout;
1447
1448   if( !resultLayout.mLinesLayoutInfo.empty() )
1449   {
1450     resultLineLayout = *resultLayout.mLinesLayoutInfo.begin();
1451   }
1452
1453   RemoveWordGroupsFromLine( groupIndex,
1454                             numberOfGroups,
1455                             PointSize( lineHeightOffset ),
1456                             inputLineLayout );
1457
1458   if( !TestEqual( inputLineLayout, resultLineLayout ) )
1459   {
1460     tet_printf( "Fail. different layout info. %s", location );
1461     return false;
1462   }
1463
1464   return true;
1465 }
1466
1467 /**
1468  * Tests inserts, removes and updates operation in the given \e input text and checks with the given \e result.
1469  *
1470  * If the test fails it prints a short description and the line where this function was called.
1471  *
1472  * @param description Short description of the experiment.
1473  * @param operation Type of update operation (insert, remove, replace)
1474  * @param input The input text.
1475  * @param position Where to insert, remove or replace text.
1476  * @param numberOfCharacters Number of characters to remove or replace.
1477  * @param inputText Inserted or updated text.
1478  * @param lineHeightOffset Offset between lines.
1479  * @param result Expected result.
1480  * @param location Where this function has been called.
1481  *
1482  * @return \e true if the experiment is successful. Otherwise returns \e false.
1483  */
1484 bool TestUpdateTextInfo( const std::string& description,
1485                          const UpdateTextInfoOperation operation,
1486                          const std::string& input,
1487                          const std::size_t position,
1488                          const std::size_t numberOfCharacters,
1489                          const std::string& inputText,
1490                          const float lineHeightOffset,
1491                          const std::string& result,
1492                          const char* location )
1493 {
1494   tet_printf( "%s", description.c_str() );
1495
1496   // Create layout info for the input.
1497   Toolkit::Internal::TextView::RelayoutData relayoutData;
1498   TextViewProcessor::TextLayoutInfo& inputLayout( relayoutData.mTextLayoutInfo );
1499
1500   MarkupProcessor::StyledTextArray inputStyledText;
1501   MarkupProcessor::GetStyledTextArray( input, inputStyledText, true );
1502
1503   TextViewProcessor::CreateTextInfo( inputStyledText,
1504                                      Toolkit::Internal::TextView::LayoutParameters( Toolkit::TextView::SplitByNewLineChar,
1505                                                                                     Toolkit::TextView::Original,
1506                                                                                     Toolkit::TextView::Original,
1507                                                                                     static_cast<Toolkit::Alignment::Type>( Toolkit::Alignment::HorizontalCenter | Toolkit::Alignment::VerticalCenter ),
1508                                                                                     Toolkit::TextView::Center,
1509                                                                                     PointSize( lineHeightOffset ),
1510                                                                                     std::string( "..." ),
1511                                                                                     true ),
1512                                      relayoutData );
1513
1514   // Create layout info for the result.
1515   Toolkit::Internal::TextView::RelayoutData resultRelayoutData;
1516   TextViewProcessor::TextLayoutInfo& resultLayout( resultRelayoutData.mTextLayoutInfo );
1517
1518   MarkupProcessor::StyledTextArray resultStyledText;
1519   MarkupProcessor::GetStyledTextArray( result, resultStyledText, true );
1520
1521   TextViewProcessor::CreateTextInfo( resultStyledText,
1522                                      Toolkit::Internal::TextView::LayoutParameters( Toolkit::TextView::SplitByNewLineChar,
1523                                                                                     Toolkit::TextView::Original,
1524                                                                                     Toolkit::TextView::Original,
1525                                                                                     static_cast<Toolkit::Alignment::Type>( Toolkit::Alignment::HorizontalCenter | Toolkit::Alignment::VerticalCenter ),
1526                                                                                     Toolkit::TextView::Center,
1527                                                                                     PointSize( lineHeightOffset ),
1528                                                                                     std::string( "..." ),
1529                                                                                     true ),
1530                                      resultRelayoutData );
1531
1532   // Choose operation and call appropiate UpdateTextInfo() method.
1533   const Toolkit::Internal::TextView::LayoutParameters layoutParameters( Toolkit::TextView::SplitByNewLineChar,
1534                                                                         Toolkit::TextView::Original,
1535                                                                         Toolkit::TextView::Original,
1536                                                                         static_cast<Toolkit::Alignment::Type>( Toolkit::Alignment::HorizontalCenter | Toolkit::Alignment::VerticalCenter ),
1537                                                                         Toolkit::TextView::Center,
1538                                                                         PointSize( lineHeightOffset ),
1539                                                                         std::string( "..." ),
1540                                                                         true );
1541
1542   switch( operation )
1543   {
1544     case Insert:
1545     {
1546       MarkupProcessor::StyledTextArray inputStyledText;
1547       MarkupProcessor::GetStyledTextArray( inputText, inputStyledText, true );
1548
1549       TextViewProcessor::UpdateTextInfo( position,
1550                                          inputStyledText,
1551                                          layoutParameters,
1552                                          relayoutData );
1553       break;
1554     }
1555     case Remove:
1556     {
1557       TextViewProcessor::UpdateTextInfo( position,
1558                                          numberOfCharacters,
1559                                          layoutParameters,
1560                                          relayoutData,
1561                                          TextViewProcessor::CLEAR_TEXT );
1562       break;
1563     }
1564     case Replace:
1565     {
1566       MarkupProcessor::StyledTextArray inputStyledText;
1567       MarkupProcessor::GetStyledTextArray( inputText, inputStyledText, true );
1568
1569       TextViewProcessor::UpdateTextInfo( position,
1570                                          numberOfCharacters,
1571                                          inputStyledText,
1572                                          layoutParameters,
1573                                          relayoutData );
1574       break;
1575     }
1576     default:
1577     {
1578       tet_printf( "TestUpdateTextInfo: unknown update operation. %s", location );
1579       return false;
1580     }
1581   }
1582
1583   if( !TestEqual( inputLayout, resultLayout ) )
1584   {
1585     tet_printf( "Fail. different layout info. %s", location );
1586
1587     std::cout << "          result : "; Print( inputLayout );
1588     std::cout << " expected result : "; Print( resultLayout );
1589     return false;
1590   }
1591
1592   return true;
1593 }
1594
1595 } // namespace
1596
1597
1598 int UtcDaliTextViewCreateTextInfo(void)
1599 {
1600   ToolkitTestApplication application;
1601
1602   tet_infoline("UtcDaliTextViewCreateTextInfo : ");
1603
1604   // Metrics for characters
1605
1606   // Font size = 10
1607   //     size : [9.48351, 9.48351]
1608   //  advance : 9.48351
1609   //  bearing : 8.53516
1610   // ascender : 8.53516
1611
1612   // Font size = 12
1613   //     size : [11.3802, 11.3802]
1614   //  advance : 11.3802
1615   //  bearing : 10.2422
1616   // ascender : 10.2422
1617
1618   // Font size = 14
1619   //     size : [13.2769, 13.2769]
1620   //  advance : 13.2769
1621   //  bearing : 11.9492
1622   // ascender : 11.9492
1623
1624   const float WIDTH_10( 9.48351f );
1625   const float HEIGHT_10( 9.48351f );
1626   const float ADVANCE_10( 9.48351f );
1627   const float BEARING_10( 8.53516f );
1628   const float ASCENDER_10( 8.53516f );
1629
1630   const float WIDTH_12( 11.3802f );
1631   const float HEIGHT_12( 11.3802f );
1632   const float ADVANCE_12( 11.3802f );
1633   const float BEARING_12( 10.2422f );
1634   const float ASCENDER_12( 10.2422f );
1635
1636
1637   // Generate a text.
1638   Toolkit::Internal::TextView::RelayoutData relayoutData;
1639   TextViewProcessor::TextLayoutInfo& textLayoutInfo( relayoutData.mTextLayoutInfo );
1640
1641   std::string text( "Hel<font size='10'>lo wo</font>rld!\n"
1642                     "\n" );
1643
1644   MarkupProcessor::StyledTextArray styledText;
1645   MarkupProcessor::GetStyledTextArray( text, styledText, true );
1646
1647   TextViewProcessor::CreateTextInfo( styledText,
1648                                      DEFAULT_LAYOUT_PARAMETERS,
1649                                      relayoutData );
1650
1651
1652   // Build the text info with metric values.
1653
1654   // Characters
1655
1656   TextViewProcessor::CharacterLayoutInfo layoutInfo10; // ( [lo wo])
1657   layoutInfo10.mHeight = HEIGHT_10;
1658   layoutInfo10.mAdvance = ADVANCE_10;
1659   layoutInfo10.mBearing = BEARING_10;
1660   layoutInfo10.mSize = Size( WIDTH_10, HEIGHT_10 );
1661   layoutInfo10.mAscender = ASCENDER_10;
1662   TextViewProcessor::CharacterLayoutInfo layoutInfo12; // ( [Hel], [rld!] and [CR])
1663   layoutInfo12.mHeight = HEIGHT_12;
1664   layoutInfo12.mAdvance = ADVANCE_12;
1665   layoutInfo12.mBearing = BEARING_12;
1666   layoutInfo12.mSize = Size( WIDTH_12, HEIGHT_12 );
1667   layoutInfo12.mAscender = ASCENDER_12;
1668
1669   TextStyle style10;
1670   style10.SetFontPointSize( PointSize( 10.f ) );
1671   TextStyle style12;
1672   style12.SetFontPointSize( PointSize( 0.f ) ); // point size is set to zero because is a default point size.
1673
1674   layoutInfo12.mStyledText.mStyle = style12;
1675   layoutInfo10.mStyledText.mStyle = style10;
1676
1677   // Words
1678
1679   TextViewProcessor::WordLayoutInfo wordLayout1, wordLayout2, wordLayout3, wordLayout4;
1680
1681   // Hello
1682   wordLayout1.mSize = Size( 3.f * WIDTH_12 + 2.f * WIDTH_10, HEIGHT_12 );
1683   wordLayout1.mAscender = ASCENDER_12;
1684   wordLayout1.mType = TextViewProcessor::NoSeparator;
1685
1686   layoutInfo12.mStyledText.mText = Text( "H" );
1687   wordLayout1.mCharactersLayoutInfo.push_back( layoutInfo12 ); // H
1688   layoutInfo12.mStyledText.mText = Text( "e" );
1689   wordLayout1.mCharactersLayoutInfo.push_back( layoutInfo12 ); // e
1690   layoutInfo12.mStyledText.mText = Text( "l" );
1691   wordLayout1.mCharactersLayoutInfo.push_back( layoutInfo12 ); // l
1692   layoutInfo10.mStyledText.mText = Text( "l" );
1693   wordLayout1.mCharactersLayoutInfo.push_back( layoutInfo10 ); // l
1694   layoutInfo10.mStyledText.mText = Text( "o" );
1695   wordLayout1.mCharactersLayoutInfo.push_back( layoutInfo10 ); // o
1696
1697   // (white space)
1698   wordLayout2.mSize = Size( WIDTH_10, HEIGHT_10 );
1699   wordLayout2.mAscender = ASCENDER_10;
1700   wordLayout2.mType = TextViewProcessor::WordSeparator;
1701   layoutInfo10.mStyledText.mText = Text( " " );
1702   wordLayout2.mCharactersLayoutInfo.push_back( layoutInfo10 ); // (white space)
1703
1704   // world!
1705   wordLayout3.mSize = Size( 2.f * WIDTH_10 + 4.f * WIDTH_12, HEIGHT_12 );
1706   wordLayout3.mAscender = ASCENDER_12;
1707   wordLayout3.mType = TextViewProcessor::NoSeparator;
1708   layoutInfo10.mStyledText.mText = Text( "w" );
1709   wordLayout3.mCharactersLayoutInfo.push_back( layoutInfo10 ); // w
1710   layoutInfo10.mStyledText.mText = Text( "o" );
1711   wordLayout3.mCharactersLayoutInfo.push_back( layoutInfo10 ); // o
1712   layoutInfo12.mStyledText.mText = Text( "r" );
1713   wordLayout3.mCharactersLayoutInfo.push_back( layoutInfo12 ); // r
1714   layoutInfo12.mStyledText.mText = Text( "l" );
1715   wordLayout3.mCharactersLayoutInfo.push_back( layoutInfo12 ); // l
1716   layoutInfo12.mStyledText.mText = Text( "d" );
1717   wordLayout3.mCharactersLayoutInfo.push_back( layoutInfo12 ); // d
1718   layoutInfo12.mStyledText.mText = Text( "!" );
1719   wordLayout3.mCharactersLayoutInfo.push_back( layoutInfo12 ); // !
1720
1721   // (new line character)
1722   wordLayout4.mSize = Size( 0.f, HEIGHT_12 );
1723   wordLayout4.mAscender = ASCENDER_12;
1724   wordLayout4.mType = TextViewProcessor::LineSeparator;
1725   layoutInfo12.mStyledText.mText = Text( "\n" );
1726   layoutInfo12.mSize.width = 0.f;
1727   wordLayout4.mCharactersLayoutInfo.push_back( layoutInfo12 ); // (new line char)
1728
1729   // Groups
1730
1731   TextViewProcessor::WordGroupLayoutInfo groupLayout1, groupLayout2;
1732
1733   groupLayout1.mSize = Size( 5.f * WIDTH_10 + 7.f * WIDTH_12, HEIGHT_12 );
1734   groupLayout1.mAscender = ASCENDER_12;
1735   groupLayout1.mDirection = TextViewProcessor::LTR;
1736   groupLayout1.mNumberOfCharacters = 13;
1737   groupLayout1.mWordsLayoutInfo.push_back( wordLayout1 );
1738   groupLayout1.mWordsLayoutInfo.push_back( wordLayout2 );
1739   groupLayout1.mWordsLayoutInfo.push_back( wordLayout3 );
1740   groupLayout1.mWordsLayoutInfo.push_back( wordLayout4 );
1741
1742   groupLayout2.mSize = Size( 0.f, HEIGHT_12 );
1743   groupLayout2.mAscender = ASCENDER_12;
1744   groupLayout2.mDirection = TextViewProcessor::LTR;
1745   groupLayout2.mNumberOfCharacters = 1;
1746   groupLayout2.mWordsLayoutInfo.push_back( wordLayout4 );
1747
1748   // Lines
1749
1750   TextViewProcessor::LineLayoutInfo lineLayout1, lineLayout2, lineLayout3;
1751
1752   lineLayout1.mSize = Size( 5.f * WIDTH_10 + 7.f * WIDTH_12, HEIGHT_12 );
1753   lineLayout1.mAscender = ASCENDER_12;
1754   lineLayout1.mNumberOfCharacters = 13;
1755   lineLayout1.mWordGroupsLayoutInfo.push_back( groupLayout1 );
1756
1757   lineLayout2.mSize = Size( 0.f, HEIGHT_12 );
1758   lineLayout2.mAscender = ASCENDER_12;
1759   lineLayout2.mNumberOfCharacters = 1;
1760   lineLayout2.mWordGroupsLayoutInfo.push_back( groupLayout2 );
1761
1762   lineLayout3.mSize = Size( 0.f, HEIGHT_12 );
1763
1764   // Text (layout)
1765   TextViewProcessor::TextLayoutInfo textLayout;
1766
1767   textLayout.mWholeTextSize = Size( 5.f * WIDTH_10 + 7.f * WIDTH_12, 3.f * HEIGHT_12 );
1768   textLayout.mMaxWordWidth = 2.f * WIDTH_10 + 4.f * WIDTH_12;
1769   textLayout.mNumberOfCharacters = 14;
1770   textLayout.mLinesLayoutInfo.push_back( lineLayout1 );
1771   textLayout.mLinesLayoutInfo.push_back( lineLayout2 );
1772   textLayout.mLinesLayoutInfo.push_back( lineLayout3 );
1773
1774   if(!TestEqual( textLayout, textLayoutInfo ))
1775   {
1776     std::cout << "Layout fails" << std::endl;
1777     Print(textLayout); std::cout << std::endl;
1778     Print(textLayoutInfo); std::cout << std::endl;
1779   }
1780
1781   DALI_TEST_CHECK( TestEqual( textLayout, textLayoutInfo ) );
1782   END_TEST;
1783 }
1784
1785 int UtcDaliTextViewSplitWord(void)
1786 {
1787   ToolkitTestApplication application;
1788
1789   tet_infoline("UtcDaliTextViewSplitWord : ");
1790
1791   struct SplitWordTest splitWordTests[] =
1792   {
1793     {
1794       std::string( "Split word, position 0." ),
1795       std::string( "<font size='10'>He<font size='12'>ll</font>oooo</font>" ),
1796       0,
1797       std::string( "" ),
1798       std::string( "<font size='10'>He<font size='12'>ll</font>oooo</font>" ),
1799     },
1800     {
1801       std::string( "Split word, position 8." ),
1802       std::string( "<font size='10'>He<font size='12'>ll</font>oooo</font>" ),
1803       8,
1804       std::string( "<font size='10'>He<font size='12'>ll</font>oooo</font>" ),
1805       std::string( "" ),
1806     },
1807     {
1808       std::string( "Split word, position 2." ),
1809       std::string( "<font size='10'>He<font size='12'>ll</font>oooo</font>" ),
1810       2,
1811       std::string( "<font size='10'>He</font>" ),
1812       std::string( "<font size='12'>ll</font><font size='10'>oooo</font>" ),
1813     },
1814     {
1815       std::string( "Split word, position 3." ),
1816       std::string( "<font size='10'>He<font size='12'>ll</font>oooo</font>" ),
1817       3,
1818       std::string( "<font size='10'>He</font><font size='12'>l</font>" ),
1819       std::string( "<font size='12'>l</font><font size='10'>oooo</font>" ),
1820     },
1821     {
1822       std::string( "Split word, position 4." ),
1823       std::string( "<font size='10'>He<font size='12'>ll</font>oooo</font>" ),
1824       4,
1825       std::string( "<font size='10'>He</font><font size='12'>ll</font>" ),
1826       std::string( "<font size='10'>oooo</font>" ),
1827     },
1828   };
1829   const std::size_t numberOfTests( 5 );
1830
1831   for( std::size_t index = 0; index < numberOfTests; ++index )
1832   {
1833     const SplitWordTest& test = splitWordTests[index];
1834
1835     if( !TestSplitWord( test.description, test.input, test.position, test.firstResult, test.lastResult, TEST_LOCATION ) )
1836     {
1837       tet_result( TET_FAIL );
1838     }
1839   }
1840
1841   tet_result( TET_PASS );
1842   END_TEST;
1843 }
1844
1845 int UtcDaliTextViewUpdateTextInfo(void)
1846 {
1847   ToolkitTestApplication application;
1848
1849   tet_infoline("UtcDaliTextViewUpdateTextInfo : ");
1850
1851   struct UpdateTextInfoTest updateTextInfoTest[] =
1852   {
1853     // Remove operations
1854
1855     {
1856       std::string( "Remove from new line character to first character next line." ),
1857       Remove,
1858       std::string("Hello world\nhello world."),
1859       11,
1860       2,
1861       std::string(""),
1862       0.f,
1863       std::string("Hello worldello world."),
1864     },
1865     {
1866       std::string( "Replace style from new line character to first character next line." ),
1867       Replace,
1868       std::string("Hello world\nhello world."),
1869       11,
1870       2,
1871       std::string("<b>\nh</b>"),
1872       0.f,
1873       std::string("Hello world<b>\nh</b>ello world."),
1874     },
1875     {
1876       std::string( "Remove from the beginning to the middle of last word." ),
1877       Remove,
1878       std::string("Hello world, hello world."),
1879       0,
1880       22,
1881       std::string(), // Not used.
1882       0.f,
1883       std::string("ld."),
1884     },
1885     {
1886       std::string( "Remove from the beginning to the middle of the text." ),
1887       Remove,
1888       std::string("Hello world hello world."),
1889       0,
1890       12,
1891       std::string(), // Not used.
1892       0.f,
1893       std::string("hello world."),
1894     },
1895     // Remove within the same word:
1896     // * within the same group of characters.
1897     {
1898       std::string( "Remove within the same word, within the same group of characters" ),
1899       Remove,
1900       std::string("Hello <font size='30'>world\nhello</font> world"),
1901       7,
1902       3,
1903       std::string(), // Not used.
1904       0.f,
1905       std::string( "Hello <font size='30'>wd\nhello</font> world" )
1906     },
1907     // * whole group of characters (merge adjacent group of characters)
1908     {
1909       std::string( "Remove within the same word, whole group of characters (merge adjacent group of characters)" ),
1910       Remove,
1911       std::string("Hello <font size='30'>w<font size='20'>orl</font>d\nhello</font> world"),
1912       7,
1913       3,
1914       std::string(), // Not used.
1915       0.f,
1916       std::string( "Hello <font size='30'>wd\nhello</font> world" )
1917     },
1918     // * whole group of characters (don't merge adjacent gtoup of characters)
1919     {
1920       std::string( "Remove within the same word, whole group of characters (don't merge adjacent gtoup of characters)" ),
1921       Remove,
1922       std::string("Hello <font size='30'>w</font>orl<font size='10'>d\nhello</font> world"),
1923       7,
1924       3,
1925       std::string(), // Not used.
1926       0.f,
1927       std::string( "Hello <font size='30'>w</font><font size='10'>d\nhello</font> world" )
1928     },
1929     // * Remove whole word (merge words)
1930     {
1931       std::string( "Remove within the same word, whole word (merge words)" ),
1932       Remove,
1933       std::string("Hello <font size='30'>w</font>orl<font size='10'>d\nhello</font> world"),
1934       5,
1935       1,
1936       std::string(), // Not used.
1937       0.f,
1938       std::string( "Hello<font size='30'>w</font>orl<font size='10'>d\nhello</font> world" )
1939     },
1940     // * Remove whole word (don't merge words)
1941     {
1942       std::string( "Remove within the same word, whole word (don't merge words)" ),
1943       Remove,
1944       std::string("Hello <font size='30'>w</font>orl<font size='10'>d\nhello</font> world"),
1945       6,
1946       5,
1947       std::string(), // Not used.
1948       0.f,
1949       std::string( "Hello <font size='10'>\nhello</font> world" )
1950     },
1951     // * Remove whole word (merge lines)
1952     {
1953       std::string( "Remove within the same word, whole word (merge lines)" ),
1954       Remove,
1955       std::string("Hello <font size='30'>w</font>orl<font size='10'>d\nhello</font> world"),
1956       11,
1957       1,
1958       std::string(), // Not used.
1959       0.f,
1960       std::string( "Hello <font size='30'>w</font>orl<font size='10'>dhello</font> world" )
1961     },
1962     // * Remove whole group of words
1963     /* TODO check this when RTL text is working
1964     {
1965       std::string( "Remove within the same line, whole group of words (merge groups)" ),
1966       Remove,
1967       std::string("Hello world, שלום עולם, hello world"),
1968       10,
1969       15,
1970       std::string(), // Not used.
1971       0.f,
1972       std::string( "Hello worlello world" )
1973     },
1974     */
1975     // * Remove whole line
1976     {
1977       std::string( "Remove whole line" ),
1978       Remove,
1979       std::string("Hello world, hello world\n"
1980                   "Hello world, hello world\n"
1981                   "Hello world, hello world\n"
1982                   "Hello world, hello world\n"),
1983       25,
1984       25,
1985       std::string(), // Not used.
1986       0.f,
1987       std::string("Hello world, hello world\n"
1988                   "Hello world, hello world\n"
1989                   "Hello world, hello world\n"),
1990     },
1991     {
1992       std::string( "Remove whole line" ),
1993       Remove,
1994       std::string("Hello world, hello world\n"
1995                   "H"),
1996       25,
1997       1,
1998       std::string(), // Not used.
1999       0.f,
2000       std::string("Hello world, hello world\n"),
2001     },
2002
2003
2004     // Insert operations
2005     {
2006       std::string( "insert some text" ),
2007       Insert,
2008       std::string("inpuext"),
2009       4,
2010       0,             // Not used
2011       std::string( "t t" ),
2012       0.f,
2013       std::string( "input text" )
2014     },
2015     {
2016       std::string( "Insert text at the end" ),
2017       Insert,
2018       std::string("touch "),
2019       6,
2020       0,
2021       std::string("me\nhello"),
2022       0.f,
2023       std::string("touch me\nhello")
2024     },
2025
2026     // Replace operations.
2027     {
2028       std::string( "Replace style from the beginning to some point in the middle of the text." ),
2029       Replace,
2030       std::string( "Hello <font color='green'>world</font>" ),
2031       0,
2032       7,
2033       std::string( "<font color='red'>Hello w</font>" ),
2034       0.f,
2035       std::string( "<font color='red'>Hello w</font><font color='green'>orld</font>" )
2036     },
2037     {
2038       std::string( "Replace style from the middle of the text to the end." ),
2039       Replace,
2040       std::string( "Touch me\nhello" ),
2041       6,
2042       8,
2043       std::string( "<b>me\nhello</b>" ),
2044       0.f,
2045       std::string( "Touch <b>me\nhello</b>" )
2046     },
2047     {
2048       std::string( "Remove characters from text. Previous next test:Replace style from the middle of the text 1." ),
2049       Remove,
2050       std::string( "Touch me\nhello\nworld" ),
2051       6,
2052       8,
2053       std::string( "" ),
2054       0.f,
2055       std::string( "Touch \nworld" )
2056     },
2057     {
2058       std::string( "Insert styled text in the middle of a text. Previous: Replace style from the middle of the text 1." ),
2059       Insert,
2060       std::string( "Touch \nworld" ),
2061       6,
2062       0,
2063       std::string( "<b>me\nhello</b>" ),
2064       0.f,
2065       std::string( "Touch <b>me\nhello</b>\nworld" )
2066     },
2067     {
2068       std::string( "Replace style from the middle of the text 1." ),
2069       Replace,
2070       std::string( "Touch me\nhello\nworld" ),
2071       6,
2072       8,
2073       std::string( "<b>me\nhello</b>" ),
2074       0.f,
2075       std::string( "Touch <b>me\nhello</b>\nworld" )
2076     },
2077     {
2078       std::string( "Remove characters from text. Previous next test:Replace style from the middle of the text 2." ),
2079       Remove,
2080       std::string( "Touch me\nhello\nworld" ),
2081       6,
2082       9,
2083       std::string( "" ),
2084       0.f,
2085       std::string( "Touch world" )
2086     },
2087     {
2088       std::string( "Replace style from the middle of the text 2." ),
2089       Replace,
2090       std::string( "Touch me\nhello\nworld" ),
2091       6,
2092       9,
2093       std::string( "<b>me\nhello\n</b>" ),
2094       0.f,
2095       std::string( "Touch <b>me\nhello\n</b>world" )
2096     },
2097   };
2098   const std::size_t numberOfTests( 21 );
2099
2100   for( std::size_t index = 0; index < numberOfTests; ++index )
2101   {
2102     const UpdateTextInfoTest& test = updateTextInfoTest[index];
2103
2104     if( !TestUpdateTextInfo( test.description, test.operation, test.input, test.position, test.numberOfCharacters, test.inputText, test.lineHeightOffset, test.result, TEST_LOCATION ) )
2105     {
2106       tet_result( TET_FAIL );
2107     }
2108   }
2109
2110   tet_result( TET_PASS );
2111   END_TEST;
2112 }
2113
2114 int UtcDaliTextViewSplitWordGroup(void)
2115 {
2116   ToolkitTestApplication application;
2117
2118   tet_infoline("UtcDaliTextViewSplitWordGroup : ");
2119
2120   struct SplitWordGroupTest splitWordGroupTests[] =
2121   {
2122     {
2123       std::string( "Split word group, wordPosition 0, position 0." ),
2124       std::string( "<u><font size='10'>He<font size='12'>ll</font>oooo wooorld</font></u>" ),
2125       0,
2126       0,
2127       std::string( "" ),
2128       std::string( "<u><font size='10'>He<font size='12'>ll</font>oooo wooorld</font></u>" ),
2129     },
2130     {
2131       std::string( "Split word group, wordPosition 2, position 8." ),
2132       std::string( "<font size='10'>He<font size='12'>ll</font>oooo wooorld</font>" ),
2133       2,
2134       7,
2135       std::string( "<font size='10'>He<font size='12'>ll</font>oooo wooorld</font>" ),
2136       std::string( "" ),
2137     },
2138     {
2139       std::string( "Split word group, wordPosition 0, position 2." ),
2140       std::string( "<font size='10'>He<font size='12'>ll</font>oooo wooorld</font>" ),
2141       0,
2142       2,
2143       std::string( "<font size='10'>He</font>" ),
2144       std::string( "<font size='12'>ll</font><font size='10'>oooo wooorld</font>" ),
2145     },
2146     {
2147       std::string( "Split word group, wordPosition 0, position 3." ),
2148       std::string( "<font size='10'>He<font size='12'>ll</font>oooo wooorld</font>" ),
2149       0,
2150       3,
2151       std::string( "<font size='10'>He</font><font size='12'>l</font>" ),
2152       std::string( "<font size='12'>l</font><font size='10'>oooo wooorld</font>" ),
2153     },
2154     {
2155       std::string( "Split word group, wordPosition 0, position 4." ),
2156       std::string( "<font size='10'>He<font size='12'>ll</font>oooo wooorld</font>" ),
2157       0,
2158       4,
2159       std::string( "<font size='10'>He</font><font size='12'>ll</font>" ),
2160       std::string( "<font size='10'>oooo wooorld</font>" ),
2161     },
2162     {
2163       std::string( "Split word group, wordPosition 1, position 0." ),
2164       std::string( "<font size='10'>He<font size='12'>ll</font>oooo wooorld</font>" ),
2165       1,
2166       0,
2167       std::string( "<font size='10'>He<font size='12'>ll</font>oooo</font>" ),
2168       std::string( "<font size='10'> wooorld</font>" ),
2169     },
2170   };
2171   const std::size_t numberOfTests( 6 );
2172
2173   for( std::size_t index = 0; index < numberOfTests; ++index )
2174   {
2175     const SplitWordGroupTest& test = splitWordGroupTests[index];
2176
2177     if( !TestSplitWordGroup( test.description, test.input, test.wordPosition, test.position, test.firstResult, test.lastResult, TEST_LOCATION ) )
2178     {
2179       tet_result( TET_FAIL );
2180     }
2181   }
2182
2183   tet_result( TET_PASS );
2184   END_TEST;
2185 }
2186
2187 int UtcDaliTextViewSplitLine(void)
2188 {
2189   ToolkitTestApplication application;
2190
2191   tet_infoline("UtcDaliTextViewSplitLine : ");
2192
2193   struct SplitLineTest splitLineTests[] =
2194   {
2195     {
2196       std::string( "Split line, groupPosition 0, wordPosition 0, position 0." ),
2197       std::string( "<font size='10'>He<font size='12'>ll</font>oooo wooorld</font> שלום עולם text text" ),
2198       0,
2199       0,
2200       0,
2201       3.f,
2202       std::string( "" ),
2203       std::string( "<font size='10'>He<font size='12'>ll</font>oooo wooorld</font> שלום עולם text text" ),
2204     },
2205     {
2206       std::string( "Split line, groupPosition 2, wordPosition 2, position 4." ),
2207       std::string( "<font size='10'>He<font size='12'>ll</font>oooo wooorld</font> שלום עולם text text" ),
2208       2,
2209       2,
2210       4,
2211       0.f,
2212       std::string( "<font size='10'>He<font size='12'>ll</font>oooo wooorld</font> שלום עולם text text" ),
2213       std::string( "" ),
2214     },
2215     /* TODO check when RTL is working.
2216     {
2217       std::string( "Split line, groupPosition 1, wordPosition 2, position 0." ),
2218       std::string( "<font size='10'>He<font size='12'>ll</font>oooo wooorld</font> שלום עולם text text" ),
2219       1,
2220       2,
2221       0,
2222       0.f,
2223       std::string( "<font size='10'>He<font size='12'>ll</font>oooo wooorld</font> שלום" ),
2224       std::string( " עולם text text" ),
2225     },
2226     {
2227       std::string( "Split line, groupPosition 1, wordPosition 0, position 0." ),
2228       std::string( "<font size='10'>He<font size='12'>ll</font>oooo wooorld</font> שלום עולם text text" ),
2229       1,
2230       0,
2231       0,
2232       0.f,
2233       std::string( "<font size='10'>He<font size='12'>ll</font>oooo wooorld</font> " ),
2234       std::string( "שלום עולם text text" ),
2235     },
2236     */
2237     {
2238       std::string( "Split line, groupPosition 2, wordPosition 0, position 0." ),
2239       std::string( "<font size='10'>He<font size='12'>ll</font>oooo wooorld</font> שלום עולם text text" ),
2240       2,
2241       0,
2242       0,
2243       6.f,
2244       std::string( "<font size='10'>He<font size='12'>ll</font>oooo wooorld</font> שלום עולם " ),
2245       std::string( "text text" ),
2246     },
2247   };
2248   const std::size_t numberOfTests( 3 );
2249
2250   for( std::size_t index = 0; index < numberOfTests; ++index )
2251   {
2252     const SplitLineTest& test = splitLineTests[index];
2253
2254     if( !TestSplitLine( test.description, test.input, test.groupPosition, test.wordPosition, test.position, test.lineHeightOffset, test.firstResult, test.lastResult, TEST_LOCATION ) )
2255     {
2256       tet_result( TET_FAIL );
2257     }
2258   }
2259
2260   tet_result( TET_PASS );
2261   END_TEST;
2262 }
2263
2264 int UtcDaliTextViewMergeWord01(void)
2265 {
2266   ToolkitTestApplication application;
2267
2268   tet_infoline("UtcDaliTextViewMergeWord01 : ");
2269
2270   struct MergeWordsTest mergeWordsTests[] =
2271   {
2272     {
2273       std::string( "Merge words with same style." ),
2274       std::string( "Hel" ),
2275       std::string( "lo" ),
2276       std::string( "Hello" ),
2277     },
2278     {
2279       std::string( "Merge words with different styles." ),
2280       std::string( "<font size='10>Hel</font>" ),
2281       std::string( "<font size='20'>lo</font>" ),
2282       std::string( "<font size='10'>Hel</font><font size='20'>lo</font>" )
2283     },
2284   };
2285   const std::size_t numberOfTests( 2 );
2286
2287   for( std::size_t index = 0; index < numberOfTests; ++index )
2288   {
2289     const MergeWordsTest& test = mergeWordsTests[index];
2290
2291     if( !TestMergeWords( test.description, test.inputFirst, test.inputLast, test.result, TEST_LOCATION ) )
2292     {
2293       tet_result( TET_FAIL );
2294     }
2295   }
2296
2297   tet_result( TET_PASS );
2298   END_TEST;
2299 }
2300
2301 int UtcDaliTextViewMergeWord02(void)
2302 {
2303   // Negative test.
2304   // It test white spaces and new line characters can't be merged to other words.
2305
2306   ToolkitTestApplication application;
2307
2308   tet_infoline("UtcDaliTextViewMergeWord02 : ");
2309
2310   // Generate three words
2311
2312   Toolkit::Internal::TextView::RelayoutData relayoutData01;
2313   Toolkit::Internal::TextView::RelayoutData relayoutData02;
2314   Toolkit::Internal::TextView::RelayoutData relayoutData03;
2315   TextViewProcessor::TextLayoutInfo& textLayoutInfo01( relayoutData01.mTextLayoutInfo );
2316   TextViewProcessor::TextLayoutInfo& textLayoutInfo02( relayoutData02.mTextLayoutInfo );
2317   TextViewProcessor::TextLayoutInfo& textLayoutInfo03( relayoutData03.mTextLayoutInfo );
2318
2319   std::string text01( " " );
2320   std::string text02( "\n" );
2321   std::string text03( "a" );
2322   MarkupProcessor::StyledTextArray styledText01;
2323   MarkupProcessor::StyledTextArray styledText02;
2324   MarkupProcessor::StyledTextArray styledText03;
2325   MarkupProcessor::GetStyledTextArray( text01, styledText01, true );
2326   MarkupProcessor::GetStyledTextArray( text02, styledText02, true );
2327   MarkupProcessor::GetStyledTextArray( text03, styledText03, true );
2328
2329   TextViewProcessor::CreateTextInfo( styledText01,
2330                                      DEFAULT_LAYOUT_PARAMETERS,
2331                                      relayoutData01 );
2332
2333   TextViewProcessor::WordLayoutInfo wordLayoutInfo01;
2334
2335   wordLayoutInfo01 = *( *( *textLayoutInfo01.mLinesLayoutInfo.begin() ).mWordGroupsLayoutInfo.begin() ).mWordsLayoutInfo.begin();
2336
2337   TextViewProcessor::CreateTextInfo( styledText02,
2338                                      DEFAULT_LAYOUT_PARAMETERS,
2339                                      relayoutData02 );
2340
2341   TextViewProcessor::WordLayoutInfo wordLayoutInfo02;
2342
2343   wordLayoutInfo02 = *( *( *textLayoutInfo02.mLinesLayoutInfo.begin() ).mWordGroupsLayoutInfo.begin() ).mWordsLayoutInfo.begin();
2344
2345   TextViewProcessor::CreateTextInfo( styledText03,
2346                                      DEFAULT_LAYOUT_PARAMETERS,
2347                                      relayoutData03 );
2348
2349   TextViewProcessor::WordLayoutInfo wordLayoutInfo03;
2350
2351   wordLayoutInfo03 = *( *( *textLayoutInfo03.mLinesLayoutInfo.begin() ).mWordGroupsLayoutInfo.begin() ).mWordsLayoutInfo.begin();
2352
2353   // Test MergeWord() asserts if white spaces or new line chars are merged.
2354   bool assert1 = false;
2355   bool assert2 = false;
2356   bool assert3 = false;
2357   bool assert4 = false;
2358   bool assert5 = false;
2359   bool assert6 = false;
2360
2361   try
2362   {
2363     MergeWord( wordLayoutInfo01,
2364                wordLayoutInfo02 );
2365   }
2366   catch( Dali::DaliException& e )
2367   {
2368     tet_printf( "Assertion %s failed at %s\n", e.mCondition.c_str(), e.mLocation.c_str() );
2369     DALI_TEST_EQUALS( e.mCondition, "!\"TextViewProcessor::MergeWord(). ERROR: White spaces or new line characters can't be merged with other words.\"", TEST_LOCATION );
2370     assert1 = true;
2371   }
2372   try
2373   {
2374     MergeWord( wordLayoutInfo01,
2375                wordLayoutInfo03 );
2376   }
2377   catch( Dali::DaliException& e )
2378   {
2379     tet_printf( "Assertion %s failed at %s\n", e.mCondition.c_str(), e.mLocation.c_str() );
2380     DALI_TEST_EQUALS( e.mCondition, "!\"TextViewProcessor::MergeWord(). ERROR: White spaces or new line characters can't be merged with other words.\"", TEST_LOCATION );
2381     assert2 = true;
2382   }
2383   try
2384   {
2385     MergeWord( wordLayoutInfo02,
2386                wordLayoutInfo01 );
2387   }
2388   catch( Dali::DaliException& e )
2389   {
2390     tet_printf( "Assertion %s failed at %s\n", e.mCondition.c_str(), e.mLocation.c_str() );
2391     DALI_TEST_EQUALS( e.mCondition, "!\"TextViewProcessor::MergeWord(). ERROR: White spaces or new line characters can't be merged with other words.\"", TEST_LOCATION );
2392     assert3 = true;
2393   }
2394   try
2395   {
2396     MergeWord( wordLayoutInfo02,
2397                wordLayoutInfo03 );
2398   }
2399   catch( Dali::DaliException& e )
2400   {
2401     tet_printf( "Assertion %s failed at %s\n", e.mCondition.c_str(), e.mLocation.c_str() );
2402     DALI_TEST_EQUALS( e.mCondition, "!\"TextViewProcessor::MergeWord(). ERROR: White spaces or new line characters can't be merged with other words.\"", TEST_LOCATION );
2403     assert4 = true;
2404   }
2405   try
2406   {
2407     MergeWord( wordLayoutInfo03,
2408                wordLayoutInfo01 );
2409   }
2410   catch( Dali::DaliException& e )
2411   {
2412     tet_printf( "Assertion %s failed at %s\n", e.mCondition.c_str(), e.mLocation.c_str() );
2413     DALI_TEST_EQUALS( e.mCondition, "!\"TextViewProcessor::MergeWord(). ERROR: White spaces or new line characters can't be merged with other words.\"", TEST_LOCATION );
2414     assert5 = true;
2415   }
2416   try
2417   {
2418     MergeWord( wordLayoutInfo03,
2419                wordLayoutInfo02 );
2420   }
2421   catch( Dali::DaliException& e )
2422   {
2423     tet_printf( "Assertion %s failed at %s\n", e.mCondition.c_str(), e.mLocation.c_str() );
2424     DALI_TEST_EQUALS( e.mCondition, "!\"TextViewProcessor::MergeWord(). ERROR: White spaces or new line characters can't be merged with other words.\"", TEST_LOCATION );
2425     assert6 = true;
2426   }
2427
2428   if( assert1 && assert2 && assert3 && assert4 && assert5 && assert6 )
2429   {
2430     tet_result( TET_PASS );
2431   }
2432   else
2433   {
2434     tet_result( TET_FAIL );
2435   }
2436   END_TEST;
2437 }
2438
2439 int UtcDaliTextViewMergeGroup01(void)
2440 {
2441   ToolkitTestApplication application;
2442
2443   tet_infoline("UtcDaliTextViewMergeGroup01 : ");
2444
2445   struct MergeWordGroupsTest mergeWordGroupssTests[] =
2446   {
2447     {
2448       std::string( "Merge a void first group." ),
2449       std::string( "" ),
2450       std::string( "Hello world" ),
2451       std::string( "Hello world" ),
2452     },
2453     {
2454       std::string( "Merge a void last group." ),
2455       std::string( "Hello world" ),
2456       std::string( "" ),
2457       std::string( "Hello world" ),
2458     },
2459     {
2460       std::string( "Merge groups and merge last and first words." ),
2461       std::string( "Hello wor" ),
2462       std::string( "ld, hello world" ),
2463       std::string( "Hello world, hello world" ),
2464     },
2465     {
2466       std::string( "Merge groups and don't merge last and first words." ),
2467       std::string( "Hello world, " ),
2468       std::string( "hello world" ),
2469       std::string( "Hello world, hello world" )
2470     },
2471   };
2472   const std::size_t numberOfTests( 4 );
2473
2474   for( std::size_t index = 0; index < numberOfTests; ++index )
2475   {
2476     const MergeWordGroupsTest& test = mergeWordGroupssTests[index];
2477
2478     if( !TestMergeGroupsOfWords( test.description, test.inputFirst, test.inputLast, test.result, TEST_LOCATION ) )
2479     {
2480       tet_result( TET_FAIL );
2481     }
2482   }
2483
2484   tet_result(TET_PASS);
2485   END_TEST;
2486 }
2487
2488 int UtcDaliTextViewMergeGroup02(void)
2489 {
2490   ToolkitTestApplication application;
2491
2492   tet_infoline("UtcDaliTextViewMergeGroup02 : ");
2493
2494   Toolkit::Internal::TextView::RelayoutData relayoutData01;
2495   Toolkit::Internal::TextView::RelayoutData relayoutData02;
2496   Toolkit::Internal::TextView::RelayoutData relayoutData03;
2497   TextViewProcessor::TextLayoutInfo& textLayoutInfo01( relayoutData01.mTextLayoutInfo );
2498   TextViewProcessor::TextLayoutInfo& textLayoutInfo02( relayoutData02.mTextLayoutInfo );
2499   TextViewProcessor::TextLayoutInfo& textLayoutInfo03( relayoutData03.mTextLayoutInfo );
2500
2501   std::string text01( "Hello \n" );
2502   std::string text02( "world" );
2503   std::string text03( "السلام عليكم" );
2504   MarkupProcessor::StyledTextArray styledText01;
2505   MarkupProcessor::StyledTextArray styledText02;
2506   MarkupProcessor::StyledTextArray styledText03;
2507   MarkupProcessor::GetStyledTextArray( text01, styledText01, true );
2508   MarkupProcessor::GetStyledTextArray( text02, styledText02, true );
2509   MarkupProcessor::GetStyledTextArray( text03, styledText03, true );
2510
2511   TextViewProcessor::CreateTextInfo( styledText01,
2512                                      DEFAULT_LAYOUT_PARAMETERS,
2513                                      relayoutData01 );
2514
2515   TextViewProcessor::WordGroupLayoutInfo wordGroupLayoutInfo01;
2516
2517   wordGroupLayoutInfo01 = *( *textLayoutInfo01.mLinesLayoutInfo.begin() ).mWordGroupsLayoutInfo.begin();
2518
2519   TextViewProcessor::CreateTextInfo( styledText02,
2520                                      DEFAULT_LAYOUT_PARAMETERS,
2521                                      relayoutData02 );
2522
2523   TextViewProcessor::WordGroupLayoutInfo wordGroupLayoutInfo02;
2524
2525   wordGroupLayoutInfo02 = *( *textLayoutInfo02.mLinesLayoutInfo.begin() ).mWordGroupsLayoutInfo.begin();
2526
2527   TextViewProcessor::CreateTextInfo( styledText03,
2528                                      DEFAULT_LAYOUT_PARAMETERS,
2529                                      relayoutData03 );
2530
2531   TextViewProcessor::WordGroupLayoutInfo wordGroupLayoutInfo03;
2532
2533   wordGroupLayoutInfo03 = *( *textLayoutInfo03.mLinesLayoutInfo.begin() ).mWordGroupsLayoutInfo.begin();
2534
2535   bool assert1 = false;
2536   bool assert2 = false;
2537
2538   try
2539   {
2540     MergeWordGroup( wordGroupLayoutInfo01,
2541                     wordGroupLayoutInfo02 );
2542   }
2543   catch( Dali::DaliException& e )
2544   {
2545     tet_printf( "Assertion %s failed at %s\n", e.mCondition.c_str(), e.mLocation.c_str() );
2546     DALI_TEST_EQUALS( e.mCondition, "!\"TextViewProcessor::MergeWordGroup(). ERROR: A group of words can't be merged to another group which finishes with a new line character.\"", TEST_LOCATION );
2547     assert1 = true;
2548   }
2549
2550   try
2551   {
2552     MergeWordGroup( wordGroupLayoutInfo03,
2553                     wordGroupLayoutInfo02 );
2554   }
2555   catch( Dali::DaliException& e )
2556   {
2557     tet_printf( "Assertion %s failed at %s\n", e.mCondition.c_str(), e.mLocation.c_str() );
2558     DALI_TEST_EQUALS( e.mCondition, "!\"TextViewProcessor::MergeWordGroup(). ERROR: groups with different direction can't be merged.\"", TEST_LOCATION );
2559     assert2 = true;
2560   }
2561
2562   if( assert1 && assert2 )
2563   {
2564     tet_result( TET_PASS );
2565   }
2566   else
2567   {
2568     tet_result( TET_FAIL );
2569   }
2570   END_TEST;
2571 }
2572
2573 int UtcDaliTextViewMergeLine01(void)
2574 {
2575   ToolkitTestApplication application;
2576
2577   tet_infoline("UtcDaliTextViewMergeLine01 : ");
2578
2579   struct MergeLinesTest mergeLinesTests[] =
2580   {
2581     {
2582       std::string( "Merge a void first line." ),
2583       std::string( "" ),
2584       std::string( "Hello world, this is a whole line" ),
2585       2.f,
2586       std::string( "Hello world, this is a whole line" )
2587     },
2588     {
2589       std::string( "Merge a void last line." ),
2590       std::string( "Hello world, this is a whole line" ),
2591       std::string( "" ),
2592       0.f,
2593       std::string( "Hello world, this is a whole line" )
2594     },
2595     /* TODO: check when RTL text is working.
2596     {
2597       std::string( "Merge lines and merge last and first groups" ),
2598       std::string( "Hello world, שלום" ),
2599       std::string( " עולם, hello world." ),
2600       6.f,
2601       std::string( "Hello world, שלום עולם, hello world." )
2602     },
2603     {
2604       std::string( "Merge lines and don't merge last and first words." ),
2605       std::string( "Hello world, " ),
2606       std::string( "שלום עולם, hello world." ),
2607       3.f,
2608       std::string( "Hello world, שלום עולם, hello world." )
2609     },
2610     */
2611     {
2612       std::string( "Merge lines. Don't merge words" ),
2613       std::string( "Hello world," ),
2614       std::string( " this is a whole line" ),
2615       0.f,
2616       std::string( "Hello world, this is a whole line" )
2617     },
2618     {
2619       std::string( "Merge lines. Merge words" ),
2620       std::string( "Hello world, th" ),
2621       std::string( "is is a whole line" ),
2622       0.f,
2623       std::string( "Hello world, this is a whole line" )
2624     },
2625   };
2626   const std::size_t numberOfTests( 4 );
2627
2628   for( std::size_t index = 0; index < numberOfTests; ++index )
2629   {
2630     const MergeLinesTest& test = mergeLinesTests[index];
2631
2632     if( !TestMergeLines( test.description, test.inputFirst, test.inputLast, test.lineHeightOffset, test.result, TEST_LOCATION ) )
2633     {
2634       tet_result( TET_FAIL );
2635     }
2636   }
2637
2638   tet_result( TET_PASS );
2639   END_TEST;
2640 }
2641
2642 int UtcDaliTextViewMergeLine02(void)
2643 {
2644   ToolkitTestApplication application;
2645
2646   tet_infoline("UtcDaliTextViewMergeLine02 : ");
2647
2648   Toolkit::Internal::TextView::RelayoutData relayoutData01;
2649   Toolkit::Internal::TextView::RelayoutData relayoutData02;
2650   TextViewProcessor::TextLayoutInfo& textLayoutInfo01( relayoutData01.mTextLayoutInfo );
2651   TextViewProcessor::TextLayoutInfo& textLayoutInfo02( relayoutData02.mTextLayoutInfo );
2652
2653   std::string text01( "Hello world\n" );
2654   std::string text02( "hello world" );
2655   MarkupProcessor::StyledTextArray styledText01;
2656   MarkupProcessor::StyledTextArray styledText02;
2657   MarkupProcessor::GetStyledTextArray( text01, styledText01, true );
2658   MarkupProcessor::GetStyledTextArray( text02, styledText02, true );
2659
2660   TextViewProcessor::CreateTextInfo( styledText01,
2661                                      DEFAULT_LAYOUT_PARAMETERS,
2662                                      relayoutData01 );
2663
2664   TextViewProcessor::LineLayoutInfo lineLayoutInfo01;
2665
2666   lineLayoutInfo01 = *textLayoutInfo01.mLinesLayoutInfo.begin();
2667
2668   TextViewProcessor::CreateTextInfo( styledText02,
2669                                      DEFAULT_LAYOUT_PARAMETERS,
2670                                      relayoutData02 );
2671
2672   TextViewProcessor::LineLayoutInfo lineLayoutInfo02;
2673
2674   lineLayoutInfo02 = *textLayoutInfo02.mLinesLayoutInfo.begin();
2675
2676   bool assert1 = false;
2677
2678   try
2679   {
2680     MergeLine( lineLayoutInfo01,
2681                lineLayoutInfo02 );
2682   }
2683   catch( Dali::DaliException& e )
2684   {
2685     tet_printf( "Assertion %s failed at %s\n", e.mCondition.c_str(), e.mLocation.c_str() );
2686     DALI_TEST_EQUALS( e.mCondition, "!\"TextViewProcessor::MergeLine(). ERROR: A line can't be merged to another line which finishes with a new line character.\"", TEST_LOCATION );
2687     assert1 = true;
2688   }
2689
2690   if( assert1 )
2691   {
2692     tet_result( TET_PASS );
2693   }
2694   else
2695   {
2696     tet_result( TET_FAIL );
2697   }
2698   END_TEST;
2699 }
2700
2701 int UtcDaliTextViewRemoveCharactersFromWord(void)
2702 {
2703   ToolkitTestApplication application;
2704
2705   tet_infoline("UtcDaliTextViewMergeWord02 : ");
2706
2707   struct RemoveCharactersFromWordTest removeCharactersFromWordTests[] =
2708   {
2709     {
2710       std::string( "Delete 0 characters." ),
2711       std::string( "Hello" ),
2712       3,
2713       0,
2714       std::string( "Hello" ),
2715     },
2716     {
2717       std::string( "Delete within the same group of characters. Starting from the beginning" ),
2718       std::string( "Hello" ),
2719       0,
2720       3,
2721       std::string( "lo" ),
2722     },
2723     {
2724       std::string( "Delete within the same group of characters. Somewhere in the middle" ),
2725       std::string( "Hello" ),
2726       2,
2727       2,
2728       std::string( "Heo" ),
2729     },
2730     {
2731       std::string( "Delete within the same group of characters. Starting somewhere in the middle to the end" ),
2732       std::string( "Hello" ),
2733       3,
2734       2,
2735       std::string( "Hel" ),
2736     },
2737     {
2738       std::string( "Delete within the same group of characters. Finish just before a new one." ),
2739       std::string( "<font size='10'>Hel</font><font size='20'>loWo</font><font size='30'>rld</font>" ),
2740       1,
2741       2,
2742       std::string( "<font size='10'>H</font><font size='20'>loWo</font><font size='30'>rld</font>" ),
2743     },
2744     {
2745       std::string( "Delete starting in one group of characters and finishing in a different one. No merge of groups." ),
2746       std::string( "<font size='10'>Hel</font><font size='20'>loWo</font><font size='30'>rld</font>" ),
2747       2,
2748       3,
2749       std::string( "<font size='10'>He</font><font size='20'>Wo</font><font size='30'>rld</font>" ),
2750     },
2751     {
2752       std::string( "Delete within the same group of characters. Starting just after a different one." ),
2753       std::string( "<font size='10'>Hel</font><font size='20'>loWo</font><font size='30'>rld</font>" ),
2754       7,
2755       2,
2756       std::string( "<font size='10'>Hel</font><font size='20'>loWo</font><font size='30'>d</font>" ),
2757     },
2758     {
2759       std::string( "Delete whole group of characters. No merge" ),
2760       std::string( "<font size='10'>Hel</font><font size='20'>loWo</font><font size='30'>rld</font>" ),
2761       3,
2762       4,
2763       std::string( "<font size='10'>Hel</font><font size='30'>rld</font>" ),
2764     },
2765     {
2766       std::string( "Delete whole group of characters and part of the adjacent ones. No merge" ),
2767       std::string( "<font size='10'>Hel</font><font size='20'>loWo</font><font size='30'>rld</font>" ),
2768       2,
2769       6,
2770       std::string( "<font size='10'>He</font><font size='30'>ld</font>" ),
2771     },
2772     {
2773       std::string( "Delete whole group of characters. Merge" ),
2774       std::string( "<font size='10'>Hel</font><font size='20'>loWo</font><font size='10'>rld</font>" ),
2775       3,
2776       4,
2777       std::string( "<font size='10'>Helrld</font>" ),
2778     },
2779     {
2780       std::string( "Delete whole group of characters and part of the adjacent ones. Merge" ),
2781       std::string( "<font size='10'>Hel</font><font size='20'>loWo</font><font size='10'>rld</font>" ),
2782       2,
2783       6,
2784       std::string( "<font size='10'>Held</font>" ),
2785     },
2786   };
2787   const std::size_t numberOfTests( 11 );
2788
2789   for( std::size_t index = 0; index < numberOfTests; ++index )
2790   {
2791     const RemoveCharactersFromWordTest& test = removeCharactersFromWordTests[index];
2792
2793     if( !TestRemoveCharactersFromWord( test.description, test.input, test.position, test.numberOfCharacters, test.result, TEST_LOCATION ) )
2794     {
2795       tet_result( TET_FAIL );
2796     }
2797   }
2798
2799   tet_result( TET_PASS );
2800   END_TEST;
2801 }
2802
2803 int UtcDaliTextViewRemoveWordsFromGroup(void)
2804 {
2805   // Note: Currently RemoveWordsFromWordGroup() function is only used to remove a number of words from the beginning, or
2806   //       from a given index to the end. RemoveWordsFromWordGroup() doesn't merge words (if a white space is removed) so
2807   //       tehere isn't any TET case to cover these cases. To be done if needed.
2808
2809   ToolkitTestApplication application;
2810
2811   tet_infoline("UtcDaliTextViewRemoveWordsFromGroup : ");
2812   struct RemoveWordsFromGroupTest removeWordsFromGroupTests[] =
2813   {
2814     {
2815       std::string( "Delete 0 words." ),
2816       std::string( "Hello world, hello world" ),
2817       3,
2818       0,
2819       std::string( "Hello world, hello world" ),
2820     },
2821     {
2822       std::string( "Delete some words in the middle. Don't merge words" ),
2823       std::string( "<font size='10'>Hel</font><font size='20'>lo wo</font><font size='30'>rld, hello world</font>" ),
2824       1,
2825       4,
2826       std::string( "<font size='10'>Hel</font><font size='20'>lo</font><font size='30'> world</font>" ),
2827     },
2828     {
2829       std::string( "Delete words up to the end" ),
2830       std::string( "<font size='10'>Hel</font><font size='20'>lo wo</font><font size='30'>rld, hello world</font>" ),
2831       5,
2832       2,
2833       std::string( "<font size='10'>Hel</font><font size='20'>lo wo</font><font size='30'>rld, hello</font>" ),
2834     },
2835     {
2836       std::string( "Delete words from the beginning." ),
2837       std::string( "Hello world, hello world" ),
2838       0,
2839       3,
2840       std::string( " hello world" ),
2841     },
2842   };
2843   const std::size_t numberOfTests( 4 );
2844
2845   for( std::size_t index = 0; index < numberOfTests; ++index )
2846   {
2847     const RemoveWordsFromGroupTest& test = removeWordsFromGroupTests[index];
2848
2849     if( !TestRemoveWordsFromGroup( test.description, test.input, test.wordIndex, test.numberOfWords, test.result, TEST_LOCATION ) )
2850     {
2851       tet_result( TET_FAIL );
2852     }
2853   }
2854
2855   tet_result( TET_PASS );
2856   END_TEST;
2857 }
2858
2859 int UtcDaliTextViewRemoveGroupsFromLine(void)
2860 {
2861   // Note: Currently RemoveWordGroupsFromLine() function is only used to remove a number of group of words from the beginning, or
2862   //       from a given index to the end. RemoveWordGroupsFromLine() doesn't merge groups of words (if a whole group of words is removed) so
2863   //       tehere isn't any TET case to cover these cases. To be done if needed.
2864
2865   ToolkitTestApplication application;
2866
2867   tet_infoline("UtcDaliTextViewRemoveGroupsFromLine : ");
2868   struct RemoveGroupsFromLineTest removeGroupsFromLineTests[] =
2869   {
2870     {
2871       std::string( "Delete 0 groups of words." ),
2872       std::string( "Hello hello, שלום עולם hello hello" ),
2873       1,
2874       0,
2875       2.f,
2876       std::string( "Hello hello, שלום עולם hello hello" ),
2877     },
2878     {
2879       std::string( "Delete from the middle to the end." ),
2880       std::string( "Hello hello, שלום עולם hello hello" ),
2881       1,
2882       2,
2883       0.f,
2884       std::string( "Hello hello, " ),
2885     },
2886     {
2887       std::string( "Delete from the beginning to the middle." ),
2888       std::string( "Hello hello, שלום עולם hello hello" ),
2889       0,
2890       2,
2891       6.f,
2892       std::string( "hello hello" ),
2893     },
2894   };
2895   const std::size_t numberOfTests( 3 );
2896
2897   for( std::size_t index = 0; index < numberOfTests; ++index )
2898   {
2899     const RemoveGroupsFromLineTest& test = removeGroupsFromLineTests[index];
2900
2901     if( !TestRemoveGroupsFromLine( test.description, test.input, test.groupIndex, test.numberOfGroups, test.lineHeightOffset, test.result, TEST_LOCATION ) )
2902     {
2903       tet_result( TET_FAIL );
2904     }
2905   }
2906
2907   tet_result( TET_PASS );
2908   END_TEST;
2909 }