pidgin/pidgin

Add buddy icons in demo protocol

2022-03-08, Elliott Sales de Andrade
c6bd9ea15211
Parents ef8cfc432444
Children 3c11bbd93e97
Add buddy icons in demo protocol

Sample buddy icons are generated from the user name using the existing colour generation algorithm (repeated for the background at low value), and a font that maps a letter to a reasonable symbol.

Testing Done:
Checked buddy list for icons, and opened a few conversations to see avatars were there.

Reviewed at https://reviews.imfreedom.org/r/1314/
--- a/libpurple/protocols/demo/purpledemocontacts.c Tue Mar 08 01:21:19 2022 -0600
+++ b/libpurple/protocols/demo/purpledemocontacts.c Tue Mar 08 01:40:12 2022 -0600
@@ -76,6 +76,27 @@
}
static void
+purple_demo_protocol_load_icon(PurpleAccount *account, const gchar *name)
+{
+ gchar *path = NULL;
+ GBytes *icon = NULL;
+ gpointer icon_data = NULL;
+ gsize icon_len = 0;
+
+ path = g_strdup_printf("/im/pidgin/purple/demo/buddy_icons/%s.png", name);
+ icon = g_resource_lookup_data(purple_demo_get_resource(), path, G_RESOURCE_LOOKUP_FLAGS_NONE, NULL);
+ g_free(path);
+
+ if(icon == NULL) {
+ /* No stored icon. */
+ return;
+ }
+
+ icon_data = g_bytes_unref_to_data(icon, &icon_len);
+ purple_buddy_icons_set_for_user(account, name, icon_data, icon_len, NULL);
+}
+
+static void
purple_demo_protocol_load_buddies(PurpleAccount *account, PurpleGroup *group,
PurpleContact *contact, GList *buddies)
{
@@ -104,6 +125,7 @@
purple_blist_add_buddy(buddy, contact, group, NULL);
}
+ purple_demo_protocol_load_icon(account, name);
purple_demo_protocol_load_status(account, group, contact, buddy,
buddy_object);
}
Binary file libpurple/protocols/demo/resources/buddy_icons/Eion.png has changed
Binary file libpurple/protocols/demo/resources/buddy_icons/Elliott.png has changed
Binary file libpurple/protocols/demo/resources/buddy_icons/Gary.png has changed
Binary file libpurple/protocols/demo/resources/buddy_icons/John.png has changed
Binary file libpurple/protocols/demo/resources/buddy_icons/Richard.png has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/protocols/demo/resources/buddy_icons/mkicon.py Tue Mar 08 01:40:12 2022 -0600
@@ -0,0 +1,90 @@
+#!/usr/bin/env python3
+#
+# Purple - Internet Messaging Library
+# Copyright (C) Pidgin Developers <devel@pidgin.im>
+#
+# Purple is the legal property of its developers, whose names are too numerous
+# to list here. Please refer to the COPYRIGHT file distributed with this
+# source distribution.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, see <https://www.gnu.org/licenses/>.
+
+import argparse
+import colorsys
+import hashlib
+from pathlib import Path
+
+from PIL import Image, ImageDraw, ImageFont
+
+parser = argparse.ArgumentParser(
+ description='Generate buddy icons from user names.')
+parser.add_argument('name', nargs='+', help='The name(s) to use.')
+parser.add_argument('-f', '--font',
+ default='/usr/share/fonts/urw-base35/D050000L.otf',
+ help='Path to (TrueType or OpenType) font to use.')
+parser.add_argument('-s', '--size', default=96, type=int,
+ help='Size of buddy icons to produce.')
+parser.add_argument('-o', '--output', default='.',
+ help='Directory in which to place files.')
+args = parser.parse_args()
+
+
+def calculate_colours_for_text(text):
+ """
+ Calculate the foreground and background colours from text.
+
+ This is based on pidgin_color_calculate_for_text in Pidgin C code.
+ """
+ # Hash the string and get the first 2 bytes of the digest.
+ checksum = hashlib.sha1()
+ checksum.update(text.encode('utf-8'))
+ digest = checksum.digest()
+
+ # Calculate the hue based on the digest, scaled to 0-1.
+ hue = (digest[0] << 8 | digest[1]) / 65535
+ # Get the RGB values for the hue at full saturation and value.
+ foreground = colorsys.hsv_to_rgb(hue, 1.0, 1.0)
+
+ # Calculate the hue based on the end of the digest, scaled to 0-1.
+ hue = (digest[-1] << 8 | digest[-2]) / 65535
+ # Get the RGB values for the hue at full saturation and low value.
+ background = colorsys.hsv_to_rgb(hue, 1.0, 0.2)
+
+ # Finally calculate the foreground summing 20% of the inverted background
+ # with 80% of the foreground.
+ foreground = (
+ (0.2 * (1 - bc)) + (0.8 * fc) for bc, fc in zip(background, foreground)
+ )
+
+ # Pillow requires colours in 0-255.
+ return (tuple(int(c * 255) for c in foreground),
+ tuple(int(c * 255) for c in background))
+
+
+output_dir = Path(args.output)
+font = ImageFont.truetype(args.font, size=int(args.size * 96/72))
+
+for name in args.name:
+ fore, back = calculate_colours_for_text(name)
+
+ # Generate an image using the first letter of the name to choose a glyph
+ # from the specified font. The default font generates some star-like or
+ # flower-like symbols.
+ img = Image.new('RGBA', (args.size, args.size), color=back)
+ draw = ImageDraw.Draw(img)
+ letter = name[0].upper()
+ draw.text((args.size // 2, args.size - 1), letter,
+ font=font, anchor='mb', fill=fore)
+
+ img.save(output_dir / f'{name}.png', 'PNG')
--- a/libpurple/protocols/demo/resources/contacts.json Tue Mar 08 01:21:19 2022 -0600
+++ b/libpurple/protocols/demo/resources/contacts.json Tue Mar 08 01:40:12 2022 -0600
@@ -21,7 +21,7 @@
}],
"Work": [{
"buddies": [{
- "name": "Elliot",
+ "name": "Elliott",
"status": {
"id": "away",
"message": "Coding..."
--- a/libpurple/protocols/demo/resources/purpledemo.gresource.xml Tue Mar 08 01:21:19 2022 -0600
+++ b/libpurple/protocols/demo/resources/purpledemo.gresource.xml Tue Mar 08 01:40:12 2022 -0600
@@ -6,5 +6,10 @@
<file>icons/22x22/apps/im-purple-demo.png</file>
<file>icons/48x48/apps/im-purple-demo.png</file>
<file>icons/scalable/apps/im-purple-demo.svg</file>
+ <file>buddy_icons/Eion.png</file>
+ <file>buddy_icons/Elliott.png</file>
+ <file>buddy_icons/Gary.png</file>
+ <file>buddy_icons/John.png</file>
+ <file>buddy_icons/Richard.png</file>
</gresource>
</gresources>