From 04ed06538a1461d2ccdbd132c4902e4572b9960a Mon Sep 17 00:00:00 2001 From: ssabah Date: Wed, 11 May 2022 17:21:06 +0300 Subject: [PATCH] Ignore vertical line alignment when the line spacing is negative This is to resolved cut-off in first-line when line-spacing is negative and vertical line alignment is bottom or middle. Testing code: https://github.com/wonrst/NUI-Test/blob/main/text-vertical-line-align/verticalline.cs This patch should be preceded by the patch below: https://review.tizen.org/gerrit/c/platform/core/uifw/dali-toolkit/+/274097 Change-Id: I80e6d838ad08f7f34d79f6018bb44ae467c7a89a --- .../src/dali-toolkit-internal/CMakeLists.txt | 1 + .../utc-Dali-LineHelperFunctions.cpp | 228 +++++++++++++++++++++ dali-toolkit/internal/file.list | 1 + .../internal/text/line-helper-functions.cpp | 88 ++++++++ dali-toolkit/internal/text/line-helper-functions.h | 59 ++++++ .../internal/text/rendering/text-typesetter.cpp | 53 +---- 6 files changed, 378 insertions(+), 52 deletions(-) create mode 100644 automated-tests/src/dali-toolkit-internal/utc-Dali-LineHelperFunctions.cpp create mode 100644 dali-toolkit/internal/text/line-helper-functions.cpp create mode 100644 dali-toolkit/internal/text/line-helper-functions.h diff --git a/automated-tests/src/dali-toolkit-internal/CMakeLists.txt b/automated-tests/src/dali-toolkit-internal/CMakeLists.txt index 035f6c3..ebed7c6 100755 --- a/automated-tests/src/dali-toolkit-internal/CMakeLists.txt +++ b/automated-tests/src/dali-toolkit-internal/CMakeLists.txt @@ -16,6 +16,7 @@ SET(TC_SOURCES utc-Dali-Dictionary.cpp utc-Dali-FeedbackStyle.cpp utc-Dali-ItemView-internal.cpp + utc-Dali-LineHelperFunctions.cpp utc-Dali-LogicalModel.cpp utc-Dali-PropertyHelper.cpp utc-Dali-Text-Characters.cpp diff --git a/automated-tests/src/dali-toolkit-internal/utc-Dali-LineHelperFunctions.cpp b/automated-tests/src/dali-toolkit-internal/utc-Dali-LineHelperFunctions.cpp new file mode 100644 index 0000000..2930c6d --- /dev/null +++ b/automated-tests/src/dali-toolkit-internal/utc-Dali-LineHelperFunctions.cpp @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2020 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +using namespace Dali; +using namespace Toolkit; +using namespace Text; + +int UtcDaliGetPreOffsetVerticalLineAlignmentWithNegativeLineSpacing(void) +{ + tet_infoline(" UtcDaliGetPreOffsetVerticalLineAlignmentWithNegativeLineSpacing "); + ToolkitTestApplication application; + + uint32_t expectedNumberOfLines = 2u; + + // Creates a text controller. + ControllerPtr controller = Controller::New(); + + // Configures the text controller similarly to the text-label. + ConfigureTextLabel(controller); + + // Sets the text. + controller->SetMarkupProcessorEnabled(true); + controller->SetTextElideEnabled(false); + controller->SetText("

Line one Line two

