summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2015-01-20 05:54:45 +0100
committerBenjamin Otte <otte@redhat.com>2015-01-20 06:30:20 +0100
commitf7433557abd63c8e6d03ba31c14f004a0d62c173 (patch)
treec384a480cb30bac93da604b0cba9fd473176f0f4
parent8c745088d5376ba399985dad98d82311218ca548 (diff)
downloadgtk+-f7433557abd63c8e6d03ba31c14f004a0d62c173.tar.gz
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.
-rw-r--r--gtk/gtkrendericon.c54
1 files changed, 51 insertions, 3 deletions
diff --git a/gtk/gtkrendericon.c b/gtk/gtkrendericon.c
index 3d3fbb754a..a6aecbcb45 100644
--- a/gtk/gtkrendericon.c
+++ b/gtk/gtkrendericon.c
@@ -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);
+
+ 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_translate (cr, x + extents.x, y + extents.y);
- _gtk_css_shadows_value_paint_icon (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_ICON_SHADOW), cr);
+ if (_gtk_css_transform_value_get_matrix (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_ICON_TRANSFORM), &transform_matrix))
+ {
+ cairo_pattern_t *pattern;
- cairo_paint (cr);
+ /* 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);
+ }
}