From eec166d805a775a763db4fa4cb874e87fa640be5 Mon Sep 17 00:00:00 2001 From: Victor Cebollada Date: Sat, 20 Sep 2014 12:34:21 +0100 Subject: [PATCH] TextView - Right to left implementation. Fixes text edition when deleting or replacing characters. Sets direction information (right or left) to each character in the TextView's layout info table. Fixex an out of range crash in TextInput when moving the cursor position. Change-Id: I7ee7a49d4716e92cebc0eec9a6c61a95922952cf Signed-off-by: Victor Cebollada --- .../controls/text-input/text-input-impl.cpp | 6 +- .../controls/text-view/relayout-utilities.cpp | 4 +- .../text-view/text-view-character-processor.cpp | 7 +- .../internal/controls/text-view/text-view-impl.cpp | 97 +++++++++++++++------- .../controls/text-view/text-view-processor-types.h | 33 ++++---- .../text-view/text-view-word-processor.cpp | 5 ++ 6 files changed, 98 insertions(+), 54 deletions(-) diff --git a/base/dali-toolkit/internal/controls/text-input/text-input-impl.cpp b/base/dali-toolkit/internal/controls/text-input/text-input-impl.cpp index 402f619..a9162b8 100644 --- a/base/dali-toolkit/internal/controls/text-input/text-input-impl.cpp +++ b/base/dali-toolkit/internal/controls/text-input/text-input-impl.cpp @@ -1839,7 +1839,7 @@ bool TextInput::OnKeyDownEvent(const KeyEvent& event) DeleteHighlightedText( false ); // Received key String - mCursorPosition = mCursorPosition + InsertAt( Text( keyString ), mCursorPosition, 0 ); + mCursorPosition += InsertAt( Text( keyString ), mCursorPosition, 0 ); update = true; EmitTextModified(); } @@ -2895,7 +2895,7 @@ void TextInput::DrawCursor(const std::size_t nthChar) { // Get height of cursor and set its size Size size( CURSOR_THICKNESS, 0.0f ); - if (!mTextLayoutInfo.mCharacterLayoutInfoTable.empty()) + if( !mTextLayoutInfo.mCharacterLayoutInfoTable.empty() ) { size.height = GetRowRectFromCharacterPosition( GetVisualPosition( mCursorPosition ) ).height; } @@ -4250,7 +4250,7 @@ Vector3 TextInput::GetActualPositionFromCharacterPosition(std::size_t characterP // between RTL and LTR text... if(characterPosition != mTextLayoutInfo.mCharacterLogicalToVisualMap.size()) { - std::size_t visualCharacterAltPosition = mTextLayoutInfo.mCharacterLogicalToVisualMap[characterPosition] - 1; + std::size_t visualCharacterAltPosition = mTextLayoutInfo.mCharacterLogicalToVisualMap[characterPosition]; // VCC TODO: find why in the previous patch it was a -1 here. DALI_ASSERT_ALWAYS(visualCharacterAltPosition < mTextLayoutInfo.mCharacterLayoutInfoTable.size()); const Toolkit::TextView::CharacterLayoutInfo& infoAlt = mTextLayoutInfo.mCharacterLayoutInfoTable[ visualCharacterAltPosition ]; diff --git a/base/dali-toolkit/internal/controls/text-view/relayout-utilities.cpp b/base/dali-toolkit/internal/controls/text-view/relayout-utilities.cpp index d39300e..23c943c 100644 --- a/base/dali-toolkit/internal/controls/text-view/relayout-utilities.cpp +++ b/base/dali-toolkit/internal/controls/text-view/relayout-utilities.cpp @@ -937,8 +937,8 @@ void UpdateLayoutInfoTable( Vector4& minMaxXY, characterLayoutInfo.mSize.height * relayoutData.mShrinkFactor ), positionOffset, ( TextViewProcessor::ParagraphSeparator == wordLayoutInfo.mType ), - false, - true, + characterLayoutInfo.mIsRightToLeft, // whether the character is right to left. + true, // whether the character is visible. descender ); relayoutData.mCharacterLayoutInfoTable.push_back( characterLayoutTableInfo ); diff --git a/base/dali-toolkit/internal/controls/text-view/text-view-character-processor.cpp b/base/dali-toolkit/internal/controls/text-view/text-view-character-processor.cpp index ddcf00f..a3a8ced 100644 --- a/base/dali-toolkit/internal/controls/text-view/text-view-character-processor.cpp +++ b/base/dali-toolkit/internal/controls/text-view/text-view-character-processor.cpp @@ -78,7 +78,8 @@ CharacterLayoutInfo::CharacterLayoutInfo() mIsVisible( true ), mSetText( false ), mSetStyle( false ), - mIsColorGlyph( false ) + mIsColorGlyph( false ), + mIsRightToLeft( false ) { } @@ -102,7 +103,8 @@ CharacterLayoutInfo::CharacterLayoutInfo( const CharacterLayoutInfo& character ) mIsVisible( character.mIsVisible ), mSetText( character.mSetText ), mSetStyle( character.mSetStyle ), - mIsColorGlyph( character.mIsColorGlyph ) + mIsColorGlyph( character.mIsColorGlyph ), + mIsRightToLeft( character.mIsRightToLeft ) { } @@ -147,6 +149,7 @@ CharacterLayoutInfo& CharacterLayoutInfo::operator=( const CharacterLayoutInfo& mSetText = character.mSetText; mSetStyle = character.mSetStyle; mIsColorGlyph = character.mIsColorGlyph; + mIsRightToLeft = character.mIsRightToLeft; return *this; } diff --git a/base/dali-toolkit/internal/controls/text-view/text-view-impl.cpp b/base/dali-toolkit/internal/controls/text-view/text-view-impl.cpp index be8f974..9cce54a 100644 --- a/base/dali-toolkit/internal/controls/text-view/text-view-impl.cpp +++ b/base/dali-toolkit/internal/controls/text-view/text-view-impl.cpp @@ -240,49 +240,84 @@ void TextView::ReplaceTextFromTo( std::size_t position, std::size_t numberOfChar void TextView::ReplaceTextFromTo( std::size_t position, std::size_t numberOfCharacters, const MarkupProcessor::StyledTextArray& text ) { - // Creates metadata with the Insert operation. - TextViewProcessorMetadata metadata; - metadata.mType = TextView::TextReplaced; - metadata.mPosition = position; - metadata.mNumberOfCharacters = numberOfCharacters; - metadata.mText = text; + std::string textStr; + MarkupProcessor::GetPlainString( text, textStr ); - // Store metadata. - mTextViewProcessorOperations.push_back( metadata ); + if( TextProcessor::ContainsRightToLeftCharacter( Text( textStr ) ) || + TextProcessor::ContainsRightToLeftCharacter( Text( GetText() ) ) ) + { + // Temporary fix. Creates the whole layout if there is rtl text. - // Updates current styled text. - MarkupProcessor::StyledTextArray::iterator it = mCurrentStyledText.begin() + position; - mCurrentStyledText.erase( it, it + numberOfCharacters ); - it = mCurrentStyledText.begin() + position; - mCurrentStyledText.insert( it, text.begin(), text.end() ); + // Updates current styled text. + MarkupProcessor::StyledTextArray textToSet = mCurrentStyledText; - // Request to be relaid out - RelayoutRequest(); + MarkupProcessor::StyledTextArray::iterator it = textToSet.begin() + position; + textToSet.erase( it, it + numberOfCharacters ); + it = textToSet.begin() + position; + textToSet.insert( it, text.begin(), text.end() ); - // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values. - mRelayoutOperations = RELAYOUT_ALL; + SetText( textToSet ); + } + else + { + // Creates metadata with the Insert operation. + TextViewProcessorMetadata metadata; + metadata.mType = TextView::TextReplaced; + metadata.mPosition = position; + metadata.mNumberOfCharacters = numberOfCharacters; + metadata.mText = text; + + // Store metadata. + mTextViewProcessorOperations.push_back( metadata ); + + // Updates current styled text. + MarkupProcessor::StyledTextArray::iterator it = mCurrentStyledText.begin() + position; + mCurrentStyledText.erase( it, it + numberOfCharacters ); + it = mCurrentStyledText.begin() + position; + mCurrentStyledText.insert( it, text.begin(), text.end() ); + + // Request to be relaid out + RelayoutRequest(); + + // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values. + mRelayoutOperations = RELAYOUT_ALL; + } } void TextView::RemoveTextFrom( std::size_t position, std::size_t numberOfCharacters ) { - // Creates metadata with the Remove operation. - TextViewProcessorMetadata metadata; - metadata.mType = TextView::TextRemoved; - metadata.mPosition = position; - metadata.mNumberOfCharacters = numberOfCharacters; + if( TextProcessor::ContainsRightToLeftCharacter( Text( GetText() ) ) ) + { + // Temporary fix. Creates the whole layout if there is rtl text. - // Store metadata. - mTextViewProcessorOperations.push_back( metadata ); + // Updates current styled text. + MarkupProcessor::StyledTextArray textToSet = mCurrentStyledText; + MarkupProcessor::StyledTextArray::iterator it = textToSet.begin() + position; + textToSet.erase( it, it + numberOfCharacters ); - // Updates current styled text. - MarkupProcessor::StyledTextArray::iterator it = mCurrentStyledText.begin() + position; - mCurrentStyledText.erase( it, it + numberOfCharacters ); + SetText( textToSet ); + } + else + { + // Creates metadata with the Remove operation. + TextViewProcessorMetadata metadata; + metadata.mType = TextView::TextRemoved; + metadata.mPosition = position; + metadata.mNumberOfCharacters = numberOfCharacters; - // Request to be relaid out - RelayoutRequest(); + // Store metadata. + mTextViewProcessorOperations.push_back( metadata ); - // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values. - mRelayoutOperations = RELAYOUT_ALL; + // Updates current styled text. + MarkupProcessor::StyledTextArray::iterator it = mCurrentStyledText.begin() + position; + mCurrentStyledText.erase( it, it + numberOfCharacters ); + + // Request to be relaid out + RelayoutRequest(); + + // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values. + mRelayoutOperations = RELAYOUT_ALL; + } } std::string TextView::GetText() const diff --git a/base/dali-toolkit/internal/controls/text-view/text-view-processor-types.h b/base/dali-toolkit/internal/controls/text-view/text-view-processor-types.h index 15005cc..8cb689b 100644 --- a/base/dali-toolkit/internal/controls/text-view/text-view-processor-types.h +++ b/base/dali-toolkit/internal/controls/text-view/text-view-processor-types.h @@ -161,24 +161,25 @@ struct CharacterLayoutInfo CharacterLayoutInfo& operator=( const CharacterLayoutInfo& character ); // Metrics of the glyph. - Size mSize; ///< Height of the font and advance (the horizontal distance from the origin of the current character and the next one). - float mBearing; ///< Vertical distance from the baseline to the top of the glyph's boundary box. - float mAscender; ///< Distance from the base line to the top of the line. - float mUnderlineThickness; ///< The underline's thickness. - float mUnderlinePosition; ///< The underline's position. + Size mSize; ///< Height of the font and advance (the horizontal distance from the origin of the current character and the next one). + float mBearing; ///< Vertical distance from the baseline to the top of the glyph's boundary box. + float mAscender; ///< Distance from the base line to the top of the line. + float mUnderlineThickness; ///< The underline's thickness. + float mUnderlinePosition; ///< The underline's position. // Position and alignment offset. It depends on the lay-out. - Vector3 mPosition; ///< Position within the text-view - Vector2 mOffset; ///< Alignment and justification offset. - - RenderableActor mGlyphActor; ///< Handle to a text-actor. - float mColorAlpha; ///< Alpha component for the initial text color when text is faded. - GradientInfo* mGradientInfo; ///< Stores gradient info. - - bool mIsVisible:1; ///< Whether the text-actor is visible. - bool mSetText:1; ///< Whether a new text needs to be set in the text-actor. - bool mSetStyle:1; ///< Whether a new style needs to be set in the text-actor. - bool mIsColorGlyph:1; ///< Whether this character is an emoticon. + Vector3 mPosition; ///< Position within the text-view + Vector2 mOffset; ///< Alignment and justification offset. + + RenderableActor mGlyphActor; ///< Handle to a text-actor. + float mColorAlpha; ///< Alpha component for the initial text color when text is faded. + GradientInfo* mGradientInfo; ///< Stores gradient info. + + bool mIsVisible:1; ///< Whether the text-actor is visible. + bool mSetText:1; ///< Whether a new text needs to be set in the text-actor. + bool mSetStyle:1; ///< Whether a new style needs to be set in the text-actor. + bool mIsColorGlyph:1; ///< Whether this character is an emoticon. + bool mIsRightToLeft:1; ///< Whether this character is right to left. }; typedef std::vector CharacterLayoutInfoContainer; diff --git a/base/dali-toolkit/internal/controls/text-view/text-view-word-processor.cpp b/base/dali-toolkit/internal/controls/text-view/text-view-word-processor.cpp index 800a96b..eba4f52 100644 --- a/base/dali-toolkit/internal/controls/text-view/text-view-word-processor.cpp +++ b/base/dali-toolkit/internal/controls/text-view/text-view-word-processor.cpp @@ -113,6 +113,11 @@ void CreateWordTextInfo( const Text& paragraph, ChooseFontFamilyName( character, *textStyle ); } + // Checks whether the charcter is right to left. + const Character::CharacterDirection direction = character.GetCharacterDirection(); + characterLayoutInfo.mIsRightToLeft = ( ( direction == Character::RightToLeft ) || + ( direction == Character::RightToLeftWeak ) ); + // Gets the metrics of the font. const Font font = Font::New( FontParameters( textStyle->GetFontName(), textStyle->GetFontStyle(), textStyle->GetFontPointSize() ) ); const Font::Metrics metrics = font.GetMetrics( character ); -- 2.7.4