+ /**
+ * @brief Calculates the vertical offset to add to the new laid-out glyphs.
+ *
+ * @pre @p lineIndex must be between 0 and the number of lines (both inclusive).
+ *
+ * @param[in] lines The previously laid-out lines.
+ * @param[in] lineIndex Index to the line where the new laid-out lines are inserted.
+ *
+ * @return The vertical offset of the lines starting from the beginning to the line @p lineIndex.
+ */
+ float SetParagraphOffset( const Vector<LineRun>& lines,
+ LineIndex lineIndex )
+ {
+ float offset = 0.f;
+
+ for( Vector<LineRun>::ConstIterator it = lines.Begin(),
+ endIt = lines.Begin() + lineIndex;
+ it != endIt;
+ ++it )
+ {
+ const LineRun& line = *it;
+
+ offset += line.ascender + -line.descender;
+ }
+
+ return offset;
+ }
+
+ void SetGlyphPositions( const GlyphInfo* const glyphsBuffer,
+ Length numberOfGlyphs,
+ 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 : 0.f;
+
+ 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.
+ *
+ * return Whether the line is ellipsized.
+ */
+ bool EllipsisLine( const LayoutParameters& layoutParameters,
+ const LineLayout& layout,
+ Size& layoutSize,
+ LineRun* linesBuffer,
+ Vector2* glyphPositionsBuffer,
+ Length& numberOfLines,
+ float penY,
+ CharacterDirection currentParagraphDirection )