#include <dali/devel-api/text-abstraction/font-client.h>
// INTERNAL INCLUDES
-#include <dali-toolkit/internal/text/layouts/layout-parameters.h>
#include <dali-toolkit/internal/text/bidirectional-line-info-run.h>
+#include <dali-toolkit/internal/text/glyph-metrics-helper.h>
+#include <dali-toolkit/internal/text/layouts/layout-parameters.h>
namespace Dali
{
const float MAX_FLOAT = std::numeric_limits<float>::max();
const bool RTL = true;
const float CURSOR_WIDTH = 1.f;
+const float LINE_SPACING= 0.f;
} //namespace
mHorizontalAlignment( LayoutEngine::HORIZONTAL_ALIGN_BEGIN ),
mVerticalAlignment( LayoutEngine::VERTICAL_ALIGN_TOP ),
mCursorWidth( CURSOR_WIDTH ),
+ mDefaultLineSpacing( LINE_SPACING ),
mEllipsisEnabled( false )
{
}
LineLayout tmpLineLayout;
const bool isMultiline = mLayout == MULTI_LINE_BOX;
- const GlyphIndex lastGlyphIndex = parameters.totalNumberOfGlyphs - 1u;
+
+ // The last glyph to be laid-out.
+ const GlyphIndex lastGlyphOfParagraphPlusOne = parameters.startGlyphIndex + parameters.numberOfGlyphs;
// If the first glyph has a negative bearing its absolute value needs to be added to the line length.
// In the case the line starts with a right to left character, if the width is longer than the advance,
// the difference needs to be added to the line length.
- const GlyphInfo& glyphInfo = *( parameters.glyphsBuffer + lineLayout.glyphIndex );
+
+ // Check whether the first glyph comes from a character that is shaped in multiple glyphs.
+ const Length numberOfGLyphsInGroup = GetNumberOfGlyphsOfGroup( lineLayout.glyphIndex,
+ lastGlyphOfParagraphPlusOne,
+ parameters.charactersPerGlyphBuffer );
+
+ GlyphMetrics glyphMetrics;
+ GetGlyphsMetrics( lineLayout.glyphIndex,
+ numberOfGLyphsInGroup,
+ glyphMetrics,
+ parameters.glyphsBuffer,
+ mMetrics );
// Set the direction of the first character of the line.
lineLayout.characterIndex = *( parameters.glyphsToCharactersBuffer + lineLayout.glyphIndex );
const CharacterDirection firstCharacterDirection = ( NULL == parameters.characterDirectionBuffer ) ? false : *( parameters.characterDirectionBuffer + lineLayout.characterIndex );
CharacterDirection previousCharacterDirection = firstCharacterDirection;
- const float extraWidth = glyphInfo.xBearing + glyphInfo.width - glyphInfo.advance;
+ const float extraWidth = glyphMetrics.xBearing + glyphMetrics.width - glyphMetrics.advance;
float tmpExtraWidth = ( 0.f < extraWidth ) ? extraWidth : 0.f;
- float tmpExtraBearing = ( 0.f > glyphInfo.xBearing ) ? -glyphInfo.xBearing : 0.f;
+ float tmpExtraBearing = ( 0.f > glyphMetrics.xBearing ) ? -glyphMetrics.xBearing : 0.f;
tmpLineLayout.length += mCursorWidth; // Added to give some space to the cursor.
// Calculate the line height if there is no characters.
- FontId lastFontId = glyphInfo.fontId;
+ FontId lastFontId = glyphMetrics.fontId;
UpdateLineHeight( lastFontId, tmpLineLayout );
bool oneWordLaidOut = false;
- const GlyphIndex lastGlyphPlusOne = parameters.startGlyphIndex + parameters.numberOfGlyphs;
for( GlyphIndex glyphIndex = lineLayout.glyphIndex;
- glyphIndex < lastGlyphPlusOne;
- ++glyphIndex )
+ glyphIndex < lastGlyphOfParagraphPlusOne; )
{
DALI_LOG_INFO( gLogFilter, Debug::Verbose, " glyph index : %d\n", glyphIndex );
- const bool isLastGlyph = glyphIndex == lastGlyphIndex;
- // Get the glyph info.
- const GlyphInfo& glyphInfo = *( parameters.glyphsBuffer + glyphIndex );
+ // Check whether this glyph comes from a character that is shaped in multiple glyphs.
+ const Length numberOfGLyphsInGroup = GetNumberOfGlyphsOfGroup( glyphIndex,
+ lastGlyphOfParagraphPlusOne,
+ parameters.charactersPerGlyphBuffer );
+
+ GlyphMetrics glyphMetrics;
+ GetGlyphsMetrics( glyphIndex,
+ numberOfGLyphsInGroup,
+ glyphMetrics,
+ parameters.glyphsBuffer,
+ mMetrics );
+
+ const bool isLastGlyph = glyphIndex + numberOfGLyphsInGroup == parameters.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.
- if( lastFontId != glyphInfo.fontId )
+ if( lastFontId != glyphMetrics.fontId )
{
- UpdateLineHeight( glyphInfo.fontId, tmpLineLayout );
- lastFontId = glyphInfo.fontId;
+ UpdateLineHeight( glyphMetrics.fontId, tmpLineLayout );
+ lastFontId = glyphMetrics.fontId;
}
// 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 );
+ const Length charactersPerGlyph = *( parameters.charactersPerGlyphBuffer + glyphIndex + numberOfGLyphsInGroup - 1u );
+ const bool hasCharacters = charactersPerGlyph > 0u;
const CharacterIndex characterFirstIndex = *( parameters.glyphsToCharactersBuffer + glyphIndex );
- const CharacterIndex characterLastIndex = characterFirstIndex + ( ( 1u > charactersPerGlyph ) ? 0u : charactersPerGlyph - 1u );
+ const CharacterIndex characterLastIndex = characterFirstIndex + ( hasCharacters ? charactersPerGlyph - 1u : 0u );
// Get the line break info for the current character.
- const LineBreakInfo lineBreakInfo = *( parameters.lineBreakInfoBuffer + characterLastIndex );
+ const LineBreakInfo lineBreakInfo = hasCharacters ? *( parameters.lineBreakInfoBuffer + characterLastIndex ) : TextAbstraction::LINE_NO_BREAK;
// Get the word break info for the current character.
const WordBreakInfo wordBreakInfo = *( parameters.wordBreakInfoBuffer + characterLastIndex );
tmpLineLayout.numberOfCharacters += charactersPerGlyph;
// Increase the number of glyphs.
- tmpLineLayout.numberOfGlyphs++;
+ tmpLineLayout.numberOfGlyphs += numberOfGLyphsInGroup;
// Check whether is a white space.
const Character character = *( parameters.textBuffer + characterFirstIndex );
if( isWhiteSpace )
{
// Add the length to the length of white spaces at the end of the line.
- tmpLineLayout.wsLengthEndOfLine += glyphInfo.advance; // The advance is used as the width is always zero for the white spaces.
+ tmpLineLayout.wsLengthEndOfLine += glyphMetrics.advance; // The advance is used as the width is always zero for the white spaces.
}
else
{
// Add as well any previous white space length.
- tmpLineLayout.length += tmpLineLayout.wsLengthEndOfLine + glyphInfo.advance;
+ tmpLineLayout.length += tmpLineLayout.wsLengthEndOfLine + glyphMetrics.advance;
// An extra space may be added to the line for the first and last glyph of the line.
// If the bearing of the first glyph is negative, its positive value needs to be added.
// | Rll|
//
- tmpExtraBearing = ( 0.f > glyphInfo.xBearing ) ? -glyphInfo.xBearing : 0.f;
+ tmpExtraBearing = ( 0.f > glyphMetrics.xBearing ) ? -glyphMetrics.xBearing : 0.f;
}
else // LTR
{
// |rrL |
//
- const float extraWidth = glyphInfo.xBearing + glyphInfo.width - glyphInfo.advance;
+ const float extraWidth = glyphMetrics.xBearing + glyphMetrics.width - glyphMetrics.advance;
tmpExtraWidth = ( 0.f < extraWidth ) ? extraWidth : 0.f;
}
}
// -->
// |lllR |
- const float extraWidth = glyphInfo.xBearing + glyphInfo.width - glyphInfo.advance;
+ const float extraWidth = glyphMetrics.xBearing + glyphMetrics.width - glyphMetrics.advance;
tmpExtraWidth = ( 0.f < extraWidth ) ? extraWidth : 0.f;
}
else // LTR
// <--
// | Lrrrr|
- tmpExtraBearing = ( 0.f > glyphInfo.xBearing ) ? -glyphInfo.xBearing : 0.f;
+ tmpExtraBearing = ( 0.f > glyphMetrics.xBearing ) ? -glyphMetrics.xBearing : 0.f;
}
}
else if( characterDirection == firstCharacterDirection )
// |llllllrr|
// |Rr |
- tmpExtraBearing = ( 0.f > glyphInfo.xBearing ) ? -glyphInfo.xBearing : 0.f;
+ tmpExtraBearing = ( 0.f > glyphMetrics.xBearing ) ? -glyphMetrics.xBearing : 0.f;
}
else // LTR
{
// |llllrrrr|
// | llL|
- const float extraWidth = glyphInfo.xBearing + glyphInfo.width - glyphInfo.advance;
+ const float extraWidth = glyphMetrics.xBearing + glyphMetrics.width - glyphMetrics.advance;
tmpExtraWidth = ( 0.f < extraWidth ) ? extraWidth : 0.f;
}
}
if( tmpLineLayout.numberOfGlyphs > 0u )
{
tmpLineLayout.numberOfCharacters -= charactersPerGlyph;
- --tmpLineLayout.numberOfGlyphs;
+ tmpLineLayout.numberOfGlyphs -= numberOfGLyphsInGroup;
tmpLineLayout.length = previousTmpLineLength;
tmpExtraBearing = previousTmpExtraBearing;
tmpExtraWidth = previousTmpExtraWidth;
DALI_LOG_INFO( gLogFilter, Debug::Verbose, " Must break\n" );
DALI_LOG_INFO( gLogFilter, Debug::Verbose, "<--GetLineLayoutForBox\n" );
+
return;
}
}
previousCharacterDirection = characterDirection;
+ glyphIndex += numberOfGLyphsInGroup;
}
lineLayout.extraBearing = tmpExtraBearing;
{
// Need to add a new line with no characters but with height to increase the layoutSize.height
LineRun newLine;
+ Initialize( newLine );
lines.PushBack( newLine );
UpdateTextLayout( layoutParameters,
Vector<LineRun> newLines;
// Estimate the number of lines.
- Length linesCapacity = layoutParameters.estimatedNumberOfLines;
+ Length linesCapacity = std::max( 1u, layoutParameters.estimatedNumberOfLines );
Length numberOfLines = 0u;
if( updateCurrentBuffer )
}
}
+ void Initialize( LineRun& line )
+ {
+ line.glyphRun.glyphIndex = 0u;
+ line.glyphRun.numberOfGlyphs = 0u;
+ line.characterRun.characterIndex = 0u;
+ line.characterRun.numberOfCharacters = 0u;
+ line.width = 0.f;
+ line.ascender = 0.f;
+ line.descender = 0.f;
+ line.extraLength = 0.f;
+ line.alignmentOffset = 0.f;
+ line.direction = !RTL;
+ line.ellipsis = false;
+ }
+
LayoutEngine::Layout mLayout;
LayoutEngine::HorizontalAlignment mHorizontalAlignment;
LayoutEngine::VerticalAlignment mVerticalAlignment;
float mCursorWidth;
+ float mDefaultLineSpacing;
IntrusivePtr<Metrics> mMetrics;
LayoutEngine::Layout LayoutEngine::GetLayout() const
{
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "GetLayout[%d]\n", mImpl->mLayout);
return mImpl->mLayout;
}
void LayoutEngine::SetTextEllipsisEnabled( bool enabled )
{
+ DALI_LOG_INFO( gLogFilter, Debug::General, "-->LayoutEngine::SetTextEllipsisEnabled[%s]\n", (enabled)?"true":"false" );
mImpl->mEllipsisEnabled = enabled;
}
lines );
}
+void LayoutEngine::SetDefaultLineSpacing( float lineSpacing )
+{
+ mImpl->mDefaultLineSpacing = lineSpacing;
+}
+
+float LayoutEngine::GetDefaultLineSpacing() const
+{
+ return mImpl->mDefaultLineSpacing;
+}
+
} // namespace Text
} // namespace Toolkit