Add Conic Gradient 82/323382/8
authorANZ1217 <chihun.jeong@samsung.com>
Mon, 28 Apr 2025 04:29:44 +0000 (13:29 +0900)
committerANZ1217 <chihun.jeong@samsung.com>
Thu, 8 May 2025 04:34:43 +0000 (13:34 +0900)
Change-Id: I878ec576e6cea14d09bc7f117eb3e1ff8e054148

automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp
dali-toolkit/internal/file.list
dali-toolkit/internal/graphics/shaders/gradient-visual-shader.frag
dali-toolkit/internal/visuals/gradient/conic-gradient.cpp [new file with mode: 0644]
dali-toolkit/internal/visuals/gradient/conic-gradient.h [new file with mode: 0644]
dali-toolkit/internal/visuals/gradient/gradient-visual.cpp
dali-toolkit/internal/visuals/gradient/gradient-visual.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
dali-toolkit/public-api/visuals/gradient-visual-properties.h

index f3fc551cee43639ccc46332d300395c12e1af143..cb6055a27ff14f5d3a63be01d1e6cd69432a3056 100644 (file)
@@ -1888,6 +1888,176 @@ int UtcDaliVisualGetPropertyMap13(void)
   END_TEST;
 }
 
+int UtcDaliVisualGetPropertyMap14(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliVisualGetPropertyMap14: conic GradientVisual");
+
+  VisualFactory factory = VisualFactory::Get();
+  DALI_TEST_CHECK(factory);
+
+  Property::Map propertyMap;
+  propertyMap.Insert(Visual::Property::TYPE, Visual::GRADIENT);
+
+  Vector2 center(100.f, 100.f);
+  float   startAngle = -Math::PI;
+  propertyMap.Insert(GradientVisual::Property::UNITS, GradientVisual::Units::USER_SPACE);
+  propertyMap.Insert(GradientVisual::Property::CENTER, center);
+  propertyMap.Insert(GradientVisual::Property::START_ANGLE, startAngle);
+  propertyMap.Insert(GradientVisual::Property::STOP_OFFSET, Vector3(0.1f, 0.3f, 1.1f));
+
+  Property::Array stopColors;
+  stopColors.PushBack(Color::RED);
+  stopColors.PushBack(Color::BLACK);
+  stopColors.PushBack(Color::GREEN);
+  propertyMap.Insert(GradientVisual::Property::STOP_COLOR, stopColors);
+
+  float   borderlineWidth = 8.0f;
+  Vector4 cornerRadius(1.0f, 2.0f, 4.0f, 8.0f);
+  propertyMap.Insert(DevelVisual::Property::BORDERLINE_WIDTH, borderlineWidth);
+  propertyMap.Insert(DevelVisual::Property::CORNER_RADIUS, cornerRadius);
+
+  Visual::Base gradientVisual = factory.CreateVisual(propertyMap);
+  DALI_TEST_CHECK(gradientVisual);
+
+  Property::Map resultMap;
+  gradientVisual.CreatePropertyMap(resultMap);
+
+  // check the property values from the returned map from visual
+  Property::Value* value = resultMap.Find(Toolkit::Visual::Property::TYPE, Property::INTEGER);
+  DALI_TEST_CHECK(value);
+  DALI_TEST_CHECK(value->Get<int>() == Visual::GRADIENT);
+
+  value = resultMap.Find(GradientVisual::Property::UNITS, Property::INTEGER);
+  DALI_TEST_CHECK(value);
+  DALI_TEST_CHECK(value->Get<int>() == GradientVisual::Units::USER_SPACE);
+
+  value = resultMap.Find(GradientVisual::Property::SPREAD_METHOD, Property::INTEGER);
+  DALI_TEST_CHECK(value);
+  DALI_TEST_CHECK(value->Get<int>() == GradientVisual::SpreadMethod::PAD);
+
+  value = resultMap.Find(GradientVisual::Property::CENTER, Property::VECTOR2);
+  DALI_TEST_CHECK(value);
+  DALI_TEST_EQUALS(value->Get<Vector2>(), center, Math::MACHINE_EPSILON_100, TEST_LOCATION);
+
+  value = resultMap.Find(GradientVisual::Property::START_ANGLE, Property::FLOAT);
+  DALI_TEST_CHECK(value);
+  // start angle will be wraped to [0.0, 2*PI];
+  DALI_TEST_EQUALS(value->Get<float>(), Math::PI, Math::MACHINE_EPSILON_100, TEST_LOCATION);
+
+  value = resultMap.Find(DevelVisual::Property::BORDERLINE_WIDTH, Property::FLOAT);
+  DALI_TEST_CHECK(value);
+  DALI_TEST_EQUALS(value->Get<float>(), borderlineWidth, Math::MACHINE_EPSILON_100, TEST_LOCATION);
+
+  value = resultMap.Find(DevelVisual::Property::CORNER_RADIUS, Property::VECTOR4);
+  DALI_TEST_CHECK(value);
+  DALI_TEST_EQUALS(value->Get<Vector4>(), cornerRadius, Math::MACHINE_EPSILON_100, TEST_LOCATION);
+
+  value = resultMap.Find(GradientVisual::Property::STOP_OFFSET, Property::ARRAY);
+  DALI_TEST_CHECK(value);
+  Property::Array* offsetArray = value->GetArray();
+  DALI_TEST_CHECK(offsetArray->Count() == 3);
+  DALI_TEST_EQUALS(offsetArray->GetElementAt(0).Get<float>(), 0.1f, Math::MACHINE_EPSILON_100, TEST_LOCATION);
+  DALI_TEST_EQUALS(offsetArray->GetElementAt(1).Get<float>(), 0.3f, Math::MACHINE_EPSILON_100, TEST_LOCATION);
+  // any stop value will be clamped to [0.0, 1.0];
+  DALI_TEST_EQUALS(offsetArray->GetElementAt(2).Get<float>(), 1.0f, Math::MACHINE_EPSILON_100, TEST_LOCATION);
+
+  value = resultMap.Find(GradientVisual::Property::STOP_COLOR, Property::ARRAY);
+  DALI_TEST_CHECK(value);
+  Property::Array* colorArray = value->GetArray();
+  DALI_TEST_CHECK(colorArray->Count() == 3);
+  DALI_TEST_EQUALS(colorArray->GetElementAt(0).Get<Vector4>(), Color::RED, Math::MACHINE_EPSILON_100, TEST_LOCATION);
+  DALI_TEST_EQUALS(colorArray->GetElementAt(1).Get<Vector4>(), Color::BLACK, Math::MACHINE_EPSILON_100, TEST_LOCATION);
+  DALI_TEST_EQUALS(colorArray->GetElementAt(2).Get<Vector4>(), Color::GREEN, Math::MACHINE_EPSILON_100, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliVisualGetPropertyMap15(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliVisualGetPropertyMap15: conic GradientVisual");
+
+  VisualFactory factory = VisualFactory::Get();
+  DALI_TEST_CHECK(factory);
+
+  Property::Map propertyMap;
+  propertyMap.Insert(Visual::Property::TYPE, Visual::GRADIENT);
+
+  Vector2 center(0.f, 0.f);
+  float   startAngle = 3 * Math::PI;
+  propertyMap.Insert(GradientVisual::Property::UNITS, GradientVisual::Units::USER_SPACE);
+  propertyMap.Insert(GradientVisual::Property::CENTER, center);
+  propertyMap.Insert(GradientVisual::Property::START_ANGLE, startAngle);
+  propertyMap.Insert(GradientVisual::Property::STOP_OFFSET, Vector3(0.1f, 0.3f, 1.1f));
+
+  Property::Array stopColors;
+  stopColors.PushBack(Color::RED);
+  stopColors.PushBack(Color::BLACK);
+  stopColors.PushBack(Color::GREEN);
+  propertyMap.Insert(GradientVisual::Property::STOP_COLOR, stopColors);
+
+  float   borderlineWidth = 8.0f;
+  Vector4 cornerRadius(1.0f, 2.0f, 4.0f, 8.0f);
+  propertyMap.Insert(DevelVisual::Property::BORDERLINE_WIDTH, borderlineWidth);
+  propertyMap.Insert(DevelVisual::Property::CORNER_RADIUS, cornerRadius);
+
+  Visual::Base gradientVisual = factory.CreateVisual(propertyMap);
+  DALI_TEST_CHECK(gradientVisual);
+
+  Property::Map resultMap;
+  gradientVisual.CreatePropertyMap(resultMap);
+
+  // check the property values from the returned map from visual
+  Property::Value* value = resultMap.Find(Toolkit::Visual::Property::TYPE, Property::INTEGER);
+  DALI_TEST_CHECK(value);
+  DALI_TEST_CHECK(value->Get<int>() == Visual::GRADIENT);
+
+  value = resultMap.Find(GradientVisual::Property::UNITS, Property::INTEGER);
+  DALI_TEST_CHECK(value);
+  DALI_TEST_CHECK(value->Get<int>() == GradientVisual::Units::USER_SPACE);
+
+  value = resultMap.Find(GradientVisual::Property::SPREAD_METHOD, Property::INTEGER);
+  DALI_TEST_CHECK(value);
+  DALI_TEST_CHECK(value->Get<int>() == GradientVisual::SpreadMethod::PAD);
+
+  value = resultMap.Find(GradientVisual::Property::CENTER, Property::VECTOR2);
+  DALI_TEST_CHECK(value);
+  DALI_TEST_EQUALS(value->Get<Vector2>(), center, Math::MACHINE_EPSILON_100, TEST_LOCATION);
+
+  value = resultMap.Find(GradientVisual::Property::START_ANGLE, Property::FLOAT);
+  DALI_TEST_CHECK(value);
+  // start angle will be wraped to [0.0, 2*PI];
+  DALI_TEST_EQUALS(value->Get<float>(), Math::PI, Math::MACHINE_EPSILON_100, TEST_LOCATION);
+
+  value = resultMap.Find(DevelVisual::Property::BORDERLINE_WIDTH, Property::FLOAT);
+  DALI_TEST_CHECK(value);
+  DALI_TEST_EQUALS(value->Get<float>(), borderlineWidth, Math::MACHINE_EPSILON_100, TEST_LOCATION);
+
+  value = resultMap.Find(DevelVisual::Property::CORNER_RADIUS, Property::VECTOR4);
+  DALI_TEST_CHECK(value);
+  DALI_TEST_EQUALS(value->Get<Vector4>(), cornerRadius, Math::MACHINE_EPSILON_100, TEST_LOCATION);
+
+  value = resultMap.Find(GradientVisual::Property::STOP_OFFSET, Property::ARRAY);
+  DALI_TEST_CHECK(value);
+  Property::Array* offsetArray = value->GetArray();
+  DALI_TEST_CHECK(offsetArray->Count() == 3);
+  DALI_TEST_EQUALS(offsetArray->GetElementAt(0).Get<float>(), 0.1f, Math::MACHINE_EPSILON_100, TEST_LOCATION);
+  DALI_TEST_EQUALS(offsetArray->GetElementAt(1).Get<float>(), 0.3f, Math::MACHINE_EPSILON_100, TEST_LOCATION);
+  // any stop value will be clamped to [0.0, 1.0];
+  DALI_TEST_EQUALS(offsetArray->GetElementAt(2).Get<float>(), 1.0f, Math::MACHINE_EPSILON_100, TEST_LOCATION);
+
+  value = resultMap.Find(GradientVisual::Property::STOP_COLOR, Property::ARRAY);
+  DALI_TEST_CHECK(value);
+  Property::Array* colorArray = value->GetArray();
+  DALI_TEST_CHECK(colorArray->Count() == 3);
+  DALI_TEST_EQUALS(colorArray->GetElementAt(0).Get<Vector4>(), Color::RED, Math::MACHINE_EPSILON_100, TEST_LOCATION);
+  DALI_TEST_EQUALS(colorArray->GetElementAt(1).Get<Vector4>(), Color::BLACK, Math::MACHINE_EPSILON_100, TEST_LOCATION);
+  DALI_TEST_EQUALS(colorArray->GetElementAt(2).Get<Vector4>(), Color::GREEN, Math::MACHINE_EPSILON_100, TEST_LOCATION);
+
+  END_TEST;
+}
+
 int UtcDaliVisualAnimateArcVisual(void)
 {
   ToolkitTestApplication application;
index 7e746911e187bc8c76f53425cb85ded030cb81a5..3d4092d385067791beffbc343b4678135a52c7e1 100644 (file)
@@ -40,6 +40,7 @@ SET( toolkit_src_files
    ${toolkit_src_dir}/visuals/custom-shader-factory.cpp
    ${toolkit_src_dir}/visuals/gradient/gradient-visual.cpp
    ${toolkit_src_dir}/visuals/gradient/gradient.cpp
+   ${toolkit_src_dir}/visuals/gradient/conic-gradient.cpp
    ${toolkit_src_dir}/visuals/gradient/linear-gradient.cpp
    ${toolkit_src_dir}/visuals/gradient/radial-gradient.cpp
    ${toolkit_src_dir}/visuals/animated-gradient/animated-gradient-visual.cpp
index 338dc4b042739aac29412305aee792230bf98c3a..a8e3eedebb0aa5ddcc16c73af48d15247844906b 100644 (file)
@@ -32,6 +32,10 @@ UNIFORM_BLOCK FragBlock
 #ifdef IS_REQUIRED_SQUIRCLE_CORNER
   UNIFORM highp vec4 cornerSquareness;
 #endif
+
+#ifdef CONIC
+  UNIFORM highp float uStartAngle;
+#endif
 };
 
 #ifdef IS_REQUIRED_BORDERLINE
@@ -257,6 +261,12 @@ void main()
 #ifdef RADIAL
   mediump float radialTexCoord = ((length(vTexCoord) - 0.5) * uTextureCoordinateScaleFactor) + 0.5;
   lowp vec4 textureColor = TEXTURE(sTexture, vec2(radialTexCoord + uGradientOffset, 0.5)) * uColor;
+#elif defined(CONIC)
+  highp float angle = atan(vTexCoord.y, vTexCoord.x);
+  angle -= uStartAngle;
+  // fract(angle / (2 * PI))
+  highp float normalizedAngle = fract(angle * 0.15915494309189533576888376337251);
+  lowp vec4 textureColor = TEXTURE(sTexture, vec2(normalizedAngle + uGradientOffset, 0.5)) * uColor;
 #else
   lowp vec4 textureColor = TEXTURE(sTexture, vec2(vTexCoord.y + uGradientOffset, 0.5)) * uColor;
 #endif
diff --git a/dali-toolkit/internal/visuals/gradient/conic-gradient.cpp b/dali-toolkit/internal/visuals/gradient/conic-gradient.cpp
new file mode 100644 (file)
index 0000000..ecb4f0a
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2025 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include "conic-gradient.h"
+
+// EXTERNAL INCLUDES
+#include <dali/integration-api/debug.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Internal
+{
+ConicGradient::ConicGradient(const Vector2& center, Dali::Radian startAngle)
+: Gradient()
+{
+  SetCenterAndStartAngle(center, startAngle);
+}
+
+ConicGradient::~ConicGradient()
+{
+}
+
+void ConicGradient::SetCenterAndStartAngle(const Vector2& center, Dali::Radian startAngle)
+{
+  mCenter     = center;
+  mStartAngle = WrapInDomain(startAngle, Dali::ANGLE_0, Dali::ANGLE_360);
+
+  // Calculate the transform aligning to the circle
+  Matrix3 invertedAlignMatrix(1.f, 0.f, 0.f, 0.f, 1.f, 0.f, -mCenter.x, -mCenter.y, 1.f);
+
+  mAlignmentTransform = invertedAlignMatrix;
+}
+
+const Vector2& ConicGradient::GetCenter() const
+{
+  return mCenter;
+}
+
+Dali::Radian ConicGradient::GetStartAngle() const
+{
+  return mStartAngle;
+}
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/internal/visuals/gradient/conic-gradient.h b/dali-toolkit/internal/visuals/gradient/conic-gradient.h
new file mode 100644 (file)
index 0000000..667f392
--- /dev/null
@@ -0,0 +1,88 @@
+#ifndef DALI_TOOLKIT_INTERNAL_CONIC_GRADIENT_H
+#define DALI_TOOLKIT_INTERNAL_CONIC_GRADIENT_H
+
+/*
+ * Copyright (c) 2025 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <dali-toolkit/internal/visuals/gradient/gradient.h>
+
+#include <dali/public-api/math/vector2.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Internal
+{
+/**
+ * Conic gradient creates a color transition around a center point, rotating based on the angle from a defined start direction.
+ * It blends colors smoothly as the angle increases around the center.
+ */
+class ConicGradient : public Gradient
+{
+public:
+  /**
+   * Contructor.
+   * @param[in] center The point around which the conic gradient rotates.
+   * @param[in] startAngle The initial angle from which the gradient begins.
+   */
+  ConicGradient(const Vector2& center, Dali::Radian startAngle);
+
+  /**
+   * Destructor.
+   */
+  virtual ~ConicGradient();
+
+  /**
+   * Get the center of the conic gradient.
+   * @return The center of the conic gradient.
+   */
+  const Vector2& GetCenter() const;
+
+  /**
+   * Get the start angle of the conic gradient.
+   * @return The start angle of the conic gradient.
+   */
+  Dali::Radian GetStartAngle() const;
+
+private:
+  // Undefined
+  ConicGradient(const ConicGradient& gradient);
+
+  // Undefined
+  ConicGradient& operator=(const ConicGradient& handle);
+
+private:
+  /**
+   * Set the center and start angle for the conic gradient.
+   * @param[in] center The point around which the conic gradient rotates.
+   * @param[in] startAngle The initial angle from which the gradient begins.
+   * @note An angle out side the range of 0 to 2pi is converted into an equivalent angle within that range.
+   */
+  void SetCenterAndStartAngle(const Vector2& center, Dali::Radian startAngle);
+
+  Vector2 mCenter;
+  Dali::Radian mStartAngle;
+};
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif /* DALI_TOOLKIT_INTERNAL_CONIC_GRADIENT_H */
index 4a646e7e3b25d7a2b4e4466bb4a415e3f37618b0..887068acbfea1339335cd4927ae9fe79d5c485c7 100644 (file)
@@ -30,6 +30,7 @@
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/graphics/builtin-shader-extern-gen.h>
+#include <dali-toolkit/internal/visuals/gradient/conic-gradient.h>
 #include <dali-toolkit/internal/visuals/gradient/linear-gradient.h>
 #include <dali-toolkit/internal/visuals/gradient/radial-gradient.h>
 #include <dali-toolkit/internal/visuals/visual-base-data-impl.h>
@@ -63,6 +64,7 @@ DALI_ENUM_TO_STRING_TABLE_END(SPREAD_METHOD)
 // uniform names
 static constexpr std::string_view UNIFORM_ALIGNMENT_MATRIX_NAME("uAlignmentMatrix");
 static constexpr std::string_view UNIFORM_TEXTURE_COORDINATE_SCALE_FACTOR_NAME("uTextureCoordinateScaleFactor");
+static constexpr std::string_view UNIFORM_START_ANGLE_NAME("uStartAngle");
 static constexpr std::string_view UNIFORM_START_OFFSET_NAME("uGradientOffset");
 
 // default offset value
@@ -94,6 +96,18 @@ VisualFactoryCache::ShaderType SHADER_TYPE_TABLE[] = {
   VisualFactoryCache::GRADIENT_SHADER_RADIAL_USER_SPACE_BORDERLINE,
   VisualFactoryCache::GRADIENT_SHADER_RADIAL_USER_SPACE_ROUNDED_BORDERLINE,
   VisualFactoryCache::GRADIENT_SHADER_RADIAL_USER_SPACE_SQUIRCLE_BORDERLINE,
+  VisualFactoryCache::GRADIENT_SHADER_CONIC_BOUNDING_BOX,
+  VisualFactoryCache::GRADIENT_SHADER_CONIC_BOUNDING_BOX_ROUNDED_CORNER,
+  VisualFactoryCache::GRADIENT_SHADER_CONIC_BOUNDING_BOX_SQUIRCLE_CORNER,
+  VisualFactoryCache::GRADIENT_SHADER_CONIC_BOUNDING_BOX_BORDERLINE,
+  VisualFactoryCache::GRADIENT_SHADER_CONIC_BOUNDING_BOX_ROUNDED_BORDERLINE,
+  VisualFactoryCache::GRADIENT_SHADER_CONIC_BOUNDING_BOX_SQUIRCLE_BORDERLINE,
+  VisualFactoryCache::GRADIENT_SHADER_CONIC_USER_SPACE,
+  VisualFactoryCache::GRADIENT_SHADER_CONIC_USER_SPACE_ROUNDED_CORNER,
+  VisualFactoryCache::GRADIENT_SHADER_CONIC_USER_SPACE_SQUIRCLE_CORNER,
+  VisualFactoryCache::GRADIENT_SHADER_CONIC_USER_SPACE_BORDERLINE,
+  VisualFactoryCache::GRADIENT_SHADER_CONIC_USER_SPACE_ROUNDED_BORDERLINE,
+  VisualFactoryCache::GRADIENT_SHADER_CONIC_USER_SPACE_SQUIRCLE_BORDERLINE,
 };
 constexpr uint32_t SHADER_TYPE_TABLE_COUNT = sizeof(SHADER_TYPE_TABLE) / sizeof(SHADER_TYPE_TABLE[0]);
 
@@ -107,6 +121,7 @@ enum GradientVisualRequireFlag
   BORDERLINE = (1 << 0) * 3,
   USER_SPACE = (1 << 1) * 3,
   RADIAL     = (1 << 2) * 3,
+  CONIC      = (2 << 2) * 3
 };
 
 Dali::WrapMode::Type GetWrapMode(Toolkit::GradientVisual::SpreadMethod::Type spread)
@@ -169,6 +184,10 @@ void GradientVisual::DoSetProperties(const Property::Map& propertyMap)
   {
     mGradientType = Type::RADIAL;
   }
+  else if(propertyMap.Find(Toolkit::GradientVisual::Property::START_ANGLE, CONIC_START_ANGLE_NAME))
+  {
+    mGradientType = Type::CONIC;
+  }
 
   if(NewGradient(mGradientType, propertyMap))
   {
@@ -244,12 +263,18 @@ void GradientVisual::DoCreatePropertyMap(Property::Map& map) const
     map.Insert(Toolkit::GradientVisual::Property::START_POSITION, gradient->GetStartPosition());
     map.Insert(Toolkit::GradientVisual::Property::END_POSITION, gradient->GetEndPosition());
   }
-  else // if( &typeid( *mGradient ) == &typeid(RadialGradient) )
+  else if(&typeid(*mGradient) == &typeid(RadialGradient))
   {
     RadialGradient* gradient = static_cast<RadialGradient*>(mGradient.Get());
     map.Insert(Toolkit::GradientVisual::Property::CENTER, gradient->GetCenter());
     map.Insert(Toolkit::GradientVisual::Property::RADIUS, gradient->GetRadius());
   }
+  else // if( &typeid( *mGradient ) == &typeid(ConicGradient) )
+  {
+    ConicGradient* gradient = static_cast<ConicGradient*>(mGradient.Get());
+    map.Insert(Toolkit::GradientVisual::Property::CENTER, gradient->GetCenter());
+    map.Insert(Toolkit::GradientVisual::Property::START_ANGLE, gradient->GetStartAngle().radian);
+  }
 }
 
 void GradientVisual::DoCreateInstancePropertyMap(Property::Map& map) const
@@ -294,6 +319,11 @@ void GradientVisual::OnInitialize()
   }
 
   mImpl->mRenderer.RegisterUniqueProperty(UNIFORM_ALIGNMENT_MATRIX_NAME, mGradientTransform);
+  if(mGradientType == Type::CONIC)
+  {
+    ConicGradient* gradient = static_cast<ConicGradient*>(mGradient.Get());
+    mImpl->mRenderer.RegisterUniqueProperty(UNIFORM_START_ANGLE_NAME, gradient->GetStartAngle().radian);
+  }
 
   float textureSize = static_cast<float>(lookupTexture.GetWidth());
   mImpl->mRenderer.RegisterUniqueProperty(UNIFORM_TEXTURE_COORDINATE_SCALE_FACTOR_NAME, (textureSize - 1.0f) / textureSize);
@@ -323,7 +353,7 @@ bool GradientVisual::NewGradient(Type gradientType, const Property::Map& propert
       return false;
     }
   }
