Commit 5e3e1dd6 authored by Matthias Clasen's avatar Matthias Clasen
Browse files

Merge branch 'matthiasc/for-master' into 'master'

image, picture: Move pixbuf code to gdkpixbufutils

See merge request !3449
parents 486a2c96 379bb6c9
Pipeline #275312 passed with stages
in 27 minutes and 14 seconds
......@@ -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;
}
......@@ -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__ */
......@@ -26,6 +26,7 @@
#include "gtkcssimageinvalidprivate.h"
#include "gtkcssimagepaintableprivate.h"
#include "gtkstyleproviderprivate.h"
#include "gdkpixbufutilsprivate.h"
#include "gtk/css/gtkcssdataurlprivate.h"
......@@ -41,9 +42,7 @@ gtk_css_image_url_load_image (GtkCssImageUrl *url,
if (url->loaded_image)
return url->loaded_image;
/* We special case resources here so we can use
gdk_pixbuf_new_from_resource, which in turn has some special casing
for GdkPixdata files to avoid duplicating the memory for the pixbufs */
/* We special case resources here so we can use gdk_texture_new_from_resource. */
if (g_file_has_uri_scheme (url->file, "resource"))
{
char *uri = g_file_get_uri (url->file);
......@@ -181,19 +180,19 @@ gtk_css_image_url_parse (GtkCssImage *image,
scheme = g_uri_parse_scheme (url);
if (scheme && g_ascii_strcasecmp (scheme, "data") == 0)
{
GInputStream *stream;
GdkPixbuf *pixbuf;
GBytes *bytes;
GdkPaintable *paintable;
GError *error = NULL;
bytes = gtk_css_data_url_parse (url, NULL, &error);
if (bytes)
{
stream = g_memory_input_stream_new_from_bytes (bytes);
pixbuf = gdk_pixbuf_new_from_stream (stream, NULL, &error);
g_object_unref (stream);
if (pixbuf == NULL)
paintable = gdk_paintable_new_from_bytes_scaled (bytes, 1);
g_bytes_unref (bytes);
if (paintable == NULL)
{
error = g_error_new (G_IO_ERROR, G_IO_ERROR_FAILED,
"Failed to load image from '%s'", url);
gtk_css_parser_emit_error (parser,
gtk_css_parser_get_start_location (parser),
gtk_css_parser_get_end_location (parser),
......@@ -202,12 +201,17 @@ gtk_css_image_url_parse (GtkCssImage *image,
}
else
{
GdkTexture *texture = gdk_texture_new_for_pixbuf (pixbuf);
self->loaded_image = gtk_css_image_paintable_new (GDK_PAINTABLE (texture), GDK_PAINTABLE (texture));
g_object_unref (texture);
g_object_unref (pixbuf);
self->loaded_image = gtk_css_image_paintable_new (paintable, paintable);
}
}
else
{
gtk_css_parser_emit_error (parser,
gtk_css_parser_get_start_location (parser),
gtk_css_parser_get_end_location (parser),
error);
g_clear_error (&error);
}
}
else
{
......
......@@ -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));
}
......
......@@ -580,12 +580,11 @@ gtk_mount_operation_ask_password_do_gtk (GtkMountOperation *operation,
GtkWidget *hbox, *main_vbox, *icon;
GtkWidget *grid;
GtkWidget *label;
GtkWidget *content_area, *action_area;
GtkWidget *content_area;
gboolean can_anonymous;
guint rows;
char *primary;
const char *secondary = NULL;
PangoAttrList *attrs;
gboolean use_header;
priv = operation->priv;
......@@ -602,11 +601,6 @@ gtk_mount_operation_ask_password_do_gtk (GtkMountOperation *operation,
priv->dialog = dialog;
content_area = gtk_dialog_get_content_area (dialog);
action_area = gtk_dialog_get_action_area (dialog);
/* Set the dialog up with HIG properties */
gtk_box_set_spacing (GTK_BOX (content_area), 2); /* 2 * 5 + 2 = 12 */
gtk_box_set_spacing (GTK_BOX (action_area), 6);
gtk_window_set_resizable (window, FALSE);
gtk_window_set_title (window, "");
......@@ -621,6 +615,12 @@ gtk_mount_operation_ask_password_do_gtk (GtkMountOperation *operation,
/* Build contents */
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
g_object_set (hbox,
"margin-start", 12,
"margin-end", 12,
"margin-top", 12,
"margin-bottom", 12,
NULL);
gtk_box_append (GTK_BOX (content_area), hbox);
icon = gtk_image_new_from_icon_name ("dialog-password");
......@@ -646,10 +646,7 @@ gtk_mount_operation_ask_password_do_gtk (GtkMountOperation *operation,
gtk_label_set_wrap (GTK_LABEL (label), TRUE);
gtk_box_append (GTK_BOX (main_vbox), GTK_WIDGET (label));
g_free (primary);
attrs = pango_attr_list_new ();
pango_attr_list_insert (attrs, pango_attr_weight_new (PANGO_WEIGHT_BOLD));
gtk_label_set_attributes (GTK_LABEL (label), attrs);
pango_attr_list_unref (attrs);
gtk_widget_add_css_class (label, "title-3");
if (secondary != NULL)
{
......
......@@ -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);
......
......@@ -550,7 +550,7 @@ populate_servers (GtkPlacesView *view)
/* clear previous items */
while ((child = gtk_widget_get_first_child (GTK_WIDGET (view->recent_servers_listbox))))
gtk_list_box_remove (GTK_LIST_BOX (view->listbox), child);
gtk_list_box_remove (GTK_LIST_BOX (view->recent_servers_listbox), child);
gtk_list_store_clear (view->completion_store);
......@@ -1215,12 +1215,14 @@ server_mount_ready_cb (GObject *source_file,
g_clear_error (&error);
}
if (view->destroyed) {
g_object_unref (view);
return;
}
if (view->destroyed)
{
g_object_unref (view);
return;
}
view->should_pulse_entry = FALSE;
gtk_entry_set_progress_fraction (GTK_ENTRY (view->address_entry), 0);
/* Restore from Cancel to Connect */
gtk_button_set_label (GTK_BUTTON (view->connect_button), _("Con_nect"));
......@@ -1388,8 +1390,7 @@ pulse_entry_cb (gpointer user_data)
}
else
{
gtk_entry_set_progress_pulse_step (GTK_ENTRY (view->address_entry), 0.0);
gtk_entry_set_progress_fraction (GTK_ENTRY (view->address_entry), 0.0);
gtk_entry_set_progress_fraction (GTK_ENTRY (view->address_entry), 0);
view->entry_pulse_timeout_id = 0;
return G_SOURCE_REMOVE;
......@@ -1443,6 +1444,7 @@ mount_server (GtkPlacesView *view,
view->should_pulse_entry = TRUE;
gtk_entry_set_progress_pulse_step (GTK_ENTRY (view->address_entry), 0.1);
gtk_entry_set_progress_fraction (GTK_ENTRY (view->address_entry), 0.1);
/* Allow to cancel the operation */