[geary/wip/3.32-avatars: 42/50] Port GNOME 3.32 avatar code to vala, use when Folks avatar is missing
- From: Michael Gratton <mjog src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [geary/wip/3.32-avatars: 42/50] Port GNOME 3.32 avatar code to vala, use when Folks avatar is missing
- Date: Sat, 9 Mar 2019 09:17:55 +0000 (UTC)
commit 9306d7ccd0a380a1c74d98b303ce1d89d2a323f9
Author: Michael Gratton <mike vee net>
Date: Fri Mar 1 13:02:43 2019 +1100
Port GNOME 3.32 avatar code to vala, use when Folks avatar is missing
This ports the code written by Felipe Borges for GNOME/Initiatives#6 to
vala, and uses that when no Folks individual was found or it does not
have an avatar.
po/POTFILES.in | 1 +
.../application/application-avatar-store.vala | 26 ++++
src/client/meson.build | 1 +
src/client/util/util-avatar.vala | 140 +++++++++++++++++++++
4 files changed, 168 insertions(+)
---
diff --git a/po/POTFILES.in b/po/POTFILES.in
index e68a30aa..6fc3bc1b 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -88,6 +88,7 @@ src/client/sidebar/sidebar-common.vala
src/client/sidebar/sidebar-count-cell-renderer.vala
src/client/sidebar/sidebar-entry.vala
src/client/sidebar/sidebar-tree.vala
+src/client/util/util-avatar.vala
src/client/util/util-date.vala
src/client/util/util-email.vala
src/client/util/util-files.vala
diff --git a/src/client/application/application-avatar-store.vala
b/src/client/application/application-avatar-store.vala
index 1a334c53..6d3d9402 100644
--- a/src/client/application/application-avatar-store.vala
+++ b/src/client/application/application-avatar-store.vala
@@ -81,9 +81,35 @@ public class Application.AvatarStore : Geary.BaseObject {
pixbuf = yield new Gdk.Pixbuf.from_stream_at_scale_async(
data, pixel_size, pixel_size, true, cancellable
);
+ pixbuf = Util.Avatar.round_image(pixbuf);
this.pixbufs.add(pixbuf);
}
}
+
+ if (pixbuf == null) {
+ string? name = null;
+ // XXX should really be using the folks display name
+ // here as below, but since we should the name from
+ // the email address if present in
+ // ConversationMessage, and since that might not match
+ // the folks display name, it is confusing when the
+ // initials are one thing and the name is
+ // another. Re-enable below when we start using the
+ // folks display name in ConversationEmail
+ name = this.mailbox.to_short_display();
+ // if (this.individual != null) {
+ // name = this.individual.display_name;
+ // } else {
+ // // Use short display because it will clean up the
+ // // string, use the name if present and fall back
+ // // on the address if not.
+ // name = this.mailbox.to_short_display();
+ // }
+ pixbuf = Util.Avatar.generate_user_picture(name, pixel_size);
+ pixbuf = Util.Avatar.round_image(pixbuf);
+ this.pixbufs.add(pixbuf);
+ }
+
return pixbuf;
}
diff --git a/src/client/meson.build b/src/client/meson.build
index 271ad46b..d1c7863a 100644
--- a/src/client/meson.build
+++ b/src/client/meson.build
@@ -92,6 +92,7 @@ geary_client_vala_sources = files(
'sidebar/sidebar-entry.vala',
'sidebar/sidebar-tree.vala',
+ 'util/util-avatar.vala',
'util/util-date.vala',
'util/util-email.vala',
'util/util-files.vala',
diff --git a/src/client/util/util-avatar.vala b/src/client/util/util-avatar.vala
new file mode 100644
index 00000000..21ce4ab8
--- /dev/null
+++ b/src/client/util/util-avatar.vala
@@ -0,0 +1,140 @@
+/*
+ * Copyright 2019 Michael Gratton <mike vee net>
+ *
+ * This software is licensed under the GNU Lesser General Public License
+ * (version 2.1 or later). See the COPYING file in this distribution.
+ */
+
+namespace Util.Avatar {
+
+ // The following was ported from code written by Felipe Borges for
+ // gnome-control-enter in panels/user-accounts/user-utils.c commit
+ // 02c288ab6f069a0c106323a93400f192a63cb67e. The copyright in that
+ // file is: "Copyright 2009-2010 Red Hat, Inc,"
+
+ public Gdk.Pixbuf generate_user_picture(string name, int size) {
+ string initials = extract_initials_from_name(name);
+ string font = "Sans %d".printf((int) GLib.Math.ceil(size / 2.5));
+ Gdk.RGBA color = get_color_for_name(name);
+
+ Cairo.Surface surface = new Cairo.ImageSurface(
+ Cairo.Format.ARGB32, size, size
+ );
+ Cairo.Context cr = new Cairo.Context(surface);
+ cr.rectangle(0, 0, size, size);
+ cr.set_source_rgb(
+ color.red / 255.0, color.green / 255.0, color.blue / 255.0
+ );
+ cr.fill();
+
+ /* Draw the initials on top */
+ cr.set_source_rgb(1.0, 1.0, 1.0);
+ Pango.Layout layout = Pango.cairo_create_layout(cr);
+ layout.set_text(initials, -1);
+ layout.set_font_description(Pango.FontDescription.from_string(font));
+
+ int width, height;
+ layout.get_size(out width, out height);
+ cr.translate(size / 2, size / 2);
+ cr.move_to(
+ -((double) width / Pango.SCALE) / 2,
+ -((double) height / Pango.SCALE) / 2
+ );
+ Pango.cairo_show_layout(cr, layout);
+
+ return Gdk.pixbuf_get_from_surface(
+ surface, 0, 0, size, size
+ );
+ }
+
+ public Gdk.Pixbuf round_image(Gdk.Pixbuf source) {
+ int size = source.width;
+ Cairo.Surface surface = new Cairo.ImageSurface(
+ Cairo.Format.ARGB32, size, size
+ );
+ Cairo.Context cr = new Cairo.Context(surface);
+
+ /* Clip a circle */
+ cr.arc(size / 2, size / 2, size / 2, 0, 2 * GLib.Math.PI);
+ cr.clip();
+ cr.new_path();
+
+ Gdk.cairo_set_source_pixbuf(cr, source, 0, 0);
+ cr.paint();
+
+ return Gdk.pixbuf_get_from_surface(
+ surface, 0, 0, size, size
+ );
+ }
+
+ public string? extract_initials_from_name(string name) {
+ string normalized = name.strip().up().normalize();
+ string? initials = null;
+ if (normalized != "") {
+ GLib.StringBuilder buf = new GLib.StringBuilder();
+ buf.append_unichar(normalized.get_char(0));
+
+ int index = normalized.last_index_of_char(' ');
+ if (index != -1 && (index + 1) < normalized.length) {
+ buf.append_unichar(normalized.get_char(index + 1));
+ }
+ initials = (string) buf.data;
+ }
+ return initials;
+ }
+
+
+ public Gdk.RGBA get_color_for_name(string name) {
+ // https://gitlab.gnome.org/Community/Design/HIG-app-icons/blob/master/GNOME%20HIG.gpl
+ const double[,3] GNOME_COLOR_PALETTE = {
+ { 98, 160, 234 },
+ { 53, 132, 228 },
+ { 28, 113, 216 },
+ { 26, 95, 180 },
+ { 87, 227, 137 },
+ { 51, 209, 122 },
+ { 46, 194, 126 },
+ { 38, 162, 105 },
+ { 248, 228, 92 },
+ { 246, 211, 45 },
+ { 245, 194, 17 },
+ { 229, 165, 10 },
+ { 255, 163, 72 },
+ { 255, 120, 0 },
+ { 230, 97, 0 },
+ { 198, 70, 0 },
+ { 237, 51, 59 },
+ { 224, 27, 36 },
+ { 192, 28, 40 },
+ { 165, 29, 45 },
+ { 192, 97, 203 },
+ { 163, 71, 186 },
+ { 129, 61, 156 },
+ { 97, 53, 131 },
+ { 181, 131, 90 },
+ { 152, 106, 68 },
+ { 134, 94, 60 },
+ { 99, 69, 44 }
+ };
+
+ Gdk.RGBA color = { 255, 255, 255, 1.0 };
+ uint hash;
+ uint number_of_colors;
+ uint idx;
+
+ if (name == "") {
+ return color;
+ }
+
+ hash = name.hash();
+ number_of_colors = GNOME_COLOR_PALETTE.length[0];
+ idx = hash % number_of_colors;
+
+ color.red = GNOME_COLOR_PALETTE[idx,0];
+ color.green = GNOME_COLOR_PALETTE[idx,1];
+ color.blue = GNOME_COLOR_PALETTE[idx,2];
+
+ return color;
+ }
+
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]