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