Extending Style - Adding Strikethrough 31/258031/35
authorSara Samara <sara.samara@samsung.com>
Sun, 9 May 2021 06:10:54 +0000 (09:10 +0300)
committerabdullah <abdullahhasan10@gmail.com>
Sun, 26 Dec 2021 15:17:47 +0000 (17:17 +0200)
***********************************************************
Description:
Adding the strikethrough for the text-editor and the text-label.
The sample code below can be used to test the strikethrough using the property maps.
The following can be used in the property map: enable and color.
***********************************************************

using namespace Dali;
using namespace Dali::Toolkit;

class SimpleApp : public ConnectionTracker
{
public:
  SimpleApp(Application& application)
  : mApplication(application)
  {
    mApplication.InitSignal().Connect(this, &SimpleApp::Create);
  }

  void Create(Application& application)
  {
    Window window = application.GetWindow();
    window.SetBackgroundColor(Vector4(0.04f, 0.345f, 0.392f, 1.0f));

    mEditor = TextEditor::New();
    mEditor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_CENTER);
    mEditor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_CENTER);
    mEditor.SetProperty(Actor::Property::POSITION, Vector3(0.f, 0.0f, 0.f));
    mEditor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 100.0f));
    mEditor.SetBackgroundColor(Vector4(0.04f, 0.345f, 0.392f, 1.0f));
    mEditor.SetProperty(TextEditor::Property::TEXT, "Hello");

    // new label code
    TextLabel label = TextLabel::New();
    label.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_CENTER);
    label.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_CENTER);
    label.SetProperty(Actor::Property::POSITION, Vector3(0.f, 0.0f, 0.f));
    label.SetProperty(Actor::Property::SIZE, Vector2(200.f, 100.0f));
    label.SetBackgroundColor(Vector4(0.04f, 0.345f, 0.392f, 1.0f));
    label.SetProperty(TextEditor::Property::TEXT, "Hello");

    //editor property map
    // Property::Map strikethruMapSet;
    // strikethruMapSet.Insert("enable", true);
    // strikethruMapSet.Insert("color", Color::RED);
    // mEditor.SetProperty(TextEditor::Property::STRIKETHROUGH, strikethruMapSet);

    Property::Map strikethruMapSet;
    strikethruMapSet.Insert("enable",true);
    strikethruMapSet.Insert("color",Vector4(0.75f, 0.96f, 1.f, 1.f));
    label.SetProperty(TextLabel::Property::STRIKETHROUGH, strikethruMapSet);

    window.Add(label);
    //window.Add(mEditor);
  }

private:
  Application& mApplication;
  TextEditor mEditor;
};

int DALI_EXPORT_API main(int argc, char** argv)
{
  Application application = Application::New(&argc, &argv);
  SimpleApp test(application);
  application.MainLoop();

  return 0;
}

Change-Id: I8de5088c1de0c042573c925a92a4829b67e00624

43 files changed:
automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp
automated-tests/src/dali-toolkit/utc-Dali-TextField.cpp
automated-tests/src/dali-toolkit/utc-Dali-TextLabel.cpp
dali-toolkit/devel-api/controls/text-controls/text-editor-devel.h
dali-toolkit/devel-api/controls/text-controls/text-field-devel.h
dali-toolkit/devel-api/controls/text-controls/text-label-devel.h
dali-toolkit/devel-api/controls/text-controls/text-style-properties-devel.h
dali-toolkit/devel-api/visuals/text-visual-properties-devel.h
dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp
dali-toolkit/internal/controls/text-controls/text-editor-property-handler.cpp
dali-toolkit/internal/controls/text-controls/text-field-impl.cpp
dali-toolkit/internal/controls/text-controls/text-field-property-handler.cpp
dali-toolkit/internal/controls/text-controls/text-label-impl.cpp
dali-toolkit/internal/graphics/shaders/text-visual-multi-color-text-with-style-shader.frag
dali-toolkit/internal/graphics/shaders/text-visual-single-color-text-with-style-and-emoji-shader.frag
dali-toolkit/internal/graphics/shaders/text-visual-single-color-text-with-style-shader.frag
dali-toolkit/internal/text/input-style.h
dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp
dali-toolkit/internal/text/rendering/text-typesetter.cpp
dali-toolkit/internal/text/rendering/text-typesetter.h
dali-toolkit/internal/text/rendering/view-model.cpp
dali-toolkit/internal/text/rendering/view-model.h
dali-toolkit/internal/text/text-controller-impl.h
dali-toolkit/internal/text/text-controller.cpp
dali-toolkit/internal/text/text-controller.h
dali-toolkit/internal/text/text-effects-style.cpp
dali-toolkit/internal/text/text-effects-style.h
dali-toolkit/internal/text/text-model-interface.h
dali-toolkit/internal/text/text-model.cpp
dali-toolkit/internal/text/text-model.h
dali-toolkit/internal/text/text-view-interface.h
dali-toolkit/internal/text/text-view.cpp
dali-toolkit/internal/text/text-view.h
dali-toolkit/internal/text/visual-model-impl.cpp
dali-toolkit/internal/text/visual-model-impl.h
dali-toolkit/internal/visuals/text/text-visual.cpp
dali-toolkit/internal/visuals/text/text-visual.h
dali-toolkit/internal/visuals/visual-string-constants.cpp
dali-toolkit/internal/visuals/visual-string-constants.h
dali-toolkit/public-api/controls/text-controls/text-editor.h
dali-toolkit/public-api/controls/text-controls/text-field.h
dali-toolkit/public-api/controls/text-controls/text-label.h
dali-toolkit/public-api/visuals/text-visual-properties.h

index 0bac46a..7701e61 100644 (file)
@@ -88,6 +88,8 @@ const char* const PROPERTY_NAME_EMBOSS                               = "emboss";
 const char* const PROPERTY_NAME_INPUT_EMBOSS                         = "inputEmboss";
 const char* const PROPERTY_NAME_OUTLINE                              = "outline";
 const char* const PROPERTY_NAME_INPUT_OUTLINE                        = "inputOutline";
+const char* const PROPERTY_NAME_STRIKETHROUGH                        = "strikethrough";
+const char* const PROPERTY_NAME_INPUT_STRIKETHROUGH                  = "inputStrikethrough";
 
 const char* const PROPERTY_NAME_SMOOTH_SCROLL                        = "smoothScroll";
 const char* const PROPERTY_NAME_SMOOTH_SCROLL_DURATION               = "smoothScrollDuration";
@@ -544,6 +546,8 @@ int UtcDaliTextEditorGetPropertyP(void)
   DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_INPUT_EMBOSS ) == TextEditor::Property::INPUT_EMBOSS );
   DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_OUTLINE ) == TextEditor::Property::OUTLINE );
   DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_INPUT_OUTLINE ) == TextEditor::Property::INPUT_OUTLINE );
+  DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_STRIKETHROUGH ) == DevelTextEditor::Property::STRIKETHROUGH );
+  DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_INPUT_STRIKETHROUGH ) == DevelTextEditor::Property::INPUT_STRIKETHROUGH );
   DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_SMOOTH_SCROLL ) == TextEditor::Property::SMOOTH_SCROLL );
   DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_SMOOTH_SCROLL_DURATION ) == TextEditor::Property::SMOOTH_SCROLL_DURATION );
   DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_ENABLE_SCROLL_BAR ) == TextEditor::Property::ENABLE_SCROLL_BAR );
@@ -564,6 +568,8 @@ int UtcDaliTextEditorGetPropertyP(void)
   DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_ENABLE_GRAB_HANDLE_POPUP ) == DevelTextEditor::Property::ENABLE_GRAB_HANDLE_POPUP );
   DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_INPUT_METHOD_SETTINGS ) == DevelTextEditor::Property::INPUT_METHOD_SETTINGS );
   DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_INPUT_FILTER ) == DevelTextEditor::Property::INPUT_FILTER );
+  DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_STRIKETHROUGH ) == DevelTextEditor::Property::STRIKETHROUGH );
+  DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_INPUT_STRIKETHROUGH ) == DevelTextEditor::Property::INPUT_STRIKETHROUGH );
 
   END_TEST;
 }
@@ -1033,6 +1039,36 @@ int UtcDaliTextEditorSetPropertyP(void)
   inputFilterMapSet.Clear();
   editor.SetProperty(DevelTextEditor::Property::INPUT_FILTER, inputFilterMapSet);
 
+  // Check the strikethrough property
+
+  Property::Map strikethroughMapSet;
+  Property::Map strikethroughMapGet;
+
+  application.SendNotification();
+  application.Render();
+
+  // Check the input strikethrough property
+
+  strikethroughMapSet.Clear();
+  strikethroughMapGet.Clear();
+  strikethroughMapSet.Insert( "enable", true );
+  strikethroughMapSet.Insert( "color", Color::BLUE );
+  strikethroughMapSet.Insert( "height", 2.0f );
+
+  editor.SetProperty( DevelTextEditor::Property::STRIKETHROUGH, strikethroughMapSet );
+
+  application.SendNotification();
+  application.Render();
+
+  strikethroughMapGet = editor.GetProperty<Property::Map>( DevelTextEditor::Property::STRIKETHROUGH );
+
+  DALI_TEST_EQUALS( strikethroughMapGet.Count(), strikethroughMapSet.Count(), TEST_LOCATION );
+  DALI_TEST_EQUALS( DaliTestCheckMaps( strikethroughMapSet, strikethroughMapGet ), true,  TEST_LOCATION );
+
+  // Check the input strikethrough property
+  editor.SetProperty( DevelTextEditor::Property::INPUT_STRIKETHROUGH, "Strikethrough input properties" );
+  DALI_TEST_EQUALS( editor.GetProperty<std::string>( DevelTextEditor::Property::INPUT_STRIKETHROUGH ), std::string("Strikethrough input properties"), TEST_LOCATION );
+
   application.SendNotification();
   application.Render();
 
@@ -1618,6 +1654,7 @@ int utcDaliTextEditorInputStyleChanged02(void)
   editor.SetProperty( TextEditor::Property::INPUT_SHADOW, "shadow" );
   editor.SetProperty( TextEditor::Property::INPUT_EMBOSS, "emboss" );
   editor.SetProperty( TextEditor::Property::INPUT_OUTLINE, "outline" );
+  editor.SetProperty( DevelTextEditor::Property::INPUT_STRIKETHROUGH, "strikethrough" );
 
   application.ProcessEvent( GenerateKey( "a", "", "a", KEY_A_CODE, 0, 0, Integration::KeyEvent::DOWN, "a", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE ) );
 
@@ -2850,6 +2887,50 @@ int utcDaliTextEditorUnderPropertyStringP(void)
   END_TEST;
 }
 
+int utcDaliTextEditorStrikethroughPropertyStringP(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" utcDaliTextEditorStrikethroughPropertyStringP");
+  TextEditor editor = TextEditor::New();
+  DALI_TEST_CHECK( editor );
+
+  std::string strikethroughSettings1( "{\"enable\":\"true\",\"color\":\"red\",\"height\":\"2\"}" );
+
+  application.GetScene().Add( editor );
+
+  editor.SetProperty( DevelTextEditor::Property::STRIKETHROUGH, strikethroughSettings1 );
+  DALI_TEST_EQUALS( editor.GetProperty<std::string>( DevelTextEditor::Property::STRIKETHROUGH ), strikethroughSettings1, TEST_LOCATION );
+
+  tet_infoline("Set strikethrough settings with a map");
+  // Check the input strikethrough property
+  Property::Map strikethroughMapSet;
+  Property::Map strikethroughMapGet;
+  strikethroughMapSet.Insert( "enable", true );
+  strikethroughMapSet.Insert( "color", Color::BLUE );
+  strikethroughMapSet.Insert( "height", 2.0f );
+
+  editor.SetProperty( DevelTextEditor::Property::STRIKETHROUGH, strikethroughMapSet );
+  strikethroughMapGet = editor.GetProperty<Property::Map>( DevelTextEditor::Property::STRIKETHROUGH );
+  DALI_TEST_EQUALS( strikethroughMapGet.Count(), strikethroughMapSet.Count(), TEST_LOCATION );
+  DALI_TEST_EQUALS( DaliTestCheckMaps( strikethroughMapSet, strikethroughMapGet ), true,  TEST_LOCATION );
+
+  tet_infoline("Set strikethrough settings with a string");
+  editor.SetProperty( DevelTextEditor::Property::STRIKETHROUGH, strikethroughSettings1 );
+  Property::Value value = editor.GetProperty( DevelTextEditor::Property::STRIKETHROUGH );
+  std::string result;
+  value.Get(result);
+  DALI_TEST_EQUALS( result , strikethroughSettings1, TEST_LOCATION  );
+
+  tet_infoline("Trying to set invalid strikethrough settings, should not update and stay at previous settings");
+  std::string strikethroughSettingsVoid( "{\"enable\":\"true\",\"coooolor\":\"blue\",\"height\":\"2\"}" );
+  editor.SetProperty( DevelTextEditor::Property::STRIKETHROUGH, strikethroughSettingsVoid );
+  value = editor.GetProperty( TextEditor::Property::UNDERLINE );
+  value.Get(result);
+  DALI_TEST_EQUALS( result , strikethroughSettings1, TEST_LOCATION  );
+
+  END_TEST;
+}
+
 int utcDaliTextEditorShadowPropertyStringP(void)
 {
   ToolkitTestApplication application;
@@ -4975,6 +5056,44 @@ int utcDaliTextEditorSelectionChangedSignal(void)
   END_TEST;
 }
 
+int UtcDaliToolkitTextEditorStrikethroughGeneration(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliToolkitTextEditorStrikethroughGeneration");
+
+  TextEditor textEditor = TextEditor::New();
+  textEditor.SetProperty( TextEditor::Property::TEXT, "Test" );
+  textEditor.SetProperty( Actor::Property::SIZE, Vector2( 200.0f, 100.f ) );
+  textEditor.SetProperty( TextEditor::Property::POINT_SIZE, 10) ;
+  textEditor.SetProperty( TextEditor::Property::FONT_FAMILY, "DejaVu Sans");
+
+  application.GetScene().Add( textEditor );
+  application.SendNotification();
+  application.Render();
+
+  Property::Map strikethroughMapSet;
+  Property::Map strikethroughMapGet;
+
+  strikethroughMapSet.Insert( "enable", true );
+  strikethroughMapSet.Insert( "color", Color::RED );
+  strikethroughMapSet.Insert( "height", 2.0f );
+
+  // Check the strikethrough property
+  textEditor.SetProperty( DevelTextEditor::Property::STRIKETHROUGH, strikethroughMapSet );
+  strikethroughMapGet = textEditor.GetProperty<Property::Map>( DevelTextEditor::Property::STRIKETHROUGH );
+  textEditor.SetProperty( TextEditor::Property::TEXT, "Test1" );
+  DALI_TEST_EQUALS( strikethroughMapGet.Count(), strikethroughMapSet.Count(), TEST_LOCATION );
+  DALI_TEST_EQUALS( DaliTestCheckMaps( strikethroughMapGet, strikethroughMapSet ), true, TEST_LOCATION );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  strikethroughMapSet.Clear();
+  strikethroughMapGet.Clear();
+
+  END_TEST;
+}
 
 int utcDaliTextEditorInsertCharacterAfterInitWithResizePolicyNaturalSize(void)
 {
@@ -5181,4 +5300,4 @@ int utcDaliTextEditorDoubleEnterAfterInitWithResizePolicyNaturalSize(void)
   application.Render();
 
   END_TEST;
-}
\ No newline at end of file
+}
index d1a04e9..b4e4c93 100644 (file)
@@ -95,6 +95,8 @@ const char* const PROPERTY_NAME_EMBOSS                               = "emboss";
 const char* const PROPERTY_NAME_INPUT_EMBOSS                         = "inputEmboss";
 const char* const PROPERTY_NAME_OUTLINE                              = "outline";
 const char* const PROPERTY_NAME_INPUT_OUTLINE                        = "inputOutline";
+const char* const PROPERTY_NAME_STRIKETHROUGH                        = "strikethrough";
+const char* const PROPERTY_NAME_INPUT_STRIKETHROUGH                  = "inputStrikethrough";
 
 const char* const PROPERTY_NAME_HIDDEN_INPUT_SETTINGS                = "hiddenInputSettings";
 const char* const PROPERTY_NAME_PIXEL_SIZE                           = "pixelSize";
