/*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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.
#include <dali-toolkit/internal/text/glyph-metrics-helper.h>
#include <dali-toolkit/internal/text/layouts/layout-engine-helper-functions.h>
#include <dali-toolkit/internal/text/layouts/layout-parameters.h>
+#include <dali-toolkit/internal/text/rendering/styles/character-spacing-helper-functions.h>
namespace Dali
{
{
namespace Text
{
-float GetLineHeight(const LineRun lineRun)
+float GetLineHeight(const LineRun lineRun, bool isLastLine)
{
// The line height is the addition of the line ascender, the line descender and the line spacing.
// However, the line descender has a negative value, hence the subtraction.
- return lineRun.ascender - lineRun.descender + lineRun.lineSpacing;
+ // In case this is the only/last line then line spacing should be ignored.
+ float lineHeight = lineRun.ascender - lineRun.descender;
+
+ if(!isLastLine || lineRun.lineSpacing > 0)
+ {
+ lineHeight += lineRun.lineSpacing;
+ }
+ return lineHeight;
}
namespace Layout
Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_LAYOUT");
#endif
-const float MAX_FLOAT = std::numeric_limits<float>::max();
-const CharacterDirection LTR = false;
-const CharacterDirection RTL = !LTR;
-const float LINE_SPACING = 0.f;
-const float MIN_LINE_SIZE = 0.f;
-const Character HYPHEN_UNICODE = 0x002D;
+const float MAX_FLOAT = std::numeric_limits<float>::max();
+const CharacterDirection LTR = false;
+const CharacterDirection RTL = !LTR;
+const float LINE_SPACING = 0.f;
+const float MIN_LINE_SIZE = 0.f;
+const Character HYPHEN_UNICODE = 0x002D;
+const float RELATIVE_LINE_SIZE = 1.f;
inline bool isEmptyLineAtLast(const Vector<LineRun>& lines, const Vector<LineRun>::Iterator& line)
{
glyphIndexInSecondHalfLine{0u},
characterIndexInSecondHalfLine{0u},
numberOfGlyphsInSecondHalfLine{0u},
- numberOfCharactersInSecondHalfLine{0u}
+ numberOfCharactersInSecondHalfLine{0u},
+ relativeLineSize{1.0f}
{
}
characterIndexInSecondHalfLine = 0u;
numberOfGlyphsInSecondHalfLine = 0u;
numberOfCharactersInSecondHalfLine = 0u;
+ relativeLineSize = 1.0f;
}
GlyphIndex glyphIndex; ///< Index of the first glyph to be laid-out.
CharacterIndex characterIndexInSecondHalfLine; ///< Index of the first character to be laid-out for the second half of line.
Length numberOfGlyphsInSecondHalfLine; ///< The number of glyph which fit in one line for the second half of line.
Length numberOfCharactersInSecondHalfLine; ///< The number of characters which fit in one line for the second half of line.
+
+ float relativeLineSize; ///< The relative line size to be applied for this line.
};
struct LayoutBidiParameters
: mLayout{Layout::Engine::SINGLE_LINE_BOX},
mCursorWidth{0.f},
mDefaultLineSpacing{LINE_SPACING},
- mDefaultLineSize{MIN_LINE_SIZE}
+ mDefaultLineSize{MIN_LINE_SIZE},
+ mRelativeLineSize{RELATIVE_LINE_SIZE}
{
}
/**
+ * @brief get the line spacing.
+ *
+ * @param[in] textSize The text size.
+ * @param[in] relativeLineSize The relative line size to be applied.
+ * @return the line spacing value.
+ */
+ float GetLineSpacing(float textSize, float relativeLineSize)
+ {
+ float lineSpacing;
+ float relTextSize;
+
+ // Sets the line size
+ lineSpacing = mDefaultLineSize - textSize;
+ lineSpacing = lineSpacing < 0.f ? 0.f : lineSpacing;
+
+ // Add the line spacing
+ lineSpacing += mDefaultLineSpacing;
+
+ //subtract line spcaing if relativeLineSize < 1 & larger than min height
+ relTextSize = textSize * relativeLineSize;
+ if(relTextSize > mDefaultLineSize)
+ {
+ if(relativeLineSize < 1)
+ {
+ //subtract the difference (always will be positive)
+ lineSpacing -= (textSize - relTextSize);
+ }
+ else
+ {
+ //reverse the addition in the top.
+ if(mDefaultLineSize > textSize)
+ {
+ lineSpacing -= mDefaultLineSize - textSize;
+ }
+
+ //add difference instead
+ lineSpacing += relTextSize - textSize;
+ }
+ }
+
+ return lineSpacing;
+ }
+
+ /**
* @brief Updates the line ascender and descender with the metrics of a new font.
*
* @param[in] glyphMetrics The metrics of the new font.
// Sets the minimum descender.
lineLayout.descender = std::min(lineLayout.descender, fontMetrics.descender);
- // Sets the line size
- lineLayout.lineSpacing = mDefaultLineSize - (lineLayout.ascender + -lineLayout.descender);
- lineLayout.lineSpacing = lineLayout.lineSpacing < 0.f ? 0.f : lineLayout.lineSpacing;
-
- // Add the line spacing
- lineLayout.lineSpacing += mDefaultLineSpacing;
+ lineLayout.lineSpacing = GetLineSpacing(lineLayout.ascender + -lineLayout.descender, lineLayout.relativeLineSize);
}
/**
const float outlineWidth = static_cast<float>(parameters.textModel->GetOutlineWidth());
const GlyphIndex lastGlyphOfParagraphPlusOne = parameters.startGlyphIndex + parameters.numberOfGlyphs;
- const float characterSpacing = parameters.textModel->mVisualModel->GetCharacterSpacing();
+ const float modelCharacterSpacing = parameters.textModel->mVisualModel->GetCharacterSpacing();
+
+ // Get the character-spacing runs.
+ const Vector<CharacterSpacingGlyphRun>& characterSpacingGlyphRuns = parameters.textModel->mVisualModel->GetCharacterSpacingGlyphRuns();
CharacterIndex characterLogicalIndex = 0u;
CharacterIndex characterVisualIndex = 0u;
{
const GlyphInfo& glyphInfo = *(glyphsBuffer + *(charactersToGlyphsBuffer + characterVisualIndex));
- calculatedAdvance = GetCalculatedAdvance(*(textBuffer + characterVisualIndex), characterSpacing, glyphInfo.advance);
+ const float characterSpacing = GetGlyphCharacterSpacing(characterVisualIndex, characterSpacingGlyphRuns, modelCharacterSpacing);
+ calculatedAdvance = GetCalculatedAdvance(*(textBuffer + characterVisualIndex), characterSpacing, glyphInfo.advance);
whiteSpaceLengthEndOfLine += calculatedAdvance;
++characterLogicalIndex;
{
const GlyphInfo& glyphInfo = *(glyphsBuffer + *(charactersToGlyphsBuffer + characterVisualIndex));
- calculatedAdvance = GetCalculatedAdvance(*(textBuffer + characterVisualIndex), characterSpacing, glyphInfo.advance);
+ const float characterSpacing = GetGlyphCharacterSpacing(characterVisualIndex, characterSpacingGlyphRuns, modelCharacterSpacing);
+ calculatedAdvance = GetCalculatedAdvance(*(textBuffer + characterVisualIndex), characterSpacing, glyphInfo.advance);
whiteSpaceLengthEndOfLine += calculatedAdvance;
++characterLogicalIndex;
charactersPerGlyphBuffer);
GlyphMetrics glyphMetrics;
- calculatedAdvance = GetCalculatedAdvance(*(textBuffer + characterVisualIndex), characterSpacing, (*(glyphsBuffer + glyphIndex)).advance);
+ const float characterSpacing = GetGlyphCharacterSpacing(glyphIndex, characterSpacingGlyphRuns, modelCharacterSpacing);
+ calculatedAdvance = GetCalculatedAdvance(*(textBuffer + characterVisualIndex), characterSpacing, (*(glyphsBuffer + glyphIndex)).advance);
GetGlyphsMetrics(glyphIndex,
numberOfGLyphsInGroup,
glyphMetrics,
characterLogicalIndex += *(charactersPerGlyphBuffer + glyphIndex + numberOfGLyphsInGroup - 1u);
GlyphMetrics glyphMetrics;
- calculatedAdvance = GetCalculatedAdvance(*(textBuffer + characterVisualIndex), characterSpacing, (*(glyphsBuffer + glyphIndex)).advance);
+ const float characterSpacing = GetGlyphCharacterSpacing(glyphIndex, characterSpacingGlyphRuns, modelCharacterSpacing);
+ calculatedAdvance = GetCalculatedAdvance(*(textBuffer + characterVisualIndex), characterSpacing, (*(glyphsBuffer + glyphIndex)).advance);
GetGlyphsMetrics(glyphIndex,
numberOfGLyphsInGroup,
glyphMetrics,
{
whiteSpaceLengthEndOfLine = 0.f;
}
- length = std::max(length, penX + glyphMetrics.xBearing + glyphMetrics.width);
+
+ if(parameters.textModel->mRemoveBackInset)
+ {
+ length = std::max(length, penX + glyphMetrics.xBearing + glyphMetrics.width);
+ }
+ else
+ {
+ length = std::max(length, penX + glyphMetrics.advance);
+ }
+
penX += (glyphMetrics.advance + parameters.interGlyphExtraAdvance);
}
}
characterLogicalIndex += *(charactersPerGlyphBuffer + glyphIndex + numberOfGLyphsInGroup - 1u);
GlyphMetrics glyphMetrics;
- calculatedAdvance = GetCalculatedAdvance(*(textBuffer + characterVisualIndex), characterSpacing, (*(glyphsBuffer + glyphIndex)).advance);
+ const float characterSpacing = GetGlyphCharacterSpacing(glyphIndex, characterSpacingGlyphRuns, modelCharacterSpacing);
+ calculatedAdvance = GetCalculatedAdvance(*(textBuffer + characterVisualIndex), characterSpacing, (*(glyphsBuffer + glyphIndex)).advance);
GetGlyphsMetrics(glyphIndex,
numberOfGLyphsInGroup,
glyphMetrics,
{
whiteSpaceLengthEndOfLine = 0.f;
}
- length = std::max(length, penX + glyphMetrics.xBearing + glyphMetrics.width);
+
+ if(parameters.textModel->mRemoveBackInset)
+ {
+ length = std::max(length, penX + glyphMetrics.xBearing + glyphMetrics.width);
+ }
+ else
+ {
+ length = std::max(length, penX + glyphMetrics.advance);
+ }
penX += (glyphMetrics.advance + parameters.interGlyphExtraAdvance);
}
}
* @param[out] lineLayout The line layout.
* @param[in] completelyFill Whether to completely fill the line ( even if the last word exceeds the boundaries ).
* @param[in] ellipsisPosition Where is the location the text elide
+ * @param[in] hiddenInputEnabled Whether the hidden input is enabled.
*/
void GetLineLayoutForBox(const Parameters& parameters,
LayoutBidiParameters& bidiParameters,
bool completelyFill,
DevelText::EllipsisPosition::Type ellipsisPosition,
bool enforceEllipsisInSingleLine,
- bool elideTextEnabled)
+ bool elideTextEnabled,
+ bool hiddenInputEnabled)
{
DALI_LOG_INFO(gLogFilter, Debug::Verbose, "-->GetLineLayoutForBox\n");
DALI_LOG_INFO(gLogFilter, Debug::Verbose, " initial glyph index : %d\n", lineLayout.glyphIndex);
bool isSecondHalf = false;
// Character Spacing
- const float characterSpacing = parameters.textModel->mVisualModel->GetCharacterSpacing();
+ const float modelCharacterSpacing = parameters.textModel->mVisualModel->GetCharacterSpacing();
float calculatedAdvance = 0.f;
Vector<CharacterIndex>& glyphToCharacterMap = parameters.textModel->mVisualModel->mGlyphsToCharacters;
const CharacterIndex* glyphToCharacterMapBuffer = glyphToCharacterMap.Begin();
+ // Get the character-spacing runs.
+ const Vector<CharacterSpacingGlyphRun>& characterSpacingGlyphRuns = parameters.textModel->mVisualModel->GetCharacterSpacingGlyphRuns();
+
GlyphMetrics glyphMetrics;
- calculatedAdvance = GetCalculatedAdvance(*(textBuffer + (*(glyphToCharacterMapBuffer + lineLayout.glyphIndex))), characterSpacing, (*(glyphsBuffer + lineLayout.glyphIndex)).advance);
+ const float characterSpacing = GetGlyphCharacterSpacing(lineLayout.glyphIndex, characterSpacingGlyphRuns, modelCharacterSpacing);
+ calculatedAdvance = GetCalculatedAdvance(*(textBuffer + (*(glyphToCharacterMapBuffer + lineLayout.glyphIndex))), characterSpacing, (*(glyphsBuffer + lineLayout.glyphIndex)).advance);
GetGlyphsMetrics(lineLayout.glyphIndex,
numberOfGLyphsInGroup,
glyphMetrics,
// 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 + outlineWidth;
+
+ tmpLineLayout.penX = mCursorWidth + outlineWidth;
+ if(parameters.textModel->mRemoveFrontInset)
+ {
+ tmpLineLayout.penX -= glyphMetrics.xBearing;
+ }
+
+ tmpLineLayout.relativeLineSize = lineLayout.relativeLineSize;
// Calculate the line height if there is no characters.
FontId lastFontId = glyphMetrics.fontId;
charactersPerGlyphBuffer);
GlyphMetrics glyphMetrics;
- calculatedAdvance = GetCalculatedAdvance(*(textBuffer + (*(glyphToCharacterMapBuffer + glyphIndex))), characterSpacing, (*(glyphsBuffer + glyphIndex)).advance);
+ const float characterSpacing = GetGlyphCharacterSpacing(glyphIndex, characterSpacingGlyphRuns, modelCharacterSpacing);
+ calculatedAdvance = GetCalculatedAdvance(*(textBuffer + (*(glyphToCharacterMapBuffer + glyphIndex))), characterSpacing, (*(glyphsBuffer + glyphIndex)).advance);
GetGlyphsMetrics(glyphIndex,
numberOfGLyphsInGroup,
glyphMetrics,
const float previousTmpLength = tmpLineLayout.length;
const float previousTmpWhiteSpaceLengthEndOfLine = tmpLineLayout.whiteSpaceLengthEndOfLine;
- if(isWhiteSpace)
+ // The calculated text size is used in atlas renderer.
+ // When the text is all white space, partial render issue occurs because the width is 0.
+ // To avoid issue, do not remove the white space size in hidden input mode.
+ if(isWhiteSpace && !hiddenInputEnabled)
{
// Add the length to the length of white spaces at the end of the line.
tmpLineLayout.whiteSpaceLengthEndOfLine += glyphMetrics.advance;
tmpLineLayout.penX += tmpLineLayout.previousAdvance + tmpLineLayout.whiteSpaceLengthEndOfLine;
tmpLineLayout.previousAdvance = (glyphMetrics.advance + parameters.interGlyphExtraAdvance);
- tmpLineLayout.length = std::max(tmpLineLayout.length, tmpLineLayout.penX + glyphMetrics.xBearing + glyphMetrics.width);
+ if(parameters.textModel->mRemoveBackInset)
+ {
+ tmpLineLayout.length = std::max(tmpLineLayout.length, tmpLineLayout.penX + glyphMetrics.xBearing + glyphMetrics.width);
+ }
+ else
+ {
+ tmpLineLayout.length = std::max(tmpLineLayout.length, tmpLineLayout.penX + glyphMetrics.advance);
+ }
// Clear the white space length at the end of the line.
tmpLineLayout.whiteSpaceLengthEndOfLine = 0.f;
while(tmpLineLayout.length + tmpLineLayout.whiteSpaceLengthEndOfLine > targetWidth && glyphIndexToRemove < glyphIndex)
{
GlyphMetrics glyphMetrics;
- calculatedAdvance = GetCalculatedAdvance(*(textBuffer + (*(glyphToCharacterMapBuffer + glyphIndexToRemove))), characterSpacing, (*(glyphsBuffer + glyphIndexToRemove)).advance);
+ const float characterSpacing = GetGlyphCharacterSpacing(glyphIndexToRemove, characterSpacingGlyphRuns, modelCharacterSpacing);
+ calculatedAdvance = GetCalculatedAdvance(*(textBuffer + (*(glyphToCharacterMapBuffer + glyphIndexToRemove))), characterSpacing, (*(glyphsBuffer + glyphIndexToRemove)).advance);
GetGlyphsMetrics(glyphIndexToRemove,
numberOfGLyphsInGroup,
glyphMetrics,
tmpLineLayout.numberOfGlyphs -= numberOfGLyphsInGroup;
}
- if(isRemovedGlyphWhiteSpace)
+ if(isRemovedGlyphWhiteSpace && !hiddenInputEnabled)
{
tmpLineLayout.penX -= glyphMetrics.advance;
tmpLineLayout.length -= glyphMetrics.advance;
// 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 + startIndexForGlyph);
- float penX = -glyph.xBearing + mCursorWidth + outlineWidth; //
+ float penX = mCursorWidth + outlineWidth; //
+
+ if(layoutParameters.textModel->mRemoveFrontInset)
+ {
+ penX -= glyph.xBearing;
+ }
CalculateGlyphPositionsLTR(layoutParameters.textModel->mVisualModel,
layoutParameters.textModel->mLogicalModel,
* @param[in] penY The vertical layout position.
* @param[in] currentParagraphDirection The current paragraph's direction.
* @param[in,out] isAutoScrollEnabled If the isAutoScrollEnabled is true and the height of the text exceeds the boundaries of the control the text is elided and the isAutoScrollEnabled is set to false to disable the autoscroll
+ * @param[in] isHiddenInputEnabled Whether the hidden input is enabled.
* @param[in] ellipsisPosition Where is the location the text elide
*
* return Whether the line is ellipsized.
Length& numberOfLines,
float penY,
bool& isAutoScrollEnabled,
+ bool isAutoScrollMaxTextureExceeded,
+ bool isHiddenInputEnabled,
DevelText::EllipsisPosition::Type ellipsisPosition,
bool enforceEllipsisInSingleLine)
{
- const bool ellipsis = enforceEllipsisInSingleLine || (isAutoScrollEnabled ? (penY - layout.descender > layoutParameters.boundingBox.height) : ((penY - layout.descender > layoutParameters.boundingBox.height) || ((mLayout == SINGLE_LINE_BOX) && (layout.length > layoutParameters.boundingBox.width))));
+ const bool ellipsis = enforceEllipsisInSingleLine || (isAutoScrollEnabled ? isAutoScrollMaxTextureExceeded : ((penY - layout.descender > layoutParameters.boundingBox.height) || ((mLayout == SINGLE_LINE_BOX) && (layout.length > layoutParameters.boundingBox.width))));
const bool isMultiline = !enforceEllipsisInSingleLine && (mLayout == MULTI_LINE_BOX);
if(ellipsis && (ellipsisPosition == DevelText::EllipsisPosition::END || !isMultiline))
{
- isAutoScrollEnabled = false;
- // Do not layout more lines if ellipsis is enabled.
+ if(penY - layout.descender > layoutParameters.boundingBox.height)
+ {
+ // Even if auto scroll is enabled and text is bigger than max texture size,
+ // if the the height is small, auto scroll should not work.
+ isAutoScrollEnabled = false;
+ }
+ // Do not layout more lines if ellipsis is enabled.
// The last line needs to be completely filled with characters.
// Part of a word may be used.
LineRun* lineRun = nullptr;
LineLayout ellipsisLayout;
+
+ ellipsisLayout.relativeLineSize = layout.relativeLineSize;
+
if(0u != numberOfLines)
{
// Get the last line and layout it again with the 'completelyFill' flag to true.
true,
ellipsisPosition,
enforceEllipsisInSingleLine,
- true);
+ true,
+ isHiddenInputEnabled);
if(ellipsisPosition == DevelText::EllipsisPosition::START && !isMultiline)
{
layoutSize.width = layoutParameters.boundingBox.width;
if(layoutSize.height < Math::MACHINE_EPSILON_1000)
{
- layoutSize.height += GetLineHeight(*lineRun);
+ layoutSize.height += GetLineHeight(*lineRun, true);
+ }
+ else
+ {
+ //when we apply ellipsis, the last line should not take negative linespacing into account for layoutSize.height calculation
+ //usually we don't includ it in normal cases using GetLineHeight()
+ if(lineRun->lineSpacing < 0)
+ {
+ layoutSize.height -= lineRun->lineSpacing;
+ }
}
const Vector<BidirectionalLineInfoRun>& bidirectionalLinesInfo = layoutParameters.textModel->mLogicalModel->mBidirectionalLineInfo;
lineRun.direction = layout.direction;
lineRun.ellipsis = false;
- lineRun.lineSpacing = mDefaultLineSize - (lineRun.ascender + -lineRun.descender);
- lineRun.lineSpacing = lineRun.lineSpacing < 0.f ? 0.f : lineRun.lineSpacing;
-
- lineRun.lineSpacing += mDefaultLineSpacing;
+ lineRun.lineSpacing = GetLineSpacing(lineRun.ascender + -lineRun.descender, layout.relativeLineSize);
// Update the actual size.
if(lineRun.width > layoutSize.width)
layoutSize.width = lineRun.width;
}
- layoutSize.height += GetLineHeight(lineRun);
+ layoutSize.height += GetLineHeight(lineRun, isLastLine);
}
/**
{
const Vector<GlyphInfo>& glyphs = layoutParameters.textModel->mVisualModel->mGlyphs;
+ if(glyphs.Size() == 0u)
+ {
+ // Do nothing.
+ return;
+ }
+
// Need to add a new line with no characters but with height to increase the layoutSize.height
const GlyphInfo& glyphInfo = glyphs[glyphs.Count() - 1u];
lineRun.direction = LTR;
lineRun.ellipsis = false;
- lineRun.lineSpacing = mDefaultLineSize - (lineRun.ascender + -lineRun.descender);
- lineRun.lineSpacing = lineRun.lineSpacing < 0.f ? 0.f : lineRun.lineSpacing;
+ BoundedParagraphRun currentParagraphRun;
+ LineLayout tempLineLayout;
+ (GetBoundedParagraph(layoutParameters.textModel->GetBoundedParagraphRuns(), characterIndex, currentParagraphRun) ? SetRelativeLineSize(¤tParagraphRun, tempLineLayout) : SetRelativeLineSize(nullptr, tempLineLayout));
- lineRun.lineSpacing += mDefaultLineSpacing;
+ lineRun.lineSpacing = GetLineSpacing(lineRun.ascender + -lineRun.descender, tempLineLayout.relativeLineSize);
- layoutSize.height += GetLineHeight(lineRun);
+ layoutSize.height += GetLineHeight(lineRun, true);
}
/**
it != endIt;
++it)
{
- const LineRun& line = *it;
+ const LineRun& line = *it;
+ bool isLastLine = (it + 1 == endIt);
if(line.width > layoutSize.width)
{
layoutSize.width = line.width;
}
- layoutSize.height += GetLineHeight(line);
+ layoutSize.height += GetLineHeight(line, isLastLine);
}
}
}
}
+ /**
+ * @brief Sets the relative line size for the LineLayout
+ *
+ * @param[in] currentParagraphRun Contains the bounded paragraph for this line layout.
+ * @param[in,out] lineLayout The line layout to be updated.
+ */
+ void SetRelativeLineSize(BoundedParagraphRun* currentParagraphRun, LineLayout& lineLayout)
+ {
+ lineLayout.relativeLineSize = mRelativeLineSize;
+
+ if(currentParagraphRun != nullptr && currentParagraphRun->relativeLineSizeDefined)
+ {
+ lineLayout.relativeLineSize = currentParagraphRun->relativeLineSize;
+ }
+ }
+
+ /**
+ * @brief Get the bounded paragraph for the characterIndex if exists.
+ *
+ * @param[in] boundedParagraphRuns The bounded paragraph list to search in.
+ * @param[in] characterIndex The character index to get bounded paragraph for.
+ * @param[out] currentParagraphRun Contains the bounded paragraph if found for the characterIndex.
+ *
+ * @return returns true if a bounded paragraph was found.
+ */
+ bool GetBoundedParagraph(const Vector<BoundedParagraphRun> boundedParagraphRuns, CharacterIndex characterIndex, BoundedParagraphRun& currentParagraphRun)
+ {
+ for(Vector<BoundedParagraphRun>::Iterator it = boundedParagraphRuns.Begin(),
+ endIt = boundedParagraphRuns.End();
+ it != endIt;
+ ++it)
+ {
+ BoundedParagraphRun& tempParagraphRun = *it;
+
+ if(characterIndex >= tempParagraphRun.characterRun.characterIndex &&
+ characterIndex < (tempParagraphRun.characterRun.characterIndex + tempParagraphRun.characterRun.numberOfCharacters))
+ {
+ currentParagraphRun = tempParagraphRun;
+ return true;
+ }
+ }
+
+ return false;
+ }
+
bool LayoutText(Parameters& layoutParameters,
Size& layoutSize,
bool elideTextEnabled,
bool& isAutoScrollEnabled,
+ bool isAutoScrollMaxTextureExceeded,
+ bool isHiddenInputEnabled,
DevelText::EllipsisPosition::Type ellipsisPosition)
{
DALI_LOG_INFO(gLogFilter, Debug::Verbose, "-->LayoutText\n");
layoutParameters.textModel->mVisualModel->SetFirstMiddleIndexOfElidedGlyphs(0u);
layoutParameters.textModel->mVisualModel->SetSecondMiddleIndexOfElidedGlyphs(0u);
- Vector<LineRun>& lines = layoutParameters.textModel->mVisualModel->mLines;
+ Vector<LineRun>& lines = layoutParameters.textModel->mVisualModel->mLines;
+ const Vector<BoundedParagraphRun>& boundedParagraphRuns = layoutParameters.textModel->GetBoundedParagraphRuns();
if(0u == layoutParameters.numberOfGlyphs)
{
// Retrieve BiDi info.
const bool hasBidiParagraphs = !layoutParameters.textModel->mLogicalModel->mBidirectionalParagraphInfo.Empty();
- const CharacterIndex* const glyphsToCharactersBuffer = hasBidiParagraphs ? layoutParameters.textModel->mVisualModel->mGlyphsToCharacters.Begin() : nullptr;
+ const CharacterIndex* const glyphsToCharactersBuffer = layoutParameters.textModel->mVisualModel->mGlyphsToCharacters.Begin();
const Vector<BidirectionalParagraphInfoRun>& bidirectionalParagraphsInfo = layoutParameters.textModel->mLogicalModel->mBidirectionalParagraphInfo;
const Vector<BidirectionalLineInfoRun>& bidirectionalLinesInfo = layoutParameters.textModel->mLogicalModel->mBidirectionalLineInfo;
LineLayout layout;
layout.direction = layoutBidiParameters.paragraphDirection;
layout.glyphIndex = index;
+
+ BoundedParagraphRun currentParagraphRun;
+ (GetBoundedParagraph(boundedParagraphRuns, *(glyphsToCharactersBuffer + index), currentParagraphRun) ? SetRelativeLineSize(¤tParagraphRun, layout) : SetRelativeLineSize(nullptr, layout));
+
GetLineLayoutForBox(layoutParameters,
layoutBidiParameters,
layout,
false,
ellipsisPosition,
false,
- elideTextEnabled);
+ elideTextEnabled,
+ isHiddenInputEnabled);
DALI_LOG_INFO(gLogFilter, Debug::Verbose, " glyph index %d\n", layout.glyphIndex);
DALI_LOG_INFO(gLogFilter, Debug::Verbose, " character index %d\n", layout.characterIndex);
DALI_LOG_INFO(gLogFilter, Debug::Verbose, " number of characters %d\n", layout.numberOfCharacters);
DALI_LOG_INFO(gLogFilter, Debug::Verbose, " length %f\n", layout.length);
+ CharacterIndex lastCharacterInParagraph = currentParagraphRun.characterRun.characterIndex + currentParagraphRun.characterRun.numberOfCharacters - 1;
+
+ //check if this is the last line in paragraph, if false we should use the default relative line size (the one set using the property)
+ if(lastCharacterInParagraph >= layout.characterIndex && lastCharacterInParagraph < layout.characterIndex + layout.numberOfCharacters)
+ {
+ layout.relativeLineSize = mRelativeLineSize;
+ }
+
if(0u == layout.numberOfGlyphs + layout.numberOfGlyphsInSecondHalfLine)
{
// The width is too small and no characters are laid-out.
numberOfLines,
penY,
isAutoScrollEnabled,
+ isAutoScrollMaxTextureExceeded,
+ isHiddenInputEnabled,
ellipsisPosition,
false);
}
numberOfLines,
penY,
isAutoScrollEnabled,
+ isAutoScrollMaxTextureExceeded,
+ isHiddenInputEnabled,
ellipsisPosition,
true);
}
}
// Updates the vertical pen's position.
- penY += -layout.descender + layout.lineSpacing + mDefaultLineSpacing;
- // If there is a defaultLineSize, updates the pen's position.
- if(mDefaultLineSize > 0.f)
- {
- float lineSpacing = mDefaultLineSize - (layout.ascender + -layout.descender);
- lineSpacing = lineSpacing < 0.f ? 0.f : lineSpacing;
- penY += lineSpacing;
- }
+ penY += -layout.descender + layout.lineSpacing + GetLineSpacing(layout.ascender + -layout.descender, layout.relativeLineSize);
// Increase the glyph index.
index = nextIndex;
float mDefaultLineSize;
IntrusivePtr<Metrics> mMetrics;
+ float mRelativeLineSize;
};
Engine::Engine()
Size& layoutSize,
bool elideTextEnabled,
bool& isAutoScrollEnabled,
+ bool isAutoScrollMaxTextureExceeded,
+ bool isHiddenInputEnabled,
DevelText::EllipsisPosition::Type ellipsisPosition)
{
return mImpl->LayoutText(layoutParameters,
layoutSize,
elideTextEnabled,
isAutoScrollEnabled,
+ isAutoScrollMaxTextureExceeded,
+ isHiddenInputEnabled,
ellipsisPosition);
}
return mImpl->mDefaultLineSize;
}
+void Engine::SetRelativeLineSize(float relativeLineSize)
+{
+ mImpl->mRelativeLineSize = relativeLineSize;
+}
+
+float Engine::GetRelativeLineSize() const
+{
+ return mImpl->mRelativeLineSize;
+}
+
} // namespace Layout
} // namespace Text