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()
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,
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
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()
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