[cogl/cogl-1.16] color: Add HSL conversion functions



commit 5858cac873dac28087b3d31cac254c31a7b04e38
Author: Damien Lespiau <damien lespiau intel com>
Date:   Mon May 13 13:24:21 2013 +0100

    color: Add HSL conversion functions
    
    This allows to easily caculate shades of the same color or pick colors
    with the same saturation/luminance. In short, all sorts of interesting
    things.
    
    Reviewed-by: Robert Bragg <robert linux intel com>
    Reviewed-by: Neil Roberts <neil linux intel com>
    
    (cherry picked from commit edcbeaf3c941f7a2335fbec47d5248cd9b0e8088)

 cogl/cogl-color.c                                  |  125 ++++++++++++++++++++
 cogl/cogl-color.h                                  |   38 ++++++
 .../cogl-2.0-experimental-sections.txt             |    4 +
 doc/reference/cogl/cogl-sections.txt               |    4 +
 4 files changed, 171 insertions(+), 0 deletions(-)
---
diff --git a/cogl/cogl-color.c b/cogl/cogl-color.c
index 1f9a01e..7d5db0f 100644
--- a/cogl/cogl-color.c
+++ b/cogl/cogl-color.c
@@ -312,3 +312,128 @@ _cogl_color_get_rgba_4ubv (const CoglColor *color,
   memcpy (dest, color, 4);
 }
 
+void
+cogl_color_to_hsl (const CoglColor *color,
+                   float           *hue,
+                   float           *saturation,
+                   float           *luminance)
+{
+  float red, green, blue;
+  float min, max, delta;
+  float h, l, s;
+
+  red   = color->red / 255.0;
+  green = color->green / 255.0;
+  blue  = color->blue / 255.0;
+
+  if (red > green)
+    {
+      if (red > blue)
+       max = red;
+      else
+       max = blue;
+
+      if (green < blue)
+       min = green;
+      else
+       min = blue;
+    }
+  else
+    {
+      if (green > blue)
+       max = green;
+      else
+       max = blue;
+
+      if (red < blue)
+       min = red;
+      else
+       min = blue;
+    }
+
+  l = (max + min) / 2;
+  s = 0;
+  h = 0;
+
+  if (max != min)
+    {
+      if (l <= 0.5)
+       s = (max - min) / (max + min);
+      else
+       s = (max - min) / (2.0 - max - min);
+
+      delta = max - min;
+
+      if (red == max)
+       h = (green - blue) / delta;
+      else if (green == max)
+       h = 2.0 + (blue - red) / delta;
+      else if (blue == max)
+       h = 4.0 + (red - green) / delta;
+
+      h *= 60;
+
+      if (h < 0)
+       h += 360.0;
+    }
+
+  if (hue)
+    *hue = h;
+
+  if (luminance)
+    *luminance = l;
+
+  if (saturation)
+    *saturation = s;
+}
+
+void
+cogl_color_init_from_hsl (CoglColor *color,
+                          float      hue,
+                          float      saturation,
+                          float      luminance)
+{
+  float tmp1, tmp2;
+  float tmp3[3];
+  float clr[3];
+  int   i;
+
+  hue /= 360.0;
+
+  if (saturation == 0)
+    {
+      cogl_color_init_from_4f (color, luminance, luminance, luminance, 1.0f);
+      return;
+    }
+
+  if (luminance <= 0.5)
+    tmp2 = luminance * (1.0 + saturation);
+  else
+    tmp2 = luminance + saturation - (luminance * saturation);
+
+  tmp1 = 2.0 * luminance - tmp2;
+
+  tmp3[0] = hue + 1.0 / 3.0;
+  tmp3[1] = hue;
+  tmp3[2] = hue - 1.0 / 3.0;
+
+  for (i = 0; i < 3; i++)
+    {
+      if (tmp3[i] < 0)
+        tmp3[i] += 1.0;
+
+      if (tmp3[i] > 1)
+        tmp3[i] -= 1.0;
+
+      if (6.0 * tmp3[i] < 1.0)
+        clr[i] = tmp1 + (tmp2 - tmp1) * tmp3[i] * 6.0;
+      else if (2.0 * tmp3[i] < 1.0)
+        clr[i] = tmp2;
+      else if (3.0 * tmp3[i] < 2.0)
+        clr[i] = (tmp1 + (tmp2 - tmp1) * ((2.0 / 3.0) - tmp3[i]) * 6.0);
+      else
+        clr[i] = tmp1;
+    }
+
+  cogl_color_init_from_4f (color, clr[0], clr[1], clr[2], 1.0f);
+}
diff --git a/cogl/cogl-color.h b/cogl/cogl-color.h
index 70c0347..713f567 100644
--- a/cogl/cogl-color.h
+++ b/cogl/cogl-color.h
@@ -541,6 +541,44 @@ cogl_color_unpremultiply (CoglColor *color);
 CoglBool
 cogl_color_equal (const void *v1, const void *v2);
 
+/**
+ * cogl_color_to_hsl:
+ * @color: a #CoglColor
+ * @hue: (out): return location for the hue value or %NULL
+ * @saturation: (out): return location for the saturation value or %NULL
+ * @luminance: (out): return location for the luminance value or %NULL
+ *
+ * Converts @color to the HLS format.
+ *
+ * The @hue value is in the 0 .. 360 range. The @luminance and
+ * @saturation values are in the 0 .. 1 range.
+ *
+ * Since: 1.16
+ */
+void
+cogl_color_to_hsl (const CoglColor *color,
+                   float           *hue,
+                   float           *saturation,
+                   float           *luminance);
+
+/**
+ * cogl_color_init_from_hsl:
+ * @color: (out): return location for a #CoglColor
+ * @hue: hue value, in the 0 .. 360 range
+ * @saturation: saturation value, in the 0 .. 1 range
+ * @luminance: luminance value, in the 0 .. 1 range
+ *
+ * Converts a color expressed in HLS (hue, luminance and saturation)
+ * values into a #CoglColor.
+ *
+ * Since: 1.16
+ */
+void
+cogl_color_init_from_hsl (CoglColor *color,
+                          float      hue,
+                          float      saturation,
+                          float      luminance);
+
 COGL_END_DECLS
 
 #endif /* __COGL_COLOR_H__ */
diff --git a/doc/reference/cogl-2.0-experimental/cogl-2.0-experimental-sections.txt 
b/doc/reference/cogl-2.0-experimental/cogl-2.0-experimental-sections.txt
index 00ed18f..4cea49d 100644
--- a/doc/reference/cogl-2.0-experimental/cogl-2.0-experimental-sections.txt
+++ b/doc/reference/cogl-2.0-experimental/cogl-2.0-experimental-sections.txt
@@ -692,6 +692,10 @@ cogl_color_set_alpha_float
 cogl_color_premultiply
 cogl_color_unpremultiply
 cogl_color_equal
+
+<SUBSECTION>
+cogl_color_init_from_hsl
+cogl_color_to_hsl
 </SECTION>
 
 <SECTION>
diff --git a/doc/reference/cogl/cogl-sections.txt b/doc/reference/cogl/cogl-sections.txt
index 60db06d..60c0048 100644
--- a/doc/reference/cogl/cogl-sections.txt
+++ b/doc/reference/cogl/cogl-sections.txt
@@ -417,6 +417,10 @@ cogl_color_set_alpha_float
 cogl_color_premultiply
 cogl_color_unpremultiply
 cogl_color_equal
+
+<SUBSECTION>
+cogl_color_init_from_hsl
+cogl_color_to_hsl
 </SECTION>
 
 <SECTION>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]