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>
33 VisualModelPtr VisualModel::New()
35 return VisualModelPtr( new VisualModel() );
38 void VisualModel::CreateCharacterToGlyphTable( Length numberOfCharacters )
40 // 1) Reserve some space for the characters to avoid reallocations.
41 if( 0u == numberOfCharacters )
43 // If no number of characters is given, just set something sensible to avoid reallocations.
44 numberOfCharacters = static_cast<Length> ( static_cast<float>( mGlyphs.Count() ) * 1.3f );
46 mCharactersToGlyph.Reserve( numberOfCharacters );
48 DALI_ASSERT_DEBUG( mGlyphsPerCharacter.Count() != 0u ||
49 ( 0u == numberOfCharacters ) );
51 const Length* const glyphsPerCharacterBuffer = mGlyphsPerCharacter.Begin();
53 // 2) Traverse the glyphs and set the glyph indices per character.
55 // Index to the glyph.
56 GlyphIndex glyphIndex = 0u;
57 CharacterIndex characterIndex = 0u;
58 for( Vector<Length>::ConstIterator it = mCharactersPerGlyph.Begin(),
59 endIt = mCharactersPerGlyph.End();
63 const Length numberOfCharactersPerGlyph = *it;
65 Length numberOfGlyphs = 0u;
66 // Set the glyph indices.
67 for( Length index = 0u; index < numberOfCharactersPerGlyph; ++index, ++characterIndex )
69 mCharactersToGlyph.PushBack( glyphIndex );
70 numberOfGlyphs += *( glyphsPerCharacterBuffer + characterIndex );
72 glyphIndex += numberOfGlyphs;
76 void VisualModel::CreateGlyphsPerCharacterTable( Length numberOfCharacters )
78 // 1) Reserve some space for the characters to avoid reallocations.
79 if( 0u == numberOfCharacters )
81 // If no number of characters is given, just set something sensible to avoid reallocations.
82 numberOfCharacters = static_cast<Length> ( static_cast<float>( mGlyphs.Count() ) * 1.3f );
84 mGlyphsPerCharacter.Reserve( numberOfCharacters );
86 // 2) Traverse the glyphs and set the number of glyphs per character.
88 // The number of 'characters per glyph' equal to zero.
89 Length zeroCharactersPerGlyph = 0u;
91 for( Vector<Length>::ConstIterator it = mCharactersPerGlyph.Begin(),
92 endIt = mCharactersPerGlyph.End();
96 const Length numberOfCharactersPerGlyph = *it;
98 // Set the glyphs per character.
99 if( 0u == numberOfCharactersPerGlyph )
101 ++zeroCharactersPerGlyph;
105 const Length numberOfZeroGlyphsPerCharacter = ( numberOfCharactersPerGlyph - 1u );
106 for( Length zeroIndex = 0u; zeroIndex < numberOfZeroGlyphsPerCharacter ; ++zeroIndex )
108 mGlyphsPerCharacter.PushBack( 0u );
111 mGlyphsPerCharacter.PushBack( 1u + zeroCharactersPerGlyph );
113 zeroCharactersPerGlyph = 0u;
118 void VisualModel::GetGlyphs( GlyphInfo* glyphs,
119 GlyphIndex glyphIndex,
120 Length numberOfGlyphs ) const
122 memcpy( glyphs, mGlyphs.Begin() + glyphIndex, numberOfGlyphs * sizeof( GlyphInfo ) );
125 void VisualModel::GetGlyphPositions( Vector2* glyphPositions,
126 GlyphIndex glyphIndex,
127 Length numberOfGlyphs ) const
129 memcpy( glyphPositions, mGlyphPositions.Begin() + glyphIndex, numberOfGlyphs * sizeof( Vector2 ) );
132 void VisualModel::GetNumberOfLines( GlyphIndex glyphIndex,
133 Length numberOfGlyphs,
134 LineIndex& firstLine,
135 Length& numberOfLines ) const
137 // Initialize the number of lines and the first line.
140 bool firstLineFound = false;
142 const GlyphIndex lastGlyphIndex = glyphIndex + numberOfGlyphs;
144 // Traverse the lines and count those lines within the range of glyphs.
145 for( Vector<LineRun>::ConstIterator it = mLines.Begin(),
146 endIt = mLines.End();
150 const LineRun& line = *it;
152 if( ( line.glyphRun.glyphIndex + line.glyphRun.numberOfGlyphs > glyphIndex ) &&
153 ( lastGlyphIndex > line.glyphRun.glyphIndex ) )
155 firstLineFound = true;
158 else if( lastGlyphIndex <= line.glyphRun.glyphIndex )
160 // nothing else to do.
164 if( !firstLineFound )
171 void VisualModel::GetLinesOfGlyphRange( LineRun* lines,
172 GlyphIndex glyphIndex,
173 Length numberOfGlyphs ) const
175 LineIndex firstLine = 0u;
176 Length numberOfLines = 0u;
178 GetNumberOfLines( glyphIndex,
183 memcpy( lines, mLines.Begin() + firstLine, numberOfLines * sizeof( LineRun ) );
186 LineIndex VisualModel::GetLineOfCharacter( CharacterIndex characterIndex )
188 // 1) Check first in the cached line.
190 const LineRun& lineRun = *( mLines.Begin() + mCachedLineIndex );
192 if( ( lineRun.characterRun.characterIndex <= characterIndex ) &&
193 ( characterIndex < lineRun.characterRun.characterIndex + lineRun.characterRun.numberOfCharacters ) )
195 return mCachedLineIndex;
198 // 2) Is not in the cached line. Check in the other lines.
200 LineIndex index = characterIndex < lineRun.characterRun.characterIndex ? 0u : mCachedLineIndex + 1u;
202 for( Vector<LineRun>::ConstIterator it = mLines.Begin() + index,
203 endIt = mLines.End();
207 const LineRun& lineRun = *it;
209 if( characterIndex < lineRun.characterRun.characterIndex + lineRun.characterRun.numberOfCharacters )
211 mCachedLineIndex = index;
219 void VisualModel::GetUnderlineRuns( GlyphRun* underlineRuns,
220 UnderlineRunIndex index,
221 Length numberOfRuns ) const
223 memcpy( underlineRuns,
224 mUnderlineRuns.Begin() + index,
225 numberOfRuns * sizeof( GlyphRun ) );
228 void VisualModel::SetNaturalSize( const Vector2& size )
233 const Vector2& VisualModel::GetNaturalSize() const
238 void VisualModel::SetActualSize( const Vector2& size )
243 const Vector2& VisualModel::GetActualSize() const
248 void VisualModel::SetTextColor( const Vector4& textColor )
250 mTextColor = textColor;
252 if ( !mUnderlineColorSet )
254 mUnderlineColor = textColor;
258 void VisualModel::SetShadowOffset( const Vector2& shadowOffset )
260 mShadowOffset = shadowOffset;
263 void VisualModel::SetShadowColor( const Vector4& shadowColor )
265 mShadowColor = shadowColor;
268 void VisualModel::SetUnderlineColor( const Vector4& color )
270 mUnderlineColor = color;
271 mUnderlineColorSet = true;
274 void VisualModel::SetUnderlineEnabled( bool enabled )
276 mUnderlineEnabled = enabled;
279 void VisualModel::SetUnderlineHeight( float height )
281 mUnderlineHeight = height;
284 const Vector4& VisualModel::GetTextColor() const
289 const Vector2& VisualModel::GetShadowOffset() const
291 return mShadowOffset;
294 const Vector4& VisualModel::GetShadowColor() const
299 const Vector4& VisualModel::GetUnderlineColor() const
301 return mUnderlineColor;
304 bool VisualModel::IsUnderlineEnabled() const
306 return mUnderlineEnabled;
309 float VisualModel::GetUnderlineHeight() const
311 return mUnderlineHeight;
314 void VisualModel::ClearCaches()
316 mCachedLineIndex = 0u;
319 VisualModel::~VisualModel()
323 VisualModel::VisualModel()
325 mGlyphsToCharacters(),
326 mCharactersToGlyph(),
327 mCharactersPerGlyph(),
328 mGlyphsPerCharacter(),
331 mTextColor( Color::BLACK ),
332 mShadowColor( Color::BLACK ),
333 mUnderlineColor( Color::BLACK ),
334 mShadowOffset( Vector2::ZERO ),
335 mUnderlineHeight( 0.0f ),
338 mCachedLineIndex( 0u ),
339 mUnderlineEnabled( false ),
340 mUnderlineColorSet( false )
346 } // namespace Toolkit