[dali_2.3.22] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / visuals / gradient / gradient.cpp
index 2c90e52..e96cf32 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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.
 
 #include "gradient.h"
 
-#include <algorithm>    // std::sort
 #include <dali/public-api/math/vector4.h>
+#include <algorithm> // std::sort
 
 namespace
 {
 // The maximum width of the lookup texture ( it is a 1-dimension texture with the height as 1 )
 const unsigned int MAXIMUM_TEXTURE_RESOLUTION(128u);
-}
+} // namespace
 
 namespace Dali
 {
-
 namespace Toolkit
 {
-
 namespace Internal
 {
-
 Gradient::Gradient()
-: mGradientUnits( Toolkit::GradientVisual::Units::OBJECT_BOUNDING_BOX ),
-  mSpreadMethod( Toolkit::GradientVisual::SpreadMethod::PAD )
-{}
+: mGradientUnits(Toolkit::GradientVisual::Units::OBJECT_BOUNDING_BOX),
+  mSpreadMethod(Toolkit::GradientVisual::SpreadMethod::PAD)
+{
+}
 
 Gradient::~Gradient()
-{}
+{
+}
 
-void Gradient::AddStop( float offset, const Vector4& color )
+void Gradient::AddStop(float offset, const Vector4& color)
 {
   // the offset is clamped to the range [0.0, 1.0]
-  mGradientStops.PushBack( GradientStop( Clamp( offset, 0.f, 1.f ), color) );
+  mGradientStops.PushBack(GradientStop(Clamp(offset, 0.f, 1.f), color));
 }
 
 const Vector<Gradient::GradientStop>& Gradient::GetStops()
@@ -54,7 +53,7 @@ const Vector<Gradient::GradientStop>& Gradient::GetStops()
   return mGradientStops;
 }
 
-void Gradient::SetGradientUnits( Toolkit::GradientVisual::Units::Type gradientUnits )
+void Gradient::SetGradientUnits(Toolkit::GradientVisual::Units::Type gradientUnits)
 {
   mGradientUnits = gradientUnits;
 }
@@ -64,7 +63,7 @@ Toolkit::GradientVisual::Units::Type Gradient::GetGradientUnits() const
   return mGradientUnits;
 }
 
-void Gradient::SetSpreadMethod( Toolkit::GradientVisual::SpreadMethod::Type spread )
+void Gradient::SetSpreadMethod(Toolkit::GradientVisual::SpreadMethod::Type spread)
 {
   mSpreadMethod = spread;
 }
@@ -90,9 +89,10 @@ const Matrix3& Gradient::GetAlignmentTransform() const
  */
 Dali::Texture Gradient::GenerateLookupTexture()
 {
-  std::sort( mGradientStops.Begin(), mGradientStops.End() );
+  std::sort(mGradientStops.Begin(), mGradientStops.End());
 
-  unsigned int numStops = mGradientStops.Count();
+  uint32_t numStops = mGradientStops.Count();
+  DALI_ASSERT_ALWAYS(numStops > 0u && "The number of gradient stop should not be zero!");
 
   /**
    * If the stops have not covered the whole zero to one range,
@@ -101,31 +101,29 @@ Dali::Texture Gradient::GenerateLookupTexture()
    * for REPEAT, mix the two color of the first and last stop to fill the remainder
    */
   bool tempFirstStop = false;
-  if( mGradientStops[0].mOffset > 0.f )
+  if(mGradientStops[0].mOffset > 0.f)
   {
     tempFirstStop = true;
-    Vector4 firstStopColor( mGradientStops[0].mStopColor ); // If spread method is PAD or REFLECT
-    if( mSpreadMethod == Toolkit::GradientVisual::SpreadMethod::REPEAT )
+    Vector4 firstStopColor(mGradientStops[0].mStopColor); // If spread method is PAD or REFLECT
+    if(mSpreadMethod == Toolkit::GradientVisual::SpreadMethod::REPEAT)
     {
-      firstStopColor = ( mGradientStops[0].mStopColor * (1.f-mGradientStops[numStops-1].mOffset)
-                       + mGradientStops[numStops-1].mStopColor  * mGradientStops[0].mOffset )
-                   / ( mGradientStops[0].mOffset+1.f-mGradientStops[numStops-1].mOffset);
+      firstStopColor = (mGradientStops[0].mStopColor * (1.f - mGradientStops[numStops - 1].mOffset) + mGradientStops[numStops - 1].mStopColor * mGradientStops[0].mOffset) / (mGradientStops[0].mOffset + 1.f - mGradientStops[numStops - 1].mOffset);
     }
 
-    mGradientStops.Insert( mGradientStops.Begin(), GradientStop(0.f, firstStopColor) );
+    mGradientStops.Insert(mGradientStops.Begin(), GradientStop(0.f, firstStopColor));
     numStops++;
   }
 
   bool tempLastStop = false;
-  if( mGradientStops[numStops-1].mOffset < 1.f )
+  if(mGradientStops[numStops - 1].mOffset < 1.f)
   {
     tempLastStop = true;
-    Vector4 lastStopColor( mGradientStops[numStops-1].mStopColor ); // If spread method is PAD or REFLECT
-    if( mSpreadMethod == Toolkit::GradientVisual::SpreadMethod::REPEAT )
+    Vector4 lastStopColor(mGradientStops[numStops - 1].mStopColor); // If spread method is PAD or REFLECT
+    if(mSpreadMethod == Toolkit::GradientVisual::SpreadMethod::REPEAT)
     {
       lastStopColor = mGradientStops[0].mStopColor;
     }
-    mGradientStops.PushBack( GradientStop(1.f, lastStopColor) );
+    mGradientStops.PushBack(GradientStop(1.f, lastStopColor));
     numStops++;
   }
 
@@ -134,47 +132,47 @@ Dali::Texture Gradient::GenerateLookupTexture()
    */
   unsigned int resolution = EstimateTextureResolution();
 
-  unsigned int bufferSize = resolution * 4u;
-  unsigned char* pixels = new unsigned char[ bufferSize ];
-  PixelData pixelData = PixelData::New( pixels, bufferSize, resolution, 1u, Pixel::RGBA8888, PixelData::DELETE_ARRAY );
+  unsigned int   bufferSize = resolution * 4u;
+  unsigned char* pixels     = new unsigned char[bufferSize];
+  PixelData      pixelData  = PixelData::New(pixels, bufferSize, resolution, 1u, Pixel::RGBA8888, PixelData::DELETE_ARRAY);
 
-  int segmentStart = 0;
-  int segmentEnd = 0;
-  int k = 0;
-  float length = static_cast<float>(resolution);
-  for( unsigned int i=0; i<numStops-1u; i++ )
+  int   segmentStart = 0;
+  int   segmentEnd   = 0;
+  int   k            = 0;
+  float length       = static_cast<float>(resolution);
+  for(unsigned int i = 0; i < numStops - 1u; i++)
   {
-    segmentEnd = floorf(mGradientStops[i+1].mOffset * length + 0.5f);
-    if( segmentEnd == segmentStart )
+    segmentEnd = floorf(mGradientStops[i + 1].mOffset * length + 0.5f);
+    if(segmentEnd == segmentStart)
     {
       continue;
     }
-    float segmentWidth = static_cast<float>(segmentEnd-segmentStart);
+    float segmentWidth = static_cast<float>(segmentEnd - segmentStart);
 
-    for( int j = segmentStart; j<segmentEnd; j++ )
+    for(int j = segmentStart; j < segmentEnd; j++)
     {
-      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 ) );
-      pixels[k*4+2] = static_cast<unsigned char>( 255.f * Clamp( currentColor.b, 0.f, 1.f ) );
-      pixels[k*4+3] = static_cast<unsigned char>( 255.f * Clamp( currentColor.a, 0.f, 1.f ) );
+      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));
+      pixels[k * 4 + 2]    = static_cast<unsigned char>(255.f * Clamp(currentColor.b, 0.f, 1.f));
+      pixels[k * 4 + 3]    = static_cast<unsigned char>(255.f * Clamp(currentColor.a, 0.f, 1.f));
       k++;
     }
     segmentStart = segmentEnd;
   }
 
