END_TEST;
}
+int UtcDaliTextEditorTextSizeNegativeLineSpacing(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("UtcDaliTextEditorTextSizeNegativeLineSpacing");
+
+ TextEditor editor = TextEditor::New();
+
+ float lineSpacing = -20.f;
+
+ editor.SetProperty(Actor::Property::SIZE, Vector2(450.0f, 300.f));
+ editor.SetProperty(TextEditor::Property::POINT_SIZE, 10.f);
+ editor.SetProperty(DevelTextEditor::Property::LINE_SPACING, lineSpacing);
+ editor.SetProperty(TextEditor::Property::TEXT, "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.");
+
+ application.GetScene().Add(editor);
+ application.SendNotification();
+ application.Render();
+
+ Vector<Vector2> positionsList = DevelTextEditor::GetTextPosition(editor, 0, 123);
+ Vector<Vector2> sizeList = DevelTextEditor::GetTextSize(editor, 0, 123);
+
+ Vector2 lastLinePos = positionsList[positionsList.Size() - 1];
+ Vector2 lastLineSize = sizeList[sizeList.Size() - 1];
+
+ DALI_TEST_EQUALS(sizeList[0].y * (sizeList.Size() - 1), lastLinePos.y, Math::MACHINE_EPSILON_1000, TEST_LOCATION);
+ DALI_TEST_EQUALS(sizeList[0].y - lineSpacing, lastLineSize.y, Math::MACHINE_EPSILON_1000, TEST_LOCATION);
+
+ application.SendNotification();
+ application.Render();
+
+ END_TEST;
+}
+
int UtcDaliToolkitTexteditorParagraphTag(void)
{
ToolkitTestApplication application;
END_TEST;
}
+int UtcDaliTextTextLabelSizeNegativeLineSpacing(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("UtcDaliTextTextLabelSizeNegativeLineSpacing");
+
+ TextLabel label = TextLabel::New();
+
+ float lineSpacing = -20.f;
+
+ label.SetProperty(Actor::Property::SIZE, Vector2(450.0f, 300.f));
+ label.SetProperty(TextLabel::Property::POINT_SIZE, 10.f);
+ label.SetProperty(DevelTextLabel::Property::LINE_SPACING, lineSpacing);
+ label.SetProperty(TextLabel::Property::MULTI_LINE, true);
+ label.SetProperty(TextLabel::Property::TEXT, "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.");
+
+ application.GetScene().Add(label);
+ application.SendNotification();
+ application.Render();
+
+ Vector<Vector2> positionsList = DevelTextLabel::GetTextPosition(label, 0, 123);
+ Vector<Vector2> sizeList = DevelTextLabel::GetTextSize(label, 0, 123);
+
+ Vector2 lastLinePos = positionsList[positionsList.Size() - 1];
+ Vector2 lastLineSize = sizeList[sizeList.Size() - 1];
+
+ DALI_TEST_EQUALS(sizeList[0].y * (sizeList.Size() - 1), lastLinePos.y, Math::MACHINE_EPSILON_1000, TEST_LOCATION);
+ DALI_TEST_EQUALS(sizeList[0].y - lineSpacing, lastLineSize.y, Math::MACHINE_EPSILON_1000, TEST_LOCATION);
+
+ application.SendNotification();
+ application.Render();
+
+ END_TEST;
+}
+
int UtcDaliToolkitTextlabelParagraphTag(void)
{
ToolkitTestApplication application;
#include <dali-toolkit/internal/text/bidirectional-support.h>
#include <dali-toolkit/internal/text/character-set-conversion.h>
#include <dali-toolkit/internal/text/color-segmentation.h>
+#include <dali-toolkit/internal/text/glyph-metrics-helper.h>
#include <dali-toolkit/internal/text/layouts/layout-engine.h>
#include <dali-toolkit/internal/text/layouts/layout-parameters.h>
#include <dali-toolkit/internal/text/markup-processor.h>
#include <dali-toolkit/internal/text/text-enumerations-impl.h>
#include <dali-toolkit/internal/text/text-font-style.h>
#include <dali-toolkit/internal/text/text-model.h>
-#include <dali-toolkit/internal/text/glyph-metrics-helper.h>
namespace Dali
{
{
Length finalNumberOfGlyphs = 0u;
- if((GetLineHeight(line)) > textLayoutArea.height)
+ if((GetLineHeight(line, (lines.Size() == 1))) > textLayoutArea.height)
{
// The height of the line is bigger than the height of the text area.
// Show the ellipsis glyph even if it doesn't fit in the text area.
float penY = 0.f;
float lineSize = internalData.layoutEngine.GetDefaultLineSize();
float lineOffset = 0.f;
+ bool isLastLine;
for(unsigned int index = 0u; index < numberOfLines; ++index)
{
const LineRun& line = *(lines.Begin() + index);
numberOfCharacters += line.characterRun.numberOfCharacters;
+ isLastLine = (index == numberOfLines - 1);
- lineOffset = lineSize > 0.f ? lineSize : GetLineHeight(line);
+ lineOffset = lineSize > 0.f ? lineSize : GetLineHeight(line, isLastLine);
penY += lineOffset;
if((penY + lineOffset) > boundingBox)
{
it != endIt;
++it, ++lineIndex)
{
- const LineRun& lineRun = *it;
+ const LineRun& lineRun = *it;
+ bool isLastLine = (it + 1 == endIt);
- totalHeight += GetLineHeight(lineRun);
+ totalHeight += GetLineHeight(lineRun, isLastLine);
if(visualY < totalHeight)
{
it != endIt;
++it)
{
- const LineRun& lineRun = *it;
+ const LineRun& lineRun = *it;
+ bool isLastLine = (it + 1 == lines.End());
- offset += GetLineHeight(lineRun);
+ offset += GetLineHeight(lineRun, isLastLine);
}
return offset;
{
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
layoutSize.width = layoutParameters.boundingBox.width;
if(layoutSize.height < Math::MACHINE_EPSILON_1000)
{
- layoutSize.height += GetLineHeight(*lineRun);
+ layoutSize.height += GetLineHeight(*lineRun, true);
}
const Vector<BidirectionalLineInfoRun>& bidirectionalLinesInfo = layoutParameters.textModel->mLogicalModel->mBidirectionalLineInfo;
layoutSize.width = lineRun.width;
}
- layoutSize.height += GetLineHeight(lineRun);
+ layoutSize.height += GetLineHeight(lineRun, isLastLine);
}
/**
lineRun.lineSpacing += mDefaultLineSpacing;
- 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);
}
}
#define DALI_TOOLKIT_TEXT_LINE_RUN_H
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
* @brief Get the line height for the specified line run.
*
* @param[in] lineRun The line runs to get the height for.
+ * @param[in] isLastLine whether this is the last line in the text.
*/
-float GetLineHeight(const LineRun lineRun);
+float GetLineHeight(const LineRun lineRun, bool isLastLine);
} // namespace Text
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
const LineIndex lineIndex = visualModel->GetLineOfCharacter(characterIndex);
const LineIndex previousLineIndex = (lineIndex > 0 ? lineIndex - 1u : lineIndex);
+ const LineIndex lastLineIndex = (visualModel->mLines.Size() > 0 ? visualModel->mLines.Size() - 1u : 0);
+ const bool isLastLine = (previousLineIndex == lastLineIndex);
// Retrieve the cursor position info.
CursorInfo cursorInfo;
const LineRun& line = *(visualModel->mLines.Begin() + previousLineIndex);
// Get the next hit 'y' point.
- const float hitPointY = cursorInfo.lineOffset - 0.5f * GetLineHeight(line);
+ const float hitPointY = cursorInfo.lineOffset - 0.5f * GetLineHeight(line, isLastLine);
// Use the cursor hook position 'x' and the next hit 'y' position to calculate the new cursor index.
bool matchedCharacter = false;
// Get the line below.
const LineRun& line = *(visualModel->mLines.Begin() + lineIndex + 1u);
+ // Get last line index
+ const LineIndex lastLineIndex = (visualModel->mLines.Size() > 0 ? visualModel->mLines.Size() - 1u : 0);
+ const bool isLastLine = (lineIndex + 1u == lastLineIndex);
+
// Get the next hit 'y' point.
- const float hitPointY = cursorInfo.lineOffset + cursorInfo.lineHeight + 0.5f * GetLineHeight(line);
+ const float hitPointY = cursorInfo.lineOffset + cursorInfo.lineHeight + 0.5f * GetLineHeight(line, isLastLine);
// Use the cursor hook position 'x' and the next hit 'y' position to calculate the new cursor index.
bool matchedCharacter = false;
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
{
namespace Text
{
-bool GetNextLine(GlyphIndex index, LineIndex& lineIndex, LineRun*& lineRun, GlyphIndex& lastGlyphOfLine, Length numberOfLines)
+bool GetNextLine(GlyphIndex index, LineIndex& lineIndex, LineRun*& lineRun, GlyphIndex& lastGlyphOfLine, Length numberOfLines, bool& isLastLine)
{
if(index == lastGlyphOfLine)
{
++lineIndex;
if(lineIndex < numberOfLines)
{
+ isLastLine = (lineIndex + 1 == numberOfLines);
++lineRun;
return true;
}
return false;
}
-void UpdateLineInfo(const LineRun* lineRun, float& currentLineOffset, float& currentLineHeight, GlyphIndex& lastGlyphOfLine)
+void UpdateLineInfo(const LineRun* lineRun, float& currentLineOffset, float& currentLineHeight, GlyphIndex& lastGlyphOfLine, bool isLastLine)
{
lastGlyphOfLine = lineRun->glyphRun.glyphIndex + lineRun->glyphRun.numberOfGlyphs - 1u;
currentLineOffset = currentLineOffset + currentLineHeight;
- currentLineHeight = GetLineHeight(*lineRun);
+ currentLineHeight = GetLineHeight(*lineRun, isLastLine);
}
void GetTextGeometry(ModelPtr textModel, CharacterIndex startIndex, CharacterIndex endIndex, Vector<Vector2>& sizesList, Vector<Vector2>& positionsList)
GlyphIndex glyphEnd = *(charactersToGlyphBuffer + endIndex) + ((numberOfGlyphs > 0) ? numberOfGlyphs - 1u : 0u);
LineIndex lineIndex = visualModel->GetLineOfCharacter(startIndex);
Length numberOfLines = visualModel->GetTotalNumberOfLines();
+ bool isLastLine = lineIndex + 1 == numberOfLines;
LineIndex firstLineIndex = lineIndex;
Size textInLineSize;
//get the first line and its vertical offset
float currentLineOffset = CalculateLineOffset(visualModel->mLines, firstLineIndex);
- float currentLineHeight = GetLineHeight(*lineRun);
+ float currentLineHeight = GetLineHeight(*lineRun, isLastLine);
GlyphIndex lastGlyphOfLine = lineRun->glyphRun.glyphIndex + lineRun->glyphRun.numberOfGlyphs - 1;
// Check if the first/last glyph is a ligature that needs be splitted like English fi or Arabic ﻻ.
positionsList.PushBack(blockPos);
}
- if(GetNextLine(index, lineIndex, lineRun, lastGlyphOfLine, numberOfLines))
+ if(GetNextLine(index, lineIndex, lineRun, lastGlyphOfLine, numberOfLines, isLastLine))
{
- UpdateLineInfo(lineRun, currentLineOffset, currentLineHeight, lastGlyphOfLine);
+ UpdateLineInfo(lineRun, currentLineOffset, currentLineHeight, lastGlyphOfLine, isLastLine);
}
// Ignore any glyph that was removed
continue;
}
else if((ellipsisPosition == DevelText::EllipsisPosition::START) && (index <= startIndexOfGlyphs))
{
- if(GetNextLine(index, lineIndex, lineRun, lastGlyphOfLine, numberOfLines))
+ if(GetNextLine(index, lineIndex, lineRun, lastGlyphOfLine, numberOfLines, isLastLine))
{
- UpdateLineInfo(lineRun, currentLineOffset, currentLineHeight, lastGlyphOfLine);
+ UpdateLineInfo(lineRun, currentLineOffset, currentLineHeight, lastGlyphOfLine, isLastLine);
}
continue;
currentSize.y = currentLineHeight;
// if there is next line to retrieve.
- if(GetNextLine(index, lineIndex, lineRun, lastGlyphOfLine, numberOfLines))
+ if(GetNextLine(index, lineIndex, lineRun, lastGlyphOfLine, numberOfLines, isLastLine))
{
- UpdateLineInfo(lineRun, currentLineOffset, currentLineHeight, lastGlyphOfLine);
+ UpdateLineInfo(lineRun, currentLineOffset, currentLineHeight, lastGlyphOfLine, isLastLine);
}
}
const LineRun& elidedLine = *ellipsisLine;
if((1u == numberOfLines) &&
- (GetLineHeight(elidedLine) > mImpl->mVisualModel->mControlSize.height))
+ (GetLineHeight(elidedLine, true) > mImpl->mVisualModel->mControlSize.height))
{
// Replace the first glyph with ellipsis glyph
auto indexOfFirstGlyph = (ellipsisPosition == DevelText::EllipsisPosition::START) ? startIndexOfEllipsis : 0u;