ToolkitTestApplication application;
auto control = Control::New();
- auto noneset = control.GetProperty( DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE );
- DALI_TEST_EQUALS( Property::NONE, noneset.GetType(), TEST_LOCATION );
+ auto highlightable = control.GetProperty<bool>(DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE);
+ DALI_TEST_EQUALS(highlightable, false, TEST_LOCATION);
// negative testcase - trying to set unconvertible value
- control.SetProperty( DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, "deadbeef" );
- noneset = control.GetProperty( DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE );
- DALI_TEST_EQUALS( Property::NONE, noneset.GetType(), TEST_LOCATION );
+ control.SetProperty(DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, "deadbeef");
+ highlightable = control.GetProperty<bool>(DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE);
+ DALI_TEST_EQUALS(highlightable, false, TEST_LOCATION);
auto q = Dali::Accessibility::Accessible::Get( control );
auto control = Control::New();
auto accessibility_translation_domain = DevelControl::Property::ACCESSIBILITY_TRANSLATION_DOMAIN;
- DALI_TEST_EQUALS( Property::NONE , control.GetProperty( accessibility_translation_domain ).GetType(), TEST_LOCATION );
+ DALI_TEST_EQUALS("", control.GetProperty<std::string>(accessibility_translation_domain), TEST_LOCATION);
control.SetProperty( accessibility_translation_domain, "translation_domain_test_1" );
DALI_TEST_EQUALS( "translation_domain_test_1" , control.GetProperty( accessibility_translation_domain ).Get< std::string >(), TEST_LOCATION );
application.SendNotification();
application.Render();
- uint32_t expectedNumberOfUnderlinedGlyphs = 5u;
+ uint32_t expectedNumberOfUnderlineRuns = 2u;
Toolkit::Internal::TextEditor& textEditorImpl = GetImpl(textEditor);
const Text::Length numberOfUnderlineRuns = textEditorImpl.GetTextController()->GetTextModel()->GetNumberOfUnderlineRuns();
- DALI_TEST_EQUALS(numberOfUnderlineRuns, expectedNumberOfUnderlinedGlyphs, TEST_LOCATION);
+ DALI_TEST_EQUALS(numberOfUnderlineRuns, expectedNumberOfUnderlineRuns, TEST_LOCATION);
Vector<UnderlinedGlyphRun> underlineRuns;
underlineRuns.Resize(numberOfUnderlineRuns);
//ABC are underlined
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);
+ DALI_TEST_EQUALS(underlineRuns[0u].glyphRun.numberOfGlyphs, 3u, TEST_LOCATION);
//GH are underlined
- DALI_TEST_EQUALS(underlineRuns[3u].glyphRun.glyphIndex, 5u, TEST_LOCATION);
- DALI_TEST_EQUALS(underlineRuns[4u].glyphRun.glyphIndex, 6u, TEST_LOCATION);
+ DALI_TEST_EQUALS(underlineRuns[1u].glyphRun.glyphIndex, 5u, TEST_LOCATION);
+ DALI_TEST_EQUALS(underlineRuns[1u].glyphRun.numberOfGlyphs, 2u, TEST_LOCATION);
END_TEST;
}
"<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"
-
- ;
+ "<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;
+ const uint32_t expectedNumberOfUnderlineRuns = 9u;
Toolkit::Internal::TextEditor& textEditorImpl = GetImpl(textEditor);
const Text::Length numberOfUnderlineRuns = textEditorImpl.GetTextController()->GetTextModel()->GetNumberOfUnderlineRuns();
- DALI_TEST_EQUALS(numberOfUnderlineRuns, expectedNumberOfUnderlinedGlyphs, TEST_LOCATION);
+ DALI_TEST_EQUALS(numberOfUnderlineRuns, expectedNumberOfUnderlineRuns, TEST_LOCATION);
Vector<UnderlinedGlyphRun> underlineRuns;
underlineRuns.Resize(numberOfUnderlineRuns);
struct DataOfCase
{
std::string title;
- uint32_t startIndex;
- uint32_t endIndex;
- GlyphIndex startGlyphIndex;
- GlyphIndex endGlyphIndex;
+ GlyphIndex glyphIndex;
+ Length numberOfGlyphs;
UnderlineStyleProperties properties;
};
DataOfCase data[] =
{
//<u>ABC1</u>
{"<u>ABC1</u>",
- 0u,
- 3u,
5u,
- 8u,
+ 4u,
{
Text::Underline::SOLID,
Color::BLACK,
//<u type='solid'>ABC2</u>
{"<u type='solid'>ABC2</u>",
- 4u,
- 7u,
13u,
- 16u,
+ 4u,
{
Text::Underline::SOLID,
Color::BLACK,
//<u type='dashed'>ABC3</u>
{"<u type='dashed'>ABC3</u>",
- 8u,
- 11u,
21u,
- 24u,
+ 4u,
{
Text::Underline::DASHED,
Color::BLACK,
//<u type='double'>ABC4</u>
{"<u type='double'>ABC4</u>",
- 12u,
- 15u,
29u,
- 32u,
+ 4u,
{
Text::Underline::DOUBLE,
Color::BLACK,
//<u color='green'>ABC5</u>
{"<u color='green'>ABC5</u>",
- 16u,
- 19u,
37u,
- 40u,
+ 4u,
{
Text::Underline::SOLID,
Color::GREEN,
//<u height='5.0f'>ABC6</u>
{"<u height='5.0f'>ABC6</u>",
- 20u,
- 23u,
45u,
- 48u,
+ 4u,
{
Text::Underline::SOLID,
Color::BLACK,
//<u type='dashed' dash-gap='3.0f'>ABC7</u>
{"<u type='dashed' dash-gap='3.0f'>ABC7</u>",
- 24u,
- 27u,
53u,
- 56u,
+ 4u,
{
Text::Underline::DASHED,
Color::BLACK,
//<u type='dashed' dash-width='4.0f'>ABC8</u>
{"<u type='dashed' dash-width='4.0f'>ABC8</u>",
- 28u,
- 31u,
61u,
- 64u,
+ 4u,
{
Text::Underline::DASHED,
Color::BLACK,
//<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,
+ 4u,
{
Text::Underline::DASHED,
Color::BLUE,
};
- for(uint32_t i = 0; i < NUMBER_OF_CASES; i++)
+ for(uint32_t i = 0; i < expectedNumberOfUnderlineRuns; 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_EQUALS(underlineRuns[i].glyphRun.glyphIndex, data[i].glyphIndex, TEST_LOCATION);
+ DALI_TEST_EQUALS(underlineRuns[i].glyphRun.numberOfGlyphs, data[i].numberOfGlyphs, TEST_LOCATION);
+ DALI_TEST_CHECK(data[i].properties == underlineRuns[i].properties);
+ }
+
+ END_TEST;
+}
+
+int UtcDaliTextEditorMarkupSpanUnderline(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliTextEditorMarkupSpanUnderline ");
+
+ TextEditor textEditor = TextEditor::New();
+
+ application.GetScene().Add(textEditor);
+
+ std::string testText =
+ "start<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red'>ABC1</span>then"
+ "<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-type='solid'>ABC2</span>then"
+ "<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-type='dashed'>ABC3</span>then"
+ "<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-type='double'>ABC4</span>then"
+ "<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-color='green'>ABC5</span>then"
+ "<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-height='5.0f'>ABC6</span>then"
+ "<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-type='dashed' u-dash-gap='3.0f'>ABC7</span>then"
+ "<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-type='dashed' u-dash-width='4.0f'>ABC8</span>then"
+ "<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-color='blue' u-type='dashed' u-height='4.0f' u-dash-gap='2.0f' u-dash-width='3.0f'>ABC9</span>end";
+
+ textEditor.SetProperty(TextEditor::Property::TEXT, testText);
+ textEditor.SetProperty(TextEditor ::Property::ENABLE_MARKUP, true);
+
+ application.SendNotification();
+ application.Render();
+
+ const uint32_t expectedNumberOfUnderlineRuns = 8u;
+
+ Toolkit::Internal::TextEditor& textEditorImpl = GetImpl(textEditor);
+ const Text::Length numberOfUnderlineRuns = textEditorImpl.GetTextController()->GetTextModel()->GetNumberOfUnderlineRuns();
+
+ DALI_TEST_EQUALS(numberOfUnderlineRuns, expectedNumberOfUnderlineRuns, TEST_LOCATION);
+
+ Vector<UnderlinedGlyphRun> underlineRuns;
+ underlineRuns.Resize(numberOfUnderlineRuns);
+ textEditorImpl.GetTextController()->GetTextModel()->GetUnderlineRuns(underlineRuns.Begin(), 0u, numberOfUnderlineRuns);
+
+ struct DataOfCase
+ {
+ std::string title;
+ GlyphIndex glyphIndex;
+ Length numberOfGlyphs;
+ UnderlineStyleProperties properties;
+ };
+ DataOfCase data[] =
+ {
+ //<u type='solid'>ABC2</u>
+ {"<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-type='solid'>ABC2</span>",
+ 13u,
+ 4u,
+ {
+ Text::Underline::SOLID,
+ Color::BLACK,
+ 0u,
+ 1u,
+ 2u,
+ true,
+ false,
+ false,
+ false,
+ false,
+ }},
+
+ //<u type='dashed'>ABC3</u>
+ {"<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-type='dashed'>ABC3</span>",
+ 21u,
+ 4u,
+ {
+ Text::Underline::DASHED,
+ Color::BLACK,
+ 0u,
+ 1u,
+ 2u,
+ true,
+ false,
+ false,
+ false,
+ false,
+ }},
- DALI_TEST_CHECK(data[i].properties == underlineRuns[data[i].startIndex].properties);
- DALI_TEST_CHECK(data[i].properties == underlineRuns[data[i].endIndex].properties);
+ //<u type='double'>ABC4</u>
+ {"<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-type='double'>ABC4</span>",
+ 29u,
+ 4u,
+ {
+ Text::Underline::DOUBLE,
+ Color::BLACK,
+ 0u,
+ 1u,
+ 2u,
+ true,
+ false,
+ false,
+ false,
+ false,
+ }},
+
+ //<u color='green'>ABC5</u>
+ {"<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-color='green'>ABC5</span>",
+ 37u,
+ 4u,
+ {
+ Text::Underline::SOLID,
+ Color::GREEN,
+ 0u,
+ 1u,
+ 2u,
+ false,
+ true,
+ false,
+ false,
+ false,
+ }},
+
+ //<u height='5.0f'>ABC6</u>
+ {"<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-height='5.0f'>ABC6</span>",
+ 45u,
+ 4u,
+ {
+ Text::Underline::SOLID,
+ Color::BLACK,
+ 5u,
+ 1u,
+ 2u,
+ false,
+ false,
+ true,
+ false,
+ false,
+ }},
+
+ //<u type='dashed' dash-gap='3.0f'>ABC7</u>
+ {"<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-type='dashed' u-dash-gap='3.0f'>ABC7</span>",
+ 53u,
+ 4u,
+ {
+ Text::Underline::DASHED,
+ Color::BLACK,
+ 0u,
+ 3u,
+ 2u,
+ true,
+ false,
+ false,
+ true,
+ false,
+ }},
+
+ //<u type='dashed' dash-width='4.0f'>ABC8</u>
+ {"<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-type='dashed' u-dash-width='4.0f'>ABC8</span>",
+ 61u,
+ 4u,
+ {
+ 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'>
+ {"<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-color='blue' u-type='dashed' u-height='4.0f' u-dash-gap='2.0f' u-dash-width='3.0f'>ABC9</span>",
+ 69u,
+ 4u,
+ {
+ Text::Underline::DASHED,
+ Color::BLUE,
+ 4u,
+ 2u,
+ 3u,
+ true,
+ true,
+ true,
+ true,
+ true,
+ }},
+
+ };
+
+ for(uint32_t i = 0; i < expectedNumberOfUnderlineRuns; i++)
+ {
+ tet_infoline(data[i].title.c_str());
+ DALI_TEST_EQUALS(underlineRuns[i].glyphRun.glyphIndex, data[i].glyphIndex, TEST_LOCATION);
+ DALI_TEST_EQUALS(underlineRuns[i].glyphRun.numberOfGlyphs, data[i].numberOfGlyphs, TEST_LOCATION);
+ DALI_TEST_CHECK(data[i].properties == underlineRuns[i].properties);
+ }
+
+ END_TEST;
+}
+
+int UtcDaliTextEditorMarkupNestedUnderlineTags(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliTextEditorMarkupNestedUnderlineTags ");
+
+ TextEditor textEditor = TextEditor::New();
+
+ application.GetScene().Add(textEditor);
+
+ std::string testText = "start<u height='5.0f' color='green' >AB<u color='blue' >XYZ</u>CDE</u>end";
+
+ textEditor.SetProperty(TextEditor::Property::TEXT, testText);
+ textEditor.SetProperty(TextEditor ::Property::ENABLE_MARKUP, true);
+
+ application.SendNotification();
+ application.Render();
+
+ const uint32_t expectedNumberOfUnderlineRuns = 2u;
+
+ Toolkit::Internal::TextEditor& textEditorImpl = GetImpl(textEditor);
+ const Text::Length numberOfUnderlineRuns = textEditorImpl.GetTextController()->GetTextModel()->GetNumberOfUnderlineRuns();
+
+ DALI_TEST_EQUALS(numberOfUnderlineRuns, expectedNumberOfUnderlineRuns, TEST_LOCATION);
+
+ Vector<UnderlinedGlyphRun> underlineRuns;
+ underlineRuns.Resize(numberOfUnderlineRuns);
+ textEditorImpl.GetTextController()->GetTextModel()->GetUnderlineRuns(underlineRuns.Begin(), 0u, numberOfUnderlineRuns);
+
+ struct DataOfCase
+ {
+ std::string title;
+ GlyphIndex glyphIndex;
+ Length numberOfGlyphs;
+ UnderlineStyleProperties properties;
+ };
+ DataOfCase data[] =
+ {
+ //Outter
+ {"<u height='5.0f' color='green' >AB<u color='blue' >XYZ</u>CDE</u>",
+ 5u,
+ 8u,
+ {
+ Text::Underline::SOLID,
+ Color::GREEN,
+ 5u,
+ 1u,
+ 2u,
+ false,
+ true,
+ true,
+ false,
+ false,
+ }},
+
+ //Inner
+ {"<u color='blue' >XYZ</u>",
+ 7u,
+ 3u,
+ {
+ Text::Underline::SOLID,
+ Color::BLUE,
+ 5u,
+ 1u,
+ 2u,
+ false,
+ true,
+ true,
+ false,
+ false,
+ }},
+
+ };
+
+ for(uint32_t i = 0; i < expectedNumberOfUnderlineRuns; i++)
+ {
+ tet_infoline(data[i].title.c_str());
+ DALI_TEST_EQUALS(underlineRuns[i].glyphRun.glyphIndex, data[i].glyphIndex, TEST_LOCATION);
+ DALI_TEST_EQUALS(underlineRuns[i].glyphRun.numberOfGlyphs, data[i].numberOfGlyphs, TEST_LOCATION);
+ DALI_TEST_CHECK(data[i].properties == underlineRuns[i].properties);
}
END_TEST;
application.SendNotification();
application.Render();
- uint32_t expectedNumberOfUnderlinedGlyphs = 5u;
+ uint32_t expectedNumberOfUnderlineRuns = 2u;
Toolkit::Internal::TextField& textFieldImpl = GetImpl(textField);
const Text::Length numberOfUnderlineRuns = textFieldImpl.GetTextController()->GetTextModel()->GetNumberOfUnderlineRuns();
- DALI_TEST_EQUALS(numberOfUnderlineRuns, expectedNumberOfUnderlinedGlyphs, TEST_LOCATION);
+ DALI_TEST_EQUALS(numberOfUnderlineRuns, expectedNumberOfUnderlineRuns, TEST_LOCATION);
Vector<UnderlinedGlyphRun> underlineRuns;
underlineRuns.Resize(numberOfUnderlineRuns);
//ABC are underlined
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);
+ DALI_TEST_EQUALS(underlineRuns[0u].glyphRun.numberOfGlyphs, 3u, TEST_LOCATION);
//GH are underlined
- DALI_TEST_EQUALS(underlineRuns[3u].glyphRun.glyphIndex, 5u, TEST_LOCATION);
- DALI_TEST_EQUALS(underlineRuns[4u].glyphRun.glyphIndex, 6u, TEST_LOCATION);
+ DALI_TEST_EQUALS(underlineRuns[1u].glyphRun.glyphIndex, 5u, TEST_LOCATION);
+ DALI_TEST_EQUALS(underlineRuns[1u].glyphRun.numberOfGlyphs, 2u, TEST_LOCATION);
END_TEST;
}
application.SendNotification();
application.Render();
- const uint32_t NUMBER_OF_CASES = 9u;
- uint32_t expectedNumberOfUnderlinedGlyphs = 36u;
+ const uint32_t expectedNumberOfUnderlineRuns = 9u;
Toolkit::Internal::TextField& textFieldImpl = GetImpl(textField);
const Text::Length numberOfUnderlineRuns = textFieldImpl.GetTextController()->GetTextModel()->GetNumberOfUnderlineRuns();
- DALI_TEST_EQUALS(numberOfUnderlineRuns, expectedNumberOfUnderlinedGlyphs, TEST_LOCATION);
+ DALI_TEST_EQUALS(numberOfUnderlineRuns, expectedNumberOfUnderlineRuns, TEST_LOCATION);
Vector<UnderlinedGlyphRun> underlineRuns;
underlineRuns.Resize(numberOfUnderlineRuns);
struct DataOfCase
{
std::string title;
- uint32_t startIndex;
- uint32_t endIndex;
- GlyphIndex startGlyphIndex;
- GlyphIndex endGlyphIndex;
+ GlyphIndex glyphIndex;
+ Length numberOfGlyphs;
UnderlineStyleProperties properties;
};
DataOfCase data[] =
{
//<u>ABC1</u>
{"<u>ABC1</u>",
- 0u,
- 3u,
5u,
- 8u,
+ 4u,
{
Text::Underline::SOLID,
Color::BLACK,
//<u type='solid'>ABC2</u>
{"<u type='solid'>ABC2</u>",
- 4u,
- 7u,
13u,
- 16u,
+ 4u,
{
Text::Underline::SOLID,
Color::BLACK,
//<u type='dashed'>ABC3</u>
{"<u type='dashed'>ABC3</u>",
- 8u,
- 11u,
21u,
- 24u,
+ 4u,
{
Text::Underline::DASHED,
Color::BLACK,
//<u type='double'>ABC4</u>
{"<u type='double'>ABC4</u>",
- 12u,
- 15u,
29u,
- 32u,
+ 4u,
{
Text::Underline::DOUBLE,
Color::BLACK,
//<u color='green'>ABC5</u>
{"<u color='green'>ABC5</u>",
- 16u,
- 19u,
37u,
- 40u,
+ 4u,
{
Text::Underline::SOLID,
Color::GREEN,
//<u height='5.0f'>ABC6</u>
{"<u height='5.0f'>ABC6</u>",
- 20u,
- 23u,
45u,
- 48u,
+ 4u,
{
Text::Underline::SOLID,
Color::BLACK,
//<u type='dashed' dash-gap='3.0f'>ABC7</u>
{"<u type='dashed' dash-gap='3.0f'>ABC7</u>",
- 24u,
- 27u,
53u,
- 56u,
+ 4u,
{
Text::Underline::DASHED,
Color::BLACK,
//<u type='dashed' dash-width='4.0f'>ABC8</u>
{"<u type='dashed' dash-width='4.0f'>ABC8</u>",
- 28u,
- 31u,
61u,
- 64u,
+ 4u,
{
Text::Underline::DASHED,
Color::BLACK,
//<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,
+ 4u,
+ {
+ Text::Underline::DASHED,
+ Color::BLUE,
+ 4u,
+ 2u,
+ 3u,
+ true,
+ true,
+ true,
+ true,
+ true,
+ }},
+
+ };
+
+ for(uint32_t i = 0; i < expectedNumberOfUnderlineRuns; i++)
+ {
+ tet_infoline(data[i].title.c_str());
+ DALI_TEST_EQUALS(underlineRuns[i].glyphRun.glyphIndex, data[i].glyphIndex, TEST_LOCATION);
+ DALI_TEST_EQUALS(underlineRuns[i].glyphRun.numberOfGlyphs, data[i].numberOfGlyphs, TEST_LOCATION);
+ DALI_TEST_CHECK(data[i].properties == underlineRuns[i].properties);
+ }
+
+ END_TEST;
+}
+
+int UtcDaliTextFieldMarkupSpanUnderline(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliTextFieldMarkupSpanUnderline ");
+
+ TextField textField = TextField::New();
+
+ application.GetScene().Add(textField);
+
+ std::string testText =
+ "start<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red'>ABC1</span>then"
+ "<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-type='solid'>ABC2</span>then"
+ "<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-type='dashed'>ABC3</span>then"
+ "<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-type='double'>ABC4</span>then"
+ "<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-color='green'>ABC5</span>then"
+ "<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-height='5.0f'>ABC6</span>then"
+ "<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-type='dashed' u-dash-gap='3.0f'>ABC7</span>then"
+ "<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-type='dashed' u-dash-width='4.0f'>ABC8</span>then"
+ "<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-color='blue' u-type='dashed' u-height='4.0f' u-dash-gap='2.0f' u-dash-width='3.0f'>ABC9</span>end";
+
+ textField.SetProperty(TextField::Property::TEXT, testText);
+ textField.SetProperty(TextField ::Property::ENABLE_MARKUP, true);
+
+ application.SendNotification();
+ application.Render();
+
+ const uint32_t expectedNumberOfUnderlineRuns = 8u;
+
+ Toolkit::Internal::TextField& textFieldImpl = GetImpl(textField);
+ const Text::Length numberOfUnderlineRuns = textFieldImpl.GetTextController()->GetTextModel()->GetNumberOfUnderlineRuns();
+
+ DALI_TEST_EQUALS(numberOfUnderlineRuns, expectedNumberOfUnderlineRuns, TEST_LOCATION);
+
+ Vector<UnderlinedGlyphRun> underlineRuns;
+ underlineRuns.Resize(numberOfUnderlineRuns);
+ textFieldImpl.GetTextController()->GetTextModel()->GetUnderlineRuns(underlineRuns.Begin(), 0u, numberOfUnderlineRuns);
+
+ struct DataOfCase
+ {
+ std::string title;
+ GlyphIndex glyphIndex;
+ Length numberOfGlyphs;
+ UnderlineStyleProperties properties;
+ };
+ DataOfCase data[] =
+ {
+ //<u type='solid'>ABC2</u>
+ {"<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-type='solid'>ABC2</span>",
+ 13u,
+ 4u,
+ {
+ Text::Underline::SOLID,
+ Color::BLACK,
+ 0u,
+ 1u,
+ 2u,
+ true,
+ false,
+ false,
+ false,
+ false,
+ }},
+
+ //<u type='dashed'>ABC3</u>
+ {"<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-type='dashed'>ABC3</span>",
+ 21u,
+ 4u,
+ {
+ Text::Underline::DASHED,
+ Color::BLACK,
+ 0u,
+ 1u,
+ 2u,
+ true,
+ false,
+ false,
+ false,
+ false,
+ }},
+
+ //<u type='double'>ABC4</u>
+ {"<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-type='double'>ABC4</span>",
+ 29u,
+ 4u,
+ {
+ Text::Underline::DOUBLE,
+ Color::BLACK,
+ 0u,
+ 1u,
+ 2u,
+ true,
+ false,
+ false,
+ false,
+ false,
+ }},
+
+ //<u color='green'>ABC5</u>
+ {"<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-color='green'>ABC5</span>",
+ 37u,
+ 4u,
+ {
+ Text::Underline::SOLID,
+ Color::GREEN,
+ 0u,
+ 1u,
+ 2u,
+ false,
+ true,
+ false,
+ false,
+ false,
+ }},
+
+ //<u height='5.0f'>ABC6</u>
+ {"<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-height='5.0f'>ABC6</span>",
+ 45u,
+ 4u,
+ {
+ Text::Underline::SOLID,
+ Color::BLACK,
+ 5u,
+ 1u,
+ 2u,
+ false,
+ false,
+ true,
+ false,
+ false,
+ }},
+
+ //<u type='dashed' dash-gap='3.0f'>ABC7</u>
+ {"<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-type='dashed' u-dash-gap='3.0f'>ABC7</span>",
+ 53u,
+ 4u,
+ {
+ Text::Underline::DASHED,
+ Color::BLACK,
+ 0u,
+ 3u,
+ 2u,
+ true,
+ false,
+ false,
+ true,
+ false,
+ }},
+
+ //<u type='dashed' dash-width='4.0f'>ABC8</u>
+ {"<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-type='dashed' u-dash-width='4.0f'>ABC8</span>",
+ 61u,
+ 4u,
+ {
+ 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'>
+ {"<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-color='blue' u-type='dashed' u-height='4.0f' u-dash-gap='2.0f' u-dash-width='3.0f'>ABC9</span>",
+ 69u,
+ 4u,
{
Text::Underline::DASHED,
Color::BLUE,
};
- for(uint32_t i = 0; i < NUMBER_OF_CASES; i++)
+ for(uint32_t i = 0; i < expectedNumberOfUnderlineRuns; 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_EQUALS(underlineRuns[i].glyphRun.glyphIndex, data[i].glyphIndex, TEST_LOCATION);
+ DALI_TEST_EQUALS(underlineRuns[i].glyphRun.numberOfGlyphs, data[i].numberOfGlyphs, TEST_LOCATION);
+ DALI_TEST_CHECK(data[i].properties == underlineRuns[i].properties);
+ }
- DALI_TEST_CHECK(data[i].properties == underlineRuns[data[i].startIndex].properties);
- DALI_TEST_CHECK(data[i].properties == underlineRuns[data[i].endIndex].properties);
+ END_TEST;
+}
+
+int UtcDaliTextFieldMarkupNestedUnderlineTags(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliTextFieldMarkupNestedUnderlineTags ");
+
+ TextField textField = TextField::New();
+
+ application.GetScene().Add(textField);
+
+ std::string testText = "start<u height='5.0f' color='green' >AB<u color='blue' >XYZ</u>CDE</u>end";
+
+ textField.SetProperty(TextField::Property::TEXT, testText);
+ textField.SetProperty(TextField ::Property::ENABLE_MARKUP, true);
+
+ application.SendNotification();
+ application.Render();
+
+ const uint32_t expectedNumberOfUnderlineRuns = 2u;
+
+ Toolkit::Internal::TextField& textFieldImpl = GetImpl(textField);
+ const Text::Length numberOfUnderlineRuns = textFieldImpl.GetTextController()->GetTextModel()->GetNumberOfUnderlineRuns();
+
+ DALI_TEST_EQUALS(numberOfUnderlineRuns, expectedNumberOfUnderlineRuns, TEST_LOCATION);
+
+ Vector<UnderlinedGlyphRun> underlineRuns;
+ underlineRuns.Resize(numberOfUnderlineRuns);
+ textFieldImpl.GetTextController()->GetTextModel()->GetUnderlineRuns(underlineRuns.Begin(), 0u, numberOfUnderlineRuns);
+
+ struct DataOfCase
+ {
+ std::string title;
+ GlyphIndex glyphIndex;
+ Length numberOfGlyphs;
+ UnderlineStyleProperties properties;
+ };
+ DataOfCase data[] =
+ {
+ //Outter
+ {"<u height='5.0f' color='green' >AB<u color='blue' >XYZ</u>CDE</u>",
+ 5u,
+ 8u,
+ {
+ Text::Underline::SOLID,
+ Color::GREEN,
+ 5u,
+ 1u,
+ 2u,
+ false,
+ true,
+ true,
+ false,
+ false,
+ }},
+
+ //Inner
+ {"<u color='blue' >XYZ</u>",
+ 7u,
+ 3u,
+ {
+ Text::Underline::SOLID,
+ Color::BLUE,
+ 5u,
+ 1u,
+ 2u,
+ false,
+ true,
+ true,
+ false,
+ false,
+ }},
+
+ };
+
+ for(uint32_t i = 0; i < expectedNumberOfUnderlineRuns; i++)
+ {
+ tet_infoline(data[i].title.c_str());
+ DALI_TEST_EQUALS(underlineRuns[i].glyphRun.glyphIndex, data[i].glyphIndex, TEST_LOCATION);
+ DALI_TEST_EQUALS(underlineRuns[i].glyphRun.numberOfGlyphs, data[i].numberOfGlyphs, TEST_LOCATION);
+ DALI_TEST_CHECK(data[i].properties == underlineRuns[i].properties);
}
END_TEST;
application.SendNotification();
application.Render();
- uint32_t expectedNumberOfUnderlinedGlyphs = 5u;
+ uint32_t expectedNumberOfUnderlineRuns = 2u;
Toolkit::Internal::TextLabel& textLabelImpl = GetImpl(textLabel);
const Text::Length numberOfUnderlineRuns = textLabelImpl.GetTextController()->GetTextModel()->GetNumberOfUnderlineRuns();
- DALI_TEST_EQUALS(numberOfUnderlineRuns, expectedNumberOfUnderlinedGlyphs, TEST_LOCATION);
+ DALI_TEST_EQUALS(numberOfUnderlineRuns, expectedNumberOfUnderlineRuns, TEST_LOCATION);
Vector<UnderlinedGlyphRun> underlineRuns;
underlineRuns.Resize(numberOfUnderlineRuns);
//ABC are underlined
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);
+ DALI_TEST_EQUALS(underlineRuns[0u].glyphRun.numberOfGlyphs, 3u, TEST_LOCATION);
//GH are underlined
- DALI_TEST_EQUALS(underlineRuns[3u].glyphRun.glyphIndex, 5u, TEST_LOCATION);
- DALI_TEST_EQUALS(underlineRuns[4u].glyphRun.glyphIndex, 6u, TEST_LOCATION);
+ DALI_TEST_EQUALS(underlineRuns[1u].glyphRun.glyphIndex, 5u, TEST_LOCATION);
+ DALI_TEST_EQUALS(underlineRuns[1u].glyphRun.numberOfGlyphs, 2u, TEST_LOCATION);
END_TEST;
}
application.SendNotification();
application.Render();
- const uint32_t NUMBER_OF_CASES = 9u;
- uint32_t expectedNumberOfUnderlinedGlyphs = 36u;
+ const uint32_t expectedNumberOfUnderlineRuns = 9u;
Toolkit::Internal::TextLabel& textLabelImpl = GetImpl(textLabel);
const Text::Length numberOfUnderlineRuns = textLabelImpl.GetTextController()->GetTextModel()->GetNumberOfUnderlineRuns();
- DALI_TEST_EQUALS(numberOfUnderlineRuns, expectedNumberOfUnderlinedGlyphs, TEST_LOCATION);
+ DALI_TEST_EQUALS(numberOfUnderlineRuns, expectedNumberOfUnderlineRuns, TEST_LOCATION);
Vector<UnderlinedGlyphRun> underlineRuns;
underlineRuns.Resize(numberOfUnderlineRuns);
struct DataOfCase
{
std::string title;
- uint32_t startIndex;
- uint32_t endIndex;
- GlyphIndex startGlyphIndex;
- GlyphIndex endGlyphIndex;
+ GlyphIndex glyphIndex;
+ Length numberOfGlyphs;
UnderlineStyleProperties properties;
};
DataOfCase data[] =
{
//<u>ABC1</u>
{"<u>ABC1</u>",
- 0u,
- 3u,
5u,
- 8u,
+ 4u,
{
Text::Underline::SOLID,
Color::BLACK,
//<u type='solid'>ABC2</u>
{"<u type='solid'>ABC2</u>",
- 4u,
- 7u,
13u,
- 16u,
+ 4u,
{
Text::Underline::SOLID,
Color::BLACK,
//<u type='dashed'>ABC3</u>
{"<u type='dashed'>ABC3</u>",
- 8u,
- 11u,
21u,
- 24u,
+ 4u,
{
Text::Underline::DASHED,
Color::BLACK,
//<u type='double'>ABC4</u>
{"<u type='double'>ABC4</u>",
- 12u,
- 15u,
29u,
- 32u,
+ 4u,
{
Text::Underline::DOUBLE,
Color::BLACK,
//<u color='green'>ABC5</u>
{"<u color='green'>ABC5</u>",
- 16u,
- 19u,
37u,
- 40u,
+ 4u,
{
Text::Underline::SOLID,
Color::GREEN,
//<u height='5.0f'>ABC6</u>
{"<u height='5.0f'>ABC6</u>",
- 20u,
- 23u,
45u,
- 48u,
+ 4u,
{
Text::Underline::SOLID,
Color::BLACK,
//<u type='dashed' dash-gap='3.0f'>ABC7</u>
{"<u type='dashed' dash-gap='3.0f'>ABC7</u>",
- 24u,
- 27u,
53u,
- 56u,
+ 4u,
{
Text::Underline::DASHED,
Color::BLACK,
//<u type='dashed' dash-width='4.0f'>ABC8</u>
{"<u type='dashed' dash-width='4.0f'>ABC8</u>",
- 28u,
- 31u,
61u,
- 64u,
+ 4u,
{
Text::Underline::DASHED,
Color::BLACK,
//<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,
+ 4u,
+ {
+ Text::Underline::DASHED,
+ Color::BLUE,
+ 4u,
+ 2u,
+ 3u,
+ true,
+ true,
+ true,
+ true,
+ true,
+ }},
+
+ };
+
+ for(uint32_t i = 0; i < expectedNumberOfUnderlineRuns; i++)
+ {
+ tet_infoline(data[i].title.c_str());
+ DALI_TEST_EQUALS(underlineRuns[i].glyphRun.glyphIndex, data[i].glyphIndex, TEST_LOCATION);
+ DALI_TEST_EQUALS(underlineRuns[i].glyphRun.numberOfGlyphs, data[i].numberOfGlyphs, TEST_LOCATION);
+ DALI_TEST_CHECK(data[i].properties == underlineRuns[i].properties);
+ }
+
+ END_TEST;
+}
+
+int UtcDaliTextLabelMarkupSpanUnderline(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliTextLabelMarkupSpanUnderline ");
+
+ TextLabel textLabel = TextLabel::New();
+
+ application.GetScene().Add(textLabel);
+
+ std::string testText =
+ "start<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red'>ABC1</span>then"
+ "<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-type='solid'>ABC2</span>then"
+ "<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-type='dashed'>ABC3</span>then"
+ "<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-type='double'>ABC4</span>then"
+ "<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-color='green'>ABC5</span>then"
+ "<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-height='5.0f'>ABC6</span>then"
+ "<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-type='dashed' u-dash-gap='3.0f'>ABC7</span>then"
+ "<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-type='dashed' u-dash-width='4.0f'>ABC8</span>then"
+ "<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-color='blue' u-type='dashed' u-height='4.0f' u-dash-gap='2.0f' u-dash-width='3.0f'>ABC9</span>end";
+
+ textLabel.SetProperty(TextLabel::Property::TEXT, testText);
+ textLabel.SetProperty(TextLabel ::Property::ENABLE_MARKUP, true);
+
+ application.SendNotification();
+ application.Render();
+
+ const uint32_t expectedNumberOfUnderlineRuns = 8u;
+
+ Toolkit::Internal::TextLabel& textLabelImpl = GetImpl(textLabel);
+ const Text::Length numberOfUnderlineRuns = textLabelImpl.GetTextController()->GetTextModel()->GetNumberOfUnderlineRuns();
+
+ DALI_TEST_EQUALS(numberOfUnderlineRuns, expectedNumberOfUnderlineRuns, TEST_LOCATION);
+
+ Vector<UnderlinedGlyphRun> underlineRuns;
+ underlineRuns.Resize(numberOfUnderlineRuns);
+ textLabelImpl.GetTextController()->GetTextModel()->GetUnderlineRuns(underlineRuns.Begin(), 0u, numberOfUnderlineRuns);
+
+ struct DataOfCase
+ {
+ std::string title;
+ GlyphIndex glyphIndex;
+ Length numberOfGlyphs;
+ UnderlineStyleProperties properties;
+ };
+ DataOfCase data[] =
+ {
+ //<u type='solid'>ABC2</u>
+ {"<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-type='solid'>ABC2</span>",
+ 13u,
+ 4u,
+ {
+ Text::Underline::SOLID,
+ Color::BLACK,
+ 0u,
+ 1u,
+ 2u,
+ true,
+ false,
+ false,
+ false,
+ false,
+ }},
+
+ //<u type='dashed'>ABC3</u>
+ {"<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-type='dashed'>ABC3</span>",
+ 21u,
+ 4u,
+ {
+ Text::Underline::DASHED,
+ Color::BLACK,
+ 0u,
+ 1u,
+ 2u,
+ true,
+ false,
+ false,
+ false,
+ false,
+ }},
+
+ //<u type='double'>ABC4</u>
+ {"<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-type='double'>ABC4</span>",
+ 29u,
+ 4u,
+ {
+ Text::Underline::DOUBLE,
+ Color::BLACK,
+ 0u,
+ 1u,
+ 2u,
+ true,
+ false,
+ false,
+ false,
+ false,
+ }},
+
+ //<u color='green'>ABC5</u>
+ {"<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-color='green'>ABC5</span>",
+ 37u,
+ 4u,
+ {
+ Text::Underline::SOLID,
+ Color::GREEN,
+ 0u,
+ 1u,
+ 2u,
+ false,
+ true,
+ false,
+ false,
+ false,
+ }},
+
+ //<u height='5.0f'>ABC6</u>
+ {"<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-height='5.0f'>ABC6</span>",
+ 45u,
+ 4u,
+ {
+ Text::Underline::SOLID,
+ Color::BLACK,
+ 5u,
+ 1u,
+ 2u,
+ false,
+ false,
+ true,
+ false,
+ false,
+ }},
+
+ //<u type='dashed' dash-gap='3.0f'>ABC7</u>
+ {"<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-type='dashed' u-dash-gap='3.0f'>ABC7</span>",
+ 53u,
+ 4u,
+ {
+ Text::Underline::DASHED,
+ Color::BLACK,
+ 0u,
+ 3u,
+ 2u,
+ true,
+ false,
+ false,
+ true,
+ false,
+ }},
+
+ //<u type='dashed' dash-width='4.0f'>ABC8</u>
+ {"<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-type='dashed' u-dash-width='4.0f'>ABC8</span>",
+ 61u,
+ 4u,
+ {
+ 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'>
+ {"<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' u-color='blue' u-type='dashed' u-height='4.0f' u-dash-gap='2.0f' u-dash-width='3.0f'>ABC9</span>",
+ 69u,
+ 4u,
{
Text::Underline::DASHED,
Color::BLUE,
};
- for(uint32_t i = 0; i < NUMBER_OF_CASES; i++)
+ for(uint32_t i = 0; i < expectedNumberOfUnderlineRuns; 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_EQUALS(underlineRuns[i].glyphRun.glyphIndex, data[i].glyphIndex, TEST_LOCATION);
+ DALI_TEST_EQUALS(underlineRuns[i].glyphRun.numberOfGlyphs, data[i].numberOfGlyphs, TEST_LOCATION);
+ DALI_TEST_CHECK(data[i].properties == underlineRuns[i].properties);
+ }
- DALI_TEST_CHECK(data[i].properties == underlineRuns[data[i].startIndex].properties);
- DALI_TEST_CHECK(data[i].properties == underlineRuns[data[i].endIndex].properties);
+ END_TEST;
+}
+
+int UtcDaliTextLabelMarkupNestedUnderlineTags(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliTextLabelMarkupNestedUnderlineTags ");
+
+ TextLabel textLabel = TextLabel::New();
+
+ application.GetScene().Add(textLabel);
+
+ std::string testText = "start<u height='5.0f' color='green' >AB<u color='blue' >XYZ</u>CDE</u>end";
+
+ textLabel.SetProperty(TextLabel::Property::TEXT, testText);
+ textLabel.SetProperty(TextLabel ::Property::ENABLE_MARKUP, true);
+
+ application.SendNotification();
+ application.Render();
+
+ const uint32_t expectedNumberOfUnderlineRuns = 2u;
+
+ Toolkit::Internal::TextLabel& textLabelImpl = GetImpl(textLabel);
+ const Text::Length numberOfUnderlineRuns = textLabelImpl.GetTextController()->GetTextModel()->GetNumberOfUnderlineRuns();
+
+ DALI_TEST_EQUALS(numberOfUnderlineRuns, expectedNumberOfUnderlineRuns, TEST_LOCATION);
+
+ Vector<UnderlinedGlyphRun> underlineRuns;
+ underlineRuns.Resize(numberOfUnderlineRuns);
+ textLabelImpl.GetTextController()->GetTextModel()->GetUnderlineRuns(underlineRuns.Begin(), 0u, numberOfUnderlineRuns);
+
+ struct DataOfCase
+ {
+ std::string title;
+ GlyphIndex glyphIndex;
+ Length numberOfGlyphs;
+ UnderlineStyleProperties properties;
+ };
+ DataOfCase data[] =
+ {
+ //Outter
+ {"<u height='5.0f' color='green' >AB<u color='blue' >XYZ</u>CDE</u>",
+ 5u,
+ 8u,
+ {
+ Text::Underline::SOLID,
+ Color::GREEN,
+ 5u,
+ 1u,
+ 2u,
+ false,
+ true,
+ true,
+ false,
+ false,
+ }},
+
+ //Inner
+ {"<u color='blue' >XYZ</u>",
+ 7u,
+ 3u,
+ {
+ Text::Underline::SOLID,
+ Color::BLUE,
+ 5u,
+ 1u,
+ 2u,
+ false,
+ true,
+ true,
+ false,
+ false,
+ }},
+
+ };
+
+ for(uint32_t i = 0; i < expectedNumberOfUnderlineRuns; i++)
+ {
+ tet_infoline(data[i].title.c_str());
+ DALI_TEST_EQUALS(underlineRuns[i].glyphRun.glyphIndex, data[i].glyphIndex, TEST_LOCATION);
+ DALI_TEST_EQUALS(underlineRuns[i].glyphRun.numberOfGlyphs, data[i].numberOfGlyphs, TEST_LOCATION);
+ DALI_TEST_CHECK(data[i].properties == underlineRuns[i].properties);
}
END_TEST;
END_TEST;
}
+int UtcDaliTextEditorSelectionWithLineSpacing(void)
+{
+ //Only for test coverage
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliTextEditorSelectionWithLineSpacing ");
+
+ TextEditor textEditor = TextEditor::New();
+ textEditor.SetProperty(Actor::Property::SIZE, Vector2(400.0f, 400.f));
+ application.GetScene().Add(textEditor);
+ application.SendNotification();
+ application.Render();
+
+ textEditor.SetProperty(TextEditor::Property::TEXT, "Line #1\nLine #2\nLine #3");
+ textEditor.SetProperty(DevelTextEditor::Property::LINE_SPACING, -20);
+
+ application.SendNotification();
+ application.Render();
+
+ DevelTextEditor::SelectWholeText(textEditor);
+
+ application.SendNotification();
+ application.Render();
+
+ DevelTextEditor::SelectNone(textEditor);
+ textEditor.SetProperty(DevelTextEditor::Property::LINE_SPACING, 20);
+
+ application.SendNotification();
+ application.Render();
+
+ DevelTextEditor::SelectWholeText(textEditor);
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS(textEditor.GetProperty<float>(DevelTextEditor::Property::LINE_SPACING), 20.0f, TEST_LOCATION);
+
+ END_TEST;
+}
+
int UtcDaliTextEditorMinLineSize(void)
{
ToolkitTestApplication application;
END_TEST;
}
+int UtcDaliToolkitTextEditorRelativeLineHeight(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliToolkitTextEditorRelativeLineHeight");
+
+ TextEditor editor = TextEditor::New();
+ editor.SetProperty(Actor::Property::SIZE, Vector2(200.0f, 300.f));
+ editor.SetProperty(TextEditor::Property::POINT_SIZE, 10);
+ editor.SetProperty(TextEditor::Property::TEXT, "Hello\nWorld");
+
+ application.GetScene().Add(editor);
+ application.SendNotification();
+ application.Render();
+
+ Vector3 naturalSize = editor.GetNaturalSize();
+
+ editor.SetProperty(DevelTextEditor::Property::RELATIVE_LINE_SIZE, 0.5f);
+
+ application.SendNotification();
+ application.Render();
+
+ Vector3 relativeNaturalSize = editor.GetNaturalSize();
+
+ DALI_TEST_EQUALS(naturalSize.y, relativeNaturalSize.y, TEST_LOCATION);
+
+ editor.SetProperty(DevelTextEditor::Property::RELATIVE_LINE_SIZE, 2.0f);
+
+ application.SendNotification();
+ application.Render();
+
+ relativeNaturalSize = editor.GetNaturalSize();
+
+ DALI_TEST_EQUALS(naturalSize.y * 2, relativeNaturalSize.y, TEST_LOCATION);
+ END_TEST;
+}
+
int UtcDaliTextEditorCharacterSpacing(void)
{
ToolkitTestApplication application;
END_TEST;
}
+int UtcDaliTextEditorTextSizeNegativeLineSpacing(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("UtcDaliTextEditorTextSizeNegativeLineSpacing");
+
+ TextEditor editor = TextEditor::New();
+
+ float lineSpacing = -20.f;
+
+ editor.SetProperty(Actor::Property::SIZE, Vector2(450.0f, 300.f));
+ editor.SetProperty(TextEditor::Property::POINT_SIZE, 10.f);
+ editor.SetProperty(DevelTextEditor::Property::LINE_SPACING, lineSpacing);
+ editor.SetProperty(TextEditor::Property::TEXT, "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.");
+
+ application.GetScene().Add(editor);
+ application.SendNotification();
+ application.Render();
+
+ Vector<Vector2> positionsList = DevelTextEditor::GetTextPosition(editor, 0, 123);
+ Vector<Vector2> sizeList = DevelTextEditor::GetTextSize(editor, 0, 123);
+
+ Vector2 lastLinePos = positionsList[positionsList.Size() - 1];
+ Vector2 lastLineSize = sizeList[sizeList.Size() - 1];
+
+ DALI_TEST_EQUALS(sizeList[0].y * (sizeList.Size() - 1), lastLinePos.y, Math::MACHINE_EPSILON_1000, TEST_LOCATION);
+ DALI_TEST_EQUALS(sizeList[0].y - lineSpacing, lastLineSize.y, Math::MACHINE_EPSILON_1000, TEST_LOCATION);
+
+ application.SendNotification();
+ application.Render();
+
+ END_TEST;
+}
+
int UtcDaliToolkitTexteditorParagraphTag(void)
{
ToolkitTestApplication application;
END_TEST;
}
+int UtcDaliToolkitTextLabelRelativeLineHeight(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliToolkitTextLabelRelativeLineHeight");
+
+ TextLabel label = TextLabel::New();
+ label.SetProperty(Actor::Property::SIZE, Vector2(200.0f, 300.f));
+ label.SetProperty(TextLabel::Property::POINT_SIZE, 10);
+ label.SetProperty(TextLabel::Property::TEXT, "Hello\nWorld");
+
+ application.GetScene().Add(label);
+ application.SendNotification();
+ application.Render();
+
+ Vector3 naturalSize = label.GetNaturalSize();
+
+ label.SetProperty(DevelTextLabel::Property::RELATIVE_LINE_SIZE, 0.5f);
+
+ application.SendNotification();
+ application.Render();
+
+ Vector3 relativeNaturalSize = label.GetNaturalSize();
+
+ DALI_TEST_EQUALS(naturalSize.y, relativeNaturalSize.y, TEST_LOCATION);
+
+ label.SetProperty(DevelTextLabel::Property::RELATIVE_LINE_SIZE, 2.0f);
+
+ application.SendNotification();
+ application.Render();
+
+ relativeNaturalSize = label.GetNaturalSize();
+
+ DALI_TEST_EQUALS(naturalSize.y * 2, relativeNaturalSize.y, TEST_LOCATION);
+ END_TEST;
+}
+
int UtcDaliTextLabelCharacterSpacing(void)
{
ToolkitTestApplication application;
END_TEST;
}
+int UtcDaliTextTextLabelSizeNegativeLineSpacing(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("UtcDaliTextTextLabelSizeNegativeLineSpacing");
+
+ TextLabel label = TextLabel::New();
+
+ float lineSpacing = -20.f;
+
+ label.SetProperty(Actor::Property::SIZE, Vector2(450.0f, 300.f));
+ label.SetProperty(TextLabel::Property::POINT_SIZE, 10.f);
+ label.SetProperty(DevelTextLabel::Property::LINE_SPACING, lineSpacing);
+ label.SetProperty(TextLabel::Property::MULTI_LINE, true);
+ label.SetProperty(TextLabel::Property::TEXT, "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.");
+
+ application.GetScene().Add(label);
+ application.SendNotification();
+ application.Render();
+
+ Vector<Vector2> positionsList = DevelTextLabel::GetTextPosition(label, 0, 123);
+ Vector<Vector2> sizeList = DevelTextLabel::GetTextSize(label, 0, 123);
+
+ Vector2 lastLinePos = positionsList[positionsList.Size() - 1];
+ Vector2 lastLineSize = sizeList[sizeList.Size() - 1];
+
+ DALI_TEST_EQUALS(sizeList[0].y * (sizeList.Size() - 1), lastLinePos.y, Math::MACHINE_EPSILON_1000, TEST_LOCATION);
+ DALI_TEST_EQUALS(sizeList[0].y - lineSpacing, lastLineSize.y, Math::MACHINE_EPSILON_1000, TEST_LOCATION);
+
+ application.SendNotification();
+ application.Render();
+
+ END_TEST;
+}
+
int UtcDaliToolkitTextlabelParagraphTag(void)
{
ToolkitTestApplication application;
DALI_TEST_CHECK( !(callStack.FindMethod("CreateShader")) );
END_TEST;
-}
\ No newline at end of file
+}
+
+int UtcDaliVisualUpdatePropertyChangeShader04(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline( "UtcDaliVisualUpdatePropertyChangeShader04: Test update property by DoAction during Animation. Change the shader case" );
+
+ TraceCallStack& callStack = application.GetGraphicsController().mCallStack;
+
+ VisualFactory factory = VisualFactory::Get();
+ Property::Map propertyMap;
+ // Case ImageVisual
+ propertyMap[Visual::Property::TYPE] = Visual::Type::IMAGE;
+ propertyMap[ImageVisual::Property::URL] = TEST_IMAGE_FILE_NAME;
+ propertyMap[DevelVisual::Property::CORNER_RADIUS] = 10.0f;
+
+ Visual::Base imageVisual = factory.CreateVisual(propertyMap);
+
+ DummyControl dummyControl = DummyControl::New(true);
+ Impl::DummyControl& dummyImpl = static_cast<Impl::DummyControl&>(dummyControl.GetImplementation());
+ dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, imageVisual);
+ dummyControl[Actor::Property::SIZE] = Vector2(200.f, 200.f);
+ application.GetScene().Add(dummyControl);
+
+ application.SendNotification();
+ application.Render();
+
+ // Wait for image loading
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+
+ application.SendNotification();
+ application.Render();
+
+ // Get shader
+ {
+ Renderer renderer = dummyControl.GetRendererAt( 0 );
+ Shader shader = renderer.GetShader();
+ Property::Value value = shader.GetProperty( Shader::Property::PROGRAM );
+ Property::Map* map = value.GetMap();
+ DALI_TEST_CHECK( map );
+
+ Property::Value* fragment = map->Find( "fragment" ); // fragment key name from shader-impl.cpp
+ DALI_TEST_CHECK( fragment );
+ std::string fragmentShader;
+ DALI_TEST_CHECK( fragment->Get(fragmentShader) );
+ DALI_TEST_CHECK( fragmentShader.find("#define IS_REQUIRED_BORDERLINE 1") == std::string::npos );
+ DALI_TEST_CHECK( fragmentShader.find("#define IS_REQUIRED_ROUNDED_CORNER 1") != std::string::npos );
+
+ Property::Value* vertex = map->Find( "vertex" ); // vertex key name from shader-impl.cpp
+ std::string vertexShader;
+ DALI_TEST_CHECK( vertex->Get(vertexShader) );
+ DALI_TEST_CHECK( vertexShader.find("#define IS_REQUIRED_BORDERLINE 1") == std::string::npos );
+ DALI_TEST_CHECK( vertexShader.find("#define IS_REQUIRED_ROUNDED_CORNER 1") != std::string::npos );
+ }
+ callStack.Reset();
+ callStack.Enable(true);
+
+ Vector4 targetCornerRadius = Vector4(0.0f, 0.0f, 0.0f, 0.0f);
+
+ Animation animation = Animation::New(1.0f);
+ animation.AnimateTo(DevelControl::GetVisualProperty(dummyControl, DummyControl::Property::TEST_VISUAL, DevelVisual::Property::CORNER_RADIUS), targetCornerRadius);
+ animation.Play();
+
+ application.SendNotification();
+ application.Render();
+ application.Render(1001u); // End of animation
+
+ // Get shader
+ {
+ Renderer renderer = dummyControl.GetRendererAt( 0 );
+ Shader shader = renderer.GetShader();
+ Property::Value value = shader.GetProperty( Shader::Property::PROGRAM );
+ Property::Map* map = value.GetMap();
+ DALI_TEST_CHECK( map );
+
+ Property::Value* fragment = map->Find( "fragment" ); // fragment key name from shader-impl.cpp
+ DALI_TEST_CHECK( fragment );
+ std::string fragmentShader;
+ DALI_TEST_CHECK( fragment->Get(fragmentShader) );
+ DALI_TEST_CHECK( fragmentShader.find("#define IS_REQUIRED_BORDERLINE 1") == std::string::npos );
+ // Note : mAlwaysUsingCornerRadius is true.
+ DALI_TEST_CHECK( fragmentShader.find("#define IS_REQUIRED_ROUNDED_CORNER 1") != std::string::npos );
+
+ Property::Value* vertex = map->Find( "vertex" ); // vertex key name from shader-impl.cpp
+ std::string vertexShader;
+ DALI_TEST_CHECK( vertex->Get(vertexShader) );
+ DALI_TEST_CHECK( vertexShader.find("#define IS_REQUIRED_BORDERLINE 1") == std::string::npos );
+ // Note : mAlwaysUsingCornerRadius is true.
+ DALI_TEST_CHECK( vertexShader.find("#define IS_REQUIRED_ROUNDED_CORNER 1") != std::string::npos );
+ }
+ callStack.Enable(false);
+ // Shader not changed
+ DALI_TEST_CHECK( !callStack.FindMethod("CreateShader") );
+ callStack.Reset();
+ callStack.Enable(true);
+
+ float targetBorderlineWidth = 10.0f;
+ Property::Map targetPropertyMap;
+ targetPropertyMap[DevelVisual::Property::BORDERLINE_WIDTH] = targetBorderlineWidth;
+
+ // Update Properties with CornerRadius
+ DevelControl::DoAction(dummyControl, DummyControl::Property::TEST_VISUAL, DevelVisual::Action::UPDATE_PROPERTY, targetPropertyMap);
+
+ Property::Map resultMap;
+ imageVisual.CreatePropertyMap( resultMap );
+
+ // Test property values: they should be updated
+ Property::Value* cornerRadiusValue = resultMap.Find(DevelVisual::Property::CORNER_RADIUS, Property::VECTOR4);
+ DALI_TEST_CHECK(cornerRadiusValue);
+ DALI_TEST_EQUALS(cornerRadiusValue->Get<Vector4>(), targetCornerRadius, TEST_LOCATION);
+
+ Property::Value* cornerRadiusPolicyValue = resultMap.Find(DevelVisual::Property::CORNER_RADIUS_POLICY, Property::INTEGER);
+ DALI_TEST_CHECK(cornerRadiusPolicyValue);
+ DALI_TEST_EQUALS(cornerRadiusPolicyValue->Get<int>(), static_cast<int>(Toolkit::Visual::Transform::Policy::ABSOLUTE), TEST_LOCATION);
+
+ Property::Value* borderlineWidthValue = resultMap.Find(DevelVisual::Property::BORDERLINE_WIDTH, Property::FLOAT);
+ DALI_TEST_CHECK(borderlineWidthValue);
+ DALI_TEST_EQUALS(borderlineWidthValue->Get<float>(), targetBorderlineWidth, TEST_LOCATION);
+
+ // Get shader
+ {
+ Renderer renderer = dummyControl.GetRendererAt( 0 );
+ Shader shader = renderer.GetShader();
+ Property::Value value = shader.GetProperty( Shader::Property::PROGRAM );
+ Property::Map* map = value.GetMap();
+ DALI_TEST_CHECK( map );
+
+ Property::Value* fragment = map->Find( "fragment" ); // fragment key name from shader-impl.cpp
+ DALI_TEST_CHECK( fragment );
+ std::string fragmentShader;
+ DALI_TEST_CHECK( fragment->Get(fragmentShader) );
+ DALI_TEST_CHECK( fragmentShader.find("#define IS_REQUIRED_BORDERLINE 1") != std::string::npos );
+ // Note : mAlwaysUsingCornerRadius is true.
+ DALI_TEST_CHECK( fragmentShader.find("#define IS_REQUIRED_ROUNDED_CORNER 1") != std::string::npos );
+
+ Property::Value* vertex = map->Find( "vertex" ); // vertex key name from shader-impl.cpp
+ std::string vertexShader;
+ DALI_TEST_CHECK( vertex->Get(vertexShader) );
+ DALI_TEST_CHECK( vertexShader.find("#define IS_REQUIRED_BORDERLINE 1") != std::string::npos );
+ // Note : mAlwaysUsingCornerRadius is true.
+ DALI_TEST_CHECK( vertexShader.find("#define IS_REQUIRED_ROUNDED_CORNER 1") != std::string::npos );
+ }
+
+ // Send shader compile signal
+ application.SendNotification();
+ application.Render();
+
+ callStack.Enable(false);
+ // Shader changed
+ DALI_TEST_CHECK( callStack.FindMethod("CreateShader") );
+
+ END_TEST;
+}
return;
}
- if(index == DevelControl::Property::ACCESSIBILITY_NAME || (index == GetNamePropertyIndex() && !controlImpl.mAccessibilityNameSet))
+ if(index == DevelControl::Property::ACCESSIBILITY_NAME || (index == GetNamePropertyIndex() && controlImpl.mAccessibilityName.empty()))
{
if(controlImpl.mAccessibilityGetNameSignal.Empty())
{
}
}
- if(index == DevelControl::Property::ACCESSIBILITY_DESCRIPTION || (index == GetDescriptionPropertyIndex() && !controlImpl.mAccessibilityDescriptionSet))
+ if(index == DevelControl::Property::ACCESSIBILITY_DESCRIPTION || (index == GetDescriptionPropertyIndex() && controlImpl.mAccessibilityDescription.empty()))
{
if(controlImpl.mAccessibilityGetDescriptionSignal.Empty())
{
{
controlImpl.mAccessibilityGetNameSignal.Emit(name);
}
- else if(controlImpl.mAccessibilityNameSet)
+ else if(!controlImpl.mAccessibilityName.empty())
{
name = controlImpl.mAccessibilityName;
}
name = Self().GetProperty<std::string>(Actor::Property::NAME);
}
- if(controlImpl.mAccessibilityTranslationDomainSet)
+ if(!controlImpl.mAccessibilityTranslationDomain.empty())
{
return GetLocaleText(name, controlImpl.mAccessibilityTranslationDomain.c_str());
}
{
controlImpl.mAccessibilityGetDescriptionSignal.Emit(description);
}
- else if(controlImpl.mAccessibilityDescriptionSet)
+ else if(!controlImpl.mAccessibilityDescription.empty())
{
description = controlImpl.mAccessibilityDescription;
}
{
description = GetDescriptionRaw();
}
- if(controlImpl.mAccessibilityTranslationDomainSet)
+
+ if(!controlImpl.mAccessibilityTranslationDomain.empty())
{
return GetLocaleText(description, controlImpl.mAccessibilityTranslationDomain.c_str());
}
* The default value is 0.f which does nothing.
*/
CHARACTER_SPACING,
+
+ /**
+ * @brief the relative height of the line (a factor that will be multiplied by text height).
+ * @details Name "relativeLineSize", type Property::FLOAT.
+ * @note If the value is less than 1, the lines could to be overlapped.
+ */
+ RELATIVE_LINE_SIZE,
};
} // namespace Property
* The default value is 0.f which does nothing.
*/
CHARACTER_SPACING,
+
+ /**
+ * @brief the relative height of the line (a factor that will be multiplied by text height).
+ * @details Name "relativeLineSize", type Property::FLOAT.
+ * @note If the value is less than 1, the lines could to be overlapped.
+ */
+ RELATIVE_LINE_SIZE,
};
} // namespace Property
#include <dali-toolkit/internal/text/bidirectional-support.h>
#include <dali-toolkit/internal/text/character-set-conversion.h>
#include <dali-toolkit/internal/text/color-segmentation.h>
+#include <dali-toolkit/internal/text/glyph-metrics-helper.h>
#include <dali-toolkit/internal/text/layouts/layout-engine.h>
#include <dali-toolkit/internal/text/layouts/layout-parameters.h>
#include <dali-toolkit/internal/text/markup-processor.h>
#include <dali-toolkit/internal/text/text-enumerations-impl.h>
#include <dali-toolkit/internal/text/text-font-style.h>
#include <dali-toolkit/internal/text/text-model.h>
-#include <dali-toolkit/internal/text/glyph-metrics-helper.h>
namespace Dali
{
{
Length finalNumberOfGlyphs = 0u;
- if((GetLineHeight(line)) > textLayoutArea.height)
+ if((GetLineHeight(line, (lines.Size() == 1))) > textLayoutArea.height)
{
// The height of the line is bigger than the height of the text area.
// Show the ellipsis glyph even if it doesn't fit in the text area.
float penY = 0.f;
float lineSize = internalData.layoutEngine.GetDefaultLineSize();
float lineOffset = 0.f;
+ bool isLastLine;
for(unsigned int index = 0u; index < numberOfLines; ++index)
{
const LineRun& line = *(lines.Begin() + index);
numberOfCharacters += line.characterRun.numberOfCharacters;
+ isLastLine = (index == numberOfLines - 1);
- lineOffset = lineSize > 0.f ? lineSize : GetLineHeight(line);
+ lineOffset = lineSize > 0.f ? lineSize : GetLineHeight(line, isLastLine);
penY += lineOffset;
if((penY + lineOffset) > boundingBox)
{
std::string name;
if(value.Get(name))
{
- controlImpl.mImpl->mAccessibilityName = name;
- controlImpl.mImpl->mAccessibilityNameSet = true;
- }
- else
- {
- controlImpl.mImpl->mAccessibilityNameSet = false;
+ controlImpl.mImpl->mAccessibilityName = name;
}
+ break;
}
- break;
case Toolkit::DevelControl::Property::ACCESSIBILITY_DESCRIPTION:
{
std::string text;
if(value.Get(text))
{
- controlImpl.mImpl->mAccessibilityDescription = text;
- controlImpl.mImpl->mAccessibilityDescriptionSet = true;
- }
- else
- {
- controlImpl.mImpl->mAccessibilityDescriptionSet = false;
+ controlImpl.mImpl->mAccessibilityDescription = text;
}
+ break;
}
- break;
case Toolkit::DevelControl::Property::ACCESSIBILITY_TRANSLATION_DOMAIN:
{
std::string text;
if(value.Get(text))
{
- controlImpl.mImpl->mAccessibilityTranslationDomain = text;
- controlImpl.mImpl->mAccessibilityTranslationDomainSet = true;
- }
- else
- {
- controlImpl.mImpl->mAccessibilityTranslationDomainSet = false;
+ controlImpl.mImpl->mAccessibilityTranslationDomain = text;
}
+ break;
}
- break;
case Toolkit::DevelControl::Property::ACCESSIBILITY_ROLE:
{
{
controlImpl.mImpl->mAccessibilityRole = role;
}
+ break;
}
- break;
case Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE:
{
bool highlightable;
if(value.Get(highlightable))
{
- controlImpl.mImpl->mAccessibilityHighlightable = highlightable;
- controlImpl.mImpl->mAccessibilityHighlightableSet = true;
- }
- else
- {
- controlImpl.mImpl->mAccessibilityHighlightableSet = false;
+ controlImpl.mImpl->mAccessibilityHighlightable = highlightable;
}
+ break;
}
- break;
case Toolkit::DevelControl::Property::ACCESSIBILITY_ATTRIBUTES:
{
case Toolkit::DevelControl::Property::ACCESSIBILITY_NAME:
{
- if(controlImpl.mImpl->mAccessibilityNameSet)
- {
- value = controlImpl.mImpl->mAccessibilityName;
- }
+ value = controlImpl.mImpl->mAccessibilityName;
break;
}
case Toolkit::DevelControl::Property::ACCESSIBILITY_DESCRIPTION:
{
- if(controlImpl.mImpl->mAccessibilityDescriptionSet)
- {
- value = controlImpl.mImpl->mAccessibilityDescription;
- }
+ value = controlImpl.mImpl->mAccessibilityDescription;
break;
}
case Toolkit::DevelControl::Property::ACCESSIBILITY_TRANSLATION_DOMAIN:
{
- if(controlImpl.mImpl->mAccessibilityTranslationDomainSet)
- {
- value = controlImpl.mImpl->mAccessibilityTranslationDomain;
- }
+ value = controlImpl.mImpl->mAccessibilityTranslationDomain;
break;
}
case Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE:
{
- if(controlImpl.mImpl->mAccessibilityHighlightableSet)
- {
- value = controlImpl.mImpl->mAccessibilityHighlightable;
- }
+ value = controlImpl.mImpl->mAccessibilityHighlightable;
break;
}
std::string mAccessibilityName;
std::string mAccessibilityDescription;
std::string mAccessibilityTranslationDomain;
- bool mAccessibilityNameSet = false;
- bool mAccessibilityDescriptionSet = false;
- bool mAccessibilityTranslationDomainSet = false;
- bool mAccessibilityHighlightable = false;
- bool mAccessibilityHighlightableSet = false;
-
- bool mAccessibilityHidden = false;
+ bool mAccessibilityHighlightable = false;
+ bool mAccessibilityHidden = false;
Dali::Accessibility::Role mAccessibilityRole = Dali::Accessibility::Role::UNKNOWN;
DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextEditor, "strikethrough", MAP, STRIKETHROUGH )
DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextEditor, "inputStrikethrough", MAP, INPUT_STRIKETHROUGH )
DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextEditor, "characterSpacing", FLOAT, CHARACTER_SPACING )
+DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextEditor, "relativeLineSize", FLOAT, RELATIVE_LINE_SIZE )
DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "textChanged", SIGNAL_TEXT_CHANGED )
DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "inputStyleChanged", SIGNAL_INPUT_STYLE_CHANGED )
impl.mRenderer.Reset();
break;
}
+ case Toolkit::DevelTextEditor::Property::RELATIVE_LINE_SIZE:
+ {
+ const float relativeLineSize = value.Get<float>();
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::Verbose, "TextEditor %p RELATIVE_LINE_SIZE %f\n", impl.mController.Get(), relativeLineSize);
+
+ impl.mController->SetRelativeLineSize(relativeLineSize);
+ impl.mRenderer.Reset();
+ break;
+ }
}
}
value = impl.mController->GetCharacterSpacing();
break;
}
+ case Toolkit::DevelTextEditor::Property::RELATIVE_LINE_SIZE:
+ {
+ value = impl.mController->GetRelativeLineSize();
+ break;
+ }
} //switch
return value;
}
DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextLabel, "ellipsisPosition", INTEGER, ELLIPSIS_POSITION )
DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextLabel, "strikethrough", MAP, STRIKETHROUGH )
DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextLabel, "characterSpacing", FLOAT, CHARACTER_SPACING )
+DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextLabel, "relativeLineSize", FLOAT, RELATIVE_LINE_SIZE )
DALI_ANIMATABLE_PROPERTY_REGISTRATION_WITH_DEFAULT(Toolkit, TextLabel, "textColor", Color::BLACK, TEXT_COLOR )
DALI_ANIMATABLE_PROPERTY_COMPONENT_REGISTRATION(Toolkit, TextLabel, "textColorRed", TEXT_COLOR_RED, TEXT_COLOR, 0)
impl.mController->SetCharacterSpacing(characterSpacing);
break;
}
+ case Toolkit::DevelTextLabel::Property::RELATIVE_LINE_SIZE:
+ {
+ const float relativeLineSize = value.Get<float>();
+ DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextLabel %p RELATIVE_LINE_SIZE %f\n", impl.mController.Get(), relativeLineSize);
+
+ impl.mController->SetRelativeLineSize(relativeLineSize);
+ break;
+ }
}
// Request relayout when text update is needed. It's necessary to call it
value = impl.mController->GetCharacterSpacing();
break;
}
+ case Toolkit::DevelTextLabel::Property::RELATIVE_LINE_SIZE:
+ {
+ value = impl.mController->GetRelativeLineSize();
+ break;
+ }
}
}
{
if(keyName == "Left")
{
- if(!mIsFocusIndicatorShown)
+ if(mIsFocusIndicatorShown == HIDE)
{
- if(mIsFocusIndicatorShown == HIDE)
- {
- // Show focus indicator
- mIsFocusIndicatorShown = SHOW;
- }
- else
- {
- // Move the focus towards left
- MoveFocus(Toolkit::Control::KeyboardFocus::LEFT);
- }
-
- isFocusStartableKey = true;
+ // Show focus indicator
+ mIsFocusIndicatorShown = SHOW;
}
else
{
}
else if(keyName == "Right")
{
- if(!mIsFocusIndicatorShown)
+ if(mIsFocusIndicatorShown == HIDE)
{
- if(mIsFocusIndicatorShown == HIDE)
- {
- // Show focus indicator
- mIsFocusIndicatorShown = SHOW;
- }
- else
- {
- // Move the focus towards right
- MoveFocus(Toolkit::Control::KeyboardFocus::RIGHT);
- }
+ // Show focus indicator
+ mIsFocusIndicatorShown = SHOW;
}
else
{
it != endIt;
++it, ++lineIndex)
{
- const LineRun& lineRun = *it;
+ const LineRun& lineRun = *it;
+ bool isLastLine = (it + 1 == endIt);
- totalHeight += GetLineHeight(lineRun);
+ totalHeight += GetLineHeight(lineRun, isLastLine);
if(visualY < totalHeight)
{
it != endIt;
++it)
{
- const LineRun& lineRun = *it;
+ const LineRun& lineRun = *it;
+ bool isLastLine = (it + 1 == lines.End());
- offset += GetLineHeight(lineRun);
+ offset += GetLineHeight(lineRun, isLastLine);
}
return offset;
cursorInfo.lineOffset = CalculateLineOffset(parameters.visualModel->mLines,
newLineIndex);
- cursorInfo.lineHeight = GetLineHeight(newLine);
+ // The line height is the addition of the line ascender and the line descender.
+ // However, the line descender has a negative value, hence the subtraction also line spacing should not be included in cursor height.
+ cursorInfo.lineHeight = newLine.ascender - newLine.descender;
index = 0u;
const Length totalNumberOfCharacters = parameters.logicalModel->mText.Count();
cursorInfo.lineOffset = CalculateLineOffset(parameters.visualModel->mLines,
lineIndex);
- cursorInfo.lineHeight = GetLineHeight(line);
+ // The line height is the addition of the line ascender and the line descender.
+ // However, the line descender has a negative value, hence the subtraction also line spacing should not be included in cursor height.
+ cursorInfo.lineHeight = line.ascender - line.descender;
// Calculate the primary cursor.
{
namespace Text
{
-float GetLineHeight(const LineRun lineRun)
+float GetLineHeight(const LineRun lineRun, bool isLastLine)
{
// The line height is the addition of the line ascender, the line descender and the line spacing.
// However, the line descender has a negative value, hence the subtraction.
- return lineRun.ascender - lineRun.descender + lineRun.lineSpacing;
+ // In case this is the only/last line then line spacing should be ignored.
+ float lineHeight = lineRun.ascender - lineRun.descender;
+
+ if(!isLastLine || lineRun.lineSpacing > 0)
+ {
+ lineHeight += lineRun.lineSpacing;
+ }
+ return lineHeight;
}
namespace Layout
Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_LAYOUT");
#endif
-const float MAX_FLOAT = std::numeric_limits<float>::max();
-const CharacterDirection LTR = false;
-const CharacterDirection RTL = !LTR;
-const float LINE_SPACING = 0.f;
-const float MIN_LINE_SIZE = 0.f;
-const Character HYPHEN_UNICODE = 0x002D;
+const float MAX_FLOAT = std::numeric_limits<float>::max();
+const CharacterDirection LTR = false;
+const CharacterDirection RTL = !LTR;
+const float LINE_SPACING = 0.f;
+const float MIN_LINE_SIZE = 0.f;
+const Character HYPHEN_UNICODE = 0x002D;
+const float RELATIVE_LINE_SIZE = 1.f;
inline bool isEmptyLineAtLast(const Vector<LineRun>& lines, const Vector<LineRun>::Iterator& line)
{
: mLayout{Layout::Engine::SINGLE_LINE_BOX},
mCursorWidth{0.f},
mDefaultLineSpacing{LINE_SPACING},
- mDefaultLineSize{MIN_LINE_SIZE}
+ mDefaultLineSize{MIN_LINE_SIZE},
+ mRelativeLineSize{RELATIVE_LINE_SIZE}
+ {
+ }
+
+ /**
+ * @brief get the line spacing.
+ *
+ * @param[in] textSize The text size.
+ * @return the line spacing value.
+ */
+ float GetLineSpacing(float textSize)
{
+ float lineSpacing;
+ float relTextSize;
+
+ // Sets the line size
+ lineSpacing = mDefaultLineSize - textSize;
+ lineSpacing = lineSpacing < 0.f ? 0.f : lineSpacing;
+
+ // Add the line spacing
+ lineSpacing += mDefaultLineSpacing;
+
+ //subtract line spcaing if relativeLineSize < 1 & larger than min height
+ relTextSize = textSize * mRelativeLineSize;
+ if(relTextSize > mDefaultLineSize)
+ {
+ if(mRelativeLineSize < 1)
+ {
+ //subtract the difference (always will be positive)
+ lineSpacing -= (textSize - relTextSize);
+ }
+ else
+ {
+ //reverse the addition in the top.
+ if(mDefaultLineSize > textSize)
+ {
+ lineSpacing -= mDefaultLineSize - textSize;
+ }
+
+ //add difference instead
+ lineSpacing += relTextSize - textSize;
+ }
+ }
+
+ return lineSpacing;
}
/**
// Sets the minimum descender.
lineLayout.descender = std::min(lineLayout.descender, fontMetrics.descender);
- // Sets the line size
- lineLayout.lineSpacing = mDefaultLineSize - (lineLayout.ascender + -lineLayout.descender);
- lineLayout.lineSpacing = lineLayout.lineSpacing < 0.f ? 0.f : lineLayout.lineSpacing;
-
- // Add the line spacing
- lineLayout.lineSpacing += mDefaultLineSpacing;
+ lineLayout.lineSpacing = GetLineSpacing(lineLayout.ascender + -lineLayout.descender);
}
/**
layoutSize.width = layoutParameters.boundingBox.width;
if(layoutSize.height < Math::MACHINE_EPSILON_1000)
{
- layoutSize.height += GetLineHeight(*lineRun);
+ layoutSize.height += GetLineHeight(*lineRun, true);
}
const Vector<BidirectionalLineInfoRun>& bidirectionalLinesInfo = layoutParameters.textModel->mLogicalModel->mBidirectionalLineInfo;
lineRun.direction = layout.direction;
lineRun.ellipsis = false;
- lineRun.lineSpacing = mDefaultLineSize - (lineRun.ascender + -lineRun.descender);
- lineRun.lineSpacing = lineRun.lineSpacing < 0.f ? 0.f : lineRun.lineSpacing;
-
- lineRun.lineSpacing += mDefaultLineSpacing;
+ lineRun.lineSpacing = GetLineSpacing(lineRun.ascender + -lineRun.descender);
// Update the actual size.
if(lineRun.width > layoutSize.width)
layoutSize.width = lineRun.width;
}
- layoutSize.height += GetLineHeight(lineRun);
+ layoutSize.height += GetLineHeight(lineRun, isLastLine);
}
/**
lineRun.direction = LTR;
lineRun.ellipsis = false;
- lineRun.lineSpacing = mDefaultLineSize - (lineRun.ascender + -lineRun.descender);
- lineRun.lineSpacing = lineRun.lineSpacing < 0.f ? 0.f : lineRun.lineSpacing;
+ lineRun.lineSpacing = GetLineSpacing(lineRun.ascender + -lineRun.descender);
- lineRun.lineSpacing += mDefaultLineSpacing;
-
- layoutSize.height += GetLineHeight(lineRun);
+ layoutSize.height += GetLineHeight(lineRun, true);
}
/**
it != endIt;
++it)
{
- const LineRun& line = *it;
+ const LineRun& line = *it;
+ bool isLastLine = (it + 1 == endIt);
if(line.width > layoutSize.width)
{
layoutSize.width = line.width;
}
- layoutSize.height += GetLineHeight(line);
+ layoutSize.height += GetLineHeight(line, isLastLine);
}
}
}
// Updates the vertical pen's position.
- penY += -layout.descender + layout.lineSpacing + mDefaultLineSpacing;
- // If there is a defaultLineSize, updates the pen's position.
- if(mDefaultLineSize > 0.f)
- {
- float lineSpacing = mDefaultLineSize - (layout.ascender + -layout.descender);
- lineSpacing = lineSpacing < 0.f ? 0.f : lineSpacing;
- penY += lineSpacing;
- }
+ penY += -layout.descender + layout.lineSpacing + GetLineSpacing(layout.ascender + -layout.descender);
// Increase the glyph index.
index = nextIndex;
float mDefaultLineSize;
IntrusivePtr<Metrics> mMetrics;
+ float mRelativeLineSize;
};
Engine::Engine()
return mImpl->mDefaultLineSize;
}
+void Engine::SetRelativeLineSize(float relativeLineSize)
+{
+ mImpl->mRelativeLineSize = relativeLineSize;
+}
+
+float Engine::GetRelativeLineSize() const
+{
+ return mImpl->mRelativeLineSize;
+}
+
} // namespace Layout
} // namespace Text
#define DALI_TOOLKIT_TEXT_LAYOUT_ENGINE_H
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
float GetDefaultLineSize() const;
+ /**
+ * @brief Sets relative line size to the original line size.
+ *
+ * @param[in] relativeLineSize The relative line size.
+ */
+ void SetRelativeLineSize(float relativeLineSize);
+
+ /**
+ * @brief Retrieves the relative line size.
+ *
+ * @return The relative line size.
+ */
+ float GetRelativeLineSize() const;
+
private:
// Undefined
Engine(const Engine& handle);
#define DALI_TOOLKIT_TEXT_LINE_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.
* @brief Get the line height for the specified line run.
*
* @param[in] lineRun The line runs to get the height for.
+ * @param[in] isLastLine whether this is the last line in the text.
*/
-float GetLineHeight(const LineRun lineRun);
+float GetLineHeight(const LineRun lineRun, bool isLastLine);
} // namespace Text
#include <dali-toolkit/internal/text/font-description-run.h>
#include <dali-toolkit/internal/text/markup-processor-font.h>
#include <dali-toolkit/internal/text/markup-processor-helper-functions.h>
+#include <dali-toolkit/internal/text/markup-processor-underline.h>
namespace Dali
{
const std::string XHTML_SLANT_ATTRIBUTE("font-slant");
const std::string XHTML_COLOR_ATTRIBUTE("text-color");
+
+//the underlined character's attributes
+const std::string XHTML_UNDERLINE_COLOR_ATTRIBUTE("u-color");
+const std::string XHTML_UNDERLINE_HEIGHT_ATTRIBUTE("u-height");
+const std::string XHTML_UNDERLINE_TYPE_ATTRIBUTE("u-type");
+const std::string XHTML_UNDERLINE_DASH_GAP_ATTRIBUTE("u-dash-gap");
+const std::string XHTML_UNDERLINE_DASH_WIDTH_ATTRIBUTE("u-dash-width");
} // namespace
-void ProcessSpanTag(const Tag& tag, ColorRun& colorRun, FontDescriptionRun& fontRun, bool& isColorDefined, bool& isFontDefined)
+void ProcessSpanTag(const Tag& tag,
+ ColorRun& colorRun,
+ FontDescriptionRun& fontRun,
+ UnderlinedCharacterRun& underlinedCharacterRun,
+ bool& isColorDefined,
+ bool& isFontDefined,
+ bool& isUnderlinedCharacterDefined)
{
for(Vector<Attribute>::ConstIterator it = tag.attributes.Begin(),
endIt = tag.attributes.End();
isFontDefined = true;
ProcessFontSlant(attribute, fontRun);
}
+ else if(TokenComparison(XHTML_UNDERLINE_COLOR_ATTRIBUTE, attribute.nameBuffer, attribute.nameLength))
+ {
+ isUnderlinedCharacterDefined = true;
+ ProcessColorAttribute(attribute, underlinedCharacterRun);
+ }
+ else if(TokenComparison(XHTML_UNDERLINE_HEIGHT_ATTRIBUTE, attribute.nameBuffer, attribute.nameLength))
+ {
+ isUnderlinedCharacterDefined = true;
+ ProcessHeightAttribute(attribute, underlinedCharacterRun);
+ }
+ else if(TokenComparison(XHTML_UNDERLINE_TYPE_ATTRIBUTE, attribute.nameBuffer, attribute.nameLength))
+ {
+ isUnderlinedCharacterDefined = true;
+ ProcessTypeAttribute(attribute, underlinedCharacterRun);
+ }
+ else if(TokenComparison(XHTML_UNDERLINE_DASH_GAP_ATTRIBUTE, attribute.nameBuffer, attribute.nameLength))
+ {
+ isUnderlinedCharacterDefined = true;
+ ProcessDashGapAttribute(attribute, underlinedCharacterRun);
+ }
+ else if(TokenComparison(XHTML_UNDERLINE_DASH_WIDTH_ATTRIBUTE, attribute.nameBuffer, attribute.nameLength))
+ {
+ isUnderlinedCharacterDefined = true;
+ ProcessDashWidthAttribute(attribute, underlinedCharacterRun);
+ }
}
}
* @param[in] tag The span tag and its attributes.
* @param[out] colorRun the color run to be filled.
* @param[out] fontRun the font run to be filled.
+ * @param[out] underlinedCharacterRun the underlined character run to be filled.
* @param[out] isColorDefined if the span has color defined.
* @param[out] isFontDefined if the span has font defined.
+ * @param[out] isUnderlinedCharacterDefined if the span has underlined-character defined.
*/
-void ProcessSpanTag(const Tag& tag, ColorRun& colorRun, FontDescriptionRun& fontRun, bool& isColorDefined, bool& isFontDefined);
+void ProcessSpanTag(const Tag& tag,
+ ColorRun& colorRun,
+ FontDescriptionRun& fontRun,
+ UnderlinedCharacterRun& underlinedCharacterRun,
+ bool& isColorDefined,
+ bool& isFontDefined,
+ bool& isUnderlinedCharacterDefined);
} // namespace Text
}
}
+void OverrideNestedUnderlinedCharacterRuns(Vector<UnderlinedCharacterRun>& underlinedCharacterRuns)
+{
+ // Handle nested tags
+ // The inner tag inherit the attributes of the outer tag and override them when defined in the inner tag.
+ // Example:
+ // <u height='5.0f' color='blue'> outer tag before <u color='green'> inner tag </u> outer tag after </u>
+ // "outer tag before" and "outer tag after" have height = 5.0f and color = 'blue'
+ // "inner tag" has height = 5.0f and color = 'green'
+
+ if(underlinedCharacterRuns.Count() > 0u)
+ {
+ Vector<UnderlinedCharacterRun>::ConstIterator preIt = underlinedCharacterRuns.Begin();
+
+ Vector<UnderlinedCharacterRun>::Iterator it = underlinedCharacterRuns.Begin() + 1;
+ Vector<UnderlinedCharacterRun>::ConstIterator endIt = underlinedCharacterRuns.End();
+
+ while(it != endIt)
+ {
+ const UnderlinedCharacterRun& run = *it;
+ const CharacterIndex& characterIndex = run.characterRun.characterIndex;
+ const Length& numberOfCharacters = run.characterRun.numberOfCharacters;
+
+ const UnderlinedCharacterRun& preRun = *preIt;
+ const CharacterIndex& preCharacterIndex = preRun.characterRun.characterIndex;
+ const Length& preNumberOfCharacters = preRun.characterRun.numberOfCharacters;
+
+ if((preCharacterIndex <= characterIndex) &&
+ ((characterIndex + numberOfCharacters) <= (preCharacterIndex + preNumberOfCharacters)))
+ {
+ it->properties.CopyIfNotDefined(preIt->properties);
+ }
+
+ it++;
+ preIt++;
+ }
+ }
+}
+
} // namespace Text
} // namespace Toolkit
*
*/
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/dali-vector.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/underlined-character-run.h>
+
namespace Dali
{
namespace Toolkit
{
struct Tag;
struct Attribute;
-struct UnderlinedCharacterRun;
/**
* @brief Fill the underlined character run with the type attribute value.
*/
void ProcessUnderlineTag(const Tag& tag, UnderlinedCharacterRun& underlinedCharacterRun);
+/**
+ * @brief Override the run's attributes which contained in the previous run. This is to handle the nested tags.
+ *
+ * @param[in,out] underlinedCharacterRuns The list of underlined character run
+ */
+void OverrideNestedUnderlinedCharacterRuns(Vector<UnderlinedCharacterRun>& underlinedCharacterRuns);
+
} // namespace Text
} // namespace Toolkit
// Range 3 0x10000u < XHTML_DECIMAL_ENTITY_RANGE <= 0x10FFFFu
const unsigned long XHTML_DECIMAL_ENTITY_RANGE[] = {0x0u, 0xD7FFu, 0xE000u, 0xFFFDu, 0x10000u, 0x10FFFFu};
-const unsigned int MAX_NUM_OF_ATTRIBUTES = 5u; ///< The font tag has the 'family', 'size' 'weight', 'width' and 'slant' attrubutes.
+const unsigned int MAX_NUM_OF_ATTRIBUTES = 11u; ///< The span tag has the 'font-family', 'font-size' 'font-weight', 'font-width', 'font-slant','text-color', 'u-color', 'u-height','u-type','u-dash-gap'and 'u-dash-width' attrubutes.
const unsigned int DEFAULT_VECTOR_SIZE = 16u; ///< Default size of run vectors.
#if defined(DEBUG_ENABLED)
{
RunIndex colorRunIndex;
RunIndex fontRunIndex;
+ RunIndex underlinedCharacterRunIndex;
bool isColorDefined;
bool isFontDefined;
+ bool isUnderlinedCharacterDefined;
};
/**
*/
void Initialize(Span& span)
{
- span.colorRunIndex = 0u;
- span.isColorDefined = false;
- span.fontRunIndex = 0u;
- span.isFontDefined = false;
+ span.colorRunIndex = 0u;
+ span.isColorDefined = false;
+ span.fontRunIndex = 0u;
+ span.isFontDefined = false;
+ span.underlinedCharacterRunIndex = 0u;
+ span.isUnderlinedCharacterDefined = false;
}
/**
* @param[in] tagReference The tagReference we should increment/decrement
*/
void ProcessSpanForRun(
- const Tag& spanTag,
- StyleStack<Span>& spanStack,
- Vector<ColorRun>& colorRuns,
- Vector<FontDescriptionRun>& fontRuns,
- RunIndex& colorRunIndex,
- RunIndex& fontRunIndex,
- const CharacterIndex characterIndex,
- int& tagReference)
+ const Tag& spanTag,
+ StyleStack<Span>& spanStack,
+ Vector<ColorRun>& colorRuns,
+ Vector<FontDescriptionRun>& fontRuns,
+ Vector<UnderlinedCharacterRun>& underlinedCharacterRuns,
+ RunIndex& colorRunIndex,
+ RunIndex& fontRunIndex,
+ RunIndex& underlinedCharacterRunIndex,
+ const CharacterIndex characterIndex,
+ int& tagReference)
{
if(!spanTag.isEndTag)
{
FontDescriptionRun fontRun;
Initialize(fontRun);
+ UnderlinedCharacterRun underlinedCharacterRun;
+ Initialize(underlinedCharacterRun);
+
Span span;
Initialize(span);
// Fill the run with the parameters.
- colorRun.characterRun.characterIndex = characterIndex;
- fontRun.characterRun.characterIndex = characterIndex;
+ colorRun.characterRun.characterIndex = characterIndex;
+ fontRun.characterRun.characterIndex = characterIndex;
+ underlinedCharacterRun.characterRun.characterIndex = characterIndex;
- span.colorRunIndex = colorRunIndex;
- span.fontRunIndex = fontRunIndex;
+ span.colorRunIndex = colorRunIndex;
+ span.fontRunIndex = fontRunIndex;
+ span.underlinedCharacterRunIndex = underlinedCharacterRunIndex;
- ProcessSpanTag(spanTag, colorRun, fontRun, span.isColorDefined, span.isFontDefined);
+ ProcessSpanTag(spanTag, colorRun, fontRun, underlinedCharacterRun, span.isColorDefined, span.isFontDefined, span.isUnderlinedCharacterDefined);
// Push the span into the stack.
spanStack.Push(span);
++fontRunIndex;
}
+ if(span.isUnderlinedCharacterDefined)
+ {
+ // Push the run in the logical model.
+ underlinedCharacterRuns.PushBack(underlinedCharacterRun);
+ ++underlinedCharacterRunIndex;
+ }
+
// Increase reference
++tagReference;
}
fontRun.characterRun.numberOfCharacters = characterIndex - fontRun.characterRun.characterIndex;
}
+ if(span.isUnderlinedCharacterDefined)
+ {
+ UnderlinedCharacterRun& underlinedCharacterRun = *(underlinedCharacterRuns.Begin() + span.underlinedCharacterRunIndex);
+ underlinedCharacterRun.characterRun.numberOfCharacters = characterIndex - underlinedCharacterRun.characterRun.characterIndex;
+ }
+
--tagReference;
}
}
/* Underline */
ProcessTagForRun<UnderlinedCharacterRun>(
markupProcessData.underlinedCharacterRuns, styleStack, tag, characterIndex, underlinedCharacterRunIndex, uTagReference, [](const Tag& tag, UnderlinedCharacterRun& run) {
- run.properties.color = Color::BLUE;
+ run.properties.color = Color::BLUE;
run.properties.colorDefined = true;
ProcessUnderlineTag(tag, run);
});
}
else if(TokenComparison(XHTML_SPAN_TAG, tag.buffer, tag.length))
{
- ProcessSpanForRun(tag, spanStack, markupProcessData.colorRuns, markupProcessData.fontRuns, colorRunIndex, fontRunIndex, characterIndex, spanTagReference);
+ ProcessSpanForRun(tag, spanStack, markupProcessData.colorRuns, markupProcessData.fontRuns, markupProcessData.underlinedCharacterRuns, colorRunIndex, fontRunIndex, underlinedCharacterRunIndex, characterIndex, spanTagReference);
}
else if(TokenComparison(XHTML_STRIKETHROUGH_TAG, tag.buffer, tag.length))
{
// Resize the model's vectors.
ResizeModelVectors(markupProcessData, fontRunIndex, colorRunIndex, underlinedCharacterRunIndex, backgroundRunIndex, boundedParagraphRunIndex);
+
+ // Handle the nested tags
+ OverrideNestedUnderlinedCharacterRuns(markupProcessData.underlinedCharacterRuns);
}
} // namespace Text
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);
+ const UnderlineStyleProperties currentUnderlineProperties = GetCurrentUnderlineProperties(i, isGlyphUnderlined, underlineRuns, currentUnderlinedGlyphRunIt, viewUnderlineProperties);
+ float currentUnderlineHeight = currentUnderlineProperties.height;
thereAreUnderlinedGlyphs = thereAreUnderlinedGlyphs || isGlyphUnderlined;
currentStrikethroughColor = strikethroughColor;
//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)))
+ if((!isPreUnderlined && isGlyphUnderlined) || (isGlyphUnderlined && (preUnderlineProperties != currentUnderlineProperties)))
{
- mapUnderlineChunkIdWithProperties.insert(std::pair<uint32_t, UnderlineStyleProperties>(underlineChunkId, preUnderlineProperties));
underlineChunkId++;
+ mapUnderlineChunkIdWithProperties.insert(std::pair<uint32_t, UnderlineStyleProperties>(underlineChunkId, currentUnderlineProperties));
}
//Keep status of underlined for previous glyph to check consecutive indices
return false;
}
-float GetCurrentUnderlineHeight(const Vector<UnderlinedGlyphRun>& underlineRuns,
- Vector<UnderlinedGlyphRun>::ConstIterator currentUnderlinedGlyphRunIt,
- const float underlineHeight)
+UnderlineStyleProperties GetCurrentUnderlineProperties(GlyphIndex index,
+ const bool& isGlyphUnderlined,
+ const Vector<UnderlinedGlyphRun>& underlineRuns,
+ Vector<UnderlinedGlyphRun>::ConstIterator& currentUnderlinedGlyphRunIt,
+ const UnderlineStyleProperties& commonUnderlineProperties)
{
- if(currentUnderlinedGlyphRunIt == underlineRuns.End())
+ UnderlineStyleProperties currentUnderlineStyleProperties = commonUnderlineProperties;
+
+ if(isGlyphUnderlined && (currentUnderlinedGlyphRunIt != underlineRuns.End()))
{
- return underlineHeight;
- }
+ // Retrieve the latest run to handle the nested case.
+ for(Vector<UnderlinedGlyphRun>::ConstIterator it = currentUnderlinedGlyphRunIt + 1,
+ endIt = underlineRuns.End();
+ it != endIt;
+ ++it)
+ {
+ const UnderlinedGlyphRun& run = *it;
- const UnderlinedGlyphRun& underlinedGlyphRun = *currentUnderlinedGlyphRunIt;
- return (underlinedGlyphRun.properties.heightDefined ? underlinedGlyphRun.properties.height : underlineHeight);
-}
+ if((run.glyphRun.glyphIndex <= index) && (index < (run.glyphRun.glyphIndex + run.glyphRun.numberOfGlyphs)))
+ {
+ currentUnderlinedGlyphRunIt = it;
+ }
+ }
-UnderlineStyleProperties GetCurrentUnderlineProperties(const bool& isGlyphUnderlined,
- const Vector<UnderlinedGlyphRun>& underlineRuns,
- Vector<UnderlinedGlyphRun>::ConstIterator currentUnderlinedGlyphRunIt,
- const UnderlineStyleProperties& commonUnderlineProperties)
-{
- return (isGlyphUnderlined && (currentUnderlinedGlyphRunIt != underlineRuns.End()))
- ? currentUnderlinedGlyphRunIt->properties
- : commonUnderlineProperties;
+ currentUnderlineStyleProperties.OverrideByDefinedProperties(currentUnderlinedGlyphRunIt->properties);
+ }
+
+ return currentUnderlineStyleProperties;
}
float FetchUnderlinePositionFromFontMetrics(const FontMetrics& fontMetrics)
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] index the index of glyph.
* @param[in] isGlyphUnderlined whether the glyph is underlined.
* @param[in] underlineRuns the underline runs.
* @param[in] currentUnderlinedGlyphRunIt the iterator of current underlined glyph run.
*
* @return the determined underline properties
*/
-UnderlineStyleProperties GetCurrentUnderlineProperties(const bool& isGlyphUnderlined,
- const Vector<UnderlinedGlyphRun>& underlineRuns,
- Vector<UnderlinedGlyphRun>::ConstIterator currentUnderlinedGlyphRunIt,
- const UnderlineStyleProperties& commonUnderlineProperties);
+UnderlineStyleProperties GetCurrentUnderlineProperties(GlyphIndex index,
+ const bool& isGlyphUnderlined,
+ const Vector<UnderlinedGlyphRun>& underlineRuns,
+ Vector<UnderlinedGlyphRun>::ConstIterator& currentUnderlinedGlyphRunIt,
+ const UnderlineStyleProperties& commonUnderlineProperties);
/**
* @brief Fetch and calculate underline Position using font-metrics
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);
+ currentUnderlineProperties = GetCurrentUnderlineProperties(glyphIndex, underlineGlyph, underlineRuns, currentUnderlinedGlyphRunIt, modelUnderlineProperties);
+ currentUnderlineHeight = currentUnderlineProperties.height;
thereAreUnderlinedGlyphs = thereAreUnderlinedGlyphs || underlineGlyph;
currentStrikethroughColor = strikethroughColor;
//The outer loop to iterate on the separated chunks of underlined glyph runs
while(itGlyphRun != endItGlyphRun)
{
- 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->glyphRun.numberOfGlyphs;
- itGlyphRun++;
- } while(itGlyphRun != endItGlyphRun && itGlyphRun->glyphRun.glyphIndex == endGlyphIndex &&
- (firstUnderlineStyleProperties == itGlyphRun->properties));
-
- endGlyphIndex--;
+ endGlyphIndex = startGlyphIndex + itGlyphRun->glyphRun.numberOfGlyphs - 1;
// Create the image buffer for underline
Devel::PixelBuffer underlineImageBuffer = CreateImageBuffer(bufferWidth, bufferHeight, Typesetter::STYLE_UNDERLINE, ignoreHorizontalAlignment, pixelFormat, horizontalOffset, verticalOffset, startGlyphIndex, endGlyphIndex);
// Combine the two buffers
- topPixelBuffer = CombineImageBuffer(topPixelBuffer, underlineImageBuffer, bufferWidth, bufferHeight);
+ topPixelBuffer = CombineImageBuffer(underlineImageBuffer, topPixelBuffer, bufferWidth, bufferHeight);
+
+ itGlyphRun++;
}
return topPixelBuffer;
/*
- * 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.
const LineIndex lineIndex = visualModel->GetLineOfCharacter(characterIndex);
const LineIndex previousLineIndex = (lineIndex > 0 ? lineIndex - 1u : lineIndex);
+ const LineIndex lastLineIndex = (visualModel->mLines.Size() > 0 ? visualModel->mLines.Size() - 1u : 0);
+ const bool isLastLine = (previousLineIndex == lastLineIndex);
// Retrieve the cursor position info.
CursorInfo cursorInfo;
const LineRun& line = *(visualModel->mLines.Begin() + previousLineIndex);
// Get the next hit 'y' point.
- const float hitPointY = cursorInfo.lineOffset - 0.5f * GetLineHeight(line);
+ const float hitPointY = cursorInfo.lineOffset - 0.5f * GetLineHeight(line, isLastLine);
// Use the cursor hook position 'x' and the next hit 'y' position to calculate the new cursor index.
bool matchedCharacter = false;
// Get the line below.
const LineRun& line = *(visualModel->mLines.Begin() + lineIndex + 1u);
+ // Get last line index
+ const LineIndex lastLineIndex = (visualModel->mLines.Size() > 0 ? visualModel->mLines.Size() - 1u : 0);
+ const bool isLastLine = (lineIndex + 1u == lastLineIndex);
+
// Get the next hit 'y' point.
- const float hitPointY = cursorInfo.lineOffset + cursorInfo.lineHeight + 0.5f * GetLineHeight(line);
+ const float hitPointY = cursorInfo.lineOffset + cursorInfo.lineHeight + 0.5f * GetLineHeight(line, isLastLine);
// Use the cursor hook position 'x' and the next hit 'y' position to calculate the new cursor index.
bool matchedCharacter = false;
return false;
}
+bool Controller::Impl::SetRelativeLineSize(float relativeLineSize)
+{
+ if(std::fabs(relativeLineSize - GetRelativeLineSize()) > Math::MACHINE_EPSILON_1000)
+ {
+ mLayoutEngine.SetRelativeLineSize(relativeLineSize);
+
+ RelayoutAllCharacters();
+ return true;
+ }
+ return false;
+}
+
+float Controller::Impl::GetRelativeLineSize()
+{
+ return mLayoutEngine.GetRelativeLineSize();
+}
+
string Controller::Impl::GetSelectedText()
{
string text;
{
CharacterIndex characterIndex = it->characterRun.characterIndex;
Length numberOfCharacters = it->characterRun.numberOfCharacters;
- for(Length index = 0u; index < numberOfCharacters; index++)
+
+ if(numberOfCharacters == 0)
+ {
+ continue;
+ }
+
+ // Create one run for all glyphs of all run's characters that has same properties
+ // This enhance performance and reduce the needed memory to store glyphs-runs
+ UnderlinedGlyphRun underlineGlyphRun;
+ underlineGlyphRun.glyphRun.glyphIndex = charactersToGlyph[characterIndex];
+ underlineGlyphRun.glyphRun.numberOfGlyphs = glyphsPerCharacter[characterIndex];
+ //Copy properties (attributes)
+ underlineGlyphRun.properties = it->properties;
+
+ for(Length index = 1u; index < numberOfCharacters; 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);
+ underlineGlyphRun.glyphRun.numberOfGlyphs += glyphsPerCharacter[characterIndex + index];
}
+
+ mModel->mVisualModel->mUnderlineRuns.PushBack(underlineGlyphRun);
}
}
bool SetDefaultLineSize(float lineSize);
/**
+ * @copydoc Controller::SetRelativeLineSize
+ */
+ bool SetRelativeLineSize(float relativeLineSize);
+
+ /**
+ * @copydoc Controller::GetRelativeLineSize
+ */
+ float GetRelativeLineSize();
+
+ /**
* @copydoc Text::Controller::GetPrimaryCursorPosition()
*/
CharacterIndex GetPrimaryCursorPosition() const;
return mImpl->mLayoutEngine.GetDefaultLineSize();
}
+bool Controller::SetRelativeLineSize(float relativeLineSize)
+{
+ return mImpl->SetRelativeLineSize(relativeLineSize);
+}
+
+float Controller::GetRelativeLineSize() const
+{
+ return mImpl->GetRelativeLineSize();
+}
+
void Controller::SetInputColor(const Vector4& color)
{
InputProperties::SetInputColor(*this, color);
float GetDefaultLineSize() const;
/**
+ * @brief Sets the relative line size to the original line size.
+ *
+ * @param[in] relativeLineSize The relativeline size.
+ *
+ * @return True if relativeLineSize has been updated, false otherwise
+ */
+ bool SetRelativeLineSize(float lineSize);
+
+ /**
+ * @brief Retrieves the relative line size.
+ *
+ * @return The relative line size.
+ */
+ float GetRelativeLineSize() const;
+
+ /**
* @brief Sets the input text's color.
*
* @param[in] color The input text's color.
/*
- * 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.
{
namespace Text
{
-bool GetNextLine(GlyphIndex index, LineIndex& lineIndex, LineRun*& lineRun, GlyphIndex& lastGlyphOfLine, Length numberOfLines)
+bool GetNextLine(GlyphIndex index, LineIndex& lineIndex, LineRun*& lineRun, GlyphIndex& lastGlyphOfLine, Length numberOfLines, bool& isLastLine)
{
if(index == lastGlyphOfLine)
{
++lineIndex;
if(lineIndex < numberOfLines)
{
+ isLastLine = (lineIndex + 1 == numberOfLines);
++lineRun;
return true;
}
return false;
}
-void UpdateLineInfo(const LineRun* lineRun, float& currentLineOffset, float& currentLineHeight, GlyphIndex& lastGlyphOfLine)
+void UpdateLineInfo(const LineRun* lineRun, float& currentLineOffset, float& currentLineHeight, GlyphIndex& lastGlyphOfLine, bool isLastLine)
{
lastGlyphOfLine = lineRun->glyphRun.glyphIndex + lineRun->glyphRun.numberOfGlyphs - 1u;
currentLineOffset = currentLineOffset + currentLineHeight;
- currentLineHeight = GetLineHeight(*lineRun);
+ currentLineHeight = GetLineHeight(*lineRun, isLastLine);
}
void GetTextGeometry(ModelPtr textModel, CharacterIndex startIndex, CharacterIndex endIndex, Vector<Vector2>& sizesList, Vector<Vector2>& positionsList)
GlyphIndex glyphEnd = *(charactersToGlyphBuffer + endIndex) + ((numberOfGlyphs > 0) ? numberOfGlyphs - 1u : 0u);
LineIndex lineIndex = visualModel->GetLineOfCharacter(startIndex);
Length numberOfLines = visualModel->GetTotalNumberOfLines();
+ bool isLastLine = lineIndex + 1 == numberOfLines;
LineIndex firstLineIndex = lineIndex;
Size textInLineSize;
//get the first line and its vertical offset
float currentLineOffset = CalculateLineOffset(visualModel->mLines, firstLineIndex);
- float currentLineHeight = GetLineHeight(*lineRun);
+ float currentLineHeight = GetLineHeight(*lineRun, isLastLine);
GlyphIndex lastGlyphOfLine = lineRun->glyphRun.glyphIndex + lineRun->glyphRun.numberOfGlyphs - 1;
// Check if the first/last glyph is a ligature that needs be splitted like English fi or Arabic ﻻ.
positionsList.PushBack(blockPos);
}
- if(GetNextLine(index, lineIndex, lineRun, lastGlyphOfLine, numberOfLines))
+ if(GetNextLine(index, lineIndex, lineRun, lastGlyphOfLine, numberOfLines, isLastLine))
{
- UpdateLineInfo(lineRun, currentLineOffset, currentLineHeight, lastGlyphOfLine);
+ UpdateLineInfo(lineRun, currentLineOffset, currentLineHeight, lastGlyphOfLine, isLastLine);
}
// Ignore any glyph that was removed
continue;
}
else if((ellipsisPosition == DevelText::EllipsisPosition::START) && (index <= startIndexOfGlyphs))
{
- if(GetNextLine(index, lineIndex, lineRun, lastGlyphOfLine, numberOfLines))
+ if(GetNextLine(index, lineIndex, lineRun, lastGlyphOfLine, numberOfLines, isLastLine))
{
- UpdateLineInfo(lineRun, currentLineOffset, currentLineHeight, lastGlyphOfLine);
+ UpdateLineInfo(lineRun, currentLineOffset, currentLineHeight, lastGlyphOfLine, isLastLine);
}
continue;
currentSize.y = currentLineHeight;
// if there is next line to retrieve.
- if(GetNextLine(index, lineIndex, lineRun, lastGlyphOfLine, numberOfLines))
+ if(GetNextLine(index, lineIndex, lineRun, lastGlyphOfLine, numberOfLines, isLastLine))
{
- UpdateLineInfo(lineRun, currentLineOffset, currentLineHeight, lastGlyphOfLine);
+ UpdateLineInfo(lineRun, currentLineOffset, currentLineHeight, lastGlyphOfLine, isLastLine);
}
}
lineRun += firstLineIndex;
- selectionBoxInfo->lineHeight = GetLineHeight(*lineRun);
+ // The line height is the addition of the line ascender and the line descender.
+ // However, the line descender has a negative value, hence the subtraction also line spacing should not be included in selection height.
+ selectionBoxInfo->lineHeight = lineRun->ascender - lineRun->descender;
GlyphIndex lastGlyphOfLine = lineRun->glyphRun.glyphIndex + lineRun->glyphRun.numberOfGlyphs - 1u;
++lineIndex;
if(lineIndex < firstLineIndex + numberOfLines)
{
+ float currentLineSpacing = lineRun->lineSpacing;
+
// Retrieve the next line.
++lineRun;
// Update the line's vertical offset.
selectionBoxInfo->lineOffset = currentLineOffset + currentLineHeight;
- selectionBoxInfo->lineHeight = GetLineHeight(*lineRun);
+ if(currentLineSpacing < 0)
+ {
+ selectionBoxInfo->lineOffset += currentLineSpacing;
+ }
+
+ // The line height is the addition of the line ascender and the line descender.
+ // However, the line descender has a negative value, hence the subtraction also line spacing should not be included in selection height.
+ selectionBoxInfo->lineHeight = lineRun->ascender - lineRun->descender;
+
+ if(lineRun->lineSpacing > 0)
+ {
+ selectionBoxInfo->lineHeight += lineRun->lineSpacing;
+ }
}
}
}
const LineRun& elidedLine = *ellipsisLine;
if((1u == numberOfLines) &&
- (GetLineHeight(elidedLine) > mImpl->mVisualModel->mControlSize.height))
+ (GetLineHeight(elidedLine, true) > mImpl->mVisualModel->mControlSize.height))
{
// Replace the first glyph with ellipsis glyph
auto indexOfFirstGlyph = (ellipsisPosition == DevelText::EllipsisPosition::START) ? startIndexOfEllipsis : 0u;
*/
// EXTERNAL INCLUDES
+#include <dali/public-api/common/constants.h>
#include <dali/public-api/math/vector4.h>
// INTERNAL INCLUDES
-
#include <dali-toolkit/public-api/text/text-enumerations.h>
namespace Dali
return ((!heightDefined && !other.heightDefined) || ((heightDefined && other.heightDefined) && (height == other.height)));
}
+ UnderlineStyleProperties& CopyIfNotDefined(const UnderlineStyleProperties& other)
+ {
+ //Copy only the defined properties in other and not defined in this from other to this
+ if(!typeDefined && other.typeDefined)
+ {
+ type = other.type;
+ typeDefined = true;
+ }
+
+ if(!heightDefined && other.heightDefined)
+ {
+ height = other.height;
+ heightDefined = true;
+ }
+
+ if(!colorDefined && other.colorDefined)
+ {
+ color = other.color;
+ colorDefined = true;
+ }
+
+ if(!dashGapDefined && other.dashGapDefined)
+ {
+ dashGap = other.dashGap;
+ dashGapDefined = true;
+ }
+
+ if(!dashWidthDefined && other.dashWidthDefined)
+ {
+ dashWidth = other.dashWidth;
+ dashWidthDefined = true;
+ }
+
+ // to chain this method
+ return *this;
+ }
+
+ UnderlineStyleProperties& OverrideByDefinedProperties(const UnderlineStyleProperties& other)
+ {
+ //Copy only the defined properties in other from other to this
+ if(other.typeDefined)
+ {
+ type = other.type;
+ typeDefined = true;
+ }
+
+ if(other.heightDefined)
+ {
+ height = other.height;
+ heightDefined = true;
+ }
+
+ if(other.colorDefined)
+ {
+ color = other.color;
+ colorDefined = true;
+ }
+
+ if(other.dashGapDefined)
+ {
+ dashGap = other.dashGap;
+ dashGapDefined = true;
+ }
+
+ if(other.dashWidthDefined)
+ {
+ dashWidth = other.dashWidth;
+ dashWidthDefined = true;
+ }
+
+ // to chain this method
+ return *this;
+ }
+
//Attributes
Text::Underline::Type type; ///< The type of underline.
Vector4 color; ///< The color of underline.
return OnGetPropertyObject(key);
}
}
+ else
+ {
+ if(index == mImpl->mBorderlineWidthIndex ||
+ index == mImpl->mBorderlineColorIndex ||
+ index == mImpl->mBorderlineOffsetIndex)
+ {
+ // Borderline is animated now. we always have to use borderline feature.
+ mImpl->mAlwaysUsingBorderline = true;
+ }
+ if(index == mImpl->mCornerRadiusIndex)
+ {
+ // CornerRadius is animated now. we always have to use corner radius feature.
+ mImpl->mAlwaysUsingCornerRadius = true;
+ }
+ }
return Dali::Property(mImpl->mRenderer, index);
}
{
const unsigned int TOOLKIT_MAJOR_VERSION = 2;
const unsigned int TOOLKIT_MINOR_VERSION = 1;
-const unsigned int TOOLKIT_MICRO_VERSION = 11;
+const unsigned int TOOLKIT_MICRO_VERSION = 12;
const char* const TOOLKIT_BUILD_DATE = __DATE__ " " __TIME__;
#ifdef DEBUG_ENABLED
Name: dali2-toolkit
Summary: Dali 3D engine Toolkit
-Version: 2.1.11
+Version: 2.1.12
Release: 1
Group: System/Libraries
License: Apache-2.0 and BSD-3-Clause and MIT