[dali_2.0.25] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / text / segmentation.cpp
1 /*
2  * Copyright (c) 2015 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/text/segmentation.h>
20
21 // EXTERNAL INCLUDES
22 #include <dali/devel-api/text-abstraction/segmentation.h>
23 #ifdef DEBUG_ENABLED
24 #include <dali/integration-api/debug.h>
25 #include <string>
26 #endif
27
28 // INTERNAL INCLUDES
29 #ifdef DEBUG_ENABLED
30 #include <dali-toolkit/internal/text/character-set-conversion.h>
31 #endif
32
33 namespace
34 {
35 #if defined(DEBUG_ENABLED)
36 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_SEGMENTATION");
37 #endif
38
39 } // namespace
40
41 namespace Dali
42 {
43 namespace Toolkit
44 {
45 namespace Text
46 {
47 void SetLineBreakInfo(const Vector<Character>& text,
48                       CharacterIndex           startIndex,
49                       Length                   numberOfCharacters,
50                       Vector<LineBreakInfo>&   lineBreakInfo)
51 {
52   const Length totalNumberOfCharacters = text.Count();
53
54   if(0u == totalNumberOfCharacters)
55   {
56     // Nothing to do if there are no characters.
57     return;
58   }
59
60   // Retrieve the line break info.
61   lineBreakInfo.Resize(totalNumberOfCharacters);
62
63   // Whether the current buffer is being updated or is set from scratch.
64   const bool updateCurrentBuffer = numberOfCharacters < totalNumberOfCharacters;
65
66   LineBreakInfo*        lineBreakInfoBuffer = NULL;
67   Vector<LineBreakInfo> newLineBreakInfo;
68
69   if(updateCurrentBuffer)
70   {
71     newLineBreakInfo.Resize(numberOfCharacters);
72     lineBreakInfoBuffer = newLineBreakInfo.Begin();
73   }
74   else
75   {
76     lineBreakInfoBuffer = lineBreakInfo.Begin();
77   }
78
79   // Retrieve the line break info.
80   TextAbstraction::Segmentation::Get().GetLineBreakPositions(text.Begin() + startIndex,
81                                                              numberOfCharacters,
82                                                              lineBreakInfoBuffer);
83
84   // If the line break info is updated, it needs to be inserted in the model.
85   if(updateCurrentBuffer)
86   {
87     lineBreakInfo.Insert(lineBreakInfo.Begin() + startIndex,
88                          newLineBreakInfo.Begin(),
89                          newLineBreakInfo.End());
90     lineBreakInfo.Resize(totalNumberOfCharacters);
91   }
92
93 #ifdef DEBUG_ENABLED
94   if(gLogFilter->IsEnabledFor(Debug::Verbose))
95   {
96     std::string utf8;
97     Utf32ToUtf8(text.Begin(), numberOfCharacters, utf8);
98
99     std::string info;
100     info.reserve(numberOfCharacters);
101     for(unsigned int i = 0; i < lineBreakInfo.Count(); ++i)
102     {
103       info.push_back(static_cast<char>('0' + lineBreakInfo[i]));
104     }
105
106     DALI_LOG_INFO(gLogFilter, Debug::Verbose, "SetLineBreakInfo Characters: %s\n", utf8.c_str());
107     DALI_LOG_INFO(gLogFilter, Debug::Verbose, "SetLineBreakInfo Break info: %s\n", info.c_str());
108   }
109 #endif
110 }
111
112 void SetWordBreakInfo(const Vector<Character>& text,
113                       CharacterIndex           startIndex,
114                       Length                   numberOfCharacters,
115                       Vector<WordBreakInfo>&   wordBreakInfo)
116 {
117   const Length totalNumberOfCharacters = text.Count();
118
119   if(0u == totalNumberOfCharacters)
120   {
121     // Nothing to do if there are no characters.
122     return;
123   }
124
125   // Resize the vector.
126   wordBreakInfo.Resize(totalNumberOfCharacters);
127
128   // Whether the current buffer is being updated or is set from scratch.
129   const bool updateCurrentBuffer = numberOfCharacters < totalNumberOfCharacters;
130
131   WordBreakInfo*        wordBreakInfoBuffer = NULL;
132   Vector<WordBreakInfo> newWordBreakInfo;
133
134   if(updateCurrentBuffer)
135   {
136     newWordBreakInfo.Resize(numberOfCharacters);
137     wordBreakInfoBuffer = newWordBreakInfo.Begin();
138   }
139   else
140   {
141     wordBreakInfoBuffer = wordBreakInfo.Begin();
142   }
143
144   // Retrieve the word break info.
145   TextAbstraction::Segmentation::Get().GetWordBreakPositions(text.Begin() + startIndex,
146                                                              numberOfCharacters,
147                                                              wordBreakInfoBuffer);
148
149   // If the word break info is updated, it needs to be inserted in the model.
150   if(updateCurrentBuffer)
151   {
152     wordBreakInfo.Insert(wordBreakInfo.Begin() + startIndex,
153                          newWordBreakInfo.Begin(),
154                          newWordBreakInfo.End());
155     wordBreakInfo.Resize(totalNumberOfCharacters);
156   }
157
158 #ifdef DEBUG_ENABLED
159   if(gLogFilter->IsEnabledFor(Debug::Verbose))
160   {
161     std::string utf8;
162     Utf32ToUtf8(text.Begin(), totalNumberOfCharacters, utf8);
163
164     std::string info;
165     info.reserve(totalNumberOfCharacters);
166     for(unsigned int i = 0; i < wordBreakInfo.Count(); ++i)
167     {
168       info.push_back(static_cast<char>('0' + wordBreakInfo[i]));
169     }
170
171     DALI_LOG_INFO(gLogFilter, Debug::Verbose, "SetWordBreakInfo Characters: %s\n", utf8.c_str());
172     DALI_LOG_INFO(gLogFilter, Debug::Verbose, "SetWordBreakInfo Break info: %s\n", info.c_str());
173   }
174 #endif
175 }
176
177 } // namespace Text
178
179 } // namespace Toolkit
180
181 } // namespace Dali