+Size LayoutText( const RendererParameters& textParameters, TextAbstraction::TextRenderer::Parameters& rendererParameters,
+ Vector<EmbeddedItemInfo>& embeddedItemLayout, InternalDataModel& internalDataModel )
+{
+ ////////////////////////////////////////////////////////////////////////////////
+ // Layout the text.
+ ////////////////////////////////////////////////////////////////////////////////
+ Text::ModelPtr& textModel = internalDataModel.textModel;
+ Text::Layout::Engine& layoutEngine = internalDataModel.layoutEngine;
+ FontClient& fontClient = internalDataModel.fontClient;
+ const Length numberOfGlyphs = internalDataModel.numberOfGlyphs;
+ const bool isTextMirrored = internalDataModel.isTextMirrored;
+ const Vector<Character>& mirroredUtf32Characters = internalDataModel.mirroredUtf32Characters;
+ const Length numberOfCharacters = internalDataModel.numberOfCharacters;
+
+ // Sets the alignment
+ HorizontalAlignment::Type horizontalAlignment = Toolkit::HorizontalAlignment::CENTER;
+ HorizontalAlignment::Type horizontalCircularAlignment = Toolkit::HorizontalAlignment::CENTER;
+ VerticalAlignment::Type verticalAlignment = VerticalAlignment::CENTER;
+ Layout::Type layout = Layout::SINGLELINE;
+ CircularAlignment::Type circularAlignment = CircularAlignment::BEGIN;
+
+ Property::Value horizontalAlignmentStr( textParameters.horizontalAlignment );
+ GetHorizontalAlignmentEnumeration( horizontalAlignmentStr, horizontalAlignment );
+ horizontalCircularAlignment = horizontalAlignment;
+
+ Property::Value verticalAlignmentStr( textParameters.verticalAlignment );
+ GetVerticalAlignmentEnumeration( verticalAlignmentStr, verticalAlignment );
+
+ Property::Value layoutStr( textParameters.layout );
+ GetLayoutEnumeration( layoutStr, layout );
+
+ Property::Value circularAlignmentStr( textParameters.circularAlignment );
+ GetCircularAlignmentEnumeration( circularAlignmentStr, circularAlignment );
+
+ // Whether the layout is multi-line.
+ const Text::Layout::Engine::Type horizontalLayout = ( Layout::MULTILINE == layout ) ? Text::Layout::Engine::MULTI_LINE_BOX : Text::Layout::Engine::SINGLE_LINE_BOX;
+ layoutEngine.SetLayout( horizontalLayout ); // TODO: multi-line.
+
+
+ // Whether the layout is circular.
+ const bool isCircularTextLayout = (Layout::CIRCULAR == layout);
+ const bool isClockwise = isCircularTextLayout && ( 0.f < textParameters.incrementAngle );
+
+ // Calculates the max ascender or the max descender.
+ // Is used to calculate the radius of the base line of the text.
+ float maxAscenderDescender = 0.f;
+ if( isCircularTextLayout )
+ {
+ FontId currentFontId = 0u;
+ for( const auto& glyph : rendererParameters.glyphs )
+ {
+ if( currentFontId != glyph.fontId )
+ {
+ currentFontId = glyph.fontId;
+ FontMetrics metrics;
+ fontClient.GetFontMetrics(currentFontId, metrics);
+ maxAscenderDescender = std::max( maxAscenderDescender, isClockwise ? metrics.ascender : metrics.descender );
+ }
+ }
+ }
+ const unsigned int radius = textParameters.radius - static_cast<unsigned int>( maxAscenderDescender );
+
+ // Convert CircularAlignment to HorizontalAlignment.
+ if( isCircularTextLayout )
+ {
+ switch( circularAlignment )
+ {
+ case CircularAlignment::BEGIN:
+ {
+ horizontalCircularAlignment = Toolkit::HorizontalAlignment::BEGIN;
+ break;
+ }
+ case CircularAlignment::CENTER:
+ {
+ horizontalCircularAlignment = Toolkit::HorizontalAlignment::CENTER;
+ break;
+ }
+ case CircularAlignment::END:
+ {
+ horizontalCircularAlignment = Toolkit::HorizontalAlignment::END;
+ break;
+ }
+ }
+ }
+
+ // Set the layout parameters.
+ Size textLayoutArea( static_cast<float>( textParameters.textWidth ),
+ static_cast<float>( textParameters.textHeight ) );
+
+ if( isCircularTextLayout )
+ {
+ // In a circular layout, the length of the text area depends on the radius.
+ rendererParameters.radius = radius;
+ textLayoutArea.width = fabs( Radian( Degree( textParameters.incrementAngle ) ) * static_cast<float>( rendererParameters.radius ) );
+ }
+ // Resize the vector of positions to have the same size than the vector of glyphs.
+ rendererParameters.positions.Resize( numberOfGlyphs );
+
+
+
+ textModel->mHorizontalAlignment = isCircularTextLayout ? horizontalCircularAlignment : horizontalAlignment;
+ textModel->mLineWrapMode = LineWrap::WORD;
+ textModel->mIgnoreSpacesAfterText = false;
+ textModel->mMatchSystemLanguageDirection = false;
+ Text::Layout::Parameters layoutParameters( textLayoutArea,
+ textModel );
+
+
+ // Whether the last character is a new paragraph character.
+ const Vector<Character>& textToShape = isTextMirrored ? mirroredUtf32Characters : textModel->mLogicalModel->mText;
+ layoutParameters.isLastNewParagraph = TextAbstraction::IsNewParagraph( textToShape[numberOfCharacters - 1u] );
+
+ // The initial glyph and the number of glyphs to layout.
+ layoutParameters.startGlyphIndex = 0u;
+ layoutParameters.numberOfGlyphs = numberOfGlyphs;
+ layoutParameters.startLineIndex = 0u;
+ layoutParameters.estimatedNumberOfLines = 1u;
+ layoutParameters.interGlyphExtraAdvance = 0.f;
+
+ // Update the visual model.
+ Size newLayoutSize;
+ bool isAutoScrollEnabled = false;
+ layoutEngine.LayoutText( layoutParameters,
+ newLayoutSize,
+ textParameters.ellipsisEnabled,
+ isAutoScrollEnabled );
+
+ ////////////////////////////////////////////////////////////////////////////////
+ // Align the text.
+ ////////////////////////////////////////////////////////////////////////////////
+ Align( textParameters, rendererParameters, embeddedItemLayout, internalDataModel,
+ textLayoutArea, newLayoutSize, isCircularTextLayout, isClockwise,
+ horizontalAlignment, verticalAlignment, circularAlignment, radius );
+
+ return textLayoutArea;
+
+}
+
+
+Devel::PixelBuffer RenderText( const RendererParameters& textParameters, TextAbstraction::TextRenderer::Parameters& rendererParameters )
+{