-  else // type==Type::RADIAL
+  else if(gradientType == Type::RADIAL)
   {
     Property::Value* centerValue = propertyMap.Find(Toolkit::GradientVisual::Property::CENTER, CENTER_NAME);
     Property::Value* radiusValue = propertyMap.Find(Toolkit::GradientVisual::Property::RADIUS, RADIUS_NAME);
@@ -338,6 +368,21 @@ bool GradientVisual::NewGradient(Type gradientType, const Property::Map& propert
       return false;
     }
   }
+  else // if(gradientType == Type::CONIC)
+  {
+    Property::Value* centerValue = propertyMap.Find(Toolkit::GradientVisual::Property::CENTER, CENTER_NAME);
+    Property::Value* startAngleValue = propertyMap.Find(Toolkit::GradientVisual::Property::START_ANGLE, CONIC_START_ANGLE_NAME);
+    Vector2          center;
+    float            startAngle;
+    if(centerValue && centerValue->Get(center) && startAngleValue && startAngleValue->Get(startAngle))
+    {
+      mGradient = new ConicGradient(center, Dali::Radian(startAngle));
+    }
+    else
+    {
+      return false;
+    }
+  }
 
   unsigned int     numValidStop    = 0u;
   Property::Value* stopOffsetValue = propertyMap.Find(Toolkit::GradientVisual::Property::STOP_OFFSET, STOP_OFFSET_NAME);
