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