From 40a47ee7e802afa836ba45f481b87d0bd28e34fa Mon Sep 17 00:00:00 2001 From: Victor Cebollada Date: Mon, 23 Mar 2015 07:32:13 +0000 Subject: [PATCH] Fix for text alignmnet and scrolling. Change-Id: Id800c1a6e8e53cef956d4d7633b6921f03cb5e82 Signed-off-by: Victor Cebollada --- .../controls/text-controls/text-field-impl.cpp | 10 +- .../controls/text-controls/text-label-impl.cpp | 3 + .../internal/text/layouts/layout-engine.cpp | 92 ++++++++------- dali-toolkit/internal/text/layouts/layout-engine.h | 2 + dali-toolkit/internal/text/text-controller.cpp | 123 +++++++++++++++++---- dali-toolkit/internal/text/text-controller.h | 18 ++- 6 files changed, 180 insertions(+), 68 deletions(-) diff --git a/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp b/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp index 3bf4e67..5cd3308 100644 --- a/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp +++ b/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp @@ -412,9 +412,14 @@ void TextField::OnRelayout( const Vector2& size, ActorSizeContainer& container ) if( mController->Relayout( size ) || !mRenderer ) { + const Vector2& scrollPosition = mController->GetScrollPosition(); + const Vector2& alignmentOffset = mController->GetAlignmentOffset(); + + Vector2 offset = scrollPosition + alignmentOffset; + if( mDecorator ) { - mDecorator->Relayout( size, mController->GetScrollPosition() ); + mDecorator->Relayout( size, offset ); } if( !mRenderer ) @@ -438,8 +443,7 @@ void TextField::OnRelayout( const Vector2& size, ActorSizeContainer& container ) if( mRenderableActor ) { - const Vector2& scrollPosition = mController->GetScrollPosition(); - mRenderableActor.SetPosition( scrollPosition.x, scrollPosition.y ); + mRenderableActor.SetPosition( offset.x, offset.y ); // Make sure the actor is parented correctly with/without clipping if( mClipper ) diff --git a/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp b/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp index 118c2b3..efcecbf 100644 --- a/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp +++ b/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp @@ -291,6 +291,9 @@ void TextLabel::OnRelayout( const Vector2& size, ActorSizeContainer& container ) if( renderableActor ) { + const Vector2& alignmentOffset = mController->GetAlignmentOffset(); + renderableActor.SetPosition( alignmentOffset.x, alignmentOffset.y ); + Self().Add( renderableActor ); } diff --git a/dali-toolkit/internal/text/layouts/layout-engine.cpp b/dali-toolkit/internal/text/layouts/layout-engine.cpp index 4e090e0..ebbf65b 100644 --- a/dali-toolkit/internal/text/layouts/layout-engine.cpp +++ b/dali-toolkit/internal/text/layouts/layout-engine.cpp @@ -45,9 +45,10 @@ struct LineLayout Length numberOfCharacters; ///< The number of characters which fit in one line. Length numberOfGlyphs; ///< The number of glyph which fit in one line. float length; ///< The length of the glyphs which fit in one line. + float widthAdvanceDiff; ///< The difference between the width and the advance of the last glyph. float wsLengthEndOfLine; ///< The length of the white spaces at the end of the line. - float height; ///< The maximum height of all fonts in the line. float ascender; ///< The maximum ascender of all fonts in the line. + float descender; ///< The maximum descender of all fonts in the line. }; struct LayoutEngine::Impl @@ -70,8 +71,8 @@ struct LayoutEngine::Impl lineLayout.numberOfGlyphs = 0u; lineLayout.length = 0.f; lineLayout.wsLengthEndOfLine = 0.f; - lineLayout.height = 0.f; lineLayout.ascender = 0.f; + lineLayout.descender = 0.f; // Get the last glyph index. const GlyphIndex lastGlyphIndex = parameters.totalNumberOfGlyphs - 1u; @@ -121,18 +122,18 @@ struct LayoutEngine::Impl Text::FontMetrics fontMetrics; mFontClient.GetFontMetrics( glyphInfo.fontId, fontMetrics ); - // Sets the maximum height. - if( fontMetrics.height > lineLayout.height ) - { - lineLayout.height = fontMetrics.height; - } - // Sets the maximum ascender. if( fontMetrics.ascender > lineLayout.ascender ) { lineLayout.ascender = fontMetrics.ascender; } + // Sets the maximum descender. + if( fontMetrics.descender > lineLayout.descender ) + { + lineLayout.descender = fontMetrics.descender; + } + lastFontId = glyphInfo.fontId; } } @@ -148,21 +149,20 @@ struct LayoutEngine::Impl lineLayout.numberOfCharacters = 0u; lineLayout.numberOfGlyphs = 0u; lineLayout.length = 0.f; + lineLayout.widthAdvanceDiff = 0.f; lineLayout.wsLengthEndOfLine = 0.f; - lineLayout.height = 0.f; lineLayout.ascender = 0.f; + lineLayout.descender = 0.f; // Stores temporary line layout which has not been added to the final line layout. LineLayout tmpLineLayout; tmpLineLayout.numberOfCharacters = 0u; tmpLineLayout.numberOfGlyphs = 0u; tmpLineLayout.length = 0.f; + tmpLineLayout.widthAdvanceDiff = 0.f; tmpLineLayout.wsLengthEndOfLine = 0.f; - tmpLineLayout.height = 0.f; tmpLineLayout.ascender = 0.f; - - // Get the last glyph index. - const GlyphIndex lastGlyphIndex = parameters.totalNumberOfGlyphs - 1u; + tmpLineLayout.descender = 0.f; FontId lastFontId = 0u; for( GlyphIndex glyphIndex = lineLayout.glyphIndex; @@ -200,18 +200,20 @@ struct LayoutEngine::Impl { // Add the length to the length of white spaces at the end of the line. tmpLineLayout.wsLengthEndOfLine += glyphInfo.advance; // I use the advance as the width is always zero for the white spaces. + tmpLineLayout.widthAdvanceDiff = 0.f; } else { // Add as well any previous white space length. - tmpLineLayout.length += tmpLineLayout.wsLengthEndOfLine + ( glyphIndex == lastGlyphIndex ) ? glyphInfo.width : glyphInfo.advance; + tmpLineLayout.length += tmpLineLayout.wsLengthEndOfLine + glyphInfo.advance; + tmpLineLayout.widthAdvanceDiff = glyphInfo.width - glyphInfo.advance; // Clear the white space length at the end of the line. tmpLineLayout.wsLengthEndOfLine = 0.f; } // Check if the accumulated length fits in the width of the box. - if( lineLayout.length + tmpLineLayout.length + ( ( 0.f < tmpLineLayout.length ) ? lineLayout.wsLengthEndOfLine : 0.f ) > parameters.boundingBox.width ) + if( lineLayout.length + tmpLineLayout.length + tmpLineLayout.widthAdvanceDiff + ( ( 0.f < tmpLineLayout.length ) ? lineLayout.wsLengthEndOfLine : 0.f ) > parameters.boundingBox.width ) { // Current word does not fit in the box's width. return; @@ -223,6 +225,7 @@ struct LayoutEngine::Impl lineLayout.numberOfCharacters += tmpLineLayout.numberOfCharacters; lineLayout.numberOfGlyphs += tmpLineLayout.numberOfGlyphs; lineLayout.length += tmpLineLayout.length; + lineLayout.widthAdvanceDiff = tmpLineLayout.widthAdvanceDiff; if( 0.f < tmpLineLayout.length ) { @@ -235,22 +238,23 @@ struct LayoutEngine::Impl lineLayout.wsLengthEndOfLine += tmpLineLayout.wsLengthEndOfLine; } - if( tmpLineLayout.height > lineLayout.height ) + if( tmpLineLayout.ascender > lineLayout.ascender ) { - lineLayout.height = tmpLineLayout.height; + lineLayout.ascender = tmpLineLayout.ascender; } - if( tmpLineLayout.ascender > lineLayout.ascender ) + if( tmpLineLayout.descender > lineLayout.descender ) { - lineLayout.ascender = tmpLineLayout.ascender; + lineLayout.descender = tmpLineLayout.descender; } tmpLineLayout.numberOfCharacters = 0u; tmpLineLayout.numberOfGlyphs = 0u; tmpLineLayout.length = 0u; + tmpLineLayout.widthAdvanceDiff = 0u; tmpLineLayout.wsLengthEndOfLine = 0u; - tmpLineLayout.height = 0.f; tmpLineLayout.ascender = 0.f; + tmpLineLayout.descender = 0.f; return; } @@ -261,6 +265,8 @@ struct LayoutEngine::Impl lineLayout.numberOfCharacters += tmpLineLayout.numberOfCharacters; lineLayout.numberOfGlyphs += tmpLineLayout.numberOfGlyphs; lineLayout.length += tmpLineLayout.length; + lineLayout.widthAdvanceDiff = tmpLineLayout.widthAdvanceDiff; + if( 0.f < tmpLineLayout.length ) { lineLayout.length += lineLayout.wsLengthEndOfLine; @@ -272,22 +278,23 @@ struct LayoutEngine::Impl lineLayout.wsLengthEndOfLine += tmpLineLayout.wsLengthEndOfLine; } - if( tmpLineLayout.height > lineLayout.height ) + if( tmpLineLayout.ascender > lineLayout.ascender ) { - lineLayout.height = tmpLineLayout.height; + lineLayout.ascender = tmpLineLayout.ascender; } - if( tmpLineLayout.ascender > lineLayout.ascender ) + if( tmpLineLayout.descender > lineLayout.descender ) { - lineLayout.ascender = tmpLineLayout.ascender; + lineLayout.descender = tmpLineLayout.descender; } tmpLineLayout.numberOfCharacters = 0u; tmpLineLayout.numberOfGlyphs = 0u; tmpLineLayout.length = 0u; + tmpLineLayout.widthAdvanceDiff = 0u; tmpLineLayout.wsLengthEndOfLine = 0u; - tmpLineLayout.height = 0.f; tmpLineLayout.ascender = 0.f; + tmpLineLayout.descender = 0.f; } if( lastFontId != glyphInfo.fontId ) @@ -295,18 +302,18 @@ struct LayoutEngine::Impl Text::FontMetrics fontMetrics; mFontClient.GetFontMetrics( glyphInfo.fontId, fontMetrics ); - // Sets the maximum height. - if( fontMetrics.height > tmpLineLayout.height ) - { - tmpLineLayout.height = fontMetrics.height; - } - // Sets the maximum ascender. if( fontMetrics.ascender > tmpLineLayout.ascender ) { tmpLineLayout.ascender = fontMetrics.ascender; } + // Sets the maximum descender. + if( -fontMetrics.descender > tmpLineLayout.descender ) + { + tmpLineLayout.descender = -fontMetrics.descender; + } + lastFontId = glyphInfo.fontId; } } @@ -382,6 +389,7 @@ struct LayoutEngine::Impl } void Align( const LayoutParameters& layoutParameters, + const Size& layoutSize, const Vector& lines, Vector& glyphPositions ) { @@ -423,7 +431,7 @@ struct LayoutEngine::Impl // 2) Calculate the alignment offset accordingly with the align option, // the box width, line length, and the paragraphs direction. - float alignOffset = CalculateAlignment( layoutParameters.boundingBox.width, + float alignOffset = CalculateAlignment( layoutSize.width, line.lineSize.width, line.extraLength, paragraphDirection ); @@ -460,17 +468,17 @@ struct LayoutEngine::Impl lineRun.characterRun.characterIndex = 0u; lineRun.characterRun.numberOfCharacters = *( layoutParameters.glyphsToCharactersBuffer + lastGlyphIndex ) + *( layoutParameters.charactersPerGlyphBuffer + lastGlyphIndex ); lineRun.lineSize.width = layout.length; - lineRun.lineSize.height = layout.height; + lineRun.lineSize.height = layout.ascender + layout.descender; lineRun.extraLength = layout.wsLengthEndOfLine; lines.PushBack( lineRun ); // Update the actual size. actualSize.width = layout.length; - actualSize.height = layout.height; + actualSize.height = lineRun.lineSize.height; float penX = 0.f; - float penY = layout.height; + float penY = layout.ascender; Vector2* glyphPositionsBuffer = glyphPositions.Begin(); for( GlyphIndex glyphIndex = 0u; glyphIndex < layout.numberOfGlyphs; ++glyphIndex ) @@ -517,23 +525,23 @@ struct LayoutEngine::Impl lineRun.numberOfGlyphs = layout.numberOfGlyphs; lineRun.characterRun.characterIndex = *( layoutParameters.glyphsToCharactersBuffer + index ); lineRun.characterRun.numberOfCharacters = ( *( layoutParameters.glyphsToCharactersBuffer + lastGlyphIndex ) + *( layoutParameters.charactersPerGlyphBuffer + lastGlyphIndex ) ) - lineRun.characterRun.characterIndex; - lineRun.lineSize.width = layout.length; - lineRun.lineSize.height = layout.height; + lineRun.lineSize.width = layout.length + ( ( layout.widthAdvanceDiff > 0.f ) ? layout.widthAdvanceDiff : 0.f ); + lineRun.lineSize.height = layout.ascender + layout.descender; lineRun.extraLength = layout.wsLengthEndOfLine; lines.PushBack( lineRun ); // Update the actual size. - if( layout.length > actualSize.width ) + if( layout.length + layout.widthAdvanceDiff > actualSize.width ) { actualSize.width = layout.length; } - actualSize.height += layout.height; + actualSize.height += lineRun.lineSize.height; // Traverse the glyphs and set the positions. - penY += layout.height; + penY += layout.ascender; Vector2* glyphPositionsBuffer = glyphPositions.Begin(); for( GlyphIndex i = index; i < index + layout.numberOfGlyphs; ++i ) @@ -547,6 +555,8 @@ struct LayoutEngine::Impl penX += glyph.advance; } + penY += layout.descender; + // Increase the glyph index. index += layout.numberOfGlyphs; } @@ -660,10 +670,12 @@ void LayoutEngine::ReLayoutRightToLeftLines( const LayoutParameters& layoutParam } void LayoutEngine::Align( const LayoutParameters& layoutParameters, + const Size& layoutSize, const Vector& lines, Vector& glyphPositions ) { mImpl->Align( layoutParameters, + layoutSize, lines, glyphPositions ); } diff --git a/dali-toolkit/internal/text/layouts/layout-engine.h b/dali-toolkit/internal/text/layouts/layout-engine.h index 093399b..1315445 100644 --- a/dali-toolkit/internal/text/layouts/layout-engine.h +++ b/dali-toolkit/internal/text/layouts/layout-engine.h @@ -126,10 +126,12 @@ public: * @brief Aligns the laid out lines. * * @param[in] layoutParameters The parameters needed to layout the text. + * @param[in] layoutSize The size of the laid out the text. * @param[in] lines The laid-out lines. * @param[in,out] glyphPositions The positions of all the glyphs. */ void Align( const LayoutParameters& layoutParameters, + const Size& layoutSize, const Vector& lines, Vector& glyphPositions ); diff --git a/dali-toolkit/internal/text/text-controller.cpp b/dali-toolkit/internal/text/text-controller.cpp index f6bc916..3981ce1 100644 --- a/dali-toolkit/internal/text/text-controller.cpp +++ b/dali-toolkit/internal/text/text-controller.cpp @@ -135,7 +135,8 @@ struct Controller::TextInput /** * @brief Helper to move the cursor, grab handle etc. */ - bool ProcessInputEvents( const Vector2& controlSize ) + bool ProcessInputEvents( const Vector2& controlSize, + const Vector2& alignmentOffset ) { mDecoratorUpdated = false; @@ -162,12 +163,12 @@ struct Controller::TextInput } case TAP_EVENT: { - OnTapEvent( *iter ); + OnTapEvent( *iter, alignmentOffset ); break; } case PAN_EVENT: { - OnPanEvent( *iter, controlSize ); + OnPanEvent( *iter, controlSize, alignmentOffset ); break; } case GRAB_HANDLE_EVENT: @@ -230,7 +231,8 @@ struct Controller::TextInput // TODO } - void OnTapEvent( const Event& event ) + void OnTapEvent( const Event& event, + const Vector2& alignmentOffset ) { unsigned int tapCount = event.p1.mUint; @@ -238,8 +240,8 @@ struct Controller::TextInput { ChangeState( EDITING ); - float xPosition = event.p2.mFloat; - float yPosition = event.p3.mFloat; + float xPosition = event.p2.mFloat - alignmentOffset.x; + float yPosition = event.p3.mFloat - alignmentOffset.y; float height(0.0f); GetClosestCursorPosition( mPrimaryCursorPosition, xPosition, yPosition, height ); mDecorator->SetPosition( PRIMARY_CURSOR, xPosition, yPosition, height ); @@ -254,7 +256,9 @@ struct Controller::TextInput } } - void OnPanEvent( const Event& event, const Vector2& controlSize ) + void OnPanEvent( const Event& event, + const Vector2& controlSize, + const Vector2& alignmentOffset ) { int state = event.p1.mInt; @@ -265,28 +269,43 @@ struct Controller::TextInput if( mHorizontalScrollingEnabled ) { - float displacementX = event.p2.mFloat; + const float displacementX = event.p2.mFloat; mScrollPosition.x += displacementX; - // Clamp between -space & 0 - float contentWidth = actualSize.width; - float space = (contentWidth > controlSize.width) ? contentWidth - controlSize.width : 0.0f; - mScrollPosition.x = ( mScrollPosition.x < -space ) ? -space : mScrollPosition.x; - mScrollPosition.x = ( mScrollPosition.x > 0 ) ? 0 : mScrollPosition.x; + // Clamp between -space & 0 (and the text alignment). + const float contentWidth = actualSize.width; + if( contentWidth > controlSize.width ) + { + const float space = ( contentWidth - controlSize.width ) + alignmentOffset.x; + mScrollPosition.x = ( mScrollPosition.x < -space ) ? -space : mScrollPosition.x; + mScrollPosition.x = ( mScrollPosition.x > -alignmentOffset.x ) ? -alignmentOffset.x : mScrollPosition.x; - mDecoratorUpdated = true; + mDecoratorUpdated = true; + } + else + { + mScrollPosition.x = 0.f; + } } + if( mVerticalScrollingEnabled ) { - float displacementY = event.p3.mFloat; + const float displacementY = event.p3.mFloat; mScrollPosition.y += displacementY; - // Clamp between -space & 0 - float space = (actualSize.height > controlSize.height) ? actualSize.height - controlSize.height : 0.0f; - mScrollPosition.y = ( mScrollPosition.y < -space ) ? -space : mScrollPosition.y; - mScrollPosition.y = ( mScrollPosition.y > 0 ) ? 0 : mScrollPosition.y; + // Clamp between -space & 0 (and the text alignment). + if( actualSize.height > controlSize.height ) + { + const float space = ( actualSize.height - controlSize.height ) + alignmentOffset.y; + mScrollPosition.y = ( mScrollPosition.y < -space ) ? -space : mScrollPosition.y; + mScrollPosition.y = ( mScrollPosition.y > -alignmentOffset.y ) ? -alignmentOffset.y : mScrollPosition.y; - mDecoratorUpdated = true; + mDecoratorUpdated = true; + } + else + { + mScrollPosition.y = 0.f; + } } } } @@ -561,6 +580,7 @@ struct Controller::Impl mLayoutEngine(), mModifyEvents(), mControlSize(), + mAlignmentOffset(), mOperationsPending( NO_OPERATION ), mRecalculateNaturalSize( true ) { @@ -587,6 +607,7 @@ struct Controller::Impl LayoutEngine mLayoutEngine; ///< The layout engine. std::vector mModifyEvents; ///< Temporary stores the text set until the next relayout. Size mControlSize; ///< The size of the control. + Vector2 mAlignmentOffset; ///< Vertical and horizontal offset of the whole text inside the control due to alignment. OperationsMask mOperationsPending; ///< Operations pending to be done to layout the text. bool mRecalculateNaturalSize:1; ///< Whether the natural size needs to be recalculated. }; @@ -772,6 +793,11 @@ const Vector2& Controller::GetScrollPosition() const return Vector2::ZERO; } +const Vector2& Controller::GetAlignmentOffset() const +{ + return mImpl->mAlignmentOffset; +} + Vector3 Controller::GetNaturalSize() { Vector3 naturalSize; @@ -867,7 +893,7 @@ float Controller::GetHeightForWidth( float width ) return layoutSize.height; } -bool Controller::Relayout( const Vector2& size ) +bool Controller::Relayout( const Size& size ) { if( ( size.width < Math::MACHINE_EPSILON_1000 ) || ( size.height < Math::MACHINE_EPSILON_1000 ) ) { @@ -906,10 +932,13 @@ bool Controller::Relayout( const Vector2& size ) // Do not re-do any operation until something changes. mImpl->mOperationsPending = NO_OPERATION; + // After doing the text layout, the alignment offset to place the actor in the desired position can be calculated. + CalculateTextAlignment( size ); + if( mImpl->mTextInput ) { // Move the cursor, grab handle etc. - updated = mImpl->mTextInput->ProcessInputEvents( mImpl->mControlSize ) || updated; + updated = mImpl->mTextInput->ProcessInputEvents( mImpl->mControlSize, mImpl->mAlignmentOffset ) || updated; } return updated; @@ -1258,7 +1287,7 @@ void Controller::UpdateModel( OperationsMask operationsRequired ) } } -bool Controller::DoRelayout( const Vector2& size, +bool Controller::DoRelayout( const Size& size, OperationsMask operationsRequired, Size& layoutSize ) { @@ -1368,6 +1397,7 @@ bool Controller::DoRelayout( const Vector2& size, if( ALIGN & operations ) { mImpl->mLayoutEngine.Align( layoutParameters, + layoutSize, lines, glyphPositions ); } @@ -1387,6 +1417,53 @@ bool Controller::DoRelayout( const Vector2& size, return viewUpdated; } +void Controller::CalculateTextAlignment( const Size& size ) +{ + // TODO : Calculate the vertical offset. + + // Get the direction of the first character. + const CharacterDirection firstParagraphDirection = mImpl->mLogicalModel->GetCharacterDirection( 0u ); + + const Size& actualSize = mImpl->mVisualModel->GetActualSize(); + + // If the first paragraph is right to left swap ALIGN_BEGIN and ALIGN_END; + LayoutEngine::Alignment alignment = mImpl->mLayoutEngine.GetAlignment(); + if( firstParagraphDirection && + ( LayoutEngine::ALIGN_CENTER != alignment ) ) + { + if( LayoutEngine::ALIGN_BEGIN == alignment ) + { + alignment = LayoutEngine::ALIGN_END; + } + else + { + alignment = LayoutEngine::ALIGN_BEGIN; + } + } + + switch( alignment ) + { + case LayoutEngine::ALIGN_BEGIN: + { + mImpl->mAlignmentOffset = Vector2::ZERO; + break; + } + case LayoutEngine::ALIGN_CENTER: + { + mImpl->mAlignmentOffset.y = 0.f; + const int intOffset = static_cast( 0.5f * ( size.width - actualSize.width ) ); // try to avoid pixel alignment. + mImpl->mAlignmentOffset.x = static_cast( intOffset ); + break; + } + case LayoutEngine::ALIGN_END: + { + mImpl->mAlignmentOffset.y = 0.f; + mImpl->mAlignmentOffset.x = size.width - actualSize.width; + break; + } + } +} + View& Controller::GetView() { return mImpl->mView; diff --git a/dali-toolkit/internal/text/text-controller.h b/dali-toolkit/internal/text/text-controller.h index cea9f39..2935299 100644 --- a/dali-toolkit/internal/text/text-controller.h +++ b/dali-toolkit/internal/text/text-controller.h @@ -203,6 +203,13 @@ public: const Vector2& GetScrollPosition() const; /** + * @brief Query the alignment offset. + * + * @return The alignmnet offset. + */ + const Vector2& GetAlignmentOffset() const; + + /** * @copydoc Control::GetNaturalSize() */ Vector3 GetNaturalSize(); @@ -219,7 +226,7 @@ public: * @param[in] size A the size of a bounding box to layout text within. * @return True if the text model or decorations were updated. */ - bool Relayout( const Vector2& size ); + bool Relayout( const Size& size ); /** * @brief Process queued events which modify the model. @@ -261,11 +268,18 @@ public: * @param[in] operations The layout operations which need to be done. * @param[out] layoutSize The size of the laid-out text. */ - bool DoRelayout( const Vector2& size, + bool DoRelayout( const Size& size, OperationsMask operations, Size& layoutSize ); /** + * @brief Calulates the alignment of the whole text inside the bounding box. + * + * @param[in] size The size of the bounding box. + */ + void CalculateTextAlignment( const Size& size ); + + /** * @brief Return the layout engine. * * @return A reference to the layout engine. -- 2.7.4