summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gtk/gdkpixbufutils.c128
-rw-r--r--gtk/gdkpixbufutilsprivate.h10
-rw-r--r--gtk/gtkimage.c143
-rw-r--r--gtk/gtkpicture.c75
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);