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