iconhelper: Rework to allow resizing of paintables
authorBenjamin Otte <otte@redhat.com>
Tue, 27 Feb 2018 00:55:03 +0000 (01:55 +0100)
committerBenjamin Otte <otte@redhat.com>
Fri, 16 Mar 2018 05:04:44 +0000 (06:04 +0100)
GtkImage will now allow paintables to be rendered to the full image and
the image will be sized according to CSS rules for image sizing.

gtk/gtkcellrendererpixbuf.c
gtk/gtkiconhelper.c
gtk/gtkiconhelperprivate.h
gtk/gtkimage.c

index cd042c9a7036a6b1e99aee8b18b2bca235664703..731ebc51c50c84a742e52a154b348bf1477cedab 100644 (file)
@@ -582,7 +582,7 @@ gtk_cell_renderer_pixbuf_snapshot (GtkCellRenderer      *cell,
     }
 
   gtk_snapshot_offset (snapshot, pix_rect.x, pix_rect.y);
-  gtk_icon_helper_snapshot (&icon_helper, snapshot);
+  gtk_icon_helper_snapshot (&icon_helper, snapshot, pix_rect.width, pix_rect.height);
   gtk_snapshot_offset (snapshot, - pix_rect.x, - pix_rect.y);
 
   gtk_icon_helper_destroy (&icon_helper);
index ab880d9be3c8f9988d55e80d40734ef91f8d71a4..bb9a62e7e521486f616fcfd66b58c06460195f1c 100644 (file)
@@ -385,6 +385,67 @@ gtk_icon_helper_ensure_paintable (GtkIconHelper *self)
   self->texture_is_symbolic = symbolic;
 }
 
