[SRUK] Initial copy from Tizen 2.2 version
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / text-view / text-view-processor-helper-functions.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 // INTERNAL INCLUDES
18 #include "text-view-processor-helper-functions.h"
19
20 namespace Dali
21 {
22
23 namespace Toolkit
24 {
25
26 namespace Internal
27 {
28
29 namespace TextViewProcessor
30 {
31
32 void UpdateSize( Size& size1, const Size& size2, const SizeGrowType type )
33 {
34   switch( type )
35   {
36     case GrowWidth:
37     {
38       size1.width += size2.width;
39       size1.height = std::max( size1.height, size2.height );
40       break;
41     }
42     case GrowHeight:
43     {
44       size1.width = std::max( size1.width, size2.width );
45       size1.height += size2.height;
46       break;
47     }
48   }
49 }
50
51 TextSeparatorType GetTextSeparatorType( const Character& character )
52 {
53   // returns if the given character is a line separator '\n', a word separator ' ' or if is not a separator (any other character).
54   return ( character.IsNewLine() ? LineSeparator : ( character.IsWhiteSpace() ? WordSeparator : NoSeparator ) );
55 }
56
57 void ChooseFontFamilyName( MarkupProcessor::StyledText& text )
58 {
59   bool userDefinedFontFamilyName = false;
60
61   // First check if there is a font defined in the style and it supports the given text.
62   if( !text.mStyle.GetFontName().empty() )
63   {
64     const FontParameters fontParams( text.mStyle.GetFontName(), text.mStyle.GetFontStyle() , text.mStyle.GetFontPointSize() );
65     const Font font = Font::New( fontParams );
66
67     if( !font.IsDefaultSystemFont() && font.AllGlyphsSupported( text.mText ) )
68     {
69       userDefinedFontFamilyName = true;
70     }
71   }
72
73   if( !userDefinedFontFamilyName )
74   {
75     const Font defaultSystemFont = Font::New();
76
77     // At this point no font is set or doesn't support the given text.
78     if( !defaultSystemFont.AllGlyphsSupported( text.mText ) )
79     {
80       // If the default system font doesn't support the given text,
81       // an appropiate font is selected.
82       text.mStyle.SetFontName( Font::GetFamilyForText( text.mText ) );
83       // @TODO Font::GetFamilyForText() should return font family and font style.
84     }
85     else
86     {
87       // All characters are supported with default font, so use it
88       text.mStyle.SetFontName( "" );
89     }
90   }
91 }
92
93 void GetIndicesFromGlobalCharacterIndex( const std::size_t index,
94                                          const TextLayoutInfo& textLayoutInfo,
95                                          TextInfoIndices& indices )
96 {
97   // TODO : Check for mixed LTR and RTL.
98
99   // clear all indices
100   indices = TextInfoIndices();
101
102   // Early return.
103   if( textLayoutInfo.mLinesLayoutInfo.empty() )
104   {
105     // Text is empty. All indices are 0.
106     return;
107   }
108
109   std::size_t currentIndex = 0; // stores how many characters have been traversed.
110
111   // Traverse all lines, groups of words and words until global index is found.
112   bool found = false;
113   for( LineLayoutInfoContainer::const_iterator lineIt = textLayoutInfo.mLinesLayoutInfo.begin(),
114          lineEndIt = textLayoutInfo.mLinesLayoutInfo.end();
115        ( !found ) && ( lineIt != lineEndIt );
116        ++lineIt, ++indices.mLineIndex )
117   {
118     const LineLayoutInfo& lineLayoutInfo( *lineIt );
119
120     if( currentIndex + lineLayoutInfo.mNumberOfCharacters > index )
121     {
122       // The character is in this line
123       for( WordGroupLayoutInfoContainer::const_iterator groupIt = lineLayoutInfo.mWordGroupsLayoutInfo.begin(),
124              groupEndIt = lineLayoutInfo.mWordGroupsLayoutInfo.end();
125            ( !found ) && ( groupIt != groupEndIt );
126            ++groupIt, ++indices.mGroupIndex )
127       {
128         const WordGroupLayoutInfo& wordGroupLayoutInfo( *groupIt );
129
130         if( currentIndex + wordGroupLayoutInfo.mNumberOfCharacters > index )
131         {
132           // The character is in this group of words.
133           for( WordLayoutInfoContainer::const_iterator wordIt = wordGroupLayoutInfo.mWordsLayoutInfo.begin(),
134                  wordEndIt = wordGroupLayoutInfo.mWordsLayoutInfo.end();
135                ( !found ) && ( wordIt != wordEndIt );
136                ++wordIt, ++indices.mWordIndex )
137           {
138             const WordLayoutInfo& wordLayoutInfo( *wordIt );
139
140             if( currentIndex + wordLayoutInfo.mCharactersLayoutInfo.size() > index )
141             {
142               // The character is in this word
143               indices.mCharacterIndex = index - currentIndex;
144               found = true;
145             }
146             else
147             {
148               // check in the next word.
149               currentIndex += wordLayoutInfo.mCharactersLayoutInfo.size();
150             }
151           } // end words.
152           if( !wordGroupLayoutInfo.mWordsLayoutInfo.empty() )
153           {
154             --indices.mWordIndex;
155           }
156         }
157         else
158         {
159           // check in the next group of words
160           currentIndex += wordGroupLayoutInfo.mNumberOfCharacters;
161         }
162       } // end groups of words.
163       if( !lineLayoutInfo.mWordGroupsLayoutInfo.empty() )
164       {
165         --indices.mGroupIndex;
166       }
167     }
168     else
169     {
170       // check in the next line
171       currentIndex += lineLayoutInfo.mNumberOfCharacters;
172     }
173   } // end lines.
174
175   // Need to decrease indices as they have been increased in the last loop.
176   if( !textLayoutInfo.mLinesLayoutInfo.empty() )
177   {
178     --indices.mLineIndex;
179   }
180 }
181
182 void ClearText( std::vector<TextActor>& textActors )
183 {
184     for( std::vector<TextActor>::iterator it = textActors.begin(), endIt = textActors.end(); it != endIt; ++it )
185     {
186       (*it).SetText( std::string( "" ) );
187     }
188 }
189
190 } //namespace TextViewProcessor
191
192 } //namespace Internal
193
194 } //namespace Toolkit
195
196 } //namespace Dali