From 525963d74d9f54ea502d5ff31ced5534de7cb6cf Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Sat, 6 Nov 2010 12:35:20 +0100 Subject: [PATCH] GtkSymbolicColor: convert to/from hls when shading. This makes shading equal to GtkStyle's. --- gtk/gtksymboliccolor.c | 181 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 177 insertions(+), 4 deletions(-) diff --git a/gtk/gtksymboliccolor.c b/gtk/gtksymboliccolor.c index 35d944bc84..d2506dc4e5 100644 --- a/gtk/gtksymboliccolor.c +++ b/gtk/gtksymboliccolor.c @@ -292,6 +292,181 @@ gtk_symbolic_color_unref (GtkSymbolicColor *color) } } +static void +rgb_to_hls (gdouble *r, + gdouble *g, + gdouble *b) +{ + gdouble min; + gdouble max; + gdouble red; + gdouble green; + gdouble blue; + gdouble h, l, s; + gdouble delta; + + red = *r; + green = *g; + blue = *b; + + 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 - max - min); + + delta = max -min; + if (red == max) + h = (green - blue) / delta; + else if (green == max) + h = 2 + (blue - red) / delta; + else if (blue == max) + h = 4 + (red - green) / delta; + + h *= 60; + if (h < 0.0) + h += 360; + } + + *r = h; + *g = l; + *b = s; +} + +static void +hls_to_rgb (gdouble *h, + gdouble *l, + gdouble *s) +{ + gdouble hue; + gdouble lightness; + gdouble saturation; + gdouble m1, m2; + gdouble r, g, b; + + lightness = *l; + saturation = *s; + + if (lightness <= 0.5) + m2 = lightness * (1 + saturation); + else + m2 = lightness + saturation - lightness * saturation; + m1 = 2 * lightness - m2; + + if (saturation == 0) + { + *h = lightness; + *l = lightness; + *s = lightness; + } + else + { + hue = *h + 120; + while (hue > 360) + hue -= 360; + while (hue < 0) + hue += 360; + + if (hue < 60) + r = m1 + (m2 - m1) * hue / 60; + else if (hue < 180) + r = m2; + else if (hue < 240) + r = m1 + (m2 - m1) * (240 - hue) / 60; + else + r = m1; + + hue = *h; + while (hue > 360) + hue -= 360; + while (hue < 0) + hue += 360; + + if (hue < 60) + g = m1 + (m2 - m1) * hue / 60; + else if (hue < 180) + g = m2; + else if (hue < 240) + g = m1 + (m2 - m1) * (240 - hue) / 60; + else + g = m1; + + hue = *h - 120; + while (hue > 360) + hue -= 360; + while (hue < 0) + hue += 360; + + if (hue < 60) + b = m1 + (m2 - m1) * hue / 60; + else if (hue < 180) + b = m2; + else if (hue < 240) + b = m1 + (m2 - m1) * (240 - hue) / 60; + else + b = m1; + + *h = r; + *l = g; + *s = b; + } +} + +static void +_shade_color (GdkRGBA *color, + gdouble factor) +{ + GdkRGBA temp; + + temp = *color; + rgb_to_hls (&temp.red, &temp.green, &temp.blue); + + temp.green *= factor; + if (temp.green > 1.0) + temp.green = 1.0; + else if (temp.green < 0.0) + temp.green = 0.0; + + temp.blue *= factor; + if (temp.blue > 1.0) + temp.blue = 1.0; + else if (temp.blue < 0.0) + temp.blue = 0.0; + + hls_to_rgb (&temp.red, &temp.green, &temp.blue); + *color = temp; +} + /** * gtk_symbolic_color_resolve: * @color: a #GtkSymbolicColor @@ -341,10 +516,8 @@ gtk_symbolic_color_resolve (GtkSymbolicColor *color, if (!gtk_symbolic_color_resolve (color->shade.color, props, &shade)) return FALSE; - resolved_color->red = CLAMP (shade.red * color->shade.factor, 0, 1); - resolved_color->green = CLAMP (shade.green * color->shade.factor, 0, 1); - resolved_color->blue = CLAMP (shade.blue * color->shade.factor, 0, 1); - resolved_color->alpha = shade.alpha; + _shade_color (&shade, color->shade.factor); + *resolved_color = shade; return TRUE; }