"); + + // Creates the text's model and relais-out the text. + const Size relayoutSize(120.f, 100.f); + controller->Relayout(relayoutSize); + + // Tests the rendering controller has been created. + TypesetterPtr typesetter = Typesetter::New(controller->GetTextModel()); + DALI_TEST_CHECK(typesetter); + + // Tests the view model has been created. + ViewModel* model = typesetter->GetViewModel(); + DALI_TEST_CHECK(model); + + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS(model->GetNumberOfLines(), expectedNumberOfLines, TEST_LOCATION); + DALI_TEST_CHECK(model->GetLines()); + + const LineRun& lineOne = *(model->GetLines() + 0u); + const LineRun& lineTwo = *(model->GetLines() + 1u); + + DALI_TEST_EQUALS(GetPreOffsetVerticalLineAlignment(lineOne, Dali::Toolkit::DevelText::VerticalLineAlignment::TOP), 0.0f, TEST_LOCATION); + DALI_TEST_EQUALS(GetPreOffsetVerticalLineAlignment(lineOne, Dali::Toolkit::DevelText::VerticalLineAlignment::MIDDLE), 0.0f, TEST_LOCATION); + DALI_TEST_EQUALS(GetPreOffsetVerticalLineAlignment(lineOne, Dali::Toolkit::DevelText::VerticalLineAlignment::BOTTOM), 0.0f, TEST_LOCATION); + + DALI_TEST_EQUALS(GetPreOffsetVerticalLineAlignment(lineTwo, Dali::Toolkit::DevelText::VerticalLineAlignment::TOP), 0.0f, TEST_LOCATION); + DALI_TEST_EQUALS(GetPreOffsetVerticalLineAlignment(lineTwo, Dali::Toolkit::DevelText::VerticalLineAlignment::MIDDLE), 0.0f, TEST_LOCATION); + DALI_TEST_EQUALS(GetPreOffsetVerticalLineAlignment(lineTwo, Dali::Toolkit::DevelText::VerticalLineAlignment::BOTTOM), 0.0f, TEST_LOCATION); + END_TEST; +} + +int UtcDaliGetPreOffsetVerticalLineAlignmentWithPositiveLineSpacing(void) +{ + tet_infoline(" UtcDaliGetPreOffsetVerticalLineAlignmentWithPositiveLineSpacing "); + ToolkitTestApplication application; + + uint32_t expectedNumberOfLines = 2u; + + // Creates a text controller. + ControllerPtr controller = Controller::New(); + + // Configures the text controller similarly to the text-label. + ConfigureTextLabel(controller); + + // Sets the text. + controller->SetMarkupProcessorEnabled(true); + controller->SetTextElideEnabled(false); + controller->SetText("

Line one Line two

"); + + // Creates the text's model and relais-out the text. + const Size relayoutSize(120.f, 100.f); + controller->Relayout(relayoutSize); + + // Tests the rendering controller has been created. + TypesetterPtr typesetter = Typesetter::New(controller->GetTextModel()); + DALI_TEST_CHECK(typesetter); + + // Tests the view model has been created. + ViewModel* model = typesetter->GetViewModel(); + DALI_TEST_CHECK(model); + + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS(model->GetNumberOfLines(), expectedNumberOfLines, TEST_LOCATION); + DALI_TEST_CHECK(model->GetLines()); + + const LineRun& lineOne = *(model->GetLines() + 0u); + const LineRun& lineTwo = *(model->GetLines() + 1u); + + DALI_TEST_EQUALS(GetPreOffsetVerticalLineAlignment(lineOne, Dali::Toolkit::DevelText::VerticalLineAlignment::TOP), 0.0f, TEST_LOCATION); + DALI_TEST_EQUALS(GetPreOffsetVerticalLineAlignment(lineOne, Dali::Toolkit::DevelText::VerticalLineAlignment::MIDDLE), 9.5f, TEST_LOCATION); + DALI_TEST_EQUALS(GetPreOffsetVerticalLineAlignment(lineOne, Dali::Toolkit::DevelText::VerticalLineAlignment::BOTTOM), 19.0f, TEST_LOCATION); + + DALI_TEST_EQUALS(GetPreOffsetVerticalLineAlignment(lineTwo, Dali::Toolkit::DevelText::VerticalLineAlignment::TOP), 0.0f, TEST_LOCATION); + DALI_TEST_EQUALS(GetPreOffsetVerticalLineAlignment(lineTwo, Dali::Toolkit::DevelText::VerticalLineAlignment::MIDDLE), 0.0f, TEST_LOCATION); + DALI_TEST_EQUALS(GetPreOffsetVerticalLineAlignment(lineTwo, Dali::Toolkit::DevelText::VerticalLineAlignment::BOTTOM), 0.0f, TEST_LOCATION); + END_TEST; +} + +int UtcDaliGetPostOffsetVerticalLineAlignmentWithNegativeLineSpacing(void) +{ + tet_infoline(" UtcDaliGetPostOffsetVerticalLineAlignmentWithNegativeLineSpacing "); + ToolkitTestApplication application; + + uint32_t expectedNumberOfLines = 2u; + + // Creates a text controller. + ControllerPtr controller = Controller::New(); + + // Configures the text controller similarly to the text-label. + ConfigureTextLabel(controller); + + // Sets the text. + controller->SetMarkupProcessorEnabled(true); + controller->SetTextElideEnabled(false); + controller->SetText("

