Support rounded corners for Visual 02/224802/5
authorHeeyong Song <heeyong.song@samsung.com>
Thu, 13 Feb 2020 07:02:29 +0000 (16:02 +0900)
committerHeeyong Song <heeyong.song@samsung.com>
Tue, 18 Feb 2020 02:19:26 +0000 (02:19 +0000)
Change-Id: I22f9511af2f8a860e43f4e7c0c8ecc1ef4493eaf

17 files changed:
automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp
dali-toolkit/devel-api/visuals/visual-properties-devel.h
dali-toolkit/internal/visuals/animated-image/animated-image-visual.cpp
dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp
dali-toolkit/internal/visuals/color/color-visual.cpp
dali-toolkit/internal/visuals/gradient/gradient.cpp
dali-toolkit/internal/visuals/image-visual-shader-factory.cpp
dali-toolkit/internal/visuals/image-visual-shader-factory.h
dali-toolkit/internal/visuals/image/image-visual.cpp
dali-toolkit/internal/visuals/svg/svg-visual.cpp
dali-toolkit/internal/visuals/visual-base-data-impl.cpp
dali-toolkit/internal/visuals/visual-base-data-impl.h
dali-toolkit/internal/visuals/visual-base-impl.cpp
dali-toolkit/internal/visuals/visual-base-impl.h
dali-toolkit/internal/visuals/visual-factory-cache.h
dali-toolkit/internal/visuals/visual-string-constants.cpp
dali-toolkit/internal/visuals/visual-string-constants.h

index b605cc6..d26b857 100644 (file)
@@ -508,6 +508,7 @@ int UtcDaliVisualGetPropertyMap1(void)
   Property::Map propertyMap;
   propertyMap.Insert(Visual::Property::TYPE,  Visual::COLOR);
   propertyMap.Insert(Visual::Property::MIX_COLOR,  Color::BLUE);
   Property::Map propertyMap;
   propertyMap.Insert(Visual::Property::TYPE,  Visual::COLOR);
   propertyMap.Insert(Visual::Property::MIX_COLOR,  Color::BLUE);
+  propertyMap.Insert( DevelVisual::Property::CORNER_RADIUS, 10.0f );
   Visual::Base colorVisual = factory.CreateVisual( propertyMap );
 
   Property::Map resultMap;
   Visual::Base colorVisual = factory.CreateVisual( propertyMap );
 
   Property::Map resultMap;
@@ -521,6 +522,10 @@ int UtcDaliVisualGetPropertyMap1(void)
   DALI_TEST_CHECK( colorValue );
   DALI_TEST_CHECK( colorValue->Get<Vector4>() == Color::BLUE );
 
   DALI_TEST_CHECK( colorValue );
   DALI_TEST_CHECK( colorValue->Get<Vector4>() == Color::BLUE );
 
+  Property::Value* radiusValue = resultMap.Find( DevelVisual::Property::CORNER_RADIUS, Property::FLOAT );
+  DALI_TEST_CHECK( radiusValue );
+  DALI_TEST_CHECK( radiusValue->Get< float >() == 10.0f );
+
   // change the blend color
   propertyMap[ColorVisual::Property::MIX_COLOR] = Color::CYAN;
   colorVisual = factory.CreateVisual( propertyMap  );
   // change the blend color
   propertyMap[ColorVisual::Property::MIX_COLOR] = Color::CYAN;
   colorVisual = factory.CreateVisual( propertyMap  );
@@ -3577,3 +3582,73 @@ int UtcDaliSvgVisualCustomShader(void)
 
   END_TEST;
 }
 
   END_TEST;
 }
