- Fixed a SINGLE_LINE_BOX text update bug.
Change-Id: If1742cf19ffd75cda66ec705ae611ec8340ef48c
Signed-off-by: Seoyeon Kim <seoyeon2.kim@samsung.com>
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] )
}
-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 )
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.
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;
( 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.
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 )
index = isRightToLeftParagraph ? line.characterRun.characterIndex + line.characterRun.numberOfCharacters - 1u : line.characterRun.characterIndex;
if( bidiLineFetched )
{
- index = logicalModel->GetLogicalCharacterIndex( index );
+ index = parameters.logicalModel->GetLogicalCharacterIndex( index );
}
}
else
}
}
- 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 );
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,
secondaryNumberOfGlyphs,
glyphMetrics,
glyphInfoBuffer,
- metrics );
+ parameters.metrics );
// Set the secondary cursor's position.
};
/**
+ * @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.
* 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 );
/**
mModel->mLogicalModel->UpdateTextStyleRuns( startOfSelectedText, -static_cast<int>( 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<Character>::Iterator first = utf32Characters.Begin() + startOfSelectedText;
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.
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;
+ }
}
}
}
// 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;
( ( 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.