[gtk+] render: Implement -gtk-icon-transform for icon surfaces



commit f7433557abd63c8e6d03ba31c14f004a0d62c173
Author: Benjamin Otte <otte redhat com>
Date:   Tue Jan 20 05:54:45 2015 +0100

    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.

 gtk/gtkrendericon.c |   54 ++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 51 insertions(+), 3 deletions(-)
---
diff --git a/gtk/gtkrendericon.c b/gtk/gtkrendericon.c
index 3d3fbb7..a6aecbc 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);
+    }
 }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]