+ previousCharacterDirection = characterDirection;
+ glyphIndex += numberOfGLyphsInGroup;
+ }
+
+ lineLayout.extraBearing = tmpExtraBearing;
+ lineLayout.extraWidth = tmpExtraWidth;
+
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "<--GetLineLayoutForBox\n" );
+ }
+
+ void SetGlyphPositions( const GlyphInfo* const glyphsBuffer,
+ Length numberOfGlyphs,
+ float outlineWidth,
+ Vector2* glyphPositionsBuffer )
+ {
+ // Traverse the glyphs and set the positions.
+
+ // Check if the x bearing of the first character is negative.
+ // If it has a negative x bearing, it will exceed the boundaries of the actor,
+ // so the penX position needs to be moved to the right.
+
+ const GlyphInfo& glyph = *glyphsBuffer;
+ float penX = ( 0.f > glyph.xBearing ) ? -glyph.xBearing + outlineWidth : outlineWidth;
+
+
+ for( GlyphIndex i = 0u; i < numberOfGlyphs; ++i )
+ {
+ const GlyphInfo& glyph = *( glyphsBuffer + i );
+ Vector2& position = *( glyphPositionsBuffer + i );
+
+ position.x = penX + glyph.xBearing;
+ position.y = -glyph.yBearing;
+
+ penX += glyph.advance;
+ }
+ }
+
+ /**
+ * @brief Resizes the line buffer.
+ *
+ * @param[in,out] lines The vector of lines. Used when the layout is created from scratch.
+ * @param[in,out] newLines The vector of lines used instead of @p lines when the layout is updated.
+ * @param[in,out] linesCapacity The capacity of the vector (either lines or newLines).
+ * @param[in] updateCurrentBuffer Whether the layout is updated.
+ *
+ * @return Pointer to either lines or newLines.
+ */
+ LineRun* ResizeLinesBuffer( Vector<LineRun>& lines,
+ Vector<LineRun>& newLines,
+ Length& linesCapacity,
+ bool updateCurrentBuffer )
+ {
+ LineRun* linesBuffer = NULL;
+ // Reserve more space for the next lines.
+ linesCapacity *= 2u;
+ if( updateCurrentBuffer )
+ {
+ newLines.Resize( linesCapacity );
+ linesBuffer = newLines.Begin();
+ }
+ else
+ {
+ lines.Resize( linesCapacity );
+ linesBuffer = lines.Begin();
+ }
+
+ return linesBuffer;
+ }
+
+ /**
+ * Ellipsis a line if it exceeds the width's of the bounding box.
+ *
+ * @param[in] layoutParameters The parameters needed to layout the text.
+ * @param[in] layout The line layout.
+ * @param[in,out] layoutSize The text's layout size.
+ * @param[in,out] linesBuffer Pointer to the line's buffer.
+ * @param[in,out] glyphPositionsBuffer Pointer to the position's buffer.
+ * @param[in,out] numberOfLines The number of laid-out lines.
+ * @param[in] penY The vertical layout position.
+ * @param[in] currentParagraphDirection The current paragraph's direction.
+ * @param[in,out] isAutoScrollEnabled If the isAutoScrollEnabled is true and the height of the text exceeds the boundaries of the control the text is elided and the isAutoScrollEnabled is set to false to disable the autoscroll
+ *
+ * return Whether the line is ellipsized.
+ */
+ bool EllipsisLine( const Parameters& layoutParameters,
+ const LineLayout& layout,
+ Size& layoutSize,
+ LineRun* linesBuffer,
+ Vector2* glyphPositionsBuffer,
+ Length& numberOfLines,
+ float penY,
+ CharacterDirection currentParagraphDirection,
+ bool& isAutoScrollEnabled )
+ {
+ const bool ellipsis = isAutoScrollEnabled ? ( penY - layout.descender > layoutParameters.boundingBox.height ) :
+ ( ( penY - layout.descender > layoutParameters.boundingBox.height ) ||
+ ( ( mLayout == SINGLE_LINE_BOX ) &&
+ ( layout.extraBearing + layout.length + layout.extraWidth > layoutParameters.boundingBox.width ) ) );
+
+ if( ellipsis )
+ {
+ isAutoScrollEnabled = false;
+ // Do not layout more lines if ellipsis is enabled.
+
+ // The last line needs to be completely filled with characters.
+ // Part of a word may be used.
+
+ LineRun* lineRun = NULL;
+ LineLayout ellipsisLayout;
+ if( 0u != numberOfLines )
+ {
+ // Get the last line and layout it again with the 'completelyFill' flag to true.
+ lineRun = linesBuffer + ( numberOfLines - 1u );
+
+ penY -= layout.ascender - lineRun->descender + lineRun->lineSpacing;
+
+ ellipsisLayout.glyphIndex = lineRun->glyphRun.glyphIndex;
+ }
+ else
+ {
+ // At least there is space reserved for one line.
+ lineRun = linesBuffer;
+
+ lineRun->glyphRun.glyphIndex = 0u;
+ ellipsisLayout.glyphIndex = 0u;
+
+ ++numberOfLines;
+ }
+
+ GetLineLayoutForBox( layoutParameters,
+ ellipsisLayout,
+ currentParagraphDirection,
+ true );
+
+ lineRun->glyphRun.numberOfGlyphs = ellipsisLayout.numberOfGlyphs;
+ lineRun->characterRun.characterIndex = ellipsisLayout.characterIndex;
+ lineRun->characterRun.numberOfCharacters = ellipsisLayout.numberOfCharacters;
+ lineRun->width = ellipsisLayout.length;
+ lineRun->extraLength = ( ellipsisLayout.wsLengthEndOfLine > 0.f ) ? ellipsisLayout.wsLengthEndOfLine - ellipsisLayout.extraWidth : 0.f;
+ lineRun->ascender = ellipsisLayout.ascender;
+ lineRun->descender = ellipsisLayout.descender;
+ lineRun->direction = !RTL;
+ lineRun->ellipsis = true;
+
+ layoutSize.width = layoutParameters.boundingBox.width;
+ if( layoutSize.height < Math::MACHINE_EPSILON_1000 )