Bidi implementation 58/34858/5
authorVictor Cebollada <v.cebollada@samsung.com>
Mon, 19 Jan 2015 17:37:26 +0000 (17:37 +0000)
committerVictor Cebollada <v.cebollada@samsung.com>
Wed, 4 Feb 2015 16:22:32 +0000 (16:22 +0000)
Change-Id: Iff1fa9d196766ba9b969503ecc2fc08b9e64588e
Signed-off-by: Victor Cebollada <v.cebollada@samsung.com>
text/dali/internal/text-abstraction/bidirectional-support-impl.cpp
text/dali/internal/text-abstraction/bidirectional-support-impl.h
text/dali/public-api/text-abstraction/bidirectional-support.h

index b2e4247..bfe67ff 100644 (file)
 // INTERNAL INCLUDES
 #include <singleton-service-impl.h>
 
+// EXTERNAL INCLUDES
+#include <memory.h>
+#include <fribidi/fribidi.h>
+
 namespace Dali
 {
 
@@ -30,15 +34,34 @@ namespace TextAbstraction
 namespace Internal
 {
 
-BidirectionalSupport::BidirectionalSupport()
-: mPlugin( NULL )
+struct BidirectionalSupport::BidirectionalInfo
 {
+  FriBidiCharType* characterTypes;      ///< The type of each character (right, left, neutral, ...)
+  FriBidiLevel*    embeddedLevels;      ///< Embedded levels.
+  FriBidiParType   paragraphDirection;  ///< The paragraph's direction.
+};
 
+BidirectionalSupport::BidirectionalSupport()
+: mPlugin( NULL ),
+  mParagraphBidirectionalInfo(),
+  mFreeIndices()
+{
 }
 
 BidirectionalSupport::~BidirectionalSupport()
 {
+  // free all resources.
+  for( Vector<BidirectionalInfo*>::Iterator it = mParagraphBidirectionalInfo.Begin(),
+         endIt = mParagraphBidirectionalInfo.End();
+       it != endIt;
+       ++it )
+  {
+    BidirectionalInfo* info = *it;
 
+    free( info->embeddedLevels );
+    free( info->characterTypes );
+    delete info;
+  }
 }
 
 TextAbstraction::BidirectionalSupport BidirectionalSupport::Get()
@@ -69,11 +92,67 @@ TextAbstraction::BidirectionalSupport BidirectionalSupport::Get()
 BidiInfoIndex BidirectionalSupport::CreateInfo( const Character* const paragraph,
                                                 Length numberOfCharacters )
 {
-  return 0u;
+  // Reserve memory for the paragraph's bidirectional info.
+  BidirectionalInfo* bidirectionalInfo = new BidirectionalInfo();
+
+  bidirectionalInfo->characterTypes = reinterpret_cast<FriBidiCharType*>( malloc( numberOfCharacters * sizeof( FriBidiCharType ) ) );
+  bidirectionalInfo->embeddedLevels = reinterpret_cast<FriBidiLevel*>( malloc( numberOfCharacters * sizeof( FriBidiLevel ) ) );
+
+  // Retrieve the type of each character..
+  fribidi_get_bidi_types( paragraph, numberOfCharacters, bidirectionalInfo->characterTypes );
+
+  // Retrieve the paragraph's direction.
+  bidirectionalInfo->paragraphDirection = fribidi_get_par_direction( paragraph, numberOfCharacters );
+
+  // Retrieve the embedding levels.
+  fribidi_get_par_embedding_levels( paragraph, numberOfCharacters, &bidirectionalInfo->paragraphDirection, bidirectionalInfo->embeddedLevels );
+
+  // Store the bidirectional info and return the index.
+  BidiInfoIndex index = 0u;
+  const std::size_t numberOfItems = mFreeIndices.Count();
+  if( numberOfItems != 0u )
+  {
+    Vector<BidiInfoIndex>::Iterator it = mFreeIndices.End() - 1u;
+
+    index = *it;
+
+    mFreeIndices.Remove( it );
+
+    *( mParagraphBidirectionalInfo.Begin() + index ) = bidirectionalInfo;
+  }
+  else
+  {
+    index = static_cast<BidiInfoIndex>( numberOfItems );
+
+    mParagraphBidirectionalInfo.PushBack( bidirectionalInfo );
+  }
+
+  return index;
 }
 
 void BidirectionalSupport::DestroyInfo( BidiInfoIndex bidiInfoIndex )
 {
+  if( bidiInfoIndex >= mParagraphBidirectionalInfo.Count() )
+  {
+    return;
+  }
+
+  // Retrieve the paragraph's bidirectional info.
+  Vector<BidirectionalInfo*>::Iterator it = mParagraphBidirectionalInfo.Begin() + bidiInfoIndex;
+  BidirectionalInfo* bidirectionalInfo = *it;
+
+  if( NULL != bidirectionalInfo )
+  {
+    // Free resources and destroy the container.
+    free( bidirectionalInfo->embeddedLevels );
+    free( bidirectionalInfo->characterTypes );
+    delete bidirectionalInfo;
+
+    *it = NULL;
+  }
+
+  // Add the index to the free indices vector.
+  mFreeIndices.PushBack( bidiInfoIndex );
 }
 
 void BidirectionalSupport::Reorder( BidiInfoIndex bidiInfoIndex,
@@ -81,6 +160,34 @@ void BidirectionalSupport::Reorder( BidiInfoIndex bidiInfoIndex,
                                     Length numberOfCharacters,
                                     CharacterIndex* visualToLogicalMap )
 {
+  const FriBidiFlags flags = FRIBIDI_FLAGS_DEFAULT | FRIBIDI_FLAGS_ARABIC;
+
+  // Retrieve the paragraph's bidirectional info.
+  const BidirectionalInfo* const bidirectionalInfo = *( mParagraphBidirectionalInfo.Begin() + bidiInfoIndex );
+
+  // Initialize the visual to logical mapping table to the identity. Otherwise fribidi_reorder_line fails to retrieve a valid mapping table.
+  for( CharacterIndex index = 0u; index < numberOfCharacters; ++index )
+  {
+    visualToLogicalMap[ index ] = index;
+  }
+
+  // Copy embedded levels as fribidi_reorder_line() may change them.
+  const uint32_t embeddedLevelsSize = numberOfCharacters * sizeof( FriBidiLevel );
+  FriBidiLevel* embeddedLevels = reinterpret_cast<FriBidiLevel*>( malloc( embeddedLevelsSize ) );
+  memcpy( embeddedLevels, bidirectionalInfo->embeddedLevels + firstCharacterIndex,  embeddedLevelsSize );
+
+  // Reorder the line.
+  fribidi_reorder_line( flags,
+                        bidirectionalInfo->characterTypes + firstCharacterIndex,
+                        numberOfCharacters,
+                        0u,
+                        bidirectionalInfo->paragraphDirection,
+                        embeddedLevels,
+                        NULL,
+                        reinterpret_cast<FriBidiStrIndex*>( visualToLogicalMap ) );
+
+  // Free resources.
+  free( embeddedLevels );
 }
 
 } // namespace Internal
index d4ff5b3..e207d1d 100644 (file)
@@ -36,7 +36,6 @@ namespace Internal
 /**
  * Implementation of the BidirectionalSupport
  */
-
 class BidirectionalSupport : public Dali::BaseObject
 {
 public:
@@ -85,6 +84,16 @@ private:
 
   void* mPlugin; ///< TODO replace this with bidirectional support plugin
 
+private:
+
+  /**
+   * Stores bidirectional info per paragraph.
+   */
+  struct BidirectionalInfo;
+
+  Vector<BidirectionalInfo*> mParagraphBidirectionalInfo; ///< Stores the bidirectional info per paragraph.
+  Vector<BidiInfoIndex>      mFreeIndices;                ///< Stores indices of free positions in the bidirectional info vector.
+
 }; // class BidirectionalSupport
 
 } // namespace Internal
index c95b698..d05af44 100644 (file)
@@ -37,11 +37,6 @@ class BidirectionalSupport;
 
 } // Internal
 
-} // TextAbstraction
-
-namespace TextAbstraction
-{
-
 /**
  * BidirectionalSupport API
  *