Use the Plugin architecture for the text segmentation and bidirectional support. 32/35132/3
authorVictor Cebollada <v.cebollada@samsung.com>
Mon, 9 Feb 2015 14:17:49 +0000 (14:17 +0000)
committerPaul Wisbey <p.wisbey@samsung.com>
Thu, 12 Feb 2015 10:04:22 +0000 (02:04 -0800)
Change-Id: Ib9c0b862d9a53c6ca04e8223d5386f47b081909e
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/internal/text-abstraction/segmentation-impl.cpp
text/dali/internal/text-abstraction/segmentation-impl.h

index bfe67ff..0356715 100644 (file)
@@ -34,34 +34,152 @@ namespace TextAbstraction
 namespace Internal
 {
 
-struct BidirectionalSupport::BidirectionalInfo
+struct BidirectionalSupport::Plugin
 {
-  FriBidiCharType* characterTypes;      ///< The type of each character (right, left, neutral, ...)
-  FriBidiLevel*    embeddedLevels;      ///< Embedded levels.
-  FriBidiParType   paragraphDirection;  ///< The paragraph's direction.
+  /**
+   * Stores bidirectional info per paragraph.
+   */
+  struct BidirectionalInfo
+  {
+    FriBidiCharType* characterTypes;      ///< The type of each character (right, left, neutral, ...)
+    FriBidiLevel*    embeddedLevels;      ///< Embedded levels.
+    FriBidiParType   paragraphDirection;  ///< The paragraph's direction.
+  };
+
+  Plugin()
+  : mParagraphBidirectionalInfo(),
+    mFreeIndices()
+  {}
+
+  ~Plugin()
+  {
+    // 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;
+    }
+  }
+
+  BidiInfoIndex CreateInfo( const Character* const paragraph,
+                            Length numberOfCharacters )
+  {
+    // 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 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 Reorder( BidiInfoIndex bidiInfoIndex,
+                CharacterIndex firstCharacterIndex,
+                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 );
+  }
+
+  Vector<BidirectionalInfo*> mParagraphBidirectionalInfo; ///< Stores the bidirectional info per paragraph.
+  Vector<BidiInfoIndex>      mFreeIndices;                ///< Stores indices of free positions in the bidirectional info vector.
 };
 
 BidirectionalSupport::BidirectionalSupport()
-: mPlugin( NULL ),
-  mParagraphBidirectionalInfo(),
-  mFreeIndices()
+: mPlugin( NULL )
 {
 }
 
 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;
-  }
+  delete mPlugin;
 }
 
 TextAbstraction::BidirectionalSupport BidirectionalSupport::Get()
