From 91b718d20fa4a1f9e2f13ae25a730cc0e464da12 Mon Sep 17 00:00:00 2001 From: Victor Cebollada Date: Tue, 20 Oct 2015 09:18:35 +0100 Subject: [PATCH 1/1] Fix cursor position for ligatures and group of glyphs. * Fix an issue with the Devanagari script. Change-Id: I463d2171add2829f14039d8b2ac5bd68bafe151e Signed-off-by: Victor Cebollada --- .../internal/text/text-controller-impl.cpp | 65 +++++++++++++--------- 1 file changed, 40 insertions(+), 25 deletions(-) diff --git a/dali-toolkit/internal/text/text-controller-impl.cpp b/dali-toolkit/internal/text/text-controller-impl.cpp index e6a8b18..b1c0b14 100644 --- a/dali-toolkit/internal/text/text-controller-impl.cpp +++ b/dali-toolkit/internal/text/text-controller-impl.cpp @@ -1438,7 +1438,6 @@ CharacterIndex Controller::Impl::GetClosestCursorIndex( float visualX, // Get the glyphs per character table. const Length* const glyphsPerCharacterBuffer = mVisualModel->mGlyphsPerCharacter.Begin(); - const Length* const charactersPerGlyphBuffer = mVisualModel->mCharactersPerGlyph.Begin(); // If the vector is void, there is no right to left characters. const bool hasRightToLeftCharacters = NULL != visualToLogicalBuffer; @@ -1452,6 +1451,7 @@ CharacterIndex Controller::Impl::GetClosestCursorIndex( float visualX, // Traverses glyphs in visual order. To do that use the visual to logical conversion table. CharacterIndex visualIndex = startCharacter; + Length numberOfCharacters = 0u; for( ; !matched && ( visualIndex < endCharacter ); ++visualIndex ) { // The character in logical order. @@ -1460,44 +1460,59 @@ CharacterIndex Controller::Impl::GetClosestCursorIndex( float visualX, // Get the script of the character. const Script script = mLogicalModel->GetScript( characterLogicalOrderIndex ); - // The first glyph for that character in logical order. - const GlyphIndex glyphLogicalOrderIndex = *( charactersToGlyphBuffer + characterLogicalOrderIndex ); // The number of glyphs for that character const Length numberOfGlyphs = *( glyphsPerCharacterBuffer + characterLogicalOrderIndex ); + ++numberOfCharacters; - // Get the metrics for the group of glyphs. - GlyphMetrics glyphMetrics; - GetGlyphsMetrics( glyphLogicalOrderIndex, - numberOfGlyphs, - glyphMetrics, - mVisualModel, - mMetrics ); - const Vector2& position = *( positionsBuffer + glyphLogicalOrderIndex ); + if( 0u != numberOfGlyphs ) + { + // Get the first character/glyph of the group of glyphs. + const CharacterIndex firstVisualCharacterIndex = 1u + visualIndex - numberOfCharacters; + const CharacterIndex firstLogicalCharacterIndex = hasRightToLeftCharacters ? *( visualToLogicalBuffer + firstVisualCharacterIndex ) : firstVisualCharacterIndex; + const GlyphIndex firstLogicalGlyphIndex = *( charactersToGlyphBuffer + firstLogicalCharacterIndex ); - // Prevents to jump the whole Latin ligatures like fi, ff, or Arabic ï»»... - const Length numberOfCharactersInLigature = HasLigatureMustBreak( script ) ? *( charactersPerGlyphBuffer + glyphLogicalOrderIndex ) : 1u; - const float glyphAdvance = glyphMetrics.advance / static_cast( numberOfCharactersInLigature ); + // Get the metrics for the group of glyphs. + GlyphMetrics glyphMetrics; + GetGlyphsMetrics( firstLogicalGlyphIndex, + numberOfGlyphs, + glyphMetrics, + mVisualModel, + mMetrics ); - for( GlyphIndex index = 0u; !matched && ( index < numberOfCharactersInLigature ); ++index ) - { - // Find the mid-point of the area containing the glyph - const float glyphCenter = -glyphMetrics.xBearing + position.x + ( static_cast( index ) + 0.5f ) * glyphAdvance; + // Get the position of the first glyph. + const Vector2& position = *( positionsBuffer + firstLogicalGlyphIndex ); + + // Whether the glyph can be split, like Latin ligatures fi, ff or Arabic ï»». + const bool isInterglyphIndex = ( numberOfCharacters > numberOfGlyphs ) && HasLigatureMustBreak( script ); + const Length numberOfBlocks = isInterglyphIndex ? numberOfCharacters : 1u; + const float glyphAdvance = glyphMetrics.advance / static_cast( numberOfBlocks ); + + GlyphIndex index = 0u; + for( ; !matched && ( index < numberOfBlocks ); ++index ) + { + // Find the mid-point of the area containing the glyph + const float glyphCenter = -glyphMetrics.xBearing + position.x + ( static_cast( index ) + 0.5f ) * glyphAdvance; - if( visualX < glyphCenter ) + if( visualX < glyphCenter ) + { + matched = true; + break; + } + } + + if( matched ) { - visualIndex += index; - matched = true; + visualIndex = firstVisualCharacterIndex + index; break; } - } - if( matched ) - { - break; + numberOfCharacters = 0u; } + } + // Return the logical position of the cursor in characters. if( !matched ) -- 2.7.4