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.mIsNewLineCharacter ) )
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 line which doesn't exceed the text-view's width and the max character height for the current line.
62 TextViewRelayout::SubLineLayoutInfo subLineInfo;
63 subLineInfo.mLineLength = 0.f;
64 subLineInfo.mMaxCharHeight = 0.f;
65 subLineInfo.mMaxAscender = 0.f;
66 const TextViewProcessor::LineLayoutInfo& lineLayoutInfo( *( relayoutData.mTextLayoutInfo.mLinesLayoutInfo.begin() + relayoutParameters.mIndices.mLineIndex ) );
68 TextViewRelayout::CalculateSubLineLayout( 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( !lineLayoutInfo.mWordGroupsLayoutInfo.empty() )
81 const TextViewProcessor::WordGroupLayoutInfo& wordGroupLayoutInfo( *( lineLayoutInfo.mWordGroupsLayoutInfo.begin() + relayoutParameters.mIndices.mGroupIndex ) );
82 if( !wordGroupLayoutInfo.mWordsLayoutInfo.empty() )
84 const TextViewProcessor::WordLayoutInfo& wordLayoutInfo( *( wordGroupLayoutInfo.mWordsLayoutInfo.begin() + relayoutParameters.mIndices.mWordIndex ) );
85 subLineInfo.mLineLength = wordLayoutInfo.mSize.width;
90 // Stores some info to calculate the line justification in a post-process.
91 TextView::LineJustificationInfo justificationInfo;
93 justificationInfo.mIndices = relayoutParameters.mIndices;
94 justificationInfo.mLineLength = subLineInfo.mLineLength;
96 relayoutData.mLineJustificationInfo.push_back( justificationInfo );
98 Toolkit::TextView::LineLayoutInfo lineInfo;
99 lineInfo.mCharacterGlobalIndex = relayoutParameters.mCharacterGlobalIndex; // Index to the first character of the next line.
100 lineInfo.mSize = Size( subLineInfo.mLineLength, subLineInfo.mMaxCharHeight ); // Size of this piece of line.
101 lineInfo.mAscender = subLineInfo.mMaxAscender; // Ascender of this piece of line.
102 relayoutData.mLines.push_back( lineInfo );
104 return Vector3( 0.f, previousPositionY + subLineInfo.mMaxCharHeight + layoutParameters.mLineHeightOffset, 0.f );
109 return Vector3( wordOffset, previousPositionY, 0.f );
114 * Calculates character position.
115 * @param[in] relayoutParameters Temporary layout parameters (previous size, previous position, ... )
116 * @param[in] layoutParameters The layout parameters.
117 * @param[in] relayoutData The text-view's data structures.
118 * @return The character's position.
120 Vector3 SplitWhenExceedPosition( const TextViewRelayout::RelayoutParameters& relayoutParameters,
121 const TextView::LayoutParameters& layoutParameters,
122 TextView::RelayoutData& relayoutData )
124 const float wordOffset = ( relayoutParameters.mIsFirstCharacter ? 0.f : relayoutParameters.mPositionOffset.x );
125 const float previousPositionY = ( relayoutParameters.mIsFirstCharacter ? 0.f : relayoutParameters.mPositionOffset.y );
127 if( ( relayoutParameters.mIsNewLine || relayoutParameters.mIsFirstCharacter ) ||
128 ( relayoutParameters.mIsFirstCharacterOfWord && ( wordOffset + relayoutParameters.mWordSize.width > relayoutData.mTextViewSize.width ) ) ||
129 ( wordOffset + relayoutParameters.mCharacterSize.width > relayoutData.mTextViewSize.width ) )
131 if( !relayoutParameters.mIsNewLine &&
132 ( relayoutParameters.mIsWhiteSpace || relayoutParameters.mIsNewLineCharacter ) )
134 // Current character is a white space. Don't want to move a white space to the next line.
135 // These white spaces are placed just in the edge.
136 return Vector3( relayoutData.mTextViewSize.width - relayoutParameters.mWordSize.width, relayoutParameters.mPositionOffset.y, 0.f );
140 // Calculates the line length and the max character height for the current line.
141 TextViewRelayout::SubLineLayoutInfo subLineInfo;
142 subLineInfo.mLineLength = 0.f;
143 subLineInfo.mMaxCharHeight = 0.f;
144 subLineInfo.mMaxAscender = 0.f;
145 const TextViewProcessor::LineLayoutInfo& lineLayoutInfo( *( relayoutData.mTextLayoutInfo.mLinesLayoutInfo.begin() + relayoutParameters.mIndices.mLineIndex ) );
147 TextViewRelayout::CalculateSubLineLayout( relayoutData.mTextViewSize.width,
148 relayoutParameters.mIndices,
150 TextViewRelayout::WrapByWordAndSplit,
151 1.f, // Shrink factor.
154 // Stores some info to calculate the line justification in a post-process.
155 TextView::LineJustificationInfo justificationInfo;
157 justificationInfo.mIndices = relayoutParameters.mIndices;
158 justificationInfo.mLineLength = subLineInfo.mLineLength;
160 relayoutData.mLineJustificationInfo.push_back( justificationInfo );
162 Toolkit::TextView::LineLayoutInfo lineInfo;
163 lineInfo.mCharacterGlobalIndex = relayoutParameters.mCharacterGlobalIndex; // Index to the first character of the next line.
164 lineInfo.mSize = Size( subLineInfo.mLineLength, subLineInfo.mMaxCharHeight ); // Size of this piece of line.
165 lineInfo.mAscender = subLineInfo.mMaxAscender; // Ascender of this piece of line.
166 relayoutData.mLines.push_back( lineInfo );
168 return Vector3( 0.f, previousPositionY + subLineInfo.mMaxCharHeight + layoutParameters.mLineHeightOffset, 0.f );
173 return Vector3( wordOffset, previousPositionY, 0.f );
178 * Calculates character position.
179 * @param[in] relayoutParameters Temporary layout parameters (previous size, previous position, ... )
180 * @param[in] layoutParameters The layout parameters.
181 * @param[in] relayoutData The text-view's data structures.
182 * @return The character's position.
184 Vector3 ShrinkWidthWhenExceedPosition( const TextViewRelayout::RelayoutParameters& relayoutParameters,
185 const TextView::LayoutParameters& layoutParameters,
186 TextView::RelayoutData& relayoutData )
188 const float wordOffset = ( relayoutParameters.mIsFirstCharacter ? 0.f : relayoutParameters.mPositionOffset.x );
189 const float previousPositionY = ( relayoutParameters.mIsFirstCharacter ? 0.f : relayoutParameters.mPositionOffset.y );
190 const Size wordSize = relayoutParameters.mWordSize * relayoutData.mShrinkFactor;
192 if( ( relayoutParameters.mIsNewLine || relayoutParameters.mIsFirstCharacter ) || // isNewLine is true when '\n' is found.
193 ( relayoutParameters.mIsFirstCharacterOfWord && ( wordOffset + wordSize.width > relayoutData.mTextViewSize.width ) ) ) // The word doesn't fit in the parent width.
195 if( !relayoutParameters.mIsNewLine &&
196 ( relayoutParameters.mIsWhiteSpace || relayoutParameters.mIsNewLineCharacter ) )
198 // Current character is a white space. Don't want to move a white space to the next line.
199 // These white spaces are placed just in the edge.
200 return Vector3( relayoutData.mTextViewSize.width - relayoutParameters.mWordSize.width, relayoutParameters.mPositionOffset.y, 0.f );
204 // Calculates the line length and the max character height for the current line.
205 TextViewRelayout::SubLineLayoutInfo subLineInfo;
206 subLineInfo.mLineLength = 0.f;
207 subLineInfo.mMaxCharHeight = 0.f;
208 subLineInfo.mMaxAscender = 0.f;
209 const TextViewProcessor::LineLayoutInfo& lineLayoutInfo( *( relayoutData.mTextLayoutInfo.mLinesLayoutInfo.begin() + relayoutParameters.mIndices.mLineIndex ) );
211 TextViewRelayout::CalculateSubLineLayout( relayoutData.mTextViewSize.width,
212 relayoutParameters.mIndices,
214 TextViewRelayout::WrapByWord,
215 relayoutData.mShrinkFactor,
218 // Stores some info to calculate the line justification in a post-process.
219 TextView::LineJustificationInfo justificationInfo;
221 justificationInfo.mIndices = relayoutParameters.mIndices;
222 justificationInfo.mLineLength = subLineInfo.mLineLength;
224 relayoutData.mLineJustificationInfo.push_back( justificationInfo );
226 Toolkit::TextView::LineLayoutInfo lineInfo;
227 lineInfo.mCharacterGlobalIndex = relayoutParameters.mCharacterGlobalIndex; // Index to the first character of the next line.
228 lineInfo.mSize = Size( subLineInfo.mLineLength, subLineInfo.mMaxCharHeight ); // Size of this piece of line.
229 lineInfo.mAscender = subLineInfo.mMaxAscender; // Ascender of this piece of line.
230 relayoutData.mLines.push_back( lineInfo );
232 return Vector3( 0.f, previousPositionY + subLineInfo.mMaxCharHeight + layoutParameters.mLineHeightOffset * relayoutData.mShrinkFactor, 0.f );
237 return Vector3( wordOffset, previousPositionY, 0.f );
241 void CalculatePositionsForShrinkWhenExceed( TextView::RelayoutData& relayoutData,
242 const TextView::LayoutParameters& layoutParameters,
243 const float shrinkFactor,
244 float& newTextHeight )
246 const float parentWidth = relayoutData.mTextViewSize.width;
247 TextViewProcessor::TextLayoutInfo& textLayoutInfo = relayoutData.mTextLayoutInfo;
249 relayoutData.mLineJustificationInfo.clear();
251 // Reset the text height. This value is returned in order to shrink further or not the text.
254 // Whether the first character is being processed.
255 bool isFirstChar = true;
257 // Stores the size of the previous character.
259 // Stores the position of the previous character.
260 Vector3 previousPosition;
262 // Reset the index of lines.
263 TextViewProcessor::TextInfoIndices indices;
265 // Whether the last character of the whole text is a new line char.
266 // This information is used to increase or not the height of the whole text by one line.
267 // Increase the whole text's height by one line is useful i.e. in TextInput to place the cursor
268 // after pressing 'Enter' in the last line.
269 bool isLastCharacterNewLineChar = false;
270 // Stores the height of the last character. This height used to be added to the whole text height if
271 // isLastCharacterNewLineChar is true.
272 float lastCharHeight = 0.f;
274 relayoutData.mLines.clear();
275 std::size_t characterGlobalIndex = 0;
277 for( TextViewProcessor::LineLayoutInfoContainer::iterator lineIt = textLayoutInfo.mLinesLayoutInfo.begin(), lineEndIt = textLayoutInfo.mLinesLayoutInfo.end();
279 ++lineIt, ++indices.mLineIndex )
281 TextViewProcessor::LineLayoutInfo& lineLayoutInfo( *lineIt );
283 // The next character is in a new line.
284 bool isNewLine = true;
286 // Reset the index of groups of words.
287 indices.mGroupIndex = 0;
289 for( TextViewProcessor::WordGroupLayoutInfoContainer::iterator groupIt = lineLayoutInfo.mWordGroupsLayoutInfo.begin(), groupEndIt = lineLayoutInfo.mWordGroupsLayoutInfo.end();
290 groupIt != groupEndIt;
291 ++groupIt, ++indices.mGroupIndex )
293 TextViewProcessor::WordGroupLayoutInfo& wordGroupLayoutInfo( *groupIt );
295 // Reset the index of words.
296 indices.mWordIndex = 0;
298 for( TextViewProcessor::WordLayoutInfoContainer::iterator wordIt = wordGroupLayoutInfo.mWordsLayoutInfo.begin(), wordEndIt = wordGroupLayoutInfo.mWordsLayoutInfo.end();
300 ++wordIt, ++indices.mWordIndex )
302 TextViewProcessor::WordLayoutInfo& wordLayoutInfo( *wordIt );
304 // Reset the index of the character.
305 indices.mCharacterIndex = 0;
307 // Whether current character is the first of the word.
308 bool isFirstCharOfWord = true;
309 const float wordOffset = previousPosition.x + previousSize.width;
311 isLastCharacterNewLineChar = ( TextViewProcessor::LineSeparator == wordLayoutInfo.mType );
313 for( TextViewProcessor::CharacterLayoutInfoContainer::iterator charIt = wordLayoutInfo.mCharactersLayoutInfo.begin(), charEndIt = wordLayoutInfo.mCharactersLayoutInfo.end();
315 ++charIt, ++indices.mCharacterIndex )
317 TextViewProcessor::CharacterLayoutInfo& characterLayoutInfo( *charIt );
318 lastCharHeight = characterLayoutInfo.mSize.height * shrinkFactor;
320 const float previousPositionY = isFirstChar ? 0.f : previousPosition.y;
322 if( ( isNewLine || isFirstChar ) ||
323 ( isFirstCharOfWord && ( wordOffset + wordLayoutInfo.mSize.width * shrinkFactor > parentWidth ) ) )
327 // Calculates the line length and the max character height for the current line.
328 TextViewRelayout::SubLineLayoutInfo subLineInfo;
329 subLineInfo.mLineLength = 0.f;
330 subLineInfo.mMaxCharHeight = 0.f;
331 subLineInfo.mMaxAscender = 0.f;
332 TextViewRelayout::CalculateSubLineLayout( parentWidth,
335 TextViewRelayout::WrapByWord,
339 characterLayoutInfo.mPosition = Vector3( 0.f, previousPositionY + subLineInfo.mMaxCharHeight + layoutParameters.mLineHeightOffset * shrinkFactor, 0.f );
341 newTextHeight += subLineInfo.mMaxCharHeight + layoutParameters.mLineHeightOffset * shrinkFactor;
343 Toolkit::TextView::LineLayoutInfo lineInfo;
344 lineInfo.mCharacterGlobalIndex = characterGlobalIndex; // Index to the first character of the next line.
345 lineInfo.mSize = Size( subLineInfo.mLineLength, subLineInfo.mMaxCharHeight ); // Size of this piece of line.
346 lineInfo.mAscender = subLineInfo.mMaxAscender; // Ascender of this piece of line.
347 relayoutData.mLines.push_back( lineInfo );
350 // Stores some info to calculate the line justification in a post-process.
351 TextView::LineJustificationInfo justificationInfo;
353 justificationInfo.mIndices = indices;
354 justificationInfo.mLineLength = subLineInfo.mLineLength;
356 relayoutData.mLineJustificationInfo.push_back( justificationInfo );
360 characterLayoutInfo.mPosition = previousPosition + Vector3( previousSize.width, 0.f, 0.f );
363 // Get last line info and calculate the bearing.
364 const Toolkit::TextView::LineLayoutInfo& lineInfo( *( relayoutData.mLines.end() - 1 ) );
365 const float bearingOffset = ( ( lineInfo.mSize.height - lineInfo.mAscender ) - ( characterLayoutInfo.mSize.height - characterLayoutInfo.mAscender ) ) * shrinkFactor;
367 previousSize = characterLayoutInfo.mSize * shrinkFactor;
368 previousPosition = characterLayoutInfo.mPosition;
369 characterLayoutInfo.mPosition.y -= bearingOffset;
370 isFirstCharOfWord = false;
373 ++characterGlobalIndex;
379 if( isLastCharacterNewLineChar )
381 newTextHeight += lastCharHeight + layoutParameters.mLineHeightOffset * shrinkFactor;
385 float RelayoutForShrinkToFit( TextView::RelayoutData& relayoutData,
386 const TextView::LayoutParameters& layoutParameters )
388 const Size& textViewSize = relayoutData.mTextViewSize;
389 TextViewProcessor::TextLayoutInfo& textLayoutInfo = relayoutData.mTextLayoutInfo;
391 // First step is assure the longest word fits in the text view width.
392 float shrinkFactor = ( textLayoutInfo.mMaxWordWidth > textViewSize.width ? textViewSize.width / textLayoutInfo.mMaxWordWidth : 1.f );
394 // Out parameter. Will store the new text height after relayout the text.
395 float newTextHeight = 0.f;
397 // Relayout the text for the given character's sizes.
398 CalculatePositionsForShrinkWhenExceed( relayoutData,
403 if( newTextHeight > textViewSize.height )
405 // After relayouting, the text exceeds the text view height.
406 // Find a new scale factor to fit all the text in the text view size is needed.
408 // The next algorithm does some iterations to calculate an acceptable scale factor.
409 // Some magic numbers are defined.
411 const float MIN_RATIO( 0.90f ); // The algorithm finishes if the ratio
412 const float MAX_RATIO( 1.00f ); // new_text_height / text_view_height is between this two values
413 const unsigned int MAX_ITERATIONS( 8 ); // or max_iteration is reached.
415 float ratio = newTextHeight / textViewSize.height;
417 float maxScaleFactor = shrinkFactor; // bigger scale factors than maxScaleFactor will produce a too big text.
418 float minScaleFactor = shrinkFactor * ( textViewSize.height / newTextHeight ); // smaller scale factors than minScaleFactor will produce a too small text.
420 for( unsigned int iterations = 0; ( ( MIN_RATIO > ratio ) || ( ratio > MAX_RATIO ) ) && ( iterations < MAX_ITERATIONS ); ++iterations )
422 // Calculates the new scale factor.
423 // The new scale factor is always between the min and max scale factors.
424 // 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
425 // minScaleFactor. Alternatively if the text is too big a new scale factor close to maxScaleFactor is selected.
426 // This allows the text shrink or grow smoothly.
427 shrinkFactor = minScaleFactor + ( ratio < 1.f ? 0.4f : 0.6f ) * ( maxScaleFactor - minScaleFactor );
429 CalculatePositionsForShrinkWhenExceed( relayoutData, // Relayout the text for the given character's sizes.
434 // Calculates the new text size ratio. It allows update the min and max scale factors.
435 // If the ratio is not good enough a new scale factor between min and max could be used in next iteration.
436 ratio = newTextHeight / textViewSize.height;
439 minScaleFactor = shrinkFactor;
443 maxScaleFactor = shrinkFactor;
447 if( ratio > MAX_RATIO )
449 // The algorithm didn't find an acceptable scale factor.
450 // In that case the text is shrunk to fit in the boundaries of the text view actor.
451 shrinkFactor = minScaleFactor;
453 CalculatePositionsForShrinkWhenExceed( relayoutData,
463 void CalculateSizeAndPosition( const TextView::LayoutParameters& layoutParameters,
464 TextView::RelayoutData& relayoutData )
466 TextViewRelayout::RelayoutParameters relayoutParameters;
469 relayoutData.mCharacterLayoutInfoTable.clear();
470 relayoutData.mLines.clear();
471 relayoutData.mTextSizeForRelayoutOption = Size();
473 // Calculates the text size for split by char.
474 Vector4 minMaxXY( std::numeric_limits<float>::max(),
475 std::numeric_limits<float>::max(),
476 std::numeric_limits<float>::min(),
477 std::numeric_limits<float>::min() );
479 relayoutData.mShrinkFactor = 1.f; // Shrink factor used when the exceed policy contains ShrinkToFit
481 if( TextView::Shrink== layoutParameters.mExceedPolicy )
483 // Relays-out the text for the shrink to fit policy.
484 relayoutData.mShrinkFactor = RelayoutForShrinkToFit( relayoutData, layoutParameters );
486 else if( TextView::ShrinkOriginal == layoutParameters.mExceedPolicy )
488 relayoutData.mShrinkFactor = ( relayoutData.mTextLayoutInfo.mMaxWordWidth > relayoutData.mTextViewSize.width ? relayoutData.mTextViewSize.width / relayoutData.mTextLayoutInfo.mMaxWordWidth : 1.f );
491 relayoutParameters.mPositionOffset = Vector3::ZERO;
492 relayoutParameters.mIsFirstCharacter = true;
493 relayoutParameters.mIndices.mLineIndex = 0;
494 relayoutParameters.mCharacterGlobalIndex = 0;
496 for( TextViewProcessor::LineLayoutInfoContainer::iterator lineLayoutIt = relayoutData.mTextLayoutInfo.mLinesLayoutInfo.begin(),
497 endLineLayoutIt = relayoutData.mTextLayoutInfo.mLinesLayoutInfo.end();
498 lineLayoutIt != endLineLayoutIt;
499 ++lineLayoutIt, ++relayoutParameters.mIndices.mLineIndex )
501 TextViewProcessor::LineLayoutInfo& lineLayoutInfo( *lineLayoutIt );
503 relayoutParameters.mIsNewLine = true;
504 relayoutParameters.mLineSize = lineLayoutInfo.mSize;
505 relayoutParameters.mIndices.mGroupIndex = 0;
507 for( TextViewProcessor::WordGroupLayoutInfoContainer::iterator groupLayoutIt = lineLayoutInfo.mWordGroupsLayoutInfo.begin(),
508 endGroupLayoutIt = lineLayoutInfo.mWordGroupsLayoutInfo.end();
509 groupLayoutIt != endGroupLayoutIt;
510 ++groupLayoutIt, ++relayoutParameters.mIndices.mGroupIndex )
512 TextViewProcessor::WordGroupLayoutInfo& wordGroupLayoutInfo( *groupLayoutIt );
514 relayoutParameters.mIndices.mWordIndex = 0;
516 for( TextViewProcessor::WordLayoutInfoContainer::iterator wordLayoutIt = wordGroupLayoutInfo.mWordsLayoutInfo.begin(),
517 endWordLayoutIt = wordGroupLayoutInfo.mWordsLayoutInfo.end();
518 wordLayoutIt != endWordLayoutIt;
519 ++wordLayoutIt, ++relayoutParameters.mIndices.mWordIndex )
521 TextViewProcessor::WordLayoutInfo& wordLayoutInfo( *wordLayoutIt );
522 relayoutParameters.mIsWhiteSpace = TextViewProcessor::WordSeparator == wordLayoutInfo.mType;
523 relayoutParameters.mIsNewLineCharacter = TextViewProcessor::LineSeparator == wordLayoutInfo.mType;
525 relayoutParameters.mIsFirstCharacterOfWord = true;
526 relayoutParameters.mWordSize = wordLayoutInfo.mSize;
527 relayoutParameters.mIndices.mCharacterIndex = 0;
529 for( TextViewProcessor::CharacterLayoutInfoContainer::iterator characterLayoutIt = wordLayoutInfo.mCharactersLayoutInfo.begin(),
530 endCharacterLayoutIt = wordLayoutInfo.mCharactersLayoutInfo.end();
531 ( characterLayoutIt != endCharacterLayoutIt );
532 ++characterLayoutIt, ++relayoutParameters.mIndices.mCharacterIndex )
534 TextViewProcessor::CharacterLayoutInfo& characterLayoutInfo( *characterLayoutIt );
536 relayoutParameters.mCharacterSize = characterLayoutInfo.mSize;
538 switch( layoutParameters.mExceedPolicy )
540 case TextView::OriginalShrink:
541 case TextView::SplitShrink:
542 case TextView::ShrinkFade:
544 DALI_LOG_WARNING( "SplitByWord::CalculateSizeAndPosition() policy not implemented.\n" );
547 case TextView::Original:
548 case TextView::OriginalFade:
549 case TextView::FadeOriginal:
551 case TextView::EllipsizeEndOriginal:
552 case TextView::EllipsizeEnd: // Fall Through
554 characterLayoutInfo.mPosition = OriginalPosition( relayoutParameters,
558 relayoutParameters.mPositionOffset = characterLayoutInfo.mPosition + Vector3( characterLayoutInfo.mSize.width, 0.f, 0.f );
561 case TextView::SplitOriginal:
562 case TextView::SplitFade:
563 case TextView::SplitEllipsizeEnd:
565 characterLayoutInfo.mPosition = SplitWhenExceedPosition( relayoutParameters,
569 relayoutParameters.mPositionOffset = characterLayoutInfo.mPosition + Vector3( characterLayoutInfo.mSize.width, 0.f, 0.f );
572 case TextView::ShrinkOriginal:
574 characterLayoutInfo.mPosition = ShrinkWidthWhenExceedPosition( relayoutParameters,
578 relayoutParameters.mPositionOffset = characterLayoutInfo.mPosition + Vector3( characterLayoutInfo.mSize.width * relayoutData.mShrinkFactor, 0.f, 0.f );
581 case TextView::Shrink:
583 // Does nothing. All the job has been done in the RelayoutForShrinkToFit() function.
588 DALI_LOG_WARNING( "SplitByWord::CalculateSizeAndPosition() policy combination not possible.\n" );
592 // Get last line info and calculate the bearing (used to align glyphs with the baseline).
593 if( TextView::Shrink != layoutParameters.mExceedPolicy )
595 TextViewRelayout::CalculateBearing( characterLayoutInfo, relayoutData );
598 // updates min and max position to calculate the text size for split by word.
599 TextViewRelayout::UpdateLayoutInfoTable( minMaxXY,
606 ++relayoutParameters.mCharacterGlobalIndex;
607 relayoutParameters.mIsFirstCharacter = false;
608 relayoutParameters.mIsFirstCharacterOfWord = false;
609 relayoutParameters.mIsNewLine = false;
612 } // end group of words
615 if( relayoutData.mCharacterLayoutInfoTable.empty() )
617 relayoutData.mTextSizeForRelayoutOption = Size();
621 relayoutData.mTextSizeForRelayoutOption.width = minMaxXY.z - minMaxXY.x;
622 relayoutData.mTextSizeForRelayoutOption.height = minMaxXY.w - minMaxXY.y;
625 // Check if the last character is a new line character. In that case the height should be added.
626 if( !relayoutData.mTextLayoutInfo.mLinesLayoutInfo.empty() )
628 const TextViewProcessor::LineLayoutInfo& lineLayoutInfo( *( relayoutData.mTextLayoutInfo.mLinesLayoutInfo.end() - 1 ) );
630 if( lineLayoutInfo.mWordGroupsLayoutInfo.empty() ) // if it's empty, it means the last character is a new line character.
632 relayoutData.mTextSizeForRelayoutOption.height += lineLayoutInfo.mSize.height * relayoutData.mShrinkFactor;
639 void Relayout( Actor textView,
640 TextView::RelayoutOperationMask relayoutOperationMask,
641 const TextView::LayoutParameters& layoutParameters,
642 const TextView::VisualParameters& visualParameters,
643 TextView::RelayoutData& relayoutData )
645 if( relayoutOperationMask & TextView::RELAYOUT_SIZE_POSITION )
647 relayoutData.mLineJustificationInfo.clear();
648 CalculateSizeAndPosition( layoutParameters,
651 TextViewRelayout::SetUnderlineInfo( relayoutData );
654 if( relayoutOperationMask & TextView::RELAYOUT_ALIGNMENT )
656 TextViewRelayout::UpdateAlignment( layoutParameters,
660 if( relayoutOperationMask & TextView::RELAYOUT_VISIBILITY )
662 TextViewRelayout::UpdateVisibility( layoutParameters,
667 if( relayoutOperationMask & TextView::RELAYOUT_INITIALIZE_TEXT_ACTORS )
669 TextViewProcessor::InitializeTextActorInfo( relayoutData );
672 if( relayoutOperationMask & TextView::RELAYOUT_TEXT_ACTOR_UPDATE )
674 TextViewRelayout::UpdateTextActorInfo( visualParameters,
678 if( ( relayoutOperationMask & TextView::RELAYOUT_INSERT_TO_TEXT_VIEW ) ||
679 ( relayoutOperationMask & TextView::RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST ) )
681 TextViewRelayout::InsertToTextView( relayoutOperationMask,
687 } // namespace SplitByWord
689 } // namespace Internal
691 } // namespace Toolkit