@@ -577,6 +579,8 @@ int UtcDaliTextFieldGetPropertyP(void)
   DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_BACKGROUND ) == DevelTextField::Property::BACKGROUND );
   DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_GRAB_HANDLE_COLOR ) == DevelTextField::Property::GRAB_HANDLE_COLOR );
   DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_INPUT_FILTER ) == DevelTextField::Property::INPUT_FILTER );
+  DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_STRIKETHROUGH ) == DevelTextField::Property::STRIKETHROUGH );
+  DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_INPUT_STRIKETHROUGH ) == DevelTextField::Property::INPUT_STRIKETHROUGH );
 
   END_TEST;
 }
@@ -848,6 +852,24 @@ int UtcDaliTextFieldSetPropertyP(void)
   DALI_TEST_EQUALS( fontStyleMapGet.Count(), fontStyleMapSet.Count(), TEST_LOCATION );
   DALI_TEST_EQUALS( DaliTestCheckMaps( fontStyleMapGet, fontStyleMapSet ), true, TEST_LOCATION );
 
+  Property::Map strikethroughMapSet;
+  Property::Map strikethroughMapGet;
+
+  strikethroughMapSet.Insert( "enable", true );
+  strikethroughMapSet.Insert( "color", Color::RED );
+  strikethroughMapSet.Insert( "height", 2.0f );
+
+  // Check the strikethrough property
+  field.SetProperty( DevelTextField::Property::STRIKETHROUGH, strikethroughMapSet );
+
+  strikethroughMapGet = field.GetProperty<Property::Map>( DevelTextField::Property::STRIKETHROUGH );
+  DALI_TEST_EQUALS( strikethroughMapGet.Count(), strikethroughMapSet.Count(), TEST_LOCATION );
+  DALI_TEST_EQUALS( DaliTestCheckMaps( strikethroughMapGet, strikethroughMapSet ), true, TEST_LOCATION );
+
+  // Check the input strikethrough property
+  field.SetProperty( DevelTextField::Property::INPUT_STRIKETHROUGH, "Strikethrough input properties" );
+  DALI_TEST_EQUALS( field.GetProperty<std::string>( DevelTextField::Property::INPUT_STRIKETHROUGH ), std::string("Strikethrough input properties"), TEST_LOCATION );
+
   Property::Map underlineMapSet;
   Property::Map underlineMapGet;
 
@@ -2114,6 +2136,7 @@ int utcDaliTextFieldInputStyleChanged02(void)
   field.SetProperty( TextField::Property::INPUT_SHADOW, "shadow" );
   field.SetProperty( TextField::Property::INPUT_EMBOSS, "emboss" );
   field.SetProperty( TextField::Property::INPUT_OUTLINE, "outline" );
+  field.SetProperty( DevelTextField::Property::INPUT_STRIKETHROUGH, "strikethrough" );
 
   // Render and notify
   application.SendNotification();
@@ -4834,4 +4857,72 @@ int utcDaliTextFieldSelectionChangedSignal(void)
   DALI_TEST_EQUALS(oldSelectionEnd, 23, TEST_LOCATION);
 
   END_TEST;
-}
\ No newline at end of file
+}
+
+int UtcDaliToolkitTextFieldStrikethroughGeneration(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliToolkitTextFieldStrikethroughGeneration");
+
+  TextField textField = TextField::New();
+  textField.SetProperty( TextField::Property::TEXT, "Test" );
+  textField.SetProperty( Actor::Property::SIZE, Vector2( 200.0f, 100.f ) );
+  textField.SetProperty( TextField::Property::POINT_SIZE, 10) ;
+  textField.SetProperty( TextField::Property::FONT_FAMILY, "DejaVu Sans");
+
+  application.GetScene().Add( textField );
+  application.SendNotification();
+  application.Render();
+
+  Property::Map strikethroughMapSet;
+  Property::Map strikethroughMapGet;
+
+  strikethroughMapSet.Insert( "enable", true );
+  strikethroughMapSet.Insert( "color", Color::RED );
+  strikethroughMapSet.Insert( "height", 2.0f );
+
+  // Check the strikethrough property
+  textField.SetProperty( DevelTextField::Property::STRIKETHROUGH, strikethroughMapSet );
+  strikethroughMapGet = textField.GetProperty<Property::Map>( DevelTextField::Property::STRIKETHROUGH );
+  textField.SetProperty( TextField::Property::TEXT, "Test1" );
+  DALI_TEST_EQUALS( strikethroughMapGet.Count(), strikethroughMapSet.Count(), TEST_LOCATION );
+  DALI_TEST_EQUALS( DaliTestCheckMaps( strikethroughMapGet, strikethroughMapSet ), true, TEST_LOCATION );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  strikethroughMapSet.Clear();
+  strikethroughMapGet.Clear();
+
+  END_TEST;
+}
+
+int UtcDaliToolkitTextFieldInputStrikethroughGeneration(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliToolkitTextFieldInputStrikethroughGeneration");
+
+  TextField textField = TextField::New();
+  textField.SetProperty( TextField::Property::TEXT, "Test" );
+  textField.SetProperty( Actor::Property::SIZE, Vector2( 200.0f, 100.f ) );
+  textField.SetProperty( TextField::Property::POINT_SIZE, 10) ;
+  textField.SetProperty( TextField::Property::FONT_FAMILY, "DejaVu Sans");
+
+  application.GetScene().Add( textField );
+  application.SendNotification();
+  application.Render();
+
+  std::string strikethroughSettings1( "{\"enable\":\"true\",\"color\":\"red\",\"height\":\"2\"}" );
+
+  // Check the strikethrough property
+  textField.SetProperty( DevelTextField::Property::INPUT_STRIKETHROUGH, strikethroughSettings1 );
+  textField.SetProperty( TextField::Property::TEXT, "Test1" );
+  DALI_TEST_EQUALS( textField.GetProperty<std::string>( DevelTextField::Property::INPUT_STRIKETHROUGH ), strikethroughSettings1, TEST_LOCATION );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  END_TEST;
+}
index c060743..5f27aeb 100644 (file)
@@ -69,6 +69,7 @@ const char* const PROPERTY_NAME_SHADOW = "shadow";
 const char* const PROPERTY_NAME_EMBOSS = "emboss";
 const char* const PROPERTY_NAME_OUTLINE = "outline";
 const char* const PROPERTY_NAME_BACKGROUND = "textBackground";
+const char* const PROPERTY_NAME_STRIKETHROUGH = "strikethrough";
 
 const char* const PROPERTY_NAME_PIXEL_SIZE = "pixelSize";
 const char* const PROPERTY_NAME_ELLIPSIS = "ellipsis";
@@ -353,6 +354,7 @@ int UtcDaliToolkitTextLabelGetPropertyP(void)
   DALI_TEST_CHECK( label.GetPropertyIndex( PROPERTY_NAME_AUTO_SCROLL_LOOP_DELAY ) == TextLabel::Property::AUTO_SCROLL_LOOP_DELAY );
   DALI_TEST_CHECK( label.GetPropertyIndex( PROPERTY_NAME_FONT_SIZE_SCALE ) == DevelTextLabel::Property::FONT_SIZE_SCALE );
   DALI_TEST_CHECK( label.GetPropertyIndex( PROPERTY_NAME_ELLIPSIS_POSITION ) == DevelTextLabel::Property::ELLIPSIS_POSITION );
+  DALI_TEST_CHECK( label.GetPropertyIndex( PROPERTY_NAME_STRIKETHROUGH ) == DevelTextLabel::Property::STRIKETHROUGH );
 
   END_TEST;
 }
@@ -457,6 +459,19 @@ int UtcDaliToolkitTextLabelSetPropertyP(void)
   label.SetProperty( TextLabel::Property::TEXT_COLOR, Color::BLUE );
   DALI_TEST_EQUALS( label.GetProperty<Vector4>( TextLabel::Property::TEXT_COLOR ), Color::BLUE, TEST_LOCATION );
 
+  Property::Map strikethroughMapSet;
+  Property::Map strikethroughMapGet;
+
+  strikethroughMapSet.Insert( "enable", false );
+  strikethroughMapSet.Insert( "color", Color::BLUE );
+  strikethroughMapSet.Insert( "height", 2.0f );
+
+  label.SetProperty( DevelTextLabel::Property::STRIKETHROUGH, strikethroughMapSet );
+
+  strikethroughMapGet = label.GetProperty<Property::Map>( DevelTextLabel::Property::STRIKETHROUGH );
+  DALI_TEST_EQUALS( strikethroughMapGet.Count(), strikethroughMapSet.Count(), TEST_LOCATION );
+  DALI_TEST_EQUALS( DaliTestCheckMaps( strikethroughMapGet, strikethroughMapSet ), true, TEST_LOCATION );
+
   Property::Map underlineMapSet;
   Property::Map underlineMapGet;
 
@@ -561,6 +576,52 @@ int UtcDaliToolkitTextLabelSetPropertyP(void)
   label.SetProperty( TextLabel::Property::LINE_SPACING, 10.f );
   DALI_TEST_EQUALS( label.GetProperty<float>( TextLabel::Property::LINE_SPACING ), 10.0f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
 
+  // Check the strikethrough property
+  strikethroughMapSet.Clear();
+  strikethroughMapSet.Insert( "enable", true );
+  strikethroughMapSet.Insert( "color", Color::RED );
+  strikethroughMapSet.Insert( "height", 2.0f );
+
+  label.SetProperty( DevelTextLabel::Property::STRIKETHROUGH, strikethroughMapSet );
+
+  application.SendNotification();
+  application.Render();
+
+  strikethroughMapGet = label.GetProperty<Property::Map>( DevelTextLabel::Property::STRIKETHROUGH );
+  DALI_TEST_EQUALS( strikethroughMapGet.Count(), strikethroughMapSet.Count(), TEST_LOCATION );
+  DALI_TEST_EQUALS( DaliTestCheckMaps( strikethroughMapGet, strikethroughMapSet ), true, TEST_LOCATION );
+
+  strikethroughMapSet.Clear();
+  strikethroughMapSet.Insert( Toolkit::DevelText::Strikethrough::Property::ENABLE, true );
+  strikethroughMapSet.Insert( Toolkit::DevelText::Strikethrough::Property::COLOR, Color::RED );
+  strikethroughMapSet.Insert( Toolkit::DevelText::Strikethrough::Property::HEIGHT, 2.0f );
+
+  label.SetProperty( DevelTextLabel::Property::STRIKETHROUGH, strikethroughMapSet );
+
+  application.SendNotification();
+  application.Render();
+
+  strikethroughMapGet = label.GetProperty<Property::Map>( DevelTextLabel::Property::STRIKETHROUGH );
+  DALI_TEST_EQUALS( strikethroughMapGet.Count(), strikethroughMapSet.Count(), TEST_LOCATION );
+  std::vector<std::string> strikethroughIndicesConversionTable = { "enable", "color","height"};
+  DALI_TEST_EQUALS( DaliTestCheckMaps( strikethroughMapGet, strikethroughMapSet, strikethroughIndicesConversionTable ), true, TEST_LOCATION );
+
+  strikethroughMapSet.Clear();
+
+  Property::Map strikethroughDisabledMapGet;
+  strikethroughDisabledMapGet.Insert( "enable", false );
+  strikethroughDisabledMapGet.Insert( "color", Color::RED );
+  strikethroughDisabledMapGet.Insert( "height", 2.0f );
+
+  label.SetProperty( DevelTextLabel::Property::STRIKETHROUGH, strikethroughMapSet );
+
+  application.SendNotification();
+  application.Render();
+
+  strikethroughMapGet = label.GetProperty<Property::Map>( DevelTextLabel::Property::STRIKETHROUGH );
+  DALI_TEST_EQUALS( strikethroughMapGet.Count(), strikethroughDisabledMapGet.Count(), TEST_LOCATION );
+  DALI_TEST_EQUALS( DaliTestCheckMaps( strikethroughMapGet, strikethroughDisabledMapGet ), true, TEST_LOCATION );
+
   // Check the underline property
   underlineMapSet.Clear();
   underlineMapSet.Insert( "enable", true );
@@ -758,6 +819,12 @@ int UtcDaliToolkitTextlabelAtlasRenderP(void)
   shadowMap.Insert( "offset", Vector2( 1.0f, 1.0f ) );
   label.SetProperty( TextLabel::Property::SHADOW, shadowMap );
 
+  Property::Map strikethroughMap;
+  strikethroughMap.Insert( "enable", true );
+  strikethroughMap.Insert( "color", Color::GREEN );
+  strikethroughMap.Insert( "height", 2.0f );
+  label.SetProperty( DevelTextLabel::Property::STRIKETHROUGH, strikethroughMap );
+
   try
   {
     // Render some text with the shared atlas backend
@@ -1749,6 +1816,14 @@ int UtcDaliToolkitTextlabelMaxTextureSet(void)
   label.SetProperty( TextLabel::Property::UNDERLINE, underlineMapSet );
   label.SetProperty( Toolkit::TextLabel::Property::TEXT_COLOR, Color::BLUE );
 
+  Property::Map strikethroughMapSet;
+  strikethroughMapSet.Clear();
+  strikethroughMapSet.Insert( "enable", true );
+  strikethroughMapSet.Insert( "color", Color::RED );
+  strikethroughMapSet.Insert( "height", 2.0f );
+  label.SetProperty( DevelTextLabel::Property::STRIKETHROUGH, strikethroughMapSet );
+  label.SetProperty( Toolkit::TextLabel::Property::TEXT_COLOR, Color::BLUE );
+
   application.GetScene().Add( label );
 
   application.SendNotification();
@@ -1764,6 +1839,68 @@ int UtcDaliToolkitTextlabelMaxTextureSet(void)
   END_TEST;
 }
 
+int UtcDaliToolkitTextlabelStrikethroughExceedsWidthAndHeight(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliToolkitTextlabelStrikethroughExceedsWidthAndHeight");
+
+  TextLabel label = TextLabel::New();
+  label.SetProperty( TextLabel::Property::TEXT, "Test" );
+  label.SetProperty( TextLabel::Property::FONT_FAMILY, "DejaVu Sans");
+
+  //Exeeding BufferWidth
+  label.SetProperty(Actor::Property::SIZE, Vector2(200.f, 400.0f));
+  label.SetProperty(TextLabel::Property::HORIZONTAL_ALIGNMENT, HorizontalAlignment::RIGHT);
+  label.SetProperty(TextLabel::Property::POINT_SIZE, 200.f);
+
+  application.GetScene().Add( label );
+  application.SendNotification();
+  application.Render();
+
+  Property::Map strikethroughMapSet;
+  strikethroughMapSet.Clear();
+  strikethroughMapSet.Insert( "enable", true );
+  strikethroughMapSet.Insert( "color", Color::BLUE);
+  strikethroughMapSet.Insert( "height", 2.0f);
+  label.SetProperty( TextLabel::Property::TEXT, "Test1" );
+  label.SetProperty( DevelTextLabel::Property::STRIKETHROUGH, strikethroughMapSet );
+  label.SetProperty( Toolkit::TextLabel::Property::TEXT_COLOR, Color::BLUE );
+  application.GetScene().Add( label );
+  application.SendNotification();
+  application.Render();
+  // Check if the number of renderers is 1.
+  DALI_TEST_EQUALS( 1, label.GetRendererCount(), TEST_LOCATION);
+
+
+  label = TextLabel::New();
+  label.SetProperty( TextLabel::Property::TEXT, "Test" );
+  label.SetProperty( TextLabel::Property::FONT_FAMILY, "DejaVu Sans");
+
+  //Exeeding BufferHeight
+  label.SetProperty(Actor::Property::SIZE, Vector2(200.f, 100.0f));
+  label.SetProperty(TextLabel::Property::HORIZONTAL_ALIGNMENT, HorizontalAlignment::RIGHT);
+  label.SetProperty(TextLabel::Property::POINT_SIZE, 200.f);
+
+  application.GetScene().Add( label );
+  application.SendNotification();
+  application.Render();
+
+  strikethroughMapSet.Clear();
+  strikethroughMapSet.Insert( "enable", true );
+  strikethroughMapSet.Insert( "color", Color::BLUE);
+  strikethroughMapSet.Insert( "height", 2.0f);
+  label.SetProperty( TextLabel::Property::TEXT, "Test2" );
+  label.SetProperty( DevelTextLabel::Property::STRIKETHROUGH, strikethroughMapSet );
+  label.SetProperty( Toolkit::TextLabel::Property::TEXT_COLOR, Color::BLUE );
+  application.GetScene().Add( label );
+  application.SendNotification();
+  application.Render();
+  // Check if the number of renderers is 1.
+  DALI_TEST_EQUALS( 1, label.GetRendererCount(), TEST_LOCATION);
+
+  END_TEST;
+}
+
 int UtcDaliToolkitTextlabelLastCharacterIndex(void)
 {
   ToolkitTestApplication application;
@@ -1974,7 +2111,6 @@ int UtcDaliTextLabelHyphenWrapMode(void)
   END_TEST;
 }
 
-
 int utcDaliTextLabelGetHeightForWidthChangeLineCountWhenTextChanged(void)
 {
   ToolkitTestApplication application;
@@ -2178,3 +2314,42 @@ int UtcDaliToolkitTextlabelEllipsisPositionProperty(void)
 
   END_TEST;
 }
+
+int UtcDaliToolkitTextLabelStrikethroughGeneration(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliToolkitTextLabelStrikethroughGeneration");
+
+  TextLabel textLabel = TextLabel::New();
+  textLabel.SetProperty( TextLabel::Property::TEXT, "Test" );
+  textLabel.SetProperty( Actor::Property::SIZE, Vector2( 200.0f, 100.f ) );
+  textLabel.SetProperty( TextLabel::Property::POINT_SIZE, 10) ;
+  textLabel.SetProperty( TextLabel::Property::FONT_FAMILY, "DejaVu Sans");
+
+  application.GetScene().Add( textLabel );
+  application.SendNotification();
+  application.Render();
+
+  Property::Map strikethroughMapSet;
+  Property::Map strikethroughMapGet;
+
+  strikethroughMapSet.Insert( "enable", true );
+  strikethroughMapSet.Insert( "color", Color::RED );
+  strikethroughMapSet.Insert( "height", 2.0f );
+
+  // Check the strikethrough property
+  textLabel.SetProperty( DevelTextLabel::Property::STRIKETHROUGH, strikethroughMapSet );
+  strikethroughMapGet = textLabel.GetProperty<Property::Map>( DevelTextLabel::Property::STRIKETHROUGH );
+  textLabel.SetProperty( TextLabel::Property::TEXT, "Test1" );
+  DALI_TEST_EQUALS( strikethroughMapGet.Count(), strikethroughMapSet.Count(), TEST_LOCATION );
+  DALI_TEST_EQUALS( DaliTestCheckMaps( strikethroughMapGet, strikethroughMapSet ), true, TEST_LOCATION );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  strikethroughMapSet.Clear();
+  strikethroughMapGet.Clear();
+
+  END_TEST;
+}
\ No newline at end of file
index 74c19df..94663ae 100644 (file)
@@ -274,6 +274,18 @@ enum Type
    * @note If the font size is larger than the line size, it works with the font size.
    */
   MIN_LINE_SIZE,
+
+  /**
+   * @brief A horizontal line through the text center.
+   * @details Name "strikethrough", type Property::MAP.
+   */
+  STRIKETHROUGH,
+
+  /**
+   * @brief The strikethrough parameters of the new input text.
+   * @details Name "inputStrikethrough", type Property::MAP.
+   */
+  INPUT_STRIKETHROUGH,
 };
 
 } // namespace Property
