From: David Steele Date: Tue, 22 Feb 2022 18:00:19 +0000 (+0000) Subject: Merge "Use RegisterUniqueProperty for some more renderers" into devel/master X-Git-Tag: dali_2.1.11~9 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=commitdiff_plain;h=076f84a43592f26ff0aa2bced54583f712800fe3;hp=1d71a8f7d7abd7729aa645ad062e530958097214 Merge "Use RegisterUniqueProperty for some more renderers" into devel/master --- diff --git a/automated-tests/src/dali-toolkit-internal/utc-Dali-TextEditor-internal.cpp b/automated-tests/src/dali-toolkit-internal/utc-Dali-TextEditor-internal.cpp index 0c55d97..46abf15 100644 --- a/automated-tests/src/dali-toolkit-internal/utc-Dali-TextEditor-internal.cpp +++ b/automated-tests/src/dali-toolkit-internal/utc-Dali-TextEditor-internal.cpp @@ -94,18 +94,255 @@ int UtcDaliTextEditorMarkupUnderline(void) DALI_TEST_EQUALS(numberOfUnderlineRuns, expectedNumberOfUnderlinedGlyphs, TEST_LOCATION); - Vector underlineRuns; + Vector underlineRuns; underlineRuns.Resize(numberOfUnderlineRuns); textEditorImpl.GetTextController()->GetTextModel()->GetUnderlineRuns(underlineRuns.Begin(), 0u, numberOfUnderlineRuns); //ABC are underlined - DALI_TEST_EQUALS(underlineRuns[0u].glyphIndex, 0u, TEST_LOCATION); - DALI_TEST_EQUALS(underlineRuns[1u].glyphIndex, 1u, TEST_LOCATION); - DALI_TEST_EQUALS(underlineRuns[2u].glyphIndex, 2u, TEST_LOCATION); + DALI_TEST_EQUALS(underlineRuns[0u].glyphRun.glyphIndex, 0u, TEST_LOCATION); + DALI_TEST_EQUALS(underlineRuns[1u].glyphRun.glyphIndex, 1u, TEST_LOCATION); + DALI_TEST_EQUALS(underlineRuns[2u].glyphRun.glyphIndex, 2u, TEST_LOCATION); //GH are underlined - DALI_TEST_EQUALS(underlineRuns[3u].glyphIndex, 5u, TEST_LOCATION); - DALI_TEST_EQUALS(underlineRuns[4u].glyphIndex, 6u, TEST_LOCATION); + DALI_TEST_EQUALS(underlineRuns[3u].glyphRun.glyphIndex, 5u, TEST_LOCATION); + DALI_TEST_EQUALS(underlineRuns[4u].glyphRun.glyphIndex, 6u, TEST_LOCATION); + + END_TEST; +} + +int UtcDaliTextEditorMarkupUnderlineAttributes(void) +{ + ToolkitTestApplication application; + tet_infoline(" UtcDaliTextEditorMarkupUnderlineAttributes "); + + TextEditor textEditor = TextEditor::New(); + + application.GetScene().Add(textEditor); + + std::string testText = + "startABC1then" + "ABC2then" + "ABC3then" + "ABC4then" + "ABC5then" + "ABC6then" + "ABC7then" + "ABC8then" + "ABC9end" + + ; + + textEditor.SetProperty(TextEditor::Property::TEXT, testText); + textEditor.SetProperty(TextEditor ::Property::ENABLE_MARKUP, true); + + application.SendNotification(); + application.Render(); + + const uint32_t NUMBER_OF_CASES = 9u; + uint32_t expectedNumberOfUnderlinedGlyphs = 36u; + + Toolkit::Internal::TextEditor& textEditorImpl = GetImpl(textEditor); + const Text::Length numberOfUnderlineRuns = textEditorImpl.GetTextController()->GetTextModel()->GetNumberOfUnderlineRuns(); + + DALI_TEST_EQUALS(numberOfUnderlineRuns, expectedNumberOfUnderlinedGlyphs, TEST_LOCATION); + + Vector underlineRuns; + underlineRuns.Resize(numberOfUnderlineRuns); + textEditorImpl.GetTextController()->GetTextModel()->GetUnderlineRuns(underlineRuns.Begin(), 0u, numberOfUnderlineRuns); + + struct DataOfCase + { + std::string title; + uint32_t startIndex; + uint32_t endIndex; + GlyphIndex startGlyphIndex; + GlyphIndex endGlyphIndex; + UnderlineStyleProperties properties; + }; + DataOfCase data[] = + { + //ABC1 + {"ABC1", + 0u, + 3u, + 5u, + 8u, + { + Text::Underline::SOLID, + Color::BLACK, + 0u, + 1u, + 2u, + false, + false, + false, + false, + false, + }}, + + //ABC2 + {"ABC2", + 4u, + 7u, + 13u, + 16u, + { + Text::Underline::SOLID, + Color::BLACK, + 0u, + 1u, + 2u, + true, + false, + false, + false, + false, + }}, + + //ABC3 + {"ABC3", + 8u, + 11u, + 21u, + 24u, + { + Text::Underline::DASHED, + Color::BLACK, + 0u, + 1u, + 2u, + true, + false, + false, + false, + false, + }}, + + //ABC4 + {"ABC4", + 12u, + 15u, + 29u, + 32u, + { + Text::Underline::DOUBLE, + Color::BLACK, + 0u, + 1u, + 2u, + true, + false, + false, + false, + false, + }}, + + //ABC5 + {"ABC5", + 16u, + 19u, + 37u, + 40u, + { + Text::Underline::SOLID, + Color::GREEN, + 0u, + 1u, + 2u, + false, + true, + false, + false, + false, + }}, + + //ABC6 + {"ABC6", + 20u, + 23u, + 45u, + 48u, + { + Text::Underline::SOLID, + Color::BLACK, + 5u, + 1u, + 2u, + false, + false, + true, + false, + false, + }}, + + //ABC7 + {"ABC7", + 24u, + 27u, + 53u, + 56u, + { + Text::Underline::DASHED, + Color::BLACK, + 0u, + 3u, + 2u, + true, + false, + false, + true, + false, + }}, + + //ABC8 + {"ABC8", + 28u, + 31u, + 61u, + 64u, + { + Text::Underline::DASHED, + Color::BLACK, + 0u, + 1u, + 4u, + true, + false, + false, + false, + true, + }}, + + // + {"", + 32u, + 35u, + 69u, + 72u, + { + Text::Underline::DASHED, + Color::BLUE, + 4u, + 2u, + 3u, + true, + true, + true, + true, + true, + }}, + + }; + + for(uint32_t i = 0; i < NUMBER_OF_CASES; i++) + { + tet_infoline(data[i].title.c_str()); + DALI_TEST_EQUALS(underlineRuns[data[i].startIndex].glyphRun.glyphIndex, data[i].startGlyphIndex, TEST_LOCATION); + DALI_TEST_EQUALS(underlineRuns[data[i].endIndex].glyphRun.glyphIndex, data[i].endGlyphIndex, TEST_LOCATION); + + DALI_TEST_CHECK(data[i].properties == underlineRuns[data[i].startIndex].properties); + DALI_TEST_CHECK(data[i].properties == underlineRuns[data[i].endIndex].properties); + } END_TEST; } @@ -376,3 +613,28 @@ int UtcDaliTextEditorMarkupStrikethrough(void) END_TEST; } + +int UtcDaliTextEditorMarkupStrikethroughNoEndTag(void) +{ + ToolkitTestApplication application; + tet_infoline(" UtcDaliTextEditorMarkupStrikethroughNoEndTag "); + + TextEditor textEditor = TextEditor::New(); + + application.GetScene().Add(textEditor); + + textEditor.SetProperty(TextEditor::Property::TEXT, "ABC"); + textEditor.SetProperty(TextEditor ::Property::ENABLE_MARKUP, true); + + application.SendNotification(); + application.Render(); + + uint32_t expectedNumberOfStrikethroughGlyphs = 0u; + + Toolkit::Internal::TextEditor& textEditorImpl = GetImpl(textEditor); + Text::Length numberOfStrikethroughRuns = textEditorImpl.GetTextController()->GetTextModel()->GetNumberOfStrikethroughRuns(); + + DALI_TEST_EQUALS(numberOfStrikethroughRuns, expectedNumberOfStrikethroughGlyphs, TEST_LOCATION); + + END_TEST; +} \ No newline at end of file diff --git a/automated-tests/src/dali-toolkit-internal/utc-Dali-TextField-internal.cpp b/automated-tests/src/dali-toolkit-internal/utc-Dali-TextField-internal.cpp index 57fb32b..77366b6 100644 --- a/automated-tests/src/dali-toolkit-internal/utc-Dali-TextField-internal.cpp +++ b/automated-tests/src/dali-toolkit-internal/utc-Dali-TextField-internal.cpp @@ -176,18 +176,255 @@ int UtcDaliTextFieldMarkupUnderline(void) DALI_TEST_EQUALS(numberOfUnderlineRuns, expectedNumberOfUnderlinedGlyphs, TEST_LOCATION); - Vector underlineRuns; + Vector underlineRuns; underlineRuns.Resize(numberOfUnderlineRuns); textFieldImpl.GetTextController()->GetTextModel()->GetUnderlineRuns(underlineRuns.Begin(), 0u, numberOfUnderlineRuns); //ABC are underlined - DALI_TEST_EQUALS(underlineRuns[0u].glyphIndex, 0u, TEST_LOCATION); - DALI_TEST_EQUALS(underlineRuns[1u].glyphIndex, 1u, TEST_LOCATION); - DALI_TEST_EQUALS(underlineRuns[2u].glyphIndex, 2u, TEST_LOCATION); + DALI_TEST_EQUALS(underlineRuns[0u].glyphRun.glyphIndex, 0u, TEST_LOCATION); + DALI_TEST_EQUALS(underlineRuns[1u].glyphRun.glyphIndex, 1u, TEST_LOCATION); + DALI_TEST_EQUALS(underlineRuns[2u].glyphRun.glyphIndex, 2u, TEST_LOCATION); //GH are underlined - DALI_TEST_EQUALS(underlineRuns[3u].glyphIndex, 5u, TEST_LOCATION); - DALI_TEST_EQUALS(underlineRuns[4u].glyphIndex, 6u, TEST_LOCATION); + DALI_TEST_EQUALS(underlineRuns[3u].glyphRun.glyphIndex, 5u, TEST_LOCATION); + DALI_TEST_EQUALS(underlineRuns[4u].glyphRun.glyphIndex, 6u, TEST_LOCATION); + + END_TEST; +} + +int UtcDaliTextFieldMarkupUnderlineAttributes(void) +{ + ToolkitTestApplication application; + tet_infoline(" UtcDaliTextFieldMarkupUnderlineAttributes "); + + TextField textField = TextField::New(); + + application.GetScene().Add(textField); + + std::string testText = + "startABC1then" + "ABC2then" + "ABC3then" + "ABC4then" + "ABC5then" + "ABC6then" + "ABC7then" + "ABC8then" + "ABC9end" + + ; + + textField.SetProperty(TextField::Property::TEXT, testText); + textField.SetProperty(TextField ::Property::ENABLE_MARKUP, true); + + application.SendNotification(); + application.Render(); + + const uint32_t NUMBER_OF_CASES = 9u; + uint32_t expectedNumberOfUnderlinedGlyphs = 36u; + + Toolkit::Internal::TextField& textFieldImpl = GetImpl(textField); + const Text::Length numberOfUnderlineRuns = textFieldImpl.GetTextController()->GetTextModel()->GetNumberOfUnderlineRuns(); + + DALI_TEST_EQUALS(numberOfUnderlineRuns, expectedNumberOfUnderlinedGlyphs, TEST_LOCATION); + + Vector underlineRuns; + underlineRuns.Resize(numberOfUnderlineRuns); + textFieldImpl.GetTextController()->GetTextModel()->GetUnderlineRuns(underlineRuns.Begin(), 0u, numberOfUnderlineRuns); + + struct DataOfCase + { + std::string title; + uint32_t startIndex; + uint32_t endIndex; + GlyphIndex startGlyphIndex; + GlyphIndex endGlyphIndex; + UnderlineStyleProperties properties; + }; + DataOfCase data[] = + { + //ABC1 + {"ABC1", + 0u, + 3u, + 5u, + 8u, + { + Text::Underline::SOLID, + Color::BLACK, + 0u, + 1u, + 2u, + false, + false, + false, + false, + false, + }}, + + //ABC2 + {"ABC2", + 4u, + 7u, + 13u, + 16u, + { + Text::Underline::SOLID, + Color::BLACK, + 0u, + 1u, + 2u, + true, + false, + false, + false, + false, + }}, + + //ABC3 + {"ABC3", + 8u, + 11u, + 21u, + 24u, + { + Text::Underline::DASHED, + Color::BLACK, + 0u, + 1u, + 2u, + true, + false, + false, + false, + false, + }}, + + //ABC4 + {"ABC4", + 12u, + 15u, + 29u, + 32u, + { + Text::Underline::DOUBLE, + Color::BLACK, + 0u, + 1u, + 2u, + true, + false, + false, + false, + false, + }}, + + //ABC5 + {"ABC5", + 16u, + 19u, + 37u, + 40u, + { + Text::Underline::SOLID, + Color::GREEN, + 0u, + 1u, + 2u, + false, + true, + false, + false, + false, + }}, + + //ABC6 + {"ABC6", + 20u, + 23u, + 45u, + 48u, + { + Text::Underline::SOLID, + Color::BLACK, + 5u, + 1u, + 2u, + false, + false, + true, + false, + false, + }}, + + //ABC7 + {"ABC7", + 24u, + 27u, + 53u, + 56u, + { + Text::Underline::DASHED, + Color::BLACK, + 0u, + 3u, + 2u, + true, + false, + false, + true, + false, + }}, + + //ABC8 + {"ABC8", + 28u, + 31u, + 61u, + 64u, + { + Text::Underline::DASHED, + Color::BLACK, + 0u, + 1u, + 4u, + true, + false, + false, + false, + true, + }}, + + // + {"", + 32u, + 35u, + 69u, + 72u, + { + Text::Underline::DASHED, + Color::BLUE, + 4u, + 2u, + 3u, + true, + true, + true, + true, + true, + }}, + + }; + + for(uint32_t i = 0; i < NUMBER_OF_CASES; i++) + { + tet_infoline(data[i].title.c_str()); + DALI_TEST_EQUALS(underlineRuns[data[i].startIndex].glyphRun.glyphIndex, data[i].startGlyphIndex, TEST_LOCATION); + DALI_TEST_EQUALS(underlineRuns[data[i].endIndex].glyphRun.glyphIndex, data[i].endGlyphIndex, TEST_LOCATION); + + DALI_TEST_CHECK(data[i].properties == underlineRuns[data[i].startIndex].properties); + DALI_TEST_CHECK(data[i].properties == underlineRuns[data[i].endIndex].properties); + } END_TEST; } @@ -450,3 +687,28 @@ int UtcDaliTextFieldMarkupStrikethrough(void) END_TEST; } + +int UtcDaliTextFieldMarkupStrikethroughNoEndTag(void) +{ + ToolkitTestApplication application; + tet_infoline(" UtcDaliTextFieldMarkupStrikethroughNoEndTag "); + + TextField textField = TextField::New(); + + application.GetScene().Add(textField); + + textField.SetProperty(TextField::Property::TEXT, "ABC"); + textField.SetProperty(TextField ::Property::ENABLE_MARKUP, true); + + application.SendNotification(); + application.Render(); + + uint32_t expectedNumberOfStrikethroughGlyphs = 0u; + + Toolkit::Internal::TextField& textFieldImpl = GetImpl(textField); + Text::Length numberOfStrikethroughRuns = textFieldImpl.GetTextController()->GetTextModel()->GetNumberOfStrikethroughRuns(); + + DALI_TEST_EQUALS(numberOfStrikethroughRuns, expectedNumberOfStrikethroughGlyphs, TEST_LOCATION); + + END_TEST; +} \ No newline at end of file diff --git a/automated-tests/src/dali-toolkit-internal/utc-Dali-TextLabel-internal.cpp b/automated-tests/src/dali-toolkit-internal/utc-Dali-TextLabel-internal.cpp index ba067f6..b1c380a 100644 --- a/automated-tests/src/dali-toolkit-internal/utc-Dali-TextLabel-internal.cpp +++ b/automated-tests/src/dali-toolkit-internal/utc-Dali-TextLabel-internal.cpp @@ -15,6 +15,7 @@ * */ +#include #include #include @@ -53,18 +54,255 @@ int UtcDaliTextLabelMarkupUnderline(void) DALI_TEST_EQUALS(numberOfUnderlineRuns, expectedNumberOfUnderlinedGlyphs, TEST_LOCATION); - Vector underlineRuns; + Vector underlineRuns; underlineRuns.Resize(numberOfUnderlineRuns); textLabelImpl.GetTextController()->GetTextModel()->GetUnderlineRuns(underlineRuns.Begin(), 0u, numberOfUnderlineRuns); //ABC are underlined - DALI_TEST_EQUALS(underlineRuns[0u].glyphIndex, 0u, TEST_LOCATION); - DALI_TEST_EQUALS(underlineRuns[1u].glyphIndex, 1u, TEST_LOCATION); - DALI_TEST_EQUALS(underlineRuns[2u].glyphIndex, 2u, TEST_LOCATION); + DALI_TEST_EQUALS(underlineRuns[0u].glyphRun.glyphIndex, 0u, TEST_LOCATION); + DALI_TEST_EQUALS(underlineRuns[1u].glyphRun.glyphIndex, 1u, TEST_LOCATION); + DALI_TEST_EQUALS(underlineRuns[2u].glyphRun.glyphIndex, 2u, TEST_LOCATION); //GH are underlined - DALI_TEST_EQUALS(underlineRuns[3u].glyphIndex, 5u, TEST_LOCATION); - DALI_TEST_EQUALS(underlineRuns[4u].glyphIndex, 6u, TEST_LOCATION); + DALI_TEST_EQUALS(underlineRuns[3u].glyphRun.glyphIndex, 5u, TEST_LOCATION); + DALI_TEST_EQUALS(underlineRuns[4u].glyphRun.glyphIndex, 6u, TEST_LOCATION); + + END_TEST; +} + +int UtcDaliTextLabelMarkupUnderlineAttributes(void) +{ + ToolkitTestApplication application; + tet_infoline(" UtcDaliTextLabelMarkupUnderlineAttributes "); + + TextLabel textLabel = TextLabel::New(); + + application.GetScene().Add(textLabel); + + std::string testText = + "startABC1then" + "ABC2then" + "ABC3then" + "ABC4then" + "ABC5then" + "ABC6then" + "ABC7then" + "ABC8then" + "ABC9end" + + ; + + textLabel.SetProperty(TextLabel::Property::TEXT, testText); + textLabel.SetProperty(TextLabel ::Property::ENABLE_MARKUP, true); + + application.SendNotification(); + application.Render(); + + const uint32_t NUMBER_OF_CASES = 9u; + uint32_t expectedNumberOfUnderlinedGlyphs = 36u; + + Toolkit::Internal::TextLabel& textLabelImpl = GetImpl(textLabel); + const Text::Length numberOfUnderlineRuns = textLabelImpl.GetTextController()->GetTextModel()->GetNumberOfUnderlineRuns(); + + DALI_TEST_EQUALS(numberOfUnderlineRuns, expectedNumberOfUnderlinedGlyphs, TEST_LOCATION); + + Vector underlineRuns; + underlineRuns.Resize(numberOfUnderlineRuns); + textLabelImpl.GetTextController()->GetTextModel()->GetUnderlineRuns(underlineRuns.Begin(), 0u, numberOfUnderlineRuns); + + struct DataOfCase + { + std::string title; + uint32_t startIndex; + uint32_t endIndex; + GlyphIndex startGlyphIndex; + GlyphIndex endGlyphIndex; + UnderlineStyleProperties properties; + }; + DataOfCase data[] = + { + //ABC1 + {"ABC1", + 0u, + 3u, + 5u, + 8u, + { + Text::Underline::SOLID, + Color::BLACK, + 0u, + 1u, + 2u, + false, + false, + false, + false, + false, + }}, + + //ABC2 + {"ABC2", + 4u, + 7u, + 13u, + 16u, + { + Text::Underline::SOLID, + Color::BLACK, + 0u, + 1u, + 2u, + true, + false, + false, + false, + false, + }}, + + //ABC3 + {"ABC3", + 8u, + 11u, + 21u, + 24u, + { + Text::Underline::DASHED, + Color::BLACK, + 0u, + 1u, + 2u, + true, + false, + false, + false, + false, + }}, + + //ABC4 + {"ABC4", + 12u, + 15u, + 29u, + 32u, + { + Text::Underline::DOUBLE, + Color::BLACK, + 0u, + 1u, + 2u, + true, + false, + false, + false, + false, + }}, + + //ABC5 + {"ABC5", + 16u, + 19u, + 37u, + 40u, + { + Text::Underline::SOLID, + Color::GREEN, + 0u, + 1u, + 2u, + false, + true, + false, + false, + false, + }}, + + //ABC6 + {"ABC6", + 20u, + 23u, + 45u, + 48u, + { + Text::Underline::SOLID, + Color::BLACK, + 5u, + 1u, + 2u, + false, + false, + true, + false, + false, + }}, + + //ABC7 + {"ABC7", + 24u, + 27u, + 53u, + 56u, + { + Text::Underline::DASHED, + Color::BLACK, + 0u, + 3u, + 2u, + true, + false, + false, + true, + false, + }}, + + //ABC8 + {"ABC8", + 28u, + 31u, + 61u, + 64u, + { + Text::Underline::DASHED, + Color::BLACK, + 0u, + 1u, + 4u, + true, + false, + false, + false, + true, + }}, + + // + {"", + 32u, + 35u, + 69u, + 72u, + { + Text::Underline::DASHED, + Color::BLUE, + 4u, + 2u, + 3u, + true, + true, + true, + true, + true, + }}, + + }; + + for(uint32_t i = 0; i < NUMBER_OF_CASES; i++) + { + tet_infoline(data[i].title.c_str()); + DALI_TEST_EQUALS(underlineRuns[data[i].startIndex].glyphRun.glyphIndex, data[i].startGlyphIndex, TEST_LOCATION); + DALI_TEST_EQUALS(underlineRuns[data[i].endIndex].glyphRun.glyphIndex, data[i].endGlyphIndex, TEST_LOCATION); + + DALI_TEST_CHECK(data[i].properties == underlineRuns[data[i].startIndex].properties); + DALI_TEST_CHECK(data[i].properties == underlineRuns[data[i].endIndex].properties); + } END_TEST; } @@ -262,3 +500,28 @@ int UtcDaliTextLabelMarkupStrikethrough(void) END_TEST; } + +int UtcDaliTextLabelMarkupStrikethroughNoEndTag(void) +{ + ToolkitTestApplication application; + tet_infoline(" UtcDaliTextLabelMarkupStrikethroughNoEndTag "); + + TextLabel textLabel = TextLabel::New(); + + application.GetScene().Add(textLabel); + + textLabel.SetProperty(TextLabel::Property::TEXT, "ABC"); + textLabel.SetProperty(TextLabel ::Property::ENABLE_MARKUP, true); + + application.SendNotification(); + application.Render(); + + uint32_t expectedNumberOfStrikethroughGlyphs = 0u; + + Toolkit::Internal::TextLabel& textLabelImpl = GetImpl(textLabel); + Text::Length numberOfStrikethroughRuns = textLabelImpl.GetTextController()->GetTextModel()->GetNumberOfStrikethroughRuns(); + + DALI_TEST_EQUALS(numberOfStrikethroughRuns, expectedNumberOfStrikethroughGlyphs, TEST_LOCATION); + + END_TEST; +} \ No newline at end of file diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-scene-holder-impl.h b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-scene-holder-impl.h index fb67a4b..8075dbe 100644 --- a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-scene-holder-impl.h +++ b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-scene-holder-impl.h @@ -119,6 +119,8 @@ public: Dali::Integration::SceneHolder::WheelEventSignalType& WheelEventSignal(); + Dali::Integration::SceneHolder::WheelEventGeneratedSignalType& WheelEventGeneratedSignal(); + Integration::Scene GetScene(); Dali::RenderSurfaceInterface& GetRenderSurface(); diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-scene-holder.cpp b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-scene-holder.cpp index e18809a..8bcb3c0 100644 --- a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-scene-holder.cpp +++ b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-scene-holder.cpp @@ -115,6 +115,11 @@ Dali::Integration::SceneHolder::WheelEventSignalType& SceneHolder::WheelEventSig return mScene.WheelEventSignal(); } +Dali::Integration::SceneHolder::WheelEventGeneratedSignalType& SceneHolder::WheelEventGeneratedSignal() +{ + return mScene.WheelEventGeneratedSignal(); +} + Integration::Scene SceneHolder::GetScene() { return mScene; @@ -235,6 +240,11 @@ SceneHolder::WheelEventSignalType& SceneHolder::WheelEventSignal() return GetImplementation( *this ).WheelEventSignal(); } +SceneHolder::WheelEventGeneratedSignalType& SceneHolder::WheelEventGeneratedSignal() +{ + return GetImplementation( *this ).WheelEventGeneratedSignal(); +} + } // Integration } // Dali diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-window.cpp b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-window.cpp index b8cc1bc..9fc2763 100644 --- a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-window.cpp +++ b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-window.cpp @@ -272,6 +272,11 @@ WheelEventSignalType& WheelEventSignal( Window window ) return GetImplementation( window ).WheelEventSignal(); } +WheelEventGeneratedSignalType& WheelEventGeneratedSignal( Window window ) +{ + return GetImplementation( window ).WheelEventGeneratedSignal(); +} + VisibilityChangedSignalType& VisibilityChangedSignal( Window window ) { return GetImplementation( window ).mVisibilityChangedSignal; diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-window.h b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-window.h index d102f6a..0d4e219 100644 --- a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-window.h +++ b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-window.h @@ -95,6 +95,7 @@ namespace DevelWindow typedef Signal< void () > EventProcessingFinishedSignalType; typedef Signal< bool (const KeyEvent&) > KeyEventGeneratedSignalType; typedef Signal< void (const WheelEvent&) > WheelEventSignalType; +typedef Signal< bool (const WheelEvent&) > WheelEventGeneratedSignalType; typedef Signal< void ( Window, bool ) > VisibilityChangedSignalType; Dali::Window Get( Actor actor ); @@ -107,6 +108,7 @@ void AddFramePresentedCallback( Window window, std::unique_ptr< CallbackBase > c EventProcessingFinishedSignalType& EventProcessingFinishedSignal( Window window ); KeyEventGeneratedSignalType& KeyEventGeneratedSignal( Dali::Window window ); WheelEventSignalType& WheelEventSignal( Window window ); +WheelEventGeneratedSignalType& WheelEventGeneratedSignal( Dali::Window window ); VisibilityChangedSignalType& VisibilityChangedSignal( Window window ); } diff --git a/automated-tests/src/dali-toolkit/utc-Dali-KeyboardFocusManager.cpp b/automated-tests/src/dali-toolkit/utc-Dali-KeyboardFocusManager.cpp index 6d0e8af..4780331 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-KeyboardFocusManager.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-KeyboardFocusManager.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -247,6 +248,34 @@ public: bool mIsCalled; }; +class WheelEventCallback : public Dali::ConnectionTracker +{ +public: + /** + * Constructor + * @param[in] returnValue Set return value of WheelEvent callback. + * */ + WheelEventCallback( bool consumed ) + : mConsumed( consumed ), + mIsCalled( false ) + { + } + + bool Callback( Actor actor, const WheelEvent& wheelEvent ) + { + mIsCalled = true; + return mConsumed; + } + + void Callback( const WheelEvent& wheelEvent ) + { + mIsCalled = true; + } + + bool mConsumed; + bool mIsCalled; +}; + // Used to connect to signals via the ConnectSignal Handle method struct CallbackFunctor { @@ -2036,4 +2065,46 @@ int UtcDaliKeyboardFocusManagerWithKeyboardFocusableChildren(void) DALI_TEST_CHECK(manager.GetCurrentFocusActor() == second); END_TEST; +} + +int UtcDaliKeyboardFocusManagerCheckWheelEvent(void) +{ + ToolkitTestApplication application; + + tet_infoline( "UtcDaliKeyboardFocusManagerCheckWheelEvent" ); + Dali::Integration::Scene scene = application.GetScene(); + + KeyboardFocusManager manager = KeyboardFocusManager::Get(); + DALI_TEST_CHECK( ! manager.GetCurrentFocusActor() ); + + // Create the first actor and add it to the stage + Actor parent = Actor::New(); + parent.SetProperty( Actor::Property::KEYBOARD_FOCUSABLE,true); + + Actor child = Actor::New(); + child.SetProperty( Actor::Property::KEYBOARD_FOCUSABLE,true); + + parent.Add(child); + scene.Add(parent); + + WheelEventCallback childCallback( false ); + child.WheelEventSignal().Connect( &childCallback, &WheelEventCallback::Callback ); + + WheelEventCallback parentCallback( true ); + parent.WheelEventSignal().Connect( &parentCallback, &WheelEventCallback::Callback ); + + WheelEventCallback sceneCallback( false ); + scene.WheelEventSignal().Connect( &sceneCallback, &WheelEventCallback::Callback ); + + manager.SetCurrentFocusActor( child ); + + // Emit custom wheel event is comming to KeyboardFocusManager + Integration::WheelEvent event(Integration::WheelEvent::CUSTOM_WHEEL, 0, 0u, Vector2(0.0f, 0.0f), 1, 1000u); + application.ProcessEvent(event); + + DALI_TEST_CHECK( childCallback.mIsCalled ); + DALI_TEST_CHECK( parentCallback.mIsCalled ); + DALI_TEST_CHECK( !sceneCallback.mIsCalled ); + + END_TEST; } \ No newline at end of file diff --git a/dali-toolkit/internal/file.list b/dali-toolkit/internal/file.list index e57fa31..c65b61e 100644 --- a/dali-toolkit/internal/file.list +++ b/dali-toolkit/internal/file.list @@ -149,7 +149,9 @@ SET( toolkit_src_files ${toolkit_src_dir}/text/markup-processor-background.cpp ${toolkit_src_dir}/text/markup-processor-span.cpp ${toolkit_src_dir}/text/markup-processor-strikethrough.cpp + ${toolkit_src_dir}/text/markup-processor-underline.cpp ${toolkit_src_dir}/text/markup-processor-helper-functions.cpp + ${toolkit_src_dir}/text/markup-processor-attribute-helper-functions.cpp ${toolkit_src_dir}/text/multi-language-support.cpp ${toolkit_src_dir}/text/hidden-text.cpp ${toolkit_src_dir}/text/input-filter.cpp @@ -196,6 +198,8 @@ SET( toolkit_src_files ${toolkit_src_dir}/text/rendering/text-backend-impl.cpp ${toolkit_src_dir}/text/rendering/text-typesetter.cpp ${toolkit_src_dir}/text/rendering/view-model.cpp + ${toolkit_src_dir}/text/rendering/styles/underline-helper-functions.cpp + ${toolkit_src_dir}/text/rendering/styles/strikethrough-helper-functions ${toolkit_src_dir}/transition/fade-transition-impl.cpp ${toolkit_src_dir}/transition/slide-transition-impl.cpp ${toolkit_src_dir}/transition/scale-transition-impl.cpp diff --git a/dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.cpp b/dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.cpp index cc80372..4afb39a 100644 --- a/dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.cpp +++ b/dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.cpp @@ -145,6 +145,7 @@ void KeyboardFocusManager::OnAdaptorInit() { (*iter).KeyEventSignal().Connect(mSlotDelegate, &KeyboardFocusManager::OnKeyEvent); (*iter).TouchedSignal().Connect(mSlotDelegate, &KeyboardFocusManager::OnTouch); + (*iter).WheelEventGeneratedSignal().Connect(mSlotDelegate, &KeyboardFocusManager::OnWheelEvent); Dali::Window window = DevelWindow::DownCast(*iter); if(window) { @@ -161,6 +162,7 @@ void KeyboardFocusManager::OnSceneHolderCreated(Dali::Integration::SceneHolder& { sceneHolder.KeyEventSignal().Connect(mSlotDelegate, &KeyboardFocusManager::OnKeyEvent); sceneHolder.TouchedSignal().Connect(mSlotDelegate, &KeyboardFocusManager::OnTouch); + sceneHolder.WheelEventGeneratedSignal().Connect(mSlotDelegate, &KeyboardFocusManager::OnWheelEvent); Dali::Window window = DevelWindow::DownCast(sceneHolder); if(window) { @@ -1008,6 +1010,49 @@ void KeyboardFocusManager::OnTouch(const TouchEvent& touch) } } +bool KeyboardFocusManager::OnWheelEvent(const WheelEvent& event) +{ + bool consumed = false; + Actor actor = GetCurrentFocusActor(); + if(actor) + { + // Notify the actor about the wheel event + consumed = EmitWheelSignals(actor, event); + } + return consumed; +} + +bool KeyboardFocusManager::EmitWheelSignals(Actor actor, const WheelEvent& event) +{ + bool consumed = false; + + if(actor) + { + Dali::Actor oldParent(actor.GetParent()); + + // Only do the conversion and emit the signal if the actor's wheel signal has connections. + if(!actor.WheelEventSignal().Empty()) + { + // Emit the signal to the parent + consumed = actor.WheelEventSignal().Emit(actor, event); + } + // if actor doesn't consume WheelEvent, give WheelEvent to its parent. + if(!consumed) + { + // The actor may have been removed/reparented during the signal callbacks. + Dali::Actor parent = actor.GetParent(); + + if(parent && + (parent == oldParent)) + { + consumed = EmitWheelSignals(parent, event); + } + } + } + + return consumed; +} + void KeyboardFocusManager::OnWindowFocusChanged(Window window, bool focusIn) { if(focusIn && mCurrentFocusedWindow.GetHandle() != window.GetRootLayer()) diff --git a/dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.h b/dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.h index 8212a79..783e3f5 100644 --- a/dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.h +++ b/dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.h @@ -292,6 +292,12 @@ private: void OnTouch(const TouchEvent& touch); /** + * Callback for the wheel event when the custom wheel event occurs. + * @param[in] wheel The WheelEvent information + */ + bool OnWheelEvent(const WheelEvent& wheel); + + /** * Called when the window focus is changed. * @param[in] window The window whose focus is changed * @param[in] focusIn Whether the focus is in/out @@ -303,6 +309,14 @@ private: */ Actor GetFocusActorFromCurrentWindow(); + /** + * Recursively deliver events to the control and its parents, until the event is consumed or the stage is reached. + * @param[in] actor The actor got WheelEvent. + * @param[in] event The WheelEvent. + * @return True if WheelEvent is consumed. + */ + bool EmitWheelSignals(Actor actor, const WheelEvent& event); + private: // Undefined KeyboardFocusManager(const KeyboardFocusManager&); diff --git a/dali-toolkit/internal/text/logical-model-impl.cpp b/dali-toolkit/internal/text/logical-model-impl.cpp index f1fd1f5..4516662 100644 --- a/dali-toolkit/internal/text/logical-model-impl.cpp +++ b/dali-toolkit/internal/text/logical-model-impl.cpp @@ -471,6 +471,11 @@ void LogicalModel::ClearFontDescriptionRuns() FreeFontFamilyNames(mFontDescriptionRuns); } +void LogicalModel::ClearStrikethroughRuns() +{ + mStrikethroughCharacterRuns.Clear(); +} + void LogicalModel::CreateParagraphInfo(CharacterIndex startIndex, Length numberOfCharacters) { diff --git a/dali-toolkit/internal/text/logical-model-impl.h b/dali-toolkit/internal/text/logical-model-impl.h index 1bed342..08c636d 100644 --- a/dali-toolkit/internal/text/logical-model-impl.h +++ b/dali-toolkit/internal/text/logical-model-impl.h @@ -153,6 +153,11 @@ public: */ void ClearFontDescriptionRuns(); + /** + * @brief Clears the strikethrough runs. + */ + void ClearStrikethroughRuns(); + // Paragraphs /** diff --git a/dali-toolkit/internal/text/markup-processor-attribute-helper-functions.cpp b/dali-toolkit/internal/text/markup-processor-attribute-helper-functions.cpp new file mode 100644 index 0000000..da00996 --- /dev/null +++ b/dali-toolkit/internal/text/markup-processor-attribute-helper-functions.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2015 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 + +// INTERNAL INCLUDES +#include + +// EXTERNAL INCLUDES +#include + +namespace Dali +{ +namespace Toolkit +{ +namespace Text +{ +void CopyAttributeValueFromBuffer(const Attribute& attribute, const Length maxLengthAttributeValue, char* value) +{ + const Length length = attribute.valueLength > maxLengthAttributeValue ? maxLengthAttributeValue : attribute.valueLength; + memcpy(value, attribute.valueBuffer, length); + value[length] = 0; +} + +float ProcessFloatAttribute(const Attribute& attribute) +{ + return StringToFloat(attribute.valueBuffer); +} + +} // namespace Text + +} // namespace Toolkit + +} // namespace Dali diff --git a/dali-toolkit/internal/text/markup-processor-attribute-helper-functions.h b/dali-toolkit/internal/text/markup-processor-attribute-helper-functions.h new file mode 100644 index 0000000..52771b5 --- /dev/null +++ b/dali-toolkit/internal/text/markup-processor-attribute-helper-functions.h @@ -0,0 +1,88 @@ +#ifndef DALI_TOOLKIT_TEXT_MARKUP_PROCESSOR_ATTRIBUTE_HELPER_FUNCTIONS_H +#define DALI_TOOLKIT_TEXT_MARKUP_PROCESSOR_ATTRIBUTE_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 + +// EXTERNAL INCLUDES +#include + +namespace Dali +{ +namespace Toolkit +{ +namespace Text +{ +struct Attribute; + +/** + * @brief Copy the value from attribute buffer to value. + * + * @param[in] attribute the value of attribute. + * @param[in] maxLengthAttributeValue the maximum length of any of the possible value for attribute + * @param[out] value the value container. + * + */ +void CopyAttributeValueFromBuffer(const Attribute& attribute, const Length maxLengthAttributeValue, char* value); + +/** + * @brief Process the float attribute value from buffer. + * + * @param[in] attribute the float attribute. + * + * @return The float value. + */ +float ProcessFloatAttribute(const Attribute& attribute); + +/** + * @brief Process the Enumeration attribute value from buffer. + * + * @param[in] attribute the Enumeration attribute. + * @param[in] maxLengthAttributeValue the maximum length of any of the possible value for attribute + * @param[in] funcStringToEnum the function converts string value to enum value + * @param[out] enumValue the enum value + * + * @return True if the enum value was processed successfully + * + */ +template +bool ProcessEnumerationAttribute(const Attribute& attribute, + const Length maxLengthAttributeValue, + std::function funcStringToEnum, + T& enumValue) +{ + char* value = new char[maxLengthAttributeValue + 1u]; + + CopyAttributeValueFromBuffer(attribute, maxLengthAttributeValue, value); + + enumValue = funcStringToEnum(value); // @TODO: the functions that process Enum value should be refactored to return bool from Scripting::GetEnumeration + + delete[] value; + + return true; +} + +} // namespace Text + +} // namespace Toolkit + +} // namespace Dali + +#endif // DALI_TOOLKIT_TEXT_MARKUP_PROCESSOR_ATTRIBUTE_HELPER_FUNCTIONS_H diff --git a/dali-toolkit/internal/text/markup-processor-font.cpp b/dali-toolkit/internal/text/markup-processor-font.cpp index df8b6ec..0c469b8 100644 --- a/dali-toolkit/internal/text/markup-processor-font.cpp +++ b/dali-toolkit/internal/text/markup-processor-font.cpp @@ -24,6 +24,7 @@ // INTERNAL INCLUDES #include +#include #include #include @@ -68,35 +69,23 @@ void ProcessFontFamily(const Attribute& attribute, FontDescriptionRun& fontRun) void ProcessFontSize(const Attribute& attribute, FontDescriptionRun& fontRun) { // 64.f is used to convert from point size to 26.6 pixel format. - fontRun.size = static_cast(StringToFloat(attribute.valueBuffer) * PIXEL_FORMAT_64_FACTOR); + fontRun.size = static_cast(ProcessFloatAttribute(attribute) * PIXEL_FORMAT_64_FACTOR); fontRun.sizeDefined = true; } void ProcessFontWeight(const Attribute& attribute, FontDescriptionRun& fontRun) { - char value[MAX_FONT_ATTRIBUTE_SIZE + 1u]; - processFontAttributeValue(value, attribute); - - fontRun.weight = StringToWeight(value); - fontRun.weightDefined = true; + fontRun.weightDefined = ProcessEnumerationAttribute(attribute, MAX_FONT_ATTRIBUTE_SIZE, &StringToWeight, fontRun.weight); } void ProcessFontWidth(const Attribute& attribute, FontDescriptionRun& fontRun) { - char value[MAX_FONT_ATTRIBUTE_SIZE + 1u]; - processFontAttributeValue(value, attribute); - - fontRun.width = StringToWidth(value); - fontRun.widthDefined = true; + fontRun.widthDefined = ProcessEnumerationAttribute(attribute, MAX_FONT_ATTRIBUTE_SIZE, &StringToWidth, fontRun.width); } void ProcessFontSlant(const Attribute& attribute, FontDescriptionRun& fontRun) { - char value[MAX_FONT_ATTRIBUTE_SIZE + 1u]; - processFontAttributeValue(value, attribute); - - fontRun.slant = StringToSlant(value); - fontRun.slantDefined = true; + fontRun.slantDefined = ProcessEnumerationAttribute(attribute, MAX_FONT_ATTRIBUTE_SIZE, &StringToSlant, fontRun.slant); } void ProcessFontTag(const Tag& tag, FontDescriptionRun& fontRun) diff --git a/dali-toolkit/internal/text/markup-processor-helper-functions.cpp b/dali-toolkit/internal/text/markup-processor-helper-functions.cpp index ce8bcee..e4cb1c4 100644 --- a/dali-toolkit/internal/text/markup-processor-helper-functions.cpp +++ b/dali-toolkit/internal/text/markup-processor-helper-functions.cpp @@ -38,6 +38,8 @@ const char FIRST_UPPER_CASE = 0x41; // ASCII value of the one after the first up const char LAST_UPPER_CASE = 0x5b; // ASCII value of the one after the last upper case character (Z). const char TO_LOWER_CASE = 32; // Value to add to a upper case character to transform it into a lower case. +const unsigned int MAX_FLOAT_ATTRIBUTE_SIZE = 17u; ///< The maximum length of any of the possible float values. +99999.999999999f (sign, five digits, dot, nine digits, f) + const char WEB_COLOR_TOKEN('#'); const char* const HEX_COLOR_TOKEN("0x"); const char* const ALPHA_ONE("FF"); diff --git a/dali-toolkit/internal/text/markup-processor-helper-functions.h b/dali-toolkit/internal/text/markup-processor-helper-functions.h index d7a6596..a28c1cb 100644 --- a/dali-toolkit/internal/text/markup-processor-helper-functions.h +++ b/dali-toolkit/internal/text/markup-processor-helper-functions.h @@ -193,6 +193,15 @@ void Vector2ToString(const Vector2& value, std::string& vector2Str); */ void UnderlineTypeStringToTypeValue(const char* const typeStr, Length length, Text::Underline::Type& retType); +/** + * @brief Converts a string into a float value. + * + * @param[in] floatStr A float packed inside a string. + * + * @return The float value. + */ +float StringToFloat(const char* const floatStr); + } // namespace Text } // namespace Toolkit diff --git a/dali-toolkit/internal/text/markup-processor-underline.cpp b/dali-toolkit/internal/text/markup-processor-underline.cpp new file mode 100644 index 0000000..063f3fe --- /dev/null +++ b/dali-toolkit/internal/text/markup-processor-underline.cpp @@ -0,0 +1,115 @@ +/* + * 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. + * 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 + +// EXTERNAL INCLUDES +#include + +// INTERNAL INCLUDES +#include +#include +#include +#include + +namespace Dali +{ +namespace Toolkit +{ +namespace Text +{ +namespace +{ +const std::string XHTML_COLOR_ATTRIBUTE("color"); +const std::string XHTML_HEIGHT_ATTRIBUTE("height"); +const std::string XHTML_TYPE_ATTRIBUTE("type"); +const std::string XHTML_DASH_GAP_ATTRIBUTE("dash-gap"); +const std::string XHTML_DASH_WIDTH_ATTRIBUTE("dash-width"); + +const unsigned int MAX_TYPE_ATTRIBUTE_SIZE = 7u; ///< The maximum length of any of the possible 'type' values. + +} // namespace + +void ProcessTypeAttribute(const Attribute& attribute, UnderlinedCharacterRun& underlinedCharacterRun) +{ + underlinedCharacterRun.properties.typeDefined = ProcessEnumerationAttribute(attribute, + MAX_TYPE_ATTRIBUTE_SIZE, + &StringToUnderlineType, + underlinedCharacterRun.properties.type); +} + +void ProcessDashGapAttribute(const Attribute& attribute, UnderlinedCharacterRun& underlinedCharacterRun) +{ + underlinedCharacterRun.properties.dashGap = ProcessFloatAttribute(attribute); + underlinedCharacterRun.properties.dashGapDefined = true; +} + +void ProcessDashWidthAttribute(const Attribute& attribute, UnderlinedCharacterRun& underlinedCharacterRun) +{ + underlinedCharacterRun.properties.dashWidth = ProcessFloatAttribute(attribute); + underlinedCharacterRun.properties.dashWidthDefined = true; +} +void ProcessHeightAttribute(const Attribute& attribute, UnderlinedCharacterRun& underlinedCharacterRun) +{ + underlinedCharacterRun.properties.height = ProcessFloatAttribute(attribute); + underlinedCharacterRun.properties.heightDefined = true; +} + +void ProcessColorAttribute(const Attribute& attribute, UnderlinedCharacterRun& underlinedCharacterRun) +{ + ColorStringToVector4(attribute.valueBuffer, attribute.valueLength, underlinedCharacterRun.properties.color); + underlinedCharacterRun.properties.colorDefined = true; +} + +void ProcessUnderlineTag(const Tag& tag, UnderlinedCharacterRun& underlinedCharacterRun) +{ + for(Vector::ConstIterator it = tag.attributes.Begin(), + endIt = tag.attributes.End(); + it != endIt; + ++it) + { + const Attribute& attribute(*it); + + if(TokenComparison(XHTML_COLOR_ATTRIBUTE, attribute.nameBuffer, attribute.nameLength)) + { + ProcessColorAttribute(attribute, underlinedCharacterRun); + } + else if(TokenComparison(XHTML_HEIGHT_ATTRIBUTE, attribute.nameBuffer, attribute.nameLength)) + { + ProcessHeightAttribute(attribute, underlinedCharacterRun); + } + else if(TokenComparison(XHTML_TYPE_ATTRIBUTE, attribute.nameBuffer, attribute.nameLength)) + { + ProcessTypeAttribute(attribute, underlinedCharacterRun); + } + else if(TokenComparison(XHTML_DASH_GAP_ATTRIBUTE, attribute.nameBuffer, attribute.nameLength)) + { + ProcessDashGapAttribute(attribute, underlinedCharacterRun); + } + else if(TokenComparison(XHTML_DASH_WIDTH_ATTRIBUTE, attribute.nameBuffer, attribute.nameLength)) + { + ProcessDashWidthAttribute(attribute, underlinedCharacterRun); + } + } +} + +} // namespace Text + +} // namespace Toolkit + +} // namespace Dali diff --git a/dali-toolkit/internal/text/markup-processor-underline.h b/dali-toolkit/internal/text/markup-processor-underline.h new file mode 100644 index 0000000..f210718 --- /dev/null +++ b/dali-toolkit/internal/text/markup-processor-underline.h @@ -0,0 +1,85 @@ +#ifndef DALI_TOOLKIT_TEXT_MARKUP_PROCESSOR_UNDERLINE_H +#define DALI_TOOLKIT_TEXT_MARKUP_PROCESSOR_UNDERLINE_H + +/* + * 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. + * 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. + * + */ + +namespace Dali +{ +namespace Toolkit +{ +namespace Text +{ +struct Tag; +struct Attribute; +struct UnderlinedCharacterRun; + +/** + * @brief Fill the underlined character run with the type attribute value. + * + * @param[in] attribute the type attribute. + * @param[out] underlinedCharacterRun The underlined character run + */ +void ProcessTypeAttribute(const Attribute& attribute, UnderlinedCharacterRun& underlinedCharacterRun); + +/** + * @brief Fill the underlined character run with the dash-gap attribute value. + * + * @param[in] attribute the dash-gap attribute. + * @param[out] underlinedCharacterRun The underlined character run + */ +void ProcessDashGapAttribute(const Attribute& attribute, UnderlinedCharacterRun& underlinedCharacterRun); + +/** + * @brief Fill the underlined character run with the dash-width attribute value. + * + * @param[in] attribute the dash-width attribute. + * @param[out] underlinedCharacterRun The underlined character run + */ +void ProcessDashWidthAttribute(const Attribute& attribute, UnderlinedCharacterRun& underlinedCharacterRun); + +/** + * @brief Fill the underlined character run with the height attribute value. + * + * @param[in] attribute the height attribute. + * @param[out] underlinedCharacterRun The underlined character run + */ +void ProcessHeightAttribute(const Attribute& attribute, UnderlinedCharacterRun& underlinedCharacterRun); + +/** + * @brief Fill the underlined character run with the color attribute value. + * + * @param[in] attribute the color attribute. + * @param[out] underlinedCharacterRun The underlined character run + */ +void ProcessColorAttribute(const Attribute& attribute, UnderlinedCharacterRun& underlinedCharacterRun); + +/** + * @brief Retrieves the underline run info from the tag and sets it to the underline run. + * + * @param[in] tag The underline tag and its attributes. + * @param[in,out] underlinedCharacterRun The underlined character run + */ +void ProcessUnderlineTag(const Tag& tag, UnderlinedCharacterRun& underlinedCharacterRun); + +} // namespace Text + +} // namespace Toolkit + +} // namespace Dali + +#endif // DALI_TOOLKIT_TEXT_MARKUP_PROCESSOR_UNDERLINE_H diff --git a/dali-toolkit/internal/text/markup-processor.cpp b/dali-toolkit/internal/text/markup-processor.cpp index 7ed1f61..17aae96 100644 --- a/dali-toolkit/internal/text/markup-processor.cpp +++ b/dali-toolkit/internal/text/markup-processor.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include namespace Dali @@ -940,7 +941,7 @@ void ProcessMarkupString(const std::string& markupString, MarkupProcessData& mar else if(TokenComparison(XHTML_U_TAG, tag.buffer, tag.length)) { ProcessTagForRun( - markupProcessData.underlinedCharacterRuns, styleStack, tag, characterIndex, underlinedCharacterRunIndex, uTagReference, [](const Tag& tag, UnderlinedCharacterRun& run) {}); + markupProcessData.underlinedCharacterRuns, styleStack, tag, characterIndex, underlinedCharacterRunIndex, uTagReference, [](const Tag& tag, UnderlinedCharacterRun& run) { ProcessUnderlineTag(tag, run); }); } // else if(TokenComparison(XHTML_B_TAG, tag.buffer, tag.length)) { diff --git a/dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp b/dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp index 9946d49..9eb2fd6 100644 --- a/dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp +++ b/dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp @@ -24,6 +24,7 @@ #include #include #include +#include // INTERNAL INCLUDES #include @@ -32,6 +33,8 @@ #include #include #include +#include +#include #include using namespace Dali; @@ -158,28 +161,10 @@ struct AtlasRenderer::Impl mQuadVertexFormat["aColor"] = Property::VECTOR4; } - bool IsGlyphUnderlined(GlyphIndex index, - const Vector& underlineRuns) - { - for(Vector::ConstIterator it = underlineRuns.Begin(), - endIt = underlineRuns.End(); - it != endIt; - ++it) - { - const GlyphRun& run = *it; - - if((run.glyphIndex <= index) && (index < run.glyphIndex + run.numberOfGlyphs)) - { - return true; - } - } - - return false; - } - - bool doGlyphHaveStrikethrough(GlyphIndex index, - const Vector& strikethroughRuns, - Vector4& strikethroughColor) + bool + doGlyphHaveStrikethrough(GlyphIndex index, + const Vector& strikethroughRuns, + Vector4& strikethroughColor) { for(Vector::ConstIterator it = strikethroughRuns.Begin(), endIt = strikethroughRuns.End(); @@ -456,27 +441,22 @@ struct AtlasRenderer::Impl Vector strikethroughExtents; mDepth = depth; - const Vector2& textSize(view.GetLayoutSize()); - const Vector2 halfTextSize(textSize * 0.5f); - const Vector2& shadowOffset(view.GetShadowOffset()); - const Vector4& shadowColor(view.GetShadowColor()); - const bool underlineEnabled = view.IsUnderlineEnabled(); - const Vector4& underlineColor(view.GetUnderlineColor()); - const float underlineHeight = view.GetUnderlineHeight(); - const Text::Underline::Type underlineType = view.GetUnderlineType(); - const float dashedUnderlineWidth = view.GetDashedUnderlineWidth(); - const float dashedUnderlineGap = view.GetDashedUnderlineGap(); - const uint16_t outlineWidth = view.GetOutlineWidth(); - const Vector4& outlineColor(view.GetOutlineColor()); - const bool isOutline = 0u != outlineWidth; - const GlyphInfo* hyphens = view.GetHyphens(); - const Length* hyphenIndices = view.GetHyphenIndices(); - const Length hyphensCount = view.GetHyphensCount(); - const bool strikethroughEnabled = view.IsStrikethroughEnabled(); - const Vector4& strikethroughColor(view.GetStrikethroughColor()); - const float strikethroughHeight = view.GetStrikethroughHeight(); - Vector4 currentStrikethroughColor; - const float characterSpacing(view.GetCharacterSpacing()); + const Vector2& textSize(view.GetLayoutSize()); + const Vector2 halfTextSize(textSize * 0.5f); + const Vector2& shadowOffset(view.GetShadowOffset()); + const Vector4& shadowColor(view.GetShadowColor()); + const bool underlineEnabled = view.IsUnderlineEnabled(); + const uint16_t outlineWidth = view.GetOutlineWidth(); + const Vector4& outlineColor(view.GetOutlineColor()); + const bool isOutline = 0u != outlineWidth; + const GlyphInfo* hyphens = view.GetHyphens(); + const Length* hyphenIndices = view.GetHyphenIndices(); + const Length hyphensCount = view.GetHyphensCount(); + const bool strikethroughEnabled = view.IsStrikethroughEnabled(); + const Vector4& strikethroughColor(view.GetStrikethroughColor()); + const float strikethroughHeight = view.GetStrikethroughHeight(); + Vector4 currentStrikethroughColor; + const float characterSpacing(view.GetCharacterSpacing()); // Elided text info. Indices according to elided text. const auto startIndexOfGlyphs = view.GetStartIndexOfElidedGlyphs(); @@ -485,14 +465,31 @@ struct AtlasRenderer::Impl const bool useDefaultColor = (NULL == colorsBuffer); + // Get a handle of the font client. Used to retrieve the bitmaps of the glyphs. + TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get(); + // Get the underline runs. - const Length numberOfUnderlineRuns = view.GetNumberOfUnderlineRuns(); - Vector underlineRuns; + const Length numberOfUnderlineRuns = view.GetNumberOfUnderlineRuns(); + Vector underlineRuns; underlineRuns.Resize(numberOfUnderlineRuns); view.GetUnderlineRuns(underlineRuns.Begin(), 0u, numberOfUnderlineRuns); + // Aggregate underline-style-properties from view + const UnderlineStyleProperties viewUnderlineProperties{view.GetUnderlineType(), + view.GetUnderlineColor(), + view.GetUnderlineHeight(), + view.GetDashedUnderlineGap(), + view.GetDashedUnderlineWidth(), + true, + true, + true, + true, + true}; + + float maxUnderlineHeight = viewUnderlineProperties.height; + // Get the strikethrough runs. const Length numberOfStrikethroughRuns = view.GetNumberOfStrikethroughRuns(); Vector strikethroughRuns; @@ -502,12 +499,11 @@ struct AtlasRenderer::Impl bool thereAreUnderlinedGlyphs = false; bool strikethroughGlyphsExist = false; - float currentUnderlinePosition = ZERO; - float currentUnderlineThickness = underlineHeight; - float currentStrikethroughThickness = strikethroughHeight; - FontId lastFontId = 0; - FontId lastUnderlinedFontId = 0; - Style style = STYLE_NORMAL; + float currentUnderlinePosition = ZERO; + float currentStrikethroughHeight = strikethroughHeight; + float maxStrikethroughHeight = currentStrikethroughHeight; + FontId lastFontId = 0; + Style style = STYLE_NORMAL; if(fabsf(shadowOffset.x) > Math::MACHINE_EPSILON_1 || fabsf(shadowOffset.y) > Math::MACHINE_EPSILON_1) { @@ -524,8 +520,10 @@ struct AtlasRenderer::Impl uint32_t hyphenIndex = 0; //For septated underlined chunks. (this is for Markup case) - uint32_t underlineChunkId = 0u; // give id for each chunk. - bool isPreUnderlined = false; // status of underlined for previous glyph. + uint32_t underlineChunkId = 0u; // give id for each chunk. + bool isPreUnderlined = false; // status of underlined for previous glyph. + std::map mapUnderlineChunkIdWithProperties; // mapping underlineChunkId with UnderlineStyleProperties to get properties of underlined chunk + UnderlineStyleProperties preUnderlineProperties = viewUnderlineProperties; // the previous UnderlineStyleProperties uint32_t strikethroughChunkId = 0u; // give id for each chunk. bool isPrevGlyphStrikethrough = false; // status of strikethrough for previous glyph. @@ -544,6 +542,12 @@ struct AtlasRenderer::Impl } } + //To keep the last fontMetrics of lastDecorativeLinesFontId + FontId lastDecorativeLinesFontId = 0; // DecorativeLines like Undeline and Strikethrough + FontMetrics lastDecorativeLinesFontMetrics; + fontClient.GetFontMetrics(lastDecorativeLinesFontId, lastDecorativeLinesFontMetrics); + + // Iteration on glyphs for(uint32_t i = 0, glyphSize = glyphs.Size(); i < glyphSize; ++i) { GlyphInfo glyph; @@ -558,8 +562,11 @@ struct AtlasRenderer::Impl glyph = *(glyphsBuffer + i); } - const bool isGlyphUnderlined = underlineEnabled || IsGlyphUnderlined(i, underlineRuns); - thereAreUnderlinedGlyphs = thereAreUnderlinedGlyphs || isGlyphUnderlined; + Vector::ConstIterator currentUnderlinedGlyphRunIt = underlineRuns.End(); + const bool isGlyphUnderlined = underlineEnabled || IsGlyphUnderlined(i, underlineRuns, currentUnderlinedGlyphRunIt); + const UnderlineStyleProperties currentUnderlineProperties = GetCurrentUnderlineProperties(isGlyphUnderlined, underlineRuns, currentUnderlinedGlyphRunIt, viewUnderlineProperties); + float currentUnderlineHeight = GetCurrentUnderlineHeight(underlineRuns, currentUnderlinedGlyphRunIt, viewUnderlineProperties.height); + thereAreUnderlinedGlyphs = thereAreUnderlinedGlyphs || isGlyphUnderlined; currentStrikethroughColor = strikethroughColor; const bool isStrikethroughGlyph = strikethroughEnabled || doGlyphHaveStrikethrough(i, strikethroughRuns, currentStrikethroughColor); @@ -568,58 +575,42 @@ struct AtlasRenderer::Impl // No operation for white space if(glyph.width && glyph.height) { - // Are we still using the same fontId as previous - if((isGlyphUnderlined || isStrikethroughGlyph) && (glyph.fontId != lastUnderlinedFontId)) + // Check and update decorative-lines informations + if((isGlyphUnderlined || isStrikethroughGlyph) && + ((glyph.fontId != lastDecorativeLinesFontId) || !(currentUnderlineProperties.IsHeightEqualTo(preUnderlineProperties)))) { - // We need to fetch fresh font underline metrics - FontMetrics fontMetrics; - mFontClient.GetFontMetrics(glyph.fontId, fontMetrics); - currentUnderlinePosition = ceil(fabsf(fontMetrics.underlinePosition)); - const float descender = ceil(fabsf(fontMetrics.descender)); - - if(fabsf(underlineHeight) < Math::MACHINE_EPSILON_1000) + bool isDecorativeLinesFontIdUpdated = false; + // Are we still using the same fontId as previous + if(glyph.fontId != lastDecorativeLinesFontId) { - currentUnderlineThickness = fontMetrics.underlineThickness; + // We need to fetch fresh font metrics + lastDecorativeLinesFontId = glyph.fontId; + isDecorativeLinesFontIdUpdated = true; + fontClient.GetFontMetrics(lastDecorativeLinesFontId, lastDecorativeLinesFontMetrics); - // Ensure underline will be at least a pixel high - if(currentUnderlineThickness < ONE) + if(isStrikethroughGlyph || isGlyphUnderlined) { - currentUnderlineThickness = ONE; - } - else - { - currentUnderlineThickness = ceil(currentUnderlineThickness); + //The currentUnderlinePosition will be used for both Underline and/or Strikethrough + currentUnderlinePosition = FetchUnderlinePositionFromFontMetrics(lastDecorativeLinesFontMetrics); } } - if(fabsf(strikethroughHeight) < Math::MACHINE_EPSILON_1000) + if(isGlyphUnderlined && (isDecorativeLinesFontIdUpdated || !(currentUnderlineProperties.IsHeightEqualTo(preUnderlineProperties)))) { - // Ensure strikethrough will be at least a pixel high - if(currentStrikethroughThickness < ONE) - { - currentStrikethroughThickness = ONE; - } - else + //If the Underline Height is changed then we need to recalculate height. + if(!(currentUnderlineProperties.IsHeightEqualTo(preUnderlineProperties))) { - currentStrikethroughThickness = ceil(currentStrikethroughThickness); + maxUnderlineHeight = currentUnderlineHeight; } - } - // Clamp the underline position at the font descender and check for ( as EFL describes it ) a broken font - if(currentUnderlinePosition > descender) - { - currentUnderlinePosition = descender; + CalcualteUnderlineHeight(lastDecorativeLinesFontMetrics, currentUnderlineHeight, maxUnderlineHeight); } - if(fabsf(currentUnderlinePosition) < Math::MACHINE_EPSILON_1000) + if(isDecorativeLinesFontIdUpdated && isStrikethroughGlyph) { - // Move offset down by one ( EFL behavior ) - currentUnderlinePosition = ONE; + CalcualteStrikethroughHeight(currentStrikethroughHeight, maxStrikethroughHeight); } - - lastUnderlinedFontId = glyph.fontId; - - } // underline + } // decorative-lines AtlasGlyphManager::GlyphStyle style; style.isItalic = glyph.isItalicRequired; @@ -662,6 +653,18 @@ struct AtlasRenderer::Impl const ColorIndex colorIndex = useDefaultColor ? 0u : *(colorIndicesBuffer + i); const Vector4& color = (useDefaultColor || (0u == colorIndex)) ? defaultColor : *(colorsBuffer + colorIndex - 1u); + //The new underlined chunk. Add new id if they are not consecutive indices (this is for Markup case) + // Examples: "Hello World Hello World", "World Hello World", " World Hello World" + if(isPreUnderlined && (!isGlyphUnderlined || (preUnderlineProperties != currentUnderlineProperties))) + { + mapUnderlineChunkIdWithProperties.insert(std::pair(underlineChunkId, preUnderlineProperties)); + underlineChunkId++; + } + + //Keep status of underlined for previous glyph to check consecutive indices + isPreUnderlined = isGlyphUnderlined; + preUnderlineProperties = currentUnderlineProperties; + GenerateMesh(glyph, positionPlusOutlineOffset, color, @@ -669,7 +672,7 @@ struct AtlasRenderer::Impl slot, isGlyphUnderlined, currentUnderlinePosition, - currentUnderlineThickness, + maxUnderlineHeight, meshContainer, newTextCache, extents, @@ -686,7 +689,7 @@ struct AtlasRenderer::Impl slot, strikethroughGlyphsExist, 0.0f, - currentStrikethroughThickness, + maxStrikethroughHeight, meshContainer, newTextCache, strikethroughExtents, @@ -707,7 +710,7 @@ struct AtlasRenderer::Impl slotOutline, false, currentUnderlinePosition, - currentUnderlineThickness, + maxUnderlineHeight, meshContainerOutline, newTextCache, extents, @@ -716,15 +719,6 @@ struct AtlasRenderer::Impl 0u); } - //The new underlined chunk. Add new id if they are not consecutive indices (this is for Markup case) - // Examples: "Hello World Hello World", "World Hello World", " World Hello World" - if(isPreUnderlined && (isPreUnderlined != isGlyphUnderlined)) - { - underlineChunkId++; - } - //Keep status of underlined for previous glyph to check consecutive indices - isPreUnderlined = isGlyphUnderlined; - if(isPrevGlyphStrikethrough && !isStrikethroughGlyph) { strikethroughChunkId++; @@ -746,7 +740,7 @@ struct AtlasRenderer::Impl if(thereAreUnderlinedGlyphs) { // Check to see if any of the text needs an underline - GenerateUnderlines(meshContainer, extents, underlineColor, underlineType, dashedUnderlineWidth, dashedUnderlineGap); + GenerateUnderlines(meshContainer, extents, viewUnderlineProperties, mapUnderlineChunkIdWithProperties); } if(strikethroughGlyphsExist) @@ -1051,15 +1045,14 @@ struct AtlasRenderer::Impl } } - void GenerateUnderlines(std::vector& meshRecords, - Vector& extents, - const Vector4& underlineColor, - const Text::Underline::Type& underlineType, - const float& dashedUnderlineWidth, - const float& dashedUnderlineGap) + void GenerateUnderlines(std::vector& meshRecords, + Vector& extents, + const UnderlineStyleProperties& viewUnderlineProperties, + const std::map& mapUnderlineChunkIdWithProperties) { AtlasManager::Mesh2D newMesh; unsigned short faceIndex = 0; + for(Vector::ConstIterator eIt = extents.Begin(), eEndIt = extents.End(); eIt != eEndIt; @@ -1069,6 +1062,17 @@ struct AtlasRenderer::Impl uint32_t index = eIt->mMeshRecordIndex; Vector2 uv = mGlyphManager.GetAtlasSize(meshRecords[index].mAtlasId); + auto pairUnderlineChunkIdWithProperties = mapUnderlineChunkIdWithProperties.find(eIt->mUnderlineChunkId); + + const UnderlineStyleProperties underlineProperties = (pairUnderlineChunkIdWithProperties == mapUnderlineChunkIdWithProperties.end()) + ? viewUnderlineProperties + : pairUnderlineChunkIdWithProperties->second; + + const Vector4& underlineColor = underlineProperties.colorDefined ? underlineProperties.color : viewUnderlineProperties.color; + const Text::Underline::Type& underlineType = underlineProperties.typeDefined ? underlineProperties.type : viewUnderlineProperties.type; + const float& dashedUnderlineGap = underlineProperties.dashGapDefined ? underlineProperties.dashGap : viewUnderlineProperties.dashGap; + const float& dashedUnderlineWidth = underlineProperties.dashWidthDefined ? underlineProperties.dashWidth : viewUnderlineProperties.dashWidth; + // Make sure we don't hit texture edge for single pixel texture ( filled pixel is in top left of every atlas ) float u = HALF / uv.x; float v = HALF / uv.y; @@ -1082,9 +1086,7 @@ struct AtlasRenderer::Impl { float dashTlx = tlx; float dashBrx = tlx; - faceIndex = 0; - AtlasManager::Mesh2D newMesh; while((dashTlx >= tlx) && (dashTlx < brx) && ((dashTlx + dashedUnderlineWidth) <= brx)) { dashBrx = dashTlx + dashedUnderlineWidth; diff --git a/dali-toolkit/internal/text/rendering/styles/strikethrough-helper-functions.cpp b/dali-toolkit/internal/text/rendering/styles/strikethrough-helper-functions.cpp new file mode 100644 index 0000000..c87fe88 --- /dev/null +++ b/dali-toolkit/internal/text/rendering/styles/strikethrough-helper-functions.cpp @@ -0,0 +1,53 @@ +/* + * 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. + * 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. + * + */ + +// CLASS HEADER +#include + +namespace Dali +{ +namespace Toolkit +{ +namespace Text +{ +/// Helper method to fetch the underline metrics for the specified font glyph +void CalcualteStrikethroughHeight(float& currentStrikethroughHeight, float& maxStrikethroughHeight) +{ + //Height of strikethrough represents the thickness of line. + + // Ensure strikethrough will be at least a pixel high + if(currentStrikethroughHeight < 1.0f) + { + currentStrikethroughHeight = 1.0f; + } + else + { + currentStrikethroughHeight = ceil(currentStrikethroughHeight); + } + + // The strikethrough height should be the max strikethrough height of all glyphs of the line. + if(currentStrikethroughHeight > maxStrikethroughHeight) + { + maxStrikethroughHeight = currentStrikethroughHeight; + } +} + +} // namespace Text + +} // namespace Toolkit + +} // namespace Dali \ No newline at end of file diff --git a/dali-toolkit/internal/text/rendering/styles/strikethrough-helper-functions.h b/dali-toolkit/internal/text/rendering/styles/strikethrough-helper-functions.h new file mode 100644 index 0000000..b3df7ef --- /dev/null +++ b/dali-toolkit/internal/text/rendering/styles/strikethrough-helper-functions.h @@ -0,0 +1,50 @@ +#ifndef DALI_TOOLKIT_TEXT_RENDERING_STYLES_STRIKETHROUGH_HELPER_FUNCTIONS_H +#define DALI_TOOLKIT_TEXT_RENDERING_STYLES_STRIKETHROUGH_HELPER_FUNCTIONS_H + +/* + * 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. + * 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. + * + */ + +// EXTERNAL INCLUDES +#include +#include + +// INTERNAL INCLUDES +#include +#include + +namespace Dali +{ +namespace Toolkit +{ +namespace Text +{ +/** + * @brief Calculate the current underline height and update maximum underline height + * + * @param[inout] currentStrikethroughHeight the current strikethrough height. + * @param[inout] maxStrikethroughHeight the maximum strikethrough height. + * + */ +void CalcualteStrikethroughHeight(float& currentStrikethroughHeight, float& maxStrikethroughHeight); + +} // namespace Text + +} // namespace Toolkit + +} // namespace Dali + +#endif // DALI_TOOLKIT_TEXT_RENDERING_STYLES_STRIKETHROUGH_HELPER_FUNCTIONS_H \ No newline at end of file diff --git a/dali-toolkit/internal/text/rendering/styles/underline-helper-functions.cpp b/dali-toolkit/internal/text/rendering/styles/underline-helper-functions.cpp new file mode 100644 index 0000000..6720b91 --- /dev/null +++ b/dali-toolkit/internal/text/rendering/styles/underline-helper-functions.cpp @@ -0,0 +1,122 @@ +/* + * 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. + * 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. + * + */ + +// CLASS HEADER +#include + +namespace Dali +{ +namespace Toolkit +{ +namespace Text +{ +bool IsGlyphUnderlined(GlyphIndex index, + const Vector& underlineRuns, + Vector::ConstIterator& currentUnderlinedGlyphRunIt) +{ + for(Vector::ConstIterator it = underlineRuns.Begin(), + endIt = underlineRuns.End(); + it != endIt; + ++it) + { + const UnderlinedGlyphRun& run = *it; + + if((run.glyphRun.glyphIndex <= index) && (index < run.glyphRun.glyphIndex + run.glyphRun.numberOfGlyphs)) + { + currentUnderlinedGlyphRunIt = it; + return true; + } + } + + return false; +} + +float GetCurrentUnderlineHeight(const Vector& underlineRuns, + Vector::ConstIterator currentUnderlinedGlyphRunIt, + const float underlineHeight) +{ + if(currentUnderlinedGlyphRunIt == underlineRuns.End()) + { + return underlineHeight; + } + + const UnderlinedGlyphRun& underlinedGlyphRun = *currentUnderlinedGlyphRunIt; + return (underlinedGlyphRun.properties.heightDefined ? underlinedGlyphRun.properties.height : underlineHeight); +} + +UnderlineStyleProperties GetCurrentUnderlineProperties(const bool& isGlyphUnderlined, + const Vector& underlineRuns, + Vector::ConstIterator currentUnderlinedGlyphRunIt, + const UnderlineStyleProperties& commonUnderlineProperties) +{ + return (isGlyphUnderlined && (currentUnderlinedGlyphRunIt != underlineRuns.End())) + ? currentUnderlinedGlyphRunIt->properties + : commonUnderlineProperties; +} + +float FetchUnderlinePositionFromFontMetrics(const FontMetrics& fontMetrics) +{ + //Helper method to fetch the underline metrics for the specified font glyph + const float descender = ceil(fabsf(fontMetrics.descender)); + float underlinePosition = ceil(fabsf(fontMetrics.underlinePosition)); + + // Clamp the underline position at the font descender and check for ( as EFL describes it ) a broken font + if(underlinePosition > descender) + { + underlinePosition = descender; + } + + if(fabsf(underlinePosition) < Math::MACHINE_EPSILON_1000) + { + // Move offset down by one ( EFL behavior ) + underlinePosition = 1.0f; + } + + return underlinePosition; +} + +void CalcualteUnderlineHeight(const FontMetrics& fontMetrics, float& currentUnderlineHeight, float& maxUnderlineHeight) +{ + //Helper method to fetch the underline metrics for the specified font glyph + //Height of underline represents the thickness of line. + if(fabsf(currentUnderlineHeight) < Math::MACHINE_EPSILON_1000) + { + currentUnderlineHeight = fontMetrics.underlineThickness; + + // Ensure underline will be at least a pixel high + if(currentUnderlineHeight < 1.0f) + { + currentUnderlineHeight = 1.0f; + } + else + { + currentUnderlineHeight = ceil(currentUnderlineHeight); + } + } + + // The underline height should be the max underline height of all glyphs of the line. + if(currentUnderlineHeight > maxUnderlineHeight) + { + maxUnderlineHeight = currentUnderlineHeight; + } +} + +} // namespace Text + +} // namespace Toolkit + +} // namespace Dali \ No newline at end of file diff --git a/dali-toolkit/internal/text/rendering/styles/underline-helper-functions.h b/dali-toolkit/internal/text/rendering/styles/underline-helper-functions.h new file mode 100644 index 0000000..825b05c --- /dev/null +++ b/dali-toolkit/internal/text/rendering/styles/underline-helper-functions.h @@ -0,0 +1,101 @@ +#ifndef DALI_TOOLKIT_TEXT_RENDERING_STYLES_UNDERLINE_HELPER_FUNCTIONS_H +#define DALI_TOOLKIT_TEXT_RENDERING_STYLES_UNDERLINE_HELPER_FUNCTIONS_H + +/* + * 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. + * 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. + * + */ + +// EXTERNAL INCLUDES +#include +#include + +// INTERNAL INCLUDES +#include +#include + +namespace Dali +{ +namespace Toolkit +{ +namespace Text +{ +/** + * @brief Whether the glyph at index is underlined or not. If true then return iterator to the run containes index. + * + * @param[in] index the index of glyph. + * @param[in] underlineRuns the underline runs. + * @param[out] currentUnderlinedGlyphRunIt the iterator of current underlined glyph run. + * + * @return true if glyph at index is underlined + */ +bool IsGlyphUnderlined(GlyphIndex index, + const Vector& underlineRuns, + Vector::ConstIterator& currentUnderlinedGlyphRunIt); + +/** + * @brief Check the current underlined glyph run iterator if not empty and its height is defined then return ts height. Otherwise return the common underline height. + * + * @param[in] underlineRuns the underline runs. + * @param[in] currentUnderlinedGlyphRunIt the iterator of current underlined glyph run. + * @param[in] underlineHeight the common underline height. + * + * @return the determined underline height + */ +float GetCurrentUnderlineHeight(const Vector& underlineRuns, + Vector::ConstIterator currentUnderlinedGlyphRunIt, + const float underlineHeight); + +/** + * @brief Check the current underlined glyph run iterator if not empty and isGlyphUnderlined is true then return its UnderlineProperties. Otherwise return the common underline properties. + * + * @param[in] isGlyphUnderlined whether the glyph is underlined. + * @param[in] underlineRuns the underline runs. + * @param[in] currentUnderlinedGlyphRunIt the iterator of current underlined glyph run. + * @param[in] commonUnderlineProperties the common underline properties. + * + * @return the determined underline properties + */ +UnderlineStyleProperties GetCurrentUnderlineProperties(const bool& isGlyphUnderlined, + const Vector& underlineRuns, + Vector::ConstIterator currentUnderlinedGlyphRunIt, + const UnderlineStyleProperties& commonUnderlineProperties); + +/** + * @brief Fetch and calculate underline Position using font-metrics + * + * @param[in] fontMetrics the font metrics of glyph. + * + * @return the underline position + */ +float FetchUnderlinePositionFromFontMetrics(const FontMetrics& fontMetrics); + +/** + * @brief Calculate the current underline height using font-metrics and update maximum underline height + * + * @param[in] fontMetrics the font metrics of glyph. + * @param[inout] currentUnderlineHeight the current underline height. + * @param[inout] maxUnderlineHeight the maximum underline height. + * + */ +void CalcualteUnderlineHeight(const FontMetrics& fontMetrics, float& currentUnderlineHeight, float& maxUnderlineHeight); + +} // namespace Text + +} // namespace Toolkit + +} // namespace Dali + +#endif // DALI_TOOLKIT_TEXT_RENDERING_STYLES_UNDERLINE_HELPER_FUNCTIONS_H \ No newline at end of file diff --git a/dali-toolkit/internal/text/rendering/text-typesetter.cpp b/dali-toolkit/internal/text/rendering/text-typesetter.cpp index 96088b5..790e247 100644 --- a/dali-toolkit/internal/text/rendering/text-typesetter.cpp +++ b/dali-toolkit/internal/text/rendering/text-typesetter.cpp @@ -26,6 +26,8 @@ // INTERNAL INCLUDES #include #include +#include +#include #include namespace Dali @@ -37,6 +39,7 @@ namespace Text namespace { const float HALF(0.5f); +const float ONE_AND_A_HALF(1.5f); /** * @brief Data struct used to set the buffer of the glyph's bitmap into the final bitmap's buffer. */ @@ -257,25 +260,6 @@ void TypesetGlyph(GlyphData& data, } } -bool IsGlyphUnderlined(GlyphIndex index, - const Vector& underlineRuns) -{ - for(Vector::ConstIterator it = underlineRuns.Begin(), - endIt = underlineRuns.End(); - it != endIt; - ++it) - { - const GlyphRun& run = *it; - - if((run.glyphIndex <= index) && (index < run.glyphIndex + run.numberOfGlyphs)) - { - return true; - } - } - - return false; -} - bool doGlyphHaveStrikethrough(GlyphIndex index, const Vector& strikethroughRuns, Vector4& strikethroughColor) @@ -301,79 +285,6 @@ bool doGlyphHaveStrikethrough(GlyphIndex index, return false; } -/// Helper method to fetch the underline metrics for the specified font glyph -void FetchFontDecorationlinesMetrics( - TextAbstraction::FontClient& fontClient, - const GlyphInfo* const glyphInfo, - float& currentUnderlinePosition, - const float underlineHeight, - float& currentUnderlineThickness, - float& maxUnderlineThickness, - FontId& lastlinedFontId, - const float strikethroughHeight, - float& currentStrikethroughThickness, - float& maxStrikethroughThickness) -{ - FontMetrics fontMetrics; - fontClient.GetFontMetrics(glyphInfo->fontId, fontMetrics); - currentUnderlinePosition = ceil(fabsf(fontMetrics.underlinePosition)); - const float descender = ceil(fabsf(fontMetrics.descender)); - - if(fabsf(underlineHeight) < Math::MACHINE_EPSILON_1000) - { - currentUnderlineThickness = fontMetrics.underlineThickness; - - // Ensure underline will be at least a pixel high - if(currentUnderlineThickness < 1.0f) - { - currentUnderlineThickness = 1.0f; - } - else - { - currentUnderlineThickness = ceil(currentUnderlineThickness); - } - } - - if(fabsf(strikethroughHeight) < Math::MACHINE_EPSILON_1000) - { - // Ensure strikethrough will be at least a pixel high - if(currentStrikethroughThickness < 1.0f) - { - currentStrikethroughThickness = 1.0f; - } - else - { - currentStrikethroughThickness = ceil(currentStrikethroughThickness); - } - } - - // The underline thickness should be the max underline thickness of all glyphs of the line. - if(currentUnderlineThickness > maxUnderlineThickness) - { - maxUnderlineThickness = currentUnderlineThickness; - } - - // The strikethrough thickness should be the max strikethrough thickness of all glyphs of the line. - if(currentStrikethroughThickness > maxStrikethroughThickness) - { - maxStrikethroughThickness = currentStrikethroughThickness; - } - - // Clamp the underline position at the font descender and check for ( as EFL describes it ) a broken font - if(currentUnderlinePosition > descender) - { - currentUnderlinePosition = descender; - } - - if(fabsf(currentUnderlinePosition) < Math::MACHINE_EPSILON_1000) - { - // Move offset down by one ( EFL behavior ) - currentUnderlinePosition = 1.0f; - } - - lastlinedFontId = glyphInfo->fontId; -} - /// Draws the specified color to the pixel buffer void WriteColorToPixelBuffer( GlyphData& glyphData, @@ -398,24 +309,27 @@ void WriteColorToPixelBuffer( /// Draws the specified underline color to the buffer void DrawUnderline( - const Vector4& underlineColor, - const unsigned int bufferWidth, - const unsigned int bufferHeight, - GlyphData& glyphData, - const float baseline, - const float currentUnderlinePosition, - const float maxUnderlineThickness, - const float lineExtentLeft, - const float lineExtentRight, - const Text::Underline::Type underlineType, - const float dashedUnderlineWidth, - const float dashedUnderlineGap, - const LineRun& line) + const unsigned int bufferWidth, + const unsigned int bufferHeight, + GlyphData& glyphData, + const float baseline, + const float currentUnderlinePosition, + const float maxUnderlineHeight, + const float lineExtentLeft, + const float lineExtentRight, + const UnderlineStyleProperties& commonUnderlineProperties, + const UnderlineStyleProperties& currentUnderlineProperties, + const LineRun& line) { + const Vector4& underlineColor = currentUnderlineProperties.colorDefined ? currentUnderlineProperties.color : commonUnderlineProperties.color; + const Text::Underline::Type underlineType = currentUnderlineProperties.typeDefined ? currentUnderlineProperties.type : commonUnderlineProperties.type; + const float dashedUnderlineWidth = currentUnderlineProperties.dashWidthDefined ? currentUnderlineProperties.dashWidth : commonUnderlineProperties.dashWidth; + const float dashedUnderlineGap = currentUnderlineProperties.dashGapDefined ? currentUnderlineProperties.dashGap : commonUnderlineProperties.dashGap; + int underlineYOffset = glyphData.verticalOffset + baseline + currentUnderlinePosition; uint32_t* bitmapBuffer = reinterpret_cast(glyphData.bitmapBuffer.GetBuffer()); - for(unsigned int y = underlineYOffset; y < underlineYOffset + maxUnderlineThickness; y++) + for(unsigned int y = underlineYOffset; y < underlineYOffset + maxUnderlineHeight; y++) { if(y > bufferHeight - 1) { @@ -466,8 +380,8 @@ void DrawUnderline( } if(underlineType == Text::Underline::DOUBLE) { - int secondUnderlineYOffset = glyphData.verticalOffset - line.descender - maxUnderlineThickness; - for(unsigned int y = secondUnderlineYOffset; y < secondUnderlineYOffset + maxUnderlineThickness; y++) + int secondUnderlineYOffset = underlineYOffset - ONE_AND_A_HALF * maxUnderlineHeight; + for(unsigned int y = secondUnderlineYOffset; y < secondUnderlineYOffset + maxUnderlineHeight; y++) { if(y > bufferHeight - 1) { @@ -639,14 +553,14 @@ void DrawStrikethrough( GlyphData& glyphData, const float baseline, const LineRun& line, - const float maxStrikethroughThickness, + const float maxStrikethroughHeight, const float lineExtentLeft, const float lineExtentRight, float strikethroughStartingYPosition) { uint32_t* bitmapBuffer = reinterpret_cast(glyphData.bitmapBuffer.GetBuffer()); - for(unsigned int y = strikethroughStartingYPosition; y < strikethroughStartingYPosition + maxStrikethroughThickness; y++) + for(unsigned int y = strikethroughStartingYPosition; y < strikethroughStartingYPosition + maxStrikethroughHeight; y++) { if(y > bufferHeight - 1) { @@ -987,20 +901,27 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer(const unsigned int bufferWidth, } } - const bool underlineEnabled = mModel->IsUnderlineEnabled(); - const Vector4& underlineColor = mModel->GetUnderlineColor(); - const float underlineHeight = mModel->GetUnderlineHeight(); - const Text::Underline::Type underlineType = mModel->GetUnderlineType(); - const float dashedUnderlineWidth = mModel->GetDashedUnderlineWidth(); - const float dashedUnderlineGap = mModel->GetDashedUnderlineGap(); - const bool strikethroughEnabled = mModel->IsStrikethroughEnabled(); - const Vector4& strikethroughColor = mModel->GetStrikethroughColor(); - const float strikethroughHeight = mModel->GetStrikethroughHeight(); - const float characterSpacing = mModel->GetCharacterSpacing(); + const bool underlineEnabled = mModel->IsUnderlineEnabled(); + const bool strikethroughEnabled = mModel->IsStrikethroughEnabled(); + const Vector4& strikethroughColor = mModel->GetStrikethroughColor(); + const float strikethroughHeight = mModel->GetStrikethroughHeight(); + const float characterSpacing = mModel->GetCharacterSpacing(); + + // Aggregate underline-style-properties from mModel + const UnderlineStyleProperties modelUnderlineProperties{mModel->GetUnderlineType(), + mModel->GetUnderlineColor(), + mModel->GetUnderlineHeight(), + mModel->GetDashedUnderlineGap(), + mModel->GetDashedUnderlineWidth(), + true, + true, + true, + true, + true}; // Get the underline runs. - const Length numberOfUnderlineRuns = mModel->GetNumberOfUnderlineRuns(); - Vector underlineRuns; + const Length numberOfUnderlineRuns = mModel->GetNumberOfUnderlineRuns(); + Vector underlineRuns; underlineRuns.Resize(numberOfUnderlineRuns); mModel->GetUnderlineRuns(underlineRuns.Begin(), 0u, numberOfUnderlineRuns); @@ -1013,14 +934,16 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer(const unsigned int bufferWidth, bool thereAreUnderlinedGlyphs = false; bool strikethroughGlyphsExist = false; - float currentUnderlinePosition = 0.0f; - float currentUnderlineThickness = underlineHeight; - float maxUnderlineThickness = currentUnderlineThickness; - float currentStrikethroughThickness = strikethroughHeight; - float maxStrikethroughThickness = currentStrikethroughThickness; + float currentUnderlinePosition = 0.0f; + float currentUnderlineHeight = modelUnderlineProperties.height; + float maxUnderlineHeight = currentUnderlineHeight; + auto currentUnderlineProperties = modelUnderlineProperties; + + float currentStrikethroughHeight = strikethroughHeight; + float maxStrikethroughHeight = currentStrikethroughHeight; float strikethroughStartingYPosition = 0.0f; - FontId lastUnderlinedFontId = 0; + FontId lastFontId = 0; float lineExtentLeft = bufferWidth; float lineExtentRight = 0.0f; @@ -1079,19 +1002,39 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer(const unsigned int bufferWidth, continue; } - const bool underlineGlyph = underlineEnabled || IsGlyphUnderlined(glyphIndex, underlineRuns); - thereAreUnderlinedGlyphs = thereAreUnderlinedGlyphs || underlineGlyph; + Vector::ConstIterator currentUnderlinedGlyphRunIt = underlineRuns.End(); + const bool underlineGlyph = underlineEnabled || IsGlyphUnderlined(glyphIndex, underlineRuns, currentUnderlinedGlyphRunIt); + currentUnderlineProperties = GetCurrentUnderlineProperties(underlineGlyph, underlineRuns, currentUnderlinedGlyphRunIt, modelUnderlineProperties); + currentUnderlineHeight = GetCurrentUnderlineHeight(underlineRuns, currentUnderlinedGlyphRunIt, modelUnderlineProperties.height); + thereAreUnderlinedGlyphs = thereAreUnderlinedGlyphs || underlineGlyph; currentStrikethroughColor = strikethroughColor; const bool strikethroughGlyph = strikethroughEnabled || doGlyphHaveStrikethrough(glyphIndex, strikethroughRuns, currentStrikethroughColor); strikethroughGlyphsExist = strikethroughGlyphsExist || strikethroughGlyph; // Are we still using the same fontId as previous - if((strikethroughGlyph || underlineGlyph) && (glyphInfo->fontId != lastUnderlinedFontId)) + if((glyphInfo->fontId != lastFontId) && (strikethroughGlyph || underlineGlyph)) { // We need to fetch fresh font underline metrics - FetchFontDecorationlinesMetrics(fontClient, glyphInfo, currentUnderlinePosition, underlineHeight, currentUnderlineThickness, maxUnderlineThickness, lastUnderlinedFontId, strikethroughHeight, currentStrikethroughThickness, maxStrikethroughThickness); - } // underline + FontMetrics fontMetrics; + fontClient.GetFontMetrics(glyphInfo->fontId, fontMetrics); + + //The currentUnderlinePosition will be used for both Underline and/or Strikethrough + currentUnderlinePosition = FetchUnderlinePositionFromFontMetrics(fontMetrics); + + if(underlineGlyph) + { + CalcualteUnderlineHeight(fontMetrics, currentUnderlineHeight, maxUnderlineHeight); + } + + if(strikethroughGlyph) + { + CalcualteStrikethroughHeight(currentStrikethroughHeight, maxStrikethroughHeight); + } + + // Update lastFontId because fontId is changed + lastFontId = glyphInfo->fontId; // Prevents searching for existing blocksizes when string of the same fontId. + } // Retrieves the glyph's position. Vector2 position = *(positionBuffer + elidedGlyphIndex); @@ -1210,7 +1153,7 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer(const unsigned int bufferWidth, // Draw the underline from the leftmost glyph to the rightmost glyph if(thereAreUnderlinedGlyphs && style == Typesetter::STYLE_UNDERLINE) { - DrawUnderline(underlineColor, bufferWidth, bufferHeight, glyphData, baseline, currentUnderlinePosition, maxUnderlineThickness, lineExtentLeft, lineExtentRight, underlineType, dashedUnderlineWidth, dashedUnderlineGap, line); + DrawUnderline(bufferWidth, bufferHeight, glyphData, baseline, currentUnderlinePosition, maxUnderlineHeight, lineExtentLeft, lineExtentRight, modelUnderlineProperties, currentUnderlineProperties, line); } // Draw the background color from the leftmost glyph to the rightmost glyph @@ -1224,7 +1167,7 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer(const unsigned int bufferWidth, { //TODO : The currently implemented strikethrough creates a strikethrough on the line level. We need to create different strikethroughs the case of glyphs with different sizes. strikethroughStartingYPosition = (glyphData.verticalOffset + baseline + currentUnderlinePosition) - ((line.ascender) * HALF); // Since Free Type font doesn't contain the strikethrough-position property, strikethrough position will be calculated by moving the underline position upwards by half the value of the line height. - DrawStrikethrough(currentStrikethroughColor, bufferWidth, bufferHeight, glyphData, baseline, line, maxStrikethroughThickness, lineExtentLeft, lineExtentRight, strikethroughStartingYPosition); + DrawStrikethrough(currentStrikethroughColor, bufferWidth, bufferHeight, glyphData, baseline, line, maxStrikethroughHeight, lineExtentLeft, lineExtentRight, strikethroughStartingYPosition); } // Increases the vertical offset with the line's descender. @@ -1300,27 +1243,30 @@ Devel::PixelBuffer Typesetter::ApplyUnderlineMarkupImageBuffer(Devel::PixelBuffe { // Underline-tags (this is for Markup case) // Get the underline runs. - const Length numberOfUnderlineRuns = mModel->GetNumberOfUnderlineRuns(); - Vector underlineRuns; + const Length numberOfUnderlineRuns = mModel->GetNumberOfUnderlineRuns(); + Vector underlineRuns; underlineRuns.Resize(numberOfUnderlineRuns); mModel->GetUnderlineRuns(underlineRuns.Begin(), 0u, numberOfUnderlineRuns); // Iterate on the consecutive underlined glyph run and connect them into one chunk of underlined characters. - Vector::ConstIterator itGlyphRun = underlineRuns.Begin(); - Vector::ConstIterator endItGlyphRun = underlineRuns.End(); - GlyphIndex startGlyphIndex, endGlyphIndex; + Vector::ConstIterator itGlyphRun = underlineRuns.Begin(); + Vector::ConstIterator endItGlyphRun = underlineRuns.End(); + GlyphIndex startGlyphIndex, endGlyphIndex; //The outer loop to iterate on the separated chunks of underlined glyph runs while(itGlyphRun != endItGlyphRun) { - startGlyphIndex = itGlyphRun->glyphIndex; + const UnderlineStyleProperties& firstUnderlineStyleProperties = itGlyphRun->properties; + + startGlyphIndex = itGlyphRun->glyphRun.glyphIndex; endGlyphIndex = startGlyphIndex; //The inner loop to make a connected underline for the consecutive characters do { - endGlyphIndex += itGlyphRun->numberOfGlyphs; + endGlyphIndex += itGlyphRun->glyphRun.numberOfGlyphs; itGlyphRun++; - } while(itGlyphRun != endItGlyphRun && itGlyphRun->glyphIndex == endGlyphIndex); + } while(itGlyphRun != endItGlyphRun && itGlyphRun->glyphRun.glyphIndex == endGlyphIndex && + (firstUnderlineStyleProperties == itGlyphRun->properties)); endGlyphIndex--; diff --git a/dali-toolkit/internal/text/rendering/view-model.cpp b/dali-toolkit/internal/text/rendering/view-model.cpp index 5e014df..47aed00 100644 --- a/dali-toolkit/internal/text/rendering/view-model.cpp +++ b/dali-toolkit/internal/text/rendering/view-model.cpp @@ -23,8 +23,8 @@ #include // INTERNAL INCLUDES -#include #include +#include namespace Dali { @@ -270,7 +270,7 @@ Length ViewModel::GetNumberOfUnderlineRuns() const return mModel->GetNumberOfUnderlineRuns(); } -void ViewModel::GetUnderlineRuns(GlyphRun* underlineRuns, UnderlineRunIndex index, Length numberOfRuns) const +void ViewModel::GetUnderlineRuns(UnderlinedGlyphRun* underlineRuns, UnderlineRunIndex index, Length numberOfRuns) const { mModel->GetUnderlineRuns(underlineRuns, index, numberOfRuns); } diff --git a/dali-toolkit/internal/text/rendering/view-model.h b/dali-toolkit/internal/text/rendering/view-model.h index c3ee530..ef8ba87 100644 --- a/dali-toolkit/internal/text/rendering/view-model.h +++ b/dali-toolkit/internal/text/rendering/view-model.h @@ -233,7 +233,7 @@ public: /** * @copydoc ModelInterface::GetUnderlineRuns() */ - void GetUnderlineRuns(GlyphRun* underlineRuns, UnderlineRunIndex index, Length numberOfRuns) const override; + void GetUnderlineRuns(UnderlinedGlyphRun* underlineRuns, UnderlineRunIndex index, Length numberOfRuns) const override; /** * @copydoc ModelInterface::GetOutlineColor() diff --git a/dali-toolkit/internal/text/text-controller-impl-model-updater.cpp b/dali-toolkit/internal/text/text-controller-impl-model-updater.cpp index 2d1e28d..e6ec978 100644 --- a/dali-toolkit/internal/text/text-controller-impl-model-updater.cpp +++ b/dali-toolkit/internal/text/text-controller-impl-model-updater.cpp @@ -374,9 +374,9 @@ bool ControllerImplModelUpdater::Update(Controller::Impl& impl, OperationsMask o case Dali::InputMethodContext::PreeditStyle::UNDERLINE: { // Add the underline for the pre-edit text. - GlyphRun underlineRun; - underlineRun.glyphIndex = attrData.startIndex + numberOfCommit; - underlineRun.numberOfGlyphs = numberOfIndices; + UnderlinedGlyphRun underlineRun; + underlineRun.glyphRun.glyphIndex = attrData.startIndex + numberOfCommit; + underlineRun.glyphRun.numberOfGlyphs = numberOfIndices; impl.mModel->mVisualModel->mUnderlineRuns.PushBack(underlineRun); //Mark-up processor case @@ -451,9 +451,9 @@ bool ControllerImplModelUpdater::Update(Controller::Impl& impl, OperationsMask o backgroundColorRun.color = BACKGROUND_SUB4; impl.mModel->mLogicalModel->mBackgroundColorRuns.PushBack(backgroundColorRun); - GlyphRun underlineRun; - underlineRun.glyphIndex = attrData.startIndex + numberOfCommit; - underlineRun.numberOfGlyphs = numberOfIndices; + UnderlinedGlyphRun underlineRun; + underlineRun.glyphRun.glyphIndex = attrData.startIndex + numberOfCommit; + underlineRun.glyphRun.numberOfGlyphs = numberOfIndices; impl.mModel->mVisualModel->mUnderlineRuns.PushBack(underlineRun); //Mark-up processor case @@ -472,9 +472,9 @@ bool ControllerImplModelUpdater::Update(Controller::Impl& impl, OperationsMask o backgroundColorRun.color = BACKGROUND_SUB5; impl.mModel->mLogicalModel->mBackgroundColorRuns.PushBack(backgroundColorRun); - GlyphRun underlineRun; - underlineRun.glyphIndex = attrData.startIndex + numberOfCommit; - underlineRun.numberOfGlyphs = numberOfIndices; + UnderlinedGlyphRun underlineRun; + underlineRun.glyphRun.glyphIndex = attrData.startIndex + numberOfCommit; + underlineRun.glyphRun.numberOfGlyphs = numberOfIndices; impl.mModel->mVisualModel->mUnderlineRuns.PushBack(underlineRun); //Mark-up processor case @@ -493,9 +493,9 @@ bool ControllerImplModelUpdater::Update(Controller::Impl& impl, OperationsMask o backgroundColorRun.color = BACKGROUND_SUB6; impl.mModel->mLogicalModel->mBackgroundColorRuns.PushBack(backgroundColorRun); - GlyphRun underlineRun; - underlineRun.glyphIndex = attrData.startIndex + numberOfCommit; - underlineRun.numberOfGlyphs = numberOfIndices; + UnderlinedGlyphRun underlineRun; + underlineRun.glyphRun.glyphIndex = attrData.startIndex + numberOfCommit; + underlineRun.glyphRun.numberOfGlyphs = numberOfIndices; impl.mModel->mVisualModel->mUnderlineRuns.PushBack(underlineRun); //Mark-up processor case @@ -514,9 +514,9 @@ bool ControllerImplModelUpdater::Update(Controller::Impl& impl, OperationsMask o backgroundColorRun.color = BACKGROUND_SUB7; impl.mModel->mLogicalModel->mBackgroundColorRuns.PushBack(backgroundColorRun); - GlyphRun underlineRun; - underlineRun.glyphIndex = attrData.startIndex + numberOfCommit; - underlineRun.numberOfGlyphs = numberOfIndices; + UnderlinedGlyphRun underlineRun; + underlineRun.glyphRun.glyphIndex = attrData.startIndex + numberOfCommit; + underlineRun.glyphRun.numberOfGlyphs = numberOfIndices; impl.mModel->mVisualModel->mUnderlineRuns.PushBack(underlineRun); //Mark-up processor case diff --git a/dali-toolkit/internal/text/text-controller-impl.cpp b/dali-toolkit/internal/text/text-controller-impl.cpp index db6fde1..294b534 100644 --- a/dali-toolkit/internal/text/text-controller-impl.cpp +++ b/dali-toolkit/internal/text/text-controller-impl.cpp @@ -39,6 +39,7 @@ #include #include #include +#include using namespace Dali; @@ -1620,9 +1621,22 @@ void Controller::Impl::CopyUnderlinedFromLogicalToVisualModels(bool shouldClearP Length numberOfCharacters = it->characterRun.numberOfCharacters; for(Length index = 0u; index < numberOfCharacters; index++) { - GlyphRun underlineGlyphRun; - underlineGlyphRun.glyphIndex = charactersToGlyph[characterIndex + index]; - underlineGlyphRun.numberOfGlyphs = glyphsPerCharacter[characterIndex + index]; + UnderlinedGlyphRun underlineGlyphRun; + underlineGlyphRun.glyphRun.glyphIndex = charactersToGlyph[characterIndex + index]; + underlineGlyphRun.glyphRun.numberOfGlyphs = glyphsPerCharacter[characterIndex + index]; + + //Copy properties (attributes) + underlineGlyphRun.properties.type = it->properties.type; + underlineGlyphRun.properties.color = it->properties.color; + underlineGlyphRun.properties.height = it->properties.height; + underlineGlyphRun.properties.dashGap = it->properties.dashGap; + underlineGlyphRun.properties.dashWidth = it->properties.dashWidth; + underlineGlyphRun.properties.typeDefined = it->properties.typeDefined; + underlineGlyphRun.properties.colorDefined = it->properties.colorDefined; + underlineGlyphRun.properties.heightDefined = it->properties.heightDefined; + underlineGlyphRun.properties.dashGapDefined = it->properties.dashGapDefined; + underlineGlyphRun.properties.dashWidthDefined = it->properties.dashWidthDefined; + mModel->mVisualModel->mUnderlineRuns.PushBack(underlineGlyphRun); } } @@ -1639,8 +1653,14 @@ void Controller::Impl::CopyStrikethroughFromLogicalToVisualModels() for(Vector::ConstIterator it = strikethroughCharacterRuns.Begin(), endIt = strikethroughCharacterRuns.End(); it != endIt; ++it) { - CharacterIndex characterIndex = it->characterRun.characterIndex; - Length numberOfCharacters = it->characterRun.numberOfCharacters; + CharacterIndex characterIndex = it->characterRun.characterIndex; + Length numberOfCharacters = it->characterRun.numberOfCharacters; + + if(numberOfCharacters == 0) + { + continue; + } + StrikethroughGlyphRun strikethroughGlyphRun; strikethroughGlyphRun.color = it->color; strikethroughGlyphRun.isColorSet = it->isColorSet; @@ -1836,6 +1856,7 @@ void Controller::Impl::ClearStyleData() { mModel->mLogicalModel->mColorRuns.Clear(); mModel->mLogicalModel->ClearFontDescriptionRuns(); + mModel->mLogicalModel->ClearStrikethroughRuns(); } void Controller::Impl::ResetScrollPosition() diff --git a/dali-toolkit/internal/text/text-effects-style.cpp b/dali-toolkit/internal/text/text-effects-style.cpp index 8d552d4..90c570a 100644 --- a/dali-toolkit/internal/text/text-effects-style.cpp +++ b/dali-toolkit/internal/text/text-effects-style.cpp @@ -1,5 +1,5 @@ /* - * 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. @@ -22,7 +22,6 @@ #include #include #include -#include #include namespace Dali @@ -355,8 +354,8 @@ bool SetUnderlineProperties(ControllerPtr controller, const Property::Value& val { const Property::Map& propertiesMap = value.Get(); - bool enabled = false; - bool colorDefined = false; + bool enabled = false; + bool colorDefined = false; Vector4 color; bool heightDefined = false; float height = 0.f; @@ -976,11 +975,11 @@ bool SetStrikethroughProperties(ControllerPtr controller, const Property::Value& Text::ParsePropertyString(propertyString, parsedStringMap); empty = ParseStrikethroughProperties(parsedStringMap, - enabled, - colorDefined, - color, - heightDefined, - height); + enabled, + colorDefined, + color, + heightDefined, + height); controller->StrikethroughSetByString(!empty); } @@ -1057,7 +1056,7 @@ void GetStrikethroughProperties(ControllerPtr controller, Property::Value& value if(controller->IsStrikethroughSetByString()) { std::string strikethroughProperties = "{\"enable\":"; - const std::string enabledStr = enabled ? "true" : "false"; + const std::string enabledStr = enabled ? "true" : "false"; strikethroughProperties += "\"" + enabledStr + "\","; std::string colorStr; @@ -1092,6 +1091,17 @@ void GetStrikethroughProperties(ControllerPtr controller, Property::Value& value } } +Underline::Type StringToUnderlineType(const char* const underlineTypeStr) +{ + Underline::Type underlineType = Text::Underline::SOLID; + Scripting::GetEnumeration(underlineTypeStr, + UNDERLINE_TYPE_STRING_TABLE, + UNDERLINE_TYPE_STRING_TABLE_COUNT, + underlineType); + + return underlineType; +} + } // namespace Text } // namespace Toolkit diff --git a/dali-toolkit/internal/text/text-effects-style.h b/dali-toolkit/internal/text/text-effects-style.h index a1b7bea..d87e810 100644 --- a/dali-toolkit/internal/text/text-effects-style.h +++ b/dali-toolkit/internal/text/text-effects-style.h @@ -2,7 +2,7 @@ #define DALI_TOOLKIT_INTERNAL_TEXT_EFFECTS_STYLE_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. @@ -20,6 +20,8 @@ // INTERNAL INCLUDES #include +#include +#include namespace Dali { @@ -27,6 +29,12 @@ namespace Toolkit { namespace Text { +const Scripting::StringEnum UNDERLINE_TYPE_STRING_TABLE[] = + { + {"solid", Text::Underline::SOLID}, + {"dashed", Text::Underline::DASHED}, + {"double", Text::Underline::DOUBLE}}; +const unsigned int UNDERLINE_TYPE_STRING_TABLE_COUNT = sizeof(UNDERLINE_TYPE_STRING_TABLE) / sizeof(UNDERLINE_TYPE_STRING_TABLE[0]); namespace EffectStyle { enum Type @@ -116,11 +124,11 @@ bool ParseBackgroundProperties(const Property::Map& backgroundProperties, * @param[out] height The strikethrough's height. */ bool ParseStrikethroughProperties(const Property::Map& strikethroughProperties, - bool& enabled, - bool& colorDefined, - Vector4& color, - bool& heightDefined, - float& height); + bool& enabled, + bool& colorDefined, + Vector4& color, + bool& heightDefined, + float& height); /** * @brief Sets the underline properties. @@ -242,6 +250,15 @@ bool SetBackgroundProperties(ControllerPtr controller, const Property::Value& va */ void GetBackgroundProperties(ControllerPtr controller, Property::Value& value, EffectStyle::Type type); +/** + * @brief Converts a underline type string into @e Underline::Type + * + * @param[in] underlineTypeStr The underline type string. Must end with '\0'. + * + * @return The @e Underline::Type value corresponding to the string. + */ +Underline::Type StringToUnderlineType(const char* const underlineTypeStr); + } // namespace Text } // namespace Toolkit diff --git a/dali-toolkit/internal/text/text-model-interface.h b/dali-toolkit/internal/text/text-model-interface.h index 7d51b16..f9d993a 100644 --- a/dali-toolkit/internal/text/text-model-interface.h +++ b/dali-toolkit/internal/text/text-model-interface.h @@ -27,6 +27,7 @@ #include #include #include +#include #include namespace Dali @@ -300,7 +301,7 @@ public: * @param[in] index Index of the first underline run to be copied. * @param[in] numberOfRuns Number of underline runs to be copied. */ - virtual void GetUnderlineRuns(GlyphRun* underlineRuns, UnderlineRunIndex index, Length numberOfRuns) const = 0; + virtual void GetUnderlineRuns(UnderlinedGlyphRun* underlineRuns, UnderlineRunIndex index, Length numberOfRuns) const = 0; /** * @brief Retrieve the outline color. diff --git a/dali-toolkit/internal/text/text-model.cpp b/dali-toolkit/internal/text/text-model.cpp index e19618e..7ce74ca 100644 --- a/dali-toolkit/internal/text/text-model.cpp +++ b/dali-toolkit/internal/text/text-model.cpp @@ -212,7 +212,7 @@ Length Model::GetNumberOfUnderlineRuns() const return mVisualModel->GetNumberOfUnderlineRuns(); } -void Model::GetUnderlineRuns(GlyphRun* underlineRuns, UnderlineRunIndex index, Length numberOfRuns) const +void Model::GetUnderlineRuns(UnderlinedGlyphRun* underlineRuns, UnderlineRunIndex index, Length numberOfRuns) const { mVisualModel->GetUnderlineRuns(underlineRuns, index, numberOfRuns); } diff --git a/dali-toolkit/internal/text/text-model.h b/dali-toolkit/internal/text/text-model.h index 4f7b9e3..7077c85 100644 --- a/dali-toolkit/internal/text/text-model.h +++ b/dali-toolkit/internal/text/text-model.h @@ -230,7 +230,7 @@ public: /** * @copydoc ModelInterface::GetUnderlineRuns() */ - void GetUnderlineRuns(GlyphRun* underlineRuns, UnderlineRunIndex index, Length numberOfRuns) const override; + void GetUnderlineRuns(UnderlinedGlyphRun* underlineRuns, UnderlineRunIndex index, Length numberOfRuns) const override; /** * @copydoc ModelInterface::GetOutlineColor() diff --git a/dali-toolkit/internal/text/text-view-interface.h b/dali-toolkit/internal/text/text-view-interface.h index da6b4e1..2dda239 100644 --- a/dali-toolkit/internal/text/text-view-interface.h +++ b/dali-toolkit/internal/text/text-view-interface.h @@ -24,6 +24,7 @@ // INTERNAL INCLUDES #include #include +#include #include namespace Dali @@ -233,9 +234,9 @@ public: * @param[in] index Index of the first underline run to be copied. * @param[in] numberOfRuns Number of underline runs to be copied. */ - virtual void GetUnderlineRuns(GlyphRun* underlineRuns, - UnderlineRunIndex index, - Length numberOfRuns) const = 0; + virtual void GetUnderlineRuns(UnderlinedGlyphRun* underlineRuns, + UnderlineRunIndex index, + Length numberOfRuns) const = 0; /** * @brief Retrieve the outline color. diff --git a/dali-toolkit/internal/text/text-view.cpp b/dali-toolkit/internal/text/text-view.cpp index b4644e7..137ded2 100644 --- a/dali-toolkit/internal/text/text-view.cpp +++ b/dali-toolkit/internal/text/text-view.cpp @@ -680,9 +680,9 @@ Length View::GetNumberOfUnderlineRuns() const return 0u; } -void View::GetUnderlineRuns(GlyphRun* underlineRuns, - UnderlineRunIndex index, - Length numberOfRuns) const +void View::GetUnderlineRuns(UnderlinedGlyphRun* underlineRuns, + UnderlineRunIndex index, + Length numberOfRuns) const { if(mImpl->mVisualModel) { diff --git a/dali-toolkit/internal/text/text-view.h b/dali-toolkit/internal/text/text-view.h index f673e0e..8eeb882 100644 --- a/dali-toolkit/internal/text/text-view.h +++ b/dali-toolkit/internal/text/text-view.h @@ -176,9 +176,9 @@ public: /** * @copydoc Dali::Toolkit::Text::ViewInterface::GetUnderlineRuns() */ - virtual void GetUnderlineRuns(GlyphRun* underlineRuns, - UnderlineRunIndex index, - Length numberOfRuns) const; + virtual void GetUnderlineRuns(UnderlinedGlyphRun* underlineRuns, + UnderlineRunIndex index, + Length numberOfRuns) const; /** * @copydoc Dali::Toolkit::Text::ViewInterface::GetOutlineColor() diff --git a/dali-toolkit/internal/text/underline-style-properties.h b/dali-toolkit/internal/text/underline-style-properties.h new file mode 100644 index 0000000..14016c4 --- /dev/null +++ b/dali-toolkit/internal/text/underline-style-properties.h @@ -0,0 +1,123 @@ +#ifndef DALI_TOOLKIT_TEXT_UNDERLINE_STYLE_PROPERTIES_H +#define DALI_TOOLKIT_TEXT_UNDERLINE_STYLE_PROPERTIES_H + +/* + * 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. + * 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. + * + */ + +// EXTERNAL INCLUDES +#include + +// INTERNAL INCLUDES + +#include + +namespace Dali +{ +namespace Toolkit +{ +namespace Text +{ +/** + * @brief Properties of underline style. + */ +struct UnderlineStyleProperties +{ + // Constructors + + /** + * Default constructor to set the default values of bitfields + */ + UnderlineStyleProperties() + : type{Text::Underline::SOLID}, + color{Color::BLACK}, + height{0u}, + dashGap{1u}, + dashWidth{2u}, + typeDefined{false}, + colorDefined{false}, + heightDefined{false}, + dashGapDefined{false}, + dashWidthDefined{false} + { + } + + UnderlineStyleProperties(Text::Underline::Type type, + Vector4 color, + float height, + float dashGap, + float dashWidth, + bool typeDefined, + bool colorDefined, + bool heightDefined, + bool dashGapDefined, + bool dashWidthDefined) + : type{type}, + color{color}, + height{height}, + dashGap{dashGap}, + dashWidth{dashWidth}, + typeDefined{typeDefined}, + colorDefined{colorDefined}, + heightDefined{heightDefined}, + dashGapDefined{dashGapDefined}, + dashWidthDefined{dashWidthDefined} + { + } + + // Overloading operators + + bool operator==(const UnderlineStyleProperties& other) const + { + //The property is similar when both are not defined or when both are defined and have the same value. + return ((!typeDefined && !other.typeDefined) || ((typeDefined && other.typeDefined) && (type == other.type))) && + ((!colorDefined && !other.colorDefined) || ((colorDefined && other.colorDefined) && (color == other.color))) && + ((!heightDefined && !other.heightDefined) || ((heightDefined && other.heightDefined) && (height == other.height))) && + ((!dashGapDefined && !other.dashGapDefined) || ((dashGapDefined && other.dashGapDefined) && (dashGap == other.dashGap))) && + ((!dashWidthDefined && !other.dashWidthDefined) || ((dashWidthDefined && other.dashWidthDefined) && (dashWidth == other.dashWidth))); + } + + bool operator!=(const UnderlineStyleProperties& other) const + { + return !(*this == other); + } + + bool IsHeightEqualTo(const UnderlineStyleProperties& other) const + { + return ((!heightDefined && !other.heightDefined) || ((heightDefined && other.heightDefined) && (height == other.height))); + } + + //Attributes + Text::Underline::Type type; ///< The type of underline. + Vector4 color; ///< The color of underline. + float height; ///< The height of underline. + float dashGap; ///< The dash-gap of underline. + float dashWidth; ///< The height of underline. + + bool typeDefined : 1; ///< Whether the type is defined. + bool colorDefined : 1; ///< Whether the color is defined. + bool heightDefined : 1; ///< Whether the height is defined. + bool dashGapDefined : 1; ///< Whether the dash-gap is defined. + bool dashWidthDefined : 1; ///< Whether the dash-width is defined. +}; + +} // namespace Text + +} // namespace Toolkit + +} // namespace Dali + +#endif // DALI_TOOLKIT_TEXT_UNDERLINE_STYLE_PROPERTIES_H diff --git a/dali-toolkit/internal/text/underlined-character-run.h b/dali-toolkit/internal/text/underlined-character-run.h index 99d5967..4024dff 100644 --- a/dali-toolkit/internal/text/underlined-character-run.h +++ b/dali-toolkit/internal/text/underlined-character-run.h @@ -2,7 +2,7 @@ #define DALI_TOOLKIT_TEXT_UNDERLINED_CHARACTER_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. @@ -23,7 +23,7 @@ // INTERNAL INCLUDES #include -#include +#include namespace Dali { @@ -36,10 +36,17 @@ namespace Text */ struct UnderlinedCharacterRun { - CharacterRun characterRun; ///< The initial character index and the number of characters of the run. - //TODO: add properties like color, height and style - //Vector4 color; ///< The color of underline. - //float height; ///< The height of underline. + /** + * Default constructor to set the default values of bitfields + */ + UnderlinedCharacterRun() + : characterRun{}, + properties{} + { + } + + CharacterRun characterRun; ///< The initial character index and the number of characters of the run. + UnderlineStyleProperties properties; /// The properties of underline style }; } // namespace Text diff --git a/dali-toolkit/internal/text/underlined-glyph-run.h b/dali-toolkit/internal/text/underlined-glyph-run.h new file mode 100644 index 0000000..4c5ed7a --- /dev/null +++ b/dali-toolkit/internal/text/underlined-glyph-run.h @@ -0,0 +1,58 @@ +#ifndef DALI_TOOLKIT_TEXT_UNDERLINED_GLYPH_RUN_H +#define DALI_TOOLKIT_TEXT_UNDERLINED_GLYPH_RUN_H + +/* + * 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. + * 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. + * + */ + +// EXTERNAL INCLUDES +#include + +// INTERNAL INCLUDES +#include +#include + +namespace Dali +{ +namespace Toolkit +{ +namespace Text +{ +/** + * @brief Run of underlined glyphs with same properties. + */ +struct UnderlinedGlyphRun +{ + /** + * Default constructor to set the default values of bitfields + */ + UnderlinedGlyphRun() + : glyphRun{}, + properties{} + { + } + + GlyphRun glyphRun; ///< The initial glyph index and the number of glyphs in the run. + UnderlineStyleProperties properties; /// The properties of underline style +}; + +} // namespace Text + +} // namespace Toolkit + +} // namespace Dali + +#endif // DALI_TOOLKIT_TEXT_UNDERLINED_GLYPH_RUN_H diff --git a/dali-toolkit/internal/text/visual-model-impl.cpp b/dali-toolkit/internal/text/visual-model-impl.cpp index 3fa3975..ce0fb7c 100644 --- a/dali-toolkit/internal/text/visual-model-impl.cpp +++ b/dali-toolkit/internal/text/visual-model-impl.cpp @@ -305,13 +305,13 @@ LineIndex VisualModel::GetLineOfCharacter(CharacterIndex characterIndex) return index; } -void VisualModel::GetUnderlineRuns(GlyphRun* underlineRuns, - UnderlineRunIndex index, - Length numberOfRuns) const +void VisualModel::GetUnderlineRuns(UnderlinedGlyphRun* underlineRuns, + UnderlineRunIndex index, + Length numberOfRuns) const { memcpy(underlineRuns, mUnderlineRuns.Begin() + index, - numberOfRuns * sizeof(GlyphRun)); + numberOfRuns * sizeof(UnderlinedGlyphRun)); } void VisualModel::SetNaturalSize(const Vector2& size) diff --git a/dali-toolkit/internal/text/visual-model-impl.h b/dali-toolkit/internal/text/visual-model-impl.h index ebddb35..4bae17c 100644 --- a/dali-toolkit/internal/text/visual-model-impl.h +++ b/dali-toolkit/internal/text/visual-model-impl.h @@ -29,6 +29,7 @@ #include #include #include +#include #include // DEVEL INCLUDES @@ -172,9 +173,9 @@ public: * @param[in] index Index of the first underline run to be copied. * @param[in] numberOfRuns Number of underline runs to be copied. */ - void GetUnderlineRuns(GlyphRun* underlineRuns, - UnderlineRunIndex index, - Length numberOfRuns) const; + void GetUnderlineRuns(UnderlinedGlyphRun* underlineRuns, + UnderlineRunIndex index, + Length numberOfRuns) const; // Size interface @@ -621,7 +622,7 @@ public: Vector mGlyphsPerCharacter; ///< For each character, the number of glyphs that are shaped. Vector mGlyphPositions; ///< For each glyph, the position. Vector mLines; ///< The laid out lines. - Vector mUnderlineRuns; ///< Runs of glyphs that are underlined. + Vector mUnderlineRuns; ///< Runs of glyphs that are underlined. Vector mColors; ///< Colors of the glyphs. Vector mColorIndices; ///< Indices to the vector of colors for each glyphs. Vector mBackgroundColors; ///< Background colors of the glyphs. diff --git a/dali-toolkit/public-api/dali-toolkit-version.cpp b/dali-toolkit/public-api/dali-toolkit-version.cpp index d574d6c..6a5256d 100644 --- a/dali-toolkit/public-api/dali-toolkit-version.cpp +++ b/dali-toolkit/public-api/dali-toolkit-version.cpp @@ -29,7 +29,7 @@ namespace Toolkit { const unsigned int TOOLKIT_MAJOR_VERSION = 2; const unsigned int TOOLKIT_MINOR_VERSION = 1; -const unsigned int TOOLKIT_MICRO_VERSION = 9; +const unsigned int TOOLKIT_MICRO_VERSION = 10; const char* const TOOLKIT_BUILD_DATE = __DATE__ " " __TIME__; #ifdef DEBUG_ENABLED diff --git a/packaging/dali-toolkit.spec b/packaging/dali-toolkit.spec index 7376644..6360436 100644 --- a/packaging/dali-toolkit.spec +++ b/packaging/dali-toolkit.spec @@ -1,6 +1,6 @@ Name: dali2-toolkit Summary: Dali 3D engine Toolkit -Version: 2.1.9 +Version: 2.1.10 Release: 1 Group: System/Libraries License: Apache-2.0 and BSD-3-Clause and MIT