remove unreachable code in text geometry
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / text / text-geometry.cpp
index 01ba584..3635d0c 100644 (file)
 
 // EXTERNAL INCLUDES
 #include <dali/integration-api/debug.h>
+#include <dali/public-api/math/math-utils.h>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/text/cursor-helper-functions.h>
 #include <dali-toolkit/internal/text/line-run.h>
 #include <dali-toolkit/internal/text/visual-model-impl.h>
+#include <algorithm>
 
 using namespace Dali;
 
@@ -74,7 +76,7 @@ void GetTextGeometry(ModelPtr textModel, CharacterIndex startIndex, CharacterInd
   sizesList.Clear();
   positionsList.Clear();
 
-  if(charactersToGlyphBuffer == nullptr || glyphsPerCharacterBuffer  == nullptr || charactersPerGlyphBuffer  == nullptr || glyphToCharacterBuffer == nullptr )
+  if(charactersToGlyphBuffer == nullptr || glyphsPerCharacterBuffer == nullptr || charactersPerGlyphBuffer == nullptr || glyphToCharacterBuffer == nullptr)
   {
     return;
   }
@@ -244,7 +246,7 @@ void GetTextGeometry(ModelPtr textModel, CharacterIndex startIndex, CharacterInd
       blockPos  = currentPosition;
       blockSize = currentSize;
     }
-    else if((isPrevoiusRightToLeft != isCurrentRightToLeft) || (blockPos.y != currentPosition.y)) //new direction or new line
+    else if((isPrevoiusRightToLeft != isCurrentRightToLeft) || (!Dali::Equals(blockPos.y, currentPosition.y))) //new direction or new line
     {
       sizesList.PushBack(blockSize);
       positionsList.PushBack(blockPos);
@@ -277,19 +279,19 @@ float GetLineLeft(const LineRun& lineRun)
 
 float GetLineTop(const Vector<LineRun>& lines, const LineRun& lineRun)
 {
-  float lineTop = 0;
+  float     lineTop       = 0;
   const int numberOfLines = (int)lines.Count();
 
-  int currentLineIndex = 0;
-  Vector<LineRun>::ConstIterator endIt = (&lineRun);
+  int                            currentLineIndex = 0;
+  Vector<LineRun>::ConstIterator endIt            = (&lineRun);
   for(Vector<LineRun>::Iterator it = lines.Begin();
       it != endIt;
       ++it, ++currentLineIndex)
-    {
-      LineRun& line = *it;
-      bool isLastLine  = (currentLineIndex + 1) == numberOfLines;
-      lineTop         += GetLineHeight(line, isLastLine);
-    }
+  {
+    LineRun& line       = *it;
+    bool     isLastLine = (currentLineIndex + 1) == numberOfLines;
+    lineTop += GetLineHeight(line, isLastLine);
+  }
 
   return lineTop;
 }
@@ -301,7 +303,6 @@ float GetLineWidth(const LineRun& lineRun)
 
 Rect<float> GetLineBoundingRect(ModelPtr textModel, const uint32_t lineIndex)
 {
-
   if(textModel->mVisualModel == nullptr)
   {
     return {0, 0, 0, 0};
@@ -314,10 +315,10 @@ Rect<float> GetLineBoundingRect(ModelPtr textModel, const uint32_t lineIndex)
     return {0, 0, 0, 0};
   }
 
-  const Vector<LineRun>& lines   = textModel->mVisualModel->mLines;
-  const LineRun&         lineRun = lines[lineIndex];
-  bool  isFirstLine = lineIndex == 0;
-  bool  isLastLine  = (lineIndex + 1) == numberOfLines;
+  const Vector<LineRun>& lines       = textModel->mVisualModel->mLines;
+  const LineRun&         lineRun     = lines[lineIndex];
+  bool                   isFirstLine = lineIndex == 0;
+  bool                   isLastLine  = (lineIndex + 1) == numberOfLines;
 
   // Calculate the Left(lineX) = X position.
   float lineX = GetLineLeft(lineRun) + textModel->mScrollPosition.x;
@@ -376,7 +377,7 @@ Rect<> GetCharacterBoundingRect(ModelPtr textModel, const uint32_t charIndex)
   const GlyphIndex glyphIndex = visualModel->mCharactersToGlyph[charIndex]; //took its glyphs
 
   const Vector2&   characterPosition = glyphPositions[glyphIndex];
-  const GlyphInfo& glyphInfo    = glyphs[glyphIndex];
+  const GlyphInfo& glyphInfo         = glyphs[glyphIndex];
 
   // GetLineOfCharacter function returns 0 if the lines are empty
   const int      lineIndex = visualModel->GetLineOfCharacter(charIndex);
@@ -400,6 +401,120 @@ Rect<> GetCharacterBoundingRect(ModelPtr textModel, const uint32_t charIndex)
   return {characterX, characterY, characterWidth, characterHeight};
 }
 
+int GetCharIndexAtPosition(ModelPtr textModel, float visualX, float visualY)
+{
+  if(textModel == nullptr)
+  {
+    return -1;
+  }
+
+  VisualModelPtr& visualModel = textModel->mVisualModel;
+
+  const int totalNumberOfGlyphs = visualModel->mGlyphs.Count();
+  const int totalNumberOfLines  = visualModel->mLines.Count();
+
+  if((0 == totalNumberOfGlyphs) ||
+     (0 == totalNumberOfLines))
+  {
+    return -1;
+  }
+
+  //The top point of the view = 0.
+  if(visualY < 0)
+  {
+    return -1;
+  }
+
+  const Vector<LineRun>& lines = visualModel->mLines;
+
+  float lineTop   = 0.f;
+  int   lineIndex = 0;
+  int   high      = totalNumberOfLines;
+  int   low       = -1;
+  int   guess;
+
+  // Searching for the correct line.
+  while(high - low > 1)
+  {
+    guess = (high + low) / 2;
+    Vector<LineRun>::ConstIterator it = lines.Begin() + guess;
+
+    lineTop = GetLineTop(lines, *it);
+
+    if(lineTop > visualY)
+    {
+      high = guess;
+    }
+    else
+    {
+      low = guess;
+    }
+  }
+
+  if(low < 0)
+  {
+    lineIndex = 0;
+  }
+  else
+  {
+    lineIndex = low;
+  }
+
+  bool isLastLine = lineIndex + 1 == totalNumberOfLines;
+
+  if(isLastLine)
+  {
+    const LineRun& line = *(visualModel->mLines.Begin() + lineIndex);
+    float lineHeight = GetLineHeight(line, isLastLine);
+
+    // If the visualY is placed after the last line.
+    if(visualY > lineTop + lineHeight)
+    {
+      return -1;
+    }
+  }
+
+ // Start searching for the visualX
+  const LineRun& line = *(visualModel->mLines.Begin() + lineIndex);
+
+  visualX -= line.alignmentOffset;
+
+  // Positions of the glyphs
+  const Vector2* const positionsBuffer = visualModel->mGlyphPositions.Begin();
+
+  const CharacterIndex startCharacter = line.characterRun.characterIndex;
+  const CharacterIndex endCharacter   = line.characterRun.characterIndex + line.characterRun.numberOfCharacters - 1;
+
+  CharacterIndex characterIndexAtPosition = -1;
+  CharacterIndex characterIndex           = startCharacter;
+  float characterPosition;
+  float rightMostCharacterPosition;
+
+  for(; characterIndex != endCharacter; characterIndex++)
+  {
+    characterPosition = positionsBuffer[characterIndex].x;
+    rightMostCharacterPosition = positionsBuffer[characterIndex+1].x;
+
+    if(visualX < rightMostCharacterPosition && visualX >= characterPosition)
+    {
+      characterIndexAtPosition = characterIndex;
+      break;
+    }
+  }
+
+  if(characterIndex == endCharacter)
+  {
+    // If the visualX is within the last character position or it comes after the last character; we return the last character.
+    rightMostCharacterPosition = positionsBuffer[endCharacter].x + GetCharacterWidth(visualModel->mGlyphs[endCharacter]);
+
+    if(visualX >= positionsBuffer[endCharacter].x && visualX < rightMostCharacterPosition)
+    {
+      characterIndexAtPosition = endCharacter;
+    }
+  }
+
+  return characterIndexAtPosition;
+}
 } // namespace Text
 
 } // namespace Toolkit