projects
/
platform
/
core
/
uifw
/
dali-toolkit.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Merge "Add bidirectional text tct." into devel/master
[platform/core/uifw/dali-toolkit.git]
/
dali-toolkit
/
internal
/
text
/
layouts
/
layout-engine.cpp
diff --git
a/dali-toolkit/internal/text/layouts/layout-engine.cpp
b/dali-toolkit/internal/text/layouts/layout-engine.cpp
index
148ff58
..
4ace75b
100644
(file)
--- a/
dali-toolkit/internal/text/layouts/layout-engine.cpp
+++ b/
dali-toolkit/internal/text/layouts/layout-engine.cpp
@@
-1,5
+1,5
@@
/*
/*
- * Copyright (c) 201
5
Samsung Electronics Co., Ltd.
+ * Copyright (c) 201
7
Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@
-70,7
+70,8
@@
struct LineLayout
extraWidth( 0.f ),
wsLengthEndOfLine( 0.f ),
ascender( 0.f ),
extraWidth( 0.f ),
wsLengthEndOfLine( 0.f ),
ascender( 0.f ),
- descender( MAX_FLOAT )
+ descender( MAX_FLOAT ),
+ lineSpacing( 0.f )
{}
~LineLayout()
{}
~LineLayout()
@@
-100,6
+101,7
@@
struct LineLayout
float wsLengthEndOfLine; ///< The length of the white spaces at the end of the line.
float ascender; ///< The maximum ascender of all fonts in the line.
float descender; ///< The minimum descender of all fonts in the line.
float wsLengthEndOfLine; ///< The length of the white spaces at the end of the line.
float ascender; ///< The maximum ascender of all fonts in the line.
float descender; ///< The minimum descender of all fonts in the line.
+ float lineSpacing; ///< The line spacing
};
struct Engine::Impl
};
struct Engine::Impl
@@
-107,7
+109,8
@@
struct Engine::Impl
Impl()
: mLayout( Layout::Engine::SINGLE_LINE_BOX ),
mCursorWidth( CURSOR_WIDTH ),
Impl()
: mLayout( Layout::Engine::SINGLE_LINE_BOX ),
mCursorWidth( CURSOR_WIDTH ),
- mDefaultLineSpacing( LINE_SPACING )
+ mDefaultLineSpacing( LINE_SPACING ),
+ mPreviousCharacterExtraWidth( 0.0f )
{
}
{
}
@@
-133,6
+136,9
@@
struct Engine::Impl
{
lineLayout.descender = fontMetrics.descender;
}
{
lineLayout.descender = fontMetrics.descender;
}
+
+ // set the line spacing
+ lineLayout.lineSpacing = mDefaultLineSpacing;
}
/**
}
/**
@@
-198,6
+204,7
@@
struct Engine::Impl
LineLayout tmpLineLayout;
const bool isMultiline = mLayout == MULTI_LINE_BOX;
LineLayout tmpLineLayout;
const bool isMultiline = mLayout == MULTI_LINE_BOX;
+ const bool isWordLaidOut = parameters.lineWrapMode == Text::LineWrap::WORD;
// The last glyph to be laid-out.
const GlyphIndex lastGlyphOfParagraphPlusOne = parameters.startGlyphIndex + parameters.numberOfGlyphs;
// The last glyph to be laid-out.
const GlyphIndex lastGlyphOfParagraphPlusOne = parameters.startGlyphIndex + parameters.numberOfGlyphs;
@@
-274,9
+281,6
@@
struct Engine::Impl
// Get the line break info for the current character.
const LineBreakInfo lineBreakInfo = hasCharacters ? *( parameters.lineBreakInfoBuffer + characterLastIndex ) : TextAbstraction::LINE_NO_BREAK;
// Get the line break info for the current character.
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 );
-
// Increase the number of characters.
tmpLineLayout.numberOfCharacters += charactersPerGlyph;
// Increase the number of characters.
tmpLineLayout.numberOfCharacters += charactersPerGlyph;
@@
-339,6
+343,7
@@
struct Engine::Impl
const float extraWidth = glyphMetrics.xBearing + glyphMetrics.width - glyphMetrics.advance;
tmpExtraWidth = ( 0.f < extraWidth ) ? extraWidth : 0.f;
const float extraWidth = glyphMetrics.xBearing + glyphMetrics.width - glyphMetrics.advance;
tmpExtraWidth = ( 0.f < extraWidth ) ? extraWidth : 0.f;
+ tmpExtraWidth = std::max( mPreviousCharacterExtraWidth - glyphMetrics.advance, tmpExtraWidth );
}
}
else
}
}
else
@@
-352,6
+357,7
@@
struct Engine::Impl
const float extraWidth = glyphMetrics.xBearing + glyphMetrics.width - glyphMetrics.advance;
tmpExtraWidth = ( 0.f < extraWidth ) ? extraWidth : 0.f;
const float extraWidth = glyphMetrics.xBearing + glyphMetrics.width - glyphMetrics.advance;
tmpExtraWidth = ( 0.f < extraWidth ) ? extraWidth : 0.f;
+ tmpExtraWidth = std::max( mPreviousCharacterExtraWidth - glyphMetrics.advance, tmpExtraWidth );
}
else // LTR
{
}
else // LTR
{
@@
-379,6
+385,7
@@
struct Engine::Impl
const float extraWidth = glyphMetrics.xBearing + glyphMetrics.width - glyphMetrics.advance;
tmpExtraWidth = ( 0.f < extraWidth ) ? extraWidth : 0.f;
const float extraWidth = glyphMetrics.xBearing + glyphMetrics.width - glyphMetrics.advance;
tmpExtraWidth = ( 0.f < extraWidth ) ? extraWidth : 0.f;
+ tmpExtraWidth = std::max( mPreviousCharacterExtraWidth - glyphMetrics.advance, tmpExtraWidth );
}
}
}
}
}
}
@@
-387,6
+394,9
@@
struct Engine::Impl
tmpLineLayout.wsLengthEndOfLine = 0.f;
}
tmpLineLayout.wsLengthEndOfLine = 0.f;
}
+ // Save the current extra width to compare with the next one
+ mPreviousCharacterExtraWidth = tmpExtraWidth;
+
// Check if the accumulated length fits in the width of the box.
if( ( completelyFill || isMultiline ) && !isWhiteSpace &&
( tmpExtraBearing + lineLayout.length + lineLayout.wsLengthEndOfLine + tmpLineLayout.length + tmpExtraWidth > parameters.boundingBox.width ) )
// Check if the accumulated length fits in the width of the box.
if( ( completelyFill || isMultiline ) && !isWhiteSpace &&
( tmpExtraBearing + lineLayout.length + lineLayout.wsLengthEndOfLine + tmpLineLayout.length + tmpExtraWidth > parameters.boundingBox.width ) )
@@
-445,9
+455,9
@@
struct Engine::Impl
}
if( isMultiline &&
}
if( isMultiline &&
- ( TextAbstraction::
WORD_BREAK == word
BreakInfo ) )
+ ( TextAbstraction::
LINE_ALLOW_BREAK == line
BreakInfo ) )
{
{
- oneWordLaidOut =
true
;
+ oneWordLaidOut =
isWordLaidOut
;
DALI_LOG_INFO( gLogFilter, Debug::Verbose, " One word laid-out\n" );
// Current glyph is the last one of the current word.
DALI_LOG_INFO( gLogFilter, Debug::Verbose, " One word laid-out\n" );
// Current glyph is the last one of the current word.
@@
-469,6
+479,7
@@
struct Engine::Impl
void SetGlyphPositions( const GlyphInfo* const glyphsBuffer,
Length numberOfGlyphs,
void SetGlyphPositions( const GlyphInfo* const glyphsBuffer,
Length numberOfGlyphs,
+ float outlineWidth,
Vector2* glyphPositionsBuffer )
{
// Traverse the glyphs and set the positions.
Vector2* glyphPositionsBuffer )
{
// Traverse the glyphs and set the positions.
@@
-478,7
+489,8
@@
struct Engine::Impl
// so the penX position needs to be moved to the right.
const GlyphInfo& glyph = *glyphsBuffer;
// 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;
+ float penX = ( 0.f > glyph.xBearing ) ? -glyph.xBearing + outlineWidth : outlineWidth;
+
for( GlyphIndex i = 0u; i < numberOfGlyphs; ++i )
{
for( GlyphIndex i = 0u; i < numberOfGlyphs; ++i )
{
@@
-565,7
+577,7
@@
struct Engine::Impl
// Get the last line and layout it again with the 'completelyFill' flag to true.
lineRun = linesBuffer + ( numberOfLines - 1u );
// Get the last line and layout it again with the 'completelyFill' flag to true.
lineRun = linesBuffer + ( numberOfLines - 1u );
- penY -= layout.ascender - lineRun->descender;
+ penY -= layout.ascender - lineRun->descender
+ lineRun->lineSpacing
;
ellipsisLayout.glyphIndex = lineRun->glyphRun.glyphIndex;
}
ellipsisLayout.glyphIndex = lineRun->glyphRun.glyphIndex;
}
@@
-598,11
+610,12
@@
struct Engine::Impl
layoutSize.width = layoutParameters.boundingBox.width;
if( layoutSize.height < Math::MACHINE_EPSILON_1000 )
{
layoutSize.width = layoutParameters.boundingBox.width;
if( layoutSize.height < Math::MACHINE_EPSILON_1000 )
{
- layoutSize.height += ( lineRun->ascender + -lineRun->descender );
+ layoutSize.height += ( lineRun->ascender + -lineRun->descender )
+ lineRun->lineSpacing
;
}
SetGlyphPositions( layoutParameters.glyphsBuffer + lineRun->glyphRun.glyphIndex,
ellipsisLayout.numberOfGlyphs,
}
SetGlyphPositions( layoutParameters.glyphsBuffer + lineRun->glyphRun.glyphIndex,
ellipsisLayout.numberOfGlyphs,
+ layoutParameters.outlineWidth,
glyphPositionsBuffer + lineRun->glyphRun.glyphIndex - layoutParameters.startGlyphIndex );
}
glyphPositionsBuffer + lineRun->glyphRun.glyphIndex - layoutParameters.startGlyphIndex );
}
@@
-635,6
+648,8
@@
struct Engine::Impl
lineRun.glyphRun.numberOfGlyphs = layout.numberOfGlyphs;
lineRun.characterRun.characterIndex = layout.characterIndex;
lineRun.characterRun.numberOfCharacters = layout.numberOfCharacters;
lineRun.glyphRun.numberOfGlyphs = layout.numberOfGlyphs;
lineRun.characterRun.characterIndex = layout.characterIndex;
lineRun.characterRun.numberOfCharacters = layout.numberOfCharacters;
+ lineRun.lineSpacing = mDefaultLineSpacing;
+
if( isLastLine && !layoutParameters.isLastNewParagraph )
{
const float width = layout.extraBearing + layout.length + layout.extraWidth + layout.wsLengthEndOfLine;
if( isLastLine && !layoutParameters.isLastNewParagraph )
{
const float width = layout.extraBearing + layout.length + layout.extraWidth + layout.wsLengthEndOfLine;
@@
-665,7
+680,7
@@
struct Engine::Impl
layoutSize.width = lineRun.width;
}
layoutSize.width = lineRun.width;
}
- layoutSize.height += ( lineRun.ascender + -lineRun.descender );
+ layoutSize.height += ( lineRun.ascender + -lineRun.descender )
+ lineRun.lineSpacing
;
}
/**
}
/**
@@
-705,8
+720,9
@@
struct Engine::Impl
lineRun.alignmentOffset = 0.f;
lineRun.direction = !RTL;
lineRun.ellipsis = false;
lineRun.alignmentOffset = 0.f;
lineRun.direction = !RTL;
lineRun.ellipsis = false;
+ lineRun.lineSpacing = mDefaultLineSpacing;
- layoutSize.height += ( lineRun.ascender + -lineRun.descender );
+ layoutSize.height += ( lineRun.ascender + -lineRun.descender )
+ lineRun.lineSpacing
;
}
/**
}
/**
@@
-730,7
+746,7
@@
struct Engine::Impl
layoutSize.width = line.width;
}
layoutSize.width = line.width;
}
- layoutSize.height += ( line.ascender + -line.descender );
+ layoutSize.height += ( line.ascender + -line.descender )
+ line.lineSpacing
;
}
}
}
}
@@
-962,10
+978,11
@@
struct Engine::Impl
// Sets the positions of the glyphs.
SetGlyphPositions( layoutParameters.glyphsBuffer + index,
layout.numberOfGlyphs,
// Sets the positions of the glyphs.
SetGlyphPositions( layoutParameters.glyphsBuffer + index,
layout.numberOfGlyphs,
+ layoutParameters.outlineWidth,
glyphPositionsBuffer + index - layoutParameters.startGlyphIndex );
// Updates the vertical pen's position.
glyphPositionsBuffer + index - layoutParameters.startGlyphIndex );
// Updates the vertical pen's position.
- penY += -layout.descender;
+ penY += -layout.descender
+ layout.lineSpacing + mDefaultLineSpacing
;
// Increase the glyph index.
index = nextIndex;
// Increase the glyph index.
index = nextIndex;
@@
-1042,7
+1059,7
@@
struct Engine::Impl
const CharacterIndex characterVisualIndex = bidiLine.characterRun.characterIndex + *bidiLine.visualToLogicalMap;
const GlyphInfo& glyph = *( layoutParameters.glyphsBuffer + *( layoutParameters.charactersToGlyphsBuffer + characterVisualIndex ) );
const CharacterIndex characterVisualIndex = bidiLine.characterRun.characterIndex + *bidiLine.visualToLogicalMap;
const GlyphInfo& glyph = *( layoutParameters.glyphsBuffer + *( layoutParameters.charactersToGlyphsBuffer + characterVisualIndex ) );
- float penX = ( 0.f > glyph.xBearing ) ? -glyph.xBearing
: 0.f
;
+ float penX = ( 0.f > glyph.xBearing ) ? -glyph.xBearing
- layoutParameters.outlineWidth : -layoutParameters.outlineWidth
;
Vector2* glyphPositionsBuffer = glyphPositions.Begin();
Vector2* glyphPositionsBuffer = glyphPositions.Begin();
@@
-1077,11
+1094,13
@@
struct Engine::Impl
void Align( const Size& size,
CharacterIndex startIndex,
Length numberOfCharacters,
void Align( const Size& size,
CharacterIndex startIndex,
Length numberOfCharacters,
- HorizontalAlignment horizontalAlignment,
- Vector<LineRun>& lines )
+ Text::HorizontalAlignment::Type horizontalAlignment,
+ Vector<LineRun>& lines,
+ float& alignmentOffset )
{
const CharacterIndex lastCharacterPlusOne = startIndex + numberOfCharacters;
{
const CharacterIndex lastCharacterPlusOne = startIndex + numberOfCharacters;
+ alignmentOffset = MAX_FLOAT;
// Traverse all lines and align the glyphs.
for( Vector<LineRun>::Iterator it = lines.Begin(), endIt = lines.End();
it != endIt;
// Traverse all lines and align the glyphs.
for( Vector<LineRun>::Iterator it = lines.Begin(), endIt = lines.End();
it != endIt;
@@
-1106,36
+1125,39
@@
struct Engine::Impl
CalculateHorizontalAlignment( size.width,
horizontalAlignment,
line );
CalculateHorizontalAlignment( size.width,
horizontalAlignment,
line );
+
+ // Updates the alignment offset.
+ alignmentOffset = std::min( alignmentOffset, line.alignmentOffset );
}
}
void CalculateHorizontalAlignment( float boxWidth,
}
}
void CalculateHorizontalAlignment( float boxWidth,
- HorizontalAlignment horizontalAlignment,
+ HorizontalAlignment
::Type
horizontalAlignment,
LineRun& line )
{
line.alignmentOffset = 0.f;
const bool isRTL = RTL == line.direction;
float lineLength = line.width;
LineRun& line )
{
line.alignmentOffset = 0.f;
const bool isRTL = RTL == line.direction;
float lineLength = line.width;
- HorizontalAlignment alignment = horizontalAlignment;
+ HorizontalAlignment
::Type
alignment = horizontalAlignment;
if( isRTL )
{
// Swap the alignment type if the line is right to left.
switch( alignment )
{
if( isRTL )
{
// Swap the alignment type if the line is right to left.
switch( alignment )
{
- case H
ORIZONTAL_ALIGN_
BEGIN:
+ case H
orizontalAlignment::
BEGIN:
{
{
- alignment = H
ORIZONTAL_ALIGN_
END;
+ alignment = H
orizontalAlignment::
END;
break;
}
break;
}
- case H
ORIZONTAL_ALIGN_
CENTER:
+ case H
orizontalAlignment::
CENTER:
{
// Nothing to do.
break;
}
{
// Nothing to do.
break;
}
- case H
ORIZONTAL_ALIGN_
END:
+ case H
orizontalAlignment::
END:
{
{
- alignment = H
ORIZONTAL_ALIGN_
BEGIN;
+ alignment = H
orizontalAlignment::
BEGIN;
break;
}
}
break;
}
}
@@
-1144,7
+1166,7
@@
struct Engine::Impl
// Calculate the horizontal line offset.
switch( alignment )
{
// Calculate the horizontal line offset.
switch( alignment )
{
- case H
ORIZONTAL_ALIGN_
BEGIN:
+ case H
orizontalAlignment::
BEGIN:
{
line.alignmentOffset = 0.f;
{
line.alignmentOffset = 0.f;
@@
-1155,7
+1177,7
@@
struct Engine::Impl
}
break;
}
}
break;
}
- case H
ORIZONTAL_ALIGN_
CENTER:
+ case H
orizontalAlignment::
CENTER:
{
line.alignmentOffset = 0.5f * ( boxWidth - lineLength );
{
line.alignmentOffset = 0.5f * ( boxWidth - lineLength );
@@
-1167,7
+1189,7
@@
struct Engine::Impl
line.alignmentOffset = floorf( line.alignmentOffset ); // try to avoid pixel alignment.
break;
}
line.alignmentOffset = floorf( line.alignmentOffset ); // try to avoid pixel alignment.
break;
}
- case H
ORIZONTAL_ALIGN_
END:
+ case H
orizontalAlignment::
END:
{
if( isRTL )
{
{
if( isRTL )
{
@@
-1193,11
+1215,13
@@
struct Engine::Impl
line.alignmentOffset = 0.f;
line.direction = !RTL;
line.ellipsis = false;
line.alignmentOffset = 0.f;
line.direction = !RTL;
line.ellipsis = false;
+ line.lineSpacing = mDefaultLineSpacing;
}
Type mLayout;
float mCursorWidth;
float mDefaultLineSpacing;
}
Type mLayout;
float mCursorWidth;
float mDefaultLineSpacing;
+ float mPreviousCharacterExtraWidth;
IntrusivePtr<Metrics> mMetrics;
};
IntrusivePtr<Metrics> mMetrics;
};
@@
-1266,14
+1290,16
@@
void Engine::ReLayoutRightToLeftLines( const Parameters& layoutParameters,
void Engine::Align( const Size& size,
CharacterIndex startIndex,
Length numberOfCharacters,
void Engine::Align( const Size& size,
CharacterIndex startIndex,
Length numberOfCharacters,
- Layout::HorizontalAlignment horizontalAlignment,
- Vector<LineRun>& lines )
+ Text::HorizontalAlignment::Type horizontalAlignment,
+ Vector<LineRun>& lines,
+ float& alignmentOffset )
{
mImpl->Align( size,
startIndex,
numberOfCharacters,
horizontalAlignment,
{
mImpl->Align( size,
startIndex,
numberOfCharacters,
horizontalAlignment,
- lines );
+ lines,
+ alignmentOffset );
}
void Engine::SetDefaultLineSpacing( float lineSpacing )
}
void Engine::SetDefaultLineSpacing( float lineSpacing )