shadow: add code to render blurred shadows

Split out the blurred shadow rendering in three steps:
- creation of a surface of the appropriate size - we use the clip
  rectangle as a good measurement for the size, since we won't render
  out of it anyway
- painting the unblurred shape on the surface - this is responsibility
  of the single shadow implementations
- blur the surface and compose the result back on the original cairo_t

This means we can share code between the implementations for the first
and third steps; it also makes the code independent of the rendered
size, so we can avoid passing down a cairo_rectangle_t with e.g. the
icon coordinates.
This commit is contained in:
Cosimo Cecchi
2012-04-17 15:43:58 -04:00
parent d22ed08164
commit f02ca4c034

View File

@@ -21,6 +21,7 @@
#include "gtkcssshadowvalueprivate.h"
#include "gtkcairoblurprivate.h"
#include "gtkcssnumbervalueprivate.h"
#include "gtkcssrgbavalueprivate.h"
#include "gtkstylecontextprivate.h"
@@ -289,6 +290,47 @@ _gtk_css_shadow_value_compute (GtkCssValue *shadow,
color);
}
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)
{
cairo_rectangle_int_t clip_rect;
gdouble radius;
gdk_cairo_get_clip_rectangle (original_cr, &clip_rect);
radius = _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);
*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)
{
gdouble x, y;
gdouble radius;
radius = _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);
cairo_paint (cr);
}
void
_gtk_css_shadow_value_paint_layout (const GtkCssValue *shadow,
cairo_t *cr,