Branch data Line data Source code
1 : : /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
2 : : *
3 : : * Copyright © 2015 Red Hat, Inc.
4 : : *
5 : : * This program is free software; you can redistribute it and/or modify
6 : : * it under the terms of the GNU General Public License as published by
7 : : * the Free Software Foundation; either version 2 of the License, or
8 : : * (at your option) any later version.
9 : : *
10 : : * This program is distributed in the hope that it will be useful,
11 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 : : * GNU General Public License for more details.
14 : : *
15 : : * You should have received a copy of the GNU General Public License
16 : : * along with this program; if not, see <http://www.gnu.org/licenses/>.
17 : : *
18 : : * Authors:
19 : : * - Ondrej Holy <oholy@redhat.com>
20 : : */
21 : :
22 : : #include <gtk/gtk.h>
23 : : #include <act/act.h>
24 : : #include <sys/stat.h>
25 : :
26 : : #include "user-image.h"
27 : :
28 : :
29 : : struct _MctUserImage
30 : : {
31 : : GtkImage parent_instance;
32 : :
33 : : ActUser *user;
34 : : };
35 : :
36 [ # # # # : 0 : G_DEFINE_TYPE (MctUserImage, mct_user_image, GTK_TYPE_IMAGE)
# # ]
37 : :
38 : : static GdkPixbuf *
39 : 0 : round_image (GdkPixbuf *pixbuf)
40 : : {
41 : 0 : GdkPixbuf *dest = NULL;
42 : : cairo_surface_t *surface;
43 : : cairo_t *cr;
44 : : gint size;
45 : :
46 : 0 : size = gdk_pixbuf_get_width (pixbuf);
47 : 0 : surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, size, size);
48 : 0 : cr = cairo_create (surface);
49 : :
50 : : /* Clip a circle */
51 : 0 : cairo_arc (cr, size / 2, size / 2, size / 2, 0, 2 * G_PI);
52 : 0 : cairo_clip (cr);
53 : 0 : cairo_new_path (cr);
54 : :
55 : 0 : gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
56 : 0 : cairo_paint (cr);
57 : :
58 : 0 : dest = gdk_pixbuf_get_from_surface (surface, 0, 0, size, size);
59 : 0 : cairo_surface_destroy (surface);
60 : 0 : cairo_destroy (cr);
61 : :
62 : 0 : return dest;
63 : : }
64 : :
65 : : static cairo_surface_t *
66 : 0 : render_user_icon (ActUser *user,
67 : : gint icon_size,
68 : : gint scale)
69 : : {
70 : 0 : g_autoptr(GdkPixbuf) source_pixbuf = NULL;
71 : 0 : GdkPixbuf *pixbuf = NULL;
72 : : GError *error;
73 : : const gchar *icon_file;
74 : 0 : cairo_surface_t *surface = NULL;
75 : :
76 : 0 : g_return_val_if_fail (ACT_IS_USER (user), NULL);
77 : 0 : g_return_val_if_fail (icon_size > 12, NULL);
78 : :
79 : 0 : icon_file = act_user_get_icon_file (user);
80 : 0 : pixbuf = NULL;
81 [ # # ]: 0 : if (icon_file)
82 : : {
83 : 0 : source_pixbuf = gdk_pixbuf_new_from_file_at_size (icon_file,
84 : : icon_size * scale,
85 : : icon_size * scale,
86 : : NULL);
87 [ # # ]: 0 : if (source_pixbuf)
88 : 0 : pixbuf = round_image (source_pixbuf);
89 : : }
90 : :
91 [ # # ]: 0 : if (pixbuf != NULL)
92 : 0 : goto out;
93 : :
94 : 0 : error = NULL;
95 : 0 : pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
96 : : "avatar-default",
97 : : icon_size * scale,
98 : : GTK_ICON_LOOKUP_FORCE_SIZE,
99 : : &error);
100 [ # # ]: 0 : if (error)
101 : : {
102 : 0 : g_warning ("%s", error->message);
103 : 0 : g_error_free (error);
104 : : }
105 : :
106 : 0 : out:
107 : :
108 [ # # ]: 0 : if (pixbuf != NULL)
109 : : {
110 : 0 : surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, scale, NULL);
111 : 0 : g_object_unref (pixbuf);
112 : : }
113 : :
114 : 0 : return surface;
115 : : }
116 : :
117 : : static void
118 : 0 : render_image (MctUserImage *image)
119 : : {
120 : : cairo_surface_t *surface;
121 : : gint scale, pixel_size;
122 : :
123 [ # # ]: 0 : if (image->user == NULL)
124 : 0 : return;
125 : :
126 : 0 : pixel_size = gtk_image_get_pixel_size (GTK_IMAGE (image));
127 : 0 : scale = gtk_widget_get_scale_factor (GTK_WIDGET (image));
128 [ # # ]: 0 : surface = render_user_icon (image->user,
129 : : pixel_size > 0 ? pixel_size : 48,
130 : : scale);
131 : 0 : gtk_image_set_from_surface (GTK_IMAGE (image), surface);
132 : 0 : cairo_surface_destroy (surface);
133 : : }
134 : :
135 : : void
136 : 0 : mct_user_image_set_user (MctUserImage *image,
137 : : ActUser *user)
138 : : {
139 [ # # ]: 0 : g_clear_object (&image->user);
140 : 0 : image->user = g_object_ref (user);
141 : :
142 : 0 : render_image (image);
143 : 0 : }
144 : :
145 : : static void
146 : 0 : mct_user_image_finalize (GObject *object)
147 : : {
148 : 0 : MctUserImage *image = MCT_USER_IMAGE (object);
149 : :
150 [ # # ]: 0 : g_clear_object (&image->user);
151 : :
152 : 0 : G_OBJECT_CLASS (mct_user_image_parent_class)->finalize (object);
153 : 0 : }
154 : :
155 : : static void
156 : 0 : mct_user_image_class_init (MctUserImageClass *class)
157 : : {
158 : 0 : GObjectClass *object_class = G_OBJECT_CLASS (class);
159 : :
160 : 0 : object_class->finalize = mct_user_image_finalize;
161 : 0 : }
162 : :
163 : : static void
164 : 0 : mct_user_image_init (MctUserImage *image)
165 : : {
166 : 0 : g_signal_connect_swapped (image, "notify::scale-factor", G_CALLBACK (render_image), image);
167 : 0 : g_signal_connect_swapped (image, "notify::pixel-size", G_CALLBACK (render_image), image);
168 : 0 : }
169 : :
170 : : GtkWidget *
171 : 0 : mct_user_image_new (void)
172 : : {
173 : 0 : return g_object_new (MCT_TYPE_USER_IMAGE, NULL);
174 : : }
|