+void
+gtk_icon_helper_measure (GtkIconHelper *self,
+                         GtkOrientation orientation,
+                         int            for_size,
+                         int           *minimum,
+                         int           *natural)
+{
+  switch (gtk_image_definition_get_storage_type (self->def))
+    {
+    case GTK_IMAGE_PAINTABLE:
+      {
+        double min_width, min_height, nat_width, nat_height;
+        int default_size = get_default_size (self);
+
+        gdk_paintable_compute_concrete_size (gtk_image_definition_get_paintable (self->def),
+                                             0, 0,
+                                             default_size, default_size,
+                                             &min_width, &min_height);
+
+        if (orientation == GTK_ORIENTATION_HORIZONTAL)
+          {
+            gdk_paintable_compute_concrete_size (gtk_image_definition_get_paintable (self->def),
+                                                 0,
+                                                 for_size < 0 ? 0 : for_size,
+                                                 default_size, default_size,
+                                                 &nat_width, &nat_height);
+            *minimum = ceil (min_width);
+            *natural = ceil (nat_width);
+          }
+        else
+          {
+            gdk_paintable_compute_concrete_size (gtk_image_definition_get_paintable (self->def),
+                                                 for_size < 0 ? 0 : for_size,
+                                                 0,
+                                                 default_size, default_size,
+                                                 &nat_width, &nat_height);
+            *minimum = ceil (min_height);
+            *natural = ceil (nat_height);
+          }
+      }
+      break;
+
+    case GTK_IMAGE_TEXTURE:
+    case GTK_IMAGE_SURFACE:
+    case GTK_IMAGE_ICON_NAME:
+    case GTK_IMAGE_GICON:
+    case GTK_IMAGE_EMPTY:
+    default:
+      {
+        int width, height;
+
+        _gtk_icon_helper_get_size (self, &width, &height);
+        if (orientation == GTK_ORIENTATION_HORIZONTAL)
+          *minimum = *natural = width;
+        else
+          *minimum = *natural = height;
+      }
+      break;
+    }
+}
+
 static void
 get_size_for_paintable (GtkIconHelper *self,
                         GdkPaintable  *paintable,
@@ -617,10 +678,11 @@ _gtk_icon_helper_get_icon_name (GtkIconHelper *self)
 
 void
 gtk_icon_helper_snapshot (GtkIconHelper *self,
-                          GtkSnapshot   *snapshot)
+                          GtkSnapshot   *snapshot,
+                          double         width,
+                          double         height)
 {
   GtkCssStyle *style;
-  gint width, height;
 
   style = gtk_css_node_get_style (self->node);
 
@@ -628,8 +690,6 @@ gtk_icon_helper_snapshot (GtkIconHelper *self,
   if (self->paintable == NULL)
     return;
 
-  _gtk_icon_helper_get_size (self, &width, &height);
-
   gtk_css_style_snapshot_icon_paintable (style,
                                          snapshot,
                                          self->paintable,
index 6fd794b70ba29a317a50d29dc447aa2aff7602e2..ce260b3f68745e72d7d3bc7a07c7bb76b289a825 100644 (file)
@@ -89,12 +89,19 @@ GdkPaintable *_gtk_icon_helper_peek_paintable (GtkIconHelper *self);
 GtkImageDefinition *gtk_icon_helper_get_definition (GtkIconHelper *self);
 const gchar *_gtk_icon_helper_get_icon_name (GtkIconHelper *self);
 
+void gtk_icon_helper_measure (GtkIconHelper *self,
+                              GtkOrientation orientation,
+                              int            for_size,
+                              int           *minimum,
+                              int           *natural);
 void _gtk_icon_helper_get_size (GtkIconHelper *self,
                                 gint *width_out,
                                 gint *height_out);
 
 void gtk_icon_helper_snapshot (GtkIconHelper *self,
-                               GtkSnapshot *snapshot);
+                               GtkSnapshot *snapshot,
+                               double       width,
+                               double       height);
 
 gboolean _gtk_icon_helper_get_force_scale_pixbuf (GtkIconHelper *self);
 void     _gtk_icon_helper_set_force_scale_pixbuf (GtkIconHelper *self,
index 7deb8b70d3a84f5db8b2cbd9432b5043cf2148cb..970ab758ae9fb853eefa9cf0b5e21a6d68a73569 100644 (file)
@@ -1293,21 +1293,27 @@ gtk_image_snapshot (GtkWidget   *widget,
 
   width = gtk_widget_get_width (widget);
   height = gtk_widget_get_height (widget);
-  y = 0;
 
-  _gtk_icon_helper_get_size (&priv->icon_helper, &w, &h);
-  x = (width - w) / 2;
+  if (_gtk_icon_helper_get_storage_type (&priv->icon_helper) == GTK_IMAGE_PAINTABLE)
+    {
+      gtk_icon_helper_snapshot (&priv->icon_helper, snapshot, width, height);
+    }
+  else
+    {
+      _gtk_icon_helper_get_size (&priv->icon_helper, &w, &h);
+      x = (width - w) / 2;
 
-  baseline = gtk_widget_get_allocated_baseline (widget);
+      baseline = gtk_widget_get_allocated_baseline (widget);
 
-  if (baseline == -1)
-    y += floor(height - h) / 2;
-  else
-    y += CLAMP (baseline - h * gtk_image_get_baseline_align (image), 0, height - h);
+      if (baseline == -1)
+        y = floor(height - h) / 2;
+      else
+        y = CLAMP (baseline - h * gtk_image_get_baseline_align (image), 0, height - h);
 
-  gtk_snapshot_offset (snapshot, x, y);
-  gtk_icon_helper_snapshot (&priv->icon_helper, snapshot);
-  gtk_snapshot_offset (snapshot, -x, -y);
+      gtk_snapshot_offset (snapshot, x, y);
+      gtk_icon_helper_snapshot (&priv->icon_helper, snapshot, w, h);
+      gtk_snapshot_offset (snapshot, -x, -y);
+    }
 }
 
 static void
@@ -1429,23 +1435,20 @@ gtk_image_measure (GtkWidget      *widget,
                    int           *natural_baseline)
 {
   GtkImagePrivate *priv = gtk_image_get_instance_private (GTK_IMAGE (widget));
-  gint width, height;
   float baseline_align;
 
-  _gtk_icon_helper_get_size (&priv->icon_helper, &width, &height);
+  gtk_icon_helper_measure (&priv->icon_helper,
+                           orientation,
+                           for_size,
+                           minimum, natural);
 
-  if (orientation == GTK_ORIENTATION_HORIZONTAL)
-    {
-      *minimum = *natural = width;
-    }
-  else
+  if (orientation == GTK_ORIENTATION_VERTICAL)
     {
       baseline_align = gtk_image_get_baseline_align (GTK_IMAGE (widget));
-      *minimum = *natural = height;
       if (minimum_baseline)
-        *minimum_baseline = height * baseline_align;
+        *minimum_baseline = *minimum * baseline_align;
       if (natural_baseline)
-        *natural_baseline = height * baseline_align;
+        *natural_baseline = *natural * baseline_align;
     }
 }