2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali-toolkit/internal/controls/text-view/text-processor-bidirectional-info.h>
30 namespace TextProcessor
33 BidirectionalParagraphInfo::BidirectionalParagraphInfo()
34 : mDirection( FRIBIDI_TYPE_ON ),
35 mCharactersTypeBuffer(),
37 mLogicalUnicodeBuffer()
41 BidirectionalParagraphInfo::~BidirectionalParagraphInfo()
45 BidirectionalParagraphInfo::BidirectionalParagraphInfo( const BidirectionalParagraphInfo& info )
46 : mDirection( info.mDirection ),
47 mCharactersTypeBuffer( info.mCharactersTypeBuffer ),
48 mLevelsBuffer( info.mLevelsBuffer ),
49 mLogicalUnicodeBuffer( info.mLogicalUnicodeBuffer )
53 BidirectionalParagraphInfo& BidirectionalParagraphInfo::operator=( const BidirectionalParagraphInfo& info )
57 mDirection = info.mDirection;
58 mCharactersTypeBuffer = info.mCharactersTypeBuffer;
59 mLevelsBuffer = info.mLevelsBuffer;
60 mLogicalUnicodeBuffer = info.mLogicalUnicodeBuffer;
66 BidirectionalLineInfo::BidirectionalLineInfo()
67 : mCharacterParagraphIndex(),
68 mNumberOfCharacters(),
70 mVisualToLogicalMap(),
75 BidirectionalLineInfo::~BidirectionalLineInfo()
79 BidirectionalLineInfo::BidirectionalLineInfo( const BidirectionalLineInfo& info )
80 : mCharacterParagraphIndex( info.mCharacterParagraphIndex ),
81 mNumberOfCharacters( info.mNumberOfCharacters ),
83 mVisualToLogicalMap( info.mVisualToLogicalMap ),
84 mLogicalToVisualMap( info.mLogicalToVisualMap )
88 BidirectionalLineInfo& BidirectionalLineInfo::operator=( const BidirectionalLineInfo& info )
92 mCharacterParagraphIndex = info.mCharacterParagraphIndex;
93 mNumberOfCharacters = info.mNumberOfCharacters;
95 mVisualToLogicalMap = info.mVisualToLogicalMap;
96 mLogicalToVisualMap = info.mLogicalToVisualMap;
102 bool BeginsRightToLeftCharacter( const Text& text )
104 for( size_t i = 0u, length = text.GetLength(); i < length; ++i )
106 Character::CharacterDirection direction = text[i].GetCharacterDirection();
107 if( direction != Character::Neutral )
109 return ( direction == Character::RightToLeft || direction == Character::RightToLeftWeak );
116 bool ContainsRightToLeftCharacter( const Dali::Text& text )
118 for( size_t i = 0u, length = text.GetLength(); i < length; ++i )
120 Character::CharacterDirection direction = ( text[i] ).GetCharacterDirection();
121 if( ( Character::RightToLeft == direction ) || ( Character::RightToLeftWeak == direction ) )
130 void ProcessBidirectionalText( Text& paragraph, BidirectionalParagraphInfo* info )
132 if( paragraph.IsEmpty() )
134 // nothing to do if the paragraph is empty.
138 const std::size_t stringSize = paragraph.GetText().size();
140 // Text buffer in logical order. Coded in unicode.
141 info->mLogicalUnicodeBuffer.resize( stringSize + 1u, 0u );
142 FriBidiChar* logicalUnicodeBufferPointer = &info->mLogicalUnicodeBuffer[0u];
144 // Converts from utf8 to unicode.
145 const std::size_t length = fribidi_charset_to_unicode( FRIBIDI_CHAR_SET_UTF8, paragraph.GetText().c_str(), stringSize, logicalUnicodeBufferPointer );
147 // Character type buffer.
148 info->mCharactersTypeBuffer.resize( length, 0u );
151 info->mLevelsBuffer.resize( length, 0u );
153 // Joining type buffer.
154 std::vector<FriBidiJoiningType> joiningTypeBuffer;
155 joiningTypeBuffer.resize( length, 0u );
157 // Pointers to the buffers.
158 FriBidiCharType* charactersTypeBufferPointer = &info->mCharactersTypeBuffer[0u];
159 FriBidiLevel* levelsBufferPointer = &info->mLevelsBuffer[0u];
160 FriBidiJoiningType* joiningTypeBufferPointer = &joiningTypeBuffer[0u];
162 // Retrieves the type of each character.
163 fribidi_get_bidi_types( logicalUnicodeBufferPointer, length, charactersTypeBufferPointer );
165 // Retrieves the paragraph direction.
166 info->mDirection = fribidi_get_par_direction( charactersTypeBufferPointer, length );
168 // Retrieve the embedding levels.
169 fribidi_get_par_embedding_levels( charactersTypeBufferPointer, length, &info->mDirection, levelsBufferPointer );
171 // Retrieve the joining types.
172 fribidi_get_joining_types( logicalUnicodeBufferPointer, length, joiningTypeBufferPointer );
174 fribidi_join_arabic( charactersTypeBufferPointer, length, levelsBufferPointer, joiningTypeBufferPointer );
176 const FriBidiFlags flags = FRIBIDI_FLAGS_DEFAULT | FRIBIDI_FLAGS_ARABIC;
178 fribidi_shape( flags, levelsBufferPointer, length, joiningTypeBufferPointer, logicalUnicodeBufferPointer );
180 std::vector<char> bidiTextConverted;
182 bidiTextConverted.resize( length * 4u + 1u ); // Maximum bytes to represent one UTF-8 character is 6.
183 // Currently Dali doesn't support this UTF-8 extension. Dali only supports 'regular' UTF-8 which has a maximum of 4 bytes per character.
185 fribidi_unicode_to_charset( FRIBIDI_CHAR_SET_UTF8, logicalUnicodeBufferPointer, length, &bidiTextConverted[0] );
187 paragraph = Text( &bidiTextConverted[0u] );
190 void ReorderLine( BidirectionalParagraphInfo* paragraphInfo,
191 BidirectionalLineInfo* lineInfo )
193 const FriBidiFlags flags = FRIBIDI_FLAGS_DEFAULT | FRIBIDI_FLAGS_ARABIC;
195 lineInfo->mVisualToLogicalMap.Resize( lineInfo->mNumberOfCharacters, 0u );
196 lineInfo->mLogicalToVisualMap.Resize( lineInfo->mNumberOfCharacters, 0u );
198 std::vector<FriBidiChar> visualUnicodeBuffer;
199 visualUnicodeBuffer.insert( visualUnicodeBuffer.end(),
200 paragraphInfo->mLogicalUnicodeBuffer.begin() + lineInfo->mCharacterParagraphIndex,
201 paragraphInfo->mLogicalUnicodeBuffer.begin() + ( lineInfo->mCharacterParagraphIndex + lineInfo->mNumberOfCharacters ) );
203 // Pointers to the buffers.
204 FriBidiCharType* charactersTypeBufferPointer = ¶graphInfo->mCharactersTypeBuffer[lineInfo->mCharacterParagraphIndex];
205 FriBidiLevel* levelsBufferPointer = ¶graphInfo->mLevelsBuffer[lineInfo->mCharacterParagraphIndex];
206 FriBidiChar* visualUnicodeBufferPointer = &visualUnicodeBuffer[0u];
207 FriBidiStrIndex* visualToLogicalMapPointer = &lineInfo->mVisualToLogicalMap[0u];
209 // Initialize the visual to logical mapping table to the identity. Otherwise fribidi_reorder_line fails to retrieve a valid mapping table.
210 for( std::size_t index = 0u; index < lineInfo->mNumberOfCharacters; ++index )
212 lineInfo->mVisualToLogicalMap[ index ] = index;
215 fribidi_reorder_line( flags,
216 charactersTypeBufferPointer,
217 lineInfo->mNumberOfCharacters,
219 paragraphInfo->mDirection,
221 visualUnicodeBufferPointer,
222 visualToLogicalMapPointer );
224 // Fill the logical to visual mapping table.
225 for( std::size_t index = 0u; index < lineInfo->mNumberOfCharacters; ++index )
227 lineInfo->mLogicalToVisualMap[ lineInfo->mVisualToLogicalMap[ index ] ] = index;
230 std::vector<char> bidiTextConverted;
232 bidiTextConverted.resize( lineInfo->mNumberOfCharacters * 4u + 1u ); // Maximum bytes to represent one UTF-8 character is 6.
233 // Currently Dali doesn't support this UTF-8 extension.
234 // Dali only supports 'regular' UTF-8 which has a maximum of 4 bytes per character.
236 fribidi_unicode_to_charset( FRIBIDI_CHAR_SET_UTF8, visualUnicodeBufferPointer, lineInfo->mNumberOfCharacters, &bidiTextConverted[0u] );
238 lineInfo->mText = Text( &bidiTextConverted[0u] );
241 } // namespace TextProcessor
243 } // namespace Internal
245 } // namespace Toolkit