Add SVG icon scaling/rendering preferences
authorRicardo Mones <ricardo@mones.org>
Tue, 31 Jan 2017 23:27:19 +0000 (00:27 +0100)
committerRicardo Mones <ricardo@mones.org>
Tue, 7 Feb 2017 19:02:58 +0000 (20:02 +0100)
• 'enable_alpha_svg' to use alpha channel when rendering
• 'enable_pixmap_scaling' to bypass SVG's own natural size
• 'pixmap_scaling_auto' to compute a PPI or use a user defined value
• 'pixmap_scaling_ppi' to set a user defined value for PPI

src/common/defs.h
src/prefs_common.c
src/prefs_common.h
src/stock_pixmap.c

index 4c4fd39..5ab20e6 100644 (file)
 
 #define DEFAULT_PIXMAP_THEME   "INTERNAL_DEFAULT"
 #define PIXMAP_THEME_DIR               "themes"
+#ifdef HAVE_SVG
+#define MIN_PPI 96
+#define MAX_PPI 300
+#endif
 
 #define AVATAR_NONE    0
 #define AVATAR_XFACE   1
index 7be13c4..66b1b38 100644 (file)
@@ -121,6 +121,16 @@ static PrefParam param_os_specific[] = {
        /* Interface */
        {"pixmap_theme_path", DEFAULT_PIXMAP_THEME, 
         &prefs_common.pixmap_theme_path, P_STRING, NULL, NULL, NULL},
+#ifdef HAVE_SVG
+       {"enable_alpha_svg", "TRUE",
+        &prefs_common.enable_alpha_svg, P_BOOL, NULL, NULL, NULL},
+       {"enable_pixmap_scaling", "TRUE",
+        &prefs_common.enable_pixmap_scaling, P_BOOL, NULL, NULL, NULL},
+       {"pixmap_scaling_auto", "TRUE",
+        &prefs_common.pixmap_scaling_auto, P_BOOL, NULL, NULL, NULL},
+       {"pixmap_scaling_ppi", "96",
+        &prefs_common.pixmap_scaling_ppi, P_INT, NULL, NULL, NULL},
+#endif
 
        /* Other */
        {"ext_editor_command", "notepad %s",
@@ -838,6 +848,20 @@ static PrefParam param[] = {
        {"pixmap_theme_path", DEFAULT_PIXMAP_THEME, 
         &SPECIFIC_PREFS.pixmap_theme_path, P_STRING,
         NULL, NULL, NULL},
+#ifdef HAVE_SVG
+       {"enable_alpha_svg", "TRUE",
+        &SPECIFIC_PREFS.enable_alpha_svg, P_BOOL,
+        NULL, NULL, NULL},
+       {"enable_pixmap_scaling", "TRUE",
+        &SPECIFIC_PREFS.enable_pixmap_scaling, P_BOOL,
+        NULL, NULL, NULL},
+       {"pixmap_scaling_auto", "TRUE",
+        &SPECIFIC_PREFS.pixmap_scaling_auto, P_BOOL,
+        NULL, NULL, NULL},
+       {"pixmap_scaling_ppi", "96",
+        &SPECIFIC_PREFS.pixmap_scaling_ppi, P_INT,
+        NULL, NULL, NULL},
+#endif
 
        {"ask_mark_all_read", "TRUE", &prefs_common.ask_mark_all_read, P_BOOL,
         NULL, NULL, NULL},
index 467ecdd..179e163 100644 (file)
@@ -385,6 +385,12 @@ struct _PrefsCommon
        SummaryFromShow summary_from_show;
        gboolean add_address_by_click;
        gchar *pixmap_theme_path;
+#ifdef HAVE_SVG
+       gboolean enable_alpha_svg;
+       gboolean enable_pixmap_scaling;
+       gboolean pixmap_scaling_auto;
+       gint pixmap_scaling_ppi;
+#endif
        int hover_timeout; /* msecs mouse hover timeout */
        gboolean ask_mark_all_read;
        gboolean ask_apply_per_account_filtering_rules;
index 3a59a36..fcaa79e 100644 (file)
@@ -26,6 +26,9 @@
 #include <librsvg/rsvg.h>
 #include <string.h>
 #include <dirent.h>
+#ifdef HAVE_SVG
+#include <math.h>
+#endif
 
 #include "defs.h"
 #include "stock_pixmap.h"
@@ -614,11 +617,6 @@ GdkPixbuf *pixbuf_from_svg_like_icon(char *filename, GError **error, StockPixmap
        cm_return_val_if_fail(filename != NULL, NULL);
        cm_return_val_if_fail(icondata != NULL, NULL);
 
-       if (sscanf((icondata->data)[0], "%d %d ", &width, &height) != 2) {
-               g_warning("failed reading icondata width and height");
-               return NULL;
-       }
-
        /* load SVG file */
        handle = rsvg_handle_new_from_file(filename, error);
        if (handle == NULL) {
@@ -626,6 +624,28 @@ GdkPixbuf *pixbuf_from_svg_like_icon(char *filename, GError **error, StockPixmap
                                (*error)->message, (*error)->code);
                return NULL;
        }
+
+       /* scale dimensions */
+       if (prefs_common.enable_pixmap_scaling) {
+               /* default is pixmap icon size */
+               if (sscanf((icondata->data)[0], "%d %d ", &width, &height) != 2) {
+                       g_warning("failed reading icondata width and height");
+                       return NULL;
+               }
+               /* which can be modified by some factor */
+               if (prefs_common.pixmap_scaling_ppi > 0) {
+                       gdouble factor = (gdouble) prefs_common.pixmap_scaling_ppi / MIN_PPI;
+                       width = (int) floor(factor * width);
+                       height = (int) floor(factor * height);
+               }
+       } else { /* render using SVG size */
+               RsvgDimensionData dimension;
+
+               rsvg_handle_get_dimensions (handle, &dimension);
+               width = dimension.width;
+               height = dimension.height;
+       }
+
        /* create drawing context */
        surface = cairo_image_surface_create(
                        alpha? CAIRO_FORMAT_ARGB32: CAIRO_FORMAT_RGB24,
@@ -689,7 +709,8 @@ try_next_extension:
                                        GError *err = NULL;
 #ifdef HAVE_SVG
                                        if (!strncmp(extension[i], ".svg", 4)) {
-                                               pix = pixbuf_from_svg_like_icon(icon_file_name, &err, pix_d, TRUE);
+                                               pix = pixbuf_from_svg_like_icon(icon_file_name, &err, pix_d,
+                                                               prefs_common.enable_alpha_svg);
                                        } else {
                                                pix = gdk_pixbuf_new_from_file(icon_file_name, &err);
                                        }