summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Lespiau <damien.lespiau@intel.com>2013-05-13 13:24:21 +0100
committerRobert Bragg <robert@linux.intel.com>2013-07-09 22:52:49 +0100
commit5858cac873dac28087b3d31cac254c31a7b04e38 (patch)
treeb9f2846871ca1fc12a310c3fc12971c961f11bec
parent6cc9074cfb3644153bde6b733e57f25636ca2a9e (diff)
downloadcogl-5858cac873dac28087b3d31cac254c31a7b04e38.tar.gz
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)
-rw-r--r--cogl/cogl-color.c125
-rw-r--r--cogl/cogl-color.h38
-rw-r--r--doc/reference/cogl-2.0-experimental/cogl-2.0-experimental-sections.txt4
-rw-r--r--doc/reference/cogl/cogl-sections.txt4
4 files changed, 171 insertions, 0 deletions
diff --git a/cogl/cogl-color.c b/cogl/cogl-color.c
index 1f9a01ee..7d5db0f8 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 70c03471..713f567c 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 00ed18ff..4cea49dd 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 60db06d8..60c0048a 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>