Corrected camel case for BgraShader
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / text / visual-model.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 // CLASS HEADER
19 #include <dali-toolkit/internal/text/visual-model.h>
20
21 // EXTERNAL INCLUDES
22 #include <memory.h>
23
24 // INTERNAL INCLUDES
25 #include <dali/public-api/common/dali-vector.h>
26 #include <dali/public-api/math/vector2.h>
27 #include <dali-toolkit/internal/text/line-run.h>
28
29 namespace Dali
30 {
31
32 namespace Toolkit
33 {
34
35 namespace Text
36 {
37
38 /**
39  * @brief caches some temporary values of the GetNumberOfLines( glyphIndex, numberOfGlyphs ) operation
40  * as they are going to be used in the GetLinesOfGlyphRange() call.
41  */
42 struct GetLineCache
43 {
44   GlyphIndex glyphIndex;     ///< The glyph index.
45   Length     numberOfGlyphs; ///< The number of glyphs.
46   Length     firstLine;      ///< Index to the first line.
47   Length     numberOfLines;  ///< The number of lines.
48 };
49
50 struct VisualModel::Impl
51 {
52   Vector<GlyphInfo>      mGlyphs;             ///< For each glyph, the font's id, glyph's index within the font and glyph's metrics.
53   Vector<CharacterIndex> mGlyphsToCharacters; ///< For each glyph, the index of the first character.
54   Vector<GlyphIndex>     mCharactersToGlyph;  ///< For each character, the index of the first glyph.
55   Vector<Length>         mCharactersPerGlyph; ///< For each glyph, the number of characters that form the glyph.
56   Vector<Vector2>        mGlyphPositions;     ///< For each glyph, the position.
57   Vector<LineRun>        mLines;              ///< The laid out lines.
58
59   Size                   mNaturalSize;        ///< Size of the text with no line wrapping.
60   Size                   mActualSize;         ///< Size of the laid-out text considering the layout properties set.
61
62   GetLineCache           mGetLineCache;       ///< Caches the GetNumberOfLines( glyphIndex, numberOfGlyphs ) operation.
63 };
64
65 VisualModelPtr VisualModel::New()
66 {
67   return VisualModelPtr( new VisualModel() );
68 }
69
70 void VisualModel::SetGlyphs( const GlyphInfo* glyphs,
71                              const CharacterIndex* characterIndices,
72                              const Length* charactersPerGlyph,
73                              Length numberOfGlyphs )
74 {
75   Vector<GlyphInfo>& modelGlyphs = mImpl->mGlyphs;
76   Vector<CharacterIndex>& modelGlyphsToCharacters = mImpl->mGlyphsToCharacters;
77   Vector<Length>& modelCharactersPerGlyph = mImpl->mCharactersPerGlyph;
78   Vector<GlyphIndex>& modelCharactersToGlyph = mImpl->mCharactersToGlyph;
79
80   if( 0u == numberOfGlyphs )
81   {
82     modelGlyphs.Clear();
83     modelGlyphsToCharacters.Clear();
84     modelCharactersToGlyph.Clear();
85     modelCharactersPerGlyph.Clear();
86   }
87   else
88   {
89     if( NULL != glyphs )
90     {
91       modelGlyphs.Resize( numberOfGlyphs );
92       memcpy( modelGlyphs.Begin(), glyphs, numberOfGlyphs * sizeof( GlyphInfo ) );
93     }
94
95     if( NULL != characterIndices )
96     {
97       modelGlyphsToCharacters.Resize( numberOfGlyphs );
98       memcpy( modelGlyphsToCharacters.Begin(), characterIndices, numberOfGlyphs * sizeof( CharacterIndex ) );
99     }
100
101     if( NULL != charactersPerGlyph )
102     {
103       modelCharactersPerGlyph.Resize( numberOfGlyphs );
104       memcpy( modelCharactersPerGlyph.Begin(), charactersPerGlyph, numberOfGlyphs * sizeof( Length ) );
105
106       // Build the characters to glyph conversion table.
107
108       // 1) Reserve some space for the characters to avoid reallocations.
109       modelCharactersToGlyph.Reserve( static_cast<Length> ( static_cast<float>( numberOfGlyphs ) * 1.3f ) );
110
111       // 2) Traverse the glyphs and set the glyph indices.
112       GlyphIndex glyphIndex = 0u;
113       Length totalNumberOfCharacters = 0u;
114       for( Vector<Length>::ConstIterator it = modelCharactersPerGlyph.Begin(),
115              endIt = modelCharactersPerGlyph.End();
116            it != endIt;
117            ++it, ++glyphIndex )
118       {
119         const Length numberOfCharacters = *it;
120
121         for( Length index = 0u; index < numberOfCharacters; ++index, ++totalNumberOfCharacters )
122         {
123           modelCharactersToGlyph.PushBack( glyphIndex );
124         }
125       }
126     }
127   }
128 }
129
130 Length VisualModel::GetNumberOfGlyphs() const
131 {
132   return mImpl->mGlyphs.Count();
133 }
134
135 void VisualModel::GetGlyphs( GlyphInfo* glyphs,
136                              GlyphIndex glyphIndex,
137                              Length numberOfGlyphs ) const
138 {
139   const Vector<GlyphInfo>& modelGlyphs = mImpl->mGlyphs;
140   memcpy( glyphs, modelGlyphs.Begin() + glyphIndex, numberOfGlyphs * sizeof( GlyphInfo ) );
141 }
142
143 const GlyphInfo& VisualModel::GetGlyphInfo( GlyphIndex glyphIndex ) const
144 {
145   return mImpl->mGlyphs[glyphIndex];
146 }
147
148 CharacterIndex VisualModel::GetCharacterIndex( GlyphIndex glyphIndex ) const
149 {
150   return mImpl->mGlyphsToCharacters[glyphIndex];
151 }
152
153 Length VisualModel::GetCharactersPerGlyph( GlyphIndex glyphIndex ) const
154 {
155   return mImpl->mCharactersPerGlyph[glyphIndex];
156 }
157
158 GlyphIndex VisualModel::GetGlyphIndex( CharacterIndex characterIndex ) const
159 {
160   return mImpl->mCharactersToGlyph[characterIndex];
161 }
162
163 void VisualModel::GetCharacterToGlyphMap( GlyphIndex* characterToGlyphMap,
164                                           CharacterIndex characterIndex,
165                                           Length numberOfCharacters ) const
166 {
167   const Vector<GlyphIndex>& modelCharactersToGlyph = mImpl->mCharactersToGlyph;
168   memcpy( characterToGlyphMap, modelCharactersToGlyph.Begin() + characterIndex, numberOfCharacters * sizeof( GlyphIndex ) );
169 }
170
171 void VisualModel::GetCharactersPerGlyphMap( Length* charactersPerGlyph,
172                                             GlyphIndex glyphIndex,
173                                             Length numberOfGlyphs ) const
174 {
175   const Vector<Length>& modelCharactersPerGlyph = mImpl->mCharactersPerGlyph;
176   memcpy( charactersPerGlyph, modelCharactersPerGlyph.Begin() + glyphIndex, numberOfGlyphs * sizeof( Length ) );
177 }
178
179 void VisualModel::GetGlyphToCharacterMap( CharacterIndex* glyphToCharacter,
180                                           GlyphIndex glyphIndex,
181                                           Length numberOfGlyphs ) const
182 {
183   const Vector<CharacterIndex>& modelGlyphsToCharacters = mImpl->mGlyphsToCharacters;
184   memcpy( glyphToCharacter, modelGlyphsToCharacters.Begin() + glyphIndex, numberOfGlyphs * sizeof( CharacterIndex ) );
185 }
186
187 void VisualModel::SetGlyphPositions( const Vector2* glyphPositions,
188                                      Length numberOfGlyphs )
189 {
190   Vector<Vector2>& modelPositions = mImpl->mGlyphPositions;
191   if( 0u == numberOfGlyphs )
192   {
193     modelPositions.Clear();
194   }
195   else
196   {
197     modelPositions.Resize( numberOfGlyphs );
198     memcpy( modelPositions.Begin(), glyphPositions, numberOfGlyphs * sizeof( Vector2 ) );
199   }
200 }
201
202 Length VisualModel::GetNumberOfGlyphPositions() const
203 {
204   return mImpl->mGlyphPositions.Count();
205 }
206
207 void VisualModel::GetGlyphPositions( Vector2* glyphPositions,
208                                      GlyphIndex glyphIndex,
209                                      Length numberOfGlyphs ) const
210 {
211   const Vector<Vector2>& modelPositions = mImpl->mGlyphPositions;
212   memcpy( glyphPositions, modelPositions.Begin() + glyphIndex, numberOfGlyphs * sizeof( Vector2 ) );
213 }
214
215 const Vector2& VisualModel::GetGlyphPosition( GlyphIndex glyphIndex ) const
216 {
217   return *( mImpl->mGlyphPositions.Begin() + glyphIndex );
218 }
219
220 void VisualModel::SetLines( const LineRun* const lines,
221                             Length numberOfLines )
222 {
223   Vector<LineRun>& modelLines = mImpl->mLines;
224   GetLineCache& lineCache = mImpl->mGetLineCache;
225
226   if( 0u == numberOfLines )
227   {
228     modelLines.Clear();
229   }
230   else
231   {
232     modelLines.Resize( numberOfLines );
233     memcpy( modelLines.Begin(), lines, numberOfLines * sizeof( LineRun ) );
234   }
235
236   // Clear the get line cache.
237   lineCache.glyphIndex = 0u;
238   lineCache.numberOfGlyphs = 0u;
239   lineCache.firstLine = 0u;
240   lineCache.numberOfLines = 0u;
241 }
242
243 Length VisualModel::GetNumberOfLines() const
244 {
245   return mImpl->mLines.Count();
246 }
247
248 void VisualModel::GetLines( LineRun* lines,
249                             LineIndex lineIndex,
250                             Length numberOfLines ) const
251 {
252   const Vector<LineRun>& modelLines = mImpl->mLines;
253   memcpy( lines, modelLines.Begin() + lineIndex, numberOfLines * sizeof( LineRun ) );
254 }
255
256 Length VisualModel::GetNumberOfLines( GlyphIndex glyphIndex,
257                                       Length numberOfGlyphs ) const
258 {
259   // If is likely the user query consecutively for the number of lines with the same
260   // glyph index and number of glyphs, use the cache could be considered.
261   GetLineCache& lineCache = mImpl->mGetLineCache;
262
263   // Cache the glyph index and number of glyphs to be used in the GetLinesOfGlyphRange().
264   lineCache.glyphIndex = glyphIndex;
265   lineCache.numberOfGlyphs = numberOfGlyphs;
266
267   // Check first if the query is for the total number of glyphs.
268   const Length totalNumberOfGlyphs = mImpl->mGlyphs.Count();
269
270   if( ( 0u == glyphIndex ) &&
271       ( totalNumberOfGlyphs == numberOfGlyphs ) )
272   {
273     lineCache.firstLine = 0u;
274     lineCache.numberOfLines = mImpl->mLines.Count();
275
276     return lineCache.numberOfLines;
277   }
278
279   // Initialize the number of lines and the first line.
280   lineCache.numberOfLines = 0u;
281   lineCache.firstLine = 0u;
282   bool firstLineFound = false;
283
284   const Vector<LineRun>& modelLines = mImpl->mLines;
285   const GlyphIndex lastGlyphIndex = glyphIndex + numberOfGlyphs;
286
287   // Traverse the lines and cound those lines within the range of glyphs.
288   for( Vector<LineRun>::ConstIterator it = modelLines.Begin(),
289          endIt = modelLines.End();
290        it != endIt;
291        ++it )
292   {
293     const LineRun& line = *it;
294
295     if( ( line.glyphIndex + line.numberOfGlyphs > glyphIndex ) &&
296         ( lastGlyphIndex > line.glyphIndex ) )
297     {
298       firstLineFound = true;
299       ++lineCache.numberOfLines;
300     }
301     else if( lastGlyphIndex <= line.glyphIndex )
302     {
303       // nothing else to do.
304       break;
305     }
306
307     if( !firstLineFound )
308     {
309       ++lineCache.firstLine;
310     }
311   }
312
313   return lineCache.numberOfLines;
314 }
315
316 void VisualModel::GetLinesOfGlyphRange( LineRun* lines,
317                                         GlyphIndex glyphIndex,
318                                         Length numberOfGlyphs ) const
319 {
320   const Vector<LineRun>& modelLines = mImpl->mLines;
321   GetLineCache& lineCache = mImpl->mGetLineCache;
322
323   if( ( glyphIndex != lineCache.glyphIndex ) ||
324       ( numberOfGlyphs != lineCache.numberOfGlyphs ) )
325   {
326     GetNumberOfLines( glyphIndex,
327                       numberOfGlyphs );
328   }
329
330   memcpy( lines, modelLines.Begin() + lineCache.firstLine, lineCache.numberOfLines * sizeof( LineRun ) );
331 }
332
333 void VisualModel::SetNaturalSize( const Vector2& size  )
334 {
335   mImpl->mNaturalSize = size;
336 }
337
338 const Vector2& VisualModel::GetNaturalSize() const
339 {
340   return mImpl->mNaturalSize;
341 }
342
343 void VisualModel::SetActualSize( const Vector2& size )
344 {
345   mImpl->mActualSize = size;
346 }
347
348 const Vector2& VisualModel::GetActualSize() const
349 {
350   return mImpl->mActualSize;
351 }
352
353 VisualModel::~VisualModel()
354 {
355   delete mImpl;
356 }
357
358 VisualModel::VisualModel()
359 : mImpl( NULL )
360 {
361   mImpl = new VisualModel::Impl();
362 }
363
364 } // namespace Text
365
366 } // namespace Toolkit
367
368 } // namespace Dali