mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-10 19:00:08 +00:00
image: Load resources and files into textures
Instead of loading them into surfaces (which we want to get rid of), we load into textures. In fact, we introduce a new paintable subclass called a GtkScaler that takes care of tracking scaling. This also ideally gets rid of an extra conversion once renderers learn to render textures directly.
This commit is contained in:
parent
c9557c207f
commit
7844320f10
@ -555,7 +555,7 @@ add_data_tab (const gchar *demoname)
|
||||
resource_name = g_strconcat (resource_dir, "/", resources[i], NULL);
|
||||
|
||||
widget = gtk_image_new_from_resource (resource_name);
|
||||
if (gtk_image_get_surface (GTK_IMAGE (widget)) == NULL)
|
||||
if (gtk_image_get_texture (GTK_IMAGE (widget)) == NULL)
|
||||
{
|
||||
GBytes *bytes;
|
||||
|
||||
|
@ -381,7 +381,7 @@ gtk_cell_renderer_pixbuf_set_property (GObject *object,
|
||||
take_image_definition (cellpixbuf, gtk_image_definition_new_surface (g_value_get_boxed (value)));
|
||||
break;
|
||||
case PROP_TEXTURE:
|
||||
take_image_definition (cellpixbuf, gtk_image_definition_new_texture (g_value_get_object (value), 1));
|
||||
take_image_definition (cellpixbuf, gtk_image_definition_new_texture (g_value_get_object (value)));
|
||||
break;
|
||||
case PROP_ICON_SIZE:
|
||||
gtk_cell_renderer_pixbuf_set_icon_size (cellpixbuf, g_value_get_enum (value));
|
||||
|
@ -626,7 +626,7 @@ void
|
||||
_gtk_icon_helper_set_texture (GtkIconHelper *self,
|
||||
GdkTexture *texture)
|
||||
{
|
||||
gtk_icon_helper_take_definition (self, gtk_image_definition_new_texture (texture, 1));
|
||||
gtk_icon_helper_take_definition (self, gtk_image_definition_new_texture (texture));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "gtkicontheme.h"
|
||||
#include "gtkintl.h"
|
||||
#include "gtkprivate.h"
|
||||
#include "gtkscalerprivate.h"
|
||||
#include "gtksnapshot.h"
|
||||
#include "gtktypebuiltins.h"
|
||||
#include "gtkwidgetprivate.h"
|
||||
@ -729,7 +730,8 @@ gtk_image_set_from_file (GtkImage *image,
|
||||
GtkImagePrivate *priv = gtk_image_get_instance_private (image);
|
||||
GdkPixbufAnimation *anim;
|
||||
gint scale_factor;
|
||||
cairo_surface_t *surface;
|
||||
GdkTexture *texture;
|
||||
GdkPaintable *scaler;
|
||||
|
||||
g_return_if_fail (GTK_IS_IMAGE (image));
|
||||
|
||||
@ -753,11 +755,13 @@ gtk_image_set_from_file (GtkImage *image,
|
||||
return;
|
||||
}
|
||||
|
||||
surface = gdk_cairo_surface_create_from_pixbuf (gdk_pixbuf_animation_get_static_image (anim),
|
||||
scale_factor, _gtk_widget_get_window (GTK_WIDGET (image)));
|
||||
gtk_image_set_from_surface (image, surface);
|
||||
cairo_surface_destroy (surface);
|
||||
texture = gdk_texture_new_for_pixbuf (gdk_pixbuf_animation_get_static_image (anim));
|
||||
scaler = gtk_scaler_new (GDK_PAINTABLE (texture), scale_factor);
|
||||
|
||||
gtk_image_set_from_paintable (image, scaler);
|
||||
|
||||
g_object_unref (scaler);
|
||||
g_object_unref (texture);
|
||||
g_object_unref (anim);
|
||||
|
||||
priv->filename = g_strdup (filename);
|
||||
@ -809,7 +813,8 @@ gtk_image_set_from_resource (GtkImage *image,
|
||||
GtkImagePrivate *priv = gtk_image_get_instance_private (image);
|
||||
GdkPixbufAnimation *animation;
|
||||
gint scale_factor = 1;
|
||||
cairo_surface_t *surface;
|
||||
GdkTexture *texture;
|
||||
GdkPaintable *scaler;
|
||||
|
||||
g_return_if_fail (GTK_IS_IMAGE (image));
|
||||
|
||||
@ -840,10 +845,13 @@ gtk_image_set_from_resource (GtkImage *image,
|
||||
return;
|
||||
}
|
||||
|
||||
surface = gdk_cairo_surface_create_from_pixbuf (gdk_pixbuf_animation_get_static_image (animation),
|
||||
scale_factor, _gtk_widget_get_window (GTK_WIDGET (image)));
|
||||
gtk_image_set_from_surface (image, surface);
|
||||
cairo_surface_destroy (surface);
|
||||
texture = gdk_texture_new_for_pixbuf (gdk_pixbuf_animation_get_static_image (animation));
|
||||
scaler = gtk_scaler_new (GDK_PAINTABLE (texture), scale_factor);
|
||||
|
||||
gtk_image_set_from_paintable (image, scaler);
|
||||
|
||||
g_object_unref (scaler);
|
||||
g_object_unref (texture);
|
||||
|
||||
priv->resource_path = g_strdup (resource_path);
|
||||
|
||||
|
@ -57,7 +57,6 @@ struct _GtkImageDefinitionTexture {
|
||||
gint ref_count;
|
||||
|
||||
GdkTexture *texture;
|
||||
int scale;
|
||||
};
|
||||
|
||||
struct _GtkImageDefinitionPaintable {
|
||||
@ -151,8 +150,7 @@ gtk_image_definition_new_surface (cairo_surface_t *surface)
|
||||
}
|
||||
|
||||
GtkImageDefinition *
|
||||
gtk_image_definition_new_texture (GdkTexture *texture,
|
||||
gint scale)
|
||||
gtk_image_definition_new_texture (GdkTexture *texture)
|
||||
{
|
||||
GtkImageDefinition *def;
|
||||
|
||||
@ -161,7 +159,6 @@ gtk_image_definition_new_texture (GdkTexture *texture,
|
||||
|
||||
def = gtk_image_definition_alloc (GTK_IMAGE_TEXTURE);
|
||||
def->texture.texture = g_object_ref (texture);
|
||||
def->texture.scale = scale;
|
||||
|
||||
return def;
|
||||
}
|
||||
@ -238,11 +235,10 @@ gtk_image_definition_get_scale (const GtkImageDefinition *def)
|
||||
case GTK_IMAGE_EMPTY:
|
||||
case GTK_IMAGE_SURFACE:
|
||||
case GTK_IMAGE_PAINTABLE:
|
||||
case GTK_IMAGE_TEXTURE:
|
||||
case GTK_IMAGE_ICON_NAME:
|
||||
case GTK_IMAGE_GICON:
|
||||
return 1;
|
||||
case GTK_IMAGE_TEXTURE:
|
||||
return def->texture.scale;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,8 +29,7 @@ GtkImageDefinition * gtk_image_definition_new_empty (void);
|
||||
GtkImageDefinition * gtk_image_definition_new_icon_name (const char *icon_name);
|
||||
GtkImageDefinition * gtk_image_definition_new_gicon (GIcon *gicon);
|
||||
GtkImageDefinition * gtk_image_definition_new_surface (cairo_surface_t *surface);
|
||||
GtkImageDefinition * gtk_image_definition_new_texture (GdkTexture *texture,
|
||||
int scale);
|
||||
GtkImageDefinition * gtk_image_definition_new_texture (GdkTexture *texture);
|
||||
GtkImageDefinition * gtk_image_definition_new_paintable (GdkPaintable *paintable);
|
||||
|
||||
GtkImageDefinition * gtk_image_definition_ref (GtkImageDefinition *def);
|
||||
|
173
gtk/gtkscaler.c
Normal file
173
gtk/gtkscaler.c
Normal file
@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Copyright © 2018 Benjamin Otte
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Benjamin Otte <otte@gnome.org>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gtkscalerprivate.h"
|
||||
|
||||
#include "gtksnapshot.h"
|
||||
|
||||
struct _GtkScaler
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
GdkPaintable *paintable;
|
||||
double scale_factor;
|
||||
};
|
||||
|
||||
struct _GtkScalerClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
static void
|
||||
gtk_scaler_paintable_snapshot (GdkPaintable *paintable,
|
||||
GdkSnapshot *snapshot,
|
||||
double width,
|
||||
double height)
|
||||
{
|
||||
GtkScaler *self = GTK_SCALER (paintable);
|
||||
|
||||
if (self->scale_factor == 1.0)
|
||||
{
|
||||
gdk_paintable_snapshot (self->paintable, snapshot, width, height);
|
||||
}
|
||||
else
|
||||
{
|
||||
graphene_matrix_t scale_matrix;
|
||||
|
||||
graphene_matrix_init_scale (&scale_matrix, 1.0 / self->scale_factor, 1.0 / self->scale_factor, 1.0);
|
||||
gtk_snapshot_push_transform (snapshot,
|
||||
&scale_matrix,
|
||||
"GtkScaler<%g>",
|
||||
self->scale_factor);
|
||||
gdk_paintable_snapshot (self->paintable,
|
||||
snapshot,
|
||||
width * self->scale_factor,
|
||||
height * self->scale_factor);
|
||||
gtk_snapshot_pop (snapshot);
|
||||
}
|
||||
}
|
||||
|
||||
static GdkPaintable *
|
||||
gtk_scaler_paintable_get_current_image (GdkPaintable *paintable)
|
||||
{
|
||||
GtkScaler *self = GTK_SCALER (paintable);
|
||||
GdkPaintable *current_paintable, *current_self;
|
||||
|
||||
current_paintable = gdk_paintable_get_current_image (self->paintable);
|
||||
current_self = gtk_scaler_new (current_paintable, self->scale_factor);
|
||||
g_object_unref (current_paintable);
|
||||
|
||||
return current_self;
|
||||
}
|
||||
|
||||
static GdkPaintableFlags
|
||||
gtk_scaler_paintable_get_flags (GdkPaintable *paintable)
|
||||
{
|
||||
GtkScaler *self = GTK_SCALER (paintable);
|
||||
|
||||
return gdk_paintable_get_flags (self->paintable);
|
||||
}
|
||||
|
||||
static int
|
||||
gtk_scaler_paintable_get_intrinsic_width (GdkPaintable *paintable)
|
||||
{
|
||||
GtkScaler *self = GTK_SCALER (paintable);
|
||||
|
||||
return gdk_paintable_get_intrinsic_width (self->paintable) / self->scale_factor;
|
||||
}
|
||||
|
||||
static int
|
||||
gtk_scaler_paintable_get_intrinsic_height (GdkPaintable *paintable)
|
||||
{
|
||||
GtkScaler *self = GTK_SCALER (paintable);
|
||||
|
||||
return gdk_paintable_get_intrinsic_height (self->paintable) / self->scale_factor;
|
||||
}
|
||||
|
||||
static double gtk_scaler_paintable_get_intrinsic_aspect_ratio (GdkPaintable *paintable)
|
||||
{
|
||||
GtkScaler *self = GTK_SCALER (paintable);
|
||||
|
||||
return gdk_paintable_get_intrinsic_aspect_ratio (self->paintable);
|
||||
};
|
||||
|
||||
static void
|
||||
gtk_scaler_paintable_init (GdkPaintableInterface *iface)
|
||||
{
|
||||
iface->snapshot = gtk_scaler_paintable_snapshot;
|
||||
iface->get_current_image = gtk_scaler_paintable_get_current_image;
|
||||
iface->get_flags = gtk_scaler_paintable_get_flags;
|
||||
iface->get_intrinsic_width = gtk_scaler_paintable_get_intrinsic_width;
|
||||
iface->get_intrinsic_height = gtk_scaler_paintable_get_intrinsic_height;
|
||||
iface->get_intrinsic_aspect_ratio = gtk_scaler_paintable_get_intrinsic_aspect_ratio;
|
||||
}
|
||||
|
||||
G_DEFINE_TYPE_EXTENDED (GtkScaler, gtk_scaler, G_TYPE_OBJECT, 0,
|
||||
G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE,
|
||||
gtk_scaler_paintable_init))
|
||||
|
||||
static void
|
||||
gtk_scaler_dispose (GObject *object)
|
||||
{
|
||||
GtkScaler *self = GTK_SCALER (object);
|
||||
|
||||
if (self->paintable)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (self->paintable, gdk_paintable_invalidate_contents, self);
|
||||
g_signal_handlers_disconnect_by_func (self->paintable, gdk_paintable_invalidate_size, self);
|
||||
g_clear_object (&self->paintable);
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (gtk_scaler_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_scaler_class_init (GtkScalerClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
gobject_class->dispose = gtk_scaler_dispose;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_scaler_init (GtkScaler *self)
|
||||
{
|
||||
self->scale_factor = 1.0;
|
||||
}
|
||||
|
||||
GdkPaintable *
|
||||
gtk_scaler_new (GdkPaintable *paintable,
|
||||
double scale_factor)
|
||||
{
|
||||
GtkScaler *self;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_PAINTABLE (paintable), NULL);
|
||||
g_return_val_if_fail (scale_factor > 0.0, NULL);
|
||||
|
||||
self = g_object_new (GTK_TYPE_SCALER, NULL);
|
||||
|
||||
self->paintable = g_object_ref (paintable);
|
||||
g_signal_connect_swapped (paintable, "invalidate-contents", G_CALLBACK (gdk_paintable_invalidate_contents), self);
|
||||
g_signal_connect_swapped (paintable, "invalidate-size", G_CALLBACK (gdk_paintable_invalidate_size), self);
|
||||
self->scale_factor = scale_factor;
|
||||
|
||||
return GDK_PAINTABLE (self);
|
||||
}
|
36
gtk/gtkscalerprivate.h
Normal file
36
gtk/gtkscalerprivate.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright © 2018 Benjamin Otte
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Benjamin Otte <otte@gnome.org>
|
||||
*/
|
||||
|
||||
#ifndef __GTK_SCALER_H__
|
||||
#define __GTK_SCALER_H__
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_SCALER (gtk_scaler_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (GtkScaler, gtk_scaler, GTK, SCALER, GObject)
|
||||
|
||||
GdkPaintable * gtk_scaler_new (GdkPaintable *paintable,
|
||||
double scale_factor);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_SCALER_H__ */
|
@ -123,6 +123,7 @@ gtk_private_sources = files([
|
||||
'gtkprivate.c',
|
||||
'gtkprogresstracker.c',
|
||||
'gtkquery.c',
|
||||
'gtkscaler.c',
|
||||
'gtksearchengine.c',
|
||||
'gtksearchenginemodel.c',
|
||||
'gtksearchenginesimple.c',
|
||||
|
Loading…
Reference in New Issue
Block a user