- DALI_LOG_INFO( gLogFilter, Debug::Verbose, "-->Controller::DoRelayout %p size %f,%f\n", this, size.width, size.height );
- bool viewUpdated( false );
-
- // Calculate the operations to be done.
- const OperationsMask operations = static_cast<OperationsMask>( mImpl->mOperationsPending & operationsRequired );
-
- const CharacterIndex startIndex = mImpl->mTextUpdateInfo.mParagraphCharacterIndex;
- const Length requestedNumberOfCharacters = mImpl->mTextUpdateInfo.mRequestedNumberOfCharacters;
-
- // Get the current layout size.
- layoutSize = mImpl->mModel->mVisualModel->GetLayoutSize();
-
- if( NO_OPERATION != ( LAYOUT & operations ) )
- {
- DALI_LOG_INFO( gLogFilter, Debug::Verbose, "-->Controller::DoRelayout LAYOUT & operations\n");
-
- // Some vectors with data needed to layout and reorder may be void
- // after the first time the text has been laid out.
- // Fill the vectors again.
-
- // Calculate the number of glyphs to layout.
- const Vector<GlyphIndex>& charactersToGlyph = mImpl->mModel->mVisualModel->mCharactersToGlyph;
- const Vector<Length>& glyphsPerCharacter = mImpl->mModel->mVisualModel->mGlyphsPerCharacter;
- const GlyphIndex* const charactersToGlyphBuffer = charactersToGlyph.Begin();
- const Length* const glyphsPerCharacterBuffer = glyphsPerCharacter.Begin();
-
- const CharacterIndex lastIndex = startIndex + ( ( requestedNumberOfCharacters > 0u ) ? requestedNumberOfCharacters - 1u : 0u );
- const GlyphIndex startGlyphIndex = mImpl->mTextUpdateInfo.mStartGlyphIndex;
-
- // Make sure the index is not out of bound
- if ( charactersToGlyph.Count() != glyphsPerCharacter.Count() ||
- requestedNumberOfCharacters > charactersToGlyph.Count() ||
- ( lastIndex >= charactersToGlyph.Count() && charactersToGlyph.Count() > 0u ) )
- {
- std::string currentText;
- GetText( currentText );
-
- DALI_LOG_ERROR( "Controller::DoRelayout: Attempting to access invalid buffer\n" );
- DALI_LOG_ERROR( "Current text is: %s\n", currentText.c_str() );
- DALI_LOG_ERROR( "startIndex: %u, lastIndex: %u, requestedNumberOfCharacters: %u, charactersToGlyph.Count = %lu, glyphsPerCharacter.Count = %lu\n", startIndex, lastIndex, requestedNumberOfCharacters, charactersToGlyph.Count(), glyphsPerCharacter.Count());
-
- return false;
- }
-
- const Length numberOfGlyphs = ( requestedNumberOfCharacters > 0u ) ? *( charactersToGlyphBuffer + lastIndex ) + *( glyphsPerCharacterBuffer + lastIndex ) - startGlyphIndex : 0u;
- const Length totalNumberOfGlyphs = mImpl->mModel->mVisualModel->mGlyphs.Count();
-
- if( 0u == totalNumberOfGlyphs )
- {
- if( NO_OPERATION != ( UPDATE_LAYOUT_SIZE & operations ) )
- {
- mImpl->mModel->mVisualModel->SetLayoutSize( Size::ZERO );
- }
-
- // Nothing else to do if there is no glyphs.
- DALI_LOG_INFO( gLogFilter, Debug::Verbose, "<--Controller::DoRelayout no glyphs, view updated true\n" );
- return true;
- }
-
- const Vector<LineBreakInfo>& lineBreakInfo = mImpl->mModel->mLogicalModel->mLineBreakInfo;
- const Vector<WordBreakInfo>& wordBreakInfo = mImpl->mModel->mLogicalModel->mWordBreakInfo;
- const Vector<CharacterDirection>& characterDirection = mImpl->mModel->mLogicalModel->mCharacterDirections;
- const Vector<GlyphInfo>& glyphs = mImpl->mModel->mVisualModel->mGlyphs;
- const Vector<CharacterIndex>& glyphsToCharactersMap = mImpl->mModel->mVisualModel->mGlyphsToCharacters;
- const Vector<Length>& charactersPerGlyph = mImpl->mModel->mVisualModel->mCharactersPerGlyph;
- const Character* const textBuffer = mImpl->mModel->mLogicalModel->mText.Begin();
- const float outlineWidth = static_cast<float>( mImpl->mModel->GetOutlineWidth() );
-
- // Set the layout parameters.
- Layout::Parameters layoutParameters( size,
- textBuffer,
- lineBreakInfo.Begin(),
- wordBreakInfo.Begin(),
- ( 0u != characterDirection.Count() ) ? characterDirection.Begin() : NULL,
- glyphs.Begin(),
- glyphsToCharactersMap.Begin(),
- charactersPerGlyph.Begin(),
- charactersToGlyphBuffer,
- glyphsPerCharacterBuffer,
- totalNumberOfGlyphs,
- mImpl->mModel->mHorizontalAlignment,
- mImpl->mModel->mLineWrapMode,
- outlineWidth,
- mImpl->mModel->mIgnoreSpacesAfterText,
- mImpl->mModel->mMatchSystemLanguageDirection );
-
- // Resize the vector of positions to have the same size than the vector of glyphs.
- Vector<Vector2>& glyphPositions = mImpl->mModel->mVisualModel->mGlyphPositions;
- glyphPositions.Resize( totalNumberOfGlyphs );
-
- // Whether the last character is a new paragraph character.
- mImpl->mTextUpdateInfo.mIsLastCharacterNewParagraph = TextAbstraction::IsNewParagraph( *( textBuffer + ( mImpl->mModel->mLogicalModel->mText.Count() - 1u ) ) );
- layoutParameters.isLastNewParagraph = mImpl->mTextUpdateInfo.mIsLastCharacterNewParagraph;
-
- // The initial glyph and the number of glyphs to layout.
- layoutParameters.startGlyphIndex = startGlyphIndex;
- layoutParameters.numberOfGlyphs = numberOfGlyphs;
- layoutParameters.startLineIndex = mImpl->mTextUpdateInfo.mStartLineIndex;
- layoutParameters.estimatedNumberOfLines = mImpl->mTextUpdateInfo.mEstimatedNumberOfLines;
-
- // Update the ellipsis
- bool elideTextEnabled = mImpl->mModel->mElideEnabled;
-
- if( NULL != mImpl->mEventData )
- {
- if( mImpl->mEventData->mPlaceholderEllipsisFlag && mImpl->IsShowingPlaceholderText() )
- {
- elideTextEnabled = mImpl->mEventData->mIsPlaceholderElideEnabled;
- }
- else if( EventData::INACTIVE != mImpl->mEventData->mState )
- {
- // Disable ellipsis when editing
- elideTextEnabled = false;
- }
-
- // Reset the scroll position in inactive state
- if( elideTextEnabled && ( mImpl->mEventData->mState == EventData::INACTIVE ) )
- {
- ResetScrollPosition();
- }
- }
-
- // Update the visual model.
- bool isAutoScrollEnabled = mImpl->mIsAutoScrollEnabled;
- Size newLayoutSize;
- viewUpdated = mImpl->mLayoutEngine.LayoutText( layoutParameters,
- glyphPositions,
- mImpl->mModel->mVisualModel->mLines,
- newLayoutSize,
- elideTextEnabled,
- isAutoScrollEnabled );
- mImpl->mIsAutoScrollEnabled = isAutoScrollEnabled;
-
- viewUpdated = viewUpdated || ( newLayoutSize != layoutSize );
-
- if( viewUpdated )
- {
- layoutSize = newLayoutSize;
-
- if( NO_OPERATION != ( UPDATE_DIRECTION & operations ) )
- {
- mImpl->mIsTextDirectionRTL = false;
- }
-
- // Reorder the lines
- if( NO_OPERATION != ( REORDER & operations ) )
- {
- Vector<BidirectionalParagraphInfoRun>& bidirectionalInfo = mImpl->mModel->mLogicalModel->mBidirectionalParagraphInfo;
- Vector<BidirectionalLineInfoRun>& bidirectionalLineInfo = mImpl->mModel->mLogicalModel->mBidirectionalLineInfo;
-
- // Check first if there are paragraphs with bidirectional info.
- if( 0u != bidirectionalInfo.Count() )
- {
- // Get the lines
- const Length numberOfLines = mImpl->mModel->mVisualModel->mLines.Count();
-
- // Reorder the lines.
- bidirectionalLineInfo.Reserve( numberOfLines ); // Reserve because is not known yet how many lines have right to left characters.
- ReorderLines( bidirectionalInfo,
- startIndex,
- requestedNumberOfCharacters,
- mImpl->mModel->mVisualModel->mLines,
- bidirectionalLineInfo );
-
- // Set the bidirectional info per line into the layout parameters.
- layoutParameters.lineBidirectionalInfoRunsBuffer = bidirectionalLineInfo.Begin();
- layoutParameters.numberOfBidirectionalInfoRuns = bidirectionalLineInfo.Count();
-
- // Re-layout the text. Reorder those lines with right to left characters.
- mImpl->mLayoutEngine.ReLayoutRightToLeftLines( layoutParameters,
- startIndex,
- requestedNumberOfCharacters,
- glyphPositions );
-
- if ( ( NO_OPERATION != ( UPDATE_DIRECTION & operations ) ) && ( numberOfLines > 0 ) )
- {
- const LineRun* const firstline = mImpl->mModel->mVisualModel->mLines.Begin();
- if ( firstline )
- {
- mImpl->mIsTextDirectionRTL = firstline->direction;
- }
- }
- }
- } // REORDER
-
- // Sets the layout size.
- if( NO_OPERATION != ( UPDATE_LAYOUT_SIZE & operations ) )
- {
- mImpl->mModel->mVisualModel->SetLayoutSize( layoutSize );
- }
- } // view updated
- }
-
- if( NO_OPERATION != ( ALIGN & operations ) )
- {
- // The laid-out lines.
- Vector<LineRun>& lines = mImpl->mModel->mVisualModel->mLines;
-
- // Need to align with the control's size as the text may contain lines
- // starting either with left to right text or right to left.
- mImpl->mLayoutEngine.Align( size,
- startIndex,
- requestedNumberOfCharacters,
- mImpl->mModel->mHorizontalAlignment,
- lines,
- mImpl->mModel->mAlignmentOffset,
- mImpl->mLayoutDirection,
- mImpl->mModel->mMatchSystemLanguageDirection );
-
- viewUpdated = true;
- }
-#if defined(DEBUG_ENABLED)
- std::string currentText;
- GetText( currentText );
- DALI_LOG_INFO( gLogFilter, Debug::Concise, "Controller::DoRelayout [%p] mImpl->mIsTextDirectionRTL[%s] [%s]\n", this, (mImpl->mIsTextDirectionRTL)?"true":"false", currentText.c_str() );
-#endif
- DALI_LOG_INFO( gLogFilter, Debug::Verbose, "<--Controller::DoRelayout, view updated %s\n", ( viewUpdated ? "true" : "false" ) );
- return viewUpdated;