#endif
const float MAX_FLOAT = std::numeric_limits<float>::max();
-const bool RTL = true;
+const CharacterDirection LTR = false;
+const CharacterDirection RTL = !LTR;
const float LINE_SPACING= 0.f;
inline bool isEmptyLineAtLast( const Vector<LineRun>& lines, const Vector<LineRun>::Iterator& line )
DALI_LOG_INFO( gLogFilter, Debug::Verbose, "-->GetLineLayoutForBox\n" );
DALI_LOG_INFO( gLogFilter, Debug::Verbose, " initial glyph index : %d\n", lineLayout.glyphIndex );
+ const Character* const textBuffer = parameters.textModel->mLogicalModel->mText.Begin();
+ const Length* const charactersPerGlyphBuffer = parameters.textModel->mVisualModel->mCharactersPerGlyph.Begin();
+ const GlyphInfo* const glyphsBuffer = parameters.textModel->mVisualModel->mGlyphs.Begin();
+ const CharacterIndex* const glyphsToCharactersBuffer = parameters.textModel->mVisualModel->mGlyphsToCharacters.Begin();
+ const LineBreakInfo* const lineBreakInfoBuffer = parameters.textModel->mLogicalModel->mLineBreakInfo.Begin();
+
+ const bool hasBidiParagraphs = !parameters.textModel->mLogicalModel->mBidirectionalParagraphInfo.Empty();
+ const CharacterDirection* const characterDirectionBuffer = hasBidiParagraphs ? parameters.textModel->mLogicalModel->mCharacterDirections.Begin() : nullptr;
+
+ const float outlineWidth = static_cast<float>( parameters.textModel->GetOutlineWidth() );
+ const Length totalNumberOfGlyphs = parameters.textModel->mVisualModel->mGlyphs.Count();
+
const bool isMultiline = mLayout == MULTI_LINE_BOX;
- const bool isWordLaidOut = parameters.lineWrapMode == Text::LineWrap::WORD;
+ const bool isWordLaidOut = parameters.textModel->mLineWrapMode == Text::LineWrap::WORD;
// The last glyph to be laid-out.
const GlyphIndex lastGlyphOfParagraphPlusOne = parameters.startGlyphIndex + parameters.numberOfGlyphs;
// Check whether the first glyph comes from a character that is shaped in multiple glyphs.
const Length numberOfGLyphsInGroup = GetNumberOfGlyphsOfGroup( lineLayout.glyphIndex,
lastGlyphOfParagraphPlusOne,
- parameters.charactersPerGlyphBuffer );
+ charactersPerGlyphBuffer );
GlyphMetrics glyphMetrics;
GetGlyphsMetrics( lineLayout.glyphIndex,
numberOfGLyphsInGroup,
glyphMetrics,
- parameters.glyphsBuffer,
+ glyphsBuffer,
mMetrics );
// Set the direction of the first character of the line.
- lineLayout.characterIndex = *( parameters.glyphsToCharactersBuffer + lineLayout.glyphIndex );
+ lineLayout.characterIndex = *( glyphsToCharactersBuffer + lineLayout.glyphIndex );
// Stores temporary line layout which has not been added to the final line layout.
LineLayout tmpLineLayout;
// The initial start point is zero. However it needs a correction according the 'x' bearing of the first glyph.
// i.e. if the bearing of the first glyph is negative it may exceed the boundaries of the text area.
// It needs to add as well space for the cursor if the text is in edit mode and extra space in case the text is outlined.
- tmpLineLayout.penX = -glyphMetrics.xBearing + mCursorWidth + parameters.outlineWidth;
+ tmpLineLayout.penX = -glyphMetrics.xBearing + mCursorWidth + outlineWidth;
// Initialize the advance of the previous glyph.
tmpLineLayout.previousAdvance = 0.f;
// Check whether this glyph comes from a character that is shaped in multiple glyphs.
const Length numberOfGLyphsInGroup = GetNumberOfGlyphsOfGroup( glyphIndex,
lastGlyphOfParagraphPlusOne,
- parameters.charactersPerGlyphBuffer );
+ charactersPerGlyphBuffer );
GlyphMetrics glyphMetrics;
GetGlyphsMetrics( glyphIndex,
numberOfGLyphsInGroup,
glyphMetrics,
- parameters.glyphsBuffer,
+ glyphsBuffer,
mMetrics );
- const bool isLastGlyph = glyphIndex + numberOfGLyphsInGroup == parameters.totalNumberOfGlyphs;
+ const bool isLastGlyph = glyphIndex + numberOfGLyphsInGroup == totalNumberOfGlyphs;
// Check if the font of the current glyph is the same of the previous one.
// If it's different the ascender and descender need to be updated.
// Get the character indices for the current glyph. The last character index is needed
// because there are glyphs formed by more than one character but their break info is
// given only for the last character.
- const Length charactersPerGlyph = *( parameters.charactersPerGlyphBuffer + glyphIndex + numberOfGLyphsInGroup - 1u );
+ const Length charactersPerGlyph = *( charactersPerGlyphBuffer + glyphIndex + numberOfGLyphsInGroup - 1u );
const bool hasCharacters = charactersPerGlyph > 0u;
- const CharacterIndex characterFirstIndex = *( parameters.glyphsToCharactersBuffer + glyphIndex );
+ const CharacterIndex characterFirstIndex = *( glyphsToCharactersBuffer + glyphIndex );
const CharacterIndex characterLastIndex = characterFirstIndex + ( hasCharacters ? charactersPerGlyph - 1u : 0u );
// Get the line break info for the current character.
- const LineBreakInfo lineBreakInfo = hasCharacters ? *( parameters.lineBreakInfoBuffer + characterLastIndex ) : TextAbstraction::LINE_NO_BREAK;
+ const LineBreakInfo lineBreakInfo = hasCharacters ? *( lineBreakInfoBuffer + characterLastIndex ) : TextAbstraction::LINE_NO_BREAK;
// Increase the number of characters.
tmpLineLayout.numberOfCharacters += charactersPerGlyph;
tmpLineLayout.numberOfGlyphs += numberOfGLyphsInGroup;
// Check whether is a white space.
- const Character character = *( parameters.textBuffer + characterFirstIndex );
+ const Character character = *( textBuffer + characterFirstIndex );
const bool isWhiteSpace = TextAbstraction::IsWhiteSpace( character );
// Calculate the length of the line.
// Set the next paragraph's direction.
if( !isLastGlyph &&
- ( NULL != parameters.characterDirectionBuffer ) )
+ ( nullptr != characterDirectionBuffer ) )
{
- paragraphDirection = *( parameters.characterDirectionBuffer + 1u + characterLastIndex );
+ paragraphDirection = *( characterDirectionBuffer + 1u + characterLastIndex );
}
DALI_LOG_INFO( gLogFilter, Debug::Verbose, " Must break\n" );
Length& linesCapacity,
bool updateCurrentBuffer )
{
- LineRun* linesBuffer = NULL;
+ LineRun* linesBuffer = nullptr;
// Reserve more space for the next lines.
linesCapacity *= 2u;
if( updateCurrentBuffer )
// The last line needs to be completely filled with characters.
// Part of a word may be used.
- LineRun* lineRun = NULL;
+ LineRun* lineRun = nullptr;
LineLayout ellipsisLayout;
if( 0u != numberOfLines )
{
lineRun->extraLength = std::ceil( ellipsisLayout.wsLengthEndOfLine );
lineRun->ascender = ellipsisLayout.ascender;
lineRun->descender = ellipsisLayout.descender;
- lineRun->direction = !RTL;
+ lineRun->direction = LTR;
lineRun->ellipsis = true;
layoutSize.width = layoutParameters.boundingBox.width;
layoutSize.height += ( lineRun->ascender + -lineRun->descender ) + lineRun->lineSpacing;
}
- SetGlyphPositions( layoutParameters.glyphsBuffer + lineRun->glyphRun.glyphIndex,
+ const GlyphInfo* const glyphsBuffer = layoutParameters.textModel->mVisualModel->mGlyphs.Begin();
+ const float outlineWidth = static_cast<float>( layoutParameters.textModel->GetOutlineWidth() );
+
+ SetGlyphPositions( glyphsBuffer + lineRun->glyphRun.glyphIndex,
ellipsisLayout.numberOfGlyphs,
- layoutParameters.outlineWidth,
+ outlineWidth,
layoutParameters.interGlyphExtraAdvance,
glyphPositionsBuffer + lineRun->glyphRun.glyphIndex - layoutParameters.startGlyphIndex );
}
lineRun.ascender = layout.ascender;
lineRun.descender = layout.descender;
- lineRun.direction = !RTL;
+ lineRun.direction = LTR;
lineRun.ellipsis = false;
// Update the actual size.
LineRun* linesBuffer,
Length& numberOfLines )
{
+ const Vector<GlyphInfo>& glyphs = layoutParameters.textModel->mVisualModel->mGlyphs;
+
// Need to add a new line with no characters but with height to increase the layoutSize.height
- const GlyphInfo& glyphInfo = *( layoutParameters.glyphsBuffer + layoutParameters.totalNumberOfGlyphs - 1u );
+ const GlyphInfo& glyphInfo = glyphs[glyphs.Count() - 1u];
Text::FontMetrics fontMetrics;
if( 0u != glyphInfo.fontId )
lineRun.descender = fontMetrics.descender;
lineRun.extraLength = 0.f;
lineRun.alignmentOffset = 0.f;
- lineRun.direction = !RTL;
+ lineRun.direction = LTR;
lineRun.ellipsis = false;
lineRun.lineSpacing = mDefaultLineSpacing;
}
const GlyphIndex lastGlyphPlusOne = layoutParameters.startGlyphIndex + layoutParameters.numberOfGlyphs;
+ const Length totalNumberOfGlyphs = layoutParameters.textModel->mVisualModel->mGlyphs.Count();
// In a previous layout, an extra line with no characters may have been added if the text ended with a new paragraph character.
// This extra line needs to be removed.
Vector<LineRun>::Iterator lastLine = lines.End() - 1u;
if( ( 0u == lastLine->characterRun.numberOfCharacters ) &&
- ( lastGlyphPlusOne == layoutParameters.totalNumberOfGlyphs ) )
+ ( lastGlyphPlusOne == totalNumberOfGlyphs ) )
{
lines.Remove( lastLine );
}
}
+ // Retrieve BiDi info.
+ const bool hasBidiParagraphs = !layoutParameters.textModel->mLogicalModel->mBidirectionalParagraphInfo.Empty();
+
+ const CharacterDirection* const characterDirectionBuffer = hasBidiParagraphs ? layoutParameters.textModel->mLogicalModel->mCharacterDirections.Begin() : nullptr;
+
// Set the first paragraph's direction.
- CharacterDirection paragraphDirection = ( NULL != layoutParameters.characterDirectionBuffer ) ? *layoutParameters.characterDirectionBuffer : !RTL;
+ CharacterDirection paragraphDirection = ( nullptr != characterDirectionBuffer ) ? *characterDirectionBuffer : LTR;
// Whether the layout is being updated or set from scratch.
- const bool updateCurrentBuffer = layoutParameters.numberOfGlyphs < layoutParameters.totalNumberOfGlyphs;
+ const bool updateCurrentBuffer = layoutParameters.numberOfGlyphs < totalNumberOfGlyphs;
- Vector2* glyphPositionsBuffer = NULL;
+ Vector2* glyphPositionsBuffer = nullptr;
Vector<Vector2> newGlyphPositions;
- LineRun* linesBuffer = NULL;
+ LineRun* linesBuffer = nullptr;
Vector<LineRun> newLines;
// Estimate the number of lines.
linesBuffer = lines.Begin();
}
+
+ const GlyphInfo* const glyphsBuffer = layoutParameters.textModel->mVisualModel->mGlyphs.Begin();
+ const float outlineWidth = static_cast<float>( layoutParameters.textModel->GetOutlineWidth() );
+
float penY = CalculateLineOffset( lines,
layoutParameters.startLineIndex );
+
for( GlyphIndex index = layoutParameters.startGlyphIndex; index < lastGlyphPlusOne; )
{
CharacterDirection currentParagraphDirection = paragraphDirection;
else
{
// Whether the last line has been laid-out.
- const bool isLastLine = index + layout.numberOfGlyphs == layoutParameters.totalNumberOfGlyphs;
+ const bool isLastLine = index + layout.numberOfGlyphs == totalNumberOfGlyphs;
if( numberOfLines == linesCapacity )
{
const GlyphIndex nextIndex = index + layout.numberOfGlyphs;
- if( ( nextIndex == layoutParameters.totalNumberOfGlyphs ) &&
+ if( ( nextIndex == totalNumberOfGlyphs ) &&
layoutParameters.isLastNewParagraph &&
( mLayout == MULTI_LINE_BOX ) )
{
} // whether to add a last line.
// Sets the positions of the glyphs.
- SetGlyphPositions( layoutParameters.glyphsBuffer + index,
+ SetGlyphPositions( glyphsBuffer + index,
layout.numberOfGlyphs,
- layoutParameters.outlineWidth,
+ outlineWidth,
layoutParameters.interGlyphExtraAdvance,
glyphPositionsBuffer + index - layoutParameters.startGlyphIndex );
glyphPositions.Insert( glyphPositions.Begin() + layoutParameters.startGlyphIndex,
newGlyphPositions.Begin(),
newGlyphPositions.End() );
- glyphPositions.Resize( layoutParameters.totalNumberOfGlyphs );
+ glyphPositions.Resize( totalNumberOfGlyphs );
newLines.Resize( numberOfLines );
Length numberOfCharacters,
Vector<Vector2>& glyphPositions )
{
+ const GlyphInfo* const glyphsBuffer = layoutParameters.textModel->mVisualModel->mGlyphs.Begin();
+ const GlyphIndex* const charactersToGlyphsBuffer = layoutParameters.textModel->mVisualModel->mCharactersToGlyph.Begin();
+ const Length* const glyphsPerCharacterBuffer = layoutParameters.textModel->mVisualModel->mGlyphsPerCharacter.Begin();
+ const float outlineWidth = static_cast<float>( layoutParameters.textModel->GetOutlineWidth() );
+
const CharacterIndex lastCharacterIndex = startIndex + numberOfCharacters;
// Traverses the paragraphs with right to left characters.
}
const CharacterIndex characterVisualIndex = bidiLine.characterRun.characterIndex + *bidiLine.visualToLogicalMap;
- const GlyphInfo& glyph = *( layoutParameters.glyphsBuffer + *( layoutParameters.charactersToGlyphsBuffer + characterVisualIndex ) );
+ const GlyphInfo& glyph = *( glyphsBuffer + *( charactersToGlyphsBuffer + characterVisualIndex ) );
- float penX = -glyph.xBearing + layoutParameters.outlineWidth + mCursorWidth;
+ float penX = -glyph.xBearing + outlineWidth + mCursorWidth;
Vector2* glyphPositionsBuffer = glyphPositions.Begin();
const CharacterIndex characterVisualIndex = bidiLine.characterRun.characterIndex + *( bidiLine.visualToLogicalMap + characterLogicalIndex );
// Get the number of glyphs of the character.
- const Length numberOfGlyphs = *( layoutParameters.glyphsPerCharacterBuffer + characterVisualIndex );
+ const Length numberOfGlyphs = *( glyphsPerCharacterBuffer + characterVisualIndex );
for( GlyphIndex index = 0u; index < numberOfGlyphs; ++index )
{
// Convert the character in the visual order into the glyph in the visual order.
- const GlyphIndex glyphIndex = *( layoutParameters.charactersToGlyphsBuffer + characterVisualIndex ) + index;
+ const GlyphIndex glyphIndex = *( charactersToGlyphsBuffer + characterVisualIndex ) + index;
- DALI_ASSERT_DEBUG( 0u <= glyphIndex && glyphIndex < layoutParameters.totalNumberOfGlyphs );
+ DALI_ASSERT_DEBUG( 0u <= glyphIndex && glyphIndex < layoutParameters.textModel->mVisualModel->mGlyphs.Count() );
- const GlyphInfo& glyph = *( layoutParameters.glyphsBuffer + glyphIndex );
+ const GlyphInfo& glyph = *( glyphsBuffer + glyphIndex );
Vector2& position = *( glyphPositionsBuffer + glyphIndex );
position.x = std::round( penX + glyph.xBearing );
line.descender = 0.f;
line.extraLength = 0.f;
line.alignmentOffset = 0.f;
- line.direction = !RTL;
+ line.direction = LTR;
line.ellipsis = false;
line.lineSpacing = mDefaultLineSpacing;
}
};
Engine::Engine()
-: mImpl( NULL )
+: mImpl( nullptr )
{
mImpl = new Engine::Impl();
}