Line one Line two

"); + + // Creates the text's model and relais-out the text. + const Size relayoutSize(120.f, 100.f); + controller->Relayout(relayoutSize); + + // Tests the rendering controller has been created. + TypesetterPtr typesetter = Typesetter::New(controller->GetTextModel()); + DALI_TEST_CHECK(typesetter); + + // Tests the view model has been created. + ViewModel* model = typesetter->GetViewModel(); + DALI_TEST_CHECK(model); + + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS(model->GetNumberOfLines(), expectedNumberOfLines, TEST_LOCATION); + DALI_TEST_CHECK(model->GetLines()); + + const LineRun& lineOne = *(model->GetLines() + 0u); + const LineRun& lineTwo = *(model->GetLines() + 1u); + + DALI_TEST_EQUALS(GetPostOffsetVerticalLineAlignment(lineOne, Dali::Toolkit::DevelText::VerticalLineAlignment::TOP), -9.5f, TEST_LOCATION); + DALI_TEST_EQUALS(GetPostOffsetVerticalLineAlignment(lineOne, Dali::Toolkit::DevelText::VerticalLineAlignment::MIDDLE), -9.5f, TEST_LOCATION); + DALI_TEST_EQUALS(GetPostOffsetVerticalLineAlignment(lineOne, Dali::Toolkit::DevelText::VerticalLineAlignment::BOTTOM), -9.5f, TEST_LOCATION); + + DALI_TEST_EQUALS(GetPostOffsetVerticalLineAlignment(lineTwo, Dali::Toolkit::DevelText::VerticalLineAlignment::TOP), 0.0f, TEST_LOCATION); + DALI_TEST_EQUALS(GetPostOffsetVerticalLineAlignment(lineTwo, Dali::Toolkit::DevelText::VerticalLineAlignment::MIDDLE), 0.0f, TEST_LOCATION); + DALI_TEST_EQUALS(GetPostOffsetVerticalLineAlignment(lineTwo, Dali::Toolkit::DevelText::VerticalLineAlignment::BOTTOM), 0.0f, TEST_LOCATION); + END_TEST; +} + +int UtcDaliGetPostOffsetVerticalLineAlignmentWithPositiveLineSpacing(void) +{ + tet_infoline(" UtcDaliGetPostOffsetVerticalLineAlignmentWithPositiveLineSpacing "); + ToolkitTestApplication application; + + uint32_t expectedNumberOfLines = 2u; + + // Creates a text controller. + ControllerPtr controller = Controller::New(); + + // Configures the text controller similarly to the text-label. + ConfigureTextLabel(controller); + + // Sets the text. + controller->SetMarkupProcessorEnabled(true); + controller->SetTextElideEnabled(false); + controller->SetText("

Line one Line two