@@ -92,67 +210,17 @@ TextAbstraction::BidirectionalSupport BidirectionalSupport::Get()
 BidiInfoIndex BidirectionalSupport::CreateInfo( const Character* const paragraph,
                                                 Length numberOfCharacters )
 {
-  // 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;
+  CreatePlugin();
 
-    index = *it;
-
-    mFreeIndices.Remove( it );
-
-    *( mParagraphBidirectionalInfo.Begin() + index ) = bidirectionalInfo;
-  }
-  else
-  {
-    index = static_cast<BidiInfoIndex>( numberOfItems );
-
-    mParagraphBidirectionalInfo.PushBack( bidirectionalInfo );
-  }
-
-  return index;
+  return mPlugin->CreateInfo( paragraph,
+                              numberOfCharacters );
 }
 
 void BidirectionalSupport::DestroyInfo( BidiInfoIndex bidiInfoIndex )
 {
-  if( bidiInfoIndex >= mParagraphBidirectionalInfo.Count() )
-  {
-    return;
-  }
+  CreatePlugin();
 
-  // 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 );
+  mPlugin->DestroyInfo( bidiInfoIndex );
 }
 
 void BidirectionalSupport::Reorder( BidiInfoIndex bidiInfoIndex,
@@ -160,34 +228,20 @@ void BidirectionalSupport::Reorder( BidiInfoIndex bidiInfoIndex,
                                     Length numberOfCharacters,
                                     CharacterIndex* visualToLogicalMap )
 {
-  const FriBidiFlags flags = FRIBIDI_FLAGS_DEFAULT | FRIBIDI_FLAGS_ARABIC;
+  CreatePlugin();
 
-  // Retrieve the paragraph's bidirectional info.
-  const BidirectionalInfo* const bidirectionalInfo = *( mParagraphBidirectionalInfo.Begin() + bidiInfoIndex );
+  mPlugin->Reorder( bidiInfoIndex,
+                    firstCharacterIndex,
+                    numberOfCharacters,
+                    visualToLogicalMap );
+}
 
-  // 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 )
+void BidirectionalSupport::CreatePlugin()
+{
+  if( !mPlugin )
   {
-    visualToLogicalMap[ index ] = index;
+    mPlugin = new Plugin();
   }
-
-  // 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 1d1694a..33b1984 100644 (file)
@@ -77,23 +77,23 @@ public:
 
 private:
 
+  /**
+   * Helper for lazy initialization.
+   */
+  void CreatePlugin();
+
+private:
+
   // Undefined copy constructor.
   BidirectionalSupport( const BidirectionalSupport& );
 
   // Undefined assignment constructor.
   BidirectionalSupport& operator=( BidirectionalSupport& );
 
-  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.
+  struct Plugin;
+  Plugin* mPlugin;
 
 }; // class BidirectionalSupport
 
index aca86d5..a517a42 100644 (file)
@@ -34,15 +34,30 @@ namespace TextAbstraction
 namespace Internal
 {
 
-Segmentation::Segmentation()
-: mPlugin( NULL )
+struct Segmentation::Plugin
 {
+  void GetLineBreakPositions( const Character* const text,
+                              Length numberOfCharacters,
+                              LineBreakInfo* breakInfo )
+  {
+    set_linebreaks_utf32( text, numberOfCharacters, NULL, breakInfo );
+  }
 
-}
+  void GetWordBreakPositions( const Character* const text,
+                              Length numberOfCharacters,
+                              WordBreakInfo* breakInfo )
+  {
+    set_wordbreaks_utf32( text, numberOfCharacters, NULL, breakInfo );
+  }
+};
+
+Segmentation::Segmentation()
+: mPlugin( NULL )
+{}
 
 Segmentation::~Segmentation()
 {
-
+  delete mPlugin;
 }
 
 TextAbstraction::Segmentation Segmentation::Get()
@@ -74,14 +89,26 @@ void Segmentation::GetLineBreakPositions( const Character* const text,
                                           Length numberOfCharacters,
                                           LineBreakInfo* breakInfo )
 {
-  set_linebreaks_utf32( text, numberOfCharacters, NULL, breakInfo );
+  CreatePlugin();
+
+  mPlugin->GetLineBreakPositions( text, numberOfCharacters, breakInfo );
 }
 
 void Segmentation::GetWordBreakPositions( const Character* const text,
                                           Length numberOfCharacters,
                                           WordBreakInfo* breakInfo )
 {
-  set_wordbreaks_utf32( text, numberOfCharacters, NULL, breakInfo );
+  CreatePlugin();
+
+  mPlugin->GetWordBreakPositions( text, numberOfCharacters, breakInfo );
+}
+
+void Segmentation::CreatePlugin()
+{
+  if( !mPlugin )
+  {
+    mPlugin = new Plugin();
+  }
 }
 
 } // namespace Internal
index 143978b..ca2dc7d 100644 (file)
@@ -73,13 +73,23 @@ public:
 
 private:
 
+  /**
+   * Helper for lazy initialization.
+   */
+  void CreatePlugin();
+
+private:
+
   // Undefined copy constructor.
   Segmentation( const Segmentation& );
 
   // Undefined assignment constructor.
   Segmentation& operator=( Segmentation& );
 
-  void* mPlugin; ///< TODO replace this with segmentation plugin
+private:
+
+  struct Plugin;
+  Plugin* mPlugin;
 
 }; // class Segmentation