GNOME Bugzilla – Bug 728476
GtkImage needs scale API for pixbuf and filename
Last modified: 2018-05-02 16:02:45 UTC
GtkImage is currently lacking an API to start from a file or pixbuf and display a scaled version of the image such that the scale factor is handled in a nice way (ie: not scaling down and then scaling back up again). Presently it seems that the best that you can do is to load a pixbuf from the disk, scale it to the desired (logical) pixel size and then set it. If you have a scale-factor of two then it will be scaled up again. There is an API that accepts a cairo_surface_t instead -- this could be used because cairo surfaces have scale factors, but it would require knowing in advance the proper scale factor to use (and re-rendering onto the surface each time and re-setting it). What would be nice is an API that accepted a filename or a pixbuf along with a desired image size. Then we could do the scaling internally in a hidpi-aware fashion.
It seems that instead of having n copies of the API for loading from pixbuf/filename/animation, maybe it would be better to have just one API to set the desired size. A very easy way to do this would be to use the force_scale_pixbuf mode of GtkIconHelper, but this would only work for square pixbufs. It could also be possible to add a 'forced size' mode to the iconhelper that took separate width and height. Thinking of this, though, it's not clear what the desired behaviour would be. I would guess we want to preserve aspect ratio, but this is not what the existing force_scale_pixbuf mode does...
Created attachment 274640 [details] [review] GtkImage: add "force scale pixbuf" mode This is already supported by the icon helper, but there was no way to access it via public API.
How does this compare to bug 726490 ?
If we got a new widget this could definitely be a part of it. For my part I also notice that asynchronous loading would be nice -- even for local files. Having the load delay until the widget is actually exposed would be nice for (in my case) the list of albums on my computer, with artwork only loaded as I scroll down...
fwiw, I think bug 726490 is higher level than what I want.... things like zoom/pan touch support are definitely outside of my interest here. I just want a static image of a particular (logical) pixel size, at the best possible quality.
Random fly-by comments: (1) I don't think I want GtkImage to expose API that revolves around screen's scale-factor (2) I would like to have a scale-to-fit option on GtkImage that scales every image to fit the size of the image (according to that image's idea of scaling, so SVGs and icons might not just zoom). That way it'd be easy to get an image to any size by using gtk_widget_set_size_request() or CSS.
Review of attachment 274640 [details] [review]: setting status according to the last comment
I would be pretty interested in making this work in GtkImage, even though these days this is less of a problem since the introduction of gtk_icon_theme_add_resource_path(). Benjamin, in your comment you mention that you don't like exposing API in GtkImage that revolves around the screen scale factor, and I agree, but I don't clearly understand how that applies to Ryan's patch. I would actually go one step further than Ryan's patch: why can't pixel-size just work for all the storage types of GtkImage? If pixel-size is not -1, use that, otherwise use icon-size.
That was probably because the docs contained this: + * This is better than scaling the pixbuf for yourself because it will + * prevent downscaling and upscaling again in the case that the screen + * scale factor is greater than 1. And I might have misunderstood it. And I don't like having a mode where the programmer has to set a pixel size. This pixel size is almost guaranteed to be wrong. I mean, what would you want to set it to? (keep in mind you wanna use Glade.) The size of an image is really determined by the theme. In most cases (read: in menus or buttons) you probably want it to be the font size. For some toolbars you may want a pixel size. What I want to see is a mode that sizes the image the same way CSS sizes background-images. See http://dev.w3.org/csswg/css-images-3/#sizing for a complete description. In short: Request 1x1 minimum size. Request as natural size the intrinsic size of the pixbuf/animation/surface or 1x1 for icon names. In hfw/wfh requests, try to keep the aspect ratio. Combined with min-width/min-height support in CSS, it should give us exactly what we want.
(In reply to Benjamin Otte (Company) from comment #9) > And I don't like having a mode where the programmer has to set a pixel size. > This pixel size is almost guaranteed to be wrong. I mean, what would you > want to set it to? (keep in mind you wanna use Glade.) > > The size of an image is really determined by the theme. In most cases (read: > in menus or buttons) you probably want it to be the font size. For some > toolbars you may want a pixel size. I agree with you that in most cases that is what you want. I don't setting the pixel size to be the most common use case. Sometimes though, you really want to use an asset in an application that is not part of the theme (is private to the app) and that you can't install directly at the right size (e.g. because it's used in multiple places at different sizes). GtkImage would be the perfect fit for this, except that it won't scale non icon-name images...
Another argument is that having pixel-size work for some storage types but not for others is really confusing for app developers.
I'd still argue that pixel size shouldn't exist, because people will set it to a value that doesn't work with custom themes or custom font sizes and so on. I'm also not sure what use case you have in mind here. Do you want to force scaling of a custom-installed icon to make it blurry?
(In reply to Benjamin Otte (Company) from comment #12) > I'd still argue that pixel size shouldn't exist, because people will set it > to a value that doesn't work with custom themes or custom font sizes and so > on. The pixel-size property does exist for a reason though - because some times those concerns do not apply and all you want is a GtkImage of just the right size. > I'm also not sure what use case you have in mind here. Do you want to force > scaling of a custom-installed icon to make it blurry? It won't be blurry if it's an SVG...
(In reply to Cosimo Cecchi from comment #13) > The pixel-size property does exist for a reason though - because some times > those concerns do not apply and all you want is a GtkImage of just the right > size. > I honestly can't see a single place where you'd want an icon to be too small or too big for the theme. Could you give an example? > It won't be blurry if it's an SVG... > But those cases would work with my proposal because GtkImage would just load the image at the allocated size.
(In reply to Benjamin Otte (Company) from comment #14) > I honestly can't see a single place where you'd want an icon to be too small > or too big for the theme. Could you give an example? Sure; think of a 10px emblem representing a status (e.g. starred) on top of an image corner (e.g. a thumbnail) in an application overview, which also shows a larger version (say 32px) of that emblem in an overlay in the middle of the thumbnail when it's hovered. > But those cases would work with my proposal because GtkImage would just load > the image at the allocated size. How would an application achieve the above with your proposal?
(In reply to Cosimo Cecchi from comment #15) > Sure; think of a 10px emblem representing a status (e.g. starred) on top of > an image corner (e.g. a thumbnail) in an application overview, which also > shows a larger version (say 32px) of that emblem in an overlay in the > middle of the thumbnail when it's hovered. > You'd not do that with a single GtkImage though? Because it sounds like your container would move the GtkImage objects around and size them to 10px or 32px respsectively. > How would an application achieve the above with your proposal? You'd create the image, set your icon-name and the scale-to-fit property and then - depending on if you want theme or parent container to do the sizing, you'd either set min-width/height to your size or you'd size_allocate() it your size from the parent.
(In reply to Benjamin Otte (Company) from comment #16) > You'd not do that with a single GtkImage though? Because it sounds like your > container would move the GtkImage objects around and size them to 10px or > 32px respsectively. Right, those would be two separate GtkImage objects pointing to the same underlying image on disk. > You'd create the image, set your icon-name and the scale-to-fit property and > then - depending on if you want theme or parent container to do the sizing, > you'd either set min-width/height to your size or you'd size_allocate() it > your size from the parent. The whole problem is that the underlying image is not part of the theme - or I would be able to use pixel-size today to achieve this, since it works for named icons already. A scale-to-fit property would work and is effectively equivalent to my proposal, since I would be able to then use e.g. gtk_widget_set_size_request() to size it. I was just thinking that re-using the existing pixel-size property would fit better with this model.
Wait. If it's not part of the theme already, why don't you just load it in the correct size before setting it? Are you currently using set_from_file() and want that to be scaled? Because I could probably be convinced to use pixel-size in on_loader_size_prepared() for scalable files.
(In reply to Benjamin Otte (Company) from comment #18) > Wait. If it's not part of the theme already, why don't you just load it in > the correct size before setting it? Because that's hard/complicated to do, especially taking into account things like the scale factor - hence Ryan's patch :-) > Are you currently using set_from_file() and want that to be scaled? Because > I could probably be convinced to use pixel-size in on_loader_size_prepared() > for scalable files. Yes, that's what I'm doing (well, I was using set_from_resource() but that's equivalent), and I also would expect pixel-size to work in that scenario.
*** Bug 750702 has been marked as a duplicate of this bug. ***
We're moving to gitlab! As part of this move, we are moving bugs to NEEDINFO if they haven't seen activity in more than a year. If this issue is still important to you and still relevant with GTK+ 3.22 or master, please reopen it and we will migrate it to gitlab.
Reopening so that a final ack/nack decision can be made.
-- GitLab Migration Automatic Message -- This bug has been migrated to GNOME's GitLab instance and has been closed from further activity. You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.gnome.org/GNOME/gtk/issues/483.