1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 2010 Carlos Garnacho <carlosg@gnome.org>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 #include "gtksymboliccolor.h"
22 #include "gtkstyleproperties.h"
26 * SECTION:gtksymboliccolor
27 * @Short_description: Symbolic colors
28 * @Title: GtkSymbolicColor
30 * GtkSymbolicColor is a boxed type that represents a symbolic color.
31 * It is the result of parsing a
32 * <link linkend="gtkcssprovider-symbolic-colors">color expression</link>.
33 * To obtain the color represented by a GtkSymbolicColor, it has to
34 * be resolved with gtk_symbolic_color_resolve(), which replaces all
35 * symbolic color references by the colors they refer to (in a given
36 * context) and evaluates mix, shade and other expressions, resulting
37 * in a #GdkRGBA value.
39 * It is not normally necessary to deal directly with #GtkSymbolicColors,
40 * since they are mostly used behind the scenes by #GtkStyleContext and
44 G_DEFINE_BOXED_TYPE (GtkSymbolicColor, gtk_symbolic_color,
45 gtk_symbolic_color_ref, gtk_symbolic_color_unref)
56 struct _GtkSymbolicColor
68 GtkSymbolicColor *color;
74 GtkSymbolicColor *color1;
75 GtkSymbolicColor *color2;
82 * gtk_symbolic_color_new_literal:
85 * Creates a symbolic color pointing to a literal color.
87 * Returns: a newly created #GtkSymbolicColor
92 gtk_symbolic_color_new_literal (const GdkRGBA *color)
94 GtkSymbolicColor *symbolic_color;
96 g_return_val_if_fail (color != NULL, NULL);
98 symbolic_color = g_slice_new0 (GtkSymbolicColor);
99 symbolic_color->type = COLOR_TYPE_LITERAL;
100 symbolic_color->color = *color;
101 symbolic_color->ref_count = 1;
103 return symbolic_color;
107 * gtk_symbolic_color_new_name:
110 * Creates a symbolic color pointing to an unresolved named
111 * color. See gtk_style_context_lookup_color() and
112 * gtk_style_properties_lookup_color().
114 * Returns: a newly created #GtkSymbolicColor
119 gtk_symbolic_color_new_name (const gchar *name)
121 GtkSymbolicColor *symbolic_color;
123 g_return_val_if_fail (name != NULL, NULL);
125 symbolic_color = g_slice_new0 (GtkSymbolicColor);
126 symbolic_color->type = COLOR_TYPE_NAME;
127 symbolic_color->name = g_strdup (name);
128 symbolic_color->ref_count = 1;
130 return symbolic_color;
134 * gtk_symbolic_color_new_shade:
135 * @color: another #GtkSymbolicColor
136 * @factor: shading factor to apply to @color
138 * Creates a symbolic color defined as a shade of
139 * another color. A factor > 1.0 would resolve to
140 * a brighter color, while < 1.0 would resolve to
143 * Returns: A newly created #GtkSymbolicColor
148 gtk_symbolic_color_new_shade (GtkSymbolicColor *color,
151 GtkSymbolicColor *symbolic_color;
153 g_return_val_if_fail (color != NULL, NULL);
155 symbolic_color = g_slice_new0 (GtkSymbolicColor);
156 symbolic_color->type = COLOR_TYPE_SHADE;
157 symbolic_color->shade.color = gtk_symbolic_color_ref (color);
158 symbolic_color->shade.factor = factor;
159 symbolic_color->ref_count = 1;
161 return symbolic_color;
165 * gtk_symbolic_color_new_alpha:
166 * @color: another #GtkSymbolicColor
167 * @factor: factor to apply to @color alpha
169 * Creates a symbolic color by modifying the relative alpha
170 * value of @color. A factor < 1.0 would resolve to a more
171 * transparent color, while > 1.0 would resolve to a more
174 * Returns: A newly created #GtkSymbolicColor
179 gtk_symbolic_color_new_alpha (GtkSymbolicColor *color,
182 GtkSymbolicColor *symbolic_color;
184 g_return_val_if_fail (color != NULL, NULL);
186 symbolic_color = g_slice_new0 (GtkSymbolicColor);
187 symbolic_color->type = COLOR_TYPE_ALPHA;
188 symbolic_color->alpha.color = gtk_symbolic_color_ref (color);
189 symbolic_color->alpha.factor = factor;
190 symbolic_color->ref_count = 1;
192 return symbolic_color;
196 * gtk_symbolic_color_new_mix:
197 * @color1: color to mix
198 * @color2: another color to mix
199 * @factor: mix factor
201 * Creates a symbolic color defined as a mix of another
202 * two colors. a mix factor of 0 would resolve to @color1,
203 * while a factor of 1 would resolve to @color2.
205 * Returns: A newly created #GtkSymbolicColor
210 gtk_symbolic_color_new_mix (GtkSymbolicColor *color1,
211 GtkSymbolicColor *color2,
214 GtkSymbolicColor *symbolic_color;
216 g_return_val_if_fail (color1 != NULL, NULL);
217 g_return_val_if_fail (color1 != NULL, NULL);
219 symbolic_color = g_slice_new0 (GtkSymbolicColor);
220 symbolic_color->type = COLOR_TYPE_MIX;
221 symbolic_color->mix.color1 = gtk_symbolic_color_ref (color1);
222 symbolic_color->mix.color2 = gtk_symbolic_color_ref (color2);
223 symbolic_color->mix.factor = factor;
224 symbolic_color->ref_count = 1;
226 return symbolic_color;
230 * gtk_symbolic_color_ref:
231 * @color: a #GtkSymbolicColor
233 * Increases the reference count of @color
235 * Returns: the same @color
240 gtk_symbolic_color_ref (GtkSymbolicColor *color)
242 g_return_val_if_fail (color != NULL, NULL);
250 * gtk_symbolic_color_unref:
251 * @color: a #GtkSymbolicColor
253 * Decreases the reference count of @color, freeing its memory if the
254 * reference count reaches 0.
259 gtk_symbolic_color_unref (GtkSymbolicColor *color)
261 g_return_if_fail (color != NULL);
265 if (color->ref_count == 0)
269 case COLOR_TYPE_NAME:
270 g_free (color->name);
272 case COLOR_TYPE_SHADE:
273 gtk_symbolic_color_unref (color->shade.color);
275 case COLOR_TYPE_ALPHA:
276 gtk_symbolic_color_unref (color->alpha.color);
279 gtk_symbolic_color_unref (color->mix.color1);
280 gtk_symbolic_color_unref (color->mix.color2);
286 g_slice_free (GtkSymbolicColor, color);
291 rgb_to_hls (gdouble *r,
339 s = (max - min) / (max + min);
341 s = (max - min) / (2 - max - min);
345 h = (green - blue) / delta;
346 else if (green == max)
347 h = 2 + (blue - red) / delta;
348 else if (blue == max)
349 h = 4 + (red - green) / delta;
362 hls_to_rgb (gdouble *h,
375 if (lightness <= 0.5)
376 m2 = lightness * (1 + saturation);
378 m2 = lightness + saturation - lightness * saturation;
379 m1 = 2 * lightness - m2;
396 r = m1 + (m2 - m1) * hue / 60;
400 r = m1 + (m2 - m1) * (240 - hue) / 60;
411 g = m1 + (m2 - m1) * hue / 60;
415 g = m1 + (m2 - m1) * (240 - hue) / 60;
426 b = m1 + (m2 - m1) * hue / 60;
430 b = m1 + (m2 - m1) * (240 - hue) / 60;
441 _shade_color (GdkRGBA *color,
447 rgb_to_hls (&temp.red, &temp.green, &temp.blue);
449 temp.green *= factor;
450 if (temp.green > 1.0)
452 else if (temp.green < 0.0)
458 else if (temp.blue < 0.0)
461 hls_to_rgb (&temp.red, &temp.green, &temp.blue);
466 * gtk_symbolic_color_resolve:
467 * @color: a #GtkSymbolicColor
468 * @props: (allow-none): #GtkStyleProperties to use when resolving
469 * named colors, or %NULL
470 * @resolved_color: (out): return location for the resolved color
472 * If @color is resolvable, @resolved_color will be filled in
473 * with the resolved color, and %TRUE will be returned. Generally,
474 * if @color can't be resolved, it is due to it being defined on
475 * top of a named color that doesn't exist in @props.
477 * When @props is %NULL, resolving of named colors will fail, so if
478 * your @color is or references such a color, this function will
481 * Returns: %TRUE if the color has been resolved
486 gtk_symbolic_color_resolve (GtkSymbolicColor *color,
487 GtkStyleProperties *props,
488 GdkRGBA *resolved_color)
490 g_return_val_if_fail (color != NULL, FALSE);
491 g_return_val_if_fail (resolved_color != NULL, FALSE);
492 g_return_val_if_fail (props == NULL || GTK_IS_STYLE_PROPERTIES (props), FALSE);
496 case COLOR_TYPE_LITERAL:
497 *resolved_color = color->color;
499 case COLOR_TYPE_NAME:
501 GtkSymbolicColor *named_color;
506 named_color = gtk_style_properties_lookup_color (props, color->name);
511 return gtk_symbolic_color_resolve (named_color, props, resolved_color);
515 case COLOR_TYPE_SHADE:
519 if (!gtk_symbolic_color_resolve (color->shade.color, props, &shade))
522 _shade_color (&shade, color->shade.factor);
523 *resolved_color = shade;
529 case COLOR_TYPE_ALPHA:
533 if (!gtk_symbolic_color_resolve (color->alpha.color, props, &alpha))
536 *resolved_color = alpha;
537 resolved_color->alpha = CLAMP (alpha.alpha * color->alpha.factor, 0, 1);
543 GdkRGBA color1, color2;
545 if (!gtk_symbolic_color_resolve (color->mix.color1, props, &color1))
548 if (!gtk_symbolic_color_resolve (color->mix.color2, props, &color2))
551 resolved_color->red = CLAMP (color1.red + ((color2.red - color1.red) * color->mix.factor), 0, 1);
552 resolved_color->green = CLAMP (color1.green + ((color2.green - color1.green) * color->mix.factor), 0, 1);
553 resolved_color->blue = CLAMP (color1.blue + ((color2.blue - color1.blue) * color->mix.factor), 0, 1);
554 resolved_color->alpha = CLAMP (color1.alpha + ((color2.alpha - color1.alpha) * color->mix.factor), 0, 1);
561 g_assert_not_reached ();
568 * gtk_symbolic_color_to_string:
569 * @color: color to convert to a string
571 * Converts the given @color to a string representation. This is useful
572 * both for debugging and for serialization of strings. The format of
573 * the string may change between different versions of GTK, but it is
574 * guaranteed that the GTK css parser is able to read the string and
575 * create the same symbolic color from it.
577 * Returns: a new string representing @color
580 gtk_symbolic_color_to_string (GtkSymbolicColor *color)
584 g_return_val_if_fail (color != NULL, NULL);
588 case COLOR_TYPE_LITERAL:
589 s = gdk_rgba_to_string (&color->color);
591 case COLOR_TYPE_NAME:
592 s = g_strconcat ("@", color->name, NULL);
594 case COLOR_TYPE_SHADE:
596 char *color_string = gtk_symbolic_color_to_string (color->shade.color);
597 char factor[G_ASCII_DTOSTR_BUF_SIZE];
599 g_ascii_dtostr (factor, sizeof (factor), color->shade.factor);
600 s = g_strdup_printf ("shade (%s, %s)", color_string, factor);
601 g_free (color_string);
604 case COLOR_TYPE_ALPHA:
606 char *color_string = gtk_symbolic_color_to_string (color->shade.color);
607 char factor[G_ASCII_DTOSTR_BUF_SIZE];
609 g_ascii_dtostr (factor, sizeof (factor), color->alpha.factor);
610 s = g_strdup_printf ("alpha (%s, %s)", color_string, factor);
611 g_free (color_string);
616 char *color_string1 = gtk_symbolic_color_to_string (color->mix.color1);
617 char *color_string2 = gtk_symbolic_color_to_string (color->mix.color2);
618 char factor[G_ASCII_DTOSTR_BUF_SIZE];
620 g_ascii_dtostr (factor, sizeof (factor), color->mix.factor);
621 s = g_strdup_printf ("mix (%s, %s, %s)", color_string1, color_string2, factor);
622 g_free (color_string1);
623 g_free (color_string2);
627 g_assert_not_reached ();