[dali_1.1.40] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / text / multi-language-helper-functions.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/multi-language-helper-functions.h>
20
21 // EXTERNAL INCLUDES
22 #include <dali/devel-api/text-abstraction/font-client.h>
23
24 namespace Dali
25 {
26
27 namespace Toolkit
28 {
29
30 namespace Text
31 {
32
33 void MergeFontDescriptions( const Vector<FontDescriptionRun>& fontDescriptions,
34                             Vector<FontId>& fontIds,
35                             Vector<bool>& isDefaultFont,
36                             const TextAbstraction::FontDescription& defaultFontDescription,
37                             TextAbstraction::PointSize26Dot6 defaultPointSize,
38                             CharacterIndex startIndex,
39                             Length numberOfCharacters )
40 {
41   // Get the handle to the font client.
42   TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
43
44   // Pointer to the font id buffer.
45   FontId* fontIdsBuffer = fontIds.Begin();
46
47   // Pointer to the 'is default' font buffer.
48   bool* isDefaultFontBuffer = isDefaultFont.Begin();
49
50   // Used to temporarily store the style per character.
51   TextAbstraction::FontDescription fontDescription;
52   TextAbstraction::PointSize26Dot6 fontSize;
53
54   Length familyIndex = 0u;
55   Length weightIndex = 0u;
56   Length widthIndex = 0u;
57   Length slantIndex = 0u;
58   Length sizeIndex = 0u;
59
60   // Traverse all the characters.
61   const CharacterIndex lastCharacterPlusOne = startIndex + numberOfCharacters;
62   for( CharacterIndex index = startIndex; index < lastCharacterPlusOne; ++index )
63   {
64     bool& defaultFont = *(isDefaultFontBuffer + index - startIndex );
65
66     Length runIndex = 0u;
67
68     bool familyOverriden = false;
69     bool weightOverriden = false;
70     bool widthOverriden = false;
71     bool slantOverriden = false;
72     bool sizeOverriden = false;
73
74     // Traverse all the font descriptions.
75     const FontDescriptionRun* const fontDescriptionsBuffer = fontDescriptions.Begin();
76     for( Vector<FontDescriptionRun>::ConstIterator it = fontDescriptionsBuffer,
77            endIt = fontDescriptions.End();
78          it != endIt;
79          ++it, ++runIndex )
80     {
81       // Check whether the character's font is modified by the current font description.
82       const FontDescriptionRun& fontRun = *it;
83       if( ( index >= fontRun.characterRun.characterIndex ) &&
84           ( index < fontRun.characterRun.characterIndex + fontRun.characterRun.numberOfCharacters ) )
85       {
86         if( fontRun.familyDefined )
87         {
88           defaultFont = false;
89           familyOverriden = true;
90           familyIndex = runIndex;
91         }
92         if( fontRun.weightDefined )
93         {
94           defaultFont = false;
95           weightOverriden = true;
96           weightIndex = runIndex;
97         }
98         if( fontRun.widthDefined )
99         {
100           defaultFont = false;
101           widthOverriden = true;
102           widthIndex = runIndex;
103         }
104         if( fontRun.slantDefined )
105         {
106           defaultFont = false;
107           slantOverriden = true;
108           slantIndex = runIndex;
109         }
110         if( fontRun.sizeDefined )
111         {
112           defaultFont = false;
113           sizeOverriden = true;
114           sizeIndex = runIndex;
115         }
116       }
117     }
118
119     // Get the font id if is not the default font.
120     if( !defaultFont )
121     {
122       if( familyOverriden )
123       {
124         const FontDescriptionRun& fontRun = *( fontDescriptionsBuffer + familyIndex );
125         fontDescription.family = std::string( fontRun.familyName, fontRun.familyLength ); // TODO Could use move constructor when switch to c++11.
126       }
127       else
128       {
129         fontDescription.family = defaultFontDescription.family;
130       }
131
132       if( weightOverriden )
133       {
134         const FontDescriptionRun& fontRun = *( fontDescriptionsBuffer + weightIndex );
135         fontDescription.weight = fontRun.weight;
136       }
137       else
138       {
139         fontDescription.weight = defaultFontDescription.weight;
140       }
141
142       if( widthOverriden )
143       {
144         const FontDescriptionRun& fontRun = *( fontDescriptionsBuffer + widthIndex );
145         fontDescription.width = fontRun.width;
146       }
147       else
148       {
149         fontDescription.width = defaultFontDescription.width;
150       }
151
152       if( slantOverriden )
153       {
154         const FontDescriptionRun& fontRun = *( fontDescriptionsBuffer + slantIndex );
155         fontDescription.slant = fontRun.slant;
156       }
157       else
158       {
159         fontDescription.slant = defaultFontDescription.slant;
160       }
161
162       if( sizeOverriden )
163       {
164         const FontDescriptionRun& fontRun = *( fontDescriptionsBuffer + sizeIndex );
165         fontSize = fontRun.size;
166       }
167       else
168       {
169         fontSize = defaultPointSize;
170       }
171
172       *( fontIdsBuffer + index - startIndex ) = fontClient.GetFontId( fontDescription, fontSize );
173     }
174   }
175 }
176
177 Script GetScript( Length index,
178                   Vector<ScriptRun>::ConstIterator& scriptRunIt,
179                   const Vector<ScriptRun>::ConstIterator& scriptRunEndIt )
180 {
181   Script script = TextAbstraction::UNKNOWN;
182
183   while( scriptRunIt != scriptRunEndIt )
184   {
185     const ScriptRun& scriptRun = *scriptRunIt;
186
187     if( index >= scriptRun.characterRun.characterIndex + scriptRun.characterRun.numberOfCharacters )
188     {
189       ++scriptRunIt;
190     }
191     else if( index >= scriptRun.characterRun.characterIndex )
192     {
193       script = scriptRun.script;
194
195       if( index + 1u == scriptRun.characterRun.characterIndex + scriptRun.characterRun.numberOfCharacters )
196       {
197         // All the characters of the current run have been traversed. Get the next one for the next iteration.
198         ++scriptRunIt;
199       }
200
201       break;
202     }
203   }
204
205   return script;
206 }
207
208 } // namespace Text
209
210 } // namespace Toolkit
211
212 } // namespace Dali