diff options
Diffstat (limited to 'e-util/e-misc-utils.c')
-rw-r--r-- | e-util/e-misc-utils.c | 275 |
1 files changed, 274 insertions, 1 deletions
diff --git a/e-util/e-misc-utils.c b/e-util/e-misc-utils.c index 88f6da9599..4b54e4af66 100644 --- a/e-util/e-misc-utils.c +++ b/e-util/e-misc-utils.c @@ -1223,7 +1223,6 @@ e_color_to_value (const GdkColor *color) * e_rgba_to_value: * @rgba: a #GdkRGBA * - * * Converts #GdkRGBA to a 24-bit RGB color value * * Returns: a 24-bit color value @@ -1247,6 +1246,280 @@ e_rgba_to_value (const GdkRGBA *rgba) (blue & 0xFF)) & 0xffffff); } +/** + * e_rgba_to_color: + * @rgba: a source #GdkRGBA + * @color: a destination #GdkColor + * + * Converts @rgba into @color, but loses the alpha chnnel from @rgba. + **/ +void +e_rgba_to_color (const GdkRGBA *rgba, + GdkColor *color) +{ + g_return_if_fail (rgba != NULL); + g_return_if_fail (color != NULL); + + color->pixel = 0; + color->red = rgba->red * 65535.0; + color->green = rgba->green * 65535.0; + color->blue = rgba->blue * 65535.0; +} + +/** + * e_utils_get_theme_color: + * @widget: a #GtkWidget instance + * @color_names: comma-separated theme color names + * @fallback_color_ident: fallback color identificator, in a format for gdk_rgba_parse() + * @rgba: where to store the read color + * + * Reads named theme color from a #GtkStyleContext of @widget. + * The @color_names are read one after another from left to right, + * the next are meant as fallbacks, in case the theme doesn't + * define the previous color. If none is found then the @fallback_color_ident + * is set to @rgba. + **/ +void +e_utils_get_theme_color (GtkWidget *widget, + const gchar *color_names, + const gchar *fallback_color_ident, + GdkRGBA *rgba) +{ + GtkStyleContext *style_context; + gchar **names; + gint ii; + + g_return_if_fail (GTK_IS_WIDGET (widget)); + g_return_if_fail (color_names != NULL); + g_return_if_fail (fallback_color_ident != NULL); + g_return_if_fail (rgba != NULL); + + style_context = gtk_widget_get_style_context (widget); + + names = g_strsplit (color_names, ",", -1); + for (ii = 0; names && names[ii]; ii++) { + if (gtk_style_context_lookup_color (style_context, names[ii], rgba)) { + g_strfreev (names); + return; + } + } + + g_strfreev (names); + + g_warn_if_fail (gdk_rgba_parse (rgba, fallback_color_ident)); +} + +/** + * e_utils_get_theme_color_color: + * @widget: a #GtkWidget instance + * @color_names: comma-separated theme color names + * @fallback_color_ident: fallback color identificator, in a format for gdk_rgba_parse() + * @color: where to store the read color + * + * The same as e_utils_get_theme_color(), only populates #GdkColor, + * instead of #GdkRGBA. + **/ +void +e_utils_get_theme_color_color (GtkWidget *widget, + const gchar *color_names, + const gchar *fallback_color_ident, + GdkColor *color) +{ + GdkRGBA rgba; + + g_return_if_fail (GTK_IS_WIDGET (widget)); + g_return_if_fail (color_names != NULL); + g_return_if_fail (fallback_color_ident != NULL); + g_return_if_fail (color != NULL); + + e_utils_get_theme_color (widget, color_names, fallback_color_ident, &rgba); + + e_rgba_to_color (&rgba, color); +} + +/* This is copied from gtk+ sources */ +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; +} + +/* This is copied from gtk+ sources */ +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; + } +} + +/* This is copied from gtk+ sources */ +void +e_utils_shade_color (const GdkRGBA *a, + GdkRGBA *b, + gdouble mult) +{ + gdouble red; + gdouble green; + gdouble blue; + + g_return_if_fail (a != NULL); + g_return_if_fail (b != NULL); + + red = a->red; + green = a->green; + blue = a->blue; + + rgb_to_hls (&red, &green, &blue); + + green *= mult; + if (green > 1.0) + green = 1.0; + else if (green < 0.0) + green = 0.0; + + blue *= mult; + if (blue > 1.0) + blue = 1.0; + else if (blue < 0.0) + blue = 0.0; + + hls_to_rgb (&red, &green, &blue); + + b->red = red; + b->green = green; + b->blue = blue; +} + static gint epow10 (gint number) { |