From 5177de187f2bb2736603cbd10f99e3a50084ebc7 Mon Sep 17 00:00:00 2001 From: Seoyeon Kim Date: Fri, 7 Jul 2017 15:25:58 +0900 Subject: [PATCH] Fixed for single line text updates - Fixed a SINGLE_LINE_BOX text update bug. Change-Id: If1742cf19ffd75cda66ec705ae611ec8340ef48c Signed-off-by: Seoyeon Kim --- .../dali-toolkit-internal/utc-Dali-Text-Cursor.cpp | 13 ++++-- .../internal/text/cursor-helper-functions.cpp | 53 ++++++++++------------ .../internal/text/cursor-helper-functions.h | 22 +++++---- .../internal/text/text-controller-impl.cpp | 44 ++++++++++++------ dali-toolkit/internal/text/text-controller.cpp | 28 ++++++++++-- 5 files changed, 103 insertions(+), 57 deletions(-) diff --git a/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Cursor.cpp b/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Cursor.cpp index 1e2b72d..2a5ae46 100644 --- a/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Cursor.cpp +++ b/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Cursor.cpp @@ -206,13 +206,18 @@ bool GetCursorPositionTest( const GetCursorPositionData& data ) visualModel, metrics ); + GetCursorPositionParameters parameters; + parameters.visualModel = visualModel; + parameters.logicalModel = logicalModel; + parameters.metrics = metrics; + parameters.isMultiline = true; + for( unsigned int index = 0; index < data.numberOfTests; ++index ) { CursorInfo cursorInfo; - GetCursorPosition( visualModel, - logicalModel, - metrics, - data.logicalIndex[index], + parameters.logical = data.logicalIndex[index]; + + GetCursorPosition( parameters, cursorInfo ); if( cursorInfo.primaryPosition.x != data.visualX[index] ) diff --git a/dali-toolkit/internal/text/cursor-helper-functions.cpp b/dali-toolkit/internal/text/cursor-helper-functions.cpp index 04a1af3..91b6a40 100644 --- a/dali-toolkit/internal/text/cursor-helper-functions.cpp +++ b/dali-toolkit/internal/text/cursor-helper-functions.cpp @@ -464,24 +464,21 @@ CharacterIndex GetClosestCursorIndex( VisualModelPtr visualModel, } -void GetCursorPosition( VisualModelPtr visualModel, - LogicalModelPtr logicalModel, - MetricsPtr metrics, - CharacterIndex logical, +void GetCursorPosition( GetCursorPositionParameters& parameters, CursorInfo& cursorInfo ) { // Whether the logical cursor position is at the end of the whole text. - const bool isLastPosition = logicalModel->mText.Count() == logical; + const bool isLastPosition = parameters.logicalModel->mText.Count() == parameters.logical; // Get the line where the character is laid-out. - const CharacterIndex characterOfLine = isLastPosition ? ( logical - 1u ) : logical; + const CharacterIndex characterOfLine = isLastPosition ? ( parameters.logical - 1u ) : parameters.logical; // Whether the cursor is in the last position and the last position is a new paragraph character. - const bool isLastNewParagraph = isLastPosition && TextAbstraction::IsNewParagraph( *( logicalModel->mText.Begin() + characterOfLine ) ); + const bool isLastNewParagraph = parameters.isMultiline && isLastPosition && TextAbstraction::IsNewParagraph( *( parameters.logicalModel->mText.Begin() + characterOfLine ) ); - const LineRun* const modelLines = visualModel->mLines.Begin(); + const LineRun* const modelLines = parameters.visualModel->mLines.Begin(); - const LineIndex lineIndex = visualModel->GetLineOfCharacter( characterOfLine ); + const LineIndex lineIndex = parameters.visualModel->GetLineOfCharacter( characterOfLine ); const LineRun& line = *( modelLines + lineIndex ); if( isLastNewParagraph ) @@ -493,7 +490,7 @@ void GetCursorPosition( VisualModelPtr visualModel, cursorInfo.isSecondaryCursor = false; // Set the line offset and height. - cursorInfo.lineOffset = CalculateLineOffset( visualModel->mLines, + cursorInfo.lineOffset = CalculateLineOffset( parameters.visualModel->mLines, newLineIndex ); // The line height is the addition of the line ascender and the line descender. @@ -508,24 +505,24 @@ void GetCursorPosition( VisualModelPtr visualModel, cursorInfo.primaryPosition.y = cursorInfo.lineOffset; // Transform the cursor info from line's coords to text's coords. - cursorInfo.primaryPosition.x += ( LTR == line.direction ) ? 0.f : visualModel->mControlSize.width; + cursorInfo.primaryPosition.x += ( LTR == line.direction ) ? 0.f : parameters.visualModel->mControlSize.width; } else { // Whether this line is a bidirectional line. - const bool bidiLineFetched = logicalModel->FetchBidirectionalLineInfo( characterOfLine ); + const bool bidiLineFetched = parameters.logicalModel->FetchBidirectionalLineInfo( characterOfLine ); // Check if the logical position is the first or the last one of the line. - const bool isFirstPositionOfLine = line.characterRun.characterIndex == logical; - const bool isLastPositionOfLine = line.characterRun.characterIndex + line.characterRun.numberOfCharacters == logical; + const bool isFirstPositionOfLine = line.characterRun.characterIndex == parameters.logical; + const bool isLastPositionOfLine = line.characterRun.characterIndex + line.characterRun.numberOfCharacters == parameters.logical; // 'logical' is the logical 'cursor' index. // Get the next and current logical 'character' index. - const CharacterIndex characterIndex = isFirstPositionOfLine ? logical : logical - 1u; - const CharacterIndex nextCharacterIndex = isLastPositionOfLine ? characterIndex : logical; + const CharacterIndex characterIndex = isFirstPositionOfLine ? parameters.logical : parameters.logical - 1u; + const CharacterIndex nextCharacterIndex = isLastPositionOfLine ? characterIndex : parameters.logical; // The character's direction buffer. - const CharacterDirection* const directionsBuffer = bidiLineFetched ? logicalModel->mCharacterDirections.Begin() : NULL; + const CharacterDirection* const directionsBuffer = bidiLineFetched ? parameters.logicalModel->mCharacterDirections.Begin() : NULL; CharacterDirection isCurrentRightToLeft = false; CharacterDirection isNextRightToLeft = false; @@ -544,7 +541,7 @@ void GetCursorPosition( VisualModelPtr visualModel, ( isFirstPositionOfLine && ( isRightToLeftParagraph != isCurrentRightToLeft ) ) ); // Set the line offset and height. - cursorInfo.lineOffset = CalculateLineOffset( visualModel->mLines, + cursorInfo.lineOffset = CalculateLineOffset( parameters.visualModel->mLines, lineIndex ); // The line height is the addition of the line ascender and the line descender. @@ -569,7 +566,7 @@ void GetCursorPosition( VisualModelPtr visualModel, index = isRightToLeftParagraph ? line.characterRun.characterIndex : line.characterRun.characterIndex + line.characterRun.numberOfCharacters - 1u; if( bidiLineFetched ) { - index = logicalModel->GetLogicalCharacterIndex( index ); + index = parameters.logicalModel->GetLogicalCharacterIndex( index ); } } else if( isFirstPositionOfLine ) @@ -577,7 +574,7 @@ void GetCursorPosition( VisualModelPtr visualModel, index = isRightToLeftParagraph ? line.characterRun.characterIndex + line.characterRun.numberOfCharacters - 1u : line.characterRun.characterIndex; if( bidiLineFetched ) { - index = logicalModel->GetLogicalCharacterIndex( index ); + index = parameters.logicalModel->GetLogicalCharacterIndex( index ); } } else @@ -586,12 +583,12 @@ void GetCursorPosition( VisualModelPtr visualModel, } } - const GlyphIndex* const charactersToGlyphBuffer = visualModel->mCharactersToGlyph.Begin(); - const Length* const glyphsPerCharacterBuffer = visualModel->mGlyphsPerCharacter.Begin(); - const Length* const charactersPerGlyphBuffer = visualModel->mCharactersPerGlyph.Begin(); - const CharacterIndex* const glyphsToCharactersBuffer = visualModel->mGlyphsToCharacters.Begin(); - const Vector2* const glyphPositionsBuffer = visualModel->mGlyphPositions.Begin(); - const GlyphInfo* const glyphInfoBuffer = visualModel->mGlyphs.Begin(); + const GlyphIndex* const charactersToGlyphBuffer = parameters.visualModel->mCharactersToGlyph.Begin(); + const Length* const glyphsPerCharacterBuffer = parameters.visualModel->mGlyphsPerCharacter.Begin(); + const Length* const charactersPerGlyphBuffer = parameters.visualModel->mCharactersPerGlyph.Begin(); + const CharacterIndex* const glyphsToCharactersBuffer = parameters.visualModel->mGlyphsToCharacters.Begin(); + const Vector2* const glyphPositionsBuffer = parameters.visualModel->mGlyphPositions.Begin(); + const GlyphInfo* const glyphInfoBuffer = parameters.visualModel->mGlyphs.Begin(); // Convert the cursor position into the glyph position. const GlyphIndex primaryGlyphIndex = *( charactersToGlyphBuffer + index ); @@ -604,7 +601,7 @@ void GetCursorPosition( VisualModelPtr visualModel, primaryNumberOfGlyphs, glyphMetrics, glyphInfoBuffer, - metrics ); + parameters.metrics ); // Whether to add the glyph's advance to the cursor position. // i.e if the paragraph is left to right and the logical cursor is zero, the position is the position of the first glyph and the advance is not added, @@ -698,7 +695,7 @@ void GetCursorPosition( VisualModelPtr visualModel, secondaryNumberOfGlyphs, glyphMetrics, glyphInfoBuffer, - metrics ); + parameters.metrics ); // Set the secondary cursor's position. diff --git a/dali-toolkit/internal/text/cursor-helper-functions.h b/dali-toolkit/internal/text/cursor-helper-functions.h index 34a5f7b..ad17b31 100644 --- a/dali-toolkit/internal/text/cursor-helper-functions.h +++ b/dali-toolkit/internal/text/cursor-helper-functions.h @@ -71,6 +71,18 @@ struct CursorInfo }; /** + * @brief Parameters passed to the GetCursorPosition() function. + */ +struct GetCursorPositionParameters +{ + VisualModelPtr visualModel; ///< The visual model. + LogicalModelPtr logicalModel; ///< The logical model. + MetricsPtr metrics; ///< A wrapper around FontClient used to get metrics. + CharacterIndex logical; ///< The logical cursor position (in characters). 0 is just before the first character, a value equal to the number of characters is just after the last character. + bool isMultiline; ///< Whether the text control is multi-line. +}; + +/** * @brief Retrieves the closest line for a given touch point. * * It returns the first line if the touch point is above the text and the last line if the touch point is below. @@ -130,16 +142,10 @@ CharacterIndex GetClosestCursorIndex( VisualModelPtr visualModel, * It retrieves as well the line's height and the cursor's height and * if there is a valid alternative cursor, its position and height. * - * @param[in] visualModel The visual model. - * @param[in] logicalModel The logical model. - * @param[in] metrics A wrapper around FontClient used to get metrics. - * @param[in] logical The logical cursor position (in characters). 0 is just before the first character, a value equal to the number of characters is just after the last character. + * @param[in] parameters Parameters used to calculate the cursor's position. * @param[out] cursorInfo The line's height, the cursor's height, the cursor's position and whether there is an alternative cursor. */ -void GetCursorPosition( VisualModelPtr visualModel, - LogicalModelPtr logicalModel, - MetricsPtr metrics, - CharacterIndex logical, +void GetCursorPosition( GetCursorPositionParameters& parameters, CursorInfo& cursorInfo ); /** diff --git a/dali-toolkit/internal/text/text-controller-impl.cpp b/dali-toolkit/internal/text/text-controller-impl.cpp index 6a90595..532afed 100644 --- a/dali-toolkit/internal/text/text-controller-impl.cpp +++ b/dali-toolkit/internal/text/text-controller-impl.cpp @@ -1789,8 +1789,18 @@ void Controller::Impl::RetrieveSelection( std::string& selectedText, bool delete mModel->mLogicalModel->UpdateTextStyleRuns( startOfSelectedText, -static_cast( lengthOfSelectedText ) ); // Mark the paragraphs to be updated. - mTextUpdateInfo.mCharacterIndex = startOfSelectedText; - mTextUpdateInfo.mNumberOfCharactersToRemove = lengthOfSelectedText; + if( Layout::Engine::SINGLE_LINE_BOX == mLayoutEngine.GetLayout() ) + { + mTextUpdateInfo.mCharacterIndex = 0; + mTextUpdateInfo.mNumberOfCharactersToRemove = mTextUpdateInfo.mPreviousNumberOfCharacters; + mTextUpdateInfo.mNumberOfCharactersToAdd = mTextUpdateInfo.mPreviousNumberOfCharacters - lengthOfSelectedText; + mTextUpdateInfo.mClearAll = true; + } + else + { + mTextUpdateInfo.mCharacterIndex = startOfSelectedText; + mTextUpdateInfo.mNumberOfCharactersToRemove = lengthOfSelectedText; + } // Delete text between handles Vector::Iterator first = utf32Characters.Begin() + startOfSelectedText; @@ -2621,13 +2631,18 @@ void Controller::Impl::GetCursorPosition( CharacterIndex logical, return; } - Text::GetCursorPosition( mModel->mVisualModel, - mModel->mLogicalModel, - mMetrics, - logical, + const bool isMultiLine = ( Layout::Engine::MULTI_LINE_BOX == mLayoutEngine.GetLayout() ); + GetCursorPositionParameters parameters; + parameters.visualModel = mModel->mVisualModel; + parameters.logicalModel = mModel->mLogicalModel; + parameters.metrics = mMetrics; + parameters.logical = logical; + parameters.isMultiline = isMultiLine; + + Text::GetCursorPosition( parameters, cursorInfo ); - if( Layout::Engine::MULTI_LINE_BOX == mLayoutEngine.GetLayout() ) + if( isMultiLine ) { // If the text is editable and multi-line, the cursor position after a white space shouldn't exceed the boundaries of the text control. @@ -2845,13 +2860,16 @@ void Controller::Impl::ScrollToMakePositionVisible( const Vector2& position, flo mModel->mScrollPosition.x = mModel->mVisualModel->mControlSize.width - positionEndX; } - if( decoratorPositionBeginY < 0.f ) - { - mModel->mScrollPosition.y = -position.y; - } - else if( decoratorPositionEndY > mModel->mVisualModel->mControlSize.height ) + if( Layout::Engine::MULTI_LINE_BOX == mLayoutEngine.GetLayout() ) { - mModel->mScrollPosition.y = mModel->mVisualModel->mControlSize.height - positionEndY; + if( decoratorPositionBeginY < 0.f ) + { + mModel->mScrollPosition.y = -position.y; + } + else if( decoratorPositionEndY > mModel->mVisualModel->mControlSize.height ) + { + mModel->mScrollPosition.y = mModel->mVisualModel->mControlSize.height - positionEndY; + } } } diff --git a/dali-toolkit/internal/text/text-controller.cpp b/dali-toolkit/internal/text/text-controller.cpp index b94ff3a..b2fec63 100644 --- a/dali-toolkit/internal/text/text-controller.cpp +++ b/dali-toolkit/internal/text/text-controller.cpp @@ -2947,8 +2947,18 @@ void Controller::InsertText( const std::string& text, Controller::InsertType typ } // Mark the first paragraph to be updated. - mImpl->mTextUpdateInfo.mCharacterIndex = std::min( cursorIndex, mImpl->mTextUpdateInfo.mCharacterIndex ); - mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd += maxSizeOfNewText; + if( Layout::Engine::SINGLE_LINE_BOX == mImpl->mLayoutEngine.GetLayout() ) + { + mImpl->mTextUpdateInfo.mCharacterIndex = 0; + mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = mImpl->mTextUpdateInfo.mPreviousNumberOfCharacters; + mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd = numberOfCharactersInModel + maxSizeOfNewText; + mImpl->mTextUpdateInfo.mClearAll = true; + } + else + { + mImpl->mTextUpdateInfo.mCharacterIndex = std::min( cursorIndex, mImpl->mTextUpdateInfo.mCharacterIndex ); + mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd += maxSizeOfNewText; + } // Update the cursor index. cursorIndex += maxSizeOfNewText; @@ -3046,8 +3056,18 @@ bool Controller::RemoveText( int cursorOffset, ( ( cursorIndex + numberOfCharacters ) <= mImpl->mTextUpdateInfo.mPreviousNumberOfCharacters ) ) { // Mark the paragraphs to be updated. - mImpl->mTextUpdateInfo.mCharacterIndex = std::min( cursorIndex, mImpl->mTextUpdateInfo.mCharacterIndex ); - mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove += numberOfCharacters; + if( Layout::Engine::SINGLE_LINE_BOX == mImpl->mLayoutEngine.GetLayout() ) + { + mImpl->mTextUpdateInfo.mCharacterIndex = 0; + mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = mImpl->mTextUpdateInfo.mPreviousNumberOfCharacters; + mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd = mImpl->mTextUpdateInfo.mPreviousNumberOfCharacters - numberOfCharacters; + mImpl->mTextUpdateInfo.mClearAll = true; + } + else + { + mImpl->mTextUpdateInfo.mCharacterIndex = std::min( cursorIndex, mImpl->mTextUpdateInfo.mCharacterIndex ); + mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove += numberOfCharacters; + } // Update the input style and remove the text's style before removing the text. -- 2.7.4