Fixed an error adding duplicate primary position.y 19/133319/9
authorJinho, Lee <jeano.lee@samsung.com>
Fri, 9 Jun 2017 16:32:56 +0000 (01:32 +0900)
committerJinho, Lee <jeano.lee@samsung.com>
Tue, 20 Jun 2017 13:08:24 +0000 (22:08 +0900)
In the target, characters with different glyph heights
(ex: Korean, English: "안녕하세요, hello") are written in same text field

when the character is deleted by one character,
the position of the TextField continuously goes down.

Change-Id: Ic44d79992eec67ae7ddec9e302c95877f90f2580

automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp
dali-toolkit/internal/text/cursor-helper-functions.cpp
dali-toolkit/internal/text/cursor-helper-functions.h
dali-toolkit/internal/text/decorator/text-decorator.cpp
dali-toolkit/internal/text/decorator/text-decorator.h
dali-toolkit/internal/text/text-controller-impl.cpp

index c143510..053c79c 100644 (file)
@@ -1801,6 +1801,70 @@ int utcDaliTextEditorEvent05(void)
   END_TEST;
 }
 
   END_TEST;
 }
 
+int utcDaliTextEditorEvent06(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" utcDaliTextEditorEvent06");
+
+  // Checks if the highlight actor is created.
+
+  TextEditor editor = TextEditor::New();
+  DALI_TEST_CHECK( editor );
+
+  Stage::GetCurrent().Add( editor );
+
+  editor.SetProperty( TextEditor::Property::TEXT, "Hello\nworld\nHello world" );
+  editor.SetProperty( TextEditor::Property::POINT_SIZE, 10.f );
+  editor.SetSize( 100.f, 50.f );
+  editor.SetParentOrigin( ParentOrigin::TOP_LEFT );
+  editor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+
+  // Avoid a crash when core load gl resources.
+  application.GetGlAbstraction().SetCheckFramebufferStatusResult( GL_FRAMEBUFFER_COMPLETE );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Tap on the text editor
+  application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 3.f, 25.0f ) ) );
+  application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 3.f, 25.0f ) ) );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Move to seconds line of the text.
+  application.ProcessEvent( GenerateKey( "", "", DALI_KEY_CURSOR_DOWN, 0, 0, Integration::KeyEvent::Down, DEFAULT_DEVICE_NAME, DevelKeyEvent::DeviceClass::NONE ) );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  float layoutHeight = editor.GetHeightForWidth( 100.f );
+
+
+  // Add  another script characters ( glyph height is defferent )
+  application.ProcessEvent( GenerateKey( "d", "ㅁ", KEY_D_CODE, 0, 0, Integration::KeyEvent::Down, DEFAULT_DEVICE_NAME, DevelKeyEvent::DeviceClass::NONE ) );
+  application.ProcessEvent( GenerateKey( "d", "ኢ", KEY_D_CODE, 0, 0, Integration::KeyEvent::Down, DEFAULT_DEVICE_NAME, DevelKeyEvent::DeviceClass::NONE ) );
+
+  // Delete characters
+  application.ProcessEvent( GenerateKey( "", "", DALI_KEY_BACKSPACE, 0, 0, Integration::KeyEvent::Down, DEFAULT_DEVICE_NAME, DevelKeyEvent::DeviceClass::NONE ) );
+  application.ProcessEvent( GenerateKey( "", "", DALI_KEY_BACKSPACE, 0, 0, Integration::KeyEvent::Down, DEFAULT_DEVICE_NAME, DevelKeyEvent::DeviceClass::NONE ) );
+
+  DALI_TEST_EQUALS( layoutHeight, editor.GetHeightForWidth( 100.f ), TEST_LOCATION );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( "Hello\nworld\nHello world", editor.GetProperty<std::string>( TextEditor::Property::TEXT ), TEST_LOCATION );
+
+
+
+  END_TEST;
+}
+
 int utcDaliTextEditorHandles(void)
 {
   ToolkitTestApplication application;
 int utcDaliTextEditorHandles(void)
 {
   ToolkitTestApplication application;
index b847996..04a1af3 100644 (file)
@@ -668,9 +668,11 @@ void GetCursorPosition( VisualModelPtr visualModel,
     // Set the primary cursor's height.
     cursorInfo.primaryCursorHeight = cursorInfo.isSecondaryCursor ? 0.5f * glyphMetrics.fontHeight : glyphMetrics.fontHeight;
 
     // Set the primary cursor's height.
     cursorInfo.primaryCursorHeight = cursorInfo.isSecondaryCursor ? 0.5f * glyphMetrics.fontHeight : glyphMetrics.fontHeight;
 
+
+    cursorInfo.glyphOffset = line.ascender - glyphMetrics.ascender;
     // Set the primary cursor's position.
     cursorInfo.primaryPosition.x = -glyphMetrics.xBearing + primaryPosition.x + glyphAdvance;
     // Set the primary cursor's position.
     cursorInfo.primaryPosition.x = -glyphMetrics.xBearing + primaryPosition.x + glyphAdvance;
-    cursorInfo.primaryPosition.y = cursorInfo.lineOffset + line.ascender - glyphMetrics.ascender;
+    cursorInfo.primaryPosition.y = cursorInfo.lineOffset + cursorInfo.glyphOffset;
 
     // Transform the cursor info from line's coords to text's coords.
     cursorInfo.primaryPosition.x += line.alignmentOffset;
 
     // Transform the cursor info from line's coords to text's coords.
     cursorInfo.primaryPosition.x += line.alignmentOffset;
index f62165b..34a5f7b 100644 (file)
@@ -50,6 +50,7 @@ struct CursorInfo
   : primaryPosition(),
     secondaryPosition(),
     lineOffset( 0.f ),
   : primaryPosition(),
     secondaryPosition(),
     lineOffset( 0.f ),
+    glyphOffset( 0.f ),
     lineHeight( 0.f ),
     primaryCursorHeight( 0.f ),
     secondaryCursorHeight( 0.f ),
     lineHeight( 0.f ),
     primaryCursorHeight( 0.f ),
     secondaryCursorHeight( 0.f ),
@@ -62,6 +63,7 @@ struct CursorInfo
   Vector2 primaryPosition;       ///< The primary cursor's position (in text's coords).
   Vector2 secondaryPosition;     ///< The secondary cursor's position (in text's coords).
   float   lineOffset;            ///< The vertical offset where the line containing the cursor starts.
   Vector2 primaryPosition;       ///< The primary cursor's position (in text's coords).
   Vector2 secondaryPosition;     ///< The secondary cursor's position (in text's coords).
   float   lineOffset;            ///< The vertical offset where the line containing the cursor starts.
+  float   glyphOffset;           ///< The difference of line ascender and glyph ascender.
   float   lineHeight;            ///< The height of the line where the cursor is placed.
   float   primaryCursorHeight;   ///< The primary cursor's height.
   float   secondaryCursorHeight; ///< The secondary cursor's height.
   float   lineHeight;            ///< The height of the line where the cursor is placed.
   float   primaryCursorHeight;   ///< The primary cursor's height.
   float   secondaryCursorHeight; ///< The secondary cursor's height.
index da49940..e9e0b1a 100644 (file)
@@ -164,7 +164,8 @@ struct Decorator::Impl : public ConnectionTracker
     : color( Dali::Color::BLACK ),
       position(),
       cursorHeight( 0.0f ),
     : color( Dali::Color::BLACK ),
       position(),
       cursorHeight( 0.0f ),
-      lineHeight( 0.0f )
+      lineHeight( 0.0f ),
+      glyphOffset( 0.0f )
     {
     }
 
     {
     }
 
@@ -172,6 +173,7 @@ struct Decorator::Impl : public ConnectionTracker
     Vector2 position;
     float cursorHeight;
     float lineHeight;
     Vector2 position;
     float cursorHeight;
     float lineHeight;
+    float glyphOffset;
   };
 
   struct HandleImpl
   };
 
   struct HandleImpl
@@ -2006,6 +2008,18 @@ const Vector2& Decorator::GetPosition( Cursor cursor ) const
   return mImpl->mCursor[cursor].position;
 }
 
   return mImpl->mCursor[cursor].position;
 }
 
