Merge "[AT-SPI] text: add "GetRangeExtents" interface" into devel/master
authorShinwoo Kim <cinoo.kim@samsung.com>
Thu, 10 Mar 2022 01:36:03 +0000 (01:36 +0000)
committerGerrit Code Review <gerrit@review>
Thu, 10 Mar 2022 01:36:03 +0000 (01:36 +0000)
17 files changed:
automated-tests/src/dali-toolkit-internal/utc-Dali-TextEditor-internal.cpp
automated-tests/src/dali-toolkit-internal/utc-Dali-TextField-internal.cpp
automated-tests/src/dali-toolkit-internal/utc-Dali-TextLabel-internal.cpp
automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp
dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.cpp
dali-toolkit/internal/text/markup-processor-span.cpp
dali-toolkit/internal/text/markup-processor-span.h
dali-toolkit/internal/text/markup-processor-underline.cpp
dali-toolkit/internal/text/markup-processor-underline.h
dali-toolkit/internal/text/markup-processor.cpp
dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp
dali-toolkit/internal/text/rendering/styles/underline-helper-functions.cpp
dali-toolkit/internal/text/rendering/styles/underline-helper-functions.h
dali-toolkit/internal/text/rendering/text-typesetter.cpp
dali-toolkit/internal/text/text-controller-impl.cpp
dali-toolkit/internal/text/underline-style-properties.h
dali-toolkit/internal/visuals/visual-base-impl.cpp

index 99b9e03..c75f754 100644 (file)
@@ -87,12 +87,12 @@ int UtcDaliTextEditorMarkupUnderline(void)
   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);
@@ -100,12 +100,11 @@ int UtcDaliTextEditorMarkupUnderline(void)
 
   //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;
 }
@@ -128,9 +127,7 @@ int UtcDaliTextEditorMarkupUnderlineAttributes(void)
     "<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);
@@ -138,13 +135,12 @@ int UtcDaliTextEditorMarkupUnderlineAttributes(void)
   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);
@@ -153,20 +149,16 @@ int UtcDaliTextEditorMarkupUnderlineAttributes(void)
   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,
