DALI_TEST_EQUALS(numberOfUnderlineRuns, expectedNumberOfUnderlinedGlyphs, TEST_LOCATION);
- Vector<GlyphRun> underlineRuns;
+ Vector<UnderlinedGlyphRun> 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 =
+ "start<u>ABC1</u>then"
+ "<u type='solid'>ABC2</u>then"
+ "<u type='dashed'>ABC3</u>then"
+ "<u type='double'>ABC4</u>then"
+ "<u color='green'>ABC5</u>then"
+ "<u height='5.0f'>ABC6</u>then"
+ "<u type='dashed' dash-gap='3.0f'>ABC7</u>then"
+ "<u type='dashed' dash-width='4.0f'>ABC8</u>then"
+ "<u color='blue' type='dashed' height='4.0f' dash-gap='2.0f' dash-width='3.0f'>ABC9</u>end"
+
+ ;
+
+ 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<UnderlinedGlyphRun> 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[] =
+ {
+ //<u>ABC1</u>
+ {"<u>ABC1</u>",
+ 0u,
+ 3u,
+ 5u,
+ 8u,
+ {
+ Text::Underline::SOLID,
+ Color::BLACK,
+ 0u,
+ 1u,
+ 2u,
+ false,
+ false,
+ false,
+ false,
+ false,
+ }},
+
+ //<u type='solid'>ABC2</u>
+ {"<u type='solid'>ABC2</u>",
+ 4u,
+ 7u,
+ 13u,
+ 16u,
+ {
+ Text::Underline::SOLID,
+ Color::BLACK,
+ 0u,
+ 1u,
+ 2u,
+ true,
+ false,
+ false,
+ false,
+ false,
+ }},
+
+ //<u type='dashed'>ABC3</u>
+ {"<u type='dashed'>ABC3</u>",
+ 8u,
+ 11u,
+ 21u,
+ 24u,
+ {
+ Text::Underline::DASHED,
+ Color::BLACK,
+ 0u,
+ 1u,
+ 2u,
+ true,
+ false,
+ false,
+ false,
+ false,
+ }},
+
+ //<u type='double'>ABC4</u>
+ {"<u type='double'>ABC4</u>",
+ 12u,
+ 15u,
+ 29u,
+ 32u,
+ {
+ Text::Underline::DOUBLE,
+ Color::BLACK,
+ 0u,
+ 1u,
+ 2u,
+ true,
+ false,
+ false,
+ false,
+ false,
+ }},
+
+ //<u color='green'>ABC5</u>
+ {"<u color='green'>ABC5</u>",
+ 16u,
+ 19u,
+ 37u,
+ 40u,
+ {
+ Text::Underline::SOLID,
+ Color::GREEN,
+ 0u,
+ 1u,
+ 2u,
+ false,
+ true,
+ false,
+ false,
+ false,
+ }},
+
+ //<u height='5.0f'>ABC6</u>
+ {"<u height='5.0f'>ABC6</u>",
+ 20u,
+ 23u,
+ 45u,
+ 48u,
+ {
+ Text::Underline::SOLID,
+ Color::BLACK,
+ 5u,
+ 1u,
+ 2u,
+ false,
+ false,
+ true,
+ false,
+ false,
+ }},
+
+ //<u type='dashed' dash-gap='3.0f'>ABC7</u>
+ {"<u type='dashed' dash-gap='3.0f'>ABC7</u>",
+ 24u,
+ 27u,
+ 53u,
+ 56u,
+ {
+ Text::Underline::DASHED,
+ Color::BLACK,
+ 0u,
+ 3u,
+ 2u,
+ true,
+ false,
+ false,
+ true,
+ false,
+ }},
+
+ //<u type='dashed' dash-width='4.0f'>ABC8</u>
+ {"<u type='dashed' dash-width='4.0f'>ABC8</u>",
+ 28u,
+ 31u,
+ 61u,
+ 64u,
+ {
+ Text::Underline::DASHED,
+ Color::BLACK,
+ 0u,
+ 1u,
+ 4u,
+ true,
+ false,
+ false,
+ false,
+ true,
+ }},
+
+ //<u color='blue' type='dashed' height='4.0f' dash-gap='2.0f' dash-width='3.0f'>
+ {"<u color='blue' type='dashed' height='4.0f' dash-gap='2.0f' dash-width='3.0f'>",
+ 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;
}
DALI_TEST_EQUALS(numberOfUnderlineRuns, expectedNumberOfUnderlinedGlyphs, TEST_LOCATION);
- Vector<GlyphRun> underlineRuns;
+ Vector<UnderlinedGlyphRun> 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 =
+ "start<u>ABC1</u>then"
+ "<u type='solid'>ABC2</u>then"
+ "<u type='dashed'>ABC3</u>then"
+ "<u type='double'>ABC4</u>then"
+ "<u color='green'>ABC5</u>then"
+ "<u height='5.0f'>ABC6</u>then"
+ "<u type='dashed' dash-gap='3.0f'>ABC7</u>then"
+ "<u type='dashed' dash-width='4.0f'>ABC8</u>then"
+ "<u color='blue' type='dashed' height='4.0f' dash-gap='2.0f' dash-width='3.0f'>ABC9</u>end"
+
+ ;
+
+ 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<UnderlinedGlyphRun> 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[] =
+ {
+ //<u>ABC1</u>
+ {"<u>ABC1</u>",
+ 0u,
+ 3u,
+ 5u,
+ 8u,
+ {
+ Text::Underline::SOLID,
+ Color::BLACK,
+ 0u,
+ 1u,
+ 2u,
+ false,
+ false,
+ false,
+ false,
+ false,
+ }},
+
+ //<u type='solid'>ABC2</u>
+ {"<u type='solid'>ABC2</u>",
+ 4u,
+ 7u,
+ 13u,
+ 16u,
+ {
+ Text::Underline::SOLID,
+ Color::BLACK,
+ 0u,
+ 1u,
+ 2u,
+ true,
+ false,
+ false,
+ false,
+ false,
+ }},
+
+ //<u type='dashed'>ABC3</u>
+ {"<u type='dashed'>ABC3</u>",
+ 8u,
+ 11u,
+ 21u,
+ 24u,
+ {
+ Text::Underline::DASHED,
+ Color::BLACK,
+ 0u,
+ 1u,
+ 2u,
+ true,
+ false,
+ false,
+ false,
+ false,
+ }},
+
+ //<u type='double'>ABC4</u>
+ {"<u type='double'>ABC4</u>",
+ 12u,
+ 15u,
+ 29u,
+ 32u,
+ {
+ Text::Underline::DOUBLE,
+ Color::BLACK,
+ 0u,
+ 1u,
+ 2u,
+ true,
+ false,
+ false,
+ false,
+ false,
+ }},
+
+ //<u color='green'>ABC5</u>
+ {"<u color='green'>ABC5</u>",
+ 16u,
+ 19u,
+ 37u,
+ 40u,
+ {
+ Text::Underline::SOLID,
+ Color::GREEN,
+ 0u,
+ 1u,
+ 2u,
+ false,
+ true,
+ false,
+ false,
+ false,
+ }},
+
+ //<u height='5.0f'>ABC6</u>
+ {"<u height='5.0f'>ABC6</u>",
+ 20u,
+ 23u,
+ 45u,
+ 48u,
+ {
+ Text::Underline::SOLID,
+ Color::BLACK,
+ 5u,
+ 1u,
+ 2u,
+ false,
+ false,
+ true,
+ false,
+ false,
+ }},
+
+ //<u type='dashed' dash-gap='3.0f'>ABC7</u>
+ {"<u type='dashed' dash-gap='3.0f'>ABC7</u>",
+ 24u,
+ 27u,
+ 53u,
+ 56u,
+ {
+ Text::Underline::DASHED,
+ Color::BLACK,
+ 0u,
+ 3u,
+ 2u,
+ true,
+ false,
+ false,
+ true,
+ false,
+ }},
+
+ //<u type='dashed' dash-width='4.0f'>ABC8</u>
+ {"<u type='dashed' dash-width='4.0f'>ABC8</u>",
+ 28u,
+ 31u,
+ 61u,
+ 64u,
+ {
+ Text::Underline::DASHED,
+ Color::BLACK,
+ 0u,
+ 1u,
+ 4u,
+ true,
+ false,
+ false,
+ false,
+ true,
+ }},
+
+ //<u color='blue' type='dashed' height='4.0f' dash-gap='2.0f' dash-width='3.0f'>
+ {"<u color='blue' type='dashed' height='4.0f' dash-gap='2.0f' dash-width='3.0f'>",
+ 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;
}
*
*/
+#include <bits/stdint-uintn.h>
#include <stdlib.h>
#include <iostream>
DALI_TEST_EQUALS(numberOfUnderlineRuns, expectedNumberOfUnderlinedGlyphs, TEST_LOCATION);
- Vector<GlyphRun> underlineRuns;
+ Vector<UnderlinedGlyphRun> 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 =
+ "start<u>ABC1</u>then"
+ "<u type='solid'>ABC2</u>then"
+ "<u type='dashed'>ABC3</u>then"
+ "<u type='double'>ABC4</u>then"
+ "<u color='green'>ABC5</u>then"
+ "<u height='5.0f'>ABC6</u>then"
+ "<u type='dashed' dash-gap='3.0f'>ABC7</u>then"
+ "<u type='dashed' dash-width='4.0f'>ABC8</u>then"
+ "<u color='blue' type='dashed' height='4.0f' dash-gap='2.0f' dash-width='3.0f'>ABC9</u>end"
+
+ ;
+
+ 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<UnderlinedGlyphRun> 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[] =
+ {
+ //<u>ABC1</u>
+ {"<u>ABC1</u>",
+ 0u,
+ 3u,
+ 5u,
+ 8u,
+ {
+ Text::Underline::SOLID,
+ Color::BLACK,
+ 0u,
+ 1u,
+ 2u,
+ false,
+ false,
+ false,
+ false,
+ false,
+ }},
+
+ //<u type='solid'>ABC2</u>
+ {"<u type='solid'>ABC2</u>",
+ 4u,
+ 7u,
+ 13u,
+ 16u,
+ {
+ Text::Underline::SOLID,
+ Color::BLACK,
+ 0u,
+ 1u,
+ 2u,
+ true,
+ false,
+ false,
+ false,
+ false,
+ }},
+
+ //<u type='dashed'>ABC3</u>
+ {"<u type='dashed'>ABC3</u>",
+ 8u,
+ 11u,
+ 21u,
+ 24u,
+ {
+ Text::Underline::DASHED,
+ Color::BLACK,
+ 0u,
+ 1u,
+ 2u,
+ true,
+ false,
+ false,
+ false,
+ false,
+ }},
+
+ //<u type='double'>ABC4</u>
+ {"<u type='double'>ABC4</u>",
+ 12u,
+ 15u,
+ 29u,
+ 32u,
+ {
+ Text::Underline::DOUBLE,
+ Color::BLACK,
+ 0u,
+ 1u,
+ 2u,
+ true,
+ false,
+ false,
+ false,
+ false,
+ }},
+
+ //<u color='green'>ABC5</u>
+ {"<u color='green'>ABC5</u>",
+ 16u,
+ 19u,
+ 37u,
+ 40u,
+ {
+ Text::Underline::SOLID,
+ Color::GREEN,
+ 0u,
+ 1u,
+ 2u,
+ false,
+ true,
+ false,
+ false,
+ false,
+ }},
+
+ //<u height='5.0f'>ABC6</u>
+ {"<u height='5.0f'>ABC6</u>",
+ 20u,
+ 23u,
+ 45u,
+ 48u,
+ {
+ Text::Underline::SOLID,
+ Color::BLACK,
+ 5u,
+ 1u,
+ 2u,
+ false,
+ false,
+ true,
+ false,
+ false,
+ }},
+
+ //<u type='dashed' dash-gap='3.0f'>ABC7</u>
+ {"<u type='dashed' dash-gap='3.0f'>ABC7</u>",
+ 24u,
+ 27u,
+ 53u,
+ 56u,
+ {
+ Text::Underline::DASHED,
+ Color::BLACK,
+ 0u,
+ 3u,
+ 2u,
+ true,
+ false,
+ false,
+ true,
+ false,
+ }},
+
+ //<u type='dashed' dash-width='4.0f'>ABC8</u>
+ {"<u type='dashed' dash-width='4.0f'>ABC8</u>",
+ 28u,
+ 31u,
+ 61u,
+ 64u,
+ {
+ Text::Underline::DASHED,
+ Color::BLACK,
+ 0u,
+ 1u,
+ 4u,
+ true,
+ false,
+ false,
+ false,
+ true,
+ }},
+
+ //<u color='blue' type='dashed' height='4.0f' dash-gap='2.0f' dash-width='3.0f'>
+ {"<u color='blue' type='dashed' height='4.0f' dash-gap='2.0f' dash-width='3.0f'>",
+ 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;
}
${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/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
--- /dev/null
+/*
+ * 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 <dali-toolkit/internal/text/markup-processor-underline.h>
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/dali-vector.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/markup-processor-attribute-helper-functions.h>
+#include <dali-toolkit/internal/text/markup-processor-helper-functions.h>
+#include <dali-toolkit/internal/text/text-effects-style.h>
+#include <dali-toolkit/internal/text/underlined-character-run.h>
+
+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<Text::Underline::Type>(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<Attribute>::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
--- /dev/null
+#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
#include <dali-toolkit/internal/text/markup-processor-helper-functions.h>
#include <dali-toolkit/internal/text/markup-processor-span.h>
#include <dali-toolkit/internal/text/markup-processor-strikethrough.h>
+#include <dali-toolkit/internal/text/markup-processor-underline.h>
#include <dali-toolkit/internal/text/xhtml-entities.h>
namespace Dali
else if(TokenComparison(XHTML_U_TAG, tag.buffer, tag.length))
{
ProcessTagForRun<UnderlinedCharacterRun>(
- 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); });
} // <u></u>
else if(TokenComparison(XHTML_B_TAG, tag.buffer, tag.length))
{
#include <dali/public-api/animation/constraints.h>
#include <dali/public-api/rendering/geometry.h>
#include <dali/public-api/rendering/renderer.h>
+#include <map>
// INTERNAL INCLUDES
#include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
#include <dali-toolkit/internal/text/glyph-run.h>
#include <dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager.h>
#include <dali-toolkit/internal/text/rendering/atlas/atlas-mesh-factory.h>
+#include <dali-toolkit/internal/text/rendering/styles/strikethrough-helper-functions.h>
+#include <dali-toolkit/internal/text/rendering/styles/underline-helper-functions.h>
#include <dali-toolkit/internal/text/text-view.h>
using namespace Dali;
mQuadVertexFormat["aColor"] = Property::VECTOR4;
}
- bool IsGlyphUnderlined(GlyphIndex index,
- const Vector<GlyphRun>& underlineRuns)
- {
- for(Vector<GlyphRun>::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<StrikethroughGlyphRun>& strikethroughRuns,
- Vector4& strikethroughColor)
+ bool
+ doGlyphHaveStrikethrough(GlyphIndex index,
+ const Vector<StrikethroughGlyphRun>& strikethroughRuns,
+ Vector4& strikethroughColor)
{
for(Vector<StrikethroughGlyphRun>::ConstIterator it = strikethroughRuns.Begin(),
endIt = strikethroughRuns.End();
Vector<Extent> 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();
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<GlyphRun> underlineRuns;
+ const Length numberOfUnderlineRuns = view.GetNumberOfUnderlineRuns();
+ Vector<UnderlinedGlyphRun> 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<StrikethroughGlyphRun> strikethroughRuns;
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)
{
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<uint32_t, UnderlineStyleProperties> 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.
}
}
+ //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;
glyph = *(glyphsBuffer + i);
}
- const bool isGlyphUnderlined = underlineEnabled || IsGlyphUnderlined(i, underlineRuns);
- thereAreUnderlinedGlyphs = thereAreUnderlinedGlyphs || isGlyphUnderlined;
+ Vector<UnderlinedGlyphRun>::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);
// 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;
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 <u>World</u> Hello <u>World</u>", "<u>World</u> Hello <u>World</u>", "<u> World</u> Hello <u>World</u>"
+ if(isPreUnderlined && (!isGlyphUnderlined || (preUnderlineProperties != currentUnderlineProperties)))
+ {
+ mapUnderlineChunkIdWithProperties.insert(std::pair<uint32_t, UnderlineStyleProperties>(underlineChunkId, preUnderlineProperties));
+ underlineChunkId++;
+ }
+
+ //Keep status of underlined for previous glyph to check consecutive indices
+ isPreUnderlined = isGlyphUnderlined;
+ preUnderlineProperties = currentUnderlineProperties;
+
GenerateMesh(glyph,
positionPlusOutlineOffset,
color,
slot,
isGlyphUnderlined,
currentUnderlinePosition,
- currentUnderlineThickness,
+ maxUnderlineHeight,
meshContainer,
newTextCache,
extents,
slot,
strikethroughGlyphsExist,
0.0f,
- currentStrikethroughThickness,
+ maxStrikethroughHeight,
meshContainer,
newTextCache,
strikethroughExtents,
slotOutline,
false,
currentUnderlinePosition,
- currentUnderlineThickness,
+ maxUnderlineHeight,
meshContainerOutline,
newTextCache,
extents,
0u);
}
- //The new underlined chunk. Add new id if they are not consecutive indices (this is for Markup case)
- // Examples: "Hello <u>World</u> Hello <u>World</u>", "<u>World</u> Hello <u>World</u>", "<u> World</u> Hello <u>World</u>"
- if(isPreUnderlined && (isPreUnderlined != isGlyphUnderlined))
- {
- underlineChunkId++;
- }
- //Keep status of underlined for previous glyph to check consecutive indices
- isPreUnderlined = isGlyphUnderlined;
-
if(isPrevGlyphStrikethrough && !isStrikethroughGlyph)
{
strikethroughChunkId++;
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)
}
}
- void GenerateUnderlines(std::vector<MeshRecord>& meshRecords,
- Vector<Extent>& extents,
- const Vector4& underlineColor,
- const Text::Underline::Type& underlineType,
- const float& dashedUnderlineWidth,
- const float& dashedUnderlineGap)
+ void GenerateUnderlines(std::vector<MeshRecord>& meshRecords,
+ Vector<Extent>& extents,
+ const UnderlineStyleProperties& viewUnderlineProperties,
+ const std::map<uint32_t, UnderlineStyleProperties>& mapUnderlineChunkIdWithProperties)
{
AtlasManager::Mesh2D newMesh;
unsigned short faceIndex = 0;
+
for(Vector<Extent>::ConstIterator eIt = extents.Begin(),
eEndIt = extents.End();
eIt != eEndIt;
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;
{
float dashTlx = tlx;
float dashBrx = tlx;
- faceIndex = 0;
- AtlasManager::Mesh2D newMesh;
while((dashTlx >= tlx) && (dashTlx < brx) && ((dashTlx + dashedUnderlineWidth) <= brx))
{
dashBrx = dashTlx + dashedUnderlineWidth;
--- /dev/null
+/*
+ * 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 <dali-toolkit/internal/text/rendering/styles/strikethrough-helper-functions.h>
+
+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
--- /dev/null
+#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 <dali/devel-api/text-abstraction/font-metrics.h>
+#include <dali/public-api/common/dali-vector.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/underlined-glyph-run.h>
+#include <dali/devel-api/text-abstraction/text-abstraction-definitions.h>
+
+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
--- /dev/null
+/*
+ * 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 <dali-toolkit/internal/text/rendering/styles/underline-helper-functions.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+bool IsGlyphUnderlined(GlyphIndex index,
+ const Vector<UnderlinedGlyphRun>& underlineRuns,
+ Vector<UnderlinedGlyphRun>::ConstIterator& currentUnderlinedGlyphRunIt)
+{
+ for(Vector<UnderlinedGlyphRun>::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<UnderlinedGlyphRun>& underlineRuns,
+ Vector<UnderlinedGlyphRun>::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<UnderlinedGlyphRun>& underlineRuns,
+ Vector<UnderlinedGlyphRun>::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
--- /dev/null
+#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 <dali/devel-api/text-abstraction/font-metrics.h>
+#include <dali/public-api/common/dali-vector.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/underlined-glyph-run.h>
+#include <dali/devel-api/text-abstraction/text-abstraction-definitions.h>
+
+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<UnderlinedGlyphRun>& underlineRuns,
+ Vector<UnderlinedGlyphRun>::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<UnderlinedGlyphRun>& underlineRuns,
+ Vector<UnderlinedGlyphRun>::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<UnderlinedGlyphRun>& underlineRuns,
+ Vector<UnderlinedGlyphRun>::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
// INTERNAL INCLUDES
#include <dali-toolkit/devel-api/controls/text-controls/text-label-devel.h>
#include <dali-toolkit/internal/text/glyph-metrics-helper.h>
+#include <dali-toolkit/internal/text/rendering/styles/strikethrough-helper-functions.h>
+#include <dali-toolkit/internal/text/rendering/styles/underline-helper-functions.h>
#include <dali-toolkit/internal/text/rendering/view-model.h>
namespace Dali
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.
*/
}
}
-bool IsGlyphUnderlined(GlyphIndex index,
- const Vector<GlyphRun>& underlineRuns)
-{
- for(Vector<GlyphRun>::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<StrikethroughGlyphRun>& strikethroughRuns,
Vector4& strikethroughColor)
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,
/// 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<uint32_t*>(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)
{
}
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)
{
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<uint32_t*>(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)
{
}
}
- 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<GlyphRun> underlineRuns;
+ const Length numberOfUnderlineRuns = mModel->GetNumberOfUnderlineRuns();
+ Vector<UnderlinedGlyphRun> underlineRuns;
underlineRuns.Resize(numberOfUnderlineRuns);
mModel->GetUnderlineRuns(underlineRuns.Begin(), 0u, numberOfUnderlineRuns);
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;
continue;
}
- const bool underlineGlyph = underlineEnabled || IsGlyphUnderlined(glyphIndex, underlineRuns);
- thereAreUnderlinedGlyphs = thereAreUnderlinedGlyphs || underlineGlyph;
+ Vector<UnderlinedGlyphRun>::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);
// 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
{
//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.
{
// Underline-tags (this is for Markup case)
// Get the underline runs.
- const Length numberOfUnderlineRuns = mModel->GetNumberOfUnderlineRuns();
- Vector<GlyphRun> underlineRuns;
+ const Length numberOfUnderlineRuns = mModel->GetNumberOfUnderlineRuns();
+ Vector<UnderlinedGlyphRun> 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<GlyphRun>::ConstIterator itGlyphRun = underlineRuns.Begin();
- Vector<GlyphRun>::ConstIterator endItGlyphRun = underlineRuns.End();
- GlyphIndex startGlyphIndex, endGlyphIndex;
+ Vector<UnderlinedGlyphRun>::ConstIterator itGlyphRun = underlineRuns.Begin();
+ Vector<UnderlinedGlyphRun>::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--;
#include <memory.h>
// INTERNAL INCLUDES
-#include <dali-toolkit/internal/text/line-run.h>
#include <dali-toolkit/internal/text/glyph-metrics-helper.h>
+#include <dali-toolkit/internal/text/line-run.h>
namespace Dali
{
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);
}
/**
* @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()
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
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
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
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
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
#include <dali-toolkit/internal/text/text-enumerations-impl.h>
#include <dali-toolkit/internal/text/text-run-container.h>
#include <dali-toolkit/internal/text/text-selection-handle-controller.h>
+#include <dali-toolkit/internal/text/underlined-glyph-run.h>
using namespace Dali;
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);
}
}
/*
- * 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.
#include <dali-toolkit/devel-api/controls/text-controls/text-style-properties-devel.h>
#include <dali-toolkit/internal/text/markup-processor-helper-functions.h>
#include <dali-toolkit/internal/text/property-string-parser.h>
-#include <dali-toolkit/public-api/text/text-enumerations.h>
#include <dali-toolkit/internal/text/text-enumerations-impl.h>
namespace Dali
{
const Property::Map& propertiesMap = value.Get<Property::Map>();
- bool enabled = false;
- bool colorDefined = false;
+ bool enabled = false;
+ bool colorDefined = false;
Vector4 color;
bool heightDefined = false;
float height = 0.f;
Text::ParsePropertyString(propertyString, parsedStringMap);
empty = ParseStrikethroughProperties(parsedStringMap,
- enabled,
- colorDefined,
- color,
- heightDefined,
- height);
+ enabled,
+ colorDefined,
+ color,
+ heightDefined,
+ height);
controller->StrikethroughSetByString(!empty);
}
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;
}
}
+Underline::Type StringToUnderlineType(const char* const underlineTypeStr)
+{
+ Underline::Type underlineType = Text::Underline::SOLID;
+ Scripting::GetEnumeration<Underline::Type>(underlineTypeStr,
+ UNDERLINE_TYPE_STRING_TABLE,
+ UNDERLINE_TYPE_STRING_TABLE_COUNT,
+ underlineType);
+
+ return underlineType;
+}
+
} // namespace Text
} // namespace Toolkit
#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.
// INTERNAL INCLUDES
#include <dali-toolkit/internal/text/text-controller.h>
+#include <dali-toolkit/public-api/text/text-enumerations.h>
+#include <dali/devel-api/scripting/scripting.h>
namespace Dali
{
{
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
* @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.
*/
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
#include <dali-toolkit/internal/text/script-run.h>
#include <dali-toolkit/internal/text/strikethrough-glyph-run.h>
#include <dali-toolkit/internal/text/text-definitions.h>
+#include <dali-toolkit/internal/text/underlined-glyph-run.h>
#include <dali-toolkit/public-api/text/text-enumerations.h>
namespace Dali
* @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.
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);
}
/**
* @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()
// INTERNAL INCLUDES
#include <dali-toolkit/devel-api/text/text-enumerations-devel.h>
#include <dali-toolkit/internal/text/text-definitions.h>
+#include <dali-toolkit/internal/text/underlined-glyph-run.h>
#include <dali-toolkit/public-api/text/text-enumerations.h>
namespace Dali
* @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.
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)
{
/**
* @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()
--- /dev/null
+#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 <dali/public-api/math/vector4.h>
+
+// INTERNAL INCLUDES
+
+#include <dali-toolkit/public-api/text/text-enumerations.h>
+
+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
#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.
// INTERNAL INCLUDES
#include <dali-toolkit/internal/text/character-run.h>
-#include <dali-toolkit/internal/text/glyph-run.h>
+#include <dali-toolkit/internal/text/underline-style-properties.h>
namespace Dali
{
*/
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
--- /dev/null
+#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 <dali/public-api/math/vector4.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/glyph-run.h>
+#include <dali-toolkit/internal/text/underline-style-properties.h>
+
+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
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)
#include <dali-toolkit/internal/text/color-run.h>
#include <dali-toolkit/internal/text/line-run.h>
#include <dali-toolkit/internal/text/strikethrough-glyph-run.h>
+#include <dali-toolkit/internal/text/underlined-glyph-run.h>
#include <dali-toolkit/public-api/text/text-enumerations.h>
// DEVEL INCLUDES
* @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
Vector<Length> mGlyphsPerCharacter; ///< For each character, the number of glyphs that are shaped.
Vector<Vector2> mGlyphPositions; ///< For each glyph, the position.
Vector<LineRun> mLines; ///< The laid out lines.
- Vector<GlyphRun> mUnderlineRuns; ///< Runs of glyphs that are underlined.
+ Vector<UnderlinedGlyphRun> mUnderlineRuns; ///< Runs of glyphs that are underlined.
Vector<Vector4> mColors; ///< Colors of the glyphs.
Vector<ColorIndex> mColorIndices; ///< Indices to the vector of colors for each glyphs.
Vector<Vector4> mBackgroundColors; ///< Background colors of the glyphs.