gtk_icon_theme_load_icon and GDK_SCALE=2 results in blurry icon

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

gtk_icon_theme_load_icon and GDK_SCALE=2 results in blurry icon

Alexander Shaduri

Hi,

I have a HiDPI Screen with DPI set to 192, GDK_SCALE=2 and GDK_DPI_SCALE=-1.

I need to get an icon as a pixbuf for GtkIconView.

This is the code in gtkmm:
Glib::RefPtr<Gtk::IconTheme> default_icon_theme = Gtk::IconTheme::get_default();
Glib::RefPtr<Gdk::Pixbuf> icon = default_icon_theme->load_icon("drive-harddisk", 64, Gtk::IconLookupFlags(0));

Now matter how I try, I simply cannot get a non-blurry icon. It seems that
GTK+ looks up an icon of size 64, then scales it to 128. I'd like for it to
get a 128-size icon directly.

Specifying 128 as an argument results in a blurry icon of size 256.

Note that without GDK_SCALE=2 I can specify size 128 and get a sharp icon
(there are major artifacts in the GUI though).
I need to support GDK_SCALE=2.
I tried playing with "scale" argument, but that doesn't help.

Note that icons on buttons and in menu appear sharp.

Is there a way to get a sharp icon with gtk_icon_theme_load_icon?

Thanks,
Alexander

_______________________________________________
gtk-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-list
Reply | Threaded
Open this post in threaded view
|

Re: gtk_icon_theme_load_icon and GDK_SCALE=2 results in blurry icon

Stefan Salewski-2
On Tue, 2017-10-03 at 17:28 +0400, Alexander Shaduri wrote:
> I have a HiDPI Screen

I also. 27 inch 4k display. I started also with scale of 2 to avoid
tiny objects, but now I use scale=1 with larger fonts and I use some
custom CSS to make vertical scrollbars a bit larger. Firefox can scale
webpages well, so it is OK for me now.

For your problem:

Have you tried

https://developer.gnome.org/gtk3/stable/GtkIconTheme.html#gtk-icon-theme-load-icon-for-scale

There you will find a reference to

https://developer.gnome.org/gtk3/stable/GtkIconTheme.html#gtk-icon-theme-load-icon-for-scale

where notes about displays with high pixel densities exists.


_______________________________________________
gtk-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-list
Reply | Threaded
Open this post in threaded view
|

Re: gtk_icon_theme_load_icon and GDK_SCALE=2 results in blurry icon

Alexander Shaduri

Hi Stefan,

On Tue, 2017-10-03 at 16:59 +0200, Stefan Salewski wrote:
> Have you tried
>
> https://developer.gnome.org/gtk3/stable/GtkIconTheme.html#gtk-icon-theme-load-icon-for-scale

Yes I have tried gtk_icon_theme_lookup_icon_for_scale().
Passing size=64 and scale=2 to this function results in a blurry icon
of size 256. It seems the icon is scaled twice - once by "scale" and
once
more by GDK_SCALE=2.
Passing scale=1 gets me a blurry 128-size icon.

> There you will find a reference to
>
> https://developer.gnome.org/gtk3/stable/GtkIconTheme.html#gtk-icon-theme-load-icon-for-scale
>
> where notes about displays with high pixel densities exists.

I guess you meant gtk_icon_theme_lookup_icon(). It just says to use
gtk_icon_theme_lookup_icon_for_scale(), which gets me a blurry icon.

Thanks,
Alexander

_______________________________________________
gtk-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-list
LRN
Reply | Threaded
Open this post in threaded view
|

Re: gtk_icon_theme_load_icon and GDK_SCALE=2 results in blurry icon

LRN
In reply to this post by Alexander Shaduri
On 10/3/2017 4:28 PM, Alexander Shaduri wrote:
>
> Now matter how I try, I simply cannot get a non-blurry icon. It seems that
> GTK+ looks up an icon of size 64, then scales it to 128. I'd like for it to
> get a 128-size icon directly.
>
> Specifying 128 as an argument results in a blurry icon of size 256.

Can't rightly say how this could be applied to GdkPixbuf, icons and gtkmm, but
for cairo surfaces you can use cairo_surface_set_device_scale(). This should
prevent the surface from being upscaled. Worked for me.


--
O< ascii ribbon - stop html email! - http://arc.pasp.de/

_______________________________________________
gtk-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-list

