}
DALI_LOG_INFO( gLogFilter, Debug::Verbose, "<--LayoutText\n\n" );
+
return true;
}
}
}
- void Align( const LayoutParameters& layoutParameters,
- const Size& layoutSize,
- const Vector<LineRun>& lines,
- Vector<Vector2>& glyphPositions )
+ void Align( const Size& layoutSize,
+ Vector<LineRun>& lines )
{
- Vector2* glyphPositionsBuffer = glyphPositions.Begin();
-
// Traverse all lines and align the glyphs.
- // LayoutParameters contains bidirectional info for those lines with
- // right to left text, this info includes the paragraph's direction.
- LineIndex bidiLineIndex = 0u;
- for( Vector<LineRun>::ConstIterator it = lines.Begin(), endIt = lines.End();
+ for( Vector<LineRun>::Iterator it = lines.Begin(), endIt = lines.End();
it != endIt;
++it )
{
- const LineRun& line = *it;
-
- // 1) Get the paragrap's direction.
- bool paragraphDirection = false;
-
- // Check if there is any right to left line.
- if( ( NULL != layoutParameters.lineBidirectionalInfoRunsBuffer ) &&
- ( bidiLineIndex < layoutParameters.numberOfBidirectionalInfoRuns ) )
- {
- const BidirectionalLineInfoRun* bidiLine = layoutParameters.lineBidirectionalInfoRunsBuffer + bidiLineIndex;
-
- // Get the right to left line that match with current line.
- while( ( line.characterRun.characterIndex > bidiLine->characterRun.characterIndex ) &&
- ( bidiLineIndex < layoutParameters.numberOfBidirectionalInfoRuns ) )
- {
- ++bidiLineIndex;
- bidiLine = layoutParameters.lineBidirectionalInfoRunsBuffer + bidiLineIndex;
- }
-
- if( line.characterRun.characterIndex == bidiLine->characterRun.characterIndex )
- {
- paragraphDirection = bidiLine->direction;
- }
- }
-
- // 2) Calculate the alignment offset accordingly with the align option,
- // the box width, line length, and the paragraphs direction.
- float alignOffset = CalculateHorizontalAlignment( layoutSize.width,
- line.width,
- line.extraLength,
- paragraphDirection );
-
- // 3) Traverse all glyphs and update the 'x' position.
- for( GlyphIndex index = line.glyphIndex,
- endIndex = line.glyphIndex + line.numberOfGlyphs;
- index < endIndex;
- ++index )
- {
- Vector2& position = *( glyphPositionsBuffer + index );
-
- position.x += alignOffset;
- }
+ LineRun& line = *it;
+ const bool isLastLine = lines.End() == it + 1u;
+
+ // Calculate the alignment offset accordingly with the align option,
+ // the box width, line length, and the paragraphs direction.
+ CalculateHorizontalAlignment( layoutSize.width,
+ line,
+ isLastLine );
}
}
- float CalculateHorizontalAlignment( float boxWidth,
- float lineLength,
- float extraLength,
- bool paragraphDirection )
+ void CalculateHorizontalAlignment( float boxWidth,
+ LineRun& line,
+ bool isLastLine )
{
- float offset = 0.f;
+ line.alignmentOffset = 0.f;
+ const bool isRTL = RTL == line.direction;
+ float lineLength = line.width;
HorizontalAlignment alignment = mHorizontalAlignment;
- if( paragraphDirection &&
+ if( isRTL &&
( HORIZONTAL_ALIGN_CENTER != alignment ) )
{
if( HORIZONTAL_ALIGN_BEGIN == alignment )
{
case HORIZONTAL_ALIGN_BEGIN:
{
- offset = 0.f;
+ line.alignmentOffset = 0.f;
break;
}
case HORIZONTAL_ALIGN_CENTER:
{
- offset = 0.5f * ( boxWidth - lineLength );
- const int intOffset = static_cast<int>( offset ); // try to avoid pixel alignment.
- offset = static_cast<float>( intOffset );
+ line.alignmentOffset = floorf( 0.5f * ( boxWidth - lineLength ) ); // try to avoid pixel alignment.
break;
}
case HORIZONTAL_ALIGN_END:
{
- offset = boxWidth - lineLength;
+ line.alignmentOffset = boxWidth - lineLength;
break;
}
}
- if( paragraphDirection )
+ if( isRTL )
{
- offset -= extraLength;
+ line.alignmentOffset -= line.extraLength;
}
-
- return offset;
}
LayoutEngine::Layout mLayout;
glyphPositions );
}
-void LayoutEngine::Align( const LayoutParameters& layoutParameters,
- const Size& layoutSize,
- const Vector<LineRun>& lines,
- Vector<Vector2>& glyphPositions )
+void LayoutEngine::Align( const Size& layoutSize,
+ Vector<LineRun>& lines )
{
- mImpl->Align( layoutParameters,
- layoutSize,
- lines,
- glyphPositions );
+ mImpl->Align( layoutSize,
+ lines );
}
} // namespace Text
/**
* @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.
+ * @param[in,out] lines The laid-out lines.
*/
- void Align( const LayoutParameters& layoutParameters,
- const Size& layoutSize,
- const Vector<LineRun>& lines,
- Vector<Vector2>& glyphPositions );
+ void Align( const Size& layoutSize,
+ Vector<LineRun>& lines );
private:
*/
struct LineRun
{
- GlyphIndex glyphIndex; ///< The initial glyph index.
- Length numberOfGlyphs; ///< The number of glyphs of the run.
- CharacterRun characterRun; ///< The initial character and the number of characters.
- float width; ///< The line's width.
- float ascender; ///< The line's ascender.
- float descender; ///< The line's descender.
- float extraLength; ///< The length of the white spaces at the end of the line.
- CharacterDirection direction : 1; ///< Direction of the first character of the paragraph.
- bool ellipsis : 1; ///< Wheter ellipsis is added to the line.
+ GlyphIndex glyphIndex; ///< The initial glyph index.
+ Length numberOfGlyphs; ///< The number of glyphs of the run.
+ CharacterRun characterRun; ///< The initial character and the number of characters.
+ float width; ///< The line's width.
+ float ascender; ///< The line's ascender.
+ float descender; ///< The line's descender.
+ float extraLength; ///< The length of the white spaces at the end of the line.
+ float alignmentOffset; ///< The horizontal alignment offset.
+ CharacterDirection direction : 1; ///< Direction of the first character of the paragraph.
+ bool ellipsis : 1; ///< Wheter ellipsis is added to the line.
};
} // namespace Text
}
} // REORDER
- // TODO: I'm working on a patch that changes the LayoutEngine::Align() method.
- // The layoutParameters is not needed and this call can be moved outside the if().
- // Then there is no need to do the layout again to change the alignment.
- if( ALIGN & operations )
- {
- mImpl->mLayoutEngine.Align( layoutParameters,
- layoutSize,
- lines,
- glyphPositions );
- }
-
// Sets the actual size.
if( UPDATE_ACTUAL_SIZE & operations )
{
layoutSize = mImpl->mVisualModel->GetActualSize();
}
+ if( ALIGN & operations )
+ {
+ // The laid-out lines.
+ Vector<LineRun>& lines = mImpl->mVisualModel->mLines;
+
+ mImpl->mLayoutEngine.Align( layoutSize,
+ lines );
+
+ viewUpdated = true;
+ }
+
DALI_LOG_INFO( gLogFilter, Debug::Verbose, "<--Controller::DoRelayout, view updated %s\n", ( viewUpdated ? "true" : "false" ) );
return viewUpdated;
}
mImpl->mLayoutEngine.SetHorizontalAlignment( alignment );
// Set the flag to redo the alignment operation.
- // TODO : Is not needed re-layout and reorder again but with the current implementation it is.
- // Im working on a different patch to fix an issue with the alignment. When that patch
- // is in, this issue can be fixed.
- const OperationsMask layoutOperations = static_cast<OperationsMask>( LAYOUT |
- UPDATE_ACTUAL_SIZE |
- ALIGN |
- REORDER );
-
- mImpl->mOperationsPending = static_cast<OperationsMask>( mImpl->mOperationsPending | layoutOperations );
+ mImpl->mOperationsPending = static_cast<OperationsMask>( mImpl->mOperationsPending | ALIGN );
mImpl->RequestRelayout();
}
glyphIndex,
numberOfLaidOutGlyphs );
+ // Get the lines for the given range of glyphs.
+ // The lines contain the alignment offset which needs to be added to the glyph's position.
+ LineIndex firstLine = 0u;
+ Length numberOfLines = 0u;
+ mImpl->mVisualModel->GetNumberOfLines( glyphIndex,
+ numberOfLaidOutGlyphs,
+ firstLine,
+ numberOfLines );
+
+ Vector<LineRun> lines;
+ lines.Resize( numberOfLines );
+ LineRun* lineBuffer = lines.Begin();
+
+ mImpl->mVisualModel->GetLinesOfGlyphRange( lineBuffer,
+ glyphIndex,
+ numberOfLaidOutGlyphs );
+
+ // Get the first line for the given glyph range.
+ LineIndex lineIndex = firstLine;
+ LineRun* line = lineBuffer + lineIndex;
+
+ // Index of the last glyph of the line.
+ GlyphIndex lastGlyphIndexOfLine = line->glyphIndex + line->numberOfGlyphs - 1u;
+
+ // Add the alignment offset to the glyph's position.
+ for( Length index = 0u; index < numberOfLaidOutGlyphs; ++index )
+ {
+ ( *( glyphPositions + index ) ).x += line->alignmentOffset;
+
+ if( lastGlyphIndexOfLine == index )
+ {
+ // Get the next line.
+ ++lineIndex;
+
+ if( lineIndex < numberOfLines )
+ {
+ line = lineBuffer + lineIndex;
+ lastGlyphIndexOfLine = line->glyphIndex + line->numberOfGlyphs - 1u;
+ }
+ }
+ }
+
if( 1u == numberOfLaidOutGlyphs )
{
// not a point try to do ellipsis with only one laid out character.
return VisualModelPtr( new VisualModel() );
}
-void VisualModel::SetGlyphs( const GlyphInfo* glyphs,
- const CharacterIndex* characterIndices,
- const Length* charactersPerGlyph,
+void VisualModel::SetGlyphs( const GlyphInfo* const glyphs,
+ const CharacterIndex* const characterIndices,
+ const Length* const charactersPerGlyph,
Length numberOfGlyphs )
{
if( 0u == numberOfGlyphs )
memcpy( glyphsPerCharacter, mGlyphsPerCharacter.Begin() + characterIndex, numberOfCharacters * sizeof( Length ) );
}
-void VisualModel::SetGlyphPositions( const Vector2* glyphPositions,
+void VisualModel::SetGlyphPositions( const Vector2* const glyphPositions,
Length numberOfGlyphs )
{
if( 0u == numberOfGlyphs )
* @param[in] charactersPerGlyph An array containing the number of characters per glyph.
* @param[in] numberOfGlyphs The number of glyphs.
*/
- void SetGlyphs( const GlyphInfo* glyphs,
- const CharacterIndex* characterIndices,
- const Length* charactersPerGlyph,
+ void SetGlyphs( const GlyphInfo* const glyphs,
+ const CharacterIndex* const characterIndices,
+ const Length* const charactersPerGlyph,
Length numberOfGlyphs );
/**
* @param[in] glyphPositions An array of visual positions for each glyph.
* @param[in] numberOfGlyphs The number of positions.
*/
- void SetGlyphPositions( const Vector2* glyphPositions,
+ void SetGlyphPositions( const Vector2* const glyphPositions,
Length numberOfGlyphs );
/**