X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali-toolkit%2Finternal%2Ftext%2Flogical-model-impl.cpp;h=2faca97dea759cee1646eda91adb1f3435035111;hb=a7646628bf0d87a7f9e02d8f4db52dea881579c7;hp=807f7fb65df7ee43c1452110275a0004790de39c;hpb=10d2080e1d25b75347daa2f8c2dcee494fbcb175;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git diff --git a/dali-toolkit/internal/text/logical-model-impl.cpp b/dali-toolkit/internal/text/logical-model-impl.cpp index 807f7fb..2faca97 100644 --- a/dali-toolkit/internal/text/logical-model-impl.cpp +++ b/dali-toolkit/internal/text/logical-model-impl.cpp @@ -391,15 +391,42 @@ void ReplaceBidirectionalInfo( CharacterIndex characterIndex, { } +void LogicalModel::SetCharacterDirections( const CharacterDirection* const directions, + Length numberOfCharacters ) +{ + if( 0u == numberOfCharacters ) + { + mCharacterDirections.Clear(); + } + else + { + mCharacterDirections.Resize( numberOfCharacters ); + memcpy( mCharacterDirections.Begin(), directions, numberOfCharacters * sizeof( CharacterDirection ) ); + } +} + void LogicalModel::GetCharacterDirections( CharacterDirection* directions, CharacterIndex characterIndex, Length numberOfCharacters ) const { + if( 0u == mCharacterDirections.Count() ) + { + // Nothing to retrieve if the model has no right to left characters. + return; + } + + memcpy( directions, mCharacterDirections.Begin() + characterIndex, numberOfCharacters * sizeof( CharacterDirection ) ); } CharacterDirection LogicalModel::GetCharacterDirection( CharacterIndex characterIndex ) const { - return false; + if( characterIndex >= mCharacterDirections.Count() ) + { + // The model has no right to left characters, so the vector of directions is void. + return false; + } + + return *( mCharacterDirections.Begin() + characterIndex ); } void LogicalModel::SetVisualToLogicalMap( const BidirectionalLineInfoRun* const bidirectionalInfo, @@ -409,6 +436,7 @@ void LogicalModel::SetVisualToLogicalMap( const BidirectionalLineInfoRun* const { mVisualToLogicalMap.Clear(); mLogicalToVisualMap.Clear(); + mVisualToLogicalCursorMap.Clear(); } else { @@ -416,9 +444,14 @@ void LogicalModel::SetVisualToLogicalMap( const BidirectionalLineInfoRun* const mVisualToLogicalMap.Resize( numberOfCharacters ); mLogicalToVisualMap.Resize( numberOfCharacters ); + const Length numberOfCharactersPlus = numberOfCharacters + 1u; + mVisualToLogicalCursorMap.Resize( numberOfCharactersPlus ); + CharacterIndex* modelVisualToLogicalMapBuffer = mVisualToLogicalMap.Begin(); CharacterIndex* modelLogicalToVisualMapBuffer = mLogicalToVisualMap.Begin(); + CharacterIndex* modelVisualToLogicalCursorMap = mVisualToLogicalCursorMap.Begin(); + CharacterIndex lastIndex = 0u; for( unsigned int bidiIndex = 0u; bidiIndex < numberOfRuns; ++bidiIndex ) { @@ -453,6 +486,114 @@ void LogicalModel::SetVisualToLogicalMap( const BidirectionalLineInfoRun* const { *( modelLogicalToVisualMapBuffer + *( modelVisualToLogicalMapBuffer + index ) ) = index; } + + // Sets the visual to logical conversion map for cursor positions. + + const Length numberOfBidirectionalParagraphs = mBidirectionalParagraphInfo.Count(); + BidirectionalParagraphInfoRun* bidirectionalParagraphInfoBuffer = mBidirectionalParagraphInfo.Begin(); + BidirectionalParagraphInfoRun* bidirectionalParagraph = bidirectionalParagraphInfoBuffer; + + const CharacterDirection* const modelCharacterDirections = mCharacterDirections.Begin(); + + Length bidirectionalParagraphIndex = 0u; + bool isRightToLeftParagraph = false; + for( CharacterIndex index = 0u; index < numberOfCharactersPlus; ++index ) + { + if( bidirectionalParagraph && + ( bidirectionalParagraph->characterRun.characterIndex == index ) ) + { + isRightToLeftParagraph = *( modelCharacterDirections + index ); + } + + if( 0u == index ) + { + if( isRightToLeftParagraph ) + { + *( modelVisualToLogicalCursorMap + index ) = numberOfCharacters; + } + else // else logical position is zero. + { + *( modelVisualToLogicalCursorMap + index ) = 0u; + } + } + else if( numberOfCharacters == index ) + { + if( isRightToLeftParagraph ) + { + *( modelVisualToLogicalCursorMap + index ) = 0u; + } + else // else logical position is the number of characters. + { + *( modelVisualToLogicalCursorMap + index ) = numberOfCharacters; + } + } + else + { + // Get the character indexed by index - 1 and index + // and calculate the logical position according the directions of + // both characters and the direction of the paragraph. + + const CharacterIndex previousIndex = index - 1u; + const CharacterIndex logicalPosition0 = *( modelVisualToLogicalMapBuffer + previousIndex ); + const CharacterIndex logicalPosition1 = *( modelVisualToLogicalMapBuffer + index ); + + const CharacterDirection direction0 = *( modelCharacterDirections + logicalPosition0 ); + const CharacterDirection direction1 = *( modelCharacterDirections + logicalPosition1 ); + + if( direction0 == direction1 ) + { + // Both glyphs have the same direction. + if( direction0 ) + { + *( modelVisualToLogicalCursorMap + index ) = logicalPosition0; + } + else + { + *( modelVisualToLogicalCursorMap + index ) = logicalPosition1; + } + } + else + { + if( isRightToLeftParagraph ) + { + if( direction1 ) + { + *( modelVisualToLogicalCursorMap + index ) = logicalPosition1 + 1u; + } + else + { + *( modelVisualToLogicalCursorMap + index ) = logicalPosition0; + } + } + else + { + if( direction0 ) + { + *( modelVisualToLogicalCursorMap + index ) = logicalPosition1; + } + else + { + *( modelVisualToLogicalCursorMap + index ) = logicalPosition0 + 1u; + } + } + } + } + + if( bidirectionalParagraph && + ( bidirectionalParagraph->characterRun.characterIndex + bidirectionalParagraph->characterRun.numberOfCharacters == index ) ) + { + isRightToLeftParagraph = false; + ++bidirectionalParagraphIndex; + if( bidirectionalParagraphIndex < numberOfBidirectionalParagraphs ) + { + bidirectionalParagraph = bidirectionalParagraphInfoBuffer + bidirectionalParagraphIndex; + } + else + { + bidirectionalParagraph = NULL; + } + } + } } }