diff options
-rw-r--r-- | gtk/gdkpixbufutils.c | 128 | ||||
-rw-r--r-- | gtk/gdkpixbufutilsprivate.h | 10 | ||||
-rw-r--r-- | gtk/gtkimage.c | 143 | ||||
-rw-r--r-- | gtk/gtkpicture.c | 75 |
4 files changed, 160 insertions, 196 deletions
diff --git a/gtk/gdkpixbufutils.c b/gtk/gdkpixbufutils.c index 2aa62b094c..d1b6693918 100644 --- a/gtk/gdkpixbufutils.c +++ b/gtk/gdkpixbufutils.c @@ -18,6 +18,7 @@ #include <gdk/gdk.h> #include "gdkpixbufutilsprivate.h" +#include "gtkscalerprivate.h" static GdkPixbuf * load_from_stream (GdkPixbufLoader *loader, @@ -572,3 +573,130 @@ gtk_make_symbolic_texture_from_file (GFile *file, return texture; } + +typedef struct { + int scale_factor; +} LoaderData; + +static void +on_loader_size_prepared (GdkPixbufLoader *loader, + int width, + int height, + gpointer user_data) +{ + LoaderData *loader_data = user_data; + GdkPixbufFormat *format; + + /* Let the regular icon helper code path handle non-scalable images */ + format = gdk_pixbuf_loader_get_format (loader); + if (!gdk_pixbuf_format_is_scalable (format)) + { + loader_data->scale_factor = 1; + return; + } + + gdk_pixbuf_loader_set_size (loader, + width * loader_data->scale_factor, + height * loader_data->scale_factor); +} + +GdkPaintable * +gdk_paintable_new_from_bytes_scaled (GBytes *bytes, + int scale_factor) +{ + GdkPixbufLoader *loader; + GdkPixbuf *pixbuf = NULL; + LoaderData loader_data; + GdkTexture *texture; + GdkPaintable *paintable; + + loader_data.scale_factor = scale_factor; + + loader = gdk_pixbuf_loader_new (); + g_signal_connect (loader, "size-prepared", + G_CALLBACK (on_loader_size_prepared), &loader_data); + + if (!gdk_pixbuf_loader_write_bytes (loader, bytes, NULL)) + goto out; + + if (!gdk_pixbuf_loader_close (loader, NULL)) + goto out; + + pixbuf = gdk_pixbuf_loader_get_pixbuf (loader); + if (pixbuf != NULL) + g_object_ref (pixbuf); + + out: + gdk_pixbuf_loader_close (loader, NULL); + g_object_unref (loader); + + if (!pixbuf) + return NULL; + + texture = gdk_texture_new_for_pixbuf (pixbuf); + if (loader_data.scale_factor != 1) + paintable = gtk_scaler_new (GDK_PAINTABLE (texture), loader_data.scale_factor); + else + paintable = g_object_ref ((GdkPaintable *)texture); + + g_object_unref (pixbuf); + g_object_unref (texture); + + return paintable; +} + +GdkPaintable * +gdk_paintable_new_from_path_scaled (const char *path, + int scale_factor) +{ + char *contents; + gsize length; + GBytes *bytes; + GdkPaintable *paintable; + + if (!g_file_get_contents (path, &contents, &length, NULL)) + return NULL; + + bytes = g_bytes_new_take (contents, length); + + paintable = gdk_paintable_new_from_bytes_scaled (bytes, scale_factor); + + g_bytes_unref (bytes); + + return paintable; +} + +GdkPaintable * +gdk_paintable_new_from_resource_scaled (const char *path, + int scale_factor) +{ + GBytes *bytes; + GdkPaintable *paintable; + + bytes = g_resources_lookup_data (path, G_RESOURCE_LOOKUP_FLAGS_NONE, NULL); + if (!bytes) + return NULL; + + paintable = gdk_paintable_new_from_bytes_scaled (bytes, scale_factor); + g_bytes_unref (bytes); + + return paintable; +} + +GdkPaintable * +gdk_paintable_new_from_file_scaled (GFile *file, + int scale_factor) +{ + GBytes *bytes; + GdkPaintable *paintable; + + bytes = g_file_load_bytes (file, NULL, NULL, NULL); + if (!bytes) + return NULL; + + paintable = gdk_paintable_new_from_bytes_scaled (bytes, scale_factor); + + g_bytes_unref (bytes); + + return paintable; +} diff --git a/gtk/gdkpixbufutilsprivate.h b/gtk/gdkpixbufutilsprivate.h index 2a339d2c42..62efe3699e 100644 --- a/gtk/gdkpixbufutilsprivate.h +++ b/gtk/gdkpixbufutilsprivate.h @@ -86,6 +86,16 @@ GdkTexture *gtk_make_symbolic_texture_from_resource (const char *path, int height, double scale, GError **error); + +GdkPaintable *gdk_paintable_new_from_bytes_scaled (GBytes *bytes, + int scale_factor); +GdkPaintable *gdk_paintable_new_from_path_scaled (const char *path, + int scale_factor); +GdkPaintable *gdk_paintable_new_from_resource_scaled (const char *path, + int scale_factor); +GdkPaintable *gdk_paintable_new_from_file_scaled (GFile *file, + int scale_factor); + G_END_DECLS #endif /* __GDK_PIXBUF_UTILS_PRIVATE_H__ */ diff --git a/gtk/gtkimage.c b/gtk/gtkimage.c index abe5694c71..46a494c738 100644 --- a/gtk/gtkimage.c +++ b/gtk/gtkimage.c @@ -30,10 +30,10 @@ #include "gtkicontheme.h" #include "gtkintl.h" #include "gtkprivate.h" -#include "gtkscalerprivate.h" #include "gtksnapshot.h" #include "gtktypebuiltins.h" #include "gtkwidgetprivate.h" +#include "gdkpixbufutilsprivate.h" #include <math.h> #include <string.h> @@ -581,96 +581,6 @@ gtk_image_new_from_gicon (GIcon *icon) return GTK_WIDGET (image); } -typedef struct { - GtkImage *image; - int scale_factor; -} LoaderData; - -static void -on_loader_size_prepared (GdkPixbufLoader *loader, - int width, - int height, - gpointer user_data) -{ - LoaderData *loader_data = user_data; - int scale_factor; - GdkPixbufFormat *format; - - /* Let the regular icon helper code path handle non-scalable images */ - format = gdk_pixbuf_loader_get_format (loader); - if (!gdk_pixbuf_format_is_scalable (format)) - { - loader_data->scale_factor = 1; - return; - } - - scale_factor = gtk_widget_get_scale_factor (GTK_WIDGET (loader_data->image)); - gdk_pixbuf_loader_set_size (loader, width * scale_factor, height * scale_factor); - loader_data->scale_factor = scale_factor; -} - -static GdkPixbufAnimation * -load_scalable_with_loader (GtkImage *image, - const char *file_path, - const char *resource_path, - int *scale_factor_out) -{ - GdkPixbufLoader *loader; - GBytes *bytes; - char *contents; - gsize length; - gboolean res; - GdkPixbufAnimation *animation; - LoaderData loader_data; - - animation = NULL; - bytes = NULL; - - loader = gdk_pixbuf_loader_new (); - loader_data.image = image; - - g_signal_connect (loader, "size-prepared", G_CALLBACK (on_loader_size_prepared), &loader_data); - - if (resource_path != NULL) - { - bytes = g_resources_lookup_data (resource_path, G_RESOURCE_LOOKUP_FLAGS_NONE, NULL); - } - else if (file_path != NULL) - { - res = g_file_get_contents (file_path, &contents, &length, NULL); - if (res) - bytes = g_bytes_new_take (contents, length); - } - else - { - g_assert_not_reached (); - } - - if (!bytes) - goto out; - - if (!gdk_pixbuf_loader_write_bytes (loader, bytes, NULL)) - goto out; - - if (!gdk_pixbuf_loader_close (loader, NULL)) - goto out; - - animation = gdk_pixbuf_loader_get_animation (loader); - if (animation != NULL) - { - g_object_ref (animation); - if (scale_factor_out != NULL) - *scale_factor_out = loader_data.scale_factor; - } - - out: - gdk_pixbuf_loader_close (loader, NULL); - g_object_unref (loader); - g_bytes_unref (bytes); - - return animation; -} - /** * gtk_image_set_from_file: (attributes org.gtk.Method.set_property=file) * @image: a `GtkImage` @@ -681,18 +591,16 @@ load_scalable_with_loader (GtkImage *image, * See [ctor@Gtk.Image.new_from_file] for details. */ void -gtk_image_set_from_file (GtkImage *image, - const char *filename) +gtk_image_set_from_file (GtkImage *image, + const char *filename) { - GdkPixbufAnimation *anim; int scale_factor; - GdkTexture *texture; - GdkPaintable *scaler; + GdkPaintable *paintable; g_return_if_fail (GTK_IS_IMAGE (image)); g_object_freeze_notify (G_OBJECT (image)); - + gtk_image_clear (image); if (filename == NULL) @@ -702,23 +610,19 @@ gtk_image_set_from_file (GtkImage *image, return; } - anim = load_scalable_with_loader (image, filename, NULL, &scale_factor); + scale_factor = gtk_widget_get_scale_factor (GTK_WIDGET (image)); + paintable = gdk_paintable_new_from_path_scaled (filename, scale_factor); - if (anim == NULL) + if (paintable == NULL) { gtk_image_set_from_icon_name (image, "image-missing"); g_object_thaw_notify (G_OBJECT (image)); return; } - 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); + gtk_image_set_from_paintable (image, paintable); - g_object_unref (scaler); - g_object_unref (texture); - g_object_unref (anim); + g_object_unref (paintable); image->filename = g_strdup (filename); @@ -765,13 +669,11 @@ out: * See [ctor@Gtk.Image.new_from_resource] for details. */ void -gtk_image_set_from_resource (GtkImage *image, - const char *resource_path) +gtk_image_set_from_resource (GtkImage *image, + const char *resource_path) { - GdkPixbufAnimation *animation; - int scale_factor = 1; - GdkTexture *texture; - GdkPaintable *scaler; + int scale_factor; + GdkPaintable *paintable; g_return_if_fail (GTK_IS_IMAGE (image)); @@ -788,34 +690,29 @@ gtk_image_set_from_resource (GtkImage *image, if (resource_is_pixdata (resource_path)) { g_warning ("GdkPixdata format images are not supported, remove the \"to-pixdata\" option from your GResource files"); - animation = NULL; + paintable = NULL; } else { - animation = load_scalable_with_loader (image, NULL, resource_path, &scale_factor); + scale_factor = gtk_widget_get_scale_factor (GTK_WIDGET (image)); + paintable = gdk_paintable_new_from_resource_scaled (resource_path, scale_factor); } - if (animation == NULL) + if (paintable == NULL) { gtk_image_set_from_icon_name (image, "image-missing"); g_object_thaw_notify (G_OBJECT (image)); return; } - 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); + gtk_image_set_from_paintable (image, paintable); - g_object_unref (scaler); - g_object_unref (texture); + g_object_unref (paintable); image->resource_path = g_strdup (resource_path); g_object_notify_by_pspec (G_OBJECT (image), image_props[PROP_RESOURCE]); - g_object_unref (animation); - g_object_thaw_notify (G_OBJECT (image)); } diff --git a/gtk/gtkpicture.c b/gtk/gtkpicture.c index 10607b31ae..6b9fb1c51e 100644 --- a/gtk/gtkpicture.c +++ b/gtk/gtkpicture.c @@ -26,9 +26,9 @@ #include "gtkcssstyleprivate.h" #include "gtkintl.h" #include "gtkprivate.h" -#include "gtkscalerprivate.h" #include "gtksnapshot.h" #include "gtkwidgetprivate.h" +#include "gdkpixbufutilsprivate.h" /** * GtkPicture: @@ -560,77 +560,6 @@ gtk_picture_new_for_resource (const char *resource_path) return result; } -typedef struct { - int scale_factor; -} LoaderData; - -static void -on_loader_size_prepared (GdkPixbufLoader *loader, - int width, - int height, - gpointer user_data) -{ - LoaderData *loader_data = user_data; - GdkPixbufFormat *format; - - /* Let the regular icon helper code path handle non-scalable pictures */ - format = gdk_pixbuf_loader_get_format (loader); - if (!gdk_pixbuf_format_is_scalable (format)) - { - loader_data->scale_factor = 1; - return; - } - - gdk_pixbuf_loader_set_size (loader, - width * loader_data->scale_factor, - height * loader_data->scale_factor); -} - -static GdkPaintable * -load_scalable_with_loader (GFile *file, - int scale_factor) -{ - GdkPixbufLoader *loader; - GBytes *bytes; - GdkPixbufAnimation *animation; - GdkPaintable *result, *scaler; - LoaderData loader_data; - - result = NULL; - - loader = gdk_pixbuf_loader_new (); - loader_data.scale_factor = scale_factor; - - g_signal_connect (loader, "size-prepared", G_CALLBACK (on_loader_size_prepared), &loader_data); - - bytes = g_file_load_bytes (file, NULL, NULL, NULL); - if (bytes == NULL) - goto out1; - - if (!gdk_pixbuf_loader_write_bytes (loader, bytes, NULL)) - goto out2; - - if (!gdk_pixbuf_loader_close (loader, NULL)) - goto out2; - - animation = gdk_pixbuf_loader_get_animation (loader); - if (animation == NULL) - goto out2; - - result = GDK_PAINTABLE (gdk_texture_new_for_pixbuf (gdk_pixbuf_animation_get_static_image (animation))); - scaler = gtk_scaler_new (result, loader_data.scale_factor); - g_object_unref (result); - result = scaler; - -out2: - g_bytes_unref (bytes); -out1: - gdk_pixbuf_loader_close (loader, NULL); - g_object_unref (loader); - - return result; -} - /** * gtk_picture_set_file: (attributes org.gtk.Method.set_property=file) * @self: a `GtkPicture` @@ -657,7 +586,7 @@ gtk_picture_set_file (GtkPicture *self, g_set_object (&self->file, file); g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FILE]); - paintable = load_scalable_with_loader (file, gtk_widget_get_scale_factor (GTK_WIDGET (self))); + paintable = gdk_paintable_new_from_file_scaled (file, gtk_widget_get_scale_factor (GTK_WIDGET (self))); gtk_picture_set_paintable (self, paintable); g_clear_object (&paintable); |