ToolkitTestApplication application;
auto control = Control::New();
- auto noneset = control.GetProperty( DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE );
- DALI_TEST_EQUALS( Property::NONE, noneset.GetType(), TEST_LOCATION );
+ auto highlightable = control.GetProperty<bool>(DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE);
+ DALI_TEST_EQUALS(highlightable, false, TEST_LOCATION);
// negative testcase - trying to set unconvertible value
- control.SetProperty( DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, "deadbeef" );
- noneset = control.GetProperty( DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE );
- DALI_TEST_EQUALS( Property::NONE, noneset.GetType(), TEST_LOCATION );
+ control.SetProperty(DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, "deadbeef");
+ highlightable = control.GetProperty<bool>(DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE);
+ DALI_TEST_EQUALS(highlightable, false, TEST_LOCATION);
auto q = Dali::Accessibility::Accessible::Get( control );
auto control = Control::New();
auto accessibility_translation_domain = DevelControl::Property::ACCESSIBILITY_TRANSLATION_DOMAIN;
- DALI_TEST_EQUALS( Property::NONE , control.GetProperty( accessibility_translation_domain ).GetType(), TEST_LOCATION );
+ DALI_TEST_EQUALS("", control.GetProperty<std::string>(accessibility_translation_domain), TEST_LOCATION);
control.SetProperty( accessibility_translation_domain, "translation_domain_test_1" );
DALI_TEST_EQUALS( "translation_domain_test_1" , control.GetProperty( accessibility_translation_domain ).Get< std::string >(), TEST_LOCATION );
END_TEST;
}
+int UtcDaliTextEditorSelectionWithLineSpacing(void)
+{
+ //Only for test coverage
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliTextEditorSelectionWithLineSpacing ");
+
+ TextEditor textEditor = TextEditor::New();
+ textEditor.SetProperty(Actor::Property::SIZE, Vector2(400.0f, 400.f));
+ application.GetScene().Add(textEditor);
+ application.SendNotification();
+ application.Render();
+
+ textEditor.SetProperty(TextEditor::Property::TEXT, "Line #1\nLine #2\nLine #3");
+ textEditor.SetProperty(DevelTextEditor::Property::LINE_SPACING, -20);
+
+ application.SendNotification();
+ application.Render();
+
+ DevelTextEditor::SelectWholeText(textEditor);
+
+ application.SendNotification();
+ application.Render();
+
+ DevelTextEditor::SelectNone(textEditor);
+ textEditor.SetProperty(DevelTextEditor::Property::LINE_SPACING, 20);
+
+ application.SendNotification();
+ application.Render();
+
+ DevelTextEditor::SelectWholeText(textEditor);
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS(textEditor.GetProperty<float>(DevelTextEditor::Property::LINE_SPACING), 20.0f, TEST_LOCATION);
+
+ END_TEST;
+}
+
int UtcDaliTextEditorMinLineSize(void)
{
ToolkitTestApplication application;
END_TEST;
}
+int UtcDaliToolkitTextEditorRelativeLineHeight(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliToolkitTextEditorRelativeLineHeight");
+
+ TextEditor editor = TextEditor::New();
+ editor.SetProperty(Actor::Property::SIZE, Vector2(200.0f, 300.f));
+ editor.SetProperty(TextEditor::Property::POINT_SIZE, 10);
+ editor.SetProperty(TextEditor::Property::TEXT, "Hello\nWorld");
+
+ application.GetScene().Add(editor);
+ application.SendNotification();
+ application.Render();
+
+ Vector3 naturalSize = editor.GetNaturalSize();
+
+ editor.SetProperty(DevelTextEditor::Property::RELATIVE_LINE_SIZE, 0.5f);
+
+ application.SendNotification();
+ application.Render();
+
+ Vector3 relativeNaturalSize = editor.GetNaturalSize();
+
+ DALI_TEST_EQUALS(naturalSize.y, relativeNaturalSize.y, TEST_LOCATION);
+
+ editor.SetProperty(DevelTextEditor::Property::RELATIVE_LINE_SIZE, 2.0f);
+
+ application.SendNotification();
+ application.Render();
+
+ relativeNaturalSize = editor.GetNaturalSize();
+
+ DALI_TEST_EQUALS(naturalSize.y * 2, relativeNaturalSize.y, TEST_LOCATION);
+ END_TEST;
+}
+
int UtcDaliTextEditorCharacterSpacing(void)
{
ToolkitTestApplication application;
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 UtcDaliToolkitTextLabelRelativeLineHeight(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliToolkitTextLabelRelativeLineHeight");
+
+ TextLabel label = TextLabel::New();
+ label.SetProperty(Actor::Property::SIZE, Vector2(200.0f, 300.f));
+ label.SetProperty(TextLabel::Property::POINT_SIZE, 10);
+ label.SetProperty(TextLabel::Property::TEXT, "Hello\nWorld");
+
+ application.GetScene().Add(label);
+ application.SendNotification();
+ application.Render();
+
+ Vector3 naturalSize = label.GetNaturalSize();
+
+ label.SetProperty(DevelTextLabel::Property::RELATIVE_LINE_SIZE, 0.5f);
+
+ application.SendNotification();
+ application.Render();
+
+ Vector3 relativeNaturalSize = label.GetNaturalSize();
+
+ DALI_TEST_EQUALS(naturalSize.y, relativeNaturalSize.y, TEST_LOCATION);
+
+ label.SetProperty(DevelTextLabel::Property::RELATIVE_LINE_SIZE, 2.0f);
+
+ application.SendNotification();
+ application.Render();
+
+ relativeNaturalSize = label.GetNaturalSize();
+
+ DALI_TEST_EQUALS(naturalSize.y * 2, relativeNaturalSize.y, TEST_LOCATION);
+ END_TEST;
+}
+
int UtcDaliTextLabelCharacterSpacing(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;
return;
}
- if(index == DevelControl::Property::ACCESSIBILITY_NAME || (index == GetNamePropertyIndex() && !controlImpl.mAccessibilityNameSet))
+ if(index == DevelControl::Property::ACCESSIBILITY_NAME || (index == GetNamePropertyIndex() && controlImpl.mAccessibilityName.empty()))
{
if(controlImpl.mAccessibilityGetNameSignal.Empty())
{
}
}
- if(index == DevelControl::Property::ACCESSIBILITY_DESCRIPTION || (index == GetDescriptionPropertyIndex() && !controlImpl.mAccessibilityDescriptionSet))
+ if(index == DevelControl::Property::ACCESSIBILITY_DESCRIPTION || (index == GetDescriptionPropertyIndex() && controlImpl.mAccessibilityDescription.empty()))
{
if(controlImpl.mAccessibilityGetDescriptionSignal.Empty())
{
{
controlImpl.mAccessibilityGetNameSignal.Emit(name);
}
- else if(controlImpl.mAccessibilityNameSet)
+ else if(!controlImpl.mAccessibilityName.empty())
{
name = controlImpl.mAccessibilityName;
}
name = Self().GetProperty<std::string>(Actor::Property::NAME);
}
- if(controlImpl.mAccessibilityTranslationDomainSet)
+ if(!controlImpl.mAccessibilityTranslationDomain.empty())
{
return GetLocaleText(name, controlImpl.mAccessibilityTranslationDomain.c_str());
}
{
controlImpl.mAccessibilityGetDescriptionSignal.Emit(description);
}
- else if(controlImpl.mAccessibilityDescriptionSet)
+ else if(!controlImpl.mAccessibilityDescription.empty())
{
description = controlImpl.mAccessibilityDescription;
}
{
description = GetDescriptionRaw();
}
- if(controlImpl.mAccessibilityTranslationDomainSet)
+
+ if(!controlImpl.mAccessibilityTranslationDomain.empty())
{
return GetLocaleText(description, controlImpl.mAccessibilityTranslationDomain.c_str());
}
* The default value is 0.f which does nothing.
*/
CHARACTER_SPACING,
+
+ /**
+ * @brief the relative height of the line (a factor that will be multiplied by text height).
+ * @details Name "relativeLineSize", type Property::FLOAT.
+ * @note If the value is less than 1, the lines could to be overlapped.
+ */
+ RELATIVE_LINE_SIZE,
};
} // namespace Property
* The default value is 0.f which does nothing.
*/
CHARACTER_SPACING,
+
+ /**
+ * @brief the relative height of the line (a factor that will be multiplied by text height).
+ * @details Name "relativeLineSize", type Property::FLOAT.
+ * @note If the value is less than 1, the lines could to be overlapped.
+ */
+ RELATIVE_LINE_SIZE,
};
} // namespace Property
#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)
{
std::string name;
if(value.Get(name))
{
- controlImpl.mImpl->mAccessibilityName = name;
- controlImpl.mImpl->mAccessibilityNameSet = true;
- }
- else
- {
- controlImpl.mImpl->mAccessibilityNameSet = false;
+ controlImpl.mImpl->mAccessibilityName = name;
}
+ break;
}
- break;
case Toolkit::DevelControl::Property::ACCESSIBILITY_DESCRIPTION:
{
std::string text;
if(value.Get(text))
{
- controlImpl.mImpl->mAccessibilityDescription = text;
- controlImpl.mImpl->mAccessibilityDescriptionSet = true;
- }
- else
- {
- controlImpl.mImpl->mAccessibilityDescriptionSet = false;
+ controlImpl.mImpl->mAccessibilityDescription = text;
}
+ break;
}
- break;
case Toolkit::DevelControl::Property::ACCESSIBILITY_TRANSLATION_DOMAIN:
{
std::string text;
if(value.Get(text))
{
- controlImpl.mImpl->mAccessibilityTranslationDomain = text;
- controlImpl.mImpl->mAccessibilityTranslationDomainSet = true;
- }
- else
- {
- controlImpl.mImpl->mAccessibilityTranslationDomainSet = false;
+ controlImpl.mImpl->mAccessibilityTranslationDomain = text;
}
+ break;
}
- break;
case Toolkit::DevelControl::Property::ACCESSIBILITY_ROLE:
{
{
controlImpl.mImpl->mAccessibilityRole = role;
}
+ break;
}
- break;
case Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE:
{
bool highlightable;
if(value.Get(highlightable))
{
- controlImpl.mImpl->mAccessibilityHighlightable = highlightable;
- controlImpl.mImpl->mAccessibilityHighlightableSet = true;
- }
- else
- {
- controlImpl.mImpl->mAccessibilityHighlightableSet = false;
+ controlImpl.mImpl->mAccessibilityHighlightable = highlightable;
}
+ break;
}
- break;
case Toolkit::DevelControl::Property::ACCESSIBILITY_ATTRIBUTES:
{
case Toolkit::DevelControl::Property::ACCESSIBILITY_NAME:
{
- if(controlImpl.mImpl->mAccessibilityNameSet)
- {
- value = controlImpl.mImpl->mAccessibilityName;
- }
+ value = controlImpl.mImpl->mAccessibilityName;
break;
}
case Toolkit::DevelControl::Property::ACCESSIBILITY_DESCRIPTION:
{
- if(controlImpl.mImpl->mAccessibilityDescriptionSet)
- {
- value = controlImpl.mImpl->mAccessibilityDescription;
- }
+ value = controlImpl.mImpl->mAccessibilityDescription;
break;
}
case Toolkit::DevelControl::Property::ACCESSIBILITY_TRANSLATION_DOMAIN:
{
- if(controlImpl.mImpl->mAccessibilityTranslationDomainSet)
- {
- value = controlImpl.mImpl->mAccessibilityTranslationDomain;
- }
+ value = controlImpl.mImpl->mAccessibilityTranslationDomain;
break;
}
case Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE:
{
- if(controlImpl.mImpl->mAccessibilityHighlightableSet)
- {
- value = controlImpl.mImpl->mAccessibilityHighlightable;
- }
+ value = controlImpl.mImpl->mAccessibilityHighlightable;
break;
}
std::string mAccessibilityName;
std::string mAccessibilityDescription;
std::string mAccessibilityTranslationDomain;
- bool mAccessibilityNameSet = false;
- bool mAccessibilityDescriptionSet = false;
- bool mAccessibilityTranslationDomainSet = false;
- bool mAccessibilityHighlightable = false;
- bool mAccessibilityHighlightableSet = false;
-
- bool mAccessibilityHidden = false;
+ bool mAccessibilityHighlightable = false;
+ bool mAccessibilityHidden = false;
Dali::Accessibility::Role mAccessibilityRole = Dali::Accessibility::Role::UNKNOWN;
DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextEditor, "strikethrough", MAP, STRIKETHROUGH )
DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextEditor, "inputStrikethrough", MAP, INPUT_STRIKETHROUGH )
DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextEditor, "characterSpacing", FLOAT, CHARACTER_SPACING )
+DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextEditor, "relativeLineSize", FLOAT, RELATIVE_LINE_SIZE )
DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "textChanged", SIGNAL_TEXT_CHANGED )
DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "inputStyleChanged", SIGNAL_INPUT_STYLE_CHANGED )
impl.mRenderer.Reset();
break;
}
+ case Toolkit::DevelTextEditor::Property::RELATIVE_LINE_SIZE:
+ {
+ const float relativeLineSize = value.Get<float>();
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::Verbose, "TextEditor %p RELATIVE_LINE_SIZE %f\n", impl.mController.Get(), relativeLineSize);
+
+ impl.mController->SetRelativeLineSize(relativeLineSize);
+ impl.mRenderer.Reset();
+ break;
+ }
}
}
value = impl.mController->GetCharacterSpacing();
break;
}
+ case Toolkit::DevelTextEditor::Property::RELATIVE_LINE_SIZE:
+ {
+ value = impl.mController->GetRelativeLineSize();
+ break;
+ }
} //switch
return value;
}
DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextLabel, "ellipsisPosition", INTEGER, ELLIPSIS_POSITION )
DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextLabel, "strikethrough", MAP, STRIKETHROUGH )
DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextLabel, "characterSpacing", FLOAT, CHARACTER_SPACING )
+DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextLabel, "relativeLineSize", FLOAT, RELATIVE_LINE_SIZE )
DALI_ANIMATABLE_PROPERTY_REGISTRATION_WITH_DEFAULT(Toolkit, TextLabel, "textColor", Color::BLACK, TEXT_COLOR )
DALI_ANIMATABLE_PROPERTY_COMPONENT_REGISTRATION(Toolkit, TextLabel, "textColorRed", TEXT_COLOR_RED, TEXT_COLOR, 0)
impl.mController->SetCharacterSpacing(characterSpacing);
break;
}
+ case Toolkit::DevelTextLabel::Property::RELATIVE_LINE_SIZE:
+ {
+ const float relativeLineSize = value.Get<float>();
+ DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextLabel %p RELATIVE_LINE_SIZE %f\n", impl.mController.Get(), relativeLineSize);
+
+ impl.mController->SetRelativeLineSize(relativeLineSize);
+ break;
+ }
}
// Request relayout when text update is needed. It's necessary to call it
value = impl.mController->GetCharacterSpacing();
break;
}
+ case Toolkit::DevelTextLabel::Property::RELATIVE_LINE_SIZE:
+ {
+ value = impl.mController->GetRelativeLineSize();
+ break;
+ }
}
}
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;
cursorInfo.lineOffset = CalculateLineOffset(parameters.visualModel->mLines,
newLineIndex);
- cursorInfo.lineHeight = GetLineHeight(newLine);
+ // The line height is the addition of the line ascender and the line descender.
+ // However, the line descender has a negative value, hence the subtraction also line spacing should not be included in cursor height.
+ cursorInfo.lineHeight = newLine.ascender - newLine.descender;
index = 0u;
const Length totalNumberOfCharacters = parameters.logicalModel->mText.Count();
cursorInfo.lineOffset = CalculateLineOffset(parameters.visualModel->mLines,
lineIndex);
- cursorInfo.lineHeight = GetLineHeight(line);
+ // The line height is the addition of the line ascender and the line descender.
+ // However, the line descender has a negative value, hence the subtraction also line spacing should not be included in cursor height.
+ cursorInfo.lineHeight = line.ascender - line.descender;
// Calculate the primary cursor.
{
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)
{
: 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.
+ * @return the line spacing value.
+ */
+ float GetLineSpacing(float textSize)
{
+ 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 * mRelativeLineSize;
+ if(relTextSize > mDefaultLineSize)
+ {
+ if(mRelativeLineSize < 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;
}
/**
// 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);
}
/**
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;
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);
// Update the actual size.
if(lineRun.width > layoutSize.width)
layoutSize.width = lineRun.width;
}
- layoutSize.height += GetLineHeight(lineRun);
+ layoutSize.height += GetLineHeight(lineRun, isLastLine);
}
/**
lineRun.direction = LTR;
lineRun.ellipsis = false;
- lineRun.lineSpacing = mDefaultLineSize - (lineRun.ascender + -lineRun.descender);
- lineRun.lineSpacing = lineRun.lineSpacing < 0.f ? 0.f : lineRun.lineSpacing;
+ lineRun.lineSpacing = GetLineSpacing(lineRun.ascender + -lineRun.descender);
- 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);
}
}
}
// 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);
// Increase the glyph index.
index = nextIndex;
float mDefaultLineSize;
IntrusivePtr<Metrics> mMetrics;
+ float mRelativeLineSize;
};
Engine::Engine()
return mImpl->mDefaultLineSize;
}
+void Engine::SetRelativeLineSize(float relativeLineSize)
+{
+ mImpl->mRelativeLineSize = relativeLineSize;
+}
+
+float Engine::GetRelativeLineSize() const
+{
+ return mImpl->mRelativeLineSize;
+}
+
} // namespace Layout
} // namespace Text
#define DALI_TOOLKIT_TEXT_LAYOUT_ENGINE_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.
*/
float GetDefaultLineSize() const;
+ /**
+ * @brief Sets relative line size to the original line size.
+ *
+ * @param[in] relativeLineSize The relative line size.
+ */
+ void SetRelativeLineSize(float relativeLineSize);
+
+ /**
+ * @brief Retrieves the relative line size.
+ *
+ * @return The relative line size.
+ */
+ float GetRelativeLineSize() const;
+
private:
// Undefined
Engine(const Engine& handle);
#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;
return false;
}
+bool Controller::Impl::SetRelativeLineSize(float relativeLineSize)
+{
+ if(std::fabs(relativeLineSize - GetRelativeLineSize()) > Math::MACHINE_EPSILON_1000)
+ {
+ mLayoutEngine.SetRelativeLineSize(relativeLineSize);
+
+ RelayoutAllCharacters();
+ return true;
+ }
+ return false;
+}
+
+float Controller::Impl::GetRelativeLineSize()
+{
+ return mLayoutEngine.GetRelativeLineSize();
+}
+
string Controller::Impl::GetSelectedText()
{
string text;
bool SetDefaultLineSize(float lineSize);
/**
+ * @copydoc Controller::SetRelativeLineSize
+ */
+ bool SetRelativeLineSize(float relativeLineSize);
+
+ /**
+ * @copydoc Controller::GetRelativeLineSize
+ */
+ float GetRelativeLineSize();
+
+ /**
* @copydoc Text::Controller::GetPrimaryCursorPosition()
*/
CharacterIndex GetPrimaryCursorPosition() const;
return mImpl->mLayoutEngine.GetDefaultLineSize();
}
+bool Controller::SetRelativeLineSize(float relativeLineSize)
+{
+ return mImpl->SetRelativeLineSize(relativeLineSize);
+}
+
+float Controller::GetRelativeLineSize() const
+{
+ return mImpl->GetRelativeLineSize();
+}
+
void Controller::SetInputColor(const Vector4& color)
{
InputProperties::SetInputColor(*this, color);
float GetDefaultLineSize() const;
/**
+ * @brief Sets the relative line size to the original line size.
+ *
+ * @param[in] relativeLineSize The relativeline size.
+ *
+ * @return True if relativeLineSize has been updated, false otherwise
+ */
+ bool SetRelativeLineSize(float lineSize);
+
+ /**
+ * @brief Retrieves the relative line size.
+ *
+ * @return The relative line size.
+ */
+ float GetRelativeLineSize() const;
+
+ /**
* @brief Sets the input text's color.
*
* @param[in] color The input text's color.
/*
- * 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);
}
}
lineRun += firstLineIndex;
- selectionBoxInfo->lineHeight = GetLineHeight(*lineRun);
+ // The line height is the addition of the line ascender and the line descender.
+ // However, the line descender has a negative value, hence the subtraction also line spacing should not be included in selection height.
+ selectionBoxInfo->lineHeight = lineRun->ascender - lineRun->descender;
GlyphIndex lastGlyphOfLine = lineRun->glyphRun.glyphIndex + lineRun->glyphRun.numberOfGlyphs - 1u;
++lineIndex;
if(lineIndex < firstLineIndex + numberOfLines)
{
+ float currentLineSpacing = lineRun->lineSpacing;
+
// Retrieve the next line.
++lineRun;
// Update the line's vertical offset.
selectionBoxInfo->lineOffset = currentLineOffset + currentLineHeight;
- selectionBoxInfo->lineHeight = GetLineHeight(*lineRun);
+ if(currentLineSpacing < 0)
+ {
+ selectionBoxInfo->lineOffset += currentLineSpacing;
+ }
+
+ // The line height is the addition of the line ascender and the line descender.
+ // However, the line descender has a negative value, hence the subtraction also line spacing should not be included in selection height.
+ selectionBoxInfo->lineHeight = lineRun->ascender - lineRun->descender;
+
+ if(lineRun->lineSpacing > 0)
+ {
+ selectionBoxInfo->lineHeight += lineRun->lineSpacing;
+ }
}
}
}
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;
{
const unsigned int TOOLKIT_MAJOR_VERSION = 2;
const unsigned int TOOLKIT_MINOR_VERSION = 1;
-const unsigned int TOOLKIT_MICRO_VERSION = 11;
+const unsigned int TOOLKIT_MICRO_VERSION = 12;
const char* const TOOLKIT_BUILD_DATE = __DATE__ " " __TIME__;
#ifdef DEBUG_ENABLED
Name: dali2-toolkit
Summary: Dali 3D engine Toolkit
-Version: 2.1.11
+Version: 2.1.12
Release: 1
Group: System/Libraries
License: Apache-2.0 and BSD-3-Clause and MIT