render: Implement -gtk-icon-transform for icon surfaces

Yes, I like playing around. To enjoy, add this CSS to your application
of choice (preferrably glade or something with lots of images):

GtkImage { animation: spin 2s linear infinite; }

You can thank me later.
This commit is contained in:
Benjamin Otte 2015-01-20 05:54:45 +01:00
parent 8c745088d5
commit f7433557ab

View File

@ -74,6 +74,20 @@ gtk_css_style_render_icon (GtkCssStyle *style,
}
}
gboolean
get_surface_extents (cairo_surface_t *surface,
GdkRectangle *out_extents)
{
cairo_t *cr;
gboolean result;
cr = cairo_create (surface);
result = gdk_cairo_get_clip_rectangle (cr, out_extents);
cairo_destroy (cr);
return result;
}
void
gtk_css_style_render_icon_surface (GtkCssStyle *style,
cairo_t *cr,
@ -81,14 +95,48 @@ gtk_css_style_render_icon_surface (GtkCssStyle *style,
double x,
double y)
{
const GtkCssValue *shadows;
cairo_matrix_t matrix, transform_matrix;
GdkRectangle extents;
g_return_if_fail (GTK_IS_CSS_STYLE (style));
g_return_if_fail (cr != NULL);
g_return_if_fail (surface != NULL);
cairo_set_source_surface (cr, surface, x, y);
shadows = gtk_css_style_get_value (style, GTK_CSS_PROPERTY_ICON_SHADOW);
_gtk_css_shadows_value_paint_icon (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_ICON_SHADOW), cr);
if (!get_surface_extents (surface, &extents))
{
/* weird infinite surface, no special magic for you */
cairo_set_source_surface (cr, surface, x, y);
_gtk_css_shadows_value_paint_icon (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_ICON_SHADOW), cr);
cairo_paint (cr);
return;
}
cairo_paint (cr);
cairo_translate (cr, x + extents.x, y + extents.y);
if (_gtk_css_transform_value_get_matrix (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_ICON_TRANSFORM), &transform_matrix))
{
cairo_pattern_t *pattern;
/* XXX: Implement -gtk-icon-transform-origin instead of hardcoding "50% 50%" here */
cairo_matrix_init_translate (&matrix, extents.width / 2, extents.height / 2);
cairo_matrix_multiply (&matrix, &transform_matrix, &matrix);
cairo_matrix_translate (&matrix, - extents.width / 2, - extents.height / 2);
if (cairo_matrix_invert (&matrix) != CAIRO_STATUS_SUCCESS)
{
g_assert_not_reached ();
}
cairo_matrix_translate (&matrix, extents.x, extents.y);
pattern = cairo_pattern_create_for_surface (surface);
cairo_pattern_set_matrix (pattern, &matrix);
cairo_set_source (cr, pattern);
cairo_pattern_destroy (pattern);
_gtk_css_shadows_value_paint_icon (shadows, cr);
cairo_paint (cr);
}
}