+void Decorator::SetGlyphOffset( Cursor cursor, float glyphOffset )
+{
+  Impl::CursorImpl& cursorImpl = mImpl->mCursor[cursor];
+
+  cursorImpl.glyphOffset = glyphOffset;
+}
+
+const float Decorator::GetGlyphOffset( Cursor cursor) const
+{
+  return mImpl->mCursor[cursor].glyphOffset;
+}
+
 void Decorator::SetCursorColor( Cursor cursor, const Dali::Vector4& color )
 {
   mImpl->mCursor[cursor].color = color;
 void Decorator::SetCursorColor( Cursor cursor, const Dali::Vector4& color )
 {
   mImpl->mCursor[cursor].color = color;
index 6e7c727..8cff322 100644 (file)
@@ -243,6 +243,24 @@ public:
    */
   const Vector2& GetPosition( Cursor cursor ) const;
 
    */
   const Vector2& GetPosition( Cursor cursor ) const;
 
+
+  /**
+   * @brief Sets the glyph offset of a cursor.
+   *
+   * @param[in] cursor The cursor to set.
+   * @param[in] glyphoffset The difference of line ascender and glyph ascender.
+   */
+  void SetGlyphOffset( Cursor cursor, float glyphOffset );
+
+  /**
+   * @brief Retrieves the glyph offset of a cursor.
+   *
+   * @param[in] cursor The cursor to get.
+   *
+   * @return The glyph offset. glyph offset means difference of line ascender and glyph ascender.
+   */
+  const float GetGlyphOffset( Cursor cursor ) const;
+
   /**
    * @brief Sets the color for a cursor.
    *
   /**
    * @brief Sets the color for a cursor.
    *
index f119650..58893d4 100644 (file)
@@ -2695,6 +2695,8 @@ void Controller::Impl::UpdateCursorPosition( const CursorInfo& cursorInfo )
 
   const Vector2 cursorPosition = cursorInfo.primaryPosition + mModel->mScrollPosition;
 
 
   const Vector2 cursorPosition = cursorInfo.primaryPosition + mModel->mScrollPosition;
 
+  mEventData->mDecorator->SetGlyphOffset( PRIMARY_CURSOR, cursorInfo.glyphOffset );
+
   // Sets the cursor position.
   mEventData->mDecorator->SetPosition( PRIMARY_CURSOR,
                                        cursorPosition.x,
   // Sets the cursor position.
   mEventData->mDecorator->SetPosition( PRIMARY_CURSOR,
                                        cursorPosition.x,
@@ -2845,9 +2847,20 @@ void Controller::Impl::ScrollTextToMatchCursor( const CursorInfo& cursorInfo )
   // Get the current cursor position in decorator coords.
   const Vector2& currentCursorPosition = mEventData->mDecorator->GetPosition( PRIMARY_CURSOR );
 
   // Get the current cursor position in decorator coords.
   const Vector2& currentCursorPosition = mEventData->mDecorator->GetPosition( PRIMARY_CURSOR );
 
+  const LineIndex lineIndex = mModel->mVisualModel->GetLineOfCharacter( mEventData->mPrimaryCursorPosition  );
+
+
+
   // Calculate the offset to match the cursor position before the character was deleted.
   mModel->mScrollPosition.x = currentCursorPosition.x - cursorInfo.primaryPosition.x;
   // Calculate the offset to match the cursor position before the character was deleted.
   mModel->mScrollPosition.x = currentCursorPosition.x - cursorInfo.primaryPosition.x;
-  mModel->mScrollPosition.y = currentCursorPosition.y - cursorInfo.lineOffset;
+
+  //If text control has more than two lines and current line index is not last, calculate scrollpositionY
+  if( mModel->mVisualModel->mLines.Count() > 1u && lineIndex != mModel->mVisualModel->mLines.Count() -1u )
+  {
+    const float currentCursorGlyphOffset = mEventData->mDecorator->GetGlyphOffset( PRIMARY_CURSOR );
+    mModel->mScrollPosition.y = currentCursorPosition.y - cursorInfo.lineOffset - currentCursorGlyphOffset;
+  }
+
 
   ClampHorizontalScroll( mModel->mVisualModel->GetLayoutSize() );
   ClampVerticalScroll( mModel->mVisualModel->GetLayoutSize() );
 
   ClampHorizontalScroll( mModel->mVisualModel->GetLayoutSize() );
   ClampVerticalScroll( mModel->mVisualModel->GetLayoutSize() );