+
+int UtcDaliVisualRoundedCorner(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliVisualRoundedCorner" );
+
+  // image visual
+  {
+    VisualFactory factory = VisualFactory::Get();
+    Property::Map properties;
+    float cornerRadius = 30.0f;
+
+    properties[Visual::Property::TYPE] = Visual::IMAGE;
+    properties[ImageVisual::Property::URL] = TEST_IMAGE_FILE_NAME;
+    properties[DevelVisual::Property::CORNER_RADIUS] = cornerRadius;
+
+    Visual::Base visual = factory.CreateVisual( properties );
+
+    // trigger creation through setting on stage
+    DummyControl dummy = DummyControl::New( true );
+    Impl::DummyControl& dummyImpl = static_cast< Impl::DummyControl& >( dummy.GetImplementation() );
+    dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, visual );
+
+    dummy.SetSize( 200.f, 200.f );
+    dummy.SetParentOrigin( ParentOrigin::CENTER );
+    Stage::GetCurrent().Add( dummy );
+
+    application.SendNotification();
+    application.Render();
+
+    DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+
+    application.SendNotification();
+    application.Render();
+
+    DALI_TEST_EQUALS( application.GetGlAbstraction().CheckUniformValue< float >( "cornerRadius", cornerRadius ), true, TEST_LOCATION );
+  }
+
+  // color visual
+  {
+    VisualFactory factory = VisualFactory::Get();
+    Property::Map properties;
+    float cornerRadius = 30.0f;
+
+    properties[Visual::Property::TYPE] = Visual::COLOR;
+    properties[ColorVisual::Property::MIX_COLOR] = Color::BLUE;
+    properties["cornerRadius"] = cornerRadius;
+
+    Visual::Base visual = factory.CreateVisual( properties );
+
+    // trigger creation through setting on stage
+    DummyControl dummy = DummyControl::New( true );
+    Impl::DummyControl& dummyImpl = static_cast< Impl::DummyControl& >( dummy.GetImplementation() );
+    dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, visual );
+
+    dummy.SetSize( 200.f, 200.f );
+    dummy.SetParentOrigin( ParentOrigin::CENTER );
+    Stage::GetCurrent().Add( dummy );
+
+    application.SendNotification();
+    application.Render();
+
+    application.SendNotification();
+    application.Render();
+
+    DALI_TEST_EQUALS( application.GetGlAbstraction().CheckUniformValue< float >( "cornerRadius", cornerRadius ), true, TEST_LOCATION );
+  }
+
+  END_TEST;
+}
index 709b12a..5958037 100644 (file)
@@ -72,6 +72,13 @@ enum Type
    * @note The default is defined by the type of visual (if it's suitable to be stretched or not).
    */
   VISUAL_FITTING_MODE = OPACITY + 1,
    * @note The default is defined by the type of visual (if it's suitable to be stretched or not).
    */
   VISUAL_FITTING_MODE = OPACITY + 1,
+
+  /**
+   * @brief The radius for the rounded corners of the visual
+   * @details Name "cornerRadius", type Property::FLOAT or Property::VECTOR4.
+   * @note Optional.
+   */
+  CORNER_RADIUS = OPACITY + 2,
 };
 
 } // namespace Property
 };
 
 } // namespace Property
index a1c9331..f2160ef 100755 (executable)
@@ -444,7 +444,7 @@ void AnimatedImageVisual::CreateRenderer()
 {
   bool defaultWrapMode = mWrapModeU <= WrapMode::CLAMP_TO_EDGE && mWrapModeV <= WrapMode::CLAMP_TO_EDGE;
   bool atlasing = false;
 {
   bool defaultWrapMode = mWrapModeU <= WrapMode::CLAMP_TO_EDGE && mWrapModeV <= WrapMode::CLAMP_TO_EDGE;
   bool atlasing = false;
-  Shader shader = mImageVisualShaderFactory.GetShader( mFactoryCache, atlasing, defaultWrapMode );
+  Shader shader = mImageVisualShaderFactory.GetShader( mFactoryCache, atlasing, defaultWrapMode, IsRoundedCornerRequired() );
 
   Geometry geometry = mFactoryCache.GetGeometry( VisualFactoryCache::QUAD_GEOMETRY );
 
 
   Geometry geometry = mFactoryCache.GetGeometry( VisualFactoryCache::QUAD_GEOMETRY );
 
index 2ed0502..9b3fb7e 100644 (file)
@@ -267,7 +267,7 @@ void AnimatedVectorImageVisual::DoSetOnStage( Actor& actor )
   }
   else
   {
   }
   else
   {
-    shader = mImageVisualShaderFactory.GetShader( mFactoryCache, false, true );
+    shader = mImageVisualShaderFactory.GetShader( mFactoryCache, false, true, false );
   }
 
   Geometry geometry = mFactoryCache.GetGeometry( VisualFactoryCache::QUAD_GEOMETRY );
   }
 
   Geometry geometry = mFactoryCache.GetGeometry( VisualFactoryCache::QUAD_GEOMETRY );
