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;
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;
+}
{
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
{
#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;
{
CharacterIndex characterIndex = it->characterRun.characterIndex;
Length numberOfCharacters = it->characterRun.numberOfCharacters;
- for(Length index = 0u; index < numberOfCharacters; index++)
+
+ if(numberOfCharacters == 0)
{
- 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);
+ 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++)
+ {
+ underlineGlyphRun.glyphRun.numberOfGlyphs += glyphsPerCharacter[characterIndex + index];
+ }
+
+ mModel->mVisualModel->mUnderlineRuns.PushBack(underlineGlyphRun);
}
}
*/
// 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);
}