From 3427639b08a0af92ffe4705bb938581adc4e9b27 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Tue, 27 Feb 2018 01:55:03 +0100 Subject: [PATCH] iconhelper: Rework to allow resizing of paintables 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 | 2 +- gtk/gtkiconhelper.c | 68 ++++++++++++++++++++++++++++++++++--- gtk/gtkiconhelperprivate.h | 9 ++++- gtk/gtkimage.c | 47 +++++++++++++------------ 4 files changed, 98 insertions(+), 28 deletions(-) diff --git a/gtk/gtkcellrendererpixbuf.c b/gtk/gtkcellrendererpixbuf.c index cd042c9a70..731ebc51c5 100644 --- a/gtk/gtkcellrendererpixbuf.c +++ b/gtk/gtkcellrendererpixbuf.c @@ -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); diff --git a/gtk/gtkiconhelper.c b/gtk/gtkiconhelper.c index ab880d9be3..bb9a62e7e5 100644 --- a/gtk/gtkiconhelper.c +++ b/gtk/gtkiconhelper.c @@ -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, diff --git a/gtk/gtkiconhelperprivate.h b/gtk/gtkiconhelperprivate.h index 6fd794b70b..ce260b3f68 100644 --- a/gtk/gtkiconhelperprivate.h +++ b/gtk/gtkiconhelperprivate.h @@ -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, diff --git a/gtk/gtkimage.c b/gtk/gtkimage.c index 7deb8b70d3..970ab758ae 100644 --- a/gtk/gtkimage.c +++ b/gtk/gtkimage.c @@ -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; - - baseline = gtk_widget_get_allocated_baseline (widget); - - if (baseline == -1) - y += floor(height - h) / 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 - y += CLAMP (baseline - h * gtk_image_get_baseline_align (image), 0, height - h); + { + _gtk_icon_helper_get_size (&priv->icon_helper, &w, &h); + x = (width - w) / 2; - gtk_snapshot_offset (snapshot, x, y); - gtk_icon_helper_snapshot (&priv->icon_helper, snapshot); - gtk_snapshot_offset (snapshot, -x, -y); + 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); + + 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; } }