index 9fa6a30..25ea34b 100644 (file)
@@ -78,6 +78,53 @@ const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER(
     gl_FragColor = vec4(mixColor, 1.0)*uColor;\n
   }\n
 );
     gl_FragColor = vec4(mixColor, 1.0)*uColor;\n
   }\n
 );
+
+const char* VERTEX_SHADER_ROUNDED_CORNER = DALI_COMPOSE_SHADER(
+  attribute mediump vec2 aPosition;\n
+  uniform highp   mat4 uMvpMatrix;\n
+  uniform mediump vec3 uSize;\n
+  varying mediump vec2 vPosition;\n
+  varying mediump vec2 vRectSize;\n
+  \n
+  //Visual size and offset
+  uniform mediump vec2 offset;\n
+  uniform mediump vec2 size;\n
+  uniform mediump vec4 offsetSizeMode;\n
+  uniform mediump vec2 origin;\n
+  uniform mediump vec2 anchorPoint;\n
+  uniform mediump float cornerRadius;\n
+  \n
+  vec4 ComputeVertexPosition()\n
+  {\n
+    vec2 visualSize = mix(uSize.xy*size, size, offsetSizeMode.zw );\n
+    vec2 visualOffset = mix( offset, offset/uSize.xy, offsetSizeMode.xy);\n
+    vRectSize = visualSize / 2.0 - cornerRadius;\n
+    vPosition = aPosition* visualSize;\n
+    return vec4( vPosition + anchorPoint*visualSize + (visualOffset + origin)*uSize.xy, 0.0, 1.0 );\n
+  }\n
+  \n
+  void main()\n
+  {\n
+    gl_Position = uMvpMatrix * ComputeVertexPosition();\n
+  }\n
+);
+
+//float distance = length( max( abs( position - center ), size ) - size ) - radius;
+const char* FRAGMENT_SHADER_ROUNDED_CORNER = DALI_COMPOSE_SHADER(
+  varying mediump vec2 vPosition;\n
+  varying mediump vec2 vRectSize;\n
+  uniform lowp vec4 uColor;\n
+  uniform lowp vec3 mixColor;\n
+  uniform mediump float cornerRadius;\n
+  \n
+  void main()\n
+  {\n
+      mediump float dist = length( max( abs( vPosition ), vRectSize ) - vRectSize ) - cornerRadius;\n
+      gl_FragColor = uColor * vec4( mixColor, 1.0 );\n
+      gl_FragColor.a *= smoothstep( 1.0, -1.0, dist );\n
+  }\n
+);
+
 }
 
 ColorVisualPtr ColorVisual::New( VisualFactoryCache& factoryCache, const Property::Map& properties )
 }
 
 ColorVisualPtr ColorVisual::New( VisualFactoryCache& factoryCache, const Property::Map& properties )
