1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 2011 Red Hat, Inc.
3 *
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.
8 *
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.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #include "config.h"
19
20 #include "gtkcssrgbavalueprivate.h"
21
22 #include "gtkcssstylepropertyprivate.h"
23 #include "gtkstylecontextprivate.h"
24
25 struct _GtkCssValue {
26 GTK_CSS_VALUE_BASE
27 GdkRGBA rgba;
28 };
29
30 static void
gtk_css_value_rgba_free(GtkCssValue * value)31 gtk_css_value_rgba_free (GtkCssValue *value)
32 {
33 g_slice_free (GtkCssValue, value);
34 }
35
36 static GtkCssValue *
gtk_css_value_rgba_compute(GtkCssValue * value,guint property_id,GtkStyleProviderPrivate * provider,GtkCssStyle * style,GtkCssStyle * parent_style)37 gtk_css_value_rgba_compute (GtkCssValue *value,
38 guint property_id,
39 GtkStyleProviderPrivate *provider,
40 GtkCssStyle *style,
41 GtkCssStyle *parent_style)
42 {
43 return _gtk_css_value_ref (value);
44 }
45
46 static gboolean
gtk_css_value_rgba_equal(const GtkCssValue * rgba1,const GtkCssValue * rgba2)47 gtk_css_value_rgba_equal (const GtkCssValue *rgba1,
48 const GtkCssValue *rgba2)
49 {
50 return gdk_rgba_equal (&rgba1->rgba, &rgba2->rgba);
51 }
52
53 static inline double
transition(double start,double end,double progress)54 transition (double start,
55 double end,
56 double progress)
57 {
58 return start + (end - start) * progress;
59 }
60
61 static GtkCssValue *
gtk_css_value_rgba_transition(GtkCssValue * start,GtkCssValue * end,guint property_id,double progress)62 gtk_css_value_rgba_transition (GtkCssValue *start,
63 GtkCssValue *end,
64 guint property_id,
65 double progress)
66 {
67 GdkRGBA result;
68
69 progress = CLAMP (progress, 0, 1);
70 result.alpha = transition (start->rgba.alpha, end->rgba.alpha, progress);
71 if (result.alpha <= 0.0)
72 {
73 result.red = result.green = result.blue = 0.0;
74 }
75 else
76 {
77 result.red = transition (start->rgba.red * start->rgba.alpha,
78 end->rgba.red * end->rgba.alpha,
79 progress) / result.alpha;
80 result.green = transition (start->rgba.green * start->rgba.alpha,
81 end->rgba.green * end->rgba.alpha,
82 progress) / result.alpha;
83 result.blue = transition (start->rgba.blue * start->rgba.alpha,
84 end->rgba.blue * end->rgba.alpha,
85 progress) / result.alpha;
86 }
87
88 return _gtk_css_rgba_value_new_from_rgba (&result);
89 }
90
91 static void
gtk_css_value_rgba_print(const GtkCssValue * rgba,GString * string)92 gtk_css_value_rgba_print (const GtkCssValue *rgba,
93 GString *string)
94 {
95 char *s = gdk_rgba_to_string (&rgba->rgba);
96 g_string_append (string, s);
97 g_free (s);
98 }
99
100 static const GtkCssValueClass GTK_CSS_VALUE_RGBA = {
101 gtk_css_value_rgba_free,
102 gtk_css_value_rgba_compute,
103 gtk_css_value_rgba_equal,
104 gtk_css_value_rgba_transition,
105 gtk_css_value_rgba_print
106 };
107
108 GtkCssValue *
_gtk_css_rgba_value_new_from_rgba(const GdkRGBA * rgba)109 _gtk_css_rgba_value_new_from_rgba (const GdkRGBA *rgba)
110 {
111 GtkCssValue *value;
112
113 g_return_val_if_fail (rgba != NULL, NULL);
114
115 value = _gtk_css_value_new (GtkCssValue, >K_CSS_VALUE_RGBA);
116 value->rgba = *rgba;
117
118 return value;
119 }
120
121 const GdkRGBA *
_gtk_css_rgba_value_get_rgba(const GtkCssValue * rgba)122 _gtk_css_rgba_value_get_rgba (const GtkCssValue *rgba)
123 {
124 g_return_val_if_fail (rgba->class == >K_CSS_VALUE_RGBA, NULL);
125
126 return &rgba->rgba;
127 }
128