TextView - Right to left implementation. 63/27863/1
authorVictor Cebollada <v.cebollada@samsung.com>
Sat, 20 Sep 2014 11:34:21 +0000 (12:34 +0100)
committerVictor Cebollada <v.cebollada@samsung.com>
Sat, 20 Sep 2014 11:48:53 +0000 (12:48 +0100)
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 <v.cebollada@samsung.com>
base/dali-toolkit/internal/controls/text-input/text-input-impl.cpp
base/dali-toolkit/internal/controls/text-view/relayout-utilities.cpp
base/dali-toolkit/internal/controls/text-view/text-view-character-processor.cpp
base/dali-toolkit/internal/controls/text-view/text-view-impl.cpp
base/dali-toolkit/internal/controls/text-view/text-view-processor-types.h
base/dali-toolkit/internal/controls/text-view/text-view-word-processor.cpp

index 402f619..a9162b8 100644 (file)
@@ -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 ];
index d39300e..23c943c 100644 (file)
@@ -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 );
index ddcf00f..a3a8ced 100644 (file)
@@ -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;
 }
index be8f974..9cce54a 100644 (file)
@@ -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
index 15005cc..8cb689b 100644 (file)
@@ -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<CharacterLayoutInfo> CharacterLayoutInfoContainer;
 
index 800a96b..eba4f52 100644 (file)
@@ -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 );