@@ -175,11 +222,24 @@ void ColorVisual::InitializeRenderer()
 {
   Geometry geometry = mFactoryCache.GetGeometry( VisualFactoryCache::QUAD_GEOMETRY );
 
 {
   Geometry geometry = mFactoryCache.GetGeometry( VisualFactoryCache::QUAD_GEOMETRY );
 
-  Shader shader = mFactoryCache.GetShader( VisualFactoryCache::COLOR_SHADER );
-  if( !shader )
+  Shader shader;
+  if( !IsRoundedCornerRequired() )
   {
   {
-    shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER );
-    mFactoryCache.SaveShader( VisualFactoryCache::COLOR_SHADER, shader );
+    shader = mFactoryCache.GetShader( VisualFactoryCache::COLOR_SHADER );
+    if( !shader )
+    {
+      shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER );
+      mFactoryCache.SaveShader( VisualFactoryCache::COLOR_SHADER, shader );
+    }
+  }
+  else
+  {
+    shader = mFactoryCache.GetShader( VisualFactoryCache::COLOR_SHADER_ROUNDED_CORNER );
+    if( !shader )
+    {
+      shader = Shader::New( VERTEX_SHADER_ROUNDED_CORNER, FRAGMENT_SHADER_ROUNDED_CORNER );
+      mFactoryCache.SaveShader( VisualFactoryCache::COLOR_SHADER_ROUNDED_CORNER, shader );
+    }
   }
 
   mImpl->mRenderer = Renderer::New( geometry, shader );
   }
 
   mImpl->mRenderer = Renderer::New( geometry, shader );
index 3846911..2c90e52 100644 (file)
@@ -153,7 +153,7 @@ Dali::Texture Gradient::GenerateLookupTexture()
 
     for( int j = segmentStart; j<segmentEnd; j++ )
     {
 
     for( int j = segmentStart; j<segmentEnd; j++ )
     {
-      float ratio = static_cast<float>(j-segmentStart)/segmentWidth;
+      float ratio = static_cast<float>(j-segmentStart)/(segmentWidth - 1);
       Vector4 currentColor = mGradientStops[i].mStopColor * (1.f-ratio) + mGradientStops[i+1].mStopColor * ratio;
       pixels[k*4] = static_cast<unsigned char>( 255.f * Clamp( currentColor.r, 0.f, 1.f ) );
       pixels[k*4+1] = static_cast<unsigned char>( 255.f * Clamp( currentColor.g, 0.f, 1.f ) );
       Vector4 currentColor = mGradientStops[i].mStopColor * (1.f-ratio) + mGradientStops[i+1].mStopColor * ratio;
       pixels[k*4] = static_cast<unsigned char>( 255.f * Clamp( currentColor.r, 0.f, 1.f ) );
       pixels[k*4+1] = static_cast<unsigned char>( 255.f * Clamp( currentColor.g, 0.f, 1.f ) );
index 0dec934..5d35517 100644 (file)
@@ -120,6 +120,57 @@ const char* FRAGMENT_SHADER_ATLAS_VARIOUS_WRAP = DALI_COMPOSE_SHADER(
     }\n
 );
 
     }\n
 );
 
