Compare commits
8 Commits
shader-cac
...
wip/blur
Author | SHA1 | Date | |
---|---|---|---|
|
b40f90f47b | ||
|
654553cc70 | ||
|
058cf8c5dc | ||
|
5490f30ba3 | ||
|
5b730ea96e | ||
|
f02ca4c034 | ||
|
d22ed08164 | ||
|
82c6af9884 |
@@ -415,6 +415,7 @@ gtk_private_h_sources = \
|
|||||||
gtkboxprivate.h \
|
gtkboxprivate.h \
|
||||||
gtkbuilderprivate.h \
|
gtkbuilderprivate.h \
|
||||||
gtkbuttonprivate.h \
|
gtkbuttonprivate.h \
|
||||||
|
gtkcairoblurprivate.h \
|
||||||
gtkcellareaboxcontextprivate.h \
|
gtkcellareaboxcontextprivate.h \
|
||||||
gtkcolorswatchprivate.h \
|
gtkcolorswatchprivate.h \
|
||||||
gtkcoloreditorprivate.h \
|
gtkcoloreditorprivate.h \
|
||||||
@@ -607,6 +608,7 @@ gtk_base_c_sources = \
|
|||||||
gtkbuilderparser.c \
|
gtkbuilderparser.c \
|
||||||
gtkbuilder-menus.c \
|
gtkbuilder-menus.c \
|
||||||
gtkbutton.c \
|
gtkbutton.c \
|
||||||
|
gtkcairoblur.c \
|
||||||
gtkcalendar.c \
|
gtkcalendar.c \
|
||||||
gtkcellarea.c \
|
gtkcellarea.c \
|
||||||
gtkcellareabox.c \
|
gtkcellareabox.c \
|
||||||
|
267
gtk/gtkcairoblur.c
Normal file
267
gtk/gtkcairoblur.c
Normal file
@@ -0,0 +1,267 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2012 Canonical Ltd
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free
|
||||||
|
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* Authored by Andrea Cimitan <andrea.cimitan@canonical.com>
|
||||||
|
* Original code from Mirco Mueller <mirco.mueller@canonical.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gtkcairoblurprivate.h"
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Notes:
|
||||||
|
* based on exponential-blur algorithm by Jani Huhtanen
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
_blurinner (guchar* pixel,
|
||||||
|
gint *zR,
|
||||||
|
gint *zG,
|
||||||
|
gint *zB,
|
||||||
|
gint *zA,
|
||||||
|
gint alpha,
|
||||||
|
gint aprec,
|
||||||
|
gint zprec)
|
||||||
|
{
|
||||||
|
gint R;
|
||||||
|
gint G;
|
||||||
|
gint B;
|
||||||
|
guchar A;
|
||||||
|
|
||||||
|
R = *pixel;
|
||||||
|
G = *(pixel + 1);
|
||||||
|
B = *(pixel + 2);
|
||||||
|
A = *(pixel + 3);
|
||||||
|
|
||||||
|
*zR += (alpha * ((R << zprec) - *zR)) >> aprec;
|
||||||
|
*zG += (alpha * ((G << zprec) - *zG)) >> aprec;
|
||||||
|
*zB += (alpha * ((B << zprec) - *zB)) >> aprec;
|
||||||
|
*zA += (alpha * ((A << zprec) - *zA)) >> aprec;
|
||||||
|
|
||||||
|
*pixel = *zR >> zprec;
|
||||||
|
*(pixel + 1) = *zG >> zprec;
|
||||||
|
*(pixel + 2) = *zB >> zprec;
|
||||||
|
*(pixel + 3) = *zA >> zprec;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
_blurrow (guchar* pixels,
|
||||||
|
gint width,
|
||||||
|
gint height,
|
||||||
|
gint channels,
|
||||||
|
gint line,
|
||||||
|
gint alpha,
|
||||||
|
gint aprec,
|
||||||
|
gint zprec)
|
||||||
|
{
|
||||||
|
gint zR;
|
||||||
|
gint zG;
|
||||||
|
gint zB;
|
||||||
|
gint zA;
|
||||||
|
gint index;
|
||||||
|
guchar* scanline;
|
||||||
|
|
||||||
|
scanline = &(pixels[line * width * channels]);
|
||||||
|
|
||||||
|
zR = *scanline << zprec;
|
||||||
|
zG = *(scanline + 1) << zprec;
|
||||||
|
zB = *(scanline + 2) << zprec;
|
||||||
|
zA = *(scanline + 3) << zprec;
|
||||||
|
|
||||||
|
for (index = 0; index < width; index ++)
|
||||||
|
_blurinner (&scanline[index * channels],
|
||||||
|
&zR,
|
||||||
|
&zG,
|
||||||
|
&zB,
|
||||||
|
&zA,
|
||||||
|
alpha,
|
||||||
|
aprec,
|
||||||
|
zprec);
|
||||||
|
|
||||||
|
for (index = width - 2; index >= 0; index--)
|
||||||
|
_blurinner (&scanline[index * channels],
|
||||||
|
&zR,
|
||||||
|
&zG,
|
||||||
|
&zB,
|
||||||
|
&zA,
|
||||||
|
alpha,
|
||||||
|
aprec,
|
||||||
|
zprec);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
_blurcol (guchar* pixels,
|
||||||
|
gint width,
|
||||||
|
gint height,
|
||||||
|
gint channels,
|
||||||
|
gint x,
|
||||||
|
gint alpha,
|
||||||
|
gint aprec,
|
||||||
|
gint zprec)
|
||||||
|
{
|
||||||
|
gint zR;
|
||||||
|
gint zG;
|
||||||
|
gint zB;
|
||||||
|
gint zA;
|
||||||
|
gint index;
|
||||||
|
guchar* ptr;
|
||||||
|
|
||||||
|
ptr = pixels;
|
||||||
|
|
||||||
|
ptr += x * channels;
|
||||||
|
|
||||||
|
zR = *((guchar*) ptr ) << zprec;
|
||||||
|
zG = *((guchar*) ptr + 1) << zprec;
|
||||||
|
zB = *((guchar*) ptr + 2) << zprec;
|
||||||
|
zA = *((guchar*) ptr + 3) << zprec;
|
||||||
|
|
||||||
|
for (index = width; index < (height - 1) * width; index += width)
|
||||||
|
_blurinner ((guchar*) &ptr[index * channels],
|
||||||
|
&zR,
|
||||||
|
&zG,
|
||||||
|
&zB,
|
||||||
|
&zA,
|
||||||
|
alpha,
|
||||||
|
aprec,
|
||||||
|
zprec);
|
||||||
|
|
||||||
|
for (index = (height - 2) * width; index >= 0; index -= width)
|
||||||
|
_blurinner ((guchar*) &ptr[index * channels],
|
||||||
|
&zR,
|
||||||
|
&zG,
|
||||||
|
&zB,
|
||||||
|
&zA,
|
||||||
|
alpha,
|
||||||
|
aprec,
|
||||||
|
zprec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* _expblur:
|
||||||
|
* @pixels: image data
|
||||||
|
* @width: image width
|
||||||
|
* @height: image height
|
||||||
|
* @channels: image channels
|
||||||
|
* @radius: kernel radius
|
||||||
|
* @aprec: precision of alpha parameter in fixed-point format 0.aprec
|
||||||
|
* @zprec: precision of state parameters zR,zG,zB and zA in fp format 8.zprec
|
||||||
|
*
|
||||||
|
* Performs an in-place blur of image data 'pixels'
|
||||||
|
* with kernel of approximate radius 'radius'.
|
||||||
|
*
|
||||||
|
* Blurs with two sided exponential impulse response.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
_expblur (guchar* pixels,
|
||||||
|
gint width,
|
||||||
|
gint height,
|
||||||
|
gint channels,
|
||||||
|
gint radius,
|
||||||
|
gint aprec,
|
||||||
|
gint zprec)
|
||||||
|
{
|
||||||
|
gint alpha;
|
||||||
|
gint row = 0;
|
||||||
|
gint col = 0;
|
||||||
|
|
||||||
|
if (radius < 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Calculate the alpha such that 90% of
|
||||||
|
* the kernel is within the radius.
|
||||||
|
* (Kernel extends to infinity) */
|
||||||
|
alpha = (gint) ((1 << aprec) * (1.0f - expf (-2.3f / (radius + 1.f))));
|
||||||
|
|
||||||
|
for (; row < height; row++)
|
||||||
|
_blurrow (pixels,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
channels,
|
||||||
|
row,
|
||||||
|
alpha,
|
||||||
|
aprec,
|
||||||
|
zprec);
|
||||||
|
|
||||||
|
for(; col < width; col++)
|
||||||
|
_blurcol (pixels,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
channels,
|
||||||
|
col,
|
||||||
|
alpha,
|
||||||
|
aprec,
|
||||||
|
zprec);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* _gtk_cairo_blur_surface:
|
||||||
|
* @surface: a cairo image surface.
|
||||||
|
* @radius: the blur radius.
|
||||||
|
*
|
||||||
|
* Blurs the cairo image surface at the given radius.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
_gtk_cairo_blur_surface (cairo_surface_t* surface,
|
||||||
|
guint radius)
|
||||||
|
{
|
||||||
|
cairo_format_t format;
|
||||||
|
guchar* pixels;
|
||||||
|
guint width;
|
||||||
|
guint height;
|
||||||
|
|
||||||
|
g_return_if_fail (surface != NULL);
|
||||||
|
g_return_if_fail (cairo_surface_get_type (surface) == CAIRO_SURFACE_TYPE_IMAGE);
|
||||||
|
|
||||||
|
format = cairo_image_surface_get_format (surface);
|
||||||
|
g_return_if_fail (format == CAIRO_FORMAT_A8 ||
|
||||||
|
format == CAIRO_FORMAT_RGB24 ||
|
||||||
|
format == CAIRO_FORMAT_ARGB32);
|
||||||
|
|
||||||
|
if (radius == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Before we mess with the surface execute any pending drawing. */
|
||||||
|
cairo_surface_flush (surface);
|
||||||
|
|
||||||
|
pixels = cairo_image_surface_get_data (surface);
|
||||||
|
width = cairo_image_surface_get_width (surface);
|
||||||
|
height = cairo_image_surface_get_height (surface);
|
||||||
|
format = cairo_image_surface_get_format (surface);
|
||||||
|
|
||||||
|
switch (format)
|
||||||
|
{
|
||||||
|
case CAIRO_FORMAT_ARGB32:
|
||||||
|
_expblur (pixels, width, height, 4, radius, 16, 7);
|
||||||
|
break;
|
||||||
|
case CAIRO_FORMAT_RGB24:
|
||||||
|
_expblur (pixels, width, height, 3, radius, 16, 7);
|
||||||
|
break;
|
||||||
|
case CAIRO_FORMAT_A8:
|
||||||
|
_expblur (pixels, width, height, 1, radius, 16, 7);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Inform cairo we altered the surfaces contents. */
|
||||||
|
cairo_surface_mark_dirty (surface);
|
||||||
|
}
|
37
gtk/gtkcairoblurprivate.h
Normal file
37
gtk/gtkcairoblurprivate.h
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2012 Canonical Ltd
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free
|
||||||
|
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* Authored by Andrea Cimitan <andrea.cimitan@canonical.com>
|
||||||
|
* Original code from Mirco Mueller <mirco.mueller@canonical.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _GTK_CAIRO_BLUR_H
|
||||||
|
#define _GTK_CAIRO_BLUR_H
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
#include <cairo.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
void _gtk_cairo_blur_surface (cairo_surface_t* surface,
|
||||||
|
guint radius);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* _GTK_CAIRO_BLUR_H */
|
@@ -228,7 +228,8 @@ _gtk_css_shadows_value_paint_layout (const GtkCssValue *shadows,
|
|||||||
|
|
||||||
void
|
void
|
||||||
_gtk_css_shadows_value_paint_icon (const GtkCssValue *shadows,
|
_gtk_css_shadows_value_paint_icon (const GtkCssValue *shadows,
|
||||||
cairo_t *cr)
|
cairo_t *cr,
|
||||||
|
cairo_rectangle_t *rect)
|
||||||
{
|
{
|
||||||
guint i;
|
guint i;
|
||||||
|
|
||||||
@@ -236,7 +237,7 @@ _gtk_css_shadows_value_paint_icon (const GtkCssValue *shadows,
|
|||||||
|
|
||||||
for (i = 0; i < shadows->len; i++)
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -41,12 +41,14 @@ void _gtk_css_shadows_value_paint_layout (const GtkCssValue
|
|||||||
PangoLayout *layout);
|
PangoLayout *layout);
|
||||||
|
|
||||||
void _gtk_css_shadows_value_paint_icon (const GtkCssValue *shadows,
|
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,
|
void _gtk_css_shadows_value_paint_spinner (const GtkCssValue *shadows,
|
||||||
cairo_t *cr,
|
cairo_t *cr,
|
||||||
gdouble radius,
|
gdouble radius,
|
||||||
gdouble progress);
|
gdouble progress);
|
||||||
|
|
||||||
void _gtk_css_shadows_value_paint_box (const GtkCssValue *shadows,
|
void _gtk_css_shadows_value_paint_box (const GtkCssValue *shadows,
|
||||||
cairo_t *cr,
|
cairo_t *cr,
|
||||||
const GtkRoundedBox *padding_box);
|
const GtkRoundedBox *padding_box);
|
||||||
|
@@ -18,9 +18,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "math.h"
|
||||||
|
|
||||||
#include "gtkcssshadowvalueprivate.h"
|
#include "gtkcssshadowvalueprivate.h"
|
||||||
|
|
||||||
|
#include "gtkcairoblurprivate.h"
|
||||||
#include "gtkcssnumbervalueprivate.h"
|
#include "gtkcssnumbervalueprivate.h"
|
||||||
#include "gtkcssrgbavalueprivate.h"
|
#include "gtkcssrgbavalueprivate.h"
|
||||||
#include "gtkstylecontextprivate.h"
|
#include "gtkstylecontextprivate.h"
|
||||||
@@ -289,6 +291,45 @@ _gtk_css_shadow_value_compute (GtkCssValue *shadow,
|
|||||||
color);
|
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 *rect_surface)
|
||||||
|
{
|
||||||
|
gint radius;
|
||||||
|
|
||||||
|
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,
|
||||||
|
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,
|
||||||
|
cairo_rectangle_int_t *rect_surface)
|
||||||
|
{
|
||||||
|
gint radius;
|
||||||
|
|
||||||
|
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_set_source_surface (cr, surface,
|
||||||
|
rect_surface->x - radius,
|
||||||
|
rect_surface->y - radius);
|
||||||
|
cairo_paint (cr);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_gtk_css_shadow_value_paint_layout (const GtkCssValue *shadow,
|
_gtk_css_shadow_value_paint_layout (const GtkCssValue *shadow,
|
||||||
cairo_t *cr,
|
cairo_t *cr,
|
||||||
@@ -304,8 +345,47 @@ _gtk_css_shadow_value_paint_layout (const GtkCssValue *shadow,
|
|||||||
cairo_rel_move_to (cr,
|
cairo_rel_move_to (cr,
|
||||||
_gtk_css_number_value_get (shadow->hoffset, 0),
|
_gtk_css_number_value_get (shadow->hoffset, 0),
|
||||||
_gtk_css_number_value_get (shadow->voffset, 0));
|
_gtk_css_number_value_get (shadow->voffset, 0));
|
||||||
|
|
||||||
|
if (_gtk_css_number_value_get (shadow->radius, 0) > 0)
|
||||||
|
{
|
||||||
|
PangoRectangle ink_rect;
|
||||||
|
cairo_t *blur_cr;
|
||||||
|
cairo_surface_t *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, &rect_surface);
|
||||||
|
|
||||||
|
cairo_destroy (blur_cr);
|
||||||
|
cairo_surface_destroy (surface);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
gdk_cairo_set_source_rgba (cr, _gtk_css_rgba_value_get_rgba (shadow->color));
|
gdk_cairo_set_source_rgba (cr, _gtk_css_rgba_value_get_rgba (shadow->color));
|
||||||
_gtk_pango_fill_layout (cr, layout);
|
_gtk_pango_fill_layout (cr, layout);
|
||||||
|
}
|
||||||
|
|
||||||
cairo_rel_move_to (cr,
|
cairo_rel_move_to (cr,
|
||||||
- _gtk_css_number_value_get (shadow->hoffset, 0),
|
- _gtk_css_number_value_get (shadow->hoffset, 0),
|
||||||
@@ -315,7 +395,8 @@ _gtk_css_shadow_value_paint_layout (const GtkCssValue *shadow,
|
|||||||
|
|
||||||
void
|
void
|
||||||
_gtk_css_shadow_value_paint_icon (const GtkCssValue *shadow,
|
_gtk_css_shadow_value_paint_icon (const GtkCssValue *shadow,
|
||||||
cairo_t *cr)
|
cairo_t *cr,
|
||||||
|
cairo_rectangle_t *rect)
|
||||||
{
|
{
|
||||||
cairo_pattern_t *pattern;
|
cairo_pattern_t *pattern;
|
||||||
|
|
||||||
@@ -323,12 +404,41 @@ _gtk_css_shadow_value_paint_icon (const GtkCssValue *shadow,
|
|||||||
|
|
||||||
cairo_save (cr);
|
cairo_save (cr);
|
||||||
pattern = cairo_pattern_reference (cairo_get_source (cr));
|
pattern = cairo_pattern_reference (cairo_get_source (cr));
|
||||||
|
|
||||||
|
if (_gtk_css_number_value_get (shadow->radius, 0) > 0)
|
||||||
|
{
|
||||||
|
cairo_t *blur_cr;
|
||||||
|
cairo_surface_t *surface;
|
||||||
|
cairo_rectangle_int_t rect_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_mask (blur_cr, pattern);
|
||||||
|
|
||||||
|
gtk_css_shadow_value_blur_surface_paint (shadow, cr, surface, &rect_surface);
|
||||||
|
|
||||||
|
cairo_destroy (blur_cr);
|
||||||
|
cairo_surface_destroy (surface);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
gdk_cairo_set_source_rgba (cr, _gtk_css_rgba_value_get_rgba (shadow->color));
|
gdk_cairo_set_source_rgba (cr, _gtk_css_rgba_value_get_rgba (shadow->color));
|
||||||
|
|
||||||
cairo_translate (cr,
|
cairo_translate (cr,
|
||||||
_gtk_css_number_value_get (shadow->hoffset, 0),
|
_gtk_css_number_value_get (shadow->hoffset, 0),
|
||||||
_gtk_css_number_value_get (shadow->voffset, 0));
|
_gtk_css_number_value_get (shadow->voffset, 0));
|
||||||
cairo_mask (cr, pattern);
|
cairo_mask (cr, pattern);
|
||||||
|
}
|
||||||
|
|
||||||
cairo_restore (cr);
|
cairo_restore (cr);
|
||||||
cairo_pattern_destroy (pattern);
|
cairo_pattern_destroy (pattern);
|
||||||
@@ -344,12 +454,41 @@ _gtk_css_shadow_value_paint_spinner (const GtkCssValue *shadow,
|
|||||||
|
|
||||||
cairo_save (cr);
|
cairo_save (cr);
|
||||||
|
|
||||||
|
if (_gtk_css_number_value_get (shadow->radius, 0) > 0)
|
||||||
|
{
|
||||||
|
cairo_t *blur_cr;
|
||||||
|
cairo_surface_t *surface;
|
||||||
|
cairo_rectangle_int_t rect_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. */
|
||||||
|
_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, &rect_surface);
|
||||||
|
|
||||||
|
cairo_destroy (blur_cr);
|
||||||
|
cairo_surface_destroy (surface);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
cairo_translate (cr,
|
cairo_translate (cr,
|
||||||
_gtk_css_number_value_get (shadow->hoffset, 0),
|
_gtk_css_number_value_get (shadow->hoffset, 0),
|
||||||
_gtk_css_number_value_get (shadow->voffset, 0));
|
_gtk_css_number_value_get (shadow->voffset, 0));
|
||||||
_gtk_theming_engine_paint_spinner (cr,
|
_gtk_theming_engine_paint_spinner (cr,
|
||||||
radius, progress,
|
radius, progress,
|
||||||
_gtk_css_rgba_value_get_rgba (shadow->color));
|
_gtk_css_rgba_value_get_rgba (shadow->color));
|
||||||
|
}
|
||||||
|
|
||||||
cairo_restore (cr);
|
cairo_restore (cr);
|
||||||
}
|
}
|
||||||
@@ -377,11 +516,49 @@ _gtk_css_shadow_value_paint_box (const GtkCssValue *shadow,
|
|||||||
spread = _gtk_css_number_value_get (shadow->spread, 0);
|
spread = _gtk_css_number_value_get (shadow->spread, 0);
|
||||||
_gtk_rounded_box_shrink (&box, spread, spread, spread, spread);
|
_gtk_rounded_box_shrink (&box, spread, spread, spread, spread);
|
||||||
|
|
||||||
|
if (_gtk_css_number_value_get (shadow->radius, 0) > 0)
|
||||||
|
{
|
||||||
|
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,
|
||||||
|
&rect_surface);
|
||||||
|
|
||||||
|
/* Create the path on the surface to blur. */
|
||||||
|
_gtk_rounded_box_path (padding_box, blur_cr);
|
||||||
|
cairo_clip (blur_cr);
|
||||||
|
|
||||||
|
_gtk_rounded_box_path (&box, blur_cr);
|
||||||
|
_gtk_rounded_box_clip_path (padding_box, blur_cr);
|
||||||
|
|
||||||
|
cairo_set_fill_rule (blur_cr, CAIRO_FILL_RULE_EVEN_ODD);
|
||||||
|
|
||||||
|
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, &rect_surface);
|
||||||
|
|
||||||
|
cairo_destroy (blur_cr);
|
||||||
|
cairo_surface_destroy (surface);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
_gtk_rounded_box_path (&box, cr);
|
_gtk_rounded_box_path (&box, cr);
|
||||||
_gtk_rounded_box_clip_path (padding_box, cr);
|
_gtk_rounded_box_clip_path (padding_box, cr);
|
||||||
|
|
||||||
gdk_cairo_set_source_rgba (cr, _gtk_css_rgba_value_get_rgba (shadow->color));
|
gdk_cairo_set_source_rgba (cr, _gtk_css_rgba_value_get_rgba (shadow->color));
|
||||||
cairo_fill (cr);
|
cairo_fill (cr);
|
||||||
|
}
|
||||||
|
|
||||||
cairo_restore (cr);
|
cairo_restore (cr);
|
||||||
}
|
}
|
||||||
|
@@ -42,12 +42,14 @@ void _gtk_css_shadow_value_paint_layout (const GtkCssValue
|
|||||||
PangoLayout *layout);
|
PangoLayout *layout);
|
||||||
|
|
||||||
void _gtk_css_shadow_value_paint_icon (const GtkCssValue *shadow,
|
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,
|
void _gtk_css_shadow_value_paint_spinner (const GtkCssValue *shadow,
|
||||||
cairo_t *cr,
|
cairo_t *cr,
|
||||||
gdouble radius,
|
gdouble radius,
|
||||||
gdouble progress);
|
gdouble progress);
|
||||||
|
|
||||||
void _gtk_css_shadow_value_paint_box (const GtkCssValue *shadow,
|
void _gtk_css_shadow_value_paint_box (const GtkCssValue *shadow,
|
||||||
cairo_t *cr,
|
cairo_t *cr,
|
||||||
const GtkRoundedBox *padding_box);
|
const GtkRoundedBox *padding_box);
|
||||||
|
@@ -2700,6 +2700,8 @@ _gtk_theming_engine_paint_spinner (cairo_t *cr,
|
|||||||
|
|
||||||
cairo_save (cr);
|
cairo_save (cr);
|
||||||
|
|
||||||
|
cairo_translate (cr, radius, radius);
|
||||||
|
|
||||||
cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
|
cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
|
||||||
cairo_set_line_width (cr, 2.0);
|
cairo_set_line_width (cr, 2.0);
|
||||||
|
|
||||||
@@ -2756,7 +2758,9 @@ render_spinner (GtkThemingEngine *engine,
|
|||||||
gtk_theming_engine_get_color (engine, state, &color);
|
gtk_theming_engine_get_color (engine, state, &color);
|
||||||
|
|
||||||
cairo_save (cr);
|
cairo_save (cr);
|
||||||
cairo_translate (cr, x + width / 2, y + height / 2);
|
cairo_translate (cr,
|
||||||
|
x + (width - (2 * radius)) / 2,
|
||||||
|
y + (height - (2 * radius)) / 2);
|
||||||
|
|
||||||
_gtk_css_shadows_value_paint_spinner (_gtk_theming_engine_peek_property (engine, GTK_CSS_PROPERTY_ICON_SHADOW),
|
_gtk_css_shadows_value_paint_spinner (_gtk_theming_engine_peek_property (engine, GTK_CSS_PROPERTY_ICON_SHADOW),
|
||||||
cr,
|
cr,
|
||||||
@@ -2928,11 +2932,18 @@ gtk_theming_engine_render_icon (GtkThemingEngine *engine,
|
|||||||
gdouble x,
|
gdouble x,
|
||||||
gdouble y)
|
gdouble y)
|
||||||
{
|
{
|
||||||
|
cairo_rectangle_t rect;
|
||||||
|
|
||||||
cairo_save (cr);
|
cairo_save (cr);
|
||||||
|
|
||||||
gdk_cairo_set_source_pixbuf (cr, pixbuf, x, y);
|
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);
|
cairo_paint (cr);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user