Scale icons during loading to get best quality for e.g. vector images
This commit is contained in:
parent
ab3b5c2805
commit
364bce1ed0
65
src/icon.c
65
src/icon.c
@ -110,16 +110,18 @@ cairo_surface_t *gdk_pixbuf_to_cairo_surface(GdkPixbuf *pixbuf)
|
||||
return icon_surface;
|
||||
}
|
||||
|
||||
GdkPixbuf *icon_pixbuf_scale(GdkPixbuf *pixbuf)
|
||||
{
|
||||
ASSERT_OR_RET(pixbuf, NULL);
|
||||
|
||||
int w = gdk_pixbuf_get_width(pixbuf);
|
||||
int h = gdk_pixbuf_get_height(pixbuf);
|
||||
int landscape = w > h;
|
||||
int orig_larger = landscape ? w : h;
|
||||
/**
|
||||
* Scales the given image dimensions if necessary according to the settings.
|
||||
*
|
||||
* @param w a pointer to the image width, to be modified in-place
|
||||
* @param h a pointer to the image height, to be modified in-place
|
||||
*/
|
||||
static bool icon_size_clamp(int *w, int *h) {
|
||||
int _w = *w, _h = *h;
|
||||
int landscape = _w > _h;
|
||||
int orig_larger = landscape ? _w : _h;
|
||||
double larger = orig_larger;
|
||||
double smaller = landscape ? h : w;
|
||||
double smaller = landscape ? _h : _w;
|
||||
if (settings.min_icon_size && smaller < settings.min_icon_size) {
|
||||
larger = larger / smaller * settings.min_icon_size;
|
||||
smaller = settings.min_icon_size;
|
||||
@ -129,11 +131,35 @@ GdkPixbuf *icon_pixbuf_scale(GdkPixbuf *pixbuf)
|
||||
larger = settings.max_icon_size;
|
||||
}
|
||||
if ((int) larger != orig_larger) {
|
||||
*w = (int) (landscape ? larger : smaller);
|
||||
*h = (int) (landscape ? smaller : larger);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scales the given GdkPixbuf if necessary according to the settings.
|
||||
*
|
||||
* @param pixbuf (nullable) The pixbuf, which may be too big.
|
||||
* Takes ownership of the reference.
|
||||
* @return the scaled version of the pixbuf. If scaling wasn't
|
||||
* necessary, it returns the same pixbuf. Transfers full
|
||||
* ownership of the reference.
|
||||
*/
|
||||
static GdkPixbuf *icon_pixbuf_scale(GdkPixbuf *pixbuf)
|
||||
{
|
||||
ASSERT_OR_RET(pixbuf, NULL);
|
||||
|
||||
int w = gdk_pixbuf_get_width(pixbuf);
|
||||
int h = gdk_pixbuf_get_height(pixbuf);
|
||||
|
||||
if (icon_size_clamp(&w, &h)) {
|
||||
GdkPixbuf *scaled;
|
||||
scaled = gdk_pixbuf_scale_simple(pixbuf,
|
||||
(int) (landscape ? larger : smaller),
|
||||
(int) (landscape ? smaller : larger),
|
||||
GDK_INTERP_BILINEAR);
|
||||
w,
|
||||
h,
|
||||
GDK_INTERP_BILINEAR);
|
||||
g_object_unref(pixbuf);
|
||||
pixbuf = scaled;
|
||||
}
|
||||
@ -145,8 +171,19 @@ GdkPixbuf *get_pixbuf_from_file(const char *filename)
|
||||
{
|
||||
char *path = string_to_path(g_strdup(filename));
|
||||
GError *error = NULL;
|
||||
gint w, h;
|
||||
|
||||
GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(path, &error);
|
||||
if (!gdk_pixbuf_get_file_info (path, &w, &h)) {
|
||||
LOG_W("Failed to load image info for %s", filename);
|
||||
g_error_free(error);
|
||||
return NULL;
|
||||
}
|
||||
icon_size_clamp(&w, &h);
|
||||
GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file_at_scale(path,
|
||||
w,
|
||||
h,
|
||||
TRUE,
|
||||
&error);
|
||||
|
||||
if (error) {
|
||||
LOG_W("%s", error->message);
|
||||
@ -324,6 +361,8 @@ GdkPixbuf *icon_get_for_data(GVariant *data, char **id)
|
||||
g_free(data_chk);
|
||||
g_variant_unref(data_variant);
|
||||
|
||||
pixbuf = icon_pixbuf_scale(pixbuf);
|
||||
|
||||
return pixbuf;
|
||||
}
|
||||
|
||||
|
19
src/icon.h
19
src/icon.h
@ -8,18 +8,7 @@
|
||||
|
||||
cairo_surface_t *gdk_pixbuf_to_cairo_surface(GdkPixbuf *pixbuf);
|
||||
|
||||
/**
|
||||
* Scales the given GdkPixbuf if necessary according to the settings.
|
||||
*
|
||||
* @param pixbuf (nullable) The pixbuf, which may be too big.
|
||||
* Takes ownership of the reference.
|
||||
* @return the scaled version of the pixbuf. If scaling wasn't
|
||||
* necessary, it returns the same pixbuf. Transfers full
|
||||
* ownership of the reference.
|
||||
*/
|
||||
GdkPixbuf *icon_pixbuf_scale(GdkPixbuf *pixbuf);
|
||||
|
||||
/** Retrieve an icon by its full filepath.
|
||||
/** Retrieve an icon by its full filepath, scaled according to settings.
|
||||
*
|
||||
* @param filename A string representing a readable file path
|
||||
*
|
||||
@ -28,7 +17,7 @@ GdkPixbuf *icon_pixbuf_scale(GdkPixbuf *pixbuf);
|
||||
*/
|
||||
GdkPixbuf *get_pixbuf_from_file(const char *filename);
|
||||
|
||||
/** Retrieve an icon by its name sent via the notification bus
|
||||
/** Retrieve an icon by its name sent via the notification bus, scaled according to settings
|
||||
*
|
||||
* @param iconname A string describing a `file://` URL, an arbitary filename
|
||||
* or an icon name, which then gets searched for in the
|
||||
@ -39,7 +28,7 @@ GdkPixbuf *get_pixbuf_from_file(const char *filename);
|
||||
*/
|
||||
GdkPixbuf *get_pixbuf_from_icon(const char *iconname);
|
||||
|
||||
/** Read an icon from disk and convert it to a GdkPixbuf.
|
||||
/** Read an icon from disk and convert it to a GdkPixbuf, scaled according to settings
|
||||
*
|
||||
* The returned id will be a unique identifier. To check if two given
|
||||
* GdkPixbufs are equal, it's sufficient to just compare the id strings.
|
||||
@ -54,7 +43,7 @@ GdkPixbuf *get_pixbuf_from_icon(const char *iconname);
|
||||
*/
|
||||
GdkPixbuf *icon_get_for_name(const char *name, char **id);
|
||||
|
||||
/** Convert a GVariant like described in GdkPixbuf
|
||||
/** Convert a GVariant like described in GdkPixbuf, scaled according to settings
|
||||
*
|
||||
* The returned id will be a unique identifier. To check if two given
|
||||
* GdkPixbufs are equal, it's sufficient to just compare the id strings.
|
||||
|
@ -252,7 +252,6 @@ void notification_icon_replace_path(struct notification *n, const char *new_icon
|
||||
g_clear_pointer(&n->icon_id, g_free);
|
||||
|
||||
n->icon = icon_get_for_name(new_icon, &n->icon_id);
|
||||
n->icon = icon_pixbuf_scale(n->icon);
|
||||
}
|
||||
|
||||
void notification_icon_replace_data(struct notification *n, GVariant *new_icon)
|
||||
@ -264,7 +263,6 @@ void notification_icon_replace_data(struct notification *n, GVariant *new_icon)
|
||||
g_clear_pointer(&n->icon_id, g_free);
|
||||
|
||||
n->icon = icon_get_for_data(new_icon, &n->icon_id);
|
||||
n->icon = icon_pixbuf_scale(n->icon);
|
||||
}
|
||||
|
||||
/* see notification.h */
|
||||
|
Loading…
x
Reference in New Issue
Block a user