[gtk+/wip/window-scales: 81/84] GtkIconHelper: Add support for cairo_pattern_t



commit 428e94ceefa46fda34937b730d1a59f229abd50c
Author: Alexander Larsson <alexl redhat com>
Date:   Wed Jun 26 16:33:15 2013 +0200

    GtkIconHelper: Add support for cairo_pattern_t

 gtk/gtkiconhelper.c |  116 +++++++++++++++++++++++++++++++++++++++++++++++++-
 gtk/gtkimage.h      |    5 ++-
 2 files changed, 117 insertions(+), 4 deletions(-)
---
diff --git a/gtk/gtkiconhelper.c b/gtk/gtkiconhelper.c
index 40ab0a5..ad07621 100644
--- a/gtk/gtkiconhelper.c
+++ b/gtk/gtkiconhelper.c
@@ -36,6 +36,7 @@ struct _GtkIconHelperPrivate {
   GtkIconSet *icon_set;
   gchar *icon_name;
   gchar *stock_id;
+  cairo_pattern_t *orig_pattern;
 
   GtkIconSize icon_size;
   gint pixel_size;
@@ -62,6 +63,12 @@ _gtk_icon_helper_clear (GtkIconHelper *self)
   g_clear_object (&self->priv->rendered_pixbuf);
   g_clear_object (&self->priv->window);
 
+  if (self->priv->orig_pattern)
+    {
+      cairo_pattern_destroy (self->priv->orig_pattern);
+      self->priv->orig_pattern = NULL;
+    }
+
   if (self->priv->rendered_pattern)
     {
       cairo_pattern_destroy (self->priv->rendered_pattern);
@@ -134,6 +141,7 @@ _gtk_icon_helper_init (GtkIconHelper *self)
   self->priv->icon_size = GTK_ICON_SIZE_INVALID;
   self->priv->pixel_size = -1;
   self->priv->last_rendered_state = GTK_STATE_FLAG_NORMAL;
+  self->priv->orig_pixbuf_scale = 1;
 }
 
 static void
@@ -314,6 +322,63 @@ ensure_pixbuf_for_icon_set (GtkIconHelper *self,
 }
 
 static void
+get_pattern_size (GtkIconHelper   *self,
+                 GtkStyleContext *context,
+                 cairo_pattern_t *pattern,
+                 int *width,
+                 int *height)
+{
+  cairo_surface_t *surface;
+
+  if(!cairo_pattern_get_surface (self->priv->rendered_pattern,
+                                &surface) &&
+     cairo_surface_get_type (surface) == CAIRO_SURFACE_TYPE_IMAGE)
+    {
+      cairo_matrix_t matrix;
+
+      /* Assume any set scaling is icon scale */
+      cairo_pattern_get_matrix (self->priv->rendered_pattern, &matrix);
+      *width =
+       ceil (cairo_image_surface_get_width (surface) / matrix.xx);
+      *height =
+       ceil (cairo_image_surface_get_height (surface) / matrix.yy);
+    }
+  else
+    ensure_icon_size (self, context, width, height);
+}
+
+static void
+ensure_pixbuf_from_pattern (GtkIconHelper   *self,
+                           GtkStyleContext *context)
+{
+  cairo_surface_t *surface;
+  gint width, height;
+  cairo_t *cr;
+
+
+  if (!check_invalidate_pixbuf (self, context))
+    return;
+
+  if (self->priv->rendered_pixbuf)
+    return;
+
+  get_pattern_size (self, context, self->priv->orig_pattern, &width, &height);
+
+  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+                                       width, height);
+
+  cr = cairo_create (surface);
+  cairo_set_source (cr, self->priv->orig_pattern);
+  cairo_paint (cr);
+  cairo_destroy (cr);
+
+  self->priv->rendered_pixbuf =
+    gdk_pixbuf_get_from_surface (surface, 0, 0, width, height);
+
+  cairo_surface_destroy (surface);
+}
+
+static void
 ensure_pixbuf_at_size (GtkIconHelper   *self,
                        GtkStyleContext *context)
 {
@@ -368,6 +433,10 @@ _gtk_icon_helper_ensure_pixbuf (GtkIconHelper *self,
 
   switch (self->priv->storage_type)
     {
+    case GTK_IMAGE_PATTERN:
+      ensure_pixbuf_from_pattern (self, context);
+      break;
+
     case GTK_IMAGE_PIXBUF:
       ensure_pixbuf_at_size (self, context);
       break;
@@ -447,8 +516,26 @@ check_invalidate_pattern (GtkIconHelper *self,
 }
 
 static void
-ensure_pattern_at_size (GtkIconHelper   *self,
-                       GtkStyleContext *context)
+ensure_pattern_from_pattern (GtkIconHelper   *self,
+                            GtkStyleContext *context)
+{
+  if (!check_invalidate_pattern (self, context))
+    return;
+
+  if (self->priv->rendered_pattern)
+    return;
+
+  self->priv->rendered_pattern =
+    cairo_pattern_reference (self->priv->orig_pattern);
+
+  get_pattern_size (self, context, self->priv->orig_pattern,
+                   &self->priv->rendered_pattern_width,
+                   &self->priv->rendered_pattern_height);
+}
+
+static void
+ensure_pattern_from_pixbuf (GtkIconHelper   *self,
+                           GtkStyleContext *context)
 {
   gint width, height;
   GdkPixbuf *pixbuf;
@@ -656,8 +743,12 @@ _gtk_icon_helper_ensure_pattern (GtkIconHelper *self,
 
   switch (self->priv->storage_type)
     {
+    case GTK_IMAGE_PATTERN:
+      ensure_pattern_from_pattern (self, context);
+      break;
+
     case GTK_IMAGE_PIXBUF:
-      ensure_pattern_at_size (self, context);
+      ensure_pattern_from_pixbuf (self, context);
       break;
 
     case GTK_IMAGE_STOCK:
@@ -799,6 +890,19 @@ _gtk_icon_helper_set_animation (GtkIconHelper *self,
 }
 
 void 
+_gtk_icon_helper_set_pattern (GtkIconHelper *self,
+                             cairo_pattern_t *pattern)
+{
+  _gtk_icon_helper_clear (self);
+
+  if (pattern != NULL)
+    {
+      self->priv->storage_type = GTK_IMAGE_PATTERN;
+      self->priv->orig_pattern = cairo_pattern_reference (pattern);
+    }
+}
+
+void 
 _gtk_icon_helper_set_stock_id (GtkIconHelper *self,
                                const gchar *stock_id,
                                GtkIconSize icon_size)
@@ -895,6 +999,12 @@ _gtk_icon_helper_peek_icon_set (GtkIconHelper *self)
   return self->priv->icon_set;
 }
 
+cairo_pattern_t *
+_gtk_icon_helper_peek_pattern (GtkIconHelper *self)
+{
+  return self->priv->orig_pattern;
+}
+
 const gchar *
 _gtk_icon_helper_get_stock_id (GtkIconHelper *self)
 {
diff --git a/gtk/gtkimage.h b/gtk/gtkimage.h
index 4174f5a..66d586e 100644
--- a/gtk/gtkimage.h
+++ b/gtk/gtkimage.h
@@ -60,6 +60,8 @@ typedef struct _GtkImageClass         GtkImageClass;
  *  This image type was added in GTK+ 2.6
  * @GTK_IMAGE_GICON: the widget contains a #GIcon.
  *  This image type was added in GTK+ 2.14
+ * @GTK_IMAGE_PATTERN: the widget contains a #cairo_pattern_t.
+ *  This image type was added in GTK+ 3.10
  *
  * Describes the image data representation used by a #GtkImage. If you
  * want to get the image from the widget, you can only get the
@@ -77,7 +79,8 @@ typedef enum
   GTK_IMAGE_ICON_SET,
   GTK_IMAGE_ANIMATION,
   GTK_IMAGE_ICON_NAME,
-  GTK_IMAGE_GICON
+  GTK_IMAGE_GICON,
+  GTK_IMAGE_PATTERN
 } GtkImageType;
 
 /**


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