X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtkcssshadowvalue.c;h=618288807af8d3b7e9571d013c632880a9f7f67a;hb=3c8e1c92a85b2e41161698f141747ced2c574f32;hp=a2389f4e37f27e7d1693ee6e83f65b35ed7f7c74;hpb=333a5b4307eca43786a2ffdafb216c542ec8db66;p=~andy%2Fgtk diff --git a/gtk/gtkcssshadowvalue.c b/gtk/gtkcssshadowvalue.c index a2389f4e3..618288807 100644 --- a/gtk/gtkcssshadowvalue.c +++ b/gtk/gtkcssshadowvalue.c @@ -21,10 +21,11 @@ #include "gtkcssshadowvalueprivate.h" +#include "gtkcairoblurprivate.h" +#include "gtkcsscolorvalueprivate.h" #include "gtkcssnumbervalueprivate.h" #include "gtkcssrgbavalueprivate.h" #include "gtkstylecontextprivate.h" -#include "gtksymboliccolorprivate.h" #include "gtkthemingengineprivate.h" #include "gtkpango.h" @@ -59,6 +60,40 @@ gtk_css_value_shadow_free (GtkCssValue *shadow) g_slice_free (GtkCssValue, shadow); } +static GtkCssValue * +gtk_css_value_shadow_compute (GtkCssValue *shadow, + guint property_id, + GtkStyleProviderPrivate *provider, + GtkCssComputedValues *values, + GtkCssComputedValues *parent_values, + GtkCssDependencies *dependencies) +{ + GtkCssValue *hoffset, *voffset, *radius, *spread, *color; + GtkCssDependencies child_deps; + + child_deps = 0; + hoffset = _gtk_css_value_compute (shadow->hoffset, property_id, provider, values, parent_values, &child_deps); + *dependencies = _gtk_css_dependencies_union (*dependencies, child_deps); + + child_deps = 0; + voffset = _gtk_css_value_compute (shadow->voffset, property_id, provider, values, parent_values, &child_deps); + *dependencies = _gtk_css_dependencies_union (*dependencies, child_deps); + + child_deps = 0; + radius = _gtk_css_value_compute (shadow->radius, property_id, provider, values, parent_values, &child_deps); + *dependencies = _gtk_css_dependencies_union (*dependencies, child_deps); + + child_deps = 0; + spread = _gtk_css_value_compute (shadow->spread, property_id, provider, values, parent_values, &child_deps), + *dependencies = _gtk_css_dependencies_union (*dependencies, child_deps); + + child_deps = 0; + color = _gtk_css_value_compute (shadow->color, property_id, provider, values, parent_values, &child_deps); + *dependencies = _gtk_css_dependencies_union (*dependencies, child_deps); + + return gtk_css_shadow_value_new (hoffset, voffset, radius, spread, shadow->inset, color); +} + static gboolean gtk_css_value_shadow_equal (const GtkCssValue *shadow1, const GtkCssValue *shadow2) @@ -74,17 +109,18 @@ gtk_css_value_shadow_equal (const GtkCssValue *shadow1, static GtkCssValue * gtk_css_value_shadow_transition (GtkCssValue *start, GtkCssValue *end, + guint property_id, double progress) { if (start->inset != end->inset) return NULL; - return gtk_css_shadow_value_new (_gtk_css_value_transition (start->hoffset, end->hoffset, progress), - _gtk_css_value_transition (start->voffset, end->voffset, progress), - _gtk_css_value_transition (start->radius, end->radius, progress), - _gtk_css_value_transition (start->spread, end->spread, progress), + return gtk_css_shadow_value_new (_gtk_css_value_transition (start->hoffset, end->hoffset, property_id, progress), + _gtk_css_value_transition (start->voffset, end->voffset, property_id, progress), + _gtk_css_value_transition (start->radius, end->radius, property_id, progress), + _gtk_css_value_transition (start->spread, end->spread, property_id, progress), start->inset, - _gtk_css_value_transition (start->color, end->color, progress)); + _gtk_css_value_transition (start->color, end->color, property_id, progress)); } static void @@ -117,6 +153,7 @@ gtk_css_value_shadow_print (const GtkCssValue *shadow, static const GtkCssValueClass GTK_CSS_VALUE_SHADOW = { gtk_css_value_shadow_free, + gtk_css_value_shadow_compute, gtk_css_value_shadow_equal, gtk_css_value_shadow_transition, gtk_css_value_shadow_print @@ -234,7 +271,7 @@ _gtk_css_shadow_value_parse (GtkCssParser *parser) } else if (values[COLOR] == NULL) { - values[COLOR] = _gtk_css_symbolic_value_new (parser); + values[COLOR] = _gtk_css_color_value_parse (parser); if (values[COLOR] == NULL) goto fail; @@ -250,9 +287,7 @@ _gtk_css_shadow_value_parse (GtkCssParser *parser) while (values[HOFFSET] == NULL || !value_is_done_parsing (parser)); if (values[COLOR] == NULL) - values[COLOR] = _gtk_css_symbolic_value_new_take_symbolic_color ( - gtk_symbolic_color_ref ( - _gtk_symbolic_color_get_current_color ())); + values[COLOR] = _gtk_css_color_value_new_current_color (); return gtk_css_shadow_value_new (values[HOFFSET], values[VOFFSET], values[RADIUS], values[SPREAD], @@ -268,25 +303,67 @@ fail: return NULL; } -GtkCssValue * -_gtk_css_shadow_value_compute (GtkCssValue *shadow, - GtkStyleContext *context) +static const cairo_user_data_key_t shadow_key; + +static cairo_t * +gtk_css_shadow_value_start_drawing (const GtkCssValue *shadow, + cairo_t *cr) { - GdkRGBA transparent = { 0, 0, 0, 0 }; - GtkCssValue *color; + cairo_rectangle_int_t clip_rect; + cairo_surface_t *surface; + cairo_t *blur_cr; + gdouble radius; + + radius = _gtk_css_number_value_get (shadow->radius, 0); + if (radius == 0.0) + return cr; + + gdk_cairo_get_clip_rectangle (cr, &clip_rect); + + /* Create a larger surface to center the blur. */ + surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, + clip_rect.width + 2 * radius, + clip_rect.height + 2 * radius); + cairo_surface_set_device_offset (surface, radius - clip_rect.x, radius - clip_rect.y); + blur_cr = cairo_create (surface); + cairo_set_user_data (blur_cr, &shadow_key, cairo_reference (cr), (cairo_destroy_func_t) cairo_destroy); + + if (cairo_has_current_point (cr)) + { + double x, y; + + cairo_get_current_point (cr, &x, &y); + cairo_move_to (blur_cr, x, y); + } + + return blur_cr; +} + +static cairo_t * +gtk_css_shadow_value_finish_drawing (const GtkCssValue *shadow, + cairo_t *cr) +{ + gdouble radius; + cairo_t *original_cr; + cairo_surface_t *surface; + + radius = _gtk_css_number_value_get (shadow->radius, 0); + if (radius == 0.0) + return cr; + + surface = cairo_get_target (cr); + original_cr = cairo_get_user_data (cr, &shadow_key); + + /* Blur the surface. */ + _gtk_cairo_blur_surface (surface, radius); + + cairo_set_source_surface (original_cr, surface, 0, 0); + cairo_paint (original_cr); - color = _gtk_css_rgba_value_compute_from_symbolic (shadow->color, - _gtk_css_symbolic_value_new_take_symbolic_color ( - gtk_symbolic_color_new_literal (&transparent)), - context, - FALSE); - - return gtk_css_shadow_value_new (_gtk_css_number_value_compute (shadow->hoffset, context), - _gtk_css_number_value_compute (shadow->voffset, context), - _gtk_css_number_value_compute (shadow->radius, context), - _gtk_css_number_value_compute (shadow->spread, context), - shadow->inset, - color); + cairo_destroy (cr); + cairo_surface_destroy (surface); + + return original_cr; } void @@ -304,9 +381,14 @@ _gtk_css_shadow_value_paint_layout (const GtkCssValue *shadow, cairo_rel_move_to (cr, _gtk_css_number_value_get (shadow->hoffset, 0), _gtk_css_number_value_get (shadow->voffset, 0)); + + cr = gtk_css_shadow_value_start_drawing (shadow, cr); + gdk_cairo_set_source_rgba (cr, _gtk_css_rgba_value_get_rgba (shadow->color)); _gtk_pango_fill_layout (cr, layout); + cr = gtk_css_shadow_value_finish_drawing (shadow, cr); + cairo_rel_move_to (cr, - _gtk_css_number_value_get (shadow->hoffset, 0), - _gtk_css_number_value_get (shadow->voffset, 0)); @@ -323,6 +405,9 @@ _gtk_css_shadow_value_paint_icon (const GtkCssValue *shadow, cairo_save (cr); pattern = cairo_pattern_reference (cairo_get_source (cr)); + + cr = gtk_css_shadow_value_start_drawing (shadow, cr); + gdk_cairo_set_source_rgba (cr, _gtk_css_rgba_value_get_rgba (shadow->color)); cairo_translate (cr, @@ -330,6 +415,8 @@ _gtk_css_shadow_value_paint_icon (const GtkCssValue *shadow, _gtk_css_number_value_get (shadow->voffset, 0)); cairo_mask (cr, pattern); + cr = gtk_css_shadow_value_finish_drawing (shadow, cr); + cairo_restore (cr); cairo_pattern_destroy (pattern); } @@ -344,6 +431,8 @@ _gtk_css_shadow_value_paint_spinner (const GtkCssValue *shadow, cairo_save (cr); + cr = gtk_css_shadow_value_start_drawing (shadow, cr); + cairo_translate (cr, _gtk_css_number_value_get (shadow->hoffset, 0), _gtk_css_number_value_get (shadow->voffset, 0)); @@ -351,6 +440,8 @@ _gtk_css_shadow_value_paint_spinner (const GtkCssValue *shadow, radius, progress, _gtk_css_rgba_value_get_rgba (shadow->color)); + cr = gtk_css_shadow_value_finish_drawing (shadow, cr); + cairo_restore (cr); } @@ -359,13 +450,12 @@ _gtk_css_shadow_value_paint_box (const GtkCssValue *shadow, cairo_t *cr, const GtkRoundedBox *padding_box) { - GtkRoundedBox box; - double spread; + GtkRoundedBox box, clip_box; + double spread, radius; g_return_if_fail (shadow->class == >K_CSS_VALUE_SHADOW); cairo_save (cr); - cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD); _gtk_rounded_box_path (padding_box, cr); cairo_clip (cr); @@ -377,11 +467,20 @@ _gtk_css_shadow_value_paint_box (const GtkCssValue *shadow, spread = _gtk_css_number_value_get (shadow->spread, 0); _gtk_rounded_box_shrink (&box, spread, spread, spread, spread); + clip_box = *padding_box; + radius = _gtk_css_number_value_get (shadow->radius, 0); + _gtk_rounded_box_shrink (&clip_box, -radius, -radius, -radius, -radius); + + cr = gtk_css_shadow_value_start_drawing (shadow, cr); + + cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD); _gtk_rounded_box_path (&box, cr); - _gtk_rounded_box_clip_path (padding_box, cr); + _gtk_rounded_box_clip_path (&clip_box, cr); gdk_cairo_set_source_rgba (cr, _gtk_css_rgba_value_get_rgba (shadow->color)); cairo_fill (cr); + cr = gtk_css_shadow_value_finish_drawing (shadow, cr); + cairo_restore (cr); }