[dali_1.0.31] Merge branch 'tizen'
[platform/core/uifw/dali-core.git] / dali / internal / event / text / text-impl.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 // HEADER CLASS
19 #include <dali/internal/event/text/text-impl.h>
20
21 // INTERNAL INCLUDES
22 #include <dali/internal/event/text/character-impl.h>
23 #include <dali/internal/event/text/utf8-impl.h>
24
25 // EXTERNAL INCLUDES
26 #include <algorithm>
27
28 namespace Dali
29 {
30
31 namespace Internal
32 {
33
34 namespace
35 {
36 static const Integration::TextArray VOID_TEXT_ARRAY; ///< A void text array to be used in the helper Internal::GetTextArray() function.
37 } // namespace
38
39 Text::Text()
40 : mString()
41 {
42 }
43
44 Text::Text( const std::string& text )
45 : mString()
46 {
47   const std::size_t length = text.size();
48
49   // minimize allocations for ascii strings
50   mString.Reserve( length );
51
52   // break string into UTF-8 tokens
53   UTF8Tokenize( reinterpret_cast<const unsigned char*>( text.c_str() ), length, mString );
54 }
55
56 Text::Text( const Character& character )
57 : mString()
58 {
59   mString.PushBack( character.GetCharacter() );
60 }
61
62 Text::Text( const Text& text )
63 : mString( text.mString )
64 {
65 }
66
67 void Text::GetText( std::string& text ) const
68 {
69   // minimize allocations for ascii strings
70   text.reserve( mString.Count() );
71
72   for( Integration::TextArray::ConstIterator it = mString.Begin(), endIt = mString.End(); it != endIt; ++it )
73   {
74     unsigned char utf8Data[4];
75     unsigned int utf8Length;
76
77     utf8Length = UTF8Write( *it, utf8Data );
78
79     text.append( reinterpret_cast<const char*>( utf8Data ), utf8Length );
80   }
81 }
82
83 Text& Text::operator=( const Text& text )
84 {
85   mString = text.mString;
86
87   return *this;
88 }
89
90 Text::~Text()
91 {
92   Clear();
93   mString.Release();
94 }
95
96 void Text::Clear()
97 {
98   mString.Clear();
99 }
100
101 Dali::Character Text::operator[]( size_t position ) const
102 {
103   DALI_ASSERT_ALWAYS( position < mString.Count() && "Text::operator[]: Character position is out of bounds" );
104
105   const uint32_t c = *( mString.Begin() + position );
106
107   Dali::Character character( new Character( c ) );
108
109   return character;
110 }
111
112 bool Text::IsEmpty() const
113 {
114   return 0u == mString.Count();
115 }
116
117 size_t Text::GetLength() const
118 {
119   return mString.Count();
120 }
121
122 void Text::Append( const Dali::Text& text )
123 {
124   const Integration::TextArray& utfCodes = text.GetImplementation().GetTextArray();
125
126   mString.Insert( mString.End(), utfCodes.Begin(), utfCodes.End() );
127 }
128
129 void Text::Remove( size_t position, size_t numberOfCharacters )
130 {
131   DALI_ASSERT_ALWAYS( position < mString.Count() && "Text::Remove: Character position is out of bounds" );
132   DALI_ASSERT_ALWAYS( position + numberOfCharacters <= mString.Count() && "Text::Remove: Character position + numberOfCharacters is out of bounds" );
133
134   mString.Erase( mString.Begin() + position, mString.Begin() + position + numberOfCharacters );
135 }
136
137 void Text::Find( uint32_t character, std::size_t from, std::size_t to, Vector<std::size_t>& positions ) const
138 {
139   std::size_t position = from;
140
141   for( Integration::TextArray::ConstIterator it = mString.Begin() + from, endIt = mString.Begin() + to + 1u; it != endIt; ++position, ++it )
142   {
143     if( *it == character )
144     {
145       positions.PushBack( position );
146     }
147   }
148 }
149
150 void Text::FindWhiteSpace( std::size_t from, std::size_t to, Vector<std::size_t>& positions ) const
151 {
152   std::size_t position = from;
153
154   for( Integration::TextArray::ConstIterator it = mString.Begin() + from, endIt = mString.Begin() + to + 1u; it != endIt; ++position, ++it )
155   {
156     if( Character::IsWhiteSpace( *it ) )
157     {
158       positions.PushBack( position );
159     }
160   }
161 }
162
163 void Text::FindNewLine( std::size_t from, std::size_t to, Vector<std::size_t>& positions ) const
164 {
165   std::size_t position = from;
166
167   for( Integration::TextArray::ConstIterator it = mString.Begin() + from, endIt = mString.Begin() + to + 1u; it != endIt; ++position, ++it )
168   {
169     if( Character::IsNewLine( *it ) )
170     {
171       positions.PushBack( position );
172     }
173   }
174 }
175
176 void Text::GetSubText( std::size_t from, std::size_t to, Text* subText ) const
177 {
178   if( to < from )
179   {
180     std::swap( from, to );
181     subText->mString.Insert( subText->mString.End(), mString.Begin() + from, mString.Begin() + to + 1u );
182     std::reverse( subText->mString.Begin(), subText->mString.End() );
183   }
184   else
185   {
186     subText->mString.Insert( subText->mString.End(), mString.Begin() + from, mString.Begin() + to + 1u );
187   }
188 }
189
190 bool Text::IsWhiteSpace( std::size_t index ) const
191 {
192   if( index < mString.Count() )
193   {
194     return Character::IsWhiteSpace( *( mString.Begin() + index ) );
195   }
196
197   return false;
198 }
199
200 bool Text::IsNewLine( std::size_t index ) const
201 {
202   if( index < mString.Count() )
203   {
204     return Character::IsNewLine( *( mString.Begin() + index ) );
205   }
206
207   return false;
208 }
209
210 const Integration::TextArray& Text::GetTextArray() const
211 {
212   return mString;
213 }
214
215 const Integration::TextArray& GetTextArray( const Dali::Text& text )
216 {
217   if( text.IsEmpty() )
218   {
219     return VOID_TEXT_ARRAY;
220   }
221
222   return text.GetImplementation().GetTextArray();
223 }
224
225 } // namespace Internal
226
227 } // namespace Dali