+const char* VERTEX_SHADER_ROUNDED_CORNER = DALI_COMPOSE_SHADER(
+  attribute mediump vec2 aPosition;\n
+  uniform highp   mat4 uMvpMatrix;\n
+  uniform mediump vec3 uSize;\n
+  uniform mediump vec4 pixelArea;
+  varying mediump vec2 vTexCoord;\n
+  varying mediump vec2 vPosition;\n
+  varying mediump vec2 vRectSize;\n
+  \n
+  //Visual size and offset
+  uniform mediump vec2 offset;\n
+  uniform mediump vec2 size;\n
+  uniform mediump vec4 offsetSizeMode;\n
+  uniform mediump vec2 origin;\n
+  uniform mediump vec2 anchorPoint;\n
+  uniform mediump float cornerRadius;\n
+  \n
+  vec4 ComputeVertexPosition()\n
+  {\n
+    vec2 visualSize = mix(uSize.xy*size, size, offsetSizeMode.zw );\n
+    vec2 visualOffset = mix( offset, offset/uSize.xy, offsetSizeMode.xy);\n
+    vRectSize = visualSize / 2.0 - cornerRadius;\n
+    vPosition = aPosition* visualSize;\n
+    return vec4( vPosition + anchorPoint*visualSize + (visualOffset + origin)*uSize.xy, 0.0, 1.0 );\n
+  }\n
+\n
+  void main()\n
+  {\n
+    gl_Position = uMvpMatrix * ComputeVertexPosition();\n
+    vTexCoord = pixelArea.xy+pixelArea.zw*(aPosition + vec2(0.5) );\n
+  }\n
+);
+
+//float distance = length( max( abs( position - center ), size ) - size ) - radius;
+const char* FRAGMENT_SHADER_ROUNDED_CORNER = DALI_COMPOSE_SHADER(
+  varying mediump vec2 vTexCoord;\n
+  varying mediump vec2 vPosition;\n
+  varying mediump vec2 vRectSize;\n
+  uniform sampler2D sTexture;\n
+  uniform lowp vec4 uColor;\n
+  uniform lowp vec3 mixColor;\n
+  uniform mediump float cornerRadius;\n
+  \n
+  void main()\n
+  {\n
+      mediump float dist = length( max( abs( vPosition ), vRectSize ) - vRectSize ) - cornerRadius;\n
+      gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor * vec4( mixColor, 1.0 );\n
+      gl_FragColor.a *= smoothstep( 1.0, -1.0, dist );\n
+  }\n
+);
+
 } // unnamed namespace
 
 ImageVisualShaderFactory::ImageVisualShaderFactory()
 } // unnamed namespace
 
 ImageVisualShaderFactory::ImageVisualShaderFactory()
@@ -130,7 +181,7 @@ ImageVisualShaderFactory::~ImageVisualShaderFactory()
 {
 }
 
 {
 }
 
-Shader ImageVisualShaderFactory::GetShader( VisualFactoryCache& factoryCache, bool atlasing, bool defaultTextureWrapping )
+Shader ImageVisualShaderFactory::GetShader( VisualFactoryCache& factoryCache, bool atlasing, bool defaultTextureWrapping, bool roundedCorner )
 {
   Shader shader;
   if( atlasing )
 {
   Shader shader;
   if( atlasing )
@@ -158,12 +209,25 @@ Shader ImageVisualShaderFactory::GetShader( VisualFactoryCache& factoryCache, bo
   }
   else
   {
   }
   else
   {
-    shader = factoryCache.GetShader( VisualFactoryCache::IMAGE_SHADER );
-    if( !shader )
+    if( roundedCorner )
+    {
+      shader = factoryCache.GetShader( VisualFactoryCache::IMAGE_SHADER_ROUNDED_CORNER );
+      if( !shader )
+      {
+        shader = Shader::New( VERTEX_SHADER_ROUNDED_CORNER, FRAGMENT_SHADER_ROUNDED_CORNER );
+        shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT );
+        factoryCache.SaveShader( VisualFactoryCache::IMAGE_SHADER_ROUNDED_CORNER, shader );
+      }
+    }
+    else
     {
     {
-      shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_NO_ATLAS );
-      shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT );
-      factoryCache.SaveShader( VisualFactoryCache::IMAGE_SHADER, shader );
+      shader = factoryCache.GetShader( VisualFactoryCache::IMAGE_SHADER );
+      if( !shader )
+      {
+        shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_NO_ATLAS );
+        shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT );
+        factoryCache.SaveShader( VisualFactoryCache::IMAGE_SHADER, shader );
+      }
     }
   }
 
     }
   }
 
index 58b4dd0..c5344d3 100644 (file)
@@ -55,8 +55,9 @@ public:
    * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
    * @param[in] atlasing Whether texture atlasing is applied.
    * @param[in] defaultTextureWrapping Whether the default texture wrap mode is applied.
    * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
    * @param[in] atlasing Whether texture atlasing is applied.
    * @param[in] defaultTextureWrapping Whether the default texture wrap mode is applied.
+   * @param[in] roundedCorner Whether the rounded corder is applied.
    */
    */
