From: Bowon Ryu Date: Tue, 31 May 2022 10:55:22 +0000 (+0000) Subject: Merge "Refactoring related-runs for the mutable-markup (Spannable)" into devel/master X-Git-Tag: dali_2.1.25~1 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=commitdiff_plain;h=96d0515d26859b6ca0e4b8a6cdb6dce13d6f6281;hp=64ec76af20d8d55ea78cd5726a19d76072a0a321 Merge "Refactoring related-runs for the mutable-markup (Spannable)" into devel/master --- diff --git a/automated-tests/src/dali-toolkit-internal/CMakeLists.txt b/automated-tests/src/dali-toolkit-internal/CMakeLists.txt index 0c47772..ed393f0 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-AbstractStyleCharacterRun.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 69ba25b..41d8c0d 100644 --- a/dali-toolkit/internal/file.list +++ b/dali-toolkit/internal/file.list @@ -164,6 +164,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 826e894..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 @@ -486,6 +487,8 @@ Devel::PixelBuffer DrawGlyphsBackground(const ViewModel* model, Devel::PixelBuff const Vector4* const backgroundColorsBuffer = model->GetBackgroundColors(); const ColorIndex* const backgroundColorIndicesBuffer = model->GetBackgroundColorIndices(); + const DevelText::VerticalLineAlignment::Type verLineAlign = model->GetVerticalLineAlignment(); + // Create and initialize the pixel buffer. GlyphData glyphData; glyphData.verticalOffset = verticalOffset; @@ -507,13 +510,7 @@ Devel::PixelBuffer DrawGlyphsBackground(const ViewModel* model, Devel::PixelBuff glyphData.horizontalOffset += horizontalOffset; // Increases the vertical offset with the line's ascender. - glyphData.verticalOffset += static_cast(line.ascender); - - // Include line spacing after first line - if(lineIndex > 0u) - { - glyphData.verticalOffset += static_cast(line.lineSpacing); - } + glyphData.verticalOffset += static_cast(line.ascender + GetPreOffsetVerticalLineAlignment(line, verLineAlign)); float left = bufferWidth; float right = 0.0f; @@ -579,7 +576,7 @@ Devel::PixelBuffer DrawGlyphsBackground(const ViewModel* model, Devel::PixelBuff } // Increases the vertical offset with the line's descender. - glyphData.verticalOffset += static_cast(-line.descender); + glyphData.verticalOffset += static_cast(-line.descender + GetPostOffsetVerticalLineAlignment(line, verLineAlign)); } return glyphData.bitmapBuffer; @@ -856,29 +853,6 @@ PixelData Typesetter::Render(const Vector2& size, Toolkit::DevelText::TextDirect } } - // Calculate vertical line alignment - switch(mModel->GetVerticalLineAlignment()) - { - case DevelText::VerticalLineAlignment::TOP: - { - break; - } - case DevelText::VerticalLineAlignment::MIDDLE: - { - const auto& line = *mModel->GetLines(); - penY -= line.descender; - penY += static_cast(line.lineSpacing * 0.5f + line.descender); - break; - } - case DevelText::VerticalLineAlignment::BOTTOM: - { - const auto& line = *mModel->GetLines(); - const auto lineHeight = line.ascender + (-line.descender) + line.lineSpacing; - penY += static_cast(lineHeight - (line.ascender - line.descender)); - break; - } - } - // Generate the image buffers of the text for each different style first, // then combine all of them together as one final image buffer. We try to // do all of these in CPU only, so that once the final texture is generated, @@ -1046,6 +1020,8 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer(const uint32_t& bufferWidth, co const Vector& glyphToCharacterMap = mModel->GetGlyphsToCharacters(); const CharacterIndex* glyphToCharacterMapBuffer = glyphToCharacterMap.Begin(); + const DevelText::VerticalLineAlignment::Type verLineAlign = mModel->GetVerticalLineAlignment(); + // Traverses the lines of the text. for(LineIndex lineIndex = 0u; lineIndex < modelNumberOfLines; ++lineIndex) { @@ -1056,7 +1032,7 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer(const uint32_t& bufferWidth, co glyphData.horizontalOffset += horizontalOffset; // Increases the vertical offset with the line's ascender. - glyphData.verticalOffset += static_cast(line.ascender); + glyphData.verticalOffset += static_cast(line.ascender + GetPreOffsetVerticalLineAlignment(line, verLineAlign)); // Retrieves the glyph's outline width float outlineWidth = static_cast(mModel->GetOutlineWidth()); @@ -1357,7 +1333,7 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer(const uint32_t& bufferWidth, co } // Increases the vertical offset with the line's descender & line spacing. - glyphData.verticalOffset += static_cast(-line.descender + line.lineSpacing); + glyphData.verticalOffset += static_cast(-line.descender + GetPostOffsetVerticalLineAlignment(line, verLineAlign)); } return glyphData.bitmapBuffer;