index 7498110..938bf5c 100644 (file)
@@ -213,6 +213,18 @@ enum
   * @see DevelText::EllipsisPosition
   */
   ELLIPSIS_POSITION,
+
+  /**
+   * @brief A horizontal line through the text center.
+   * @details Name "strikethrough", type Property::MAP.
+   */
+  STRIKETHROUGH,
+
+  /**
+   * @brief The strikethrough parameters of the new input text.
+   * @details Name "inputStrikethrough", type Property::MAP.
+   */
+  INPUT_STRIKETHROUGH,
 };
 
 } // namespace Property
index 17a808f..b64338f 100644 (file)
@@ -162,6 +162,21 @@ enum Type
   * @see DevelText::EllipsisPosition
   */
   ELLIPSIS_POSITION,
+
+  /**
+   * @brief The default strikethrough parameters.
+   * @details Name "strikethrough", type Property::MAP.
+   *
+   * The strikethrough map contains the following keys:
+   *
+   * | %Property Name       | Type     | Required | Description                                                                                                        |
+   * |----------------------|----------|----------|--------------------------------------------------------------------------------------------------------------------|
+   * | enable               | BOOLEAN  | No       | True to enable the strikethrough or false to disable (the default value is false)                                  |
+   * | color                | VECTOR4  | No       | The color of the strikethrough (the default value is Color::BLACK)                                                 |
+   * | height               | FLOAT    | No       | The height of the strikethrough (the default value is 0)                                                               |
+   *
+   */
+  STRIKETHROUGH,
 };
 
 } // namespace Property
index bd6450c..6b6f3ab 100644 (file)
@@ -147,6 +147,38 @@ enum
 
 } // namespace Background
 
+namespace Strikethrough
+{
+namespace Property
+{
+enum
+{
+  /**
+   * @brief Whether the strikethrough is enabled.
+   * @details Name "enable", type Property::STRING or Property::BOOLEAN. i.e. "true", "false", true or false
+   * @note Optional. By default is disabled.
+   */
+  ENABLE,
+
+  /**
+   * @brief The color of the strikethrough.
+   * @details Name "color", type Property::STRING or Property::VECTOR4
+   * @note Optional. If not provided then the default color is black.
+   */
+  COLOR,
+
+  /**
+   * @brief The height in pixels of the strikethrough.
+   * @details Name "height", type Property::STRING or Property::FLOAT. i.e. "1.0" or 1.f
+   * @note Optional. If not provided then the default height is used (1 pixel).
+   */
+  HEIGHT
+};
+
+} // namespace Property
+
+} // namespace Strikethrough
+
 } // namespace DevelText
 
 /**
index 062094f..a8c79d6 100644 (file)
@@ -56,6 +56,11 @@ enum
    * @copydoc Dali::Toolkit::DevelTextLabel::Property::BACKGROUND
    */
   BACKGROUND = UNDERLINE + 2,
+
+  /**
+   * @copydoc Dali::Toolkit::DevelTextLabel::Property::STRIKETHROUGH
+   */
+  STRIKETHROUGH = UNDERLINE + 3,
 };
 
 } // namespace Property
index 5e9e7d9..a43195b 100644 (file)
@@ -154,6 +154,8 @@ DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextEditor, "inputFilter",
 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextEditor, "ellipsis",                             BOOLEAN,   ELLIPSIS                            )
 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextEditor, "ellipsisPosition",                     INTEGER,   ELLIPSIS_POSITION                   )
 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextEditor, "minLineSize",                          FLOAT,     MIN_LINE_SIZE                       )
+DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextEditor, "strikethrough",                        MAP,       STRIKETHROUGH                       )
+DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextEditor, "inputStrikethrough",                   MAP,       INPUT_STRIKETHROUGH                 )
 
 DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "textChanged",           SIGNAL_TEXT_CHANGED           )
 DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "inputStyleChanged",     SIGNAL_INPUT_STYLE_CHANGED    )
@@ -215,6 +217,11 @@ Toolkit::TextEditor::InputStyle::Mask ConvertInputStyle(Text::InputStyle::Mask i
   {
     editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>(editorInputStyleMask | Toolkit::TextEditor::InputStyle::OUTLINE);
   }
+  if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_STRIKETHROUGH))
+  {
+    editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>(editorInputStyleMask | Toolkit::TextEditor::InputStyle::STRIKETHROUGH);
+  }
+
   return editorInputStyleMask;
 }
 
index f35c169..5b6950f 100644 (file)
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#include <dali-toolkit/internal/controls/text-controls/text-editor-property-handler.h>
 #include <dali-toolkit/internal/controls/text-controls/common-text-utils.h>
+#include <dali-toolkit/internal/controls/text-controls/text-editor-property-handler.h>
 
 #include <dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h>
 
@@ -689,6 +689,24 @@ void TextEditor::PropertyHandler::SetProperty(Toolkit::TextEditor textEditor, Pr
       impl.mRenderer.Reset();
       break;
     }
+    case Toolkit::DevelTextEditor::Property::STRIKETHROUGH:
+    {
+      const bool update = SetStrikethroughProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
+      if(update)
+      {
+        impl.mRenderer.Reset();
+      }
+      break;
+    }
+    case Toolkit::DevelTextEditor::Property::INPUT_STRIKETHROUGH:
+    {
+      const bool update = SetStrikethroughProperties(impl.mController, value, Text::EffectStyle::INPUT);
+      if(update)
+      {
+        impl.mRenderer.Reset();
+      }
+      break;
+    }
   }
 }
 
@@ -975,6 +993,16 @@ Property::Value TextEditor::PropertyHandler::GetProperty(Toolkit::TextEditor tex
       value = impl.mController->GetLineWrapMode();
       break;
     }
+    case Toolkit::DevelTextEditor::Property::STRIKETHROUGH:
+    {
+      GetStrikethroughProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
+      break;
+    }
+    case Toolkit::DevelTextEditor::Property::INPUT_STRIKETHROUGH:
+    {
+      GetStrikethroughProperties(impl.mController, value, Text::EffectStyle::INPUT);
+      break;
+    }
     case Toolkit::DevelTextEditor::Property::ENABLE_SHIFT_SELECTION:
     {
       value = impl.mController->IsShiftSelectionEnabled();
index 9cefc6c..cb820b1 100644 (file)
@@ -141,6 +141,8 @@ DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextField, "primaryCursorPos
 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextField, "grabHandleColor",                  VECTOR4,   GRAB_HANDLE_COLOR                   )
 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextField, "inputFilter",                      MAP,       INPUT_FILTER                        )
 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextField, "ellipsisPosition",                 INTEGER,   ELLIPSIS_POSITION                   )
+DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextField, "strikethrough",                    MAP,       STRIKETHROUGH                       )
+DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextField, "inputStrikethrough",               MAP,       INPUT_STRIKETHROUGH                 )
 
 DALI_SIGNAL_REGISTRATION(Toolkit, TextField, "textChanged",           SIGNAL_TEXT_CHANGED           )
 DALI_SIGNAL_REGISTRATION(Toolkit, TextField, "maxLengthReached",      SIGNAL_MAX_LENGTH_REACHED     )
index dc253f0..40b3504 100644 (file)
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#include <dali-toolkit/internal/controls/text-controls/text-field-property-handler.h>
 #include <dali-toolkit/internal/controls/text-controls/common-text-utils.h>
+#include <dali-toolkit/internal/controls/text-controls/text-field-property-handler.h>
 
 #include <dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h>
 #include <dali-toolkit/devel-api/text/rendering-backend.h>
@@ -665,6 +665,24 @@ void TextField::PropertyHandler::SetProperty(Toolkit::TextField textField, Prope
       }
       break;
     }
+    case Toolkit::DevelTextField::Property::STRIKETHROUGH:
+    {
+      const bool update = SetStrikethroughProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
+      if(update)
+      {
+        impl.mRenderer.Reset();
+      }
+      break;
+    }
+    case Toolkit::DevelTextField::Property::INPUT_STRIKETHROUGH:
+    {
+      const bool update = SetStrikethroughProperties(impl.mController, value, Text::EffectStyle::INPUT);
+      if(update)
+      {
+        impl.mRenderer.Reset();
+      }
+      break;
+    }
   }
 }
 
@@ -1025,6 +1043,16 @@ Property::Value TextField::PropertyHandler::GetProperty(Toolkit::TextField textF
       value = impl.mController->GetEllipsisPosition();
       break;
     }
+    case Toolkit::DevelTextField::Property::STRIKETHROUGH:
+    {
+      GetStrikethroughProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
+      break;
+    }
+    case Toolkit::DevelTextField::Property::INPUT_STRIKETHROUGH:
+    {
+      GetStrikethroughProperties(impl.mController, value, Text::EffectStyle::INPUT);
+      break;
+    }
   } //switch
   return value;
 }
index 9e15b34..d1cde22 100644 (file)
@@ -137,6 +137,7 @@ DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextLabel, "minLineSize",
 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextLabel, "renderingBackend",             INTEGER, RENDERING_BACKEND              )
 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextLabel, "fontSizeScale",                FLOAT,   FONT_SIZE_SCALE                )
 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextLabel, "ellipsisPosition",             INTEGER, ELLIPSIS_POSITION              )
+DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextLabel, "strikethrough",                MAP,     STRIKETHROUGH                  )
 
 DALI_ANIMATABLE_PROPERTY_REGISTRATION_WITH_DEFAULT(Toolkit, TextLabel, "textColor",      Color::BLACK,     TEXT_COLOR   )
 DALI_ANIMATABLE_PROPERTY_COMPONENT_REGISTRATION(Toolkit,    TextLabel, "textColorRed",   TEXT_COLOR_RED,   TEXT_COLOR, 0)
@@ -518,6 +519,11 @@ void TextLabel::SetProperty(BaseObject* object, Property::Index index, const Pro
         }
         break;
       }
+      case Toolkit::DevelTextLabel::Property::STRIKETHROUGH:
+      {
+        impl.mTextUpdateNeeded = SetStrikethroughProperties(impl.mController, value, Text::EffectStyle::DEFAULT) || impl.mTextUpdateNeeded;
+        break;
+      }
     }
 
     // Request relayout when text update is needed. It's necessary to call it
@@ -761,6 +767,11 @@ Property::Value TextLabel::GetProperty(BaseObject* object, Property::Index index
         value = impl.mController->GetEllipsisPosition();
         break;
       }
+      case Toolkit::DevelTextLabel::Property::STRIKETHROUGH:
+      {
+        GetStrikethroughProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
+        break;
+      }
     }
   }
 
index d8506cb..ca42ca6 100644 (file)
@@ -1,6 +1,7 @@
 varying mediump vec2 vTexCoord;
 uniform sampler2D sTexture;
 uniform sampler2D sStyle;
+uniform sampler2D sOverlayStyle;
 uniform lowp vec4 uColor;
 uniform lowp vec3 mixColor;
 
@@ -8,7 +9,8 @@ void main()
 {
   mediump vec4 textTexture = texture2D( sTexture, vTexCoord );
   mediump vec4 styleTexture = texture2D( sStyle, vTexCoord );
+  mediump vec4 overlayStyleTexture = texture2D( sOverlayStyle, vTexCoord );
 
   // Draw the text as overlay above the style
-  gl_FragColor = ( textTexture + styleTexture * ( 1.0 - textTexture.a ) ) * uColor * vec4( mixColor, 1.0 );
+  gl_FragColor = ( overlayStyleTexture + textTexture * (1.0 - overlayStyleTexture.a) + styleTexture * ( 1.0 - textTexture.a ) * (1.0 - overlayStyleTexture.a) ) * uColor * vec4( mixColor, 1.0 );
 }
index b892a17..0d82aa7 100644 (file)
@@ -1,6 +1,7 @@
 varying mediump vec2 vTexCoord;
 uniform sampler2D sTexture;
 uniform sampler2D sStyle;
+uniform sampler2D sOverlayStyle;
 uniform sampler2D sMask;
 uniform lowp float uHasMultipleTextColors;
 uniform lowp vec4 uTextColorAnimatable;
@@ -11,6 +12,7 @@ void main()
 {
   mediump vec4 textTexture = texture2D( sTexture, vTexCoord );
   mediump vec4 styleTexture = texture2D( sStyle, vTexCoord );
+  mediump vec4 overlayStyleTexture = texture2D( sOverlayStyle, vTexCoord );
   mediump float maskTexture = texture2D( sMask, vTexCoord ).r;
 
   // Set the color of non-transparent pixel in text to what it is animated to.
@@ -20,5 +22,5 @@ void main()
   textTexture.rgb = mix( textTexture.rgb, uTextColorAnimatable.rgb, vstep * maskTexture * ( 1.0 - uHasMultipleTextColors ) );
 
   // Draw the text as overlay above the style
-  gl_FragColor = ( textTexture + styleTexture * ( 1.0 - textTexture.a ) ) * uColor * vec4( mixColor, 1.0 );
+  gl_FragColor = ( overlayStyleTexture + textTexture * (1.0 - overlayStyleTexture.a) + styleTexture * ( 1.0 - textTexture.a ) * (1.0 - overlayStyleTexture.a) ) * uColor * vec4( mixColor, 1.0 );
 }
