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/split-by-word-policies.h>
22 #include <dali/integration-api/debug.h>
23 #include <dali-toolkit/internal/controls/text-view/relayout-utilities.h>
24 #include <dali-toolkit/internal/controls/text-view/text-view-processor.h>
41 Vector3 OriginalPosition( const TextViewRelayout::RelayoutParameters& relayoutParameters,
42 const TextView::LayoutParameters& layoutParameters,
43 TextView::RelayoutData& relayoutData )
45 const float wordOffset = ( relayoutParameters.mIsFirstCharacter ? 0.f : relayoutParameters.mPositionOffset.x );
46 const float previousPositionY = ( relayoutParameters.mIsFirstCharacter ? 0.f : relayoutParameters.mPositionOffset.y );
48 if( relayoutParameters.mIsNewLine ||
49 relayoutParameters.mIsFirstCharacter ||
50 ( relayoutParameters.mIsFirstCharacterOfWord && ( wordOffset + relayoutParameters.mWordSize.width > relayoutData.mTextViewSize.width ) ) )
52 if( !relayoutParameters.mIsNewLine &&
53 ( relayoutParameters.mIsWhiteSpace || relayoutParameters.mIsNewParagraphCharacter ) )
55 // Current character is a white space. Don't want to move a white space to the next line.
56 // These white spaces are placed just in the edge.
57 return Vector3( relayoutData.mTextViewSize.width - relayoutParameters.mWordSize.width, relayoutParameters.mPositionOffset.y, 0.f );
61 // Calculates the length of the portion of the paragraph which doesn't exceed the text-view's width and the max character height for the current line.
62 TextViewRelayout::LineLayoutInfo subLineInfo;
63 subLineInfo.mLineLength = 0.f;
64 subLineInfo.mMaxCharHeight = 0.f;
65 subLineInfo.mMaxAscender = 0.f;
66 const TextViewProcessor::ParagraphLayoutInfo& paragraphLayoutInfo( *( relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.begin() + relayoutParameters.mIndices.mParagraphIndex ) );
68 TextViewRelayout::CalculateLineLayout( relayoutData.mTextViewSize.width,
69 relayoutParameters.mIndices,
71 TextViewRelayout::WrapByWord,
75 if( subLineInfo.mLineLength < Math::MACHINE_EPSILON_1000 )
77 // It may mean there is a word which is actually longer than the width of the text-view.
78 // In that case the length of this word is needed.
79 if( !paragraphLayoutInfo.mWordsLayoutInfo.empty() )
81 const TextViewProcessor::WordLayoutInfo& wordLayoutInfo( *( paragraphLayoutInfo.mWordsLayoutInfo.begin() + relayoutParameters.mIndices.mWordIndex ) );
82 subLineInfo.mLineLength = wordLayoutInfo.mSize.width;
86 Toolkit::TextView::LineLayoutInfo lineInfo;
87 lineInfo.mCharacterGlobalIndex = relayoutParameters.mCharacterGlobalIndex; // Index to the first character of the next line.
88 lineInfo.mSize = Size( subLineInfo.mLineLength, subLineInfo.mMaxCharHeight ); // Size of this piece of paragraph.
89 lineInfo.mAscender = subLineInfo.mMaxAscender; // Ascender of this piece of paragraph.
90 relayoutData.mLines.push_back( lineInfo );
92 return Vector3( 0.f, previousPositionY + subLineInfo.mMaxCharHeight + layoutParameters.mLineHeightOffset, 0.f );
97 return Vector3( wordOffset, previousPositionY, 0.f );
102 * Calculates character position.
103 * @param[in] relayoutParameters Temporary layout parameters (previous size, previous position, ... )
104 * @param[in] layoutParameters The layout parameters.
105 * @param[in] relayoutData The text-view's data structures.
106 * @return The character's position.
108 Vector3 SplitWhenExceedPosition( const TextViewRelayout::RelayoutParameters& relayoutParameters,
109 const TextView::LayoutParameters& layoutParameters,
110 TextView::RelayoutData& relayoutData )
112 const float wordOffset = ( relayoutParameters.mIsFirstCharacter ? 0.f : relayoutParameters.mPositionOffset.x );
113 const float previousPositionY = ( relayoutParameters.mIsFirstCharacter ? 0.f : relayoutParameters.mPositionOffset.y );
115 if( ( relayoutParameters.mIsNewLine || relayoutParameters.mIsFirstCharacter ) ||
116 ( relayoutParameters.mIsFirstCharacterOfWord && ( wordOffset + relayoutParameters.mWordSize.width > relayoutData.mTextViewSize.width ) ) ||
117 ( wordOffset + relayoutParameters.mCharacterSize.width > relayoutData.mTextViewSize.width ) )
119 if( !relayoutParameters.mIsNewLine &&
120 ( relayoutParameters.mIsWhiteSpace || relayoutParameters.mIsNewParagraphCharacter ) )
122 // Current character is a white space. Don't want to move a white space to the next line.
123 // These white spaces are placed just in the edge.
124 return Vector3( relayoutData.mTextViewSize.width - relayoutParameters.mWordSize.width, relayoutParameters.mPositionOffset.y, 0.f );
128 // Calculates the line length and the max character height for the current line.
129 TextViewRelayout::LineLayoutInfo subLineInfo;
130 subLineInfo.mLineLength = 0.f;
131 subLineInfo.mMaxCharHeight = 0.f;
132 subLineInfo.mMaxAscender = 0.f;
133 const TextViewProcessor::ParagraphLayoutInfo& paragraphLayoutInfo( *( relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.begin() + relayoutParameters.mIndices.mParagraphIndex ) );
135 TextViewRelayout::CalculateLineLayout( relayoutData.mTextViewSize.width,
136 relayoutParameters.mIndices,
138 TextViewRelayout::WrapByWordAndSplit,
139 1.f, // Shrink factor.
142 Toolkit::TextView::LineLayoutInfo lineInfo;
143 lineInfo.mCharacterGlobalIndex = relayoutParameters.mCharacterGlobalIndex; // Index to the first character of the next line.
144 lineInfo.mSize = Size( subLineInfo.mLineLength, subLineInfo.mMaxCharHeight ); // Size of this piece of paragraph.
145 lineInfo.mAscender = subLineInfo.mMaxAscender; // Ascender of this piece of paragraph.
146 relayoutData.mLines.push_back( lineInfo );
148 return Vector3( 0.f, previousPositionY + subLineInfo.mMaxCharHeight + layoutParameters.mLineHeightOffset, 0.f );
153 return Vector3( wordOffset, previousPositionY, 0.f );
158 * Calculates character position.
159 * @param[in] relayoutParameters Temporary layout parameters (previous size, previous position, ... )
160 * @param[in] layoutParameters The layout parameters.
161 * @param[in] relayoutData The text-view's data structures.
162 * @return The character's position.
164 Vector3 ShrinkWidthWhenExceedPosition( const TextViewRelayout::RelayoutParameters& relayoutParameters,
165 const TextView::LayoutParameters& layoutParameters,
166 TextView::RelayoutData& relayoutData )
168 const float wordOffset = ( relayoutParameters.mIsFirstCharacter ? 0.f : relayoutParameters.mPositionOffset.x );
169 const float previousPositionY = ( relayoutParameters.mIsFirstCharacter ? 0.f : relayoutParameters.mPositionOffset.y );
170 const Size wordSize = relayoutParameters.mWordSize * relayoutData.mShrinkFactor;
172 if( ( relayoutParameters.mIsNewLine || relayoutParameters.mIsFirstCharacter ) || // isNewLine is true when '\n' is found.
173 ( relayoutParameters.mIsFirstCharacterOfWord && ( wordOffset + wordSize.width > relayoutData.mTextViewSize.width ) ) ) // The word doesn't fit in the parent width.
175 if( !relayoutParameters.mIsNewLine &&
176 ( relayoutParameters.mIsWhiteSpace || relayoutParameters.mIsNewParagraphCharacter ) )
178 // Current character is a white space. Don't want to move a white space to the next line.
179 // These white spaces are placed just in the edge.
180 return Vector3( relayoutData.mTextViewSize.width - relayoutParameters.mWordSize.width, relayoutParameters.mPositionOffset.y, 0.f );
184 // Calculates the line length and the max character height for the current line.
185 TextViewRelayout::LineLayoutInfo subLineInfo;
186 subLineInfo.mLineLength = 0.f;
187 subLineInfo.mMaxCharHeight = 0.f;
188 subLineInfo.mMaxAscender = 0.f;
189 const TextViewProcessor::ParagraphLayoutInfo& paragraphLayoutInfo( *( relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.begin() + relayoutParameters.mIndices.mParagraphIndex ) );
191 TextViewRelayout::CalculateLineLayout( relayoutData.mTextViewSize.width,
192 relayoutParameters.mIndices,
194 TextViewRelayout::WrapByWord,
195 relayoutData.mShrinkFactor,
198 Toolkit::TextView::LineLayoutInfo lineInfo;
199 lineInfo.mCharacterGlobalIndex = relayoutParameters.mCharacterGlobalIndex; // Index to the first character of the next line.
200 lineInfo.mSize = Size( subLineInfo.mLineLength, subLineInfo.mMaxCharHeight ); // Size of this piece of paragraph.
201 lineInfo.mAscender = subLineInfo.mMaxAscender; // Ascender of this piece of paragraph.
202 relayoutData.mLines.push_back( lineInfo );
204 return Vector3( 0.f, previousPositionY + subLineInfo.mMaxCharHeight + layoutParameters.mLineHeightOffset * relayoutData.mShrinkFactor, 0.f );
209 return Vector3( wordOffset, previousPositionY, 0.f );
213 void CalculatePositionsForShrinkWhenExceed( TextView::RelayoutData& relayoutData,
214 const TextView::LayoutParameters& layoutParameters,
215 const float shrinkFactor,
216 float& newTextHeight )
218 const float parentWidth = relayoutData.mTextViewSize.width;
219 TextViewProcessor::TextLayoutInfo& textLayoutInfo = relayoutData.mTextLayoutInfo;
221 // Reset the text height. This value is returned in order to shrink further or not the text.
224 // Whether the first character is being processed.
225 bool isFirstChar = true;
227 // Stores the size of the previous character.
229 // Stores the position of the previous character.
230 Vector3 previousPosition;
232 // Reset the index of paragraphs.
233 TextViewProcessor::TextInfoIndices indices;
235 // Whether the last character of the whole text is a new paragraph char.
236 // This information is used to increase or not the height of the whole text by one line.
237 // Increase the whole text's height by one line is useful i.e. in TextInput to place the cursor
238 // after pressing 'Enter' in the last paragraph.
239 bool isLastCharacterNewParagraphChar = false;
240 // Stores the height of the last character. This height used to be added to the whole text height if
241 // isLastCharacterNewParagraphChar is true.
242 float lastCharHeight = 0.f;
244 relayoutData.mLines.clear();
245 std::size_t characterGlobalIndex = 0u;
247 for( TextViewProcessor::ParagraphLayoutInfoContainer::iterator paragraphIt = textLayoutInfo.mParagraphsLayoutInfo.begin(), paragraphEndIt = textLayoutInfo.mParagraphsLayoutInfo.end();
248 paragraphIt != paragraphEndIt;
249 ++paragraphIt, ++indices.mParagraphIndex )
251 TextViewProcessor::ParagraphLayoutInfo& paragraphLayoutInfo( *paragraphIt );
253 // The next character is in a new line.
254 bool isNewLine = true;
256 // Reset the index of words.
257 indices.mWordIndex = 0u;
259 for( TextViewProcessor::WordLayoutInfoContainer::iterator wordIt = paragraphLayoutInfo.mWordsLayoutInfo.begin(), wordEndIt = paragraphLayoutInfo.mWordsLayoutInfo.end();
261 ++wordIt, ++indices.mWordIndex )
263 TextViewProcessor::WordLayoutInfo& wordLayoutInfo( *wordIt );
265 // Reset the index of the character.
266 indices.mCharacterIndex = 0u;
268 // Whether current character is the first of the word.
269 bool isFirstCharOfWord = true;
270 const float wordOffset = previousPosition.x + previousSize.width;
272 isLastCharacterNewParagraphChar = ( TextViewProcessor::ParagraphSeparator == wordLayoutInfo.mType );
274 for( TextViewProcessor::CharacterLayoutInfoContainer::iterator charIt = wordLayoutInfo.mCharactersLayoutInfo.begin(), charEndIt = wordLayoutInfo.mCharactersLayoutInfo.end();
276 ++charIt, ++indices.mCharacterIndex )
278 TextViewProcessor::CharacterLayoutInfo& characterLayoutInfo( *charIt );
279 lastCharHeight = characterLayoutInfo.mSize.height * shrinkFactor;
281 const float previousPositionY = isFirstChar ? 0.f : previousPosition.y;
283 if( ( isNewLine || isFirstChar ) ||
284 ( isFirstCharOfWord && ( wordOffset + wordLayoutInfo.mSize.width * shrinkFactor > parentWidth ) ) )
288 // Calculates the line length and the max character height for the current line.
289 TextViewRelayout::LineLayoutInfo subLineInfo;
290 subLineInfo.mLineLength = 0.f;
291 subLineInfo.mMaxCharHeight = 0.f;
292 subLineInfo.mMaxAscender = 0.f;
293 TextViewRelayout::CalculateLineLayout( parentWidth,
296 TextViewRelayout::WrapByWord,
300 characterLayoutInfo.mPosition = Vector3( 0.f, previousPositionY + subLineInfo.mMaxCharHeight + layoutParameters.mLineHeightOffset * shrinkFactor, 0.f );
302 newTextHeight += subLineInfo.mMaxCharHeight + layoutParameters.mLineHeightOffset * shrinkFactor;
304 Toolkit::TextView::LineLayoutInfo lineInfo;
305 lineInfo.mCharacterGlobalIndex = characterGlobalIndex; // Index to the first character of the next line.
306 lineInfo.mSize = Size( subLineInfo.mLineLength, subLineInfo.mMaxCharHeight ); // Size of this piece of paragraph.
307 lineInfo.mAscender = subLineInfo.mMaxAscender; // Ascender of this piece of paragraph.
308 relayoutData.mLines.push_back( lineInfo );
312 characterLayoutInfo.mPosition = previousPosition + Vector3( previousSize.width, 0.f, 0.f );
315 // Get last line info and calculate the bearing.
316 const Toolkit::TextView::LineLayoutInfo& lineInfo( *( relayoutData.mLines.end() - 1u ) );
317 const float bearingOffset = ( ( lineInfo.mSize.height - lineInfo.mAscender ) - ( characterLayoutInfo.mSize.height - characterLayoutInfo.mAscender ) ) * shrinkFactor;
319 previousSize = characterLayoutInfo.mSize * shrinkFactor;
320 previousPosition = characterLayoutInfo.mPosition;
321 characterLayoutInfo.mPosition.y -= bearingOffset;
322 isFirstCharOfWord = false;
325 ++characterGlobalIndex;
330 if( isLastCharacterNewParagraphChar )
332 newTextHeight += lastCharHeight + layoutParameters.mLineHeightOffset * shrinkFactor;
336 float RelayoutForShrinkToFit( TextView::RelayoutData& relayoutData,
337 const TextView::LayoutParameters& layoutParameters )
339 const Size& textViewSize = relayoutData.mTextViewSize;
340 TextViewProcessor::TextLayoutInfo& textLayoutInfo = relayoutData.mTextLayoutInfo;
342 // First step is assure the longest word fits in the text view width.
343 float shrinkFactor = ( textLayoutInfo.mMaxWordWidth > textViewSize.width ? textViewSize.width / textLayoutInfo.mMaxWordWidth : 1.f );
345 // Out parameter. Will store the new text height after relayout the text.
346 float newTextHeight = 0.f;
348 // Relayout the text for the given character's sizes.
349 CalculatePositionsForShrinkWhenExceed( relayoutData,
354 if( newTextHeight > textViewSize.height )
356 // After relayouting, the text exceeds the text view height.
357 // Find a new scale factor to fit all the text in the text view size is needed.
359 // The next algorithm does some iterations to calculate an acceptable scale factor.
360 // Some magic numbers are defined.
362 const float MIN_RATIO( 0.90f ); // The algorithm finishes if the ratio
363 const float MAX_RATIO( 1.00f ); // new_text_height / text_view_height is between this two values
364 const unsigned int MAX_ITERATIONS( 8u ); // or max_iteration is reached.
366 float ratio = newTextHeight / textViewSize.height;
368 float maxScaleFactor = shrinkFactor; // bigger scale factors than maxScaleFactor will produce a too big text.
369 float minScaleFactor = shrinkFactor * ( textViewSize.height / newTextHeight ); // smaller scale factors than minScaleFactor will produce a too small text.
371 for( unsigned int iterations = 0u; ( ( MIN_RATIO > ratio ) || ( ratio > MAX_RATIO ) ) && ( iterations < MAX_ITERATIONS ); ++iterations )
373 // Calculates the new scale factor.
374 // The new scale factor is always between the min and max scale factors.
375 // If ratio < 1 it means the text is too small and a bigger scale factor is needed. In this case the algorithm selects a new scale factor close to
376 // minScaleFactor. Alternatively if the text is too big a new scale factor close to maxScaleFactor is selected.
377 // This allows the text shrink or grow smoothly.
378 shrinkFactor = minScaleFactor + ( ratio < 1.f ? 0.4f : 0.6f ) * ( maxScaleFactor - minScaleFactor );
380 CalculatePositionsForShrinkWhenExceed( relayoutData, // Relayout the text for the given character's sizes.
385 // Calculates the new text size ratio. It allows update the min and max scale factors.
386 // If the ratio is not good enough a new scale factor between min and max could be used in next iteration.
387 ratio = newTextHeight / textViewSize.height;
390 minScaleFactor = shrinkFactor;
394 maxScaleFactor = shrinkFactor;
398 if( ratio > MAX_RATIO )
400 // The algorithm didn't find an acceptable scale factor.
401 // In that case the text is shrunk to fit in the boundaries of the text view actor.
402 shrinkFactor = minScaleFactor;
404 CalculatePositionsForShrinkWhenExceed( relayoutData,
414 void CalculateSizeAndPosition( const TextView::LayoutParameters& layoutParameters,
415 TextView::RelayoutData& relayoutData )
417 TextViewRelayout::RelayoutParameters relayoutParameters;
420 relayoutData.mCharacterLayoutInfoTable.clear();
421 relayoutData.mLines.clear();
422 relayoutData.mTextSizeForRelayoutOption = Size();
424 // Calculates the text size for split by char.
425 Vector4 minMaxXY( std::numeric_limits<float>::max(),
426 std::numeric_limits<float>::max(),
427 std::numeric_limits<float>::min(),
428 std::numeric_limits<float>::min() );
430 relayoutData.mShrinkFactor = 1.f; // Shrink factor used when the exceed policy contains ShrinkToFit
432 if( TextView::Shrink == layoutParameters.mExceedPolicy )
434 // Relays-out the text for the shrink to fit policy.
435 relayoutData.mShrinkFactor = RelayoutForShrinkToFit( relayoutData, layoutParameters );
437 else if( TextView::ShrinkOriginal == layoutParameters.mExceedPolicy )
439 relayoutData.mShrinkFactor = ( relayoutData.mTextLayoutInfo.mMaxWordWidth > relayoutData.mTextViewSize.width ? relayoutData.mTextViewSize.width / relayoutData.mTextLayoutInfo.mMaxWordWidth : 1.f );
442 relayoutParameters.mPositionOffset = Vector3::ZERO;
443 relayoutParameters.mIsFirstCharacter = true;
444 relayoutParameters.mIndices.mParagraphIndex = 0u;
445 relayoutParameters.mCharacterGlobalIndex = 0u;
447 for( TextViewProcessor::ParagraphLayoutInfoContainer::iterator paragraphLayoutIt = relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.begin(),
448 endParagraphLayoutIt = relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.end();
449 paragraphLayoutIt != endParagraphLayoutIt;
450 ++paragraphLayoutIt, ++relayoutParameters.mIndices.mParagraphIndex )
452 TextViewProcessor::ParagraphLayoutInfo& paragraphLayoutInfo( *paragraphLayoutIt );
454 relayoutParameters.mIsNewLine = true;
455 relayoutParameters.mParagraphSize = paragraphLayoutInfo.mSize;
456 relayoutParameters.mIndices.mWordIndex = 0u;
458 for( TextViewProcessor::WordLayoutInfoContainer::iterator wordLayoutIt = paragraphLayoutInfo.mWordsLayoutInfo.begin(),
459 endWordLayoutIt = paragraphLayoutInfo.mWordsLayoutInfo.end();
460 wordLayoutIt != endWordLayoutIt;
461 ++wordLayoutIt, ++relayoutParameters.mIndices.mWordIndex )
463 TextViewProcessor::WordLayoutInfo& wordLayoutInfo( *wordLayoutIt );
464 relayoutParameters.mIsWhiteSpace = TextViewProcessor::WordSeparator == wordLayoutInfo.mType;
465 relayoutParameters.mIsNewParagraphCharacter = TextViewProcessor::ParagraphSeparator == wordLayoutInfo.mType;
467 relayoutParameters.mIsFirstCharacterOfWord = true;
468 relayoutParameters.mWordSize = wordLayoutInfo.mSize;
469 relayoutParameters.mIndices.mCharacterIndex = 0u;
471 for( TextViewProcessor::CharacterLayoutInfoContainer::iterator characterLayoutIt = wordLayoutInfo.mCharactersLayoutInfo.begin(),
472 endCharacterLayoutIt = wordLayoutInfo.mCharactersLayoutInfo.end();
473 ( characterLayoutIt != endCharacterLayoutIt );
474 ++characterLayoutIt, ++relayoutParameters.mIndices.mCharacterIndex )
476 TextViewProcessor::CharacterLayoutInfo& characterLayoutInfo( *characterLayoutIt );
478 relayoutParameters.mCharacterSize = characterLayoutInfo.mSize;
480 switch( layoutParameters.mExceedPolicy )
482 case TextView::OriginalShrink:
483 case TextView::SplitShrink:
484 case TextView::ShrinkFade:
486 DALI_LOG_WARNING( "SplitByWord::CalculateSizeAndPosition() policy not implemented.\n" );
489 case TextView::Original:
490 case TextView::OriginalFade:
491 case TextView::FadeOriginal:
493 case TextView::EllipsizeEndOriginal:
494 case TextView::EllipsizeEnd: // Fall Through
496 characterLayoutInfo.mPosition = OriginalPosition( relayoutParameters,
500 relayoutParameters.mPositionOffset = characterLayoutInfo.mPosition + Vector3( characterLayoutInfo.mSize.width, 0.f, 0.f );
503 case TextView::SplitOriginal:
504 case TextView::SplitFade:
505 case TextView::SplitEllipsizeEnd:
507 characterLayoutInfo.mPosition = SplitWhenExceedPosition( relayoutParameters,
511 relayoutParameters.mPositionOffset = characterLayoutInfo.mPosition + Vector3( characterLayoutInfo.mSize.width, 0.f, 0.f );
514 case TextView::ShrinkOriginal:
516 characterLayoutInfo.mPosition = ShrinkWidthWhenExceedPosition( relayoutParameters,
520 relayoutParameters.mPositionOffset = characterLayoutInfo.mPosition + Vector3( characterLayoutInfo.mSize.width * relayoutData.mShrinkFactor, 0.f, 0.f );
523 case TextView::Shrink:
525 // Does nothing. All the job has been done in the RelayoutForShrinkToFit() function.
530 DALI_LOG_WARNING( "SplitByWord::CalculateSizeAndPosition() policy combination not possible.\n" );
534 // Get last line info and calculate the bearing (used to align glyphs with the baseline).
535 if( TextView::Shrink != layoutParameters.mExceedPolicy )
537 TextViewRelayout::CalculateBearing( characterLayoutInfo, relayoutData );
540 // updates min and max position to calculate the text size for split by word.
541 TextViewRelayout::UpdateLayoutInfoTable( minMaxXY,
547 ++relayoutParameters.mCharacterGlobalIndex;
548 relayoutParameters.mIsFirstCharacter = false;
549 relayoutParameters.mIsFirstCharacterOfWord = false;
550 relayoutParameters.mIsNewLine = false;
555 if( relayoutData.mCharacterLayoutInfoTable.empty() )
557 relayoutData.mTextSizeForRelayoutOption = Size();
561 relayoutData.mTextSizeForRelayoutOption.width = minMaxXY.z - minMaxXY.x;
562 relayoutData.mTextSizeForRelayoutOption.height = minMaxXY.w - minMaxXY.y;
565 // Check if the last character is a new paragraph character. In that case the height should be added.
566 if( !relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.empty() )
568 const TextViewProcessor::ParagraphLayoutInfo& paragraphLayoutInfo( *( relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.end() - 1u ) );
570 if( paragraphLayoutInfo.mWordsLayoutInfo.empty() ) // if it's empty, it means the last character is a new paragraph character.
572 relayoutData.mTextSizeForRelayoutOption.height += paragraphLayoutInfo.mSize.height * relayoutData.mShrinkFactor;
579 void Relayout( Actor textView,
580 TextView::RelayoutOperationMask relayoutOperationMask,
581 const TextView::LayoutParameters& layoutParameters,
582 const TextView::VisualParameters& visualParameters,
583 TextView::RelayoutData& relayoutData )
585 if( relayoutOperationMask & TextView::RELAYOUT_SIZE_POSITION )
587 CalculateSizeAndPosition( layoutParameters,
590 TextViewRelayout::ReorderRightToLeftLayout( relayoutData );
592 TextViewRelayout::SetUnderlineInfo( relayoutData );
595 if( relayoutOperationMask & TextView::RELAYOUT_ALIGNMENT )
597 TextViewRelayout::UpdateAlignment( layoutParameters,
601 if( relayoutOperationMask & TextView::RELAYOUT_VISIBILITY )
603 TextViewRelayout::UpdateVisibility( layoutParameters,
607 const bool initializeTextActors = relayoutOperationMask & TextView::RELAYOUT_INITIALIZE_TEXT_ACTORS;
608 const bool updateTextActors = relayoutOperationMask & TextView::RELAYOUT_TEXT_ACTOR_UPDATE;
609 if( initializeTextActors || updateTextActors )
611 TextViewRelayout::UpdateTextActorInfo( visualParameters,
613 initializeTextActors );
616 if( relayoutOperationMask & TextView::RELAYOUT_INSERT_TO_TEXT_VIEW )
618 TextViewRelayout::InsertToTextView( textView,
623 } // namespace SplitByWord
625 } // namespace Internal
627 } // namespace Toolkit