1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 2011 Red Hat, Inc.
4 * Author: Cosimo Cecchi <cosimoc@gnome.org>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
22 #include "gtkcssshadowvalueprivate.h"
24 #include "gtkcssrgbavalueprivate.h"
25 #include "gtkstylecontextprivate.h"
26 #include "gtksymboliccolorprivate.h"
27 #include "gtkthemingengineprivate.h"
43 gtk_css_value_shadow_free (GtkCssValue *shadow)
45 _gtk_css_value_unref (shadow->color);
47 g_slice_free (GtkCssValue, shadow);
51 gtk_css_value_shadow_equal (const GtkCssValue *shadow1,
52 const GtkCssValue *shadow2)
55 return shadow1 == shadow2;
59 gtk_css_value_shadow_transition (GtkCssValue *start,
67 gtk_css_value_shadow_print (const GtkCssValue *shadow,
71 g_string_append (string, "inset ");
73 g_string_append_printf (string, "%d %d ",
74 (gint) shadow->hoffset,
75 (gint) shadow->voffset);
77 if (shadow->radius != 0)
78 g_string_append_printf (string, "%d ", (gint) shadow->radius);
80 if (shadow->spread != 0)
81 g_string_append_printf (string, "%d ", (gint) shadow->spread);
83 _gtk_css_value_print (shadow->color, string);
86 static const GtkCssValueClass GTK_CSS_VALUE_SHADOW = {
87 gtk_css_value_shadow_free,
88 gtk_css_value_shadow_equal,
89 gtk_css_value_shadow_transition,
90 gtk_css_value_shadow_print
94 gtk_css_shadow_value_new (gdouble hoffset,
103 retval = _gtk_css_value_new (GtkCssValue, >K_CSS_VALUE_SHADOW);
105 retval->hoffset = hoffset;
106 retval->voffset = voffset;
107 retval->radius = radius;
108 retval->spread = spread;
109 retval->inset = inset;
110 retval->color = color;
116 _gtk_css_shadow_value_parse (GtkCssParser *parser)
118 gboolean have_inset, have_color, have_lengths;
119 gdouble hoffset, voffset, blur, spread;
120 GtkSymbolicColor *color;
123 have_inset = have_lengths = have_color = FALSE;
125 for (i = 0; i < 3; i++)
128 _gtk_css_parser_try (parser, "inset", TRUE))
135 _gtk_css_parser_try_double (parser, &hoffset))
139 if (!_gtk_css_parser_try_double (parser, &voffset))
141 _gtk_css_parser_error (parser, "Horizontal and vertical offsets are required");
143 gtk_symbolic_color_unref (color);
147 if (!_gtk_css_parser_try_double (parser, &blur))
150 if (!_gtk_css_parser_try_double (parser, &spread))
160 /* XXX: the color is optional and UA-defined if it's missing,
161 * but it doesn't really make sense for us...
163 color = _gtk_css_parser_read_symbolic_color (parser);
170 if (!have_color || !have_lengths)
172 _gtk_css_parser_error (parser, "Must specify at least color and offsets");
174 gtk_symbolic_color_unref (color);
178 return gtk_css_shadow_value_new (hoffset, voffset,
179 blur, spread, have_inset,
180 _gtk_css_value_new_take_symbolic_color (color));
184 _gtk_css_shadow_value_compute (GtkCssValue *shadow,
185 GtkStyleContext *context)
189 color = _gtk_css_rgba_value_compute_from_symbolic (shadow->color,
190 _gtk_css_value_new_take_symbolic_color (
191 gtk_symbolic_color_ref (
192 _gtk_symbolic_color_get_current_color ())),
196 return gtk_css_shadow_value_new (shadow->hoffset, shadow->voffset,
197 shadow->radius, shadow->spread, shadow->inset,
202 _gtk_css_shadow_value_paint_layout (const GtkCssValue *shadow,
206 g_return_if_fail (shadow->class == >K_CSS_VALUE_SHADOW);
208 if (!cairo_has_current_point (cr))
209 cairo_move_to (cr, 0, 0);
213 cairo_rel_move_to (cr, shadow->hoffset, shadow->voffset);
214 gdk_cairo_set_source_rgba (cr, _gtk_css_rgba_value_get_rgba (shadow->color));
215 _gtk_pango_fill_layout (cr, layout);
217 cairo_rel_move_to (cr, -shadow->hoffset, -shadow->voffset);
222 _gtk_css_shadow_value_paint_icon (const GtkCssValue *shadow,
225 cairo_pattern_t *pattern;
227 g_return_if_fail (shadow->class == >K_CSS_VALUE_SHADOW);
230 pattern = cairo_pattern_reference (cairo_get_source (cr));
231 gdk_cairo_set_source_rgba (cr, _gtk_css_rgba_value_get_rgba (shadow->color));
233 cairo_translate (cr, shadow->hoffset, shadow->voffset);
234 cairo_mask (cr, pattern);
237 cairo_pattern_destroy (pattern);
241 _gtk_css_shadow_value_paint_spinner (const GtkCssValue *shadow,
246 g_return_if_fail (shadow->class == >K_CSS_VALUE_SHADOW);
250 cairo_translate (cr, shadow->hoffset, shadow->voffset);
251 _gtk_theming_engine_paint_spinner (cr,
253 _gtk_css_rgba_value_get_rgba (shadow->color));
259 _gtk_css_shadow_value_paint_box (const GtkCssValue *shadow,
261 const GtkRoundedBox *padding_box)
265 g_return_if_fail (shadow->class == >K_CSS_VALUE_SHADOW);
268 cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
270 _gtk_rounded_box_path (padding_box, cr);
274 _gtk_rounded_box_move (&box, shadow->hoffset, shadow->voffset);
275 _gtk_rounded_box_shrink (&box,
276 shadow->spread, shadow->spread,
277 shadow->spread, shadow->spread);
279 _gtk_rounded_box_path (&box, cr);
280 _gtk_rounded_box_clip_path (padding_box, cr);
282 gdk_cairo_set_source_rgba (cr, _gtk_css_rgba_value_get_rgba (shadow->color));