Merge "Calculate the visual to logical cursor position conversion table." into new_text
authorPaul Wisbey <p.wisbey@samsung.com>
Thu, 9 Apr 2015 09:54:11 +0000 (02:54 -0700)
committerGerrit Code Review <gerrit@review.vlan103.tizen.org>
Thu, 9 Apr 2015 09:54:11 +0000 (02:54 -0700)
dali-toolkit/internal/text/logical-model-impl.cpp
dali-toolkit/internal/text/logical-model-impl.h

index 80d6595..5a43e35 100644 (file)
@@ -436,6 +436,7 @@ void LogicalModel::SetVisualToLogicalMap( const BidirectionalLineInfoRun* const
   {
     mVisualToLogicalMap.Clear();
     mLogicalToVisualMap.Clear();
+    mVisualToLogicalCursorMap.Clear();
   }
   else
   {
@@ -443,9 +444,14 @@ void LogicalModel::SetVisualToLogicalMap( const BidirectionalLineInfoRun* const
     mVisualToLogicalMap.Resize( numberOfCharacters );
     mLogicalToVisualMap.Resize( numberOfCharacters );
 
+    const Length numberOfCharactersPlus = numberOfCharacters + 1u;
+    mVisualToLogicalCursorMap.Resize( numberOfCharactersPlus );
+
     CharacterIndex* modelVisualToLogicalMapBuffer = mVisualToLogicalMap.Begin();
     CharacterIndex* modelLogicalToVisualMapBuffer = mLogicalToVisualMap.Begin();
 
+    CharacterIndex* modelVisualToLogicalCursorMap = mVisualToLogicalCursorMap.Begin();
+
     CharacterIndex lastIndex = 0u;
     for( unsigned int bidiIndex = 0u; bidiIndex < numberOfRuns; ++bidiIndex )
     {
@@ -480,6 +486,114 @@ void LogicalModel::SetVisualToLogicalMap( const BidirectionalLineInfoRun* const
     {
       *( modelLogicalToVisualMapBuffer + *( modelVisualToLogicalMapBuffer + index ) ) = index;
     }
+
+    // Sets the visual to logical conversion map for cursor positions.
+
+    const Length numberOfBidirectionalParagraphs = mBidirectionalParagraphInfo.Count();
+    BidirectionalParagraphInfoRun* bidirectionalParagraphInfoBuffer = mBidirectionalParagraphInfo.Begin();
+    BidirectionalParagraphInfoRun* bidirectionalParagraph = bidirectionalParagraphInfoBuffer;
+
+    const CharacterDirection* const modelCharacterDirections = mCharacterDirections.Begin();
+
+    Length bidirectionalParagraphIndex = 0u;
+    bool isRightToLeftParagraph = false;
+    for( CharacterIndex index = 0u; index < numberOfCharactersPlus; ++index )
+    {
+      if( bidirectionalParagraph &&
+          ( bidirectionalParagraph->characterRun.characterIndex == index ) )
+      {
+        isRightToLeftParagraph = true;
+      }
+
+      if( 0u == index )
+      {
+        if( isRightToLeftParagraph )
+        {
+          *( modelVisualToLogicalCursorMap + index ) = numberOfCharacters;
+        }
+        else // else logical position is zero.
+        {
+          *( modelVisualToLogicalCursorMap + index ) = 0u;
+        }
+      }
+      else if( numberOfCharacters == index )
+      {
+        if( isRightToLeftParagraph )
+        {
+          *( modelVisualToLogicalCursorMap + index ) = 0u;
+        }
+        else // else logical position is the number of characters.
+        {
+          *( modelVisualToLogicalCursorMap + index ) = numberOfCharacters;
+        }
+      }
+      else
+      {
+        // Get the character indexed by  index - 1 and index
+        // and calculate the logical position according the directions of
+        // both characters and the direction of the paragraph.
+
+        const CharacterIndex previousIndex = index - 1u;
+        const CharacterIndex logicalPosition0 = *( modelVisualToLogicalMapBuffer + previousIndex );
+        const CharacterIndex logicalPosition1 = *( modelVisualToLogicalMapBuffer + index );
+
+        const CharacterDirection direction0 = *( modelCharacterDirections + logicalPosition0 );
+        const CharacterDirection direction1 = *( modelCharacterDirections + logicalPosition1 );
+
+        if( direction0 == direction1 )
+        {
+          // Both glyphs have the same direction.
+          if( direction0 )
+          {
+            *( modelVisualToLogicalCursorMap + index ) = logicalPosition0;
+          }
+          else
+          {
+            *( modelVisualToLogicalCursorMap + index ) = logicalPosition1;
+          }
+        }
+        else
+        {
+          if( isRightToLeftParagraph )
+          {
+            if( direction1 )
+            {
+              *( modelVisualToLogicalCursorMap + index ) = logicalPosition1 + 1u;
+            }
+            else
+            {
+              *( modelVisualToLogicalCursorMap + index ) = logicalPosition0;
+            }
+          }
+          else
+          {
+            if( direction0 )
+            {
+              *( modelVisualToLogicalCursorMap + index ) = logicalPosition1;
+            }
+            else
+            {
+              *( modelVisualToLogicalCursorMap + index ) = logicalPosition0 + 1u;
+            }
+          }
+        }
+      }
+
+      if( bidirectionalParagraph &&
+          ( bidirectionalParagraph->characterRun.characterIndex + bidirectionalParagraph->characterRun.numberOfCharacters == index ) )
+      {
+        isRightToLeftParagraph = false;
+        ++bidirectionalParagraphIndex;
+        if( bidirectionalParagraphIndex < numberOfBidirectionalParagraphs )
+        {
+          bidirectionalParagraph = bidirectionalParagraphInfoBuffer + bidirectionalParagraphIndex;
+        }
+        else
+        {
+          bidirectionalParagraph = NULL;
+        }
+      }
+    }
   }
 }
 
index 6baf44e..73d9230 100644 (file)
@@ -607,6 +607,7 @@ public:
   Vector<BidirectionalLineInfoRun>      mBidirectionalLineInfo;
   Vector<CharacterIndex>                mLogicalToVisualMap;         ///< Bidirectional logical to visual conversion table.
   Vector<CharacterIndex>                mVisualToLogicalMap;         ///< Bidirectional visual to logical conversion table.
+  Vector<CharacterIndex>                mVisualToLogicalCursorMap;   ///< Bidirectional visual to logical cursor conversion table.
 };
 
 } // namespace Text