index f5d8b1c..cf93f15 100644 (file)
@@ -1,6 +1,7 @@
 varying mediump vec2 vTexCoord;
 uniform sampler2D sTexture;
 uniform sampler2D sStyle;
+uniform sampler2D sOverlayStyle;
 uniform lowp vec4 uTextColorAnimatable;
 uniform lowp vec4 uColor;
 uniform lowp vec3 mixColor;
@@ -9,7 +10,8 @@ void main()
 {
   mediump float textTexture = texture2D( sTexture, vTexCoord ).r;
   mediump vec4 styleTexture = texture2D( sStyle, vTexCoord );
+  mediump vec4 overlayStyleTexture = texture2D( sOverlayStyle, vTexCoord );
 
   // Draw the text as overlay above the style
-  gl_FragColor = ( uTextColorAnimatable * textTexture + styleTexture * ( 1.0 - uTextColorAnimatable.a * textTexture ) ) * uColor * vec4( mixColor, 1.0 );
-}
+  gl_FragColor = ( overlayStyleTexture + uTextColorAnimatable * textTexture * (1.0 - overlayStyleTexture.a) + styleTexture * ( 1.0 - uTextColorAnimatable.a * textTexture ) * (1.0 - overlayStyleTexture.a) ) * uColor * vec4( mixColor, 1.0 );
+}
\ No newline at end of file
index de3a1f2..fed87e8 100644 (file)
@@ -37,18 +37,19 @@ struct InputStyle
 {
   enum Mask
   {
-    NONE               = 0x0000,
-    INPUT_COLOR        = 0x0001,
-    INPUT_FONT_FAMILY  = 0x0002,
-    INPUT_POINT_SIZE   = 0x0004,
-    INPUT_FONT_WEIGHT  = 0x0008,
-    INPUT_FONT_WIDTH   = 0x0010,
-    INPUT_FONT_SLANT   = 0x0020,
-    INPUT_LINE_SPACING = 0x0040,
-    INPUT_UNDERLINE    = 0x0080,
-    INPUT_SHADOW       = 0x0100,
-    INPUT_EMBOSS       = 0x0200,
-    INPUT_OUTLINE      = 0x0400
+    NONE                = 0x0000,
+    INPUT_COLOR         = 0x0001,
+    INPUT_FONT_FAMILY   = 0x0002,
+    INPUT_POINT_SIZE    = 0x0004,
+    INPUT_FONT_WEIGHT   = 0x0008,
+    INPUT_FONT_WIDTH    = 0x0010,
+    INPUT_FONT_SLANT    = 0x0020,
+    INPUT_LINE_SPACING  = 0x0040,
+    INPUT_UNDERLINE     = 0x0080,
+    INPUT_SHADOW        = 0x0100,
+    INPUT_EMBOSS        = 0x0200,
+    INPUT_OUTLINE       = 0x0400,
+    INPUT_STRIKETHROUGH = 0x0800
   };
 
   InputStyle()
@@ -63,6 +64,7 @@ struct InputStyle
     shadowProperties(),
     embossProperties(),
     outlineProperties(),
+    strikethroughProperties(),
     isDefaultColor(true),
     isFamilyDefined(false),
     isWeightDefined(false),
@@ -73,7 +75,8 @@ struct InputStyle
     isUnderlineDefined(false),
     isShadowDefined(false),
     isEmbossDefined(false),
-    isOutlineDefined(false)
+    isOutlineDefined(false),
+    isStrikethroughDefined(false)
   {
   }
 
@@ -118,6 +121,9 @@ struct InputStyle
 
     isOutlineDefined  = inputStyle.isOutlineDefined;
     outlineProperties = inputStyle.outlineProperties;
+
+    isStrikethroughDefined  = inputStyle.isStrikethroughDefined;
+    strikethroughProperties = inputStyle.strikethroughProperties;
   }
 
   /**
@@ -148,7 +154,8 @@ struct InputStyle
        (underlineProperties != inputStyle.underlineProperties) ||
        (shadowProperties != inputStyle.shadowProperties) ||
        (embossProperties != inputStyle.embossProperties) ||
-       (outlineProperties != inputStyle.outlineProperties))
+       (outlineProperties != inputStyle.outlineProperties) ||
+       (isStrikethroughDefined != inputStyle.isStrikethroughDefined))
     {
       return false;
     }
@@ -204,6 +211,10 @@ struct InputStyle
     {
       mask = static_cast<Mask>(mask | INPUT_OUTLINE);
     }
+    if(strikethroughProperties != inputStyle.strikethroughProperties)
+    {
+      mask = static_cast<Mask>(mask | INPUT_STRIKETHROUGH);
+    }
 
     return mask;
   }
@@ -217,10 +228,11 @@ struct InputStyle
 
   float lineSpacing; ///< The line's spacing.
 
-  std::string underlineProperties; ///< The underline properties string.
-  std::string shadowProperties;    ///< The shadow properties string.
-  std::string embossProperties;    ///< The emboss properties string.
-  std::string outlineProperties;   ///< The outline properties string.
+  std::string underlineProperties;     ///< The underline properties string.
+  std::string shadowProperties;        ///< The shadow properties string.
+  std::string embossProperties;        ///< The emboss properties string.
+  std::string outlineProperties;       ///< The outline properties string.
+  std::string strikethroughProperties; ///< The strikethrough properties string.
 
   bool isDefaultColor : 1;  ///< Whether the text's color is the default.
   bool isFamilyDefined : 1; ///< Whether the font's family is defined.
@@ -229,11 +241,12 @@ struct InputStyle
   bool isSlantDefined : 1;  ///< Whether the font's slant is defined.
   bool isSizeDefined : 1;   ///< Whether the font's size is defined.
 
-  bool isLineSpacingDefined : 1; ///< Whether the line spacing is defined.
-  bool isUnderlineDefined : 1;   ///< Whether the underline parameters are defined.
-  bool isShadowDefined : 1;      ///< Whether the shadow parameters are defined.
-  bool isEmbossDefined : 1;      ///< Whether the emboss parameters are defined.
-  bool isOutlineDefined : 1;     ///< Whether the outline parameters are defined.
+  bool isLineSpacingDefined : 1;   ///< Whether the line spacing is defined.
+  bool isUnderlineDefined : 1;     ///< Whether the underline parameters are defined.
+  bool isShadowDefined : 1;        ///< Whether the shadow parameters are defined.
+  bool isEmbossDefined : 1;        ///< Whether the emboss parameters are defined.
+  bool isOutlineDefined : 1;       ///< Whether the outline parameters are defined.
+  bool isStrikethroughDefined : 1; ///< Whether the strikethrough parameters are defined.
 };
 
 } // namespace Text
index ef80844..626ce33 100644 (file)
@@ -70,7 +70,7 @@ struct AtlasRenderer::Impl
   };
 
   /**
-   * brief Struct used to generate the underline mesh.
+   * brief Struct used to generate the underline/striketthrough mesh.
    * There is one Extent per line of text.
    */
   struct Extent
@@ -80,9 +80,10 @@ struct AtlasRenderer::Impl
       mLeft(0.0f),
       mRight(0.0f),
       mUnderlinePosition(0.0f),
-      mUnderlineThickness(0.0f),
+      mLineThickness(0.0f),
       mMeshRecordIndex(0u),
-      mUnderlineChunkId(0u)
+      mUnderlineChunkId(0u),
+      mStrikethroughPosition(0.0f)
     {
     }
 
@@ -90,9 +91,10 @@ struct AtlasRenderer::Impl
     float    mLeft;
     float    mRight;
     float    mUnderlinePosition;
-    float    mUnderlineThickness;
+    float    mLineThickness;
     uint32_t mMeshRecordIndex;
     uint32_t mUnderlineChunkId;
+    float    mStrikethroughPosition;
   };
 
   struct MaxBlockSize
@@ -283,27 +285,31 @@ struct AtlasRenderer::Impl
                     const Vector4&           color,
                     uint16_t                 outline,
                     AtlasManager::AtlasSlot& slot,
-                    bool                     underlineGlyph,
+                    bool                     decorationlineGlyph,
                     float                    currentUnderlinePosition,
-                    float                    currentUnderlineThickness,
+                    float                    currentlineThickness,
                     std::vector<MeshRecord>& meshContainer,
                     Vector<TextCacheEntry>&  newTextCache,
                     Vector<Extent>&          extents,
-                    uint32_t                 underlineChunkId)
+                    uint32_t                 underlineChunkId,
+                    bool                     isGlyphCached)
   {
     // Generate mesh data for this quad, plugging in our supplied position
     AtlasManager::Mesh2D newMesh;
     mGlyphManager.GenerateMeshData(slot.mImageId, position, newMesh);
 
-    TextCacheEntry textCacheEntry;
-    textCacheEntry.mFontId       = glyph.fontId;
-    textCacheEntry.mImageId      = slot.mImageId;
-    textCacheEntry.mIndex        = glyph.index;
-    textCacheEntry.mOutlineWidth = outline;
-    textCacheEntry.isItalic      = glyph.isItalicRequired;
-    textCacheEntry.isBold        = glyph.isBoldRequired;
-
-    newTextCache.PushBack(textCacheEntry);
+    if(!isGlyphCached)
+    {
+      TextCacheEntry textCacheEntry;
+      textCacheEntry.mFontId       = glyph.fontId;
+      textCacheEntry.mImageId      = slot.mImageId;
+      textCacheEntry.mIndex        = glyph.index;
+      textCacheEntry.mOutlineWidth = outline;
+      textCacheEntry.isItalic      = glyph.isItalicRequired;
+      textCacheEntry.isBold        = glyph.isBoldRequired;
+
+      newTextCache.PushBack(textCacheEntry);
+    }
 
     AtlasManager::Vertex2D* verticesBuffer = newMesh.mVertices.Begin();
 
@@ -322,11 +328,12 @@ struct AtlasRenderer::Impl
                    newMesh,
                    extents,
                    position.y + glyph.yBearing,
-                   underlineGlyph,
+                   decorationlineGlyph,
                    currentUnderlinePosition,
-                   currentUnderlineThickness,
+                   currentlineThickness,
                    slot,
-                   underlineChunkId);
+                   underlineChunkId,
+                   position.y + (glyph.height * HALF));
   }
 
   void CreateActors(const std::vector<MeshRecord>& meshContainer,
@@ -416,6 +423,7 @@ struct AtlasRenderer::Impl
     std::vector<MeshRecord> meshContainer;
     std::vector<MeshRecord> meshContainerOutline;
     Vector<Extent>          extents;
+    Vector<Extent>          strikethroughExtents;
     mDepth = depth;
 
     const Vector2&   textSize(view.GetLayoutSize());
@@ -427,10 +435,13 @@ struct AtlasRenderer::Impl
     const float      underlineHeight = view.GetUnderlineHeight();
     const uint16_t   outlineWidth    = view.GetOutlineWidth();
     const Vector4&   outlineColor(view.GetOutlineColor());
-    const bool       isOutline     = 0u != outlineWidth;
-    const GlyphInfo* hyphens       = view.GetHyphens();
-    const Length*    hyphenIndices = view.GetHyphenIndices();
-    const Length     hyphensCount  = view.GetHyphensCount();
+    const bool       isOutline            = 0u != outlineWidth;
+    const GlyphInfo* hyphens              = view.GetHyphens();
+    const Length*    hyphenIndices        = view.GetHyphenIndices();
+    const Length     hyphensCount         = view.GetHyphensCount();
+    const bool       strikethroughEnabled = view.IsStrikethroughEnabled();
+    const Vector4&   strikethroughColor(view.GetStrikethroughColor());
+    const float      strikethroughHeight = view.GetStrikethroughHeight();
 
     // Elided text info. Indices according to elided text.
     const auto startIndexOfGlyphs              = view.GetStartIndexOfElidedGlyphs();
@@ -448,12 +459,14 @@ struct AtlasRenderer::Impl
                           numberOfUnderlineRuns);
 
     bool thereAreUnderlinedGlyphs = false;
+    bool strikethroughGlyphsExist = false;
 
-    float  currentUnderlinePosition  = ZERO;
-    float  currentUnderlineThickness = underlineHeight;
-    FontId lastFontId                = 0;
-    FontId lastUnderlinedFontId      = 0;
-    Style  style                     = STYLE_NORMAL;
+    float  currentUnderlinePosition      = ZERO;
+    float  currentUnderlineThickness     = underlineHeight;
+    float  currentStrikethroughThickness = strikethroughHeight;
+    FontId lastFontId                    = 0;
+    FontId lastUnderlinedFontId          = 0;
+    Style  style                         = STYLE_NORMAL;
 
     if(fabsf(shadowOffset.x) > Math::MACHINE_EPSILON_1 || fabsf(shadowOffset.y) > Math::MACHINE_EPSILON_1)
     {
@@ -499,12 +512,13 @@ struct AtlasRenderer::Impl
 
       const bool isGlyphUnderlined = underlineEnabled || IsGlyphUnderlined(i, underlineRuns);
       thereAreUnderlinedGlyphs     = thereAreUnderlinedGlyphs || isGlyphUnderlined;
+      strikethroughGlyphsExist     = strikethroughGlyphsExist || strikethroughEnabled;
 
       // No operation for white space
       if(glyph.width && glyph.height)
       {
         // Are we still using the same fontId as previous
-        if(isGlyphUnderlined && (glyph.fontId != lastUnderlinedFontId))
+        if((isGlyphUnderlined || strikethroughGlyphsExist) && (glyph.fontId != lastUnderlinedFontId))
         {
           // We need to fetch fresh font underline metrics
           FontMetrics fontMetrics;
@@ -527,6 +541,19 @@ struct AtlasRenderer::Impl
             }
           }
 
+          if(fabsf(strikethroughHeight) < Math::MACHINE_EPSILON_1000)
+          {
+            // Ensure strikethrough will be at least a pixel high
+            if(currentStrikethroughThickness < ONE)
+            {
+              currentStrikethroughThickness = ONE;
+            }
+            else
+            {
+              currentStrikethroughThickness = ceil(currentStrikethroughThickness);
+            }
+          }
+
           // Clamp the underline position at the font descender and check for ( as EFL describes it ) a broken font
           if(currentUnderlinePosition > descender)
           {
@@ -594,7 +621,25 @@ struct AtlasRenderer::Impl
                        meshContainer,
                        newTextCache,
                        extents,
-                       underlineChunkId);
+                       underlineChunkId,
+                       false);
+
+          if(strikethroughGlyphsExist)
+          {
+            GenerateMesh(glyph,
+                         positionPlusOutlineOffset,
+                         color,
+                         NO_OUTLINE,
+                         slot,
+                         strikethroughGlyphsExist,
+                         0.0f,
+                         currentStrikethroughThickness,
+                         meshContainer,
+                         newTextCache,
+                         strikethroughExtents,
+                         0u,
+                         true);
+          }
 
           lastFontId = glyph.fontId; // Prevents searching for existing blocksizes when string of the same fontId.
         }
@@ -612,7 +657,8 @@ struct AtlasRenderer::Impl
                        meshContainerOutline,
                        newTextCache,
                        extents,
-                       0u);
+                       0u,
+                       false);
         }
 
         //The new underlined chunk. Add new id if they are not consecutive indices (this is for Markup case)
@@ -641,6 +687,12 @@ struct AtlasRenderer::Impl
       GenerateUnderlines(meshContainer, extents, underlineColor);
     }
 
+    if(strikethroughGlyphsExist)
+    {
+      // Check to see if any of the text needs a strikethrough
+      GenerateStrikethrough(meshContainer, strikethroughExtents, strikethroughColor);
+    }
+
     // For each MeshData object, create a mesh actor and add to the renderable actor
     bool isShadowDrawn = false;
     if(!meshContainerOutline.empty())
@@ -775,11 +827,12 @@ struct AtlasRenderer::Impl
                       AtlasManager::Mesh2D&    newMesh,
                       Vector<Extent>&          extents,
                       float                    baseLine,
