[Cogl] [PATCH 1/3] color: Add HSL conversion functions

Damien Lespiau damien.lespiau at intel.com
Sat May 18 22:04:38 PDT 2013


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.
---
 cogl/cogl-color.c                      | 129 +++++++++++++++++++++++++++++++++
 cogl/cogl-color.h                      |  38 ++++++++++
 doc/reference/cogl2/cogl2-sections.txt |   4 +
 3 files changed, 171 insertions(+)

diff --git a/cogl/cogl-color.c b/cogl/cogl-color.c
index 9ed1e15..0dba9da 100644
--- a/cogl/cogl-color.c
+++ b/cogl/cogl-color.c
@@ -266,6 +266,135 @@ cogl_color_free (CoglColor *color)
 }
 
 void
+cogl_color_to_hsl (const CoglColor *color,
+                   float           *hue,
+                   float           *luminance,
+                   float           *saturation)
+{
+  float red, green, blue;
+  float min, max, delta;
+  float h, l, s;
+
+  red   = color->red;
+  green = color->green;
+  blue  = color->blue;
+
+  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      luminance,
+                          float      saturation)
+{
+  float tmp1, tmp2;
+  float tmp3[3];
+  float clr[3];
+  int   i;
+
+  hue /= 360.0;
+
+  if (saturation == 0)
+    {
+      color->red = color->green = color->blue = (luminance * 255);
+
+      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;
+    }
+
+  color->red   = clr[0];
+  color->green = clr[1];
+  color->blue  = clr[2];
+}
+
+void
 _cogl_color_get_rgba_4fv (const CoglColor *color,
                           float *dest)
 {
diff --git a/cogl/cogl-color.h b/cogl/cogl-color.h
index 94726a4..7e520a9 100644
--- a/cogl/cogl-color.h
+++ b/cogl/cogl-color.h
@@ -485,6 +485,44 @@ cogl_color_copy (const CoglColor *color);
 void
 cogl_color_free (CoglColor *color);
 
+/**
+ * cogl_color_to_hsl:
+ * @color: a #CoglColor
+ * @hue: (out): return location for the hue value or %NULL
+ * @luminance: (out): return location for the luminance value or %NULL
+ * @saturation: (out): return location for the saturation 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: 2.0
+ */
+void
+cogl_color_to_hsl (const CoglColor *color,
+                   float           *hue,
+                   float           *luminance,
+                   float           *saturation);
+
+/**
+ * cogl_color_init_from_hsl:
+ * @color: (out): return location for a #CoglColor
+ * @hue: hue value, in the 0 .. 360 range
+ * @luminance: luminance value, in the 0 .. 1 range
+ * @saturation: saturation value, in the 0 .. 1 range
+ *
+ * Converts a color expressed in HLS (hue, luminance and saturation)
+ * values into a #CoglColor.
+ *
+ * Since: 2.0
+ */
+void
+cogl_color_init_from_hsl (CoglColor *color,
+                          float      hue,
+                          float      luminance,
+                          float      saturation);
+
 COGL_END_DECLS
 
 #endif /* __COGL_COLOR_H__ */
diff --git a/doc/reference/cogl2/cogl2-sections.txt b/doc/reference/cogl2/cogl2-sections.txt
index 68769bd..4ac1148 100644
--- a/doc/reference/cogl2/cogl2-sections.txt
+++ b/doc/reference/cogl2/cogl2-sections.txt
@@ -628,6 +628,10 @@ cogl_color_set_alpha_float
 cogl_color_premultiply
 cogl_color_unpremultiply
 cogl_color_equal
+
+<SUBSECTION>
+cogl_color_init_from_hls
+cogl_color_to_hls
 </SECTION>
 
 <SECTION>
-- 
1.8.1.4



More information about the Cogl mailing list