@@ -399,6 +444,7 @@ Shader GradientVisual::GenerateShader() const
   bool squircleCorner = IsSquircleCornerRequired();
   bool borderline     = IsBorderlineRequired();
   bool radialGradient = (mGradientType == Type::RADIAL);
+  bool conicGradient  = (mGradientType == Type::CONIC);
 
   uint32_t shaderTypeFlag = GradientVisualRequireFlag::DEFAULT;
   if(squircleCorner)
@@ -418,10 +464,15 @@ Shader GradientVisual::GenerateShader() const
   {
     shaderTypeFlag += GradientVisualRequireFlag::USER_SPACE;
   }
+
   if(radialGradient)
   {
     shaderTypeFlag += GradientVisualRequireFlag::RADIAL;
   }
+  else if(conicGradient)
+  {
+    shaderTypeFlag += GradientVisualRequireFlag::CONIC;
+  }
 
   DALI_ASSERT_DEBUG(shaderTypeFlag < SHADER_TYPE_TABLE_COUNT && "Invalid gradient shader type generated!");
 
@@ -446,10 +497,16 @@ Shader GradientVisual::GenerateShader() const
       vertexShaderPrefixList += "#define IS_REQUIRED_BORDERLINE\n";
       fragmentShaderPrefixList += "#define IS_REQUIRED_BORDERLINE\n";
     }