-  Shader GetShader( VisualFactoryCache& factoryCache, bool atlasing, bool defaultTextureWrapping );
+  Shader GetShader( VisualFactoryCache& factoryCache, bool atlasing, bool defaultTextureWrapping, bool roundedCorner );
 
   /**
    * Request the default vertex shader source.
 
   /**
    * Request the default vertex shader source.
index ceb3669..59b68fd 100644 (file)
@@ -567,7 +567,8 @@ void ImageVisual::CreateRenderer( TextureSet& textureSet )
 
     shader = mImageVisualShaderFactory.GetShader( mFactoryCache,
                              mImpl->mFlags & Impl::IS_ATLASING_APPLIED,
 
     shader = mImageVisualShaderFactory.GetShader( mFactoryCache,
                              mImpl->mFlags & Impl::IS_ATLASING_APPLIED,
-                             mWrapModeU <= WrapMode::CLAMP_TO_EDGE && mWrapModeV <= WrapMode::CLAMP_TO_EDGE );
+                             mWrapModeU <= WrapMode::CLAMP_TO_EDGE && mWrapModeV <= WrapMode::CLAMP_TO_EDGE,
+                             IsRoundedCornerRequired() );
   }
   else
   {
   }
   else
   {
index 45566bc..e4275cd 100644 (file)
@@ -122,7 +122,7 @@ void SvgVisual::DoSetOnStage( Actor& actor )
   Shader shader;
   if( !mImpl->mCustomShader )
   {
   Shader shader;
   if( !mImpl->mCustomShader )
   {
-    shader = mImageVisualShaderFactory.GetShader( mFactoryCache, mAttemptAtlasing, true );
+    shader = mImageVisualShaderFactory.GetShader( mFactoryCache, mAttemptAtlasing, true, false );
   }
   else
   {
   }
   else
   {
index 3702aa3..67d54d5 100644 (file)
@@ -121,8 +121,10 @@ Internal::Visual::Base::Impl::Impl(FittingMode fittingMode)
   mTransform(),
   mMixColor( Color::WHITE ),
   mControlSize( Vector2::ZERO ),
   mTransform(),
   mMixColor( Color::WHITE ),
   mControlSize( Vector2::ZERO ),
+  mCornerRadius( 0.0f ),
   mDepthIndex( 0.0f ),
   mMixColorIndex( Property::INVALID_INDEX ),
   mDepthIndex( 0.0f ),
   mMixColorIndex( Property::INVALID_INDEX ),
+  mCornerRadiusIndex( Property::INVALID_INDEX ),
   mFittingMode( fittingMode ),
   mFlags( 0 ),
   mResourceStatus( Toolkit::Visual::ResourceStatus::PREPARING )
   mFittingMode( fittingMode ),
   mFlags( 0 ),
   mResourceStatus( Toolkit::Visual::ResourceStatus::PREPARING )
index 4adcc5a..123a722 100644 (file)
@@ -124,8 +124,10 @@ struct Base::Impl
   Transform       mTransform;
   Vector4         mMixColor;
   Size            mControlSize;
   Transform       mTransform;
   Vector4         mMixColor;
   Size            mControlSize;
+  float           mCornerRadius;
   int             mDepthIndex;
   Property::Index mMixColorIndex;
   int             mDepthIndex;
   Property::Index mMixColorIndex;
+  Property::Index mCornerRadiusIndex;
   FittingMode     mFittingMode;  //< How the contents should fit the view
   int             mFlags;
   Toolkit::Visual::ResourceStatus  mResourceStatus;
   FittingMode     mFittingMode;  //< How the contents should fit the view
   int             mFlags;
   Toolkit::Visual::ResourceStatus  mResourceStatus;
index d14dcd3..3abe018 100755 (executable)
@@ -121,6 +121,10 @@ void Visual::Base::SetProperties( const Property::Map& propertyMap )
       {
         matchKey = Property::Key( Toolkit::DevelVisual::Property::VISUAL_FITTING_MODE );
       }
       {
         matchKey = Property::Key( Toolkit::DevelVisual::Property::VISUAL_FITTING_MODE );
       }
+      else if( matchKey == CORNER_RADIUS )
+      {
+        matchKey = Property::Key( Toolkit::DevelVisual::Property::CORNER_RADIUS );
+      }
     }
 
     switch( matchKey.indexKey )
     }
 
     switch( matchKey.indexKey )
@@ -188,6 +192,15 @@ void Visual::Base::SetProperties( const Property::Map& propertyMap )
           value, VISUAL_FITTING_MODE_TABLE, VISUAL_FITTING_MODE_TABLE_COUNT, mImpl->mFittingMode );
         break;
       }
           value, VISUAL_FITTING_MODE_TABLE, VISUAL_FITTING_MODE_TABLE_COUNT, mImpl->mFittingMode );
         break;
       }
+      case Toolkit::DevelVisual::Property::CORNER_RADIUS:
+      {
+        float radius;
+        if( value.Get( radius ) )
+        {
+          mImpl->mCornerRadius = radius;
+        }
+        break;
+      }
     }
   }
 
     }
   }
 
@@ -279,6 +292,13 @@ void Visual::Base::SetOnStage( Actor& actor )
     {
       RegisterMixColor();
 
     {
       RegisterMixColor();
 
+      if( IsRoundedCornerRequired() )
+      {
+        mImpl->mCornerRadiusIndex = mImpl->mRenderer.RegisterProperty( CORNER_RADIUS, mImpl->mCornerRadius );
+
+        mImpl->mRenderer.SetProperty( Renderer::Property::BLEND_MODE, BlendMode::ON );
+      }
+
       mImpl->mRenderer.SetProperty( Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA, IsPreMultipliedAlphaEnabled());
       mImpl->mRenderer.SetProperty( Renderer::Property::DEPTH_INDEX, mImpl->mDepthIndex );
       mImpl->mFlags |= Impl::IS_ON_STAGE; // Only sets the flag if renderer exists
       mImpl->mRenderer.SetProperty( Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA, IsPreMultipliedAlphaEnabled());
       mImpl->mRenderer.SetProperty( Renderer::Property::DEPTH_INDEX, mImpl->mDepthIndex );
       mImpl->mFlags |= Impl::IS_ON_STAGE; // Only sets the flag if renderer exists
@@ -292,6 +312,7 @@ void Visual::Base::SetOffStage( Actor& actor )
   {
     DoSetOffStage( actor );
     mImpl->mMixColorIndex = Property::INVALID_INDEX;
   {
     DoSetOffStage( actor );
     mImpl->mMixColorIndex = Property::INVALID_INDEX;
+    mImpl->mCornerRadiusIndex = Property::INVALID_INDEX;
     mImpl->mFlags &= ~Impl::IS_ON_STAGE;
   }
 }
     mImpl->mFlags &= ~Impl::IS_ON_STAGE;
   }
 }
@@ -320,6 +341,8 @@ void Visual::Base::CreatePropertyMap( Property::Map& map ) const
   auto fittingModeString = Scripting::GetLinearEnumerationName< FittingMode >(
     mImpl->mFittingMode, VISUAL_FITTING_MODE_TABLE, VISUAL_FITTING_MODE_TABLE_COUNT );
   map.Insert( Toolkit::DevelVisual::Property::VISUAL_FITTING_MODE, fittingModeString );
   auto fittingModeString = Scripting::GetLinearEnumerationName< FittingMode >(
     mImpl->mFittingMode, VISUAL_FITTING_MODE_TABLE, VISUAL_FITTING_MODE_TABLE_COUNT );
   map.Insert( Toolkit::DevelVisual::Property::VISUAL_FITTING_MODE, fittingModeString );
+
+  map.Insert( Toolkit::DevelVisual::Property::CORNER_RADIUS, mImpl->mCornerRadius );
 }
 
 void Visual::Base::CreateInstancePropertyMap( Property::Map& map ) const
 }
 
 void Visual::Base::CreateInstancePropertyMap( Property::Map& map ) const
@@ -370,6 +393,11 @@ bool Visual::Base::IsOnStage() const
   return mImpl->mFlags & Impl::IS_ON_STAGE;
 }
 
   return mImpl->mFlags & Impl::IS_ON_STAGE;
 }
 
+bool Visual::Base::IsRoundedCornerRequired() const
+{
+  return !EqualsZero( mImpl->mCornerRadius );
+}
+
 void Visual::Base::OnDoAction( const Property::Index actionId, const Property::Value& attributes )
 {
   // May be overriden by derived class
 void Visual::Base::OnDoAction( const Property::Index actionId, const Property::Value& attributes )
 {
   // May be overriden by derived class
index 754c838..ecf832c 100644 (file)
@@ -344,6 +344,13 @@ protected:
    */
   bool IsOnStage() const;
 
    */
   bool IsOnStage() const;
 
