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.
This commit is contained in:
Benjamin Otte 2018-02-27 01:55:03 +01:00
parent 3e50092869
commit 3427639b08
4 changed files with 98 additions and 28 deletions

View 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);

View 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,

View 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,

View 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;
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;
}
}