-                      bool                     underlineGlyph,
+                      bool                     decorationlineGlyph,
                       float                    underlinePosition,
-                      float                    underlineThickness,
+                      float                    lineThickness,
                       AtlasManager::AtlasSlot& slot,
-                      uint32_t                 underlineChunkId)
+                      uint32_t                 underlineChunkId,
+                      float                    strikethroughPosition)
   {
     if(slot.mImageId)
     {
@@ -798,7 +851,7 @@ struct AtlasRenderer::Impl
           // Append the mesh to the existing mesh and adjust any extents
           Toolkit::Internal::AtlasMeshFactory::AppendMesh(mIt->mMesh, newMesh);
 
-          if(underlineGlyph)
+          if(decorationlineGlyph)
           {
             AdjustExtents(extents,
                           meshContainer,
@@ -807,8 +860,9 @@ struct AtlasRenderer::Impl
                           right,
                           baseLine,
                           underlinePosition,
-                          underlineThickness,
-                          underlineChunkId);
+                          lineThickness,
+                          underlineChunkId,
+                          strikethroughPosition);
           }
 
           return;
@@ -821,7 +875,7 @@ struct AtlasRenderer::Impl
       meshRecord.mMesh    = newMesh;
       meshContainer.push_back(meshRecord);
 
-      if(underlineGlyph)
+      if(decorationlineGlyph)
       {
         // Adjust extents for this new meshrecord
         AdjustExtents(extents,
@@ -831,8 +885,9 @@ struct AtlasRenderer::Impl
                       right,
                       baseLine,
                       underlinePosition,
-                      underlineThickness,
-                      underlineChunkId);
+                      lineThickness,
+                      underlineChunkId,
+                      strikethroughPosition);
       }
     }
   }
@@ -844,8 +899,9 @@ struct AtlasRenderer::Impl
                      float                    right,
                      float                    baseLine,
                      float                    underlinePosition,
-                     float                    underlineThickness,
-                     uint32_t                 underlineChunkId)
+                     float                    lineThickness,
+                     uint32_t                 underlineChunkId,
+                     float                    strikethroughPosition)
   {
     bool foundExtent = false;
     for(Vector<Extent>::Iterator eIt    = extents.Begin(),
@@ -869,22 +925,23 @@ struct AtlasRenderer::Impl
         {
           eIt->mUnderlinePosition = underlinePosition;
         }
-        if(underlineThickness > eIt->mUnderlineThickness)
+        if(lineThickness > eIt->mLineThickness)
         {
-          eIt->mUnderlineThickness = underlineThickness;
+          eIt->mLineThickness = lineThickness;
         }
       }
     }
     if(!foundExtent)
     {
       Extent extent;
-      extent.mLeft               = left;
-      extent.mRight              = right;
-      extent.mBaseLine           = baseLine;
-      extent.mUnderlinePosition  = underlinePosition;
-      extent.mUnderlineThickness = underlineThickness;
-      extent.mMeshRecordIndex    = index;
-      extent.mUnderlineChunkId   = underlineChunkId;
+      extent.mLeft                  = left;
+      extent.mRight                 = right;
+      extent.mBaseLine              = baseLine;
+      extent.mUnderlinePosition     = underlinePosition;
+      extent.mMeshRecordIndex       = index;
+      extent.mUnderlineChunkId      = underlineChunkId;
+      extent.mLineThickness         = lineThickness;
+      extent.mStrikethroughPosition = strikethroughPosition;
       extents.PushBack(extent);
     }
   }
@@ -945,7 +1002,7 @@ struct AtlasRenderer::Impl
       // Make sure we don't hit texture edge for single pixel texture ( filled pixel is in top left of every atlas )
       float u         = HALF / uv.x;
       float v         = HALF / uv.y;
-      float thickness = eIt->mUnderlineThickness;
+      float thickness = eIt->mLineThickness;
       float baseLine  = eIt->mBaseLine + eIt->mUnderlinePosition - (thickness * HALF);
       float tlx       = eIt->mLeft;
       float brx       = eIt->mRight;
@@ -989,6 +1046,68 @@ struct AtlasRenderer::Impl
     }
   }
 
+  void GenerateStrikethrough(std::vector<MeshRecord>& meshRecords,
+                             Vector<Extent>&          extents,
+                             const Vector4&           strikethroughColor)
+  {
+    AtlasManager::Mesh2D newMesh;
+    unsigned short       faceIndex = 0;
+    for(Vector<Extent>::ConstIterator eIt    = extents.Begin(),
+                                      eEndIt = extents.End();
+        eIt != eEndIt;
+        ++eIt)
+    {
+      AtlasManager::Vertex2D vert;
+      uint32_t               index = eIt->mMeshRecordIndex;
+      Vector2                uv    = mGlyphManager.GetAtlasSize(meshRecords[index].mAtlasId);
+
+      // Make sure we don't hit texture edge for single pixel texture ( filled pixel is in top left of every atlas )
+      float u                     = HALF / uv.x;
+      float v                     = HALF / uv.y;
+      float thickness             = eIt->mLineThickness;
+      float tlx                   = eIt->mLeft;
+      float brx                   = eIt->mRight;
+      float strikethroughPosition = eIt->mStrikethroughPosition;
+
+      vert.mPosition.x  = tlx;
+      vert.mPosition.y  = strikethroughPosition;
+      vert.mTexCoords.x = ZERO;
+      vert.mTexCoords.y = ZERO;
+      vert.mColor       = strikethroughColor;
+      newMesh.mVertices.PushBack(vert);
+
+      vert.mPosition.x  = brx;
+      vert.mPosition.y  = strikethroughPosition;
+      vert.mTexCoords.x = u;
+      vert.mColor       = strikethroughColor;
+      newMesh.mVertices.PushBack(vert);
+
+      vert.mPosition.x  = tlx;
+      vert.mPosition.y  = strikethroughPosition + thickness;
+      vert.mTexCoords.x = ZERO;
+      vert.mTexCoords.y = v;
+      vert.mColor       = strikethroughColor;
+      newMesh.mVertices.PushBack(vert);
+
+      vert.mPosition.x  = brx;
+      vert.mPosition.y  = strikethroughPosition + thickness;
+      vert.mTexCoords.x = u;
+      vert.mColor       = strikethroughColor;
+      newMesh.mVertices.PushBack(vert);
+
+      // Six indices in counter clockwise winding
+      newMesh.mIndices.PushBack(faceIndex + 1u);
+      newMesh.mIndices.PushBack(faceIndex);
+      newMesh.mIndices.PushBack(faceIndex + 2u);
+      newMesh.mIndices.PushBack(faceIndex + 2u);
+      newMesh.mIndices.PushBack(faceIndex + 3u);
+      newMesh.mIndices.PushBack(faceIndex + 1u);
+      faceIndex += 4;
+
+      Toolkit::Internal::AtlasMeshFactory::AppendMesh(meshRecords[index].mMesh, newMesh);
+    }
+  }
+
   Actor                       mActor;            ///< The actor parent which renders the text
   AtlasGlyphManager           mGlyphManager;     ///< Glyph Manager to handle upload and caching
   TextAbstraction::FontClient mFontClient;       ///< The font client used to supply glyph information