-  Texture texture = Texture::New( TextureType::TEXTURE_2D, Pixel::RGBA8888, resolution, 1u );
-  texture.Upload( pixelData );
+  Texture texture = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, resolution, 1u);
+  texture.Upload(pixelData);
 
   // remove the stops added temporarily for generating the pixels, as the spread method might get changed later
-  if( tempLastStop )
+  if(tempLastStop)
   {
-    mGradientStops.Erase( mGradientStops.Begin()+numStops-1 );
+    mGradientStops.Erase(mGradientStops.Begin() + numStops - 1);
   }
-  if( tempFirstStop )
+  if(tempFirstStop)
   {
-    mGradientStops.Erase( mGradientStops.Begin());
+    mGradientStops.Erase(mGradientStops.Begin());
   }
 
   return texture;
@@ -182,16 +180,18 @@ Dali::Texture Gradient::GenerateLookupTexture()
 
 unsigned int Gradient::EstimateTextureResolution()
 {
-  float minInterval = 1.0;
-  for( unsigned int i=0, numStops = mGradientStops.Count(); i<numStops-1u; i++ )
+  float          minInterval = 1.0;
+  const uint32_t numStops    = mGradientStops.Count();
+  DALI_ASSERT_ALWAYS(numStops > 0u && "The number of gradient stop should not be zero!");
+  for(uint32_t i = 0; i < numStops - 1u; i++)
   {
-    float interval = mGradientStops[i+1].mOffset - mGradientStops[i].mOffset;
-    minInterval = interval > minInterval ? minInterval:interval;
+    float interval = mGradientStops[i + 1].mOffset - mGradientStops[i].mOffset;
+    minInterval    = interval > minInterval ? minInterval : interval;
   }
   // Use at least three pixels for each segment between two stops
-  unsigned int resolution = static_cast<int>(3.f/(minInterval+Math::MACHINE_EPSILON_100)+0.5f);
+  unsigned int resolution = static_cast<int>(3.f / (minInterval + Math::MACHINE_EPSILON_100) + 0.5f);
   // Clamp the resolution to handle the overlapping stops
-  if( resolution > MAXIMUM_TEXTURE_RESOLUTION )
+  if(resolution > MAXIMUM_TEXTURE_RESOLUTION)
   {
     return MAXIMUM_TEXTURE_RESOLUTION;
   }