0x8DADE9276759BA74.asc (3K) Download Attachment
signature.asc (836 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: gtk_icon_theme_load_icon and GDK_SCALE=2 results in blurry icon

Alexander Shaduri
In reply to this post by Alexander Shaduri

It looks like GDK_SCALE makes GtkIconView scale its icons (the pixbufs).

Glib::RefPtr<Gdk::Pixbuf> hd_icon = default_icon_theme->load_icon("gtk-harddisk", 64, 2, Gtk::IconLookupFlags(0));
This makes a pixbuf of size 128 (the filename points to 128-size png).

However, when this pixbuf is set on a GtkIconView, it's scaled by it,
making the size 256.

Basically, I need a method of disabling GtkIconView's scaling of icons.

Thanks,
Alexander


On Tue, 2017-10-03 at 19:43 +0400, Alexander Shaduri wrote:

> Hi Stefan,
>
> On Tue, 2017-10-03 at 16:59 +0200, Stefan Salewski wrote:
> >
> > Have you tried
> >
> > https://developer.gnome.org/gtk3/stable/GtkIconTheme.html#gtk-icon-theme-load-icon-for-scale
>
> Yes I have tried gtk_icon_theme_lookup_icon_for_scale().
> Passing size=64 and scale=2 to this function results in a blurry icon
> of size 256. It seems the icon is scaled twice - once by "scale" and
> once
> more by GDK_SCALE=2.
> Passing scale=1 gets me a blurry 128-size icon.
>
> >
> > There you will find a reference to
> >
> > https://developer.gnome.org/gtk3/stable/GtkIconTheme.html#gtk-icon-theme-load-icon-for-scale
> >
> > where notes about displays with high pixel densities exists.
>
> I guess you meant gtk_icon_theme_lookup_icon(). It just says to use
> gtk_icon_theme_lookup_icon_for_scale(), which gets me a blurry icon.
>
> Thanks,
> Alexander
_______________________________________________
gtk-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-list
Reply | Threaded
Open this post in threaded view
|

Re: gtk_icon_theme_load_icon and GDK_SCALE=2 results in blurry icon

infirit
In reply to this post by Alexander Shaduri
Op 10/03/2017 om 03:28 PM schreef Alexander Shaduri:
> I have a HiDPI Screen with DPI set to 192, GDK_SCALE=2 and GDK_DPI_SCALE=-1.
>
> I need to get an icon as a pixbuf for GtkIconView.

Short answer, there is no way to do scaling properly with pixbufs. The
only way I found to do this was setting icon names and using cairo surfaces.

> This is the code in gtkmm:
> Glib::RefPtr<Gtk::IconTheme> default_icon_theme = Gtk::IconTheme::get_default();
> Glib::RefPtr<Gdk::Pixbuf> icon = default_icon_theme->load_icon("drive-harddisk", 64, Gtk::IconLookupFlags(0));

As others have mentioned use the _at_scale() version of the icon theme
functions, it handles all the necessary scaling for you. To get the
scale factor use gtk_widget_get_scale_factor on the window/widget.

Another thing to think about is the quality of the icons. I added proper
scaling for a project and found that the a couple of png icons it used
where in only a single size and of low quality. No matter what you do in
this case there is no way to prevent blurry icons.

Internally Gtk handles this transparently as long as use icon-names
instead of pixbufs. I highly recommend you use icon-names whenever
possible and use cairo surfaces if you need to draw over or transform
the icon.

I ended up using gtk_icon_theme_lookup_icon_for_scale and then retrieve
the surface at the very last moment with gtk_icon_info_load_surface.
gtk_icon_info_load_surface also sets the correct scaling factor on the
surface so there is no need to change it with
cairo_surface_set_device_scale. Most widgets will accept the surface
these days and you should start using them.

> Is there a way to get a sharp icon with gtk_icon_theme_load_icon?

Yes I managed it as described above. I have a silly experiment in python
that uses cairo surfaces at [1], maybe this helps. The moment you write
to png and use it as source on a widget things go blurry.

~infirit

[1] https://gist.github.com/infirit/7434371b93cf727f7517c4601df602b9

_______________________________________________
gtk-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-list
Reply | Threaded
Open this post in threaded view
|

Re: gtk_icon_theme_load_icon and GDK_SCALE=2 results in blurry icon

Alexander Shaduri

Hi,

On Tue, 2017-10-03 at 19:32 +0200, infirit wrote:
> Op 10/03/2017 om 03:28 PM schreef Alexander Shaduri:
> >
> > I have a HiDPI Screen with DPI set to 192, GDK_SCALE=2 and GDK_DPI_SCALE=-1.
> >
> > I need to get an icon as a pixbuf for GtkIconView.
>
> Short answer, there is no way to do scaling properly with pixbufs. The
> only way I found to do this was setting icon names and using cairo surfaces.

Unfortunately, GtkIconView expects pixbufs in the model.
I don't see a way to pass cairo surfaces to it.

> > This is the code in gtkmm:
> > Glib::RefPtr<Gtk::IconTheme> default_icon_theme = Gtk::IconTheme::get_default();
> > Glib::RefPtr<Gdk::Pixbuf> icon = default_icon_theme->load_icon("drive-harddisk", 64, Gtk::IconLookupFlags(0));
>
> As others have mentioned use the _at_scale() version of the icon theme
> functions, it handles all the necessary scaling for you. To get the
> scale factor use gtk_widget_get_scale_factor on the window/widget.

Yes, tried that, GtkIconView scales the resulting pixbuf.

> Another thing to think about is the quality of the icons. I added proper
> scaling for a project and found that the a couple of png icons it used
> where in only a single size and of low quality. No matter what you do in
> this case there is no way to prevent blurry icons.

The quality is not an issue here. I can get a sharp 128-size icon when not
using GDK_SCALE=2.

> Internally Gtk handles this transparently as long as use icon-names
> instead of pixbufs. I highly recommend you use icon-names whenever
> possible and use cairo surfaces if you need to draw over or transform
> the icon.
>
> I ended up using gtk_icon_theme_lookup_icon_for_scale and then retrieve
> the surface at the very last moment with gtk_icon_info_load_surface.
> gtk_icon_info_load_surface also sets the correct scaling factor on the
> surface so there is no need to change it with
> cairo_surface_set_device_scale. Most widgets will accept the surface
> these days and you should start using them.

Not GtkIconView, it seems.


> > Is there a way to get a sharp icon with gtk_icon_theme_load_icon?
>
> Yes I managed it as described above. I have a silly experiment in python
> that uses cairo surfaces at [1], maybe this helps. The moment you write
> to png and use it as source on a widget things go blurry.
>
> ~infirit
>
> [1] https://gist.github.com/infirit/7434371b93cf727f7517c4601df602b9

I'm at loss here, I guess this can be viewed as a bug in GtkIconView.


Thanks

_______________________________________________
gtk-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-list
Reply | Threaded
Open this post in threaded view
|

Re: gtk_icon_theme_load_icon and GDK_SCALE=2 results in blurry icon

infirit
Op 10/03/2017 om 07:49 PM schreef Alexander Shaduri:
> I'm at loss here, I guess this can be viewed as a bug in GtkIconView.

It does not support surfaces directly it seems but there is a somewhat
ugly workaround.

See bug 765167 [1] it has an example in python how you can still use a
surface in the GtkIconView.  You should be able to translate this pretty
easily to C/C++.

~infirit

[1] https://bugzilla.gnome.org/show_bug.cgi?id=765167#c5.
_______________________________________________
gtk-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-list
Reply | Threaded
Open this post in threaded view
|

Re: gtk_icon_theme_load_icon and GDK_SCALE=2 results in blurry icon

Alexander Shaduri
Hi,

On Tue, 2017-10-03 at 20:13 +0200, infirit wrote:

> See bug 765167 [1] it has an example in python how you can still use a
> surface in the GtkIconView.  You should be able to translate this pretty
> easily to C/C++.
>
> ~infirit
>
> [1] https://bugzilla.gnome.org/show_bug.cgi?id=765167#c5.

Thanks a lot for the pointer. I was able to translate this into Gtkmm.
This fixes my issue, although I wish GTK would implement a proper
method for doing this.

This is the code, if anyone is interested:

class MainWindowIconView : public Gtk::IconView {
public:

        Gtk::CellRendererPixbuf cell_renderer_pixbuf;  ///< Cell renderer for icons.
        Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf> > col_pixbuf;  ///< Model column
        // ...

        MainWindowIconView()
        {
                // ...
                columns.add(col_pixbuf);

                // For high quality rendering with GDK_SCALE=2
                this->pack_start(cell_renderer_pixbuf, false);
                this->set_cell_data_func(cell_renderer_pixbuf,
                                sigc::mem_fun(this, &MainWindowIconView::on_cell_data_render));
                // ...
        }

        /// Cell data renderer (needed for high quality icons in GDK_SCALE=2).
        /// We have to use Cairo surfaces, because pixbufs are scaled by GtkIconView.
        void on_cell_data_render(const Gtk::TreeModel::const_iterator& iter)
        {
                Gtk::TreeRow row = *iter;
                Glib::RefPtr<Gdk::Pixbuf> pixbuf = row[col_pixbuf];

                // Gtkmm property_surface() doesn't work, so use plain C.
                cairo_surface_t* surface = gdk_cairo_surface_create_from_pixbuf(
                                pixbuf->gobj(), get_scale_factor(), get_window()->gobj());
                g_object_set(G_OBJECT(cell_renderer_pixbuf.gobj()), "surface", surface, NULL);
                cairo_surface_destroy(surface);
        }

        // ...
};



Thanks,
Alexander

_______________________________________________
gtk-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-list