+  /**
+   * @brief Query whether the corners of the visual requires to be rounded.
+   *
+   * @return Returns true if the rounded corner is required, false otherwise.
+   */
+  bool IsRoundedCornerRequired() const;
+
 private:
 
   /**
 private:
 
   /**
index e080d52..f01260f 100644 (file)
@@ -58,6 +58,7 @@ public:
   enum ShaderType
   {
     COLOR_SHADER,
   enum ShaderType
   {
     COLOR_SHADER,
+    COLOR_SHADER_ROUNDED_CORNER,
     BORDER_SHADER,
     BORDER_SHADER_ANTI_ALIASING,
     GRADIENT_SHADER_LINEAR_USER_SPACE,
     BORDER_SHADER,
     BORDER_SHADER_ANTI_ALIASING,
     GRADIENT_SHADER_LINEAR_USER_SPACE,
@@ -67,6 +68,7 @@ public:
     IMAGE_SHADER,
     IMAGE_SHADER_ATLAS_DEFAULT_WRAP,
     IMAGE_SHADER_ATLAS_CUSTOM_WRAP,
     IMAGE_SHADER,
     IMAGE_SHADER_ATLAS_DEFAULT_WRAP,
     IMAGE_SHADER_ATLAS_CUSTOM_WRAP,
+    IMAGE_SHADER_ROUNDED_CORNER,
     NINE_PATCH_SHADER,
     NINE_PATCH_MASK_SHADER,
     TEXT_SHADER_MULTI_COLOR_TEXT,
     NINE_PATCH_SHADER,
     NINE_PATCH_MASK_SHADER,
     TEXT_SHADER_MULTI_COLOR_TEXT,
index af16305..64b6f84 100644 (file)
@@ -76,6 +76,9 @@ const char * const OPACITY( "opacity" );
 // Fitting mode
 const char * const VISUAL_FITTING_MODE( "visualFittingMode" );
 
 // Fitting mode
 const char * const VISUAL_FITTING_MODE( "visualFittingMode" );
 
+// Corner radius
+const char * const CORNER_RADIUS( "cornerRadius" );
+
 // Color visual
 const char * const RENDER_IF_TRANSPARENT_NAME( "renderIfTransparent" );
 
 // Color visual
 const char * const RENDER_IF_TRANSPARENT_NAME( "renderIfTransparent" );
 
index fff497f..c8311f9 100644 (file)
@@ -61,6 +61,9 @@ extern const char * const OPACITY;
 // Fitting mode
 extern const char * const VISUAL_FITTING_MODE;
 
 // Fitting mode
 extern const char * const VISUAL_FITTING_MODE;
 
+// Corner radius
+extern const char * const CORNER_RADIUS;
+
 // Color visual
 extern const char * const RENDER_IF_TRANSPARENT_NAME;
 
 // Color visual
 extern const char * const RENDER_IF_TRANSPARENT_NAME;