@@ -182,10 +174,8 @@ int UtcDaliTextEditorMarkupUnderlineAttributes(void)
 
       //<u type='solid'>ABC2</u>
       {"<u type='solid'>ABC2</u>",
-       4u,
-       7u,
        13u,
-       16u,
+       4u,
        {
          Text::Underline::SOLID,
          Color::BLACK,
@@ -201,10 +191,8 @@ int UtcDaliTextEditorMarkupUnderlineAttributes(void)
 
       //<u type='dashed'>ABC3</u>
       {"<u type='dashed'>ABC3</u>",
-       8u,
-       11u,
        21u,
-       24u,
+       4u,
        {
          Text::Underline::DASHED,
          Color::BLACK,
@@ -220,10 +208,8 @@ int UtcDaliTextEditorMarkupUnderlineAttributes(void)
 
       //<u type='double'>ABC4</u>
       {"<u type='double'>ABC4</u>",
-       12u,
-       15u,
        29u,
-       32u,
+       4u,
        {
          Text::Underline::DOUBLE,
          Color::BLACK,
@@ -239,10 +225,8 @@ int UtcDaliTextEditorMarkupUnderlineAttributes(void)
 
       //<u color='green'>ABC5</u>
       {"<u color='green'>ABC5</u>",
-       16u,
-       19u,
        37u,
-       40u,
+       4u,
        {
          Text::Underline::SOLID,
          Color::GREEN,
@@ -258,10 +242,8 @@ int UtcDaliTextEditorMarkupUnderlineAttributes(void)
 
       //<u height='5.0f'>ABC6</u>
       {"<u height='5.0f'>ABC6</u>",
-       20u,
-       23u,
        45u,
-       48u,
+       4u,
        {
          Text::Underline::SOLID,
          Color::BLACK,
@@ -277,10 +259,8 @@ int UtcDaliTextEditorMarkupUnderlineAttributes(void)
 
       //<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,
@@ -296,10 +276,8 @@ int UtcDaliTextEditorMarkupUnderlineAttributes(void)
 
       //<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,
@@ -315,10 +293,8 @@ int UtcDaliTextEditorMarkupUnderlineAttributes(void)
 
       //<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,
@@ -334,14 +310,291 @@ int UtcDaliTextEditorMarkupUnderlineAttributes(void)
 
     };
 
-  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;
index 8967f0e..b73142a 100644 (file)
@@ -169,12 +169,12 @@ int UtcDaliTextFieldMarkupUnderline(void)
   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);
@@ -182,12 +182,11 @@ int UtcDaliTextFieldMarkupUnderline(void)
 
   //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;
 }
@@ -220,13 +219,12 @@ int UtcDaliTextFieldMarkupUnderlineAttributes(void)
   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);
@@ -235,20 +233,16 @@ int UtcDaliTextFieldMarkupUnderlineAttributes(void)
   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,
@@ -264,10 +258,8 @@ int UtcDaliTextFieldMarkupUnderlineAttributes(void)
 
       //<u type='solid'>ABC2</u>
       {"<u type='solid'>ABC2</u>",
-       4u,
-       7u,
        13u,
-       16u,
+       4u,
        {
          Text::Underline::SOLID,
          Color::BLACK,
@@ -283,10 +275,8 @@ int UtcDaliTextFieldMarkupUnderlineAttributes(void)
 
       //<u type='dashed'>ABC3</u>
       {"<u type='dashed'>ABC3</u>",
-       8u,
-       11u,
        21u,
-       24u,
+       4u,
        {
          Text::Underline::DASHED,
          Color::BLACK,
@@ -302,10 +292,8 @@ int UtcDaliTextFieldMarkupUnderlineAttributes(void)
 
       //<u type='double'>ABC4</u>
       {"<u type='double'>ABC4</u>",
-       12u,
-       15u,
        29u,
-       32u,
+       4u,
        {
          Text::Underline::DOUBLE,
          Color::BLACK,
@@ -321,10 +309,8 @@ int UtcDaliTextFieldMarkupUnderlineAttributes(void)
 
       //<u color='green'>ABC5</u>
       {"<u color='green'>ABC5</u>",
-       16u,
-       19u,
        37u,
-       40u,
+       4u,
        {
          Text::Underline::SOLID,
          Color::GREEN,
@@ -340,10 +326,8 @@ int UtcDaliTextFieldMarkupUnderlineAttributes(void)
 
       //<u height='5.0f'>ABC6</u>
       {"<u height='5.0f'>ABC6</u>",
-       20u,
-       23u,
        45u,
-       48u,
+       4u,
        {
          Text::Underline::SOLID,
          Color::BLACK,
@@ -359,10 +343,8 @@ int UtcDaliTextFieldMarkupUnderlineAttributes(void)
 
       //<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,
@@ -378,10 +360,8 @@ int UtcDaliTextFieldMarkupUnderlineAttributes(void)
 
       //<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,
@@ -397,10 +377,203 @@ int UtcDaliTextFieldMarkupUnderlineAttributes(void)
 
       //<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,
@@ -416,14 +589,96 @@ int UtcDaliTextFieldMarkupUnderlineAttributes(void)
 
     };
 
-  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;
index 4259cdc..dd460f2 100644 (file)
@@ -46,12 +46,12 @@ int UtcDaliTextLabelMarkupUnderline(void)
   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);
@@ -59,12 +59,11 @@ int UtcDaliTextLabelMarkupUnderline(void)
 
   //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;
 }
@@ -97,13 +96,12 @@ int UtcDaliTextLabelMarkupUnderlineAttributes(void)
   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);
@@ -112,20 +110,16 @@ int UtcDaliTextLabelMarkupUnderlineAttributes(void)
   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,
@@ -141,10 +135,8 @@ int UtcDaliTextLabelMarkupUnderlineAttributes(void)
 
       //<u type='solid'>ABC2</u>
       {"<u type='solid'>ABC2</u>",
-       4u,
-       7u,
        13u,
-       16u,
+       4u,
        {
          Text::Underline::SOLID,
          Color::BLACK,
@@ -160,10 +152,8 @@ int UtcDaliTextLabelMarkupUnderlineAttributes(void)
 
       //<u type='dashed'>ABC3</u>
       {"<u type='dashed'>ABC3</u>",
-       8u,
-       11u,
        21u,
-       24u,
+       4u,
        {
          Text::Underline::DASHED,
          Color::BLACK,
@@ -179,10 +169,8 @@ int UtcDaliTextLabelMarkupUnderlineAttributes(void)
 
       //<u type='double'>ABC4</u>
       {"<u type='double'>ABC4</u>",
-       12u,
-       15u,
        29u,
-       32u,
+       4u,
        {
          Text::Underline::DOUBLE,
          Color::BLACK,
@@ -198,10 +186,8 @@ int UtcDaliTextLabelMarkupUnderlineAttributes(void)
 
       //<u color='green'>ABC5</u>
       {"<u color='green'>ABC5</u>",
-       16u,
-       19u,
        37u,
-       40u,
+       4u,
        {
          Text::Underline::SOLID,
          Color::GREEN,
@@ -217,10 +203,8 @@ int UtcDaliTextLabelMarkupUnderlineAttributes(void)
 
       //<u height='5.0f'>ABC6</u>
       {"<u height='5.0f'>ABC6</u>",
-       20u,
-       23u,
        45u,
-       48u,
+       4u,
        {
          Text::Underline::SOLID,
          Color::BLACK,
@@ -236,10 +220,8 @@ int UtcDaliTextLabelMarkupUnderlineAttributes(void)
 
       //<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,
@@ -255,10 +237,8 @@ int UtcDaliTextLabelMarkupUnderlineAttributes(void)
 
       //<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,
@@ -274,10 +254,203 @@ int UtcDaliTextLabelMarkupUnderlineAttributes(void)
 
       //<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,
@@ -293,14 +466,96 @@ int UtcDaliTextLabelMarkupUnderlineAttributes(void)
 
     };
 
-  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;
index 87701b2..aaedd55 100644 (file)
@@ -6110,4 +6110,156 @@ int UtcDaliVisualUpdatePropertyChangeShader03(void)
   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;
+}
index 4afb39a..75ffbfb 100644 (file)
@@ -784,20 +784,10 @@ void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event)
   {
     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
       {
@@ -809,18 +799,10 @@ void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event)
     }
     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
       {
index 40a508d..d7bf5eb 100644 (file)
@@ -26,6 +26,7 @@
 #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
 {
@@ -42,9 +43,22 @@ const std::string XHTML_WIDTH_ATTRIBUTE("font-width");
 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();
@@ -83,6 +97,31 @@ void ProcessSpanTag(const Tag& tag, ColorRun& colorRun, FontDescriptionRun& font
       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);
+    }
   }
 }
 
index 330caf1..f5c49f6 100644 (file)
@@ -33,10 +33,18 @@ struct MarkupProcessData;
  * @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
 
index 063f3fe..8f19b5a 100644 (file)
@@ -108,6 +108,44 @@ void ProcessUnderlineTag(const Tag& tag, UnderlinedCharacterRun& underlinedChara
   }
 }
 
+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
index f210718..cde347c 100644 (file)
  *
  */
 
+// 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
@@ -26,7 +32,6 @@ namespace Text
 {
 struct Tag;
 struct Attribute;
-struct UnderlinedCharacterRun;
 
 /**
  * @brief Fill the underlined character run with the type attribute value.
@@ -76,6 +81,13 @@ void ProcessColorAttribute(const Attribute& attribute, UnderlinedCharacterRun& u
  */
 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
index b41d70b..197dff1 100644 (file)
@@ -83,7 +83,7 @@ const char NEW_LINE    = 0x0A; // ASCII value of the newline.
 // 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)
@@ -140,8 +140,10 @@ struct Span
 {
   RunIndex colorRunIndex;
   RunIndex fontRunIndex;
+  RunIndex underlinedCharacterRunIndex;
   bool     isColorDefined;
   bool     isFontDefined;
+  bool     isUnderlinedCharacterDefined;
 };
 
 /**
@@ -195,10 +197,12 @@ void Initialize(UnderlinedCharacterRun& underlinedCharacterRun)
  */
 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;
 }
 
 /**
@@ -719,14 +723,16 @@ void ProcessAnchorTag(
  * @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)
   {
@@ -737,17 +743,22 @@ void ProcessSpanForRun(
     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);
@@ -767,6 +778,13 @@ void ProcessSpanForRun(
       ++fontRunIndex;
     }
 
+    if(span.isUnderlinedCharacterDefined)
+    {
+      // Push the run in the logical model.
+      underlinedCharacterRuns.PushBack(underlinedCharacterRun);
+      ++underlinedCharacterRunIndex;
+    }
+
     // Increase reference
     ++tagReference;
   }
@@ -789,6 +807,12 @@ void ProcessSpanForRun(
         fontRun.characterRun.numberOfCharacters = characterIndex - fontRun.characterRun.characterIndex;
       }
 
+      if(span.isUnderlinedCharacterDefined)
+      {
+        UnderlinedCharacterRun& underlinedCharacterRun         = *(underlinedCharacterRuns.Begin() + span.underlinedCharacterRunIndex);
+        underlinedCharacterRun.characterRun.numberOfCharacters = characterIndex - underlinedCharacterRun.characterRun.characterIndex;
+      }
+
       --tagReference;
     }
   }
@@ -1017,7 +1041,7 @@ void ProcessMarkupString(const std::string& markupString, MarkupProcessData& mar
         /* 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);
           });
@@ -1048,7 +1072,7 @@ void ProcessMarkupString(const std::string& markupString, MarkupProcessData& mar
       }
       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))
       {
@@ -1070,6 +1094,9 @@ void ProcessMarkupString(const std::string& markupString, MarkupProcessData& mar
 
   // Resize the model's vectors.
   ResizeModelVectors(markupProcessData, fontRunIndex, colorRunIndex, underlinedCharacterRunIndex, backgroundRunIndex, boundedParagraphRunIndex);
+
+  // Handle the nested tags
+  OverrideNestedUnderlinedCharacterRuns(markupProcessData.underlinedCharacterRuns);
 }
 
 } // namespace Text
index 9eb2fd6..291c187 100644 (file)
@@ -564,8 +564,8 @@ struct AtlasRenderer::Impl
 
       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;
@@ -655,10 +655,10 @@ struct AtlasRenderer::Impl
 
           //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
index 6720b91..873ef86 100644 (file)
@@ -45,27 +45,34 @@ bool IsGlyphUnderlined(GlyphIndex                                 index,
   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)
index 825b05c..38471c8 100644 (file)
@@ -46,21 +46,9 @@ bool IsGlyphUnderlined(GlyphIndex                                 index,
                        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.
@@ -68,10 +56,11 @@ float GetCurrentUnderlineHeight(const Vector<UnderlinedGlyphRun>&         underl
  *
  * @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
index 790e247..4dc9775 100644 (file)
@@ -1004,8 +1004,8 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer(const unsigned int bufferWidth,
 
       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;
@@ -1256,24 +1256,15 @@ Devel::PixelBuffer Typesetter::ApplyUnderlineMarkupImageBuffer(Devel::PixelBuffe
   //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;
index 3850f12..cf49df5 100644 (file)
@@ -1636,26 +1636,26 @@ void Controller::Impl::CopyUnderlinedFromLogicalToVisualModels(bool shouldClearP
   {
     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);
   }
 }
 
index 14016c4..d75f22b 100644 (file)
  */
 
 // 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
@@ -100,6 +100,80 @@ struct UnderlineStyleProperties
     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.
index 288ed34..81126c3 100644 (file)
@@ -1098,6 +1098,21 @@ Dali::Property Visual::Base::GetPropertyObject(Dali::Property::Key key)
       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);
 }