index cea2a19..152b732 100644 (file)
@@ -35,6 +35,7 @@ namespace Text
 {
 namespace
 {
+const float HALF(0.5f);
 /**
  * @brief Data struct used to set the buffer of the glyph's bitmap into the final bitmap's buffer.
  */
@@ -275,14 +276,17 @@ bool IsGlyphUnderlined(GlyphIndex              index,
 }
 
 /// Helper method to fetch the underline metrics for the specified font glyph
-void FetchFontUnderlineMetrics(
+void FetchFontDecorationlinesMetrics(
   TextAbstraction::FontClient& fontClient,
   const GlyphInfo* const       glyphInfo,
   float&                       currentUnderlinePosition,
   const float                  underlineHeight,
   float&                       currentUnderlineThickness,
   float&                       maxUnderlineThickness,
-  FontId&                      lastUnderlinedFontId)
+  FontId&                      lastlinedFontId,
+  const float                  strikethroughHeight,
+  float&                       currentStrikethroughThickness,
+  float&                       maxStrikethroughThickness)
 {
   FontMetrics fontMetrics;
   fontClient.GetFontMetrics(glyphInfo->fontId, fontMetrics);
@@ -304,12 +308,31 @@ void FetchFontUnderlineMetrics(
     }
   }
 
+  if(fabsf(strikethroughHeight) < Math::MACHINE_EPSILON_1000)
+  {
+    // Ensure strikethrough will be at least a pixel high
+    if(currentStrikethroughThickness < 1.0f)
+    {
+      currentStrikethroughThickness = 1.0f;
+    }
+    else
+    {
+      currentStrikethroughThickness = ceil(currentStrikethroughThickness);
+    }
+  }
+
   // The underline thickness should be the max underline thickness of all glyphs of the line.
   if(currentUnderlineThickness > maxUnderlineThickness)
   {
     maxUnderlineThickness = currentUnderlineThickness;
   }
 
+  // The strikethrough thickness should be the max strikethrough thickness of all glyphs of the line.
+  if(currentStrikethroughThickness > maxStrikethroughThickness)
+  {
+    maxStrikethroughThickness = currentStrikethroughThickness;
+  }
+
   // Clamp the underline position at the font descender and check for ( as EFL describes it ) a broken font
   if(currentUnderlinePosition > descender)
   {
@@ -322,7 +345,7 @@ void FetchFontUnderlineMetrics(
     currentUnderlinePosition = 1.0f;
   }
 
-  lastUnderlinedFontId = glyphInfo->fontId;
+  lastlinedFontId = glyphInfo->fontId;
 }
 
 /// Draws the specified color to the pixel buffer
@@ -527,6 +550,42 @@ Devel::PixelBuffer DrawGlyphsBackground(const ViewModel* model, Devel::PixelBuff
   return glyphData.bitmapBuffer;
 }
 
+/// Draws the specified strikethrough color to the buffer
+void DrawStrikethrough(
+  const Vector4&     strikethroughColor,
+  const unsigned int bufferWidth,
+  const unsigned int bufferHeight,
+  GlyphData&         glyphData,
+  const float        baseline,
+  const LineRun&     line,
+  const float        maxStrikethroughThickness,
+  const float        lineExtentLeft,
+  const float        lineExtentRight,
+  float              strikethroughStartingYPosition)
+{
+  uint32_t* bitmapBuffer = reinterpret_cast<uint32_t*>(glyphData.bitmapBuffer.GetBuffer());
+
+  for(unsigned int y = strikethroughStartingYPosition; y < strikethroughStartingYPosition + maxStrikethroughThickness; y++)
+  {
+    if(y > bufferHeight - 1)
+    {
+      // Do not write out of bounds.
+      break;
+    }
+
+    for(unsigned int x = glyphData.horizontalOffset + lineExtentLeft; x <= glyphData.horizontalOffset + lineExtentRight; x++)
+    {
+      if(x > bufferWidth - 1)
+      {
+        // Do not write out of bounds.
+        break;
+      }
+
+      WriteColorToPixelBuffer(glyphData, bitmapBuffer, strikethroughColor, x, y);
+    }
+  }
+}
+
 } // namespace
 
 TypesetterPtr Typesetter::New(const ModelInterface* const model)
@@ -659,7 +718,7 @@ PixelData Typesetter::Render(const Vector2& size, Toolkit::DevelText::TextDirect
     // Generate the image buffer as an alpha mask for color glyphs.
     imageBuffer = CreateImageBuffer(bufferWidth, bufferHeight, Typesetter::STYLE_MASK, ignoreHorizontalAlignment, pixelFormat, penX, penY, startIndexOfGlyphs, endIndexOfGlyphs);
   }
-  else if(RENDER_NO_TEXT == behaviour)
+  else if(RENDER_NO_TEXT == behaviour || RENDER_OVERLAY_STYLE == behaviour)
   {
     // Generate an empty image buffer so that it can been combined with the image buffers for styles
     imageBuffer = Devel::PixelBuffer::New(bufferWidth, bufferHeight, Pixel::RGBA8888);
@@ -675,7 +734,7 @@ PixelData Typesetter::Render(const Vector2& size, Toolkit::DevelText::TextDirect
   {
     // Generate the outline if enabled
     const uint16_t outlineWidth = mModel->GetOutlineWidth();
-    if(outlineWidth != 0u)
+    if(outlineWidth != 0u && RENDER_OVERLAY_STYLE != behaviour)
     {
       // Create the image buffer for outline
       Devel::PixelBuffer outlineImageBuffer = CreateImageBuffer(bufferWidth, bufferHeight, Typesetter::STYLE_OUTLINE, ignoreHorizontalAlignment, pixelFormat, penX, penY, startIndexOfGlyphs, endIndexOfGlyphs);
@@ -688,7 +747,7 @@ PixelData Typesetter::Render(const Vector2& size, Toolkit::DevelText::TextDirect
 
     // Generate the shadow if enabled
     const Vector2& shadowOffset = mModel->GetShadowOffset();
-    if(fabsf(shadowOffset.x) > Math::MACHINE_EPSILON_1 || fabsf(shadowOffset.y) > Math::MACHINE_EPSILON_1)
+    if(RENDER_OVERLAY_STYLE != behaviour && (fabsf(shadowOffset.x) > Math::MACHINE_EPSILON_1 || fabsf(shadowOffset.y) > Math::MACHINE_EPSILON_1))
     {
       // Create the image buffer for shadow
       Devel::PixelBuffer shadowImageBuffer = CreateImageBuffer(bufferWidth, bufferHeight, Typesetter::STYLE_SHADOW, ignoreHorizontalAlignment, pixelFormat, penX, penY, startIndexOfGlyphs, endIndexOfGlyphs);
@@ -707,7 +766,7 @@ PixelData Typesetter::Render(const Vector2& size, Toolkit::DevelText::TextDirect
 
     // Generate the underline if enabled
     const bool underlineEnabled = mModel->IsUnderlineEnabled();
-    if(underlineEnabled)
+    if(underlineEnabled && RENDER_OVERLAY_STYLE == behaviour)
     {
       // Create the image buffer for underline
       Devel::PixelBuffer underlineImageBuffer = CreateImageBuffer(bufferWidth, bufferHeight, Typesetter::STYLE_UNDERLINE, ignoreHorizontalAlignment, pixelFormat, penX, penY, startIndexOfGlyphs, endIndexOfGlyphs);
@@ -719,7 +778,7 @@ PixelData Typesetter::Render(const Vector2& size, Toolkit::DevelText::TextDirect
     // Generate the background if enabled
     const bool backgroundEnabled   = mModel->IsBackgroundEnabled();
     const bool backgroundMarkupSet = mModel->IsMarkupBackgroundColorSet();
-    if(backgroundEnabled || backgroundMarkupSet)
+    if((backgroundEnabled || backgroundMarkupSet) && RENDER_OVERLAY_STYLE != behaviour)
     {
       Devel::PixelBuffer backgroundImageBuffer;
 
@@ -741,6 +800,17 @@ PixelData Typesetter::Render(const Vector2& size, Toolkit::DevelText::TextDirect
       imageBuffer = CombineImageBuffer(imageBuffer, backgroundImageBuffer, bufferWidth, bufferHeight);
     }
 
+    // Generate the strikethrough if enabled
+    const bool strikethroughEnabled = mModel->IsStrikethroughEnabled();
+    if(strikethroughEnabled && RENDER_OVERLAY_STYLE == behaviour)
+    {
+      // Create the image buffer for strikethrough
+      Devel::PixelBuffer strikethroughImageBuffer = CreateImageBuffer(bufferWidth, bufferHeight, Typesetter::STYLE_STRIKETHROUGH, ignoreHorizontalAlignment, pixelFormat, penX, penY, 0u, endIndexOfGlyphs);
+
+      // Combine the two buffers
+      imageBuffer = CombineImageBuffer(imageBuffer, strikethroughImageBuffer, bufferWidth, bufferHeight);
+    }
+
     // Markup-Processor
 
     imageBuffer = ApplyMarkupProcessorOnPixelBuffer(imageBuffer, bufferWidth, bufferHeight, ignoreHorizontalAlignment, pixelFormat, penX, penY);
@@ -834,6 +904,10 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer(const unsigned int bufferWidth,
     const Vector4& underlineColor   = mModel->GetUnderlineColor();
     const float    underlineHeight  = mModel->GetUnderlineHeight();
 
+    const bool     strikethroughEnabled = mModel->IsStrikethroughEnabled();
+    const Vector4& strikethroughColor   = mModel->GetStrikethroughColor();
+    const float    strikethroughHeight  = mModel->GetStrikethroughHeight();
+
     // Get the underline runs.
     const Length     numberOfUnderlineRuns = mModel->GetNumberOfUnderlineRuns();
     Vector<GlyphRun> underlineRuns;
@@ -841,10 +915,14 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer(const unsigned int bufferWidth,
     mModel->GetUnderlineRuns(underlineRuns.Begin(), 0u, numberOfUnderlineRuns);
 
     bool thereAreUnderlinedGlyphs = false;
+    bool strikethroughGlyphsExist = false;
 
-    float currentUnderlinePosition  = 0.0f;
-    float currentUnderlineThickness = underlineHeight;
-    float maxUnderlineThickness     = currentUnderlineThickness;
+    float currentUnderlinePosition       = 0.0f;
+    float currentUnderlineThickness      = underlineHeight;
+    float maxUnderlineThickness          = currentUnderlineThickness;
+    float currentStrikethroughThickness  = strikethroughHeight;
+    float maxStrikethroughThickness      = currentStrikethroughThickness;
+    float strikethroughStartingYPosition = 0.0f;
 
     FontId lastUnderlinedFontId = 0;
 
@@ -908,11 +986,13 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer(const unsigned int bufferWidth,
       const bool underlineGlyph = underlineEnabled || IsGlyphUnderlined(glyphIndex, underlineRuns);
       thereAreUnderlinedGlyphs  = thereAreUnderlinedGlyphs || underlineGlyph;
 
+      strikethroughGlyphsExist = strikethroughGlyphsExist || strikethroughEnabled;
+
       // Are we still using the same fontId as previous
-      if(underlineGlyph && (glyphInfo->fontId != lastUnderlinedFontId))
+      if((strikethroughEnabled || underlineGlyph) && (glyphInfo->fontId != lastUnderlinedFontId))
       {
         // We need to fetch fresh font underline metrics
-        FetchFontUnderlineMetrics(fontClient, glyphInfo, currentUnderlinePosition, underlineHeight, currentUnderlineThickness, maxUnderlineThickness, lastUnderlinedFontId);
+        FetchFontDecorationlinesMetrics(fontClient, glyphInfo, currentUnderlinePosition, underlineHeight, currentUnderlineThickness, maxUnderlineThickness, lastUnderlinedFontId, strikethroughHeight, currentStrikethroughThickness, maxStrikethroughThickness);
       } // underline
 
       // Retrieves the glyph's position.
@@ -974,7 +1054,7 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer(const unsigned int bufferWidth,
         outlineWidth = 0.0f;
       }
 
-      if(style != Typesetter::STYLE_UNDERLINE)
+      if(style != Typesetter::STYLE_UNDERLINE && style != Typesetter::STYLE_STRIKETHROUGH)
       {
         fontClient.CreateBitmap(glyphInfo->fontId,
                                 glyphInfo->index,
@@ -1040,6 +1120,14 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer(const unsigned int bufferWidth,
       DrawBackgroundColor(mModel->GetBackgroundColor(), bufferWidth, bufferHeight, glyphData, baseline, line, lineExtentLeft, lineExtentRight);
     }
 
+    // Draw the strikethrough from the leftmost glyph to the rightmost glyph
+    if(strikethroughGlyphsExist && style == Typesetter::STYLE_STRIKETHROUGH)
+    {
+      //TODO : The currently implemented strikethrough creates a strikethrough on the line level. We need to create different strikethroughs the case of glyphs with different sizes.
+      strikethroughStartingYPosition = (glyphData.verticalOffset + baseline + currentUnderlinePosition) - ((line.ascender) * HALF); // Since Free Type font doesn't contain the strikethrough-position property, strikethrough position will be calculated by moving the underline position upwards by half the value of the line height.
+      DrawStrikethrough(strikethroughColor, bufferWidth, bufferHeight, glyphData, baseline, line, maxStrikethroughThickness, lineExtentLeft, lineExtentRight, strikethroughStartingYPosition);
+    }
+
     // Increases the vertical offset with the line's descender.
     glyphData.verticalOffset += static_cast<int>(-line.descender);
   }
index ee57e29..51ac259 100644 (file)
@@ -51,9 +51,10 @@ public:
   enum RenderBehaviour
   {
     RENDER_TEXT_AND_STYLES, ///< Render both the text and its styles
-    RENDER_NO_TEXT,         ///< Do not render the text itself
+    RENDER_NO_TEXT,         ///< Do not render the text itself but render the background styles such as outline and background.
     RENDER_NO_STYLES,       ///< Do not render any styles
-    RENDER_MASK             ///< Render an alpha mask (for color glyphs with no color animation, e.g. emoji)
+    RENDER_MASK,            ///< Render an alpha mask (for color glyphs with no color animation, e.g. emoji)
+    RENDER_OVERLAY_STYLE    ///< Do not render the text itself but render the style but overlay the style on the text (foreground styles such as strikethrough and underline)
   };
 
   /**
@@ -61,13 +62,14 @@ public:
    */
   enum Style
   {
-    STYLE_NONE,        ///< No style
-    STYLE_MASK,        ///< Alpha mask
-    STYLE_SHADOW,      ///< Hard shadow
-    STYLE_SOFT_SHADOW, ///< Soft shadow
-    STYLE_UNDERLINE,   ///< Underline
-    STYLE_OUTLINE,     ///< Outline
-    STYLE_BACKGROUND   ///< Text background
+    STYLE_NONE,         ///< No style
+    STYLE_MASK,         ///< Alpha mask
+    STYLE_SHADOW,       ///< Hard shadow
+    STYLE_SOFT_SHADOW,  ///< Soft shadow
+    STYLE_UNDERLINE,    ///< Underline
+    STYLE_OUTLINE,      ///< Outline
+    STYLE_BACKGROUND,   ///< Text background
+    STYLE_STRIKETHROUGH ///< Strikethrough
   };
 
 public: // Constructor.
@@ -215,4 +217,4 @@ private:
 
 } // namespace Dali
 
-#endif // DALI_TOOLKIT_TEXT_TYPESETTER_H
+#endif // DALI_TOOLKIT_TEXT_TYPESETTER_H
\ No newline at end of file
index 2187487..0557e09 100644 (file)
@@ -583,6 +583,21 @@ void ViewModel::ElideGlyphs()
   }
 }
 
+float ViewModel::GetStrikethroughHeight() const
+{
+  return mModel->GetStrikethroughHeight();
+}
+
+const Vector4& ViewModel::GetStrikethroughColor() const
+{
+  return mModel->GetStrikethroughColor();
+}
+
+bool ViewModel::IsStrikethroughEnabled() const
+{
+  return mModel->IsStrikethroughEnabled();
+}
+
 } // namespace Text
 
 } // namespace Toolkit
index fd83b62..b95dfab 100644 (file)
@@ -272,6 +272,12 @@ public:
    */
   void ElideGlyphs();
 
+  float GetStrikethroughHeight() const override;
+
+  const Vector4& GetStrikethroughColor() const override;
+
+  bool IsStrikethroughEnabled() const override;
+
 private:
   const ModelInterface* const mModel;                           ///< Pointer to the text's model.
   Vector<GlyphInfo>           mElidedGlyphs;                    ///< Stores the glyphs of the elided text.
index 3c72bdb..fa64a95 100644 (file)
@@ -967,6 +967,7 @@ public:
   bool                  mShadowSetByString : 1;        ///< Set when shadow is set by string (legacy) instead of map
   bool                  mOutlineSetByString : 1;       ///< Set when outline is set by string (legacy) instead of map
   bool                  mFontStyleSetByString : 1;     ///< Set when font style is set by string (legacy) instead of map
+  bool                  mStrikethroughSetByString : 1; ///< Set when strikethrough is set by string (legacy) instead of map
   bool                  mShouldClearFocusOnEscape : 1; ///< Whether text control should clear key input focus
   LayoutDirection::Type mLayoutDirection;              ///< Current system language direction
 
index be985d1..5ebd05a 100644 (file)
@@ -1092,6 +1092,65 @@ void Controller::FontStyleSetByString(bool setByString)
   mImpl->mFontStyleSetByString = setByString;
 }
 
+void Controller::SetStrikethroughHeight(float height)
+{
+  mImpl->mModel->mVisualModel->SetStrikethroughHeight(height);
+
+  mImpl->RequestRelayout();
+}
+
+float Controller::GetStrikethroughHeight() const
+{
+  return mImpl->mModel->mVisualModel->GetStrikethroughHeight();
+}
+
+void Controller::SetStrikethroughColor(const Vector4& color)
+{
+  mImpl->mModel->mVisualModel->SetStrikethroughColor(color);
+
+  mImpl->RequestRelayout();
+}
+
+const Vector4& Controller::GetStrikethroughColor() const
+{
+  return mImpl->mModel->mVisualModel->GetStrikethroughColor();
+}
+
+void Controller::SetStrikethroughEnabled(bool enabled)
+{
+  mImpl->mModel->mVisualModel->SetStrikethroughEnabled(enabled);
+
+  mImpl->RequestRelayout();
+}
+
+bool Controller::IsStrikethroughEnabled() const
+{
+  return mImpl->mModel->mVisualModel->IsStrikethroughEnabled();
+}
+
+void Controller::SetInputStrikethroughProperties(const std::string& strikethroughProperties)
+{
+  if(NULL != mImpl->mEventData)
+  {
+    mImpl->mEventData->mInputStyle.strikethroughProperties = strikethroughProperties;
+  }
+}
+
+const std::string& Controller::GetInputStrikethroughProperties() const
+{
+  return (NULL != mImpl->mEventData) ? mImpl->mEventData->mInputStyle.strikethroughProperties : EMPTY_STRING;
+}
+
+bool Controller::IsStrikethroughSetByString()
+{
+  return mImpl->mStrikethroughSetByString;
+}
+
+void Controller::StrikethroughSetByString(bool setByString)
+{
+  mImpl->mStrikethroughSetByString = setByString;
+}
+
 Layout::Engine& Controller::GetLayoutEngine()
 {
   return mImpl->mLayoutEngine;
index b16186b..da396c9 100644 (file)
@@ -659,6 +659,60 @@ public: // Configure the text controller.
    */
   void FontStyleSetByString(bool setByString);
 
+  /**
+   * @brief Query if Strikethrough settings were provided by string or map
+   * @return bool true if set by string
+   */
+  bool IsStrikethroughSetByString();
+
+  /**
+   * Set method Strikethrough setting were set by
+   * @param[in] bool, true if set by string
+   */
+  void StrikethroughSetByString(bool setByString);
+
+  /**
+   * @brief Set the override used for strikethrough height, 0 indicates height will be supplied by font metrics
+   *
+   * @param[in] height The height in pixels of the strikethrough
+   */
+  void SetStrikethroughHeight(float height);
+
+  /**
+   * @brief Retrieves the override height of an strikethrough, 0 indicates height is supplied by font metrics
+   *
+   * @return The height of the strikethrough, or 0 if height is not overrided.
+   */
+  float GetStrikethroughHeight() const;
+
+  /**
+   * @brief Set the strikethrough color.
+   *
+   * @param[in] color color of strikethrough.
+   */
+  void SetStrikethroughColor(const Vector4& color);
+
+  /**
+   * @brief Retrieve the strikethrough color.
+   *
+   * @return The strikethrough color.
+   */
+  const Vector4& GetStrikethroughColor() const;
+
+  /**
+   * @brief Set the strikethrough enabled flag.
+   *
+   * @param[in] enabled The strikethrough enabled flag.
+   */
+  void SetStrikethroughEnabled(bool enabled);
+
+  /**
+   * @brief Returns whether the text has a strikethrough or not.
+   *
+   * @return The strikethrough state.
+   */
+  bool IsStrikethroughEnabled() const;
+
 public: // Update.
   /**
    * @brief Replaces any text previously set.
@@ -1331,6 +1385,22 @@ public: // Default style & Input style
   const std::string& GetInputOutlineProperties() const;
 
   /**
+   * @brief Sets the input strikethrough's properties string.
+   *
+   * @note The string is stored to be recovered.
+   *
+   * @param[in] strikethroughProperties The strikethrough's properties string.
+   */
+  void SetInputStrikethroughProperties(const std::string& strikethroughProperties);
+
+  /**
+   * @brief Retrieves the input strikethrough's properties string.
+   *
+   * @return The strikethrough's properties string.
+   */
+  const std::string& GetInputStrikethroughProperties() const;
+
+  /**
    * @brief Set the control's interface.
    *
    * @param[in] controlInterface The control's interface.
index a367696..38145dc 100644 (file)
@@ -226,6 +226,67 @@ bool ParseBackgroundProperties(const Property::Map& backgroundProperties,
   return 0u == numberOfItems;
 }
 
+bool ParseStrikethroughProperties(const Property::Map& strikethroughPropertiesMap,
+                                  bool&                enabled,
+                                  bool&                colorDefined,
+                                  Vector4&             color,
+                                  bool&                heightDefined,
+                                  float&               height)
+{
+  const unsigned int numberOfItems = strikethroughPropertiesMap.Count();
+
+  // Parses and applies the style.
+  for(unsigned int index = 0u; index < numberOfItems; ++index)
+  {
+    const KeyValuePair& valueGet = strikethroughPropertiesMap.GetKeyValue(index);
+
+    if((DevelText::Strikethrough::Property::ENABLE == valueGet.first.indexKey) || (ENABLE_KEY == valueGet.first.stringKey))
+    {
+      /// Enable key.
+      if(valueGet.second.GetType() == Dali::Property::STRING)
+      {
+        const std::string enableStr = valueGet.second.Get<std::string>();
+        enabled                     = Text::TokenComparison(TRUE_TOKEN, enableStr.c_str(), enableStr.size());
+      }
+      else
+      {
+        enabled = valueGet.second.Get<bool>();
+      }
+    }
+    else if((DevelText::Strikethrough::Property::COLOR == valueGet.first.indexKey) || (COLOR_KEY == valueGet.first.stringKey))
+    {
+      /// Color key.
+      colorDefined = true;
+
+      if(valueGet.second.GetType() == Dali::Property::STRING)
+      {
+        const std::string colorStr = valueGet.second.Get<std::string>();
+        Text::ColorStringToVector4(colorStr.c_str(), colorStr.size(), color);
+      }
+      else
+      {
+        color = valueGet.second.Get<Vector4>();
+      }
+    }
+    else if((DevelText::Strikethrough::Property::HEIGHT == valueGet.first.indexKey) || (HEIGHT_KEY == valueGet.first.stringKey))
+    {
+      /// Height key.
+      heightDefined = true;
+
+      if(valueGet.second.GetType() == Dali::Property::STRING)
+      {
+        const std::string heightStr = valueGet.second.Get<std::string>();
+        height                      = StringToFloat(heightStr.c_str());
+      }
+      else
+      {
+        height = valueGet.second.Get<float>();
+      }
+    }
+  }
+  return 0u == numberOfItems;
+}
+
 bool SetUnderlineProperties(ControllerPtr controller, const Property::Value& value, EffectStyle::Type type)
 {
   bool update = false;
@@ -774,6 +835,153 @@ void GetBackgroundProperties(ControllerPtr controller, Property::Value& value, E
   }
 }
 
+bool SetStrikethroughProperties(ControllerPtr controller, const Property::Value& value, EffectStyle::Type type)
+{
+  bool update = false;
+
+  if(controller)
+  {
+    switch(type)
+    {
+      case EffectStyle::DEFAULT:
+      {
+        const Property::Map& propertiesMap = value.Get<Property::Map>();
+
+        bool    enabled      = false;
+        bool    colorDefined = false;
+        Vector4 color;
+        bool    heightDefined = false;
+        float   height        = 0.f;
+
+        bool empty = true;
+
+        if(propertiesMap.Empty())
+        {
+          // Map empty so check if a string provided
+          const std::string propertyString = value.Get<std::string>();
+
+          if(!propertyString.empty())
+          {
+            Property::Map parsedStringMap;
+            Text::ParsePropertyString(propertyString, parsedStringMap);
+
+            empty = ParseStrikethroughProperties(parsedStringMap,
+                                             enabled,
+                                             colorDefined,
+                                             color,
+                                             heightDefined,
+                                             height);
+
+            controller->StrikethroughSetByString(!empty);
+          }
+        }
+        else
+        {
+          empty = ParseStrikethroughProperties(propertiesMap,
+                                               enabled,
+                                               colorDefined,
+                                               color,
+                                               heightDefined,
+                                               height);
+
+          controller->StrikethroughSetByString(false);
+        }
+
+        if(!empty)
+        {
+          if(enabled != controller->IsStrikethroughEnabled())
+          {
+            controller->SetStrikethroughEnabled(enabled);
+            update = true;
+          }
+
+          // Sets the default strikethrough values.
+          if(colorDefined && (controller->GetStrikethroughColor() != color))
+          {
+            controller->SetStrikethroughColor(color);
+            update = true;
+          }
+          if(heightDefined && (fabsf(controller->GetStrikethroughHeight() - height) > Math::MACHINE_EPSILON_1000))
+          {
+            controller->SetStrikethroughHeight(height);
+            update = true;
+          }
+        }
+        else
+        {
+          // Disable strikethrough.
+          if(controller->IsStrikethroughEnabled())
+          {
+            controller->SetStrikethroughEnabled(false);
+            update = true;
+          }
+        }
+        break;
+      }
+      case EffectStyle::INPUT:
+      {
+        const std::string& strikethroughProperties = value.Get<std::string>();
+
+        controller->SetInputStrikethroughProperties(strikethroughProperties);
+        update = true;
+        break;
+      }
+    } // switch
+  }   // if( controller )
+
+  return update;
+}
+
+void GetStrikethroughProperties(ControllerPtr controller, Property::Value& value, EffectStyle::Type type)
+{
+  if(controller)
+  {
+    switch(type)
+    {
+      case EffectStyle::DEFAULT:
+      {
+        const bool     enabled = controller->IsStrikethroughEnabled();
+        const Vector4& color   = controller->GetStrikethroughColor();
+        const float    height  = controller->GetStrikethroughHeight();
+
+        if(controller->IsStrikethroughSetByString())
+        {
+          std::string       strikethroughProperties = "{\"enable\":";
+          const std::string enabledStr          = enabled ? "true" : "false";
+          strikethroughProperties += "\"" + enabledStr + "\",";
+
+          std::string colorStr;
+          Vector4ToColorString(color, colorStr);
+          strikethroughProperties += "\"color\":\"" + colorStr + "\",";
+
+          std::string heightStr;
+          FloatToString(height, heightStr);
+          strikethroughProperties += "\"height\":\"" + heightStr + "\"}";
+
+          value = strikethroughProperties;
+        }
+        else
+        {
+          Property::Map map;
+
+          map.Insert(ENABLE_KEY, enabled);
+          map.Insert(COLOR_KEY, color);
+          map.Insert(HEIGHT_KEY, height);
+
+          value = map;
+        }
+
+        break;
+      }
+      case EffectStyle::INPUT:
+      {
+        value = controller->GetInputStrikethroughProperties();
+        break;
+      }
+    }
+  }
+}
+
 } // namespace Text
 
 } // namespace Toolkit
index fcc2381..436e8d1 100644 (file)
@@ -97,6 +97,23 @@ bool ParseBackgroundProperties(const Property::Map& backgroundProperties,
                                Vector4&             color);
 
 /**
+ * @brief Parses the strikethrough properties.
+ *
+ * @param[in] strikethroughProperties The map with the strikethrough properties.
+ * @param[out] enabled Whether the strikethrough is enabled.
+ * @param[out] colorDefined Whether the strikethrough's color is defined.
+ * @param[out] color The strikethrough's color.
+ * @param[out] heightDefined Whether the strikethrough's height is defined.
+ * @param[out] height The strikethrough's height.
+ */
+bool ParseStrikethroughProperties(const Property::Map& strikethroughProperties,
+                              bool&                enabled,
+                              bool&                colorDefined,
+                              Vector4&             color,
+                              bool&                heightDefined,
+                              float&               height);
+
+/**
  * @brief Sets the underline properties.
  *
  * @param[in] controller The text's controller.
@@ -108,6 +125,17 @@ bool ParseBackgroundProperties(const Property::Map& backgroundProperties,
 bool SetUnderlineProperties(ControllerPtr controller, const Property::Value& value, EffectStyle::Type type);
 
 /**
+ * @brief Sets the strikethrough properties.
+ *
+ * @param[in] controller The text's controller.
+ * @param[in] value The values of the strikethrough's properties.
+ * @param[in] type Whether the property is for the default strikethrough or the input strikethrough.
+ *
+ * @return Whether the strikethrough properties have been updated.
+ */
+bool SetStrikethroughProperties(ControllerPtr controller, const Property::Value& value, EffectStyle::Type type);
+
+/**
  * @brief Retrieves the underline's properties.
  *
  * @param[in] controller The text's controller.
@@ -117,6 +145,15 @@ bool SetUnderlineProperties(ControllerPtr controller, const Property::Value& val
 void GetUnderlineProperties(ControllerPtr controller, Property::Value& value, EffectStyle::Type type);
 
 /**
+ * @brief Retrieves the strikethrough's properties.
+ *
+ * @param[in] controller The text's controller.
+ * @param[out] value The value of the strikethrough's properties.
+ * @param[in] type Whether the property is for the default strikethrough or the input strikethrough.
+ */
+void GetStrikethroughProperties(ControllerPtr controller, Property::Value& value, EffectStyle::Type type);
+
+/**
  * @brief Sets the shadow properties.
  *
  * @param[in] controller The text's controller.
index d9520f1..415b742 100644 (file)
@@ -335,6 +335,27 @@ public:
    * @return number of hyphens.
    */
   virtual Length GetHyphensCount() const = 0;
+
+  /**
+   * @brief Retrieves the strikethrough color.
+   *
+   * @return The strikethrough color.
+   */
+  virtual const Vector4& GetStrikethroughColor() const = 0;
+
+  /**
+   * @brief Returns whether strikethrough is enabled or not.
+   *
+   * @return The strikethrough state.
+   */
+  virtual bool IsStrikethroughEnabled() const = 0;
+
+  /**
+   * @brief Retrieves the strikethrough height override
+   *
+   * @return Returns the override height for a strikethrough, 0 indicates that adaptor will determine the height
+   */
+  virtual float GetStrikethroughHeight() const = 0;
 };
 
 } // namespace Text
index 4c3e3f0..b202d69 100644 (file)
@@ -241,6 +241,20 @@ Length Model::GetHyphensCount() const
 {
   return mVisualModel->mHyphen.glyph.Size();
 }
+const Vector4& Model::GetStrikethroughColor() const
+{
+  return mVisualModel->GetStrikethroughColor();
+}
+
+bool Model::IsStrikethroughEnabled() const
+{
+  return mVisualModel->IsStrikethroughEnabled();
+}
+
+float Model::GetStrikethroughHeight() const
+{
+  return mVisualModel->GetStrikethroughHeight();
+}
 
 Model::Model()
 : mLogicalModel(),
index 280b63d..0a01400 100644 (file)
@@ -257,6 +257,12 @@ public:
   */
   Length GetHyphensCount() const override;
 
+  float GetStrikethroughHeight() const override;
+
+  const Vector4& GetStrikethroughColor() const override;
+
+  bool IsStrikethroughEnabled() const override;
+
 private: // Private contructors & copy operator.
   /**
    * @brief Private constructor.
index 24994bf..5a2cda2 100644 (file)
@@ -266,6 +266,27 @@ public:
    * @return The second middle index of elided glyphs, index of ellipsis of middle.
    */
   virtual GlyphIndex GetSecondMiddleIndexOfElidedGlyphs() const = 0;
+
+  /**
+   * @brief Retrieves the strikethrough color.
+   *
+   * @return The strikethrough color.
+   */
+  virtual const Vector4& GetStrikethroughColor() const = 0;
+
+  /**
+   * @brief Returns whether strikethrough is enabled or not.
+   *
+   * @return The strikethrough state.
+   */
+  virtual bool IsStrikethroughEnabled() const = 0;
+
+  /**
+   * @brief Retrieves the strikethrough height override
+   *
+   * @return Returns the override height for a strikethrough, 0 indicates that adaptor will determine the height
+   */
+  virtual float GetStrikethroughHeight() const = 0;
 };
 
 } // namespace Text
index a5a6b3b..f85d1f9 100644 (file)
@@ -742,6 +742,21 @@ GlyphIndex View::GetSecondMiddleIndexOfElidedGlyphs() const
   return secondMiddleIndexOfElidedGlyphs;
 }
 
+const Vector4& View::GetStrikethroughColor() const
+{
+  return (mImpl->mVisualModel) ? mImpl->mVisualModel->GetStrikethroughColor() : Vector4::ZERO;
+}
+
+bool View::IsStrikethroughEnabled() const
+{
+  return (mImpl->mVisualModel) ? mImpl->mVisualModel->IsStrikethroughEnabled() : false;
+}
+
+float View::GetStrikethroughHeight() const
+{
+  return (mImpl->mVisualModel) ? mImpl->mVisualModel->GetStrikethroughHeight() : 0.0f;
+}
+
 } // namespace Text
 
 } // namespace Toolkit
index 62324e8..c072abd 100644 (file)
@@ -197,6 +197,21 @@ public:
    */
   GlyphIndex GetSecondMiddleIndexOfElidedGlyphs() const override;
 
+  /**
+   * @copydoc Dali::Toolkit::Text::ViewInterface::GetStrikethroughColor()
+   */
+  const Vector4& GetStrikethroughColor() const override;
+
+  /**
+   * @copydoc Dali::Toolkit::Text::ViewInterface::IsStrikethroughEnabled()
+   */
+  bool IsStrikethroughEnabled() const override;
+
+  /**
+   * @copydoc Dali::Toolkit::Text::ViewInterface::GetStrikethroughHeight()
+   */
+  float GetStrikethroughHeight() const override;
+
 private:
   // Undefined
   View(const View& handle);
index 9c57494..e138e3c 100644 (file)
@@ -430,6 +430,21 @@ void VisualModel::SetSecondMiddleIndexOfElidedGlyphs(GlyphIndex secondMiddleInde
   mSecondMiddleIndexOfElidedGlyphs = secondMiddleIndexOfElidedGlyphs;
 }
 
+void VisualModel::SetStrikethroughColor(const Vector4& color)
+{
+  mStrikethroughColor = color;
+}
+
+void VisualModel::SetStrikethroughEnabled(bool enabled)
+{
+  mStrikethroughEnabled = enabled;
+}
+
+void VisualModel::SetStrikethroughHeight(float height)
+{
+  mStrikethroughHeight = height;
+}
+
 const Vector4& VisualModel::GetTextColor() const
 {
   return mTextColor;
@@ -525,6 +540,21 @@ Length VisualModel::GetNumberOfUnderlineRuns() const
   return mUnderlineRuns.Count();
 }
 
+const Vector4& VisualModel::GetStrikethroughColor() const
+{
+  return mStrikethroughColor;
+}
+
+bool VisualModel::IsStrikethroughEnabled() const
+{
+  return mStrikethroughEnabled;
+}
+
+float VisualModel::GetStrikethroughHeight() const
+{
+  return mStrikethroughHeight;
+}
+
 void VisualModel::ClearCaches()
 {
   mCachedLineIndex = 0u;
@@ -547,9 +577,11 @@ VisualModel::VisualModel()
   mUnderlineColor(Color::BLACK),
   mOutlineColor(Color::WHITE),
   mBackgroundColor(Color::TRANSPARENT),
+  mStrikethroughColor(Color::BLACK),
   mControlSize(),
   mShadowOffset(),
   mUnderlineHeight(0.0f),
+  mStrikethroughHeight(0.0f),
   mShadowBlurRadius(0.0f),
   mOutlineWidth(0u),
   mNaturalSize(),
@@ -564,7 +596,8 @@ VisualModel::VisualModel()
   mUnderlineEnabled(false),
   mUnderlineColorSet(false),
   mBackgroundEnabled(false),
-  mMarkupProcessorEnabled(false)
+  mMarkupProcessorEnabled(false),
+  mStrikethroughEnabled(false)
 
 {
 }
index ac9b12d..6a96094 100644 (file)
@@ -467,6 +467,48 @@ public:
    */
   GlyphIndex GetSecondMiddleIndexOfElidedGlyphs() const;
 
+  /**
+   * @brief Sets the text's strikethrough color.
+   *
+   * @param[in] color The text's strikethrough color.
+   */
+  void SetStrikethroughColor(const Vector4& color);
+
+  /**
+   * @brief Retrieves the text's strikethrough color.
+   *
+   * @return The text's strikethrough color.
+   */
+  const Vector4& GetStrikethroughColor() const;
+
+  /**
+   * @brief Sets the text strikethrough flag.
+   *
+   * @param[in] enabled true if strikethrough.
+   */
+  void SetStrikethroughEnabled(bool enabled);
+
+  /**
+   * @brief Returns whether the text is strikethrough or not.
+   *
+   * @return strikethrough state.
+   */
+  bool IsStrikethroughEnabled() const;
+
+  /**
+   * @brief Set the override used for strikethrough height, 0 indicates height will be come from font metrics
+   *
+   * @param[in] height The height in pixels of the strikethrough
+   */
+  void SetStrikethroughHeight(float height);
+
+  /**
+   * @brief Retrieves the strikethrough height override
+   *
+   * @return Returns the override height for a strikethrough, 0 indicates that font metrics will determine the height
+   */
+  float GetStrikethroughHeight() const;
+
 protected:
   /**
    * @brief A reference counted object may only be deleted by calling Unreference().
@@ -499,16 +541,18 @@ public:
   Vector<Vector4>        mBackgroundColors;       ///< Background colors of the glyphs.
   Vector<ColorIndex>     mBackgroundColorIndices; ///< Indices to the vector of background colors for each glyphs.
 
-  Vector4  mTextColor;        ///< The text color
-  Vector4  mShadowColor;      ///< Color of drop shadow
-  Vector4  mUnderlineColor;   ///< Color of underline
-  Vector4  mOutlineColor;     ///< Color of outline
-  Vector4  mBackgroundColor;  ///< Color of text background
-  Size     mControlSize;      ///< The size of the UI control.
-  Vector2  mShadowOffset;     ///< Offset for drop shadow, 0 indicates no shadow
-  float    mUnderlineHeight;  ///< Fixed height for underline to override font metrics.
-  float    mShadowBlurRadius; ///< Blur radius of shadow, 0 indicates no blur.
-  uint16_t mOutlineWidth;     ///< Width of outline.
+  Vector4  mTextColor;           ///< The text color
+  Vector4  mShadowColor;         ///< Color of drop shadow
+  Vector4  mUnderlineColor;      ///< Color of underline
+  Vector4  mOutlineColor;        ///< Color of outline
+  Vector4  mBackgroundColor;     ///< Color of text background
+  Vector4  mStrikethroughColor;  ///< Color of text background
+  Size     mControlSize;         ///< The size of the UI control.
+  Vector2  mShadowOffset;        ///< Offset for drop shadow, 0 indicates no shadow
+  float    mUnderlineHeight;     ///< Fixed height for underline to override font metrics.
+  float    mStrikethroughHeight; ///< Fixed height for strikethrough to override font metrics.
+  float    mShadowBlurRadius;    ///< Blur radius of shadow, 0 indicates no blur.
+  uint16_t mOutlineWidth;        ///< Width of outline.
 
 private:
   Size mNaturalSize; ///< Size of the text with no line wrapping.
@@ -530,6 +574,7 @@ public:
   bool       mBackgroundEnabled : 1;      ///< Background enabled flag
   bool       mMarkupProcessorEnabled : 1; ///< Markup-processor enabled flag
   HyphenInfo mHyphen;                     ///< Contains hyphen glyph info & the character index to draw hyphen after.
+  bool       mStrikethroughEnabled : 1;   ///< Strikethrough enabled flag
 };
 
 } // namespace Text
index a4903c5..7720aa2 100644 (file)
@@ -223,6 +223,9 @@ void TextVisual::DoCreatePropertyMap(Property::Map& map) const
 
   GetBackgroundProperties(mController, value, Text::EffectStyle::DEFAULT);
   map.Insert(Toolkit::DevelTextVisual::Property::BACKGROUND, value);
+
+  GetStrikethroughProperties(mController, value, Text::EffectStyle::DEFAULT);
+  map.Insert(Toolkit::DevelTextVisual::Property::STRIKETHROUGH, value);
 }
 
 void TextVisual::DoCreateInstancePropertyMap(Property::Map& map) const
@@ -460,6 +463,11 @@ void TextVisual::DoSetProperty(Dali::Property::Index index, const Dali::Property
       SetBackgroundProperties(mController, propertyValue, Text::EffectStyle::DEFAULT);
       break;
     }
+    case Toolkit::DevelTextVisual::Property::STRIKETHROUGH:
+    {
+      SetStrikethroughProperties(mController, propertyValue, Text::EffectStyle::DEFAULT);
+      break;
+    }
   }
 }
 
@@ -545,10 +553,12 @@ void TextVisual::UpdateRenderer()
       const bool outlineEnabled         = (mController->GetTextModel()->GetOutlineWidth() > Math::MACHINE_EPSILON_1);
       const bool backgroundEnabled      = mController->GetTextModel()->IsBackgroundEnabled();
       const bool markupProcessorEnabled = mController->IsMarkupProcessorEnabled();
+      const bool strikethroughEnabled   = mController->GetTextModel()->IsStrikethroughEnabled();
 
-      const bool styleEnabled = (shadowEnabled || underlineEnabled || outlineEnabled || backgroundEnabled || markupProcessorEnabled);
+      const bool styleEnabled = (shadowEnabled || underlineEnabled || outlineEnabled || backgroundEnabled || markupProcessorEnabled || strikethroughEnabled);
+      const bool isOverlayStyle = underlineEnabled || strikethroughEnabled;
 
-      AddRenderer(control, relayoutSize, hasMultipleTextColors, containsColorGlyph, styleEnabled);
+      AddRenderer(control, relayoutSize, hasMultipleTextColors, containsColorGlyph, styleEnabled, isOverlayStyle);
 
       // Text rendered and ready to display
       ResourceReady(Toolkit::Visual::ResourceStatus::READY);
@@ -583,12 +593,13 @@ PixelData TextVisual::ConvertToPixelData(unsigned char* buffer, int width, int h
   return pixelData;
 }
 
-void TextVisual::CreateTextureSet(TilingInfo& info, Renderer& renderer, Sampler& sampler, bool hasMultipleTextColors, bool containsColorGlyph, bool styleEnabled)
+void TextVisual::CreateTextureSet(TilingInfo& info, Renderer& renderer, Sampler& sampler, bool hasMultipleTextColors, bool containsColorGlyph, bool styleEnabled, bool isOverlayStyle)
 {
   TextureSet   textureSet      = TextureSet::New();
   unsigned int textureSetIndex = 0u;
 
   // Convert the buffer to pixel data to make it a texture.
+
   if(info.textBuffer)
   {
     PixelData data = ConvertToPixelData(info.textBuffer, info.width, info.height, info.offsetPosition, info.textPixelFormat);
@@ -603,6 +614,13 @@ void TextVisual::CreateTextureSet(TilingInfo& info, Renderer& renderer, Sampler&
     ++textureSetIndex;
   }
 
+  if(styleEnabled && isOverlayStyle)
+  {
+    PixelData overlayStyleData = ConvertToPixelData(info.styleBuffer, info.width, info.height, info.offsetPosition, Pixel::RGBA8888);
+    AddTexture(textureSet, overlayStyleData, sampler, textureSetIndex);
+    ++textureSetIndex;
+  }
+
   if(containsColorGlyph && !hasMultipleTextColors && info.maskBuffer)
   {
     PixelData maskData = ConvertToPixelData(info.maskBuffer, info.width, info.height, info.offsetPosition, Pixel::L8);
@@ -627,7 +645,7 @@ void TextVisual::CreateTextureSet(TilingInfo& info, Renderer& renderer, Sampler&
   mRendererList.push_back(renderer);
 }
 
-void TextVisual::AddRenderer(Actor& actor, const Vector2& size, bool hasMultipleTextColors, bool containsColorGlyph, bool styleEnabled)
+void TextVisual::AddRenderer(Actor& actor, const Vector2& size, bool hasMultipleTextColors, bool containsColorGlyph, bool styleEnabled, bool isOverlayStyle)
 {
   Shader shader = GetTextShader(mFactoryCache, hasMultipleTextColors, containsColorGlyph, styleEnabled);
   mImpl->mRenderer.SetShader(shader);
@@ -638,7 +656,7 @@ void TextVisual::AddRenderer(Actor& actor, const Vector2& size, bool hasMultiple
   // No tiling required. Use the default renderer.
   if(size.height < maxTextureSize)
   {
-    TextureSet textureSet = GetTextTexture(size, hasMultipleTextColors, containsColorGlyph, styleEnabled);
+    TextureSet textureSet = GetTextTexture(size, hasMultipleTextColors, containsColorGlyph, styleEnabled, isOverlayStyle);
 
     mImpl->mRenderer.SetTextures(textureSet);
     //Register transform properties
@@ -700,7 +718,7 @@ void TextVisual::AddRenderer(Actor& actor, const Vector2& size, bool hasMultiple
     }
 
     // Create a textureset in the default renderer.
-    CreateTextureSet(info, mImpl->mRenderer, sampler, hasMultipleTextColors, containsColorGlyph, styleEnabled);
+    CreateTextureSet(info, mImpl->mRenderer, sampler, hasMultipleTextColors, containsColorGlyph, styleEnabled, isOverlayStyle);
 
     verifiedHeight -= maxTextureSize;
 
@@ -719,7 +737,7 @@ void TextVisual::AddRenderer(Actor& actor, const Vector2& size, bool hasMultiple
       // New offset for tiling.
       info.offSet.y += maxTextureSize;
       // Create a textureset int the new tiling renderer.
-      CreateTextureSet(info, tilingRenderer, sampler, hasMultipleTextColors, containsColorGlyph, styleEnabled);
+      CreateTextureSet(info, tilingRenderer, sampler, hasMultipleTextColors, containsColorGlyph, styleEnabled, isOverlayStyle);
 
       verifiedHeight -= maxTextureSize;
     }
@@ -737,7 +755,7 @@ void TextVisual::AddRenderer(Actor& actor, const Vector2& size, bool hasMultiple
   }
 }
 
-TextureSet TextVisual::GetTextTexture(const Vector2& size, bool hasMultipleTextColors, bool containsColorGlyph, bool styleEnabled)
+TextureSet TextVisual::GetTextTexture(const Vector2& size, bool hasMultipleTextColors, bool containsColorGlyph, bool styleEnabled, bool isOverlayStyle)
 {
   // Filter mode needs to be set to linear to produce better quality while scaling.
   Sampler sampler = Sampler::New();
@@ -757,17 +775,19 @@ TextureSet TextVisual::GetTextTexture(const Vector2& size, bool hasMultipleTextC
   // It may happen the image atlas can't handle a pixel data it exceeds the maximum size.
   // In that case, create a texture. TODO: should tile the text.
   unsigned int textureSetIndex = 0u;
-
   AddTexture(textureSet, data, sampler, textureSetIndex);
   ++textureSetIndex;
 
   if(styleEnabled)
   {
-    // Create RGBA texture for all the text styles (without the text itself)
+    // Create RGBA texture for all the text styles that render in the background (without the text itself)
     PixelData styleData = mTypesetter->Render(size, textDirection, Text::Typesetter::RENDER_NO_TEXT, false, Pixel::RGBA8888);
-
     AddTexture(textureSet, styleData, sampler, textureSetIndex);
     ++textureSetIndex;
+    // Create RGBA texture for overlay styles such as underline and strikethrough (without the text itself)
+    PixelData overlayStyleData = mTypesetter->Render(size, textDirection, Text::Typesetter::RENDER_OVERLAY_STYLE, false, Pixel::RGBA8888);
+    AddTexture(textureSet, overlayStyleData, sampler, textureSetIndex);
+    ++textureSetIndex;
   }
 
   if(containsColorGlyph && !hasMultipleTextColors)
@@ -855,4 +875,4 @@ Shader TextVisual::GetTextShader(VisualFactoryCache& factoryCache, bool hasMulti
 
 } // namespace Toolkit
 
-} // namespace Dali
+} // namespace Dali
\ No newline at end of file
index f9d6c79..76f4bf9 100644 (file)
@@ -269,8 +269,9 @@ private:
    * @param[in] hasMultipleTextColors Whether the text contains multiple colors.
    * @param[in] containsColorGlyph Whether the text contains color glyph.
    * @param[in] styleEnabled Whether the text contains any styles (e.g. shadow, underline, etc.).
+   * @param[in] isOverlayStyle Whether the style needs to overlay on the text (e.g. strikethrough, underline, etc.).
    */
-  void CreateTextureSet(TilingInfo& info, Renderer& renderer, Sampler& sampler, bool hasMultipleTextColors, bool containsColorGlyph, bool styleEnabled);
+  void CreateTextureSet(TilingInfo& info, Renderer& renderer, Sampler& sampler, bool hasMultipleTextColors, bool containsColorGlyph, bool styleEnabled, bool isOverlayStyle);
 
   /**
    * Create renderer of the text for rendering.
@@ -279,8 +280,9 @@ private:
    * @param[in] hasMultipleTextColors Whether the text contains multiple colors.
    * @param[in] containsColorGlyph Whether the text contains color glyph.
    * @param[in] styleEnabled Whether the text contains any styles (e.g. shadow, underline, etc.).
+   * @param[in] isOverlayStyle Whether the style needs to overlay on the text (e.g. strikethrough, underline, etc.).
    */
-  void AddRenderer(Actor& actor, const Vector2& size, bool hasMultipleTextColors, bool containsColorGlyph, bool styleEnabled);
+  void AddRenderer(Actor& actor, const Vector2& size, bool hasMultipleTextColors, bool containsColorGlyph, bool styleEnabled, bool isOverlayStyle);
 
   /**
    * Get the texture of the text for rendering.
@@ -288,8 +290,9 @@ private:
    * @param[in] hasMultipleTextColors Whether the text contains multiple colors.
    * @param[in] containsColorGlyph Whether the text contains color glyph.
    * @param[in] styleEnabled Whether the text contains any styles (e.g. shadow, underline, etc.).
+   * @param[in] isOverlayStyle Whether the style needs to overlay on the text (e.g. strikethrough, underline, etc.).
    */
-  TextureSet GetTextTexture(const Vector2& size, bool hasMultipleTextColors, bool containsColorGlyph, bool styleEnabled);
+  TextureSet GetTextTexture(const Vector2& size, bool hasMultipleTextColors, bool containsColorGlyph, bool styleEnabled, bool isOverlayStyle);
 
   /**
    * Get the text rendering shader.
@@ -347,4 +350,4 @@ private:
 
 } // namespace Dali
 
-#endif /* DALI_TOOLKIT_INTERNAL_TEXT_VISUAL_H */
+#endif /* DALI_TOOLKIT_INTERNAL_TEXT_VISUAL_H */
\ No newline at end of file
index 53bcd1c..643fb21 100644 (file)
@@ -137,6 +137,7 @@ const char* const SHADOW_PROPERTY("shadow");
 const char* const UNDERLINE_PROPERTY("underline");
 const char* const OUTLINE_PROPERTY("outline");
 const char* const BACKGROUND_PROPERTY("textBackground");
+const char* const STRIKETHROUGH_PROPERTY("strikethrough");
 
 //NPatch visual
 const char* const BORDER_ONLY("borderOnly");
index 470ded9..1544206 100644 (file)
@@ -121,6 +121,7 @@ extern const char* const SHADOW_PROPERTY;
 extern const char* const UNDERLINE_PROPERTY;
 extern const char* const OUTLINE_PROPERTY;
 extern const char* const BACKGROUND_PROPERTY;
+extern const char* const STRIKETHROUGH_PROPERTY;
 
 //NPatch visual
 extern const char* const BORDER_ONLY;
index 81eb8d3..b644b08 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_TEXT_EDITOR_H
 
 /*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -449,16 +449,17 @@ public:
      */
     enum Mask
     {
-      NONE         = 0x0000, ///< @SINCE_1_2_2
-      COLOR        = 0x0001, ///< @SINCE_1_2_2
-      FONT_FAMILY  = 0x0002, ///< @SINCE_1_2_2
-      POINT_SIZE   = 0x0004, ///< @SINCE_1_2_2
-      FONT_STYLE   = 0x0008, ///< @SINCE_1_2_2
-      LINE_SPACING = 0x0010, ///< @SINCE_1_2_2
-      UNDERLINE    = 0x0020, ///< @SINCE_1_2_2
-      SHADOW       = 0x0040, ///< @SINCE_1_2_2
-      EMBOSS       = 0x0080, ///< @SINCE_1_2_2
-      OUTLINE      = 0x0100  ///< @SINCE_1_2_2
+      NONE          = 0x0000, ///< @SINCE_1_2_2
+      COLOR         = 0x0001, ///< @SINCE_1_2_2
+      FONT_FAMILY   = 0x0002, ///< @SINCE_1_2_2
+      POINT_SIZE    = 0x0004, ///< @SINCE_1_2_2
+      FONT_STYLE    = 0x0008, ///< @SINCE_1_2_2
+      LINE_SPACING  = 0x0010, ///< @SINCE_1_2_2
+      UNDERLINE     = 0x0020, ///< @SINCE_1_2_2
+      SHADOW        = 0x0040, ///< @SINCE_1_2_2
+      EMBOSS        = 0x0080, ///< @SINCE_1_2_2
+      OUTLINE       = 0x0100, ///< @SINCE_1_2_2
+      STRIKETHROUGH = 0x0200,
     };
   };
 
index 61bab1c..a99d1d2 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_TEXT_FIELD_H
 
 /*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -452,7 +452,7 @@ public:
        * @SINCE_1_2.60
        * @note PLACEHOLDER map is used to add ellipsis to placeholder text.
        */
-      ELLIPSIS
+      ELLIPSIS,
     };
   };
 
@@ -482,15 +482,16 @@ public:
    */
     enum Mask
     {
-      NONE        = 0x0000, ///< @SINCE_1_2_2
-      COLOR       = 0x0001, ///< @SINCE_1_2_2
-      FONT_FAMILY = 0x0002, ///< @SINCE_1_2_2
-      POINT_SIZE  = 0x0004, ///< @SINCE_1_2_2
-      FONT_STYLE  = 0x0008, ///< @SINCE_1_2_2
-      UNDERLINE   = 0x0010, ///< @SINCE_1_2_2
-      SHADOW      = 0x0020, ///< @SINCE_1_2_2
-      EMBOSS      = 0x0040, ///< @SINCE_1_2_2
-      OUTLINE     = 0x0080  ///< @SINCE_1_2_2
+      NONE          = 0x0000, ///< @SINCE_1_2_2
+      COLOR         = 0x0001, ///< @SINCE_1_2_2
+      FONT_FAMILY   = 0x0002, ///< @SINCE_1_2_2
+      POINT_SIZE    = 0x0004, ///< @SINCE_1_2_2
+      FONT_STYLE    = 0x0008, ///< @SINCE_1_2_2
+      UNDERLINE     = 0x0010, ///< @SINCE_1_2_2
+      SHADOW        = 0x0020, ///< @SINCE_1_2_2
+      EMBOSS        = 0x0040, ///< @SINCE_1_2_2
+      OUTLINE       = 0x0080, ///< @SINCE_1_2_2
+      STRIKETHROUGH = 0x1000
     };
   };
 
index 2d8c763..471a619 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_TEXT_LABEL_H
 
 /*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
index cdd1a1a..2ab1cba 100644 (file)
@@ -128,6 +128,12 @@ enum
    * @SINCE_1_2.60
    */
   UNDERLINE,
+
+  /**
+   * @brief The default strikethrough parameters.
+   * @details name "strikethrough", type Property::MAP.
+   */
+  STRIKETHROUGH,
 };
 
 } // namespace Property