X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=dali-toolkit%2Finternal%2Ftext%2Fvisual-model-impl.cpp;h=3e9c1231f920fd58b00d460fb05a8243fcdb93fc;hp=bb7cdde42f9953f1d6cd08e8991a8fa9d52d93fa;hb=5b4982566aba41b5e21c3b8ce3e01a7e86db8f28;hpb=b766a879a8f8b55a7017847894a2f1bc7edd83d8 diff --git a/dali-toolkit/internal/text/visual-model-impl.cpp b/dali-toolkit/internal/text/visual-model-impl.cpp index bb7cdde..3e9c123 100644 --- a/dali-toolkit/internal/text/visual-model-impl.cpp +++ b/dali-toolkit/internal/text/visual-model-impl.cpp @@ -35,29 +35,50 @@ VisualModelPtr VisualModel::New() return VisualModelPtr( new VisualModel() ); } -void VisualModel::CreateCharacterToGlyphTable( Length numberOfCharacters ) +void VisualModel::CreateCharacterToGlyphTable( CharacterIndex startIndex, + Length numberOfCharacters ) { - // 1) Reserve some space for the characters to avoid reallocations. if( 0u == numberOfCharacters ) { - // If no number of characters is given, just set something sensible to avoid reallocations. - numberOfCharacters = static_cast ( static_cast( mGlyphs.Count() ) * 1.3f ); + // Nothing to do. + return; } - mCharactersToGlyph.Reserve( numberOfCharacters ); - DALI_ASSERT_DEBUG( mGlyphsPerCharacter.Count() != 0u || - ( 0u == numberOfCharacters ) ); + DALI_ASSERT_DEBUG( mGlyphsPerCharacter.Count() != 0u ); + + // Get the total number of characters. + const Length totalNumberOfCharacters = ( 0u == mGlyphsToCharacters.Count() ) ? 0u : *( mGlyphsToCharacters.End() - 1u ) + *( mCharactersPerGlyph.End() - 1u ); // Index to the first character + the number of characters that form the last glyph. + + // Whether the current buffer is being updated or is set from scratch. + const bool updateCurrentBuffer = numberOfCharacters < totalNumberOfCharacters; + + Vector newCharactersToGlyph; + GlyphIndex* charactersToGlyphBuffer = NULL; + + // 1) Reserve some space for the glyph indices to avoid reallocations. + if( updateCurrentBuffer ) + { + newCharactersToGlyph.Resize( numberOfCharacters ); + charactersToGlyphBuffer = newCharactersToGlyph.Begin(); + } + else + { + mCharactersToGlyph.Resize( numberOfCharacters ); + charactersToGlyphBuffer = mCharactersToGlyph.Begin() + startIndex; + } const Length* const glyphsPerCharacterBuffer = mGlyphsPerCharacter.Begin(); // 2) Traverse the glyphs and set the glyph indices per character. // Index to the glyph. - GlyphIndex glyphIndex = 0u; - CharacterIndex characterIndex = 0u; - for( Vector::ConstIterator it = mCharactersPerGlyph.Begin(), + const GlyphIndex startGlyphIndex = updateCurrentBuffer ? *( mCharactersToGlyph.Begin() + startIndex ) : 0u; + GlyphIndex glyphIndex = startGlyphIndex; + CharacterIndex characterIndex = startIndex; + const CharacterIndex lastCharacterIndexPlusOne = startIndex + numberOfCharacters; + for( Vector::ConstIterator it = mCharactersPerGlyph.Begin() + glyphIndex, endIt = mCharactersPerGlyph.End(); - it != endIt; + ( it != endIt ) && ( characterIndex < lastCharacterIndexPlusOne ); ++it ) { const Length numberOfCharactersPerGlyph = *it; @@ -66,34 +87,79 @@ void VisualModel::CreateCharacterToGlyphTable( Length numberOfCharacters ) // Set the glyph indices. for( Length index = 0u; index < numberOfCharactersPerGlyph; ++index, ++characterIndex ) { - mCharactersToGlyph.PushBack( glyphIndex ); + *charactersToGlyphBuffer = glyphIndex; numberOfGlyphs += *( glyphsPerCharacterBuffer + characterIndex ); + ++charactersToGlyphBuffer; } glyphIndex += numberOfGlyphs; } + + // If the character to glyph buffer is updated, it needs to be inserted in the model. + if( updateCurrentBuffer ) + { + // Update the indices. + const Length numberOfGlyphs = glyphIndex - startGlyphIndex; + for( Vector::Iterator it = mCharactersToGlyph.Begin() + startIndex, + endIt = mCharactersToGlyph.End(); + it != endIt; + ++it ) + { + *it += numberOfGlyphs; + } + + mCharactersToGlyph.Insert( mCharactersToGlyph.Begin() + startIndex, + newCharactersToGlyph.Begin(), + newCharactersToGlyph.End() ); + + } } -void VisualModel::CreateGlyphsPerCharacterTable( Length numberOfCharacters ) +void VisualModel::CreateGlyphsPerCharacterTable( CharacterIndex startIndex, + Length numberOfCharacters ) { - // 1) Reserve some space for the characters to avoid reallocations. if( 0u == numberOfCharacters ) { - // If no number of characters is given, just set something sensible to avoid reallocations. - numberOfCharacters = static_cast ( static_cast( mGlyphs.Count() ) * 1.3f ); + // Nothing to do. + return; + } + + // Get the total number of characters. + const Length totalNumberOfCharacters = ( 0u == mGlyphsToCharacters.Count() ) ? 0u : *( mGlyphsToCharacters.End() - 1u ) + *( mCharactersPerGlyph.End() - 1u ); // Index to the first character + the number of characters that form the last glyph. + + // Whether the current buffer is being updated or is set from scratch. + const bool updateCurrentBuffer = numberOfCharacters < totalNumberOfCharacters; + + Vector newGlyphsPerCharacter; + Length* glyphsPerCharacterBuffer = NULL; + + // 1) Reserve some space for the glyphs per character to avoid reallocations. + if( updateCurrentBuffer ) + { + newGlyphsPerCharacter.Resize( numberOfCharacters ); + glyphsPerCharacterBuffer = newGlyphsPerCharacter.Begin(); + } + else + { + mGlyphsPerCharacter.Resize( numberOfCharacters ); + glyphsPerCharacterBuffer = mGlyphsPerCharacter.Begin() + startIndex; } - mGlyphsPerCharacter.Reserve( numberOfCharacters ); // 2) Traverse the glyphs and set the number of glyphs per character. + // The glyph index. + const GlyphIndex glyphIndex = updateCurrentBuffer ? *( mCharactersToGlyph.Begin() + startIndex ) : 0u; + Length traversedCharacters = 0; + // The number of 'characters per glyph' equal to zero. Length zeroCharactersPerGlyph = 0u; - for( Vector::ConstIterator it = mCharactersPerGlyph.Begin(), + for( Vector::ConstIterator it = mCharactersPerGlyph.Begin() + glyphIndex, endIt = mCharactersPerGlyph.End(); - it != endIt; + ( it != endIt ) && ( traversedCharacters < numberOfCharacters ); ++it ) { const Length numberOfCharactersPerGlyph = *it; + traversedCharacters += numberOfCharactersPerGlyph; // Set the glyphs per character. if( 0u == numberOfCharactersPerGlyph ) @@ -103,16 +169,30 @@ void VisualModel::CreateGlyphsPerCharacterTable( Length numberOfCharacters ) else { const Length numberOfZeroGlyphsPerCharacter = ( numberOfCharactersPerGlyph - 1u ); - for( Length zeroIndex = 0u; zeroIndex < numberOfZeroGlyphsPerCharacter ; ++zeroIndex ) + for( Length zeroIndex = 0u; zeroIndex < numberOfZeroGlyphsPerCharacter; ++zeroIndex ) { - mGlyphsPerCharacter.PushBack( 0u ); + *glyphsPerCharacterBuffer = 0u; + + // Point to the next position in the buffer. + ++glyphsPerCharacterBuffer; } - mGlyphsPerCharacter.PushBack( 1u + zeroCharactersPerGlyph ); + *glyphsPerCharacterBuffer = zeroCharactersPerGlyph + 1u; zeroCharactersPerGlyph = 0u; + + // Point to the next position in the buffer. + ++glyphsPerCharacterBuffer; } } + + // If the glyphs per character buffer is updated, it needs to be inserted in the model. + if( updateCurrentBuffer ) + { + mGlyphsPerCharacter.Insert( mGlyphsPerCharacter.Begin() + startIndex, + newGlyphsPerCharacter.Begin(), + newGlyphsPerCharacter.End() ); + } } void VisualModel::GetGlyphs( GlyphInfo* glyphs, @@ -149,13 +229,13 @@ void VisualModel::GetNumberOfLines( GlyphIndex glyphIndex, { const LineRun& line = *it; - if( ( line.glyphIndex + line.numberOfGlyphs > glyphIndex ) && - ( lastGlyphIndex > line.glyphIndex ) ) + if( ( line.glyphRun.glyphIndex + line.glyphRun.numberOfGlyphs > glyphIndex ) && + ( lastGlyphIndex > line.glyphRun.glyphIndex ) ) { firstLineFound = true; ++numberOfLines; } - else if( lastGlyphIndex <= line.glyphIndex ) + else if( lastGlyphIndex <= line.glyphRun.glyphIndex ) { // nothing else to do. break; @@ -216,6 +296,15 @@ LineIndex VisualModel::GetLineOfCharacter( CharacterIndex characterIndex ) return index; } +void VisualModel::GetUnderlineRuns( GlyphRun* underlineRuns, + UnderlineRunIndex index, + Length numberOfRuns ) const +{ + memcpy( underlineRuns, + mUnderlineRuns.Begin() + index, + numberOfRuns * sizeof( GlyphRun ) ); +} + void VisualModel::SetNaturalSize( const Vector2& size ) { mNaturalSize = size;