diff --git a/demos/icon-browser/iconbrowserwin.c b/demos/icon-browser/iconbrowserwin.c index fc10a82020..d8f684a7dd 100644 --- a/demos/icon-browser/iconbrowserwin.c +++ b/demos/icon-browser/iconbrowserwin.c @@ -49,7 +49,9 @@ struct _IconBrowserWindow GtkWidget *image4; GtkWidget *image5; GtkWidget *image6; - GtkWidget *label6; + GtkWidget *image7; + GtkWidget *image8; + GtkWidget *label8; GtkWidget *description; }; @@ -113,21 +115,23 @@ item_activated (GtkIconView *icon_view, GtkTreePath *path, IconBrowserWindow *wi } gtk_window_set_title (GTK_WINDOW (win->details), name); - set_image (win->image1, name, 16); - set_image (win->image2, name, 24); - set_image (win->image3, name, 32); - set_image (win->image4, name, 48); - set_image (win->image5, name, 64); + set_image (win->image1, name, 8); + set_image (win->image2, name, 16); + set_image (win->image3, name, 18); + set_image (win->image4, name, 24); + set_image (win->image5, name, 32); + set_image (win->image6, name, 48); + set_image (win->image7, name, 64); if (win->symbolic) { - gtk_widget_show (win->image6); - gtk_widget_show (win->label6); - set_image (win->image6, name, 64); + gtk_widget_show (win->image8); + gtk_widget_show (win->label8); + set_image (win->image8, name, 64); } else { - gtk_widget_hide (win->image6); - gtk_widget_hide (win->label6); + gtk_widget_hide (win->image8); + gtk_widget_hide (win->label8); } if (description && description[0]) { @@ -372,7 +376,7 @@ get_image_paintable (GtkImage *image) NULL, size, 1, gtk_widget_get_direction (GTK_WIDGET (image)), - GTK_ICON_LOOKUP_FORCE_SIZE); + 0); if (icon == NULL) return NULL; return GDK_PAINTABLE (icon); @@ -484,7 +488,9 @@ icon_browser_window_init (IconBrowserWindow *win) setup_image_dnd (win->image3); setup_image_dnd (win->image4); setup_image_dnd (win->image5); - setup_scalable_image_dnd (win->image6); + setup_image_dnd (win->image6); + setup_image_dnd (win->image7); + setup_scalable_image_dnd (win->image8); win->contexts = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, context_free); @@ -541,7 +547,9 @@ icon_browser_window_class_init (IconBrowserWindowClass *class) gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, image4); gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, image5); gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, image6); - gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, label6); + gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, image7); + gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, image8); + gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, label8); gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, description); gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), search_text_changed); diff --git a/demos/icon-browser/window.ui b/demos/icon-browser/window.ui index 40964afc44..0aa0c48d4f 100644 --- a/demos/icon-browser/window.ui +++ b/demos/icon-browser/window.ui @@ -198,7 +198,7 @@ center end - + 5 @@ -206,11 +206,37 @@ + + + center + end + + + + + 6 + 1 + + + + + + center + end + + + + + 7 + 1 + + + center baseline - 16×16 + 8×8 @@ -227,7 +253,7 @@ center baseline - 24×24 + 16×16 @@ -244,7 +270,7 @@ center baseline - 32×32 + 18×18 @@ -261,7 +287,7 @@ center baseline - 48×48 + 24×24 @@ -278,7 +304,7 @@ center baseline - 64×64 + 32×32 @@ -295,7 +321,7 @@ center baseline - scalable + 48×48 @@ -308,6 +334,40 @@ + + + center + baseline + 64×64 + + + + + + 6 + 2 + + + + + + center + baseline + scalable + + + + + + 7 + 2 + + + diff --git a/gtk/gtkcellrendererpixbuf.c b/gtk/gtkcellrendererpixbuf.c index e89a5f8ba3..bb240bae91 100644 --- a/gtk/gtkcellrendererpixbuf.c +++ b/gtk/gtkcellrendererpixbuf.c @@ -403,7 +403,6 @@ create_icon_helper (GtkCellRendererPixbuf *cellpixbuf, icon_helper = gtk_icon_helper_new (gtk_style_context_get_node (gtk_widget_get_style_context (widget)), widget); _gtk_icon_helper_set_use_fallback (icon_helper, TRUE); - _gtk_icon_helper_set_force_scale_pixbuf (icon_helper, TRUE); _gtk_icon_helper_set_definition (icon_helper, priv->image_def); return icon_helper; diff --git a/gtk/gtkiconhelper.c b/gtk/gtkiconhelper.c index 0c8e960d53..eb6f715527 100644 --- a/gtk/gtkiconhelper.c +++ b/gtk/gtkiconhelper.c @@ -46,7 +46,6 @@ struct _GtkIconHelper gint pixel_size; guint use_fallback : 1; - guint force_scale_pixbuf : 1; guint texture_is_symbolic : 1; GtkWidget *owner; @@ -63,9 +62,6 @@ get_icon_lookup_flags (GtkIconHelper *self, flags = 0; - if (self->pixel_size != -1 || self->force_scale_pixbuf) - flags |= GTK_ICON_LOOKUP_FORCE_SIZE; - icon_style = _gtk_css_icon_style_value_get (style->icon->icon_style); switch (icon_style) @@ -567,23 +563,6 @@ _gtk_icon_helper_get_is_empty (GtkIconHelper *self) return gtk_image_definition_get_storage_type (self->def) == GTK_IMAGE_EMPTY; } -gboolean -_gtk_icon_helper_get_force_scale_pixbuf (GtkIconHelper *self) -{ - return self->force_scale_pixbuf; -} - -void -_gtk_icon_helper_set_force_scale_pixbuf (GtkIconHelper *self, - gboolean force_scale) -{ - if (self->force_scale_pixbuf != force_scale) - { - self->force_scale_pixbuf = force_scale; - gtk_icon_helper_invalidate (self); - } -} - void gtk_icon_size_set_style_classes (GtkCssNode *cssnode, GtkIconSize icon_size) diff --git a/gtk/gtkiconhelperprivate.h b/gtk/gtkiconhelperprivate.h index b7656bb849..1b51eaa250 100644 --- a/gtk/gtkiconhelperprivate.h +++ b/gtk/gtkiconhelperprivate.h @@ -66,10 +66,6 @@ const gchar *_gtk_icon_helper_get_icon_name (GtkIconHelper *self); int gtk_icon_helper_get_size (GtkIconHelper *self); -gboolean _gtk_icon_helper_get_force_scale_pixbuf (GtkIconHelper *self); -void _gtk_icon_helper_set_force_scale_pixbuf (GtkIconHelper *self, - gboolean force_scale); - void gtk_icon_helper_invalidate (GtkIconHelper *self); void gtk_icon_helper_invalidate_for_change (GtkIconHelper *self, GtkCssStyleChange *change); diff --git a/gtk/gtkicontheme.c b/gtk/gtkicontheme.c index 9cf4b29068..759a7e112f 100644 --- a/gtk/gtkicontheme.c +++ b/gtk/gtkicontheme.c @@ -273,26 +273,13 @@ struct _GtkIconPaintable /* Cache pixbuf (if there is any) */ GdkPixbuf *cache_pixbuf; - /* Information about the directory where - * the source was found - */ - IconThemeDirType dir_type; - gint dir_size; - gint dir_scale; - gint min_size; - gint max_size; - /* Parameters influencing the scaled icon */ gint desired_size; gint desired_scale; - gint rendered_size; - gdouble unscaled_scale; - guint forced_size : 1; guint is_svg : 1; guint is_resource : 1; - /* Cached information if we go ahead and try to load the icon. * * All access to these are protected by the texture_lock. Everything @@ -303,9 +290,6 @@ struct _GtkIconPaintable GdkTexture *texture; GError *load_error; - gdouble scale; - gint symbolic_width; - gint symbolic_height; }; typedef struct @@ -360,40 +344,39 @@ typedef struct gboolean exists; } IconThemeDirMtime; -static void gtk_icon_theme_finalize (GObject *object); -static void gtk_icon_theme_dispose (GObject *object); -static IconTheme * theme_new (const char *theme_name, - GKeyFile *theme_file); -static void theme_dir_size_destroy (IconThemeDirSize *dir_size); -static void theme_dir_destroy (IconThemeDir *dir); -static void theme_destroy (IconTheme *theme); -static GtkIconPaintable *theme_lookup_icon (IconTheme *theme, - const gchar *icon_name, - gint size, - gint scale, - gboolean allow_svg); -static void theme_list_icons (IconTheme *theme, - GHashTable *icons); -static gboolean theme_has_icon (IconTheme *theme, - const gchar *icon_name); -static void theme_subdir_load (GtkIconTheme *self, - IconTheme *theme, - GKeyFile *theme_file, - gchar *subdir); -static void do_theme_change (GtkIconTheme *self); -static void blow_themes (GtkIconTheme *self); -static gboolean rescan_themes (GtkIconTheme *self); -static GtkIconPaintable *icon_paintable_new (IconThemeDirType type, - gint dir_size, - gint dir_scale); -static void icon_compute_rendered_size (GtkIconPaintable *icon); -static IconCacheFlag suffix_from_name (const gchar *name); -static gboolean icon_ensure_scale_and_texture__locked (GtkIconPaintable *icon, - gboolean in_thread); -static void unset_display (GtkIconTheme *self); -static void update_current_theme__mainthread (GtkIconTheme *self); -static gboolean ensure_valid_themes (GtkIconTheme *self, - gboolean non_blocking); +static void gtk_icon_theme_finalize (GObject *object); +static void gtk_icon_theme_dispose (GObject *object); +static IconTheme * theme_new (const char *theme_name, + GKeyFile *theme_file); +static void theme_dir_size_destroy (IconThemeDirSize *dir_size); +static void theme_dir_destroy (IconThemeDir *dir); +static void theme_destroy (IconTheme *theme); +static GtkIconPaintable *theme_lookup_icon (IconTheme *theme, + const gchar *icon_name, + gint size, + gint scale, + gboolean allow_svg); +static void theme_list_icons (IconTheme *theme, + GHashTable *icons); +static gboolean theme_has_icon (IconTheme *theme, + const gchar *icon_name); +static void theme_subdir_load (GtkIconTheme *self, + IconTheme *theme, + GKeyFile *theme_file, + gchar *subdir); +static void do_theme_change (GtkIconTheme *self); +static void blow_themes (GtkIconTheme *self); +static gboolean rescan_themes (GtkIconTheme *self); +static GtkIconPaintable *icon_paintable_new (int desired_size, + int desired_scale); +static IconCacheFlag suffix_from_name (const gchar *name); +static gboolean icon_ensure_texture__locked (GtkIconPaintable *icon, + gboolean in_thread); +static void unset_display (GtkIconTheme *self); +static void update_current_theme__mainthread (GtkIconTheme *self); +static gboolean ensure_valid_themes (GtkIconTheme *self, + gboolean non_blocking); + static guint signal_changed = 0; @@ -1811,7 +1794,6 @@ real_choose_icon (GtkIconTheme *self, { GList *l; GtkIconPaintable *icon = NULL; - GtkIconPaintable *unscaled_icon; UnthemedIcon *unthemed_icon = NULL; const gchar *icon_name = NULL; IconTheme *theme = NULL; @@ -1896,7 +1878,7 @@ real_choose_icon (GtkIconTheme *self, if (hIcon) { - icon = icon_paintable_new (ICON_THEME_DIR_UNTHEMED, size, 1); + icon = icon_paintable_new (size, scale); icon->cache_pixbuf = gdk_win32_icon_to_pixbuf_libgtk_only (hIcon, NULL, NULL); DestroyIcon (hIcon); } @@ -1906,7 +1888,7 @@ real_choose_icon (GtkIconTheme *self, if (unthemed_icon) { - icon = icon_paintable_new (ICON_THEME_DIR_UNTHEMED, size, 1); + icon = icon_paintable_new (size, scale); /* A SVG icon, when allowed, beats out a XPM icon, but not a PNG icon */ if (self->pixbuf_supports_svg && @@ -1940,25 +1922,6 @@ real_choose_icon (GtkIconTheme *self, { icon->desired_size = size; icon->desired_scale = scale; - icon->forced_size = (flags & GTK_ICON_LOOKUP_FORCE_SIZE) != 0; - - /* In case we're not scaling the icon we want to reuse the exact same - * size as a scale==1 lookup would be, rather than not scaling at all - * and causing a different layout - */ - icon->unscaled_scale = 1.0; - if (scale != 1 && !icon->forced_size && theme != NULL) - { - unscaled_icon = theme_lookup_icon (theme, icon_name, size, 1, self->pixbuf_supports_svg); - if (unscaled_icon) - { - icon->unscaled_scale = - (gdouble) unscaled_icon->dir_size * scale / (icon->dir_size * icon->dir_scale); - g_object_unref (unscaled_icon); - } - } - - icon_compute_rendered_size (icon); icon->key.icon_names = g_strdupv ((char **)icon_names); icon->key.size = size; @@ -2140,7 +2103,7 @@ choose_icon (GtkIconTheme *self, * @self: a #GtkIconTheme * @icon_name: the name of the icon to lookup * @fallbacks: (nullable) (array zero-terminated=1): - * @size: desired icon size. The resulting icon may not be exactly this size. + * @size: desired icon size. * @scale: the window scale this will be displayed on * @direction: text direction the icon will be displayed in * @flags: flags modifying the behavior of the icon lookup @@ -2150,15 +2113,6 @@ choose_icon (GtkIconTheme *self, * or you can get information such as the filename and size. The pixels * of the texture can be access by using gtk_icon_paintable_download_texture(). * - * The icon icon size will be based on the requested @size, but may - * not be exactly this size; an icon theme may have icons that differ - * slightly from their nominal sizes, and in addition GTK+ will avoid - * scaling icons that it considers sufficiently close to the requested - * size or for which the source image would have to be scaled up too - * far. (This maintains sharpness.). This behaviour can be changed by - * passing the %GTK_ICON_LOOKUP_FORCE_SIZE flag, which causes the icon - * to be scaled to the exact size. - * * If the available @icon_name is not available and @fallbacks are provided, * they will be tried in order. * @@ -2763,9 +2717,7 @@ theme_lookup_icon (IconTheme *theme, IconThemeDir *dir = &g_array_index (theme->dirs, IconThemeDir, min_file->dir_index); gchar *filename; - icon = icon_paintable_new (min_dir_size->type, min_dir_size->size, min_dir_size->scale); - icon->min_size = min_dir_size->min_size; - icon->max_size = min_dir_size->max_size; + icon = icon_paintable_new (size, scale); filename = g_strconcat (icon_name, string_from_suffix (min_suffix), NULL); icon->filename = g_build_filename (dir->path, filename, NULL); @@ -3147,69 +3099,23 @@ G_DEFINE_TYPE_WITH_CODE (GtkIconPaintable, gtk_icon_paintable, G_TYPE_OBJECT, static void gtk_icon_paintable_init (GtkIconPaintable *icon) { - icon->scale = -1.; g_mutex_init (&icon->texture_lock); } static GtkIconPaintable * -icon_paintable_new (IconThemeDirType type, - gint dir_size, - gint dir_scale) +icon_paintable_new (int desired_size, + int desired_scale) { GtkIconPaintable *icon; icon = g_object_new (GTK_TYPE_ICON_PAINTABLE, NULL); - icon->dir_type = type; - icon->dir_size = dir_size; - icon->dir_scale = dir_scale; - icon->unscaled_scale = 1.0; - icon->is_svg = FALSE; - icon->is_resource = FALSE; - icon->rendered_size = -1; + icon->desired_size = desired_size; + icon->desired_scale = desired_scale; return icon; } -static void -icon_compute_rendered_size (GtkIconPaintable *icon) -{ - int rendered_size; - - if (icon->forced_size || - icon->dir_type == ICON_THEME_DIR_UNTHEMED) - { - rendered_size = icon->desired_size; - } - else if (icon->dir_type == ICON_THEME_DIR_FIXED || - icon->dir_type == ICON_THEME_DIR_THRESHOLD) - { - rendered_size = icon->dir_size * icon->dir_scale * icon->unscaled_scale / icon->desired_scale; - } - else /* Scalable */ - { - gdouble dir_scale = icon->dir_scale; - gint scaled_desired_size; - - scaled_desired_size = icon->desired_size * icon->desired_scale; - - /* See icon_ensure_scale_and_texture() comment for why we do this */ - if (icon->is_svg) - dir_scale = icon->desired_scale; - - if (scaled_desired_size < icon->min_size * dir_scale) - rendered_size = icon->min_size * dir_scale; - else if (scaled_desired_size > icon->max_size * dir_scale) - rendered_size = icon->max_size * dir_scale; - else - rendered_size = scaled_desired_size; - - rendered_size /= icon->desired_scale; - } - - icon->rendered_size = rendered_size; -} - static void gtk_icon_paintable_finalize (GObject *object) { @@ -3305,14 +3211,12 @@ icon_get_loadable (GtkIconPaintable *icon) * that size. */ static gboolean -icon_ensure_scale_and_texture__locked (GtkIconPaintable *icon, - gboolean in_thread) +icon_ensure_texture__locked (GtkIconPaintable *icon, + gboolean in_thread) { - gint image_width, image_height, image_size; - gint scaled_desired_size; GdkPixbuf *source_pixbuf; - gdouble dir_scale; gint64 before; + gint pixel_size; icon_cache_mark_used_if_cached (icon); @@ -3324,38 +3228,10 @@ icon_ensure_scale_and_texture__locked (GtkIconPaintable *icon, before = g_get_monotonic_time (); - scaled_desired_size = icon->desired_size * icon->desired_scale; - - dir_scale = icon->dir_scale; - - /* In many cases, the scale can be determined without actual access - * to the icon file. This is generally true when we have a size - * for the directory where the icon is; the image size doesn't - * matter in that case. + /* This is the natural pixel size for the requested icon size + scale in this directory. + * We precalculate this so we can use it as a rasterization size for svgs. */ - if (icon->forced_size || - icon->dir_type == ICON_THEME_DIR_UNTHEMED) - icon->scale = -1; - else if (icon->dir_type == ICON_THEME_DIR_FIXED || - icon->dir_type == ICON_THEME_DIR_THRESHOLD) - icon->scale = icon->unscaled_scale; - else if (icon->dir_type == ICON_THEME_DIR_SCALABLE) - { - /* For svg icons, treat scalable directories as if they had - * a Scale= entry. In particular, this means - * spinners that are restriced to size 32 will loaded at size - * up to 64 with Scale=2. - */ - if (icon->is_svg) - dir_scale = icon->desired_scale; - - if (scaled_desired_size < icon->min_size * dir_scale) - icon->scale = (gdouble) icon->min_size / (gdouble) icon->dir_size; - else if (scaled_desired_size > icon->max_size * dir_scale) - icon->scale = (gdouble) icon->max_size / (gdouble) icon->dir_size; - else - icon->scale = (gdouble) scaled_desired_size / (icon->dir_size * dir_scale); - } + pixel_size = icon->desired_size * icon->desired_scale; /* At this point, we need to actually get the icon; either from the * builtin image or by loading the file @@ -3367,33 +3243,19 @@ icon_ensure_scale_and_texture__locked (GtkIconPaintable *icon, { if (icon->is_svg) { - gint size; - - if (icon->forced_size || icon->dir_type == ICON_THEME_DIR_UNTHEMED) - size = scaled_desired_size; - else - size = icon->dir_size * dir_scale * icon->scale; - if (gtk_icon_paintable_is_symbolic (icon)) source_pixbuf = gtk_make_symbolic_pixbuf_from_resource (icon->filename, - size, size, + pixel_size, pixel_size, icon->desired_scale, &icon->load_error); - else if (size == 0) - source_pixbuf = _gdk_pixbuf_new_from_resource_scaled (icon->filename, - "svg", - icon->desired_scale, - &icon->load_error); else source_pixbuf = _gdk_pixbuf_new_from_resource_at_scale (icon->filename, "svg", - size, size, TRUE, - &icon->load_error); + pixel_size, pixel_size, + TRUE, &icon->load_error); } else - source_pixbuf = _gdk_pixbuf_new_from_resource (icon->filename, - "png", - &icon->load_error); + source_pixbuf = _gdk_pixbuf_new_from_resource (icon->filename, "png", &icon->load_error); } else { @@ -3402,7 +3264,7 @@ icon_ensure_scale_and_texture__locked (GtkIconPaintable *icon, loadable = icon_get_loadable (icon); stream = g_loadable_icon_load (loadable, - scaled_desired_size, + pixel_size, NULL, NULL, &icon->load_error); g_object_unref (loadable); @@ -3414,36 +3276,20 @@ icon_ensure_scale_and_texture__locked (GtkIconPaintable *icon, */ if (icon->is_svg) { - gint size; - - if (icon->forced_size || icon->dir_type == ICON_THEME_DIR_UNTHEMED) - size = scaled_desired_size; - else - size = icon->dir_size * dir_scale * icon->scale; - if (gtk_icon_paintable_is_symbolic (icon)) source_pixbuf = gtk_make_symbolic_pixbuf_from_path (icon->filename, - size, size, + pixel_size, pixel_size, icon->desired_scale, &icon->load_error); - else if (size == 0) - source_pixbuf = _gdk_pixbuf_new_from_stream_scaled (stream, - "svg", - icon->desired_scale, - NULL, - &icon->load_error); else source_pixbuf = _gdk_pixbuf_new_from_stream_at_scale (stream, "svg", - size, size, + pixel_size, pixel_size, TRUE, NULL, - &icon->load_error); + &icon->load_error); } else - source_pixbuf = _gdk_pixbuf_new_from_stream (stream, - "png", - NULL, - &icon->load_error); + source_pixbuf = _gdk_pixbuf_new_from_stream (stream, "png", NULL, &icon->load_error); g_object_unref (stream); } } @@ -3473,42 +3319,12 @@ icon_ensure_scale_and_texture__locked (GtkIconPaintable *icon, return FALSE; } - /* Do scale calculations that depend on the image size - */ - image_width = gdk_pixbuf_get_width (source_pixbuf); - image_height = gdk_pixbuf_get_height (source_pixbuf); - image_size = MAX (image_width, image_height); - - if (icon->is_svg) - icon->scale = image_size / 1000.; - else if (icon->scale < 0.0) - { - if (image_size > 0 && scaled_desired_size > 0) - icon->scale = (gdouble)scaled_desired_size / (gdouble)image_size; - else - icon->scale = 1.0; - } - - if (icon->is_svg || - icon->scale == 1.0) - { - icon->texture = gdk_texture_new_for_pixbuf (source_pixbuf); - g_object_unref (source_pixbuf); - } - else - { - GdkPixbuf *scaled = gdk_pixbuf_scale_simple (source_pixbuf, - MAX (1, 0.5 + image_width * icon->scale), - MAX (1, 0.5 + image_height * icon->scale), - GDK_INTERP_BILINEAR); - icon->texture = gdk_texture_new_for_pixbuf (scaled); - g_object_unref (scaled); - g_object_unref (source_pixbuf); - } + /* Actual scaling is done during rendering, so just keep the source pixbuf as a texture */ + icon->texture = gdk_texture_new_for_pixbuf (source_pixbuf); + g_object_unref (source_pixbuf); g_assert (icon->texture != NULL); - if (gdk_profiler_is_running ()) { char *message = g_strdup_printf ("%s size %d@%d", icon->filename, icon->desired_size, icon->desired_scale); @@ -3538,7 +3354,7 @@ gtk_icon_paintable_download_texture (GtkIconPaintable *self, g_mutex_lock (&self->texture_lock); - icon_ensure_scale_and_texture__locked (self, FALSE); + icon_ensure_texture__locked (self, FALSE); if (self->texture) texture = g_object_ref (self->texture); @@ -3632,18 +3448,15 @@ gtk_icon_paintable_snapshot_with_colors (GtkIconPaintable *icon, const GdkRGBA *error_color) { GdkTexture *texture; + int texture_width, texture_height; + double render_width; + double render_height; texture = gtk_icon_paintable_download_texture (icon, NULL); if (texture) { gboolean symbolic = gtk_icon_paintable_is_symbolic (icon); - if (icon->desired_scale != 1) - { - gtk_snapshot_save (snapshot); - gtk_snapshot_scale (snapshot, 1.0 / icon->desired_scale, 1.0 / icon->desired_scale); - } - if (symbolic) { graphene_matrix_t matrix; @@ -3656,15 +3469,31 @@ gtk_icon_paintable_snapshot_with_colors (GtkIconPaintable *icon, gtk_snapshot_push_color_matrix (snapshot, &matrix, &offset); } + texture_width = gdk_texture_get_width (texture); + texture_height = gdk_texture_get_width (texture); + + /* Keep aspect ratio and center */ + if (texture_width >= texture_height) + { + render_width = width; + render_height = height * ((double)texture_height / texture_width); + } + else + { + render_width = width * ((double)texture_width / texture_height); + render_height = height; + } + + gtk_snapshot_append_texture (snapshot, texture, - &GRAPHENE_RECT_INIT (0, 0, width * icon->desired_scale, height * icon->desired_scale)); + &GRAPHENE_RECT_INIT ((width - render_width) / 2, + (height - render_height) / 2, + render_width, + render_width)); if (symbolic) gtk_snapshot_pop (snapshot); - if (icon->desired_scale != 1) - gtk_snapshot_restore (snapshot); - g_object_unref (texture); } } @@ -3681,7 +3510,7 @@ icon_paintable_get_intrinsic_width (GdkPaintable *paintable) { GtkIconPaintable *icon = GTK_ICON_PAINTABLE (paintable); - return icon->rendered_size; + return icon->desired_size; } static int @@ -3689,7 +3518,7 @@ icon_paintable_get_intrinsic_height (GdkPaintable *paintable) { GtkIconPaintable *icon = GTK_ICON_PAINTABLE (paintable); - return icon->rendered_size; + return icon->desired_size; } static void @@ -3703,12 +3532,12 @@ icon_paintable_init (GdkPaintableInterface *iface) static GtkIconPaintable * gtk_icon_paintable_new_for_file (GFile *file, - gint size, - gint scale) + gint size, + gint scale) { GtkIconPaintable *icon; - icon = icon_paintable_new (ICON_THEME_DIR_UNTHEMED, size, 1); + icon = icon_paintable_new (size, scale); icon->loadable = G_LOADABLE_ICON (g_file_icon_new (file)); icon->is_resource = g_file_has_uri_scheme (file, "resource"); @@ -3727,12 +3556,6 @@ gtk_icon_paintable_new_for_file (GFile *file, icon->is_svg = suffix_from_name (icon->filename) == ICON_CACHE_FLAG_SVG_SUFFIX; - icon->desired_size = size; - icon->desired_scale = scale; - icon->forced_size = FALSE; - - icon->rendered_size = size; - return icon; } @@ -3747,12 +3570,8 @@ gtk_icon_paintable_new_for_pixbuf (GtkIconTheme *icon_theme, height = gdk_pixbuf_get_height (pixbuf); max = MAX (width, height); - icon = icon_paintable_new (ICON_THEME_DIR_UNTHEMED, 0, 1); + icon = icon_paintable_new (max, 1); icon->texture = gdk_texture_new_for_pixbuf (pixbuf); - icon->desired_size = max; - icon->desired_scale = 1.0; - icon->scale = 1.0; - icon->rendered_size = max; return icon; } @@ -3790,34 +3609,26 @@ gtk_icon_theme_lookup_by_gicon (GtkIconTheme *self, if (GDK_IS_PIXBUF (gicon)) { GdkPixbuf *pixbuf; + int width, height, max; + double pixbuf_scale; pixbuf = GDK_PIXBUF (gicon); - if ((flags & GTK_ICON_LOOKUP_FORCE_SIZE) != 0) + width = gdk_pixbuf_get_width (pixbuf); + height = gdk_pixbuf_get_height (pixbuf); + max = MAX (width, height); + pixbuf_scale = (gdouble) size * scale / (gdouble) max; + + if (pixbuf_scale != 1.0) { - gint width, height, max; - gdouble pixbuf_scale; + GdkPixbuf *scaled; + scaled = gdk_pixbuf_scale_simple (pixbuf, + 0.5 + width * pixbuf_scale, + 0.5 + height * pixbuf_scale, + GDK_INTERP_BILINEAR); - width = gdk_pixbuf_get_width (pixbuf); - height = gdk_pixbuf_get_height (pixbuf); - max = MAX (width, height); - pixbuf_scale = (gdouble) size * scale / (gdouble) max; - - if (pixbuf_scale != 1.0) - { - GdkPixbuf *scaled; - scaled = gdk_pixbuf_scale_simple (pixbuf, - 0.5 + width * pixbuf_scale, - 0.5 + height * pixbuf_scale, - GDK_INTERP_BILINEAR); - - icon = gtk_icon_paintable_new_for_pixbuf (self, scaled); - g_object_unref (scaled); - } - else - { - icon = gtk_icon_paintable_new_for_pixbuf (self, pixbuf); - } + icon = gtk_icon_paintable_new_for_pixbuf (self, scaled); + g_object_unref (scaled); } else { @@ -3831,18 +3642,14 @@ gtk_icon_theme_lookup_by_gicon (GtkIconTheme *self, GFile *file = g_file_icon_get_file (G_FILE_ICON (gicon)); icon = gtk_icon_paintable_new_for_file (file, size, scale); - icon->forced_size = (flags & GTK_ICON_LOOKUP_FORCE_SIZE) != 0; return icon; } else if (G_IS_LOADABLE_ICON (gicon)) { - icon = icon_paintable_new (ICON_THEME_DIR_UNTHEMED, size, 1); + icon = icon_paintable_new (size, scale); icon->loadable = G_LOADABLE_ICON (g_object_ref (gicon)); icon->is_svg = FALSE; - icon->desired_size = size; - icon->desired_scale = scale; - icon->forced_size = (flags & GTK_ICON_LOOKUP_FORCE_SIZE) != 0; return icon; } diff --git a/gtk/gtkicontheme.h b/gtk/gtkicontheme.h index 97e69d9dfb..5917f5f946 100644 --- a/gtk/gtkicontheme.h +++ b/gtk/gtkicontheme.h @@ -40,8 +40,6 @@ typedef struct _GtkIconTheme GtkIconTheme; /** * GtkIconLookupFlags: - * @GTK_ICON_LOOKUP_FORCE_SIZE: Always get the icon scaled to the - * requested size * @GTK_ICON_LOOKUP_FORCE_REGULAR: Try to always load regular icons, even * when symbolic icon names are given * @GTK_ICON_LOOKUP_FORCE_SYMBOLIC: Try to always load symbolic icons, even @@ -51,9 +49,8 @@ typedef struct _GtkIconTheme GtkIconTheme; */ typedef enum { - GTK_ICON_LOOKUP_FORCE_SIZE = 1 << 0, - GTK_ICON_LOOKUP_FORCE_REGULAR = 1 << 1, - GTK_ICON_LOOKUP_FORCE_SYMBOLIC = 1 << 2 + GTK_ICON_LOOKUP_FORCE_REGULAR = 1 << 0, + GTK_ICON_LOOKUP_FORCE_SYMBOLIC = 1 << 1 } GtkIconLookupFlags; /** diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c index c4e4446728..c296a9777f 100644 --- a/gtk/gtkwindow.c +++ b/gtk/gtkwindow.c @@ -4116,7 +4116,7 @@ gtk_window_get_icon_for_size (GtkWindow *window, info = gtk_icon_theme_lookup_icon (gtk_icon_theme_get_for_display (gtk_widget_get_display (GTK_WIDGET (window))), name, NULL, size, priv->scale, gtk_widget_get_direction (GTK_WIDGET (window)), - GTK_ICON_LOOKUP_FORCE_SIZE); + 0); if (info == NULL) return NULL; diff --git a/testsuite/gtk/icontheme.c b/testsuite/gtk/icontheme.c index a61324e6e1..8fa39b9c0d 100644 --- a/testsuite/gtk/icontheme.c +++ b/testsuite/gtk/icontheme.c @@ -593,24 +593,20 @@ test_symbolic_single_size (void) static void test_svg_size (void) { - /* To understand these results, keep in mind that we never allow upscaling, - * and don't respect min/max size for scaling (though we do take it into - * account for choosing). - */ /* Check we properly load a svg icon from a sized directory */ - assert_icon_lookup_size ("twosize-fixed", 48, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/32x32/twosize-fixed.svg", 32); + assert_icon_lookup_size ("twosize-fixed", 48, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/32x32/twosize-fixed.svg", 48); assert_icon_lookup_size ("twosize-fixed", 32, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/32x32/twosize-fixed.svg", 32); - assert_icon_lookup_size ("twosize-fixed", 20, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/32x32/twosize-fixed.svg", 32); + assert_icon_lookup_size ("twosize-fixed", 20, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/32x32/twosize-fixed.svg", 20); assert_icon_lookup_size ("twosize-fixed", 16, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/16x16/twosize-fixed.svg", 16); /* Check that we still properly load it even if a different size is requested */ - assert_icon_lookup_size ("twosize", 64, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/32x32s/twosize.svg", 48); + assert_icon_lookup_size ("twosize", 64, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/32x32s/twosize.svg", 64); assert_icon_lookup_size ("twosize", 48, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/32x32s/twosize.svg", 48); assert_icon_lookup_size ("twosize", 32, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/32x32s/twosize.svg", 32); assert_icon_lookup_size ("twosize", 24, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/32x32s/twosize.svg", 24); assert_icon_lookup_size ("twosize", 16, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/16x16s/twosize.svg", 16); assert_icon_lookup_size ("twosize", 12, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/16x16s/twosize.svg", 12); - assert_icon_lookup_size ("twosize", 8, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/16x16s/twosize.svg", 12); + assert_icon_lookup_size ("twosize", 8, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/16x16s/twosize.svg", 8); } static void @@ -625,42 +621,21 @@ test_size (void) assert_icon_lookup_size ("size-test", 18, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/16-22/size-test.png", 19); assert_icon_lookup_size ("size-test", 19, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/16-22/size-test.png", 19); /* the next 3 are because we never scale up */ - assert_icon_lookup_size ("size-test", 20, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/25+/size-test.svg", 25); - assert_icon_lookup_size ("size-test", 21, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/25+/size-test.svg", 25); - assert_icon_lookup_size ("size-test", 22, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/25+/size-test.svg", 25); + assert_icon_lookup_size ("size-test", 20, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/25+/size-test.svg", 20); + assert_icon_lookup_size ("size-test", 21, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/25+/size-test.svg", 21); + assert_icon_lookup_size ("size-test", 22, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/25+/size-test.svg", 22); - assert_icon_lookup_size ("size-test", 23, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/25+/size-test.svg", 25); - assert_icon_lookup_size ("size-test", 23, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/25+/size-test.svg", 25); + assert_icon_lookup_size ("size-test", 23, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/25+/size-test.svg", 23); + assert_icon_lookup_size ("size-test", 23, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/25+/size-test.svg", 23); assert_icon_lookup_size ("size-test", 25, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/25+/size-test.svg", 25); assert_icon_lookup_size ("size-test", 28, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/25+/size-test.svg", 28); /* the next 2 are because we never scale up */ - assert_icon_lookup_size ("size-test", 31, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/35+/size-test.svg", 35); - assert_icon_lookup_size ("size-test", 34, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/35+/size-test.svg", 35); + assert_icon_lookup_size ("size-test", 31, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/35+/size-test.svg", 31); + assert_icon_lookup_size ("size-test", 34, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/35+/size-test.svg", 34); assert_icon_lookup_size ("size-test", 37, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/35+/size-test.svg", 37); assert_icon_lookup_size ("size-test", 40, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/35+/size-test.svg", 40); assert_icon_lookup_size ("size-test", 45, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/35+/size-test.svg", 45); - - assert_icon_lookup_size ("size-test", 12, GTK_TEXT_DIR_NONE, GTK_ICON_LOOKUP_FORCE_SIZE, FALSE, "/icons/15/size-test.png", 12); - assert_icon_lookup_size ("size-test", 13, GTK_TEXT_DIR_NONE, GTK_ICON_LOOKUP_FORCE_SIZE, FALSE, "/icons/15/size-test.png", 13); - assert_icon_lookup_size ("size-test", 14, GTK_TEXT_DIR_NONE, GTK_ICON_LOOKUP_FORCE_SIZE, FALSE, "/icons/15/size-test.png", 14); - assert_icon_lookup_size ("size-test", 15, GTK_TEXT_DIR_NONE, GTK_ICON_LOOKUP_FORCE_SIZE, FALSE, "/icons/15/size-test.png", 15); - assert_icon_lookup_size ("size-test", 16, GTK_TEXT_DIR_NONE, GTK_ICON_LOOKUP_FORCE_SIZE, FALSE, "/icons/16-22/size-test.png", 16); - assert_icon_lookup_size ("size-test", 17, GTK_TEXT_DIR_NONE, GTK_ICON_LOOKUP_FORCE_SIZE, FALSE, "/icons/16-22/size-test.png", 17); - assert_icon_lookup_size ("size-test", 18, GTK_TEXT_DIR_NONE, GTK_ICON_LOOKUP_FORCE_SIZE, FALSE, "/icons/16-22/size-test.png", 18); - assert_icon_lookup_size ("size-test", 19, GTK_TEXT_DIR_NONE, GTK_ICON_LOOKUP_FORCE_SIZE, FALSE, "/icons/16-22/size-test.png", 19); - //assert_icon_lookup_size ("size-test", 20, GTK_TEXT_DIR_NONE, GTK_ICON_LOOKUP_FORCE_SIZE, FALSE, "/icons/16-22/size-test.png", 20); - //assert_icon_lookup_size ("size-test", 21, GTK_TEXT_DIR_NONE, GTK_ICON_LOOKUP_FORCE_SIZE, FALSE, "/icons/16-22/size-test.png", 21); - //assert_icon_lookup_size ("size-test", 22, GTK_TEXT_DIR_NONE, GTK_ICON_LOOKUP_FORCE_SIZE, FALSE, "/icons/16-22/size-test.png", 22); - assert_icon_lookup_size ("size-test", 23, GTK_TEXT_DIR_NONE, GTK_ICON_LOOKUP_FORCE_SIZE, FALSE, "/icons/25+/size-test.svg", 23); - assert_icon_lookup_size ("size-test", 24, GTK_TEXT_DIR_NONE, GTK_ICON_LOOKUP_FORCE_SIZE, FALSE, "/icons/25+/size-test.svg", 24); - assert_icon_lookup_size ("size-test", 25, GTK_TEXT_DIR_NONE, GTK_ICON_LOOKUP_FORCE_SIZE, FALSE, "/icons/25+/size-test.svg", 25); - assert_icon_lookup_size ("size-test", 28, GTK_TEXT_DIR_NONE, GTK_ICON_LOOKUP_FORCE_SIZE, FALSE, "/icons/25+/size-test.svg", 28); - //assert_icon_lookup_size ("size-test", 31, GTK_TEXT_DIR_NONE, GTK_ICON_LOOKUP_FORCE_SIZE, FALSE, "/icons/25+/size-test.svg", 31); - //assert_icon_lookup_size ("size-test", 34, GTK_TEXT_DIR_NONE, GTK_ICON_LOOKUP_FORCE_SIZE, FALSE, "/icons/25+/size-test.svg", 34); - assert_icon_lookup_size ("size-test", 37, GTK_TEXT_DIR_NONE, GTK_ICON_LOOKUP_FORCE_SIZE, FALSE, "/icons/35+/size-test.svg", 37); - assert_icon_lookup_size ("size-test", 40, GTK_TEXT_DIR_NONE, GTK_ICON_LOOKUP_FORCE_SIZE, FALSE, "/icons/35+/size-test.svg", 40); - assert_icon_lookup_size ("size-test", 45, GTK_TEXT_DIR_NONE, GTK_ICON_LOOKUP_FORCE_SIZE, FALSE, "/icons/35+/size-test.svg", 45); } static void