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