[Commits] [SCM] claws branch, master, updated. 3.14.1-187-g1ef7efb
mones at claws-mail.org
mones at claws-mail.org
Tue Feb 7 20:03:11 CET 2017
The branch, master has been updated
via 1ef7efbc70643f8709b3b8d081fab949b808a296 (commit)
via 89eb1e67c5e46464e0c12256af6c8b15a3d32bae (commit)
via 427ba2698e8a780c61597357cbe05a37c0946cff (commit)
via db434c2b05aec33ca6c3cc4fda792d40cf34942c (commit)
via cdf48fc3e9ce71ef09c0b9ddbdf7057f6d36e6da (commit)
from 7906fba208f469e0d26e349fab157a1db7a30116 (commit)
Summary of changes:
claws-features.h.in | 1 +
configure.ac | 24 +++++++
src/Makefile.am | 2 +
src/common/defs.h | 4 ++
src/gtk/about.c | 10 +++
src/prefs_common.c | 24 +++++++
src/prefs_common.h | 6 ++
src/prefs_themes.c | 198 +++++++++++++++++++++++++++++++++++++++++++++++++++
src/stock_pixmap.c | 190 ++++++++++++++++++++++++++++++++++++++++++++++++
9 files changed, 459 insertions(+)
- Log -----------------------------------------------------------------
commit 1ef7efbc70643f8709b3b8d081fab949b808a296
Author: Ricardo Mones <ricardo at mones.org>
Date: Tue Feb 7 00:56:29 2017 +0100
User interface for SVG preferences
diff --git a/src/prefs_themes.c b/src/prefs_themes.c
index 1d24f18..fc81582 100644
--- a/src/prefs_themes.c
+++ b/src/prefs_themes.c
@@ -26,6 +26,9 @@
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
+#ifdef HAVE_SVG
+#include <math.h>
+#endif
#include <glib.h>
#include <glib/gi18n.h>
@@ -73,6 +76,14 @@ typedef struct _ThemesPage
GtkWidget *btn_remove;
GdkPixbuf *pixbufs[PREVIEW_ICONS];
+
+#ifdef HAVE_SVG
+ GtkWidget *checkbtn_enable_alpha;
+ GtkWidget *checkbtn_enable_scaling;
+ GtkWidget *checkbtn_scaling_auto;
+ GtkWidget *label_scaling_ppi;
+ GtkWidget *spinbtn_scaling_ppi;
+#endif
} ThemesPage;
typedef struct _ThemeInfo
@@ -130,6 +141,12 @@ StockPixmap prefs_themes_icons[PREVIEW_ICONS] = {
static void prefs_themes_btn_remove_clicked_cb (GtkWidget *widget, gpointer data);
static void prefs_themes_btn_install_clicked_cb (GtkWidget *widget, gpointer data);
static void prefs_themes_menu_item_activated_cb (GtkWidget *widget, gpointer data);
+#ifdef HAVE_SVG
+static gdouble prefs_themes_compute_ppi(GdkScreen *screen);
+static gdouble prefs_themes_get_adjusted_ppi(void);
+static void prefs_themes_checkbtn_enable_scaling_toggled_cb (GtkWidget *widget, gpointer data);
+static void prefs_themes_checkbtn_scaling_auto_toggled_cb (GtkWidget *widget, gpointer data);
+#endif
static void prefs_themes_update_buttons (const ThemesData *tdata);
static void prefs_themes_display_global_stats (const ThemesData *tdata);
@@ -394,6 +411,10 @@ void prefs_themes_init(void)
tpaths = g_list_first(tdata->themes);
if (tdata->displayed == NULL)
tdata->displayed = (gchar *)(tpaths->data);
+#ifdef HAVE_SVG
+ if (prefs_common.pixmap_scaling_auto)
+ prefs_common.pixmap_scaling_ppi = prefs_themes_get_adjusted_ppi();
+#endif
}
static void prefs_themes_free_names(ThemesData *tdata)
@@ -598,6 +619,78 @@ static void prefs_themes_menu_item_activated_cb(GtkWidget *widget, gpointer data
prefs_themes_get_theme_info(tdata);
}
+#ifdef HAVE_SVG
+#define MM_INCH 0.0393700787402
+static gdouble prefs_themes_compute_ppi(GdkScreen *screen)
+{
+ gdouble wp = gdk_screen_get_width(screen);
+ gdouble hp = gdk_screen_get_height(screen);
+ gdouble wi = gdk_screen_get_width_mm(screen);
+ gdouble hi = gdk_screen_get_height_mm(screen);
+ gdouble dp, di;
+
+ debug_print("screen is %f x %f pixels, %f x %f mm\n", wp, hp, wi, hi);
+
+ /* https://en.wikipedia.org/wiki/Pixel_density */
+ wi *= MM_INCH;
+ hi *= MM_INCH;
+ dp = sqrt(wp * wp + hp * hp);
+ di = sqrt(wi * wi + hi * hi);
+
+ return (di != 0.0)? dp / di: 0.0;
+}
+
+static gdouble prefs_themes_get_adjusted_ppi(void)
+{
+ gdouble ppi, cppi;
+ GdkScreen * screen = gdk_screen_get_default();
+
+ if (screen == NULL) { /* oops! */
+ g_warning("unable to get default GDK screen");
+ return MIN_PPI;
+ }
+
+ ppi = gdk_screen_get_resolution(screen);
+ cppi = prefs_themes_compute_ppi(screen);
+ debug_print("returned PPI: %f / computed PPI: %f\n", ppi, cppi);
+ /*
+ gdk_screen_get_resolution doesn't seem to work well when running
+ on a remote display and returns the value of the local display.
+ height/width functions do this better, so we can compute a PPI
+ from them and take the highest value.
+ */
+ return MAX(ppi, cppi);
+}
+
+static void prefs_themes_checkbtn_enable_scaling_toggled_cb (GtkWidget *widget, gpointer data)
+{
+ ThemesPage *page = (ThemesPage *) data;
+ gboolean enabled = gtk_toggle_button_get_active(
+ GTK_TOGGLE_BUTTON (widget));
+ gboolean automatic = gtk_toggle_button_get_active(
+ GTK_TOGGLE_BUTTON (page->checkbtn_scaling_auto));
+
+ gtk_widget_set_sensitive(page->checkbtn_scaling_auto, enabled);
+ gtk_widget_set_sensitive(page->spinbtn_scaling_ppi, enabled && !automatic);
+ gtk_widget_set_sensitive(page->label_scaling_ppi, enabled && !automatic);
+}
+
+static void prefs_themes_checkbtn_scaling_auto_toggled_cb(GtkWidget *widget, gpointer data)
+{
+ ThemesPage *page = (ThemesPage *) data;
+ gboolean automatic = gtk_toggle_button_get_active(
+ GTK_TOGGLE_BUTTON (widget));
+
+ gtk_widget_set_sensitive(page->spinbtn_scaling_ppi, !automatic);
+ gtk_widget_set_sensitive(page->label_scaling_ppi, !automatic);
+
+ if (automatic) /* update PPI value */
+ gtk_spin_button_set_value(
+ GTK_SPIN_BUTTON (page->spinbtn_scaling_ppi),
+ prefs_themes_get_adjusted_ppi());
+}
+#endif
+
static void prefs_themes_update_buttons(const ThemesData *tdata)
{
ThemesPage *theme = tdata->page;
@@ -809,6 +902,15 @@ static void prefs_themes_create_widget(PrefsPage *page, GtkWindow *window, gpoin
GtkWidget *hbuttonbox1;
GtkWidget *btn_remove;
GtkCellRenderer *renderer;
+#ifdef HAVE_SVG
+ GtkWidget *frame_scaling;
+ GtkWidget *checkbtn_enable_alpha;
+ GtkWidget *checkbtn_enable_scaling;
+ GtkWidget *checkbtn_scaling_auto;
+ GtkWidget *label_scaling_ppi;
+ GtkWidget *spinbtn_scaling_ppi;
+ GtkAdjustment *spinbtn_scaling_ppi_adj;
+#endif
vbox1 = gtk_vbox_new (FALSE, VSPACING);
gtk_container_set_border_width (GTK_CONTAINER (vbox1), VBOX_BORDER);
@@ -960,6 +1062,65 @@ static void prefs_themes_create_widget(PrefsPage *page, GtkWindow *window, gpoin
gtk_container_add (GTK_CONTAINER (hbuttonbox1), btn_remove);
gtkut_widget_set_can_default (btn_remove, TRUE);
+#ifdef HAVE_SVG
+ PACK_FRAME(vbox1, frame_scaling, _("SVG rendering"));
+
+ vbox2 = gtk_vbox_new (FALSE, VSPACING);
+ gtk_widget_show (vbox2);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox2), 5);
+ gtk_container_add (GTK_CONTAINER (frame_scaling), vbox2);
+
+ PACK_CHECK_BUTTON(vbox2, checkbtn_enable_alpha, _("Enable alpha channel"));
+ PACK_CHECK_BUTTON(vbox2, checkbtn_enable_scaling, _("Force scaling"));
+ PACK_CHECK_BUTTON(vbox2, checkbtn_scaling_auto, _("Automatic"));
+
+ hbox3 = gtk_hbox_new (FALSE, 5);
+ gtk_widget_show (hbox3);
+
+ label_scaling_ppi = gtk_label_new (_("Pixels per inch (PPI)"));
+ gtk_widget_show (label_scaling_ppi);
+ gtk_box_pack_start (GTK_BOX (hbox3), label_scaling_ppi,
+ FALSE, FALSE, 5);
+
+ spinbtn_scaling_ppi_adj = GTK_ADJUSTMENT(
+ gtk_adjustment_new (MIN_PPI, MIN_PPI, MAX_PPI, 1, 10, 0));
+ spinbtn_scaling_ppi = gtk_spin_button_new(
+ spinbtn_scaling_ppi_adj, 1.0, 0);
+ gtk_widget_show (spinbtn_scaling_ppi);
+ gtk_box_pack_start (GTK_BOX (hbox3), spinbtn_scaling_ppi,
+ FALSE, FALSE, 5);
+
+ gtk_box_pack_start (GTK_BOX (vbox2), hbox3, FALSE, FALSE, 0);
+
+ /* initialize widget values */
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (checkbtn_enable_alpha),
+ prefs_common.enable_alpha_svg);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (checkbtn_enable_scaling),
+ prefs_common.enable_pixmap_scaling);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (checkbtn_scaling_auto),
+ prefs_common.pixmap_scaling_auto);
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON (spinbtn_scaling_ppi),
+ prefs_common.pixmap_scaling_ppi);
+
+ /* sensitivity */
+ gtk_widget_set_sensitive(checkbtn_scaling_auto,
+ prefs_common.enable_pixmap_scaling);
+ gtk_widget_set_sensitive(spinbtn_scaling_ppi,
+ prefs_common.enable_pixmap_scaling
+ && !prefs_common.pixmap_scaling_auto);
+ gtk_widget_set_sensitive(label_scaling_ppi,
+ prefs_common.enable_pixmap_scaling
+ && !prefs_common.pixmap_scaling_auto);
+
+ /* signals */
+ g_signal_connect(G_OBJECT(checkbtn_enable_scaling), "toggled",
+ G_CALLBACK(prefs_themes_checkbtn_enable_scaling_toggled_cb),
+ prefs_themes);
+ g_signal_connect(G_OBJECT(checkbtn_scaling_auto), "toggled",
+ G_CALLBACK(prefs_themes_checkbtn_scaling_auto_toggled_cb),
+ prefs_themes);
+#endif
+
g_signal_connect(G_OBJECT(btn_remove), "clicked",
G_CALLBACK(prefs_themes_btn_remove_clicked_cb),
NULL);
@@ -989,6 +1150,14 @@ static void prefs_themes_create_widget(PrefsPage *page, GtkWindow *window, gpoin
prefs_themes->op_menu = menu_themes;
+#ifdef HAVE_SVG
+ prefs_themes->checkbtn_enable_alpha = checkbtn_enable_alpha;
+ prefs_themes->checkbtn_enable_scaling = checkbtn_enable_scaling;
+ prefs_themes->checkbtn_scaling_auto = checkbtn_scaling_auto;
+ prefs_themes->label_scaling_ppi = label_scaling_ppi;
+ prefs_themes->spinbtn_scaling_ppi = spinbtn_scaling_ppi;
+#endif
+
prefs_themes->page.widget = vbox1;
prefs_themes_set_themes_menu(GTK_COMBO_BOX(menu_themes), tdata);
@@ -1010,6 +1179,22 @@ static void prefs_themes_save(PrefsPage *page)
{
ThemesData *tdata = prefs_themes_data;
gchar *theme_str = tdata->displayed;
+#ifdef HAVE_SVG
+ ThemesPage *tpage = (ThemesPage *) page;
+ gboolean alpha = prefs_common.enable_alpha_svg;
+ gboolean scaling = prefs_common.enable_pixmap_scaling;
+ gboolean scaling_auto = prefs_common.pixmap_scaling_auto;
+ gint scaling_ppi = prefs_common.pixmap_scaling_ppi;
+
+ prefs_common.enable_alpha_svg = gtk_toggle_button_get_active(
+ GTK_TOGGLE_BUTTON (tpage->checkbtn_enable_alpha));
+ prefs_common.enable_pixmap_scaling = gtk_toggle_button_get_active(
+ GTK_TOGGLE_BUTTON (tpage->checkbtn_enable_scaling));
+ prefs_common.pixmap_scaling_auto = gtk_toggle_button_get_active(
+ GTK_TOGGLE_BUTTON (tpage->checkbtn_scaling_auto));
+ prefs_common.pixmap_scaling_ppi = gtk_spin_button_get_value_as_int (
+ GTK_SPIN_BUTTON (tpage->spinbtn_scaling_ppi));
+#endif
if (!IS_CURRENT_THEME(theme_str)) {
debug_print("Changing theme to %s\n", theme_str);
@@ -1023,5 +1208,18 @@ static void prefs_themes_save(PrefsPage *page)
prefs_themes_update_buttons(tdata);
}
+#ifdef HAVE_SVG
+ else if (scaling != prefs_common.enable_pixmap_scaling
+ || alpha != prefs_common.enable_alpha_svg
+ || (scaling_auto != prefs_common.pixmap_scaling_auto
+ && scaling_ppi != prefs_common.pixmap_scaling_ppi)) {
+ /* same theme, different scaling options */
+ debug_print("Updating theme scaling\n");
+
+ main_window_reflect_prefs_all_real(FALSE);
+ compose_reflect_prefs_pixmap_theme();
+ addrcompl_reflect_prefs_pixmap_theme();
+ }
+#endif
}
commit 89eb1e67c5e46464e0c12256af6c8b15a3d32bae
Author: Ricardo Mones <ricardo at mones.org>
Date: Wed Feb 1 00:27:19 2017 +0100
Add SVG icon scaling/rendering preferences
• '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
diff --git a/src/common/defs.h b/src/common/defs.h
index 4c4fd39..5ab20e6 100644
--- a/src/common/defs.h
+++ b/src/common/defs.h
@@ -172,6 +172,10 @@
#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
diff --git a/src/prefs_common.c b/src/prefs_common.c
index 7be13c4..66b1b38 100644
--- a/src/prefs_common.c
+++ b/src/prefs_common.c
@@ -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},
diff --git a/src/prefs_common.h b/src/prefs_common.h
index 467ecdd..179e163 100644
--- a/src/prefs_common.h
+++ b/src/prefs_common.h
@@ -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;
diff --git a/src/stock_pixmap.c b/src/stock_pixmap.c
index 3a59a36..fcaa79e 100644
--- a/src/stock_pixmap.c
+++ b/src/stock_pixmap.c
@@ -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);
}
commit 427ba2698e8a780c61597357cbe05a37c0946cff
Author: Ricardo Mones <ricardo at mones.org>
Date: Mon Jan 30 23:22:20 2017 +0100
Render SVG scaled to default icon size
Default icon sizes are parsed from icon data, which is suboptimal
since these sizes can be known at compile time.
diff --git a/src/stock_pixmap.c b/src/stock_pixmap.c
index 947b2e6..3a59a36 100644
--- a/src/stock_pixmap.c
+++ b/src/stock_pixmap.c
@@ -494,6 +494,163 @@ GtkWidget *stock_pixmap_widget(StockPixmap icon)
return NULL;
}
+#ifdef HAVE_SVG
+/*
+ * Renders a SVG into a Cairo context at the given dimensions keeping
+ * the aspect ratio.
+ *
+ * Adapted from https://developer.gnome.org/rsvg/2.40/RsvgHandle.html
+ * #rsvg-handle-set-size-callback
+ */
+void render_scaled_proportionally(RsvgHandle *handle, cairo_t *cr, int width, int height)
+{
+ RsvgDimensionData dimensions;
+ double x_factor, y_factor;
+ double scale_factor;
+
+ rsvg_handle_get_dimensions(handle, &dimensions);
+
+ x_factor = (double) width / dimensions.width;
+ y_factor = (double) height / dimensions.height;
+
+ scale_factor = MIN(x_factor, y_factor);
+
+ cairo_scale(cr, scale_factor, scale_factor);
+
+ rsvg_handle_render_cairo(handle, cr);
+}
+
+/*
+ * Generates a new Pixbuf from a Cairo context of the given dimensions.
+ *
+ * Adapted from https://gist.github.com/bert/985903
+ */
+GdkPixbuf *pixbuf_from_cairo(cairo_t *cr, gboolean alpha, int width, int height)
+{
+ gint p_stride, /* Pixbuf stride value */
+ p_n_channels, /* RGB -> 3, RGBA -> 4 */
+ s_stride; /* Surface stride value */
+ guchar *p_pixels, /* Pixbuf's pixel data */
+ *s_pixels; /* Surface's pixel data */
+ cairo_surface_t *surface; /* Temporary image surface */
+ GdkPixbuf *pixbuf; /* Returned pixbuf */
+
+ /* Create pixbuf */
+ pixbuf = gdk_pixbuf_new
+ (GDK_COLORSPACE_RGB, alpha, 8, width, height);
+ if (pixbuf == NULL) {
+ g_warning("failed to create a new %d x %d pixbuf", width, height);
+ return NULL;
+ }
+ /* Obtain surface from where pixel values will be copied */
+ surface = cairo_get_target(cr);
+ if (cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) {
+ g_warning("invalid cairo surface for copying");
+ return NULL;
+ }
+ /* Inspect pixbuf */
+ g_object_get(G_OBJECT(pixbuf),
+ "rowstride", &p_stride,
+ "n-channels", &p_n_channels,
+ "pixels", &p_pixels,
+ NULL);
+ /* and surface */
+ s_stride = cairo_image_surface_get_stride(surface);
+ s_pixels = cairo_image_surface_get_data(surface);
+
+ /* Copy pixel data from surface to pixbuf */
+ while (height--) {
+ gint i;
+ guchar *p_iter = p_pixels, *s_iter = s_pixels;
+ for (i = 0; i < width; i++) {
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+ /* Pixbuf: RGB(A) - Surface: BGRA */
+ gdouble alpha_factor = (gdouble)0xff / s_iter[3];
+ p_iter[0] = (guchar)( s_iter[2] * alpha_factor + .5 );
+ p_iter[1] = (guchar)( s_iter[1] * alpha_factor + .5 );
+ p_iter[2] = (guchar)( s_iter[0] * alpha_factor + .5 );
+ if (p_n_channels == 4)
+ p_iter[3] = s_iter[3];
+#elif G_BYTE_ORDER == G_BIG_ENDIAN
+ /* Pixbuf: RGB(A) - Surface: ARGB */
+ gdouble alpha_factor = (gdouble)0xff / s_iter[0];
+ p_iter[0] = (guchar)( s_iter[1] * alpha_factor + .5 );
+ p_iter[1] = (guchar)( s_iter[2] * alpha_factor + .5 );
+ p_iter[2] = (guchar)( s_iter[3] * alpha_factor + .5 );
+ if (p_n_channels == 4)
+ p_iter[3] = s_iter[0];
+#else /* PDP endianness */
+ /* Pixbuf: RGB(A) - Surface: RABG */
+ gdouble alpha_factor = (gdouble)0xff / s_iter[1];
+ p_iter[0] = (guchar)( s_iter[0] * alpha_factor + .5 );
+ p_iter[1] = (guchar)( s_iter[3] * alpha_factor + .5 );
+ p_iter[2] = (guchar)( s_iter[2] * alpha_factor + .5 );
+ if (p_n_channels == 4)
+ p_iter[3] = s_iter[1];
+#endif
+ s_iter += 4;
+ p_iter += p_n_channels;
+ }
+ s_pixels += s_stride;
+ p_pixels += p_stride;
+ }
+ /* Destroy context */
+ cairo_destroy(cr);
+
+ return pixbuf;
+}
+
+/*
+ * Renders a SVG file into a pixbuf with the dimensions of the
+ * given pixmap data (optionally with alpha channel).
+ */
+GdkPixbuf *pixbuf_from_svg_like_icon(char *filename, GError **error, StockPixmapData *icondata, gboolean alpha)
+{
+ int width, height;
+ cairo_surface_t *surface;
+ cairo_t *context;
+ RsvgHandle *handle;
+
+ 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) {
+ g_warning("failed loading SVG '%s': %s (%d)", filename,
+ (*error)->message, (*error)->code);
+ return NULL;
+ }
+ /* create drawing context */
+ surface = cairo_image_surface_create(
+ alpha? CAIRO_FORMAT_ARGB32: CAIRO_FORMAT_RGB24,
+ width, height);
+ if (cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) {
+ g_warning("failed to create a cairo surface: %s",
+ cairo_status_to_string(cairo_surface_status(surface)));
+ g_object_unref(handle);
+ return NULL;
+ }
+ context = cairo_create(surface);
+ cairo_surface_destroy(surface);
+ if (cairo_status(context) != CAIRO_STATUS_SUCCESS) {
+ g_warning("failed to create a cairo context: %s",
+ cairo_status_to_string(cairo_status(context)));
+ cairo_destroy(context);
+ return NULL;
+ }
+ /* render SVG */
+ render_scaled_proportionally(handle, context, width, height);
+ /* build result and destroy context */
+ return pixbuf_from_cairo(context, alpha, width, height);
+}
+#endif
+
/*!
*\brief
*/
@@ -532,7 +689,7 @@ try_next_extension:
GError *err = NULL;
#ifdef HAVE_SVG
if (!strncmp(extension[i], ".svg", 4)) {
- pix = rsvg_pixbuf_from_file(icon_file_name, &err);
+ pix = pixbuf_from_svg_like_icon(icon_file_name, &err, pix_d, TRUE);
} else {
pix = gdk_pixbuf_new_from_file(icon_file_name, &err);
}
commit db434c2b05aec33ca6c3cc4fda792d40cf34942c
Author: Ricardo Mones <ricardo at mones.org>
Date: Sat Jan 28 21:29:30 2017 +0100
Load SVG files the deprecated way
diff --git a/src/stock_pixmap.c b/src/stock_pixmap.c
index b401fa7..947b2e6 100644
--- a/src/stock_pixmap.c
+++ b/src/stock_pixmap.c
@@ -23,6 +23,7 @@
#include <glib.h>
#include <gtk/gtk.h>
+#include <librsvg/rsvg.h>
#include <string.h>
#include <dirent.h>
@@ -468,6 +469,9 @@ static StockPixmapData pixmaps[] =
static const char *extension[] = {
".png",
".xpm",
+#ifdef HAVE_SVG
+ ".svg",
+#endif
NULL
};
@@ -526,7 +530,15 @@ try_next_extension:
NULL);
if (is_file_exist(icon_file_name)) {
GError *err = NULL;
+#ifdef HAVE_SVG
+ if (!strncmp(extension[i], ".svg", 4)) {
+ pix = rsvg_pixbuf_from_file(icon_file_name, &err);
+ } else {
+ pix = gdk_pixbuf_new_from_file(icon_file_name, &err);
+ }
+#else
pix = gdk_pixbuf_new_from_file(icon_file_name, &err);
+#endif
if (err) g_error_free(err);
}
if (pix) {
commit cdf48fc3e9ce71ef09c0b9ddbdf7057f6d36e6da
Author: Ricardo Mones <ricardo at mones.org>
Date: Fri Jan 27 23:41:15 2017 +0100
Configure SVG library
• New feature flag HAVE_SVG, enabled by default if dependencies
are available (librsvg-2.0 >= 2.36.0).
• New item in About window's Features tab for librSVG.
diff --git a/claws-features.h.in b/claws-features.h.in
index 0d5e8ad..65d71e6 100644
--- a/claws-features.h.in
+++ b/claws-features.h.in
@@ -7,6 +7,7 @@
#undef HAVE_NETWORKMANAGER_SUPPORT
#undef HAVE_STARTUP_NOTIFICATION
#undef HAVE_VALGRIND
+#undef HAVE_SVG
#undef USE_BOGOFILTER_PLUGIN
#undef USE_ENCHANT
#undef USE_GNUTLS
diff --git a/configure.ac b/configure.ac
index e8e4ae4..99cb448 100644
--- a/configure.ac
+++ b/configure.ac
@@ -290,6 +290,10 @@ AC_ARG_ENABLE(gtk3,
[ --enable-gtk3 Build GTK3 support],
[enable_gtk3=$enableval], [enable_gtk3=no])
+AC_ARG_ENABLE(svg,
+ [ --disable-svg Do not build SVG support],
+ [enable_svg=$enableval], [enable_svg=yes])
+
AC_ARG_ENABLE(deprecated,
[ --disable-deprecated Disable deprecated GTK functions],
[GTK_CFLAGS="$GTK_CFLAGS -DG_DISABLE_DEPRECATED -DGTK_DISABLE_DEPRECATED"], [])
@@ -927,6 +931,25 @@ else
fi
AM_CONDITIONAL(CLAWS_LIBETPAN, test "x$libetpan_result" = "xyes")
+dnl librsvg
+AC_MSG_CHECKING([whether to use librsvg])
+if test x"$enable_svg" = xyes; then
+ AC_MSG_RESULT(yes)
+ PKG_CHECK_MODULES([SVG], [librsvg-2.0 >= 2.36.0 cairo >= 1.0.0],
+ [
+ AC_SUBST(SVG_CFLAGS)
+ AC_SUBST(SVG_LIBS)
+ AC_DEFINE(HAVE_SVG, 1, [Define if librsvg2 is available for SVG support])
+ enable_svg=yes
+ ],
+ [
+ AC_MSG_NOTICE([SVG support deactivated as librsvg2 >= 2.36 was not found])
+ enable_svg=no
+ ])
+else
+ AC_MSG_RESULT(no)
+fi
+
AC_MSG_CHECKING([whether to use valgrind])
if test x$enable_valgrind = xyes; then
AC_MSG_RESULT(yes)
@@ -2009,6 +2032,7 @@ echo "DBUS : $enable_dbus"
echo "NetworkManager : $enable_networkmanager"
echo "Manual : $enable_manual"
echo "Generic UMPC code : $enable_generic_umpc"
+echo "SVG support : $enable_svg"
echo "Config dir : $ac_cv_with_config_dir"
echo "Password crypto : $pwd_crypto"
diff --git a/src/Makefile.am b/src/Makefile.am
index b78a58d..ba1b837 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -599,6 +599,7 @@ claws_mail_LDADD = \
$(STARTUP_NOTIFICATION_LIBS) \
$(LIBETPAN_LIBS) \
$(DBUS_LIBS) \
+ $(SVG_LIBS) \
$(CONTACTS_LIBS)
pixmapdir=$(datadir)/icons/hicolor/48x48/apps
@@ -619,6 +620,7 @@ AM_CPPFLAGS = \
$(LIBETPAN_CPPFLAGS) \
$(STARTUP_NOTIFICATION_CFLAGS) \
$(DBUS_CFLAGS) \
+ $(SVG_CFLAGS) \
$(NETWORKMANAGER_SUPPORT_CFLAGS) \
$(VALGRIND_CFLAGS) \
$(CONTACTS_CFLAGS)
diff --git a/src/gtk/about.c b/src/gtk/about.c
index 86570ac..9809892 100644
--- a/src/gtk/about.c
+++ b/src/gtk/about.c
@@ -510,6 +510,16 @@ static GtkWidget *about_create_child_page_features(void)
gtk_text_buffer_insert(buffer, &iter,
(gchar *)C_("NetworkManager", "adds support for detection of network connection changes\n"), -1);
+#if HAVE_SVG
+ gtk_text_buffer_insert_pixbuf(buffer, &iter, active_pixbuf);
+#else
+ gtk_text_buffer_insert_pixbuf(buffer, &iter, inactive_pixbuf);
+#endif
+ gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, (" librSVG "), -1,
+ "bold", NULL);
+ gtk_text_buffer_insert(buffer, &iter,
+ (gchar *)C_("librSVG", "adds support for SVG themes\n"), -1);
+
return scrolledwin;
}
-----------------------------------------------------------------------
hooks/post-receive
--
Claws Mail
More information about the Commits
mailing list