diff options
author | Andrea Cimitan <andrea.cimitan@canonical.com> | 2012-04-18 15:40:52 +0100 |
---|---|---|
committer | Andrea Cimitan <andrea.cimitan@canonical.com> | 2012-04-18 16:02:32 +0100 |
commit | b40f90f47b19bafb27d4ca46e52dc884276827fe (patch) | |
tree | e38752b63813cea7b947c03d84190c8edbbdbc9e | |
parent | 654553cc706d6e21e7e2b631ac9521e530c58fb1 (diff) | |
download | gtk+-wip/blur.tar.gz |
Optimize blur rendering by always choosing the smaller surface to blur, since rendering speed is inversely proportional to the dimension of the surface to blurwip/blur
-rw-r--r-- | gtk/gtkcssshadowsvalue.c | 5 | ||||
-rw-r--r-- | gtk/gtkcssshadowsvalueprivate.h | 4 | ||||
-rw-r--r-- | gtk/gtkcssshadowvalue.c | 117 | ||||
-rw-r--r-- | gtk/gtkcssshadowvalueprivate.h | 4 | ||||
-rw-r--r-- | gtk/gtkthemingengine.c | 13 |
5 files changed, 96 insertions, 47 deletions
diff --git a/gtk/gtkcssshadowsvalue.c b/gtk/gtkcssshadowsvalue.c index d4f7655b52..50ebe960d2 100644 --- a/gtk/gtkcssshadowsvalue.c +++ b/gtk/gtkcssshadowsvalue.c @@ -228,7 +228,8 @@ _gtk_css_shadows_value_paint_layout (const GtkCssValue *shadows, void _gtk_css_shadows_value_paint_icon (const GtkCssValue *shadows, - cairo_t *cr) + cairo_t *cr, + cairo_rectangle_t *rect) { guint i; @@ -236,7 +237,7 @@ _gtk_css_shadows_value_paint_icon (const GtkCssValue *shadows, for (i = 0; i < shadows->len; i++) { - _gtk_css_shadow_value_paint_icon (shadows->values[i], cr); + _gtk_css_shadow_value_paint_icon (shadows->values[i], cr, rect); } } diff --git a/gtk/gtkcssshadowsvalueprivate.h b/gtk/gtkcssshadowsvalueprivate.h index 0918278b4e..34b7db982a 100644 --- a/gtk/gtkcssshadowsvalueprivate.h +++ b/gtk/gtkcssshadowsvalueprivate.h @@ -41,12 +41,14 @@ void _gtk_css_shadows_value_paint_layout (const GtkCssValue PangoLayout *layout); void _gtk_css_shadows_value_paint_icon (const GtkCssValue *shadows, - cairo_t *cr); + cairo_t *cr, + cairo_rectangle_t *rect); void _gtk_css_shadows_value_paint_spinner (const GtkCssValue *shadows, cairo_t *cr, gdouble radius, gdouble progress); + void _gtk_css_shadows_value_paint_box (const GtkCssValue *shadows, cairo_t *cr, const GtkRoundedBox *padding_box); diff --git a/gtk/gtkcssshadowvalue.c b/gtk/gtkcssshadowvalue.c index 7296caf303..573ae3820c 100644 --- a/gtk/gtkcssshadowvalue.c +++ b/gtk/gtkcssshadowvalue.c @@ -18,6 +18,7 @@ */ #include "config.h" +#include "math.h" #include "gtkcssshadowvalueprivate.h" @@ -291,43 +292,41 @@ _gtk_css_shadow_value_compute (GtkCssValue *shadow, } static void -_gtk_css_shadow_value_blur_surface_create (const GtkCssValue *shadow, - cairo_t *original_cr, - cairo_t **out_cr, - cairo_surface_t **out_surface) +gtk_css_shadow_value_blur_surface_create (const GtkCssValue *shadow, + cairo_t *original_cr, + cairo_t **out_cr, + cairo_surface_t **out_surface, + cairo_rectangle_int_t *rect_surface) { - cairo_rectangle_int_t clip_rect; - gdouble radius; + gint radius; - gdk_cairo_get_clip_rectangle (original_cr, &clip_rect); - radius = _gtk_css_number_value_get (shadow->radius, 0); + radius = ceil (_gtk_css_number_value_get (shadow->radius, 0)); /* Create a larger surface to center the blur. */ *out_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, - clip_rect.width + 2 * radius, - clip_rect.height + 2 * radius); + rect_surface->width + 2 * radius, + rect_surface->height + 2 * radius); *out_cr = cairo_create (*out_surface); cairo_translate (*out_cr, radius, radius); } static void -_gtk_css_shadow_value_blur_surface_paint (const GtkCssValue *shadow, - cairo_t *cr, - cairo_surface_t *surface) +gtk_css_shadow_value_blur_surface_paint (const GtkCssValue *shadow, + cairo_t *cr, + cairo_surface_t *surface, + cairo_rectangle_int_t *rect_surface) { - gdouble x, y; - gdouble radius; + gint radius; - radius = _gtk_css_number_value_get (shadow->radius, 0); + radius = ceil (_gtk_css_number_value_get (shadow->radius, 0)); /* Blur the surface. */ _gtk_cairo_blur_surface (surface, radius); /* Paint the blurred surface to cr. */ - cairo_get_current_point (cr, &x, &y); cairo_set_source_surface (cr, surface, - x - radius, - y - radius); + rect_surface->x - radius, + rect_surface->y - radius); cairo_paint (cr); } @@ -349,17 +348,35 @@ _gtk_css_shadow_value_paint_layout (const GtkCssValue *shadow, if (_gtk_css_number_value_get (shadow->radius, 0) > 0) { + PangoRectangle ink_rect; cairo_t *blur_cr; cairo_surface_t *surface; - - _gtk_css_shadow_value_blur_surface_create (shadow, cr, - &blur_cr, &surface); + cairo_rectangle_int_t rect_surface; + gdouble x, y; + gint extra_pad; + + /* Calculate blur surface coordinates. */ + extra_pad = 1; /* Padding seems to help on blur edges, please verify. */ + pango_layout_get_pixel_extents (layout, &ink_rect, NULL); + cairo_get_current_point (cr, &x, &y); + rect_surface.x = x + ink_rect.x - extra_pad; /* Loss of precision? */ + rect_surface.y = y + ink_rect.y - extra_pad; /* Loss of precision? */ + rect_surface.width = ink_rect.width + 2 * extra_pad; + rect_surface.height = ink_rect.height + 2 * extra_pad; + + gtk_css_shadow_value_blur_surface_create (shadow, cr, + &blur_cr, &surface, + &rect_surface); /* Create the path on the surface to blur. */ + cairo_translate (blur_cr, + - ink_rect.x + extra_pad, + - ink_rect.y + extra_pad); + gdk_cairo_set_source_rgba (blur_cr, _gtk_css_rgba_value_get_rgba (shadow->color)); _gtk_pango_fill_layout (blur_cr, layout); - _gtk_css_shadow_value_blur_surface_paint (shadow, cr, surface); + gtk_css_shadow_value_blur_surface_paint (shadow, cr, surface, &rect_surface); cairo_destroy (blur_cr); cairo_surface_destroy (surface); @@ -378,7 +395,8 @@ _gtk_css_shadow_value_paint_layout (const GtkCssValue *shadow, void _gtk_css_shadow_value_paint_icon (const GtkCssValue *shadow, - cairo_t *cr) + cairo_t *cr, + cairo_rectangle_t *rect) { cairo_pattern_t *pattern; @@ -391,19 +409,23 @@ _gtk_css_shadow_value_paint_icon (const GtkCssValue *shadow, { cairo_t *blur_cr; cairo_surface_t *surface; + cairo_rectangle_int_t rect_surface; - _gtk_css_shadow_value_blur_surface_create (shadow, cr, - &blur_cr, &surface); + /* Calculate blur surface coordinates. */ + rect_surface.x = rect->x + _gtk_css_number_value_get (shadow->hoffset, 0); + rect_surface.y = rect->y + _gtk_css_number_value_get (shadow->voffset, 0); + rect_surface.width = rect->width; + rect_surface.height = rect->height; + + gtk_css_shadow_value_blur_surface_create (shadow, cr, + &blur_cr, &surface, + &rect_surface); /* Create the path on the surface to blur. */ gdk_cairo_set_source_rgba (blur_cr, _gtk_css_rgba_value_get_rgba (shadow->color)); - - cairo_translate (blur_cr, - _gtk_css_number_value_get (shadow->hoffset, 0), - _gtk_css_number_value_get (shadow->voffset, 0)); cairo_mask (blur_cr, pattern); - _gtk_css_shadow_value_blur_surface_paint (shadow, cr, surface); + gtk_css_shadow_value_blur_surface_paint (shadow, cr, surface, &rect_surface); cairo_destroy (blur_cr); cairo_surface_destroy (surface); @@ -436,19 +458,24 @@ _gtk_css_shadow_value_paint_spinner (const GtkCssValue *shadow, { cairo_t *blur_cr; cairo_surface_t *surface; + cairo_rectangle_int_t rect_surface; - _gtk_css_shadow_value_blur_surface_create (shadow, cr, - &blur_cr, &surface); + /* Calculate blur surface coordinates. */ + rect_surface.x = _gtk_css_number_value_get (shadow->hoffset, 0); + rect_surface.y = _gtk_css_number_value_get (shadow->voffset, 0); + rect_surface.width = 2 * radius; + rect_surface.height = 2 * radius; + + gtk_css_shadow_value_blur_surface_create (shadow, cr, + &blur_cr, &surface, + &rect_surface); /* Create the path on the surface to blur. */ - cairo_translate (blur_cr, - _gtk_css_number_value_get (shadow->hoffset, 0), - _gtk_css_number_value_get (shadow->voffset, 0)); _gtk_theming_engine_paint_spinner (blur_cr, radius, progress, _gtk_css_rgba_value_get_rgba (shadow->color)); - _gtk_css_shadow_value_blur_surface_paint (shadow, cr, surface); + gtk_css_shadow_value_blur_surface_paint (shadow, cr, surface, &rect_surface); cairo_destroy (blur_cr); cairo_surface_destroy (surface); @@ -493,9 +520,19 @@ _gtk_css_shadow_value_paint_box (const GtkCssValue *shadow, { cairo_t *blur_cr; cairo_surface_t *surface; + cairo_rectangle_int_t rect_surface; + gdouble x, y; + + /* Calculate blur surface coordinates. */ + cairo_get_current_point (cr, &x, &y); + rect_surface.x = x; /* Loss of precision? */ + rect_surface.x = y; /* Loss of precision? */ + rect_surface.width = MAX (padding_box->box.width, box.box.width); + rect_surface.height = MAX (padding_box->box.height, box.box.height); - _gtk_css_shadow_value_blur_surface_create (shadow, cr, - &blur_cr, &surface); + gtk_css_shadow_value_blur_surface_create (shadow, cr, + &blur_cr, &surface, + &rect_surface); /* Create the path on the surface to blur. */ _gtk_rounded_box_path (padding_box, blur_cr); @@ -509,7 +546,7 @@ _gtk_css_shadow_value_paint_box (const GtkCssValue *shadow, gdk_cairo_set_source_rgba (blur_cr, _gtk_css_rgba_value_get_rgba (shadow->color)); cairo_fill (blur_cr); - _gtk_css_shadow_value_blur_surface_paint (shadow, cr, surface); + gtk_css_shadow_value_blur_surface_paint (shadow, cr, surface, &rect_surface); cairo_destroy (blur_cr); cairo_surface_destroy (surface); diff --git a/gtk/gtkcssshadowvalueprivate.h b/gtk/gtkcssshadowvalueprivate.h index 3683e11091..695d863f44 100644 --- a/gtk/gtkcssshadowvalueprivate.h +++ b/gtk/gtkcssshadowvalueprivate.h @@ -42,12 +42,14 @@ void _gtk_css_shadow_value_paint_layout (const GtkCssValue PangoLayout *layout); void _gtk_css_shadow_value_paint_icon (const GtkCssValue *shadow, - cairo_t *cr); + cairo_t *cr, + cairo_rectangle_t *rect); void _gtk_css_shadow_value_paint_spinner (const GtkCssValue *shadow, cairo_t *cr, gdouble radius, gdouble progress); + void _gtk_css_shadow_value_paint_box (const GtkCssValue *shadow, cairo_t *cr, const GtkRoundedBox *padding_box); diff --git a/gtk/gtkthemingengine.c b/gtk/gtkthemingengine.c index a085dc421e..9de5254f8d 100644 --- a/gtk/gtkthemingengine.c +++ b/gtk/gtkthemingengine.c @@ -178,7 +178,7 @@ static GdkPixbuf * gtk_theming_engine_render_icon_pixbuf (GtkThemingEngine *e GtkIconSize size); static void gtk_theming_engine_render_icon (GtkThemingEngine *engine, cairo_t *cr, - GdkPixbuf *pixbuf, + GdkPixbuf *pixbuf, gdouble x, gdouble y); @@ -2928,15 +2928,22 @@ gtk_theming_engine_render_icon_pixbuf (GtkThemingEngine *engine, static void gtk_theming_engine_render_icon (GtkThemingEngine *engine, cairo_t *cr, - GdkPixbuf *pixbuf, + GdkPixbuf *pixbuf, gdouble x, gdouble y) { + cairo_rectangle_t rect; + cairo_save (cr); gdk_cairo_set_source_pixbuf (cr, pixbuf, x, y); - _gtk_css_shadows_value_paint_icon (_gtk_theming_engine_peek_property (engine, GTK_CSS_PROPERTY_ICON_SHADOW), cr); + rect.x = x; + rect.y = y; + rect.width = gdk_pixbuf_get_width (pixbuf); + rect.height = gdk_pixbuf_get_height (pixbuf); + + _gtk_css_shadows_value_paint_icon (_gtk_theming_engine_peek_property (engine, GTK_CSS_PROPERTY_ICON_SHADOW), cr, &rect); cairo_paint (cr); |