+
     if(radialGradient)
     {
       fragmentShaderPrefixList += "#define RADIAL\n";
     }
+    else if(conicGradient)
+    {
+      fragmentShaderPrefixList += "#define CONIC\n";
+    }
+
     if(userspaceUnit)
     {
       vertexShaderPrefixList += "#define USER_SPACE\n";
index 94b4523706609e85a63928e2115ba2438c2f6ada..cf616a2cf9cd4a3a396965eddd40770dcfd3d843 100644 (file)
@@ -57,7 +57,15 @@ typedef IntrusivePtr<GradientVisual> GradientVisualPtr;
  * | radius                  | FLOAT            |
  * | stopColor               | ARRAY of VECTOR4 |
  *
- * The following properties are optional for both LINEAR and RADIAL GradientRender.
+ * The following properties are essential for create a CONIC GradientRender
+ *
+ * | %Property Name          | Type             |
+ * |-------------------------|------------------|
+ * | center                  | VECTOR2          |
+ * | startAngle              | Dali::Radian     |
+ * | stopColor               | ARRAY of VECTOR4 |
+ *
+ * The following properties are optional for all kind of GradientRender.
  *
  * | %Property Name          | Type             |
  * |-------------------------|------------------|
@@ -78,7 +86,8 @@ public:
   enum Type
   {
     LINEAR,
-    RADIAL
+    RADIAL,
+    CONIC
   };
 
   /**
index 7763dc1ac50778e91b4fa545617ec0fc0857cfc2..e934dd80719e7eb75fb30dedc2e1816d99e949ce 100644 (file)
@@ -108,6 +108,18 @@ public:
     GRADIENT_SHADER_RADIAL_USER_SPACE_BORDERLINE,
     GRADIENT_SHADER_RADIAL_USER_SPACE_ROUNDED_BORDERLINE,
     GRADIENT_SHADER_RADIAL_USER_SPACE_SQUIRCLE_BORDERLINE,
+    GRADIENT_SHADER_CONIC_BOUNDING_BOX,
+    GRADIENT_SHADER_CONIC_BOUNDING_BOX_ROUNDED_CORNER,
+    GRADIENT_SHADER_CONIC_BOUNDING_BOX_SQUIRCLE_CORNER,
+    GRADIENT_SHADER_CONIC_BOUNDING_BOX_BORDERLINE,
+    GRADIENT_SHADER_CONIC_BOUNDING_BOX_ROUNDED_BORDERLINE,
+    GRADIENT_SHADER_CONIC_BOUNDING_BOX_SQUIRCLE_BORDERLINE,
+    GRADIENT_SHADER_CONIC_USER_SPACE,
+    GRADIENT_SHADER_CONIC_USER_SPACE_ROUNDED_CORNER,
+    GRADIENT_SHADER_CONIC_USER_SPACE_SQUIRCLE_CORNER,
+    GRADIENT_SHADER_CONIC_USER_SPACE_BORDERLINE,
+    GRADIENT_SHADER_CONIC_USER_SPACE_ROUNDED_BORDERLINE,
+    GRADIENT_SHADER_CONIC_USER_SPACE_SQUIRCLE_BORDERLINE,
     IMAGE_SHADER,
     IMAGE_SHADER_ROUNDED_CORNER,
     IMAGE_SHADER_SQUIRCLE_CORNER,
index 020f4c0a0e6e3fb4eb454d83168f5835613f6a9f..f6e0b38fcb733dabad8b5f4f798e3550f4e66684 100644 (file)
@@ -97,6 +97,18 @@ DALI_ENUM_TO_STRING_TABLE_BEGIN(VISUAL_SHADER_TYPE)
   DALI_ENUM_TO_STRING_WITH_SCOPE(Toolkit::Internal::VisualFactoryCache::ShaderType, GRADIENT_SHADER_RADIAL_USER_SPACE_BORDERLINE)
   DALI_ENUM_TO_STRING_WITH_SCOPE(Toolkit::Internal::VisualFactoryCache::ShaderType, GRADIENT_SHADER_RADIAL_USER_SPACE_ROUNDED_BORDERLINE)
   DALI_ENUM_TO_STRING_WITH_SCOPE(Toolkit::Internal::VisualFactoryCache::ShaderType, GRADIENT_SHADER_RADIAL_USER_SPACE_SQUIRCLE_BORDERLINE)
+  DALI_ENUM_TO_STRING_WITH_SCOPE(Toolkit::Internal::VisualFactoryCache::ShaderType, GRADIENT_SHADER_CONIC_BOUNDING_BOX)
+  DALI_ENUM_TO_STRING_WITH_SCOPE(Toolkit::Internal::VisualFactoryCache::ShaderType, GRADIENT_SHADER_CONIC_BOUNDING_BOX_ROUNDED_CORNER)
+  DALI_ENUM_TO_STRING_WITH_SCOPE(Toolkit::Internal::VisualFactoryCache::ShaderType, GRADIENT_SHADER_CONIC_BOUNDING_BOX_SQUIRCLE_CORNER)
+  DALI_ENUM_TO_STRING_WITH_SCOPE(Toolkit::Internal::VisualFactoryCache::ShaderType, GRADIENT_SHADER_CONIC_BOUNDING_BOX_BORDERLINE)
+  DALI_ENUM_TO_STRING_WITH_SCOPE(Toolkit::Internal::VisualFactoryCache::ShaderType, GRADIENT_SHADER_CONIC_BOUNDING_BOX_ROUNDED_BORDERLINE)
+  DALI_ENUM_TO_STRING_WITH_SCOPE(Toolkit::Internal::VisualFactoryCache::ShaderType, GRADIENT_SHADER_CONIC_BOUNDING_BOX_SQUIRCLE_BORDERLINE)
+  DALI_ENUM_TO_STRING_WITH_SCOPE(Toolkit::Internal::VisualFactoryCache::ShaderType, GRADIENT_SHADER_CONIC_USER_SPACE)
+  DALI_ENUM_TO_STRING_WITH_SCOPE(Toolkit::Internal::VisualFactoryCache::ShaderType, GRADIENT_SHADER_CONIC_USER_SPACE_ROUNDED_CORNER)
+  DALI_ENUM_TO_STRING_WITH_SCOPE(Toolkit::Internal::VisualFactoryCache::ShaderType, GRADIENT_SHADER_CONIC_USER_SPACE_SQUIRCLE_CORNER)
+  DALI_ENUM_TO_STRING_WITH_SCOPE(Toolkit::Internal::VisualFactoryCache::ShaderType, GRADIENT_SHADER_CONIC_USER_SPACE_BORDERLINE)
+  DALI_ENUM_TO_STRING_WITH_SCOPE(Toolkit::Internal::VisualFactoryCache::ShaderType, GRADIENT_SHADER_CONIC_USER_SPACE_ROUNDED_BORDERLINE)
+  DALI_ENUM_TO_STRING_WITH_SCOPE(Toolkit::Internal::VisualFactoryCache::ShaderType, GRADIENT_SHADER_CONIC_USER_SPACE_SQUIRCLE_BORDERLINE)
   DALI_ENUM_TO_STRING_WITH_SCOPE(Toolkit::Internal::VisualFactoryCache::ShaderType, IMAGE_SHADER)
   DALI_ENUM_TO_STRING_WITH_SCOPE(Toolkit::Internal::VisualFactoryCache::ShaderType, IMAGE_SHADER_ROUNDED_CORNER)
   DALI_ENUM_TO_STRING_WITH_SCOPE(Toolkit::Internal::VisualFactoryCache::ShaderType, IMAGE_SHADER_SQUIRCLE_CORNER)
@@ -319,6 +331,9 @@ const char* const ANTI_ALIASING("antiAliasing");
 const char* const CENTER_NAME("center"); // Property::VECTOR2
 const char* const RADIUS_NAME("radius"); // Property::FLOAT
 
+// properties: conic gradient
+const char* const CONIC_START_ANGLE_NAME("conicStartAngle"); // Property::FLOAT
+
 // properties: linear&radial gradient
 const char* const STOP_OFFSET_NAME("stopOffset");     // Property::Array FLOAT
 const char* const STOP_COLOR_NAME("stopColor");       // Property::Array VECTOR4
index 3340ec47b962fedd88962495c22e28a2dacf8031..1e00d0921dfaae8eff4a55d8043db200f4fc5015 100644 (file)
@@ -185,6 +185,9 @@ extern const char* const ANTI_ALIASING;
 extern const char* const CENTER_NAME; // Property::VECTOR2
 extern const char* const RADIUS_NAME; // Property::FLOAT
 
+// properties: conic gradient
+extern const char* const CONIC_START_ANGLE_NAME; // Property::FLOAT
+
 // properties: linear&radial gradient
 extern const char* const STOP_OFFSET_NAME;   // Property::Array FLOAT
 extern const char* const STOP_COLOR_NAME;    // Property::Array VECTOR4
index 84f9b9ea5d0fe1c33aafcfe28d67316605c3976f..375f49603cb3f62f287af648cd6b1703f2592085 100644 (file)
@@ -76,7 +76,7 @@ enum
    * @brief The center point of a radial gradient.
    * @details Name "center", type Property::VECTOR2.
    * @SINCE_1_1.45
-   * @note Mandatory for Radial.
+   * @note Mandatory for Radial and Conic.
    */
   CENTER,
 
@@ -128,7 +128,15 @@ enum
    * @SINCE_2_4.17
    * @note Optional. If not supplied, default is 0.
    */
-  START_OFFSET
+  START_OFFSET,
+
+  /**
+   * @brief The initial angle from which the conic gradient begins.
+   * @details Name "startAngle", type Property::FLOAT.
+   * @SINCE_2_4.17
+   * @note Mandatory for Conic.
+   */
+  START_ANGLE
 };
 
 } // namespace Property