2 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <dali-toolkit/internal/text/visual-model-impl.h>
23 #include <dali/public-api/math/vector2.h>
34 VisualModelPtr VisualModel::New()
36 return VisualModelPtr( new VisualModel() );
39 void VisualModel::SetGlyphs( const GlyphInfo* glyphs,
40 const CharacterIndex* characterIndices,
41 const Length* charactersPerGlyph,
42 Length numberOfGlyphs )
44 if( 0u == numberOfGlyphs )
47 mGlyphsToCharacters.Clear();
48 mCharactersToGlyph.Clear();
49 mCharactersPerGlyph.Clear();
50 mGlyphsPerCharacter.Clear();
56 mGlyphs.Resize( numberOfGlyphs );
57 memcpy( mGlyphs.Begin(), glyphs, numberOfGlyphs * sizeof( GlyphInfo ) );
60 if( NULL != characterIndices )
62 mGlyphsToCharacters.Resize( numberOfGlyphs );
63 memcpy( mGlyphsToCharacters.Begin(), characterIndices, numberOfGlyphs * sizeof( CharacterIndex ) );
66 if( NULL != charactersPerGlyph )
68 mCharactersPerGlyph.Resize( numberOfGlyphs );
69 memcpy( mCharactersPerGlyph.Begin(), charactersPerGlyph, numberOfGlyphs * sizeof( Length ) );
71 // Build the glyphs per character table.
72 CreateGlyphsPerCharacterTable();
74 // Build the characters to glyph conversion table.
75 CreateCharacterToGlyphTable();
80 void VisualModel::CreateCharacterToGlyphTable( Length numberOfCharacters )
82 // 1) Reserve some space for the characters to avoid reallocations.
83 if( 0u == numberOfCharacters )
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 );
88 mCharactersToGlyph.Reserve( numberOfCharacters );
90 DALI_ASSERT_DEBUG( mGlyphsPerCharacter.Count() != 0u ||
91 ( 0u == numberOfCharacters ) );
93 const Length* const glyphsPerCharacterBuffer = mGlyphsPerCharacter.Begin();
95 // 2) Traverse the glyphs and set the glyph indices per character.
97 // Index to the glyph.
98 GlyphIndex glyphIndex = 0u;
99 CharacterIndex characterIndex = 0u;
100 for( Vector<Length>::ConstIterator it = mCharactersPerGlyph.Begin(),
101 endIt = mCharactersPerGlyph.End();
105 const Length numberOfCharactersPerGlyph = *it;
107 Length numberOfGlyphs = 0u;
108 // Set the glyph indices.
109 for( Length index = 0u; index < numberOfCharactersPerGlyph; ++index, ++characterIndex )
111 mCharactersToGlyph.PushBack( glyphIndex );
112 numberOfGlyphs += *( glyphsPerCharacterBuffer + characterIndex );
114 glyphIndex += numberOfGlyphs;
118 void VisualModel::CreateGlyphsPerCharacterTable( Length numberOfCharacters )
120 // 1) Reserve some space for the characters to avoid reallocations.
121 if( 0u == numberOfCharacters )
123 // If no number of characters is given, just set something sensible to avoid reallocations.
124 numberOfCharacters = static_cast<Length> ( static_cast<float>( mGlyphs.Count() ) * 1.3f );
126 mGlyphsPerCharacter.Reserve( numberOfCharacters );
128 // 2) Traverse the glyphs and set the number of glyphs per character.
130 // The number of 'characters per glyph' equal to zero.
131 Length zeroCharactersPerGlyph = 0u;
133 for( Vector<Length>::ConstIterator it = mCharactersPerGlyph.Begin(),
134 endIt = mCharactersPerGlyph.End();
138 const Length numberOfCharactersPerGlyph = *it;
140 // Set the glyphs per character.
141 if( 0u == numberOfCharactersPerGlyph )
143 ++zeroCharactersPerGlyph;
147 const Length numberOfZeroGlyphsPerCharacter = ( numberOfCharactersPerGlyph - 1u );
148 for( Length zeroIndex = 0u; zeroIndex < numberOfZeroGlyphsPerCharacter ; ++zeroIndex )
150 mGlyphsPerCharacter.PushBack( 0u );
153 mGlyphsPerCharacter.PushBack( 1u + zeroCharactersPerGlyph );
155 zeroCharactersPerGlyph = 0u;
160 Length VisualModel::GetNumberOfGlyphs() const
162 return mGlyphs.Count();
165 void VisualModel::GetGlyphs( GlyphInfo* glyphs,
166 GlyphIndex glyphIndex,
167 Length numberOfGlyphs ) const
169 memcpy( glyphs, mGlyphs.Begin() + glyphIndex, numberOfGlyphs * sizeof( GlyphInfo ) );
172 const GlyphInfo& VisualModel::GetGlyphInfo( GlyphIndex glyphIndex ) const
174 return mGlyphs[glyphIndex];
177 void VisualModel::ReplaceGlyphs( GlyphIndex glyphIndex,
178 Length numberOfGlyphsToRemove,
179 const GlyphInfo* const glyphs,
180 const Length* const numberOfCharacters,
181 Length numberOfGlyphsToInsert )
185 CharacterIndex VisualModel::GetCharacterIndex( GlyphIndex glyphIndex ) const
187 return mGlyphsToCharacters[glyphIndex];
190 Length VisualModel::GetCharactersPerGlyph( GlyphIndex glyphIndex ) const
192 return mCharactersPerGlyph[glyphIndex];
195 GlyphIndex VisualModel::GetGlyphIndex( CharacterIndex characterIndex ) const
197 return mCharactersToGlyph[characterIndex];
200 void VisualModel::GetCharacterToGlyphMap( GlyphIndex* characterToGlyphMap,
201 CharacterIndex characterIndex,
202 Length numberOfCharacters ) const
204 memcpy( characterToGlyphMap, mCharactersToGlyph.Begin() + characterIndex, numberOfCharacters * sizeof( GlyphIndex ) );
207 void VisualModel::GetGlyphToCharacterMap( CharacterIndex* glyphToCharacter,
208 GlyphIndex glyphIndex,
209 Length numberOfGlyphs ) const
211 memcpy( glyphToCharacter, mGlyphsToCharacters.Begin() + glyphIndex, numberOfGlyphs * sizeof( CharacterIndex ) );
214 void VisualModel::GetCharactersPerGlyphMap( Length* charactersPerGlyph,
215 GlyphIndex glyphIndex,
216 Length numberOfGlyphs ) const
218 memcpy( charactersPerGlyph, mCharactersPerGlyph.Begin() + glyphIndex, numberOfGlyphs * sizeof( Length ) );
221 void VisualModel::GetGlyphsPerCharacterMap( Length* glyphsPerCharacter,
222 CharacterIndex characterIndex,
223 Length numberOfCharacters ) const
225 memcpy( glyphsPerCharacter, mGlyphsPerCharacter.Begin() + characterIndex, numberOfCharacters * sizeof( Length ) );
228 void VisualModel::SetGlyphPositions( const Vector2* glyphPositions,
229 Length numberOfGlyphs )
231 if( 0u == numberOfGlyphs )
233 mGlyphPositions.Clear();
237 mGlyphPositions.Resize( numberOfGlyphs );
238 memcpy( mGlyphPositions.Begin(), glyphPositions, numberOfGlyphs * sizeof( Vector2 ) );
242 Length VisualModel::GetNumberOfGlyphPositions() const
244 return mGlyphPositions.Count();
247 void VisualModel::GetGlyphPositions( Vector2* glyphPositions,
248 GlyphIndex glyphIndex,
249 Length numberOfGlyphs ) const
251 memcpy( glyphPositions, mGlyphPositions.Begin() + glyphIndex, numberOfGlyphs * sizeof( Vector2 ) );
254 const Vector2& VisualModel::GetGlyphPosition( GlyphIndex glyphIndex ) const
256 return *( mGlyphPositions.Begin() + glyphIndex );
259 void VisualModel::ReplaceGlyphPositions( GlyphIndex glyphIndex,
260 Length numberOfGlyphsToRemove,
261 const Vector2* const positions,
262 Length numberOfGlyphsToInsert )
266 void VisualModel::SetLines( const LineRun* const lines,
267 Length numberOfLines )
269 if( 0u == numberOfLines )
275 mLines.Resize( numberOfLines );
276 memcpy( mLines.Begin(), lines, numberOfLines * sizeof( LineRun ) );
280 Length VisualModel::GetNumberOfLines() const
282 return mLines.Count();
285 void VisualModel::GetLines( LineRun* lines,
287 Length numberOfLines ) const
289 memcpy( lines, mLines.Begin() + lineIndex, numberOfLines * sizeof( LineRun ) );
292 void VisualModel::GetNumberOfLines( GlyphIndex glyphIndex,
293 Length numberOfGlyphs,
294 LineIndex& firstLine,
295 Length& numberOfLines ) const
297 // Initialize the number of lines and the first line.
300 bool firstLineFound = false;
302 const GlyphIndex lastGlyphIndex = glyphIndex + numberOfGlyphs;
304 // Traverse the lines and count those lines within the range of glyphs.
305 for( Vector<LineRun>::ConstIterator it = mLines.Begin(),
306 endIt = mLines.End();
310 const LineRun& line = *it;
312 if( ( line.glyphIndex + line.numberOfGlyphs > glyphIndex ) &&
313 ( lastGlyphIndex > line.glyphIndex ) )
315 firstLineFound = true;
318 else if( lastGlyphIndex <= line.glyphIndex )
320 // nothing else to do.
324 if( !firstLineFound )
331 void VisualModel::GetLinesOfGlyphRange( LineRun* lines,
332 GlyphIndex glyphIndex,
333 Length numberOfGlyphs ) const
335 LineIndex firstLine = 0u;
336 Length numberOfLines = 0u;
338 GetNumberOfLines( glyphIndex,
343 memcpy( lines, mLines.Begin() + firstLine, numberOfLines * sizeof( LineRun ) );
346 void VisualModel::ReplaceLines( GlyphIndex glyphIndex,
347 Length numberOfGlyphsToRemove,
348 const LineRun* const lines,
349 Length numberOfGlyphsToInsert )
353 void VisualModel::SetNaturalSize( const Vector2& size )
358 const Vector2& VisualModel::GetNaturalSize() const
363 void VisualModel::SetActualSize( const Vector2& size )
368 const Vector2& VisualModel::GetActualSize() const
373 void VisualModel::SetTextColor( const Vector4& textColor )
375 mTextColor = textColor;
377 if ( !mUnderlineColorSet )
379 mUnderlineColor = textColor;
383 void VisualModel::SetShadowOffset( const Vector2& shadowOffset )
385 mShadowOffset = shadowOffset;
388 void VisualModel::SetShadowColor( const Vector4& shadowColor )
390 mShadowColor = shadowColor;
393 void VisualModel::SetUnderlineColor( const Vector4& color )
395 mUnderlineColor = color;
396 mUnderlineColorSet = true;
399 void VisualModel::SetUnderlineEnabled( bool enabled )
401 mUnderlineEnabled = enabled;
404 const Vector4& VisualModel::GetTextColor() const
409 const Vector2& VisualModel::GetShadowOffset() const
411 return mShadowOffset;
414 const Vector4& VisualModel::GetShadowColor() const
419 const Vector4& VisualModel::GetUnderlineColor() const
421 return mUnderlineColor;
424 bool VisualModel::IsUnderlineEnabled() const
426 return mUnderlineEnabled;
429 VisualModel::~VisualModel()
433 VisualModel::VisualModel()
434 : mUnderlineColorSet( false )
440 } // namespace Toolkit