"); + + // Creates the text's model and relais-out the text. + const Size relayoutSize(120.f, 100.f); + controller->Relayout(relayoutSize); + + // Tests the rendering controller has been created. + TypesetterPtr typesetter = Typesetter::New(controller->GetTextModel()); + DALI_TEST_CHECK(typesetter); + + // Tests the view model has been created. + ViewModel* model = typesetter->GetViewModel(); + DALI_TEST_CHECK(model); + + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS(model->GetNumberOfLines(), expectedNumberOfLines, TEST_LOCATION); + DALI_TEST_CHECK(model->GetLines()); + + const LineRun& lineOne = *(model->GetLines() + 0u); + const LineRun& lineTwo = *(model->GetLines() + 1u); + + DALI_TEST_EQUALS(GetPostOffsetVerticalLineAlignment(lineOne, Dali::Toolkit::DevelText::VerticalLineAlignment::TOP), 19.0f, TEST_LOCATION); + DALI_TEST_EQUALS(GetPostOffsetVerticalLineAlignment(lineOne, Dali::Toolkit::DevelText::VerticalLineAlignment::MIDDLE), 9.5f, TEST_LOCATION); + DALI_TEST_EQUALS(GetPostOffsetVerticalLineAlignment(lineOne, Dali::Toolkit::DevelText::VerticalLineAlignment::BOTTOM), 0.0f, TEST_LOCATION); + + DALI_TEST_EQUALS(GetPostOffsetVerticalLineAlignment(lineTwo, Dali::Toolkit::DevelText::VerticalLineAlignment::TOP), 0.0f, TEST_LOCATION); + DALI_TEST_EQUALS(GetPostOffsetVerticalLineAlignment(lineTwo, Dali::Toolkit::DevelText::VerticalLineAlignment::MIDDLE), 0.0f, TEST_LOCATION); + DALI_TEST_EQUALS(GetPostOffsetVerticalLineAlignment(lineTwo, Dali::Toolkit::DevelText::VerticalLineAlignment::BOTTOM), 0.0f, TEST_LOCATION); + END_TEST; +} diff --git a/dali-toolkit/internal/file.list b/dali-toolkit/internal/file.list index 15640b7..5d6926f 100644 --- a/dali-toolkit/internal/file.list +++ b/dali-toolkit/internal/file.list @@ -163,6 +163,7 @@ SET( toolkit_src_files ${toolkit_src_dir}/text/multi-language-support.cpp ${toolkit_src_dir}/text/hidden-text.cpp ${toolkit_src_dir}/text/input-filter.cpp + ${toolkit_src_dir}/text/line-helper-functions.cpp ${toolkit_src_dir}/text/property-string-parser.cpp ${toolkit_src_dir}/text/segmentation.cpp ${toolkit_src_dir}/text/shaper.cpp diff --git a/dali-toolkit/internal/text/line-helper-functions.cpp b/dali-toolkit/internal/text/line-helper-functions.cpp new file mode 100644 index 0000000..d2ffcd1 --- /dev/null +++ b/dali-toolkit/internal/text/line-helper-functions.cpp @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2021 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// FILE HEADER +#include + +namespace Dali +{ +namespace Toolkit +{ +namespace Text +{ +float GetPreOffsetVerticalLineAlignment(const LineRun& line, const DevelText::VerticalLineAlignment::Type& verLineAlign) +{ + // Calculate vertical line alignment + float offset = 0.0f; + + switch(verLineAlign) + { + case DevelText::VerticalLineAlignment::TOP: + { + break; + } + case DevelText::VerticalLineAlignment::MIDDLE: + { + offset = line.lineSpacing * 0.5f; + break; + } + case DevelText::VerticalLineAlignment::BOTTOM: + { + offset = line.lineSpacing; + break; + } + } + + // Apply TOP case when the lineSpacing is less than zero. + offset = line.lineSpacing < 0.0f ? 0.0f : offset; + + return offset; +} + +float GetPostOffsetVerticalLineAlignment(const LineRun& line, const DevelText::VerticalLineAlignment::Type& verLineAlign) +{ + // Calculate vertical line alignment + float offset = 0.0f; + + switch(verLineAlign) + { + case DevelText::VerticalLineAlignment::TOP: + { + offset = line.lineSpacing; + break; + } + case DevelText::VerticalLineAlignment::MIDDLE: + { + offset = line.lineSpacing * 0.5f; + break; + } + case DevelText::VerticalLineAlignment::BOTTOM: + { + break; + } + } + + // Apply TOP case when the lineSpacing is less than zero. + offset = line.lineSpacing < 0.0f ? line.lineSpacing : offset; + + return offset; +} +} // namespace Text + +} // namespace Toolkit + +} // namespace Dali diff --git a/dali-toolkit/internal/text/line-helper-functions.h b/dali-toolkit/internal/text/line-helper-functions.h new file mode 100644 index 0000000..ad94086 --- /dev/null +++ b/dali-toolkit/internal/text/line-helper-functions.h @@ -0,0 +1,59 @@ +#ifndef DALI_TOOLKIT_TEXT_LINE_HELPER_FUNCTIONS_H +#define DALI_TOOLKIT_TEXT_LINE_HELPER_FUNCTIONS_H + +/* + * Copyright (c) 2021 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// INTERNAL INCLUDES + +#include +#include + +namespace Dali +{ +namespace Toolkit +{ +namespace Text +{ +/** + * @brief Retrieves the vertical offset to shift text inside line to up by negative value and to down by positive value. + * The shifting depends on the vertical line alignment @p verLineAlign and lineSpacing when the lineSpacing is poistive. + * When the lineSpacing is negative then ignore @p verLineAlign + * @param[in] line the line. + * @param[in] line the line. + * + * @return The vertical offset before text. + */ +float GetPreOffsetVerticalLineAlignment(const LineRun& line, const Dali::Toolkit::DevelText::VerticalLineAlignment::Type& verLineAlign); + +/** + * @brief Retrieves the vertical offset to shift the next line to up by negative value and to down by positive value. + * The shifting depends on the vertical line alignment @p verLineAlign and lineSpacing when the lineSpacing is poistive. + * When the lineSpacing is negative then ignore @p verLineAlign + * @param[in] line the line. + * @param[in] line the line. + * + * @return The vertical offset after text. + */ +float GetPostOffsetVerticalLineAlignment(const LineRun& line, const Dali::Toolkit::DevelText::VerticalLineAlignment::Type& verLineAlign); +} // namespace Text + +} // namespace Toolkit + +} // namespace Dali + +#endif // DALI_TOOLKIT_TEXT_LINE_HELPER_FUNCTIONS_H diff --git a/dali-toolkit/internal/text/rendering/text-typesetter.cpp b/dali-toolkit/internal/text/rendering/text-typesetter.cpp index 1cd9d56..b1502a9 100644 --- a/dali-toolkit/internal/text/rendering/text-typesetter.cpp +++ b/dali-toolkit/internal/text/rendering/text-typesetter.cpp @@ -26,6 +26,7 @@ // INTERNAL INCLUDES #include #include +#include #include #include #include @@ -475,58 +476,6 @@ void DrawBackgroundColor( } } -float GetPreOffsetVerticalLineAlignment(LineRun line, DevelText::VerticalLineAlignment::Type verLineAlign) -{ - // Calculate vertical line alignment - float offset = 0.0f; - - switch(verLineAlign) - { - case DevelText::VerticalLineAlignment::TOP: - { - break; - } - case DevelText::VerticalLineAlignment::MIDDLE: - { - offset = line.lineSpacing * 0.5f; - break; - } - case DevelText::VerticalLineAlignment::BOTTOM: - { - offset = line.lineSpacing; - break; - } - } - - return offset; -} - -float GetPostOffsetVerticalLineAlignment(LineRun line, DevelText::VerticalLineAlignment::Type verLineAlign) -{ - // Calculate vertical line alignment - float offset = 0.0f; - - switch(verLineAlign) - { - case DevelText::VerticalLineAlignment::TOP: - { - offset = line.lineSpacing; - break; - } - case DevelText::VerticalLineAlignment::MIDDLE: - { - offset = line.lineSpacing * 0.5f; - break; - } - case DevelText::VerticalLineAlignment::BOTTOM: - { - break; - } - } - - return offset; -} - Devel::PixelBuffer DrawGlyphsBackground(const ViewModel* model, Devel::PixelBuffer& buffer, const uint32_t& bufferWidth, const uint32_t& bufferHeight, bool ignoreHorizontalAlignment, int32_t horizontalOffset, int32_t verticalOffset) { // Retrieve lines, glyphs, positions and colors from the view model. -- 2.7.4