From a4a06c5a4c6c02861972d1ea9029c64d60bed192 Mon Sep 17 00:00:00 2001 From: abdullah Date: Thu, 24 Feb 2022 16:33:45 +0200 Subject: [PATCH] Support RelativeLineHeight in TextEditor/TextLabel RelativeLineHeight is providing the ability to set relative line size. Ex: 0.5 means half of the line size. 2 means double the line size. Change-Id: Ic81b3ab0349b17de2339eb4b24002d0d4bb049dc --- .../src/dali-toolkit/utc-Dali-TextEditor.cpp | 36 ++++++++ .../src/dali-toolkit/utc-Dali-TextLabel.cpp | 36 ++++++++ .../controls/text-controls/text-editor-devel.h | 7 ++ .../controls/text-controls/text-label-devel.h | 7 ++ .../controls/text-controls/text-editor-impl.cpp | 1 + .../text-controls/text-editor-property-handler.cpp | 14 ++++ .../controls/text-controls/text-label-impl.cpp | 14 ++++ .../internal/text/layouts/layout-engine.cpp | 96 +++++++++++++++------- dali-toolkit/internal/text/layouts/layout-engine.h | 16 +++- .../internal/text/text-controller-impl.cpp | 17 ++++ dali-toolkit/internal/text/text-controller-impl.h | 10 +++ dali-toolkit/internal/text/text-controller.cpp | 10 +++ dali-toolkit/internal/text/text-controller.h | 16 ++++ 13 files changed, 250 insertions(+), 30 deletions(-) diff --git a/automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp b/automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp index 0c3ab82..f8b2799 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp @@ -5765,6 +5765,42 @@ int UtcDaliToolkitTextEditorUnderlineTypesGeneration3(void) 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 * 2, 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; diff --git a/automated-tests/src/dali-toolkit/utc-Dali-TextLabel.cpp b/automated-tests/src/dali-toolkit/utc-Dali-TextLabel.cpp index ecc5f67..dc3cac4 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-TextLabel.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-TextLabel.cpp @@ -2632,6 +2632,42 @@ int UtcDaliToolkitTextLabelStrikethroughGeneration(void) 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 * 2, 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; diff --git a/dali-toolkit/devel-api/controls/text-controls/text-editor-devel.h b/dali-toolkit/devel-api/controls/text-controls/text-editor-devel.h index 8ca9648..b990dc7 100644 --- a/dali-toolkit/devel-api/controls/text-controls/text-editor-devel.h +++ b/dali-toolkit/devel-api/controls/text-controls/text-editor-devel.h @@ -303,6 +303,13 @@ enum Type * 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 diff --git a/dali-toolkit/devel-api/controls/text-controls/text-label-devel.h b/dali-toolkit/devel-api/controls/text-controls/text-label-devel.h index 205950c..326d8d0 100644 --- a/dali-toolkit/devel-api/controls/text-controls/text-label-devel.h +++ b/dali-toolkit/devel-api/controls/text-controls/text-label-devel.h @@ -194,6 +194,13 @@ enum Type * 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 diff --git a/dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp b/dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp index 40fdcad..6fc1a3d 100644 --- a/dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp +++ b/dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp @@ -158,6 +158,7 @@ DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextEditor, "minLineSize", 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 ) diff --git a/dali-toolkit/internal/controls/text-controls/text-editor-property-handler.cpp b/dali-toolkit/internal/controls/text-controls/text-editor-property-handler.cpp index 3cb9df0..5ea2cf1 100644 --- a/dali-toolkit/internal/controls/text-controls/text-editor-property-handler.cpp +++ b/dali-toolkit/internal/controls/text-controls/text-editor-property-handler.cpp @@ -723,6 +723,15 @@ void TextEditor::PropertyHandler::SetProperty(Toolkit::TextEditor textEditor, Pr impl.mRenderer.Reset(); break; } + case Toolkit::DevelTextEditor::Property::RELATIVE_LINE_SIZE: + { + const float relativeLineSize = value.Get(); + 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; + } } } @@ -1130,6 +1139,11 @@ Property::Value TextEditor::PropertyHandler::GetProperty(Toolkit::TextEditor tex value = impl.mController->GetCharacterSpacing(); break; } + case Toolkit::DevelTextEditor::Property::RELATIVE_LINE_SIZE: + { + value = impl.mController->GetRelativeLineSize(); + break; + } } //switch return value; } diff --git a/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp b/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp index 49a9af8..10b05a0 100644 --- a/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp +++ b/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp @@ -140,6 +140,7 @@ DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextLabel, "enableFontSizeSc 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) @@ -541,6 +542,14 @@ void TextLabel::SetProperty(BaseObject* object, Property::Index index, const Pro impl.mController->SetCharacterSpacing(characterSpacing); break; } + case Toolkit::DevelTextLabel::Property::RELATIVE_LINE_SIZE: + { + const float relativeLineSize = value.Get(); + 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 @@ -799,6 +808,11 @@ Property::Value TextLabel::GetProperty(BaseObject* object, Property::Index index value = impl.mController->GetCharacterSpacing(); break; } + case Toolkit::DevelTextLabel::Property::RELATIVE_LINE_SIZE: + { + value = impl.mController->GetRelativeLineSize(); + break; + } } } diff --git a/dali-toolkit/internal/text/layouts/layout-engine.cpp b/dali-toolkit/internal/text/layouts/layout-engine.cpp index c8addcc..8c8ea94 100644 --- a/dali-toolkit/internal/text/layouts/layout-engine.cpp +++ b/dali-toolkit/internal/text/layouts/layout-engine.cpp @@ -52,12 +52,13 @@ namespace Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_LAYOUT"); #endif -const float MAX_FLOAT = std::numeric_limits::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::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& lines, const Vector::Iterator& line) { @@ -155,11 +156,55 @@ struct Engine::Impl : 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; + } + + /** * @brief Updates the line ascender and descender with the metrics of a new font. * * @param[in] glyphMetrics The metrics of the new font. @@ -187,12 +232,7 @@ struct Engine::Impl // 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); } /** @@ -1353,10 +1393,7 @@ struct Engine::Impl 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) @@ -1410,10 +1447,7 @@ struct Engine::Impl 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 += mDefaultLineSpacing; + lineRun.lineSpacing = GetLineSpacing(lineRun.ascender + -lineRun.descender); layoutSize.height += GetLineHeight(lineRun); } @@ -1811,14 +1845,7 @@ struct Engine::Impl } // 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; @@ -2077,6 +2104,7 @@ struct Engine::Impl float mDefaultLineSize; IntrusivePtr mMetrics; + float mRelativeLineSize; }; Engine::Engine() @@ -2168,6 +2196,16 @@ float Engine::GetDefaultLineSize() const return mImpl->mDefaultLineSize; } +void Engine::SetRelativeLineSize(float relativeLineSize) +{ + mImpl->mRelativeLineSize = relativeLineSize; +} + +float Engine::GetRelativeLineSize() const +{ + return mImpl->mRelativeLineSize; +} + } // namespace Layout } // namespace Text diff --git a/dali-toolkit/internal/text/layouts/layout-engine.h b/dali-toolkit/internal/text/layouts/layout-engine.h index e11c549..6b78e87 100644 --- a/dali-toolkit/internal/text/layouts/layout-engine.h +++ b/dali-toolkit/internal/text/layouts/layout-engine.h @@ -2,7 +2,7 @@ #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. @@ -166,6 +166,20 @@ public: */ 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); diff --git a/dali-toolkit/internal/text/text-controller-impl.cpp b/dali-toolkit/internal/text/text-controller-impl.cpp index 294b534..3850f12 100644 --- a/dali-toolkit/internal/text/text-controller-impl.cpp +++ b/dali-toolkit/internal/text/text-controller-impl.cpp @@ -712,6 +712,23 @@ bool Controller::Impl::SetDefaultLineSize(float lineSize) 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; diff --git a/dali-toolkit/internal/text/text-controller-impl.h b/dali-toolkit/internal/text/text-controller-impl.h index 4b1db94..0757bc0 100644 --- a/dali-toolkit/internal/text/text-controller-impl.h +++ b/dali-toolkit/internal/text/text-controller-impl.h @@ -627,6 +627,16 @@ struct Controller::Impl bool SetDefaultLineSize(float lineSize); /** + * @copydoc Controller::SetRelativeLineSize + */ + bool SetRelativeLineSize(float relativeLineSize); + + /** + * @copydoc Controller::GetRelativeLineSize + */ + float GetRelativeLineSize(); + + /** * @copydoc Text::Controller::GetPrimaryCursorPosition() */ CharacterIndex GetPrimaryCursorPosition() const; diff --git a/dali-toolkit/internal/text/text-controller.cpp b/dali-toolkit/internal/text/text-controller.cpp index 9ea1e60..9de7dba 100644 --- a/dali-toolkit/internal/text/text-controller.cpp +++ b/dali-toolkit/internal/text/text-controller.cpp @@ -948,6 +948,16 @@ float Controller::GetDefaultLineSize() 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); diff --git a/dali-toolkit/internal/text/text-controller.h b/dali-toolkit/internal/text/text-controller.h index f461058..2a37c3b 100644 --- a/dali-toolkit/internal/text/text-controller.h +++ b/dali-toolkit/internal/text/text-controller.h @@ -1262,6 +1262,22 @@ public: // Default style & Input style 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. -- 2.7.4