X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=dali-toolkit%2Finternal%2Ftext%2Flogical-model-impl.cpp;h=239a2f8897a870950d77598da18a36205e0f60ae;hp=d4a9d94da757622689ddcee533b21618de1c0ca0;hb=0b2e209ecfb3cedba510f53a4af58d7d8a2b3876;hpb=4d763eb68b5aa2448dfc81d90fc5ce598c68c99f diff --git a/dali-toolkit/internal/text/logical-model-impl.cpp b/dali-toolkit/internal/text/logical-model-impl.cpp index d4a9d94..239a2f8 100644 --- a/dali-toolkit/internal/text/logical-model-impl.cpp +++ b/dali-toolkit/internal/text/logical-model-impl.cpp @@ -20,7 +20,7 @@ // INTERNAL INCLUDES #include -#include +#include namespace Dali { @@ -79,168 +79,166 @@ CharacterDirection LogicalModel::GetCharacterDirection( CharacterIndex character } void LogicalModel::SetVisualToLogicalMap( const BidirectionalLineInfoRun* const bidirectionalInfo, - Length numberOfRuns ) + Length numberOfRuns, + CharacterIndex startIndex, + Length numberOfCharacters ) { - if( 0u == numberOfRuns ) - { - mVisualToLogicalMap.Clear(); - mLogicalToVisualMap.Clear(); - mVisualToLogicalCursorMap.Clear(); - } - else - { - const Length numberOfCharacters = mText.Count(); - mVisualToLogicalMap.Resize( numberOfCharacters ); - mLogicalToVisualMap.Resize( numberOfCharacters ); + mVisualToLogicalMap.Resize( numberOfCharacters ); + mLogicalToVisualMap.Resize( numberOfCharacters ); - const Length numberOfCharactersPlus = numberOfCharacters + 1u; - mVisualToLogicalCursorMap.Resize( numberOfCharactersPlus ); + const Length numberOfCharactersPlus = numberOfCharacters + 1u; + mVisualToLogicalCursorMap.Resize( numberOfCharactersPlus ); - CharacterIndex* modelVisualToLogicalMapBuffer = mVisualToLogicalMap.Begin(); - CharacterIndex* modelLogicalToVisualMapBuffer = mLogicalToVisualMap.Begin(); + CharacterIndex* modelVisualToLogicalMapBuffer = mVisualToLogicalMap.Begin(); + CharacterIndex* modelLogicalToVisualMapBuffer = mLogicalToVisualMap.Begin(); - CharacterIndex* modelVisualToLogicalCursorMap = mVisualToLogicalCursorMap.Begin(); + CharacterIndex* modelVisualToLogicalCursorMap = mVisualToLogicalCursorMap.Begin(); - CharacterIndex lastIndex = 0u; - for( unsigned int bidiIndex = 0u; bidiIndex < numberOfRuns; ++bidiIndex ) - { - const BidirectionalLineInfoRun& bidiLineInfo = *( bidirectionalInfo + bidiIndex ); + CharacterIndex lastIndex = startIndex; + for( unsigned int bidiIndex = 0u; bidiIndex < numberOfRuns; ++bidiIndex ) + { + const BidirectionalLineInfoRun& bidiLineInfo = *( bidirectionalInfo + bidiIndex ); - if( lastIndex < bidiLineInfo.characterRun.characterIndex ) - { - // Fill with the identity. - for( ; lastIndex < bidiLineInfo.characterRun.characterIndex; ++lastIndex ) - { - *( modelVisualToLogicalMapBuffer + lastIndex ) = lastIndex; - } - } + if( bidiLineInfo.characterRun.characterIndex + bidiLineInfo.characterRun.numberOfCharacters <= startIndex ) + { + // Skip this paragraph. It has been already processed. + continue; + } - // Fill the conversion table of the run. - for( CharacterIndex index = 0u; - index < bidiLineInfo.characterRun.numberOfCharacters; - ++index, ++lastIndex ) + if( lastIndex < bidiLineInfo.characterRun.characterIndex ) + { + // Fill with the identity. + for( ; lastIndex < bidiLineInfo.characterRun.characterIndex; ++lastIndex ) { - *( modelVisualToLogicalMapBuffer + lastIndex ) = bidiLineInfo.characterRun.characterIndex + *( bidiLineInfo.visualToLogicalMap + index ); + *( modelVisualToLogicalMapBuffer + lastIndex ) = lastIndex; } } - // Complete with the identity if there are some left to right characters after the last right to left. - for( ; lastIndex < numberOfCharacters; ++lastIndex ) + // Fill the conversion table of the run. + for( CharacterIndex index = 0u; + index < bidiLineInfo.characterRun.numberOfCharacters; + ++index, ++lastIndex ) { - *( modelVisualToLogicalMapBuffer + lastIndex ) = lastIndex; + *( modelVisualToLogicalMapBuffer + lastIndex ) = bidiLineInfo.characterRun.characterIndex + *( bidiLineInfo.visualToLogicalMap + index ); } + } - // Sets the logical to visual conversion map. - for( CharacterIndex index = 0u; index < numberOfCharacters; ++index ) - { - *( modelLogicalToVisualMapBuffer + *( modelVisualToLogicalMapBuffer + index ) ) = index; - } + // Complete with the identity if there are some left to right characters after the last right to left. + for( ; lastIndex < numberOfCharacters; ++lastIndex ) + { + *( modelVisualToLogicalMapBuffer + lastIndex ) = lastIndex; + } + + // Sets the logical to visual conversion map. + for( CharacterIndex index = startIndex; index < numberOfCharacters; ++index ) + { + *( modelLogicalToVisualMapBuffer + *( modelVisualToLogicalMapBuffer + index ) ) = index; + } + + // Sets the visual to logical conversion map for cursor positions. - // Sets the visual to logical conversion map for cursor positions. + const Length numberOfBidirectionalParagraphs = mBidirectionalParagraphInfo.Count(); + BidirectionalParagraphInfoRun* bidirectionalParagraphInfoBuffer = mBidirectionalParagraphInfo.Begin(); + BidirectionalParagraphInfoRun* bidirectionalParagraph = bidirectionalParagraphInfoBuffer; - const Length numberOfBidirectionalParagraphs = mBidirectionalParagraphInfo.Count(); - BidirectionalParagraphInfoRun* bidirectionalParagraphInfoBuffer = mBidirectionalParagraphInfo.Begin(); - BidirectionalParagraphInfoRun* bidirectionalParagraph = bidirectionalParagraphInfoBuffer; + const CharacterDirection* const modelCharacterDirections = mCharacterDirections.Begin(); - const CharacterDirection* const modelCharacterDirections = mCharacterDirections.Begin(); + Length bidirectionalParagraphIndex = 0u; + bool isRightToLeftParagraph = false; + for( CharacterIndex index = startIndex; index < numberOfCharactersPlus; ++index ) + { + if( bidirectionalParagraph && + ( bidirectionalParagraph->characterRun.characterIndex == index ) ) + { + isRightToLeftParagraph = *( modelCharacterDirections + index ); + } - Length bidirectionalParagraphIndex = 0u; - bool isRightToLeftParagraph = false; - for( CharacterIndex index = 0u; index < numberOfCharactersPlus; ++index ) + if( 0u == index ) { - if( bidirectionalParagraph && - ( bidirectionalParagraph->characterRun.characterIndex == index ) ) + if( isRightToLeftParagraph ) { - isRightToLeftParagraph = *( modelCharacterDirections + index ); + *( modelVisualToLogicalCursorMap + index ) = numberOfCharacters; } - - if( 0u == index ) + else // else logical position is zero. { - if( isRightToLeftParagraph ) - { - *( modelVisualToLogicalCursorMap + index ) = numberOfCharacters; - } - else // else logical position is zero. - { - *( modelVisualToLogicalCursorMap + index ) = 0u; - } + *( modelVisualToLogicalCursorMap + index ) = 0u; + } + } + else if( numberOfCharacters == index ) + { + if( isRightToLeftParagraph ) + { + *( modelVisualToLogicalCursorMap + index ) = 0u; } - else if( numberOfCharacters == index ) + else // else logical position is the number of characters. { - if( isRightToLeftParagraph ) + *( 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 ) = 0u; + *( modelVisualToLogicalCursorMap + index ) = logicalPosition0; } - else // else logical position is the number of characters. + else { - *( modelVisualToLogicalCursorMap + index ) = numberOfCharacters; + *( modelVisualToLogicalCursorMap + index ) = logicalPosition1; } } 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 ) + if( isRightToLeftParagraph ) { - // Both glyphs have the same direction. - if( direction0 ) + if( direction1 ) { - *( modelVisualToLogicalCursorMap + index ) = logicalPosition0; + *( modelVisualToLogicalCursorMap + index ) = logicalPosition1 + 1u; } else { - *( modelVisualToLogicalCursorMap + index ) = logicalPosition1; + *( modelVisualToLogicalCursorMap + index ) = logicalPosition0; } } else { - if( isRightToLeftParagraph ) + if( direction0 ) { - if( direction1 ) - { - *( modelVisualToLogicalCursorMap + index ) = logicalPosition1 + 1u; - } - else - { - *( modelVisualToLogicalCursorMap + index ) = logicalPosition0; - } + *( modelVisualToLogicalCursorMap + index ) = logicalPosition1; } else { - if( direction0 ) - { - *( modelVisualToLogicalCursorMap + index ) = logicalPosition1; - } - else - { - *( modelVisualToLogicalCursorMap + index ) = logicalPosition0 + 1u; - } + *( modelVisualToLogicalCursorMap + index ) = logicalPosition0 + 1u; } } } + } - if( bidirectionalParagraph && - ( bidirectionalParagraph->characterRun.characterIndex + bidirectionalParagraph->characterRun.numberOfCharacters == index ) ) + if( bidirectionalParagraph && + ( bidirectionalParagraph->characterRun.characterIndex + bidirectionalParagraph->characterRun.numberOfCharacters == index ) ) + { + isRightToLeftParagraph = false; + ++bidirectionalParagraphIndex; + if( bidirectionalParagraphIndex < numberOfBidirectionalParagraphs ) { - isRightToLeftParagraph = false; - ++bidirectionalParagraphIndex; - if( bidirectionalParagraphIndex < numberOfBidirectionalParagraphs ) - { - bidirectionalParagraph = bidirectionalParagraphInfoBuffer + bidirectionalParagraphIndex; - } - else - { - bidirectionalParagraph = NULL; - } + bidirectionalParagraph = bidirectionalParagraphInfoBuffer + bidirectionalParagraphIndex; + } + else + { + bidirectionalParagraph = NULL; } } } @@ -422,6 +420,131 @@ void LogicalModel::ClearFontDescriptionRuns() FreeFontFamilyNames( mFontDescriptionRuns ); } +void LogicalModel::CreateParagraphInfo( CharacterIndex startIndex, + Length numberOfCharacters ) +{ + const Length totalNumberOfCharacters = mLineBreakInfo.Count(); + + // Count the number of LINE_MUST_BREAK to reserve some space for the vector of paragraph's info. + Vector paragraphs; + paragraphs.Reserve( numberOfCharacters ); + const TextAbstraction::LineBreakInfo* lineBreakInfoBuffer = mLineBreakInfo.Begin(); + const CharacterIndex lastCharacterIndexPlusOne = startIndex + numberOfCharacters; + for( Length index = startIndex; index < lastCharacterIndexPlusOne; ++index ) + { + if( TextAbstraction::LINE_MUST_BREAK == *( lineBreakInfoBuffer + index ) ) + { + paragraphs.PushBack( index ); + } + } + + // Whether the current paragraphs are updated or set from scratch. + const bool updateCurrentParagraphs = numberOfCharacters < totalNumberOfCharacters; + + // Reserve space for current paragraphs plus new ones. + const Length numberOfNewParagraphs = paragraphs.Count(); + const Length totalNumberOfParagraphs = mParagraphInfo.Count() + numberOfNewParagraphs; + mParagraphInfo.Resize( totalNumberOfParagraphs ); + + ParagraphRun* paragraphInfoBuffer = NULL; + Vector newParagraphs; + + if( updateCurrentParagraphs ) + { + newParagraphs.Resize( numberOfNewParagraphs ); + paragraphInfoBuffer = newParagraphs.Begin(); + } + else + { + paragraphInfoBuffer = mParagraphInfo.Begin(); + } + + // Find where to insert the new paragraphs. + ParagraphRunIndex paragraphIndex = 0u; + CharacterIndex firstIndex = startIndex; + + if( updateCurrentParagraphs ) + { + for( Vector::ConstIterator it = mParagraphInfo.Begin(), + endIt = mParagraphInfo.Begin() + totalNumberOfParagraphs - numberOfNewParagraphs; + it != endIt; + ++it ) + { + const ParagraphRun& paragraph( *it ); + + if( startIndex < paragraph.characterRun.characterIndex + paragraph.characterRun.numberOfCharacters ) + { + firstIndex = paragraph.characterRun.characterIndex; + break; + } + + ++paragraphIndex; + } + } + + // Create the paragraph info. + ParagraphRunIndex newParagraphIndex = 0u; + for( Vector::ConstIterator it = paragraphs.Begin(), + endIt = paragraphs.End(); + it != endIt; + ++it, ++newParagraphIndex ) + { + const CharacterIndex index = *it; + + ParagraphRun& paragraph = *( paragraphInfoBuffer + newParagraphIndex ); + paragraph.characterRun.characterIndex = firstIndex; + paragraph.characterRun.numberOfCharacters = 1u + index - firstIndex; + + firstIndex += paragraph.characterRun.numberOfCharacters; + } + + + // Insert the new paragraphs. + if( updateCurrentParagraphs ) + { + mParagraphInfo.Insert( mParagraphInfo.Begin() + paragraphIndex, + newParagraphs.Begin(), + newParagraphs.End() ); + + mParagraphInfo.Resize( totalNumberOfParagraphs ); + + // Update the next paragraph indices. + for( Vector::Iterator it = mParagraphInfo.Begin() + paragraphIndex + newParagraphs.Count(), + endIt = mParagraphInfo.End(); + it != endIt; + ++it ) + { + ParagraphRun& paragraph( *it ); + + paragraph.characterRun.characterIndex += numberOfCharacters; + } + } +} + +void LogicalModel::FindParagraphs( CharacterIndex index, + Length numberOfCharacters, + Vector& paragraphs ) +{ + // Reserve som space for the paragraph indices. + paragraphs.Reserve( mParagraphInfo.Count() ); + + // Traverse the paragraphs to find which ones contain the given characters. + ParagraphRunIndex paragraphIndex = 0u; + for( Vector::ConstIterator it = mParagraphInfo.Begin(), + endIt = mParagraphInfo.End(); + it != endIt; + ++it, ++paragraphIndex ) + { + const ParagraphRun& paragraph( *it ); + + if( ( paragraph.characterRun.characterIndex + paragraph.characterRun.numberOfCharacters > index ) && + ( paragraph.characterRun.characterIndex < index + numberOfCharacters ) ) + { + paragraphs.PushBack( paragraphIndex ); + } + } +} + LogicalModel::~LogicalModel() { ClearFontDescriptionRuns();