Evince
Evince is a document viewer capable of displaying multiple and single page document formats like PDF and Postscript.
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
gd-icon-utils.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011, 2012 Red Hat, Inc.
3  *
4  * Gnome Documents is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by the
6  * Free Software Foundation; either version 2 of the License, or (at your
7  * option) any later version.
8  *
9  * Gnome Documents is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12  * for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with Gnome Documents; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17  *
18  * Author: Cosimo Cecchi <cosimoc@redhat.com>
19  *
20  */
21 
22 #include "gd-icon-utils.h"
23 
24 #include <gdk-pixbuf/gdk-pixbuf.h>
25 #include <string.h>
26 #include <math.h>
27 
28 #define _BG_MIN_SIZE 20
29 #define _EMBLEM_MIN_SIZE 8
30 
37 GIcon *
39  gint base_size)
40 {
41  gchar *symbolic_name;
42  GIcon *icon, *retval = NULL;
43  cairo_surface_t *surface;
44  cairo_t *cr;
45  GtkStyleContext *style;
46  GtkWidgetPath *path;
47  GdkPixbuf *pixbuf;
48  GtkIconTheme *theme;
49  GtkIconInfo *info;
50  gint bg_size;
51  gint emblem_size;
52  gint total_size;
53 
54  total_size = base_size / 2;
55  bg_size = MAX (total_size / 2, _BG_MIN_SIZE);
56  emblem_size = MAX (bg_size - 8, _EMBLEM_MIN_SIZE);
57 
58  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, total_size, total_size);
59  cr = cairo_create (surface);
60 
61  style = gtk_style_context_new ();
62 
63  path = gtk_widget_path_new ();
64  gtk_widget_path_append_type (path, GTK_TYPE_ICON_VIEW);
65  gtk_style_context_set_path (style, path);
66  gtk_widget_path_unref (path);
67 
68  gtk_style_context_add_class (style, "documents-icon-bg");
69 
70  gtk_render_background (style, cr, (total_size - bg_size) / 2, (total_size - bg_size) / 2, bg_size, bg_size);
71 
72  symbolic_name = g_strconcat (name, "-symbolic", NULL);
73  icon = g_themed_icon_new_with_default_fallbacks (symbolic_name);
74  g_free (symbolic_name);
75 
76  theme = gtk_icon_theme_get_default();
77  info = gtk_icon_theme_lookup_by_gicon (theme, icon, emblem_size,
78  GTK_ICON_LOOKUP_FORCE_SIZE);
79  g_object_unref (icon);
80 
81  if (info == NULL)
82  goto out;
83 
84  pixbuf = gtk_icon_info_load_symbolic_for_context (info, style, NULL, NULL);
85  g_object_unref (info);
86 
87  if (pixbuf == NULL)
88  goto out;
89 
90  gtk_render_icon (style, cr, pixbuf, (total_size - emblem_size) / 2, (total_size - emblem_size) / 2);
91  g_object_unref (pixbuf);
92 
93  retval = G_ICON (gdk_pixbuf_get_from_surface (surface, 0, 0, total_size, total_size));
94 
95  out:
96  g_object_unref (style);
97  cairo_surface_destroy (surface);
98  cairo_destroy (cr);
99 
100  return retval;
101 }
102 
112 cairo_surface_t *
113 gd_embed_image_in_frame (cairo_surface_t *source_image,
114  const gchar *frame_image_url,
115  GtkBorder *slice_width,
116  GtkBorder *border_width)
117 {
118  cairo_surface_t *surface;
119  cairo_t *cr;
120  int source_width, source_height;
121  int dest_width, dest_height;
122  gchar *css_str;
123  GtkCssProvider *provider;
124  GtkStyleContext *context;
125  GError *error = NULL;
126  GdkPixbuf *retval;
127  GtkWidgetPath *path;
128 
129  source_width = cairo_image_surface_get_width (source_image);
130  source_height = cairo_image_surface_get_height (source_image);
131 
132  dest_width = source_width + border_width->left + border_width->right;
133  dest_height = source_height + border_width->top + border_width->bottom;
134 
135  css_str = g_strdup_printf (".embedded-image { border-image: url(\"%s\") %d %d %d %d / %dpx %dpx %dpx %dpx }",
136  frame_image_url,
137  slice_width->top, slice_width->right, slice_width->bottom, slice_width->left,
138  border_width->top, border_width->right, border_width->bottom, border_width->left);
139  provider = gtk_css_provider_new ();
140  gtk_css_provider_load_from_data (provider, css_str, -1, &error);
141 
142  if (error != NULL)
143  {
144  g_warning ("Unable to create the thumbnail frame image: %s", error->message);
145  g_error_free (error);
146  g_free (css_str);
147 
148  return cairo_surface_reference (source_image);
149  }
150 
151  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, dest_width, dest_height);
152  cr = cairo_create (surface);
153 
154  context = gtk_style_context_new ();
155  path = gtk_widget_path_new ();
156  gtk_widget_path_append_type (path, GTK_TYPE_ICON_VIEW);
157 
158  gtk_style_context_set_path (context, path);
159  gtk_style_context_add_provider (context, GTK_STYLE_PROVIDER (provider), 600);
160 
161  gtk_render_icon_surface (context, cr,
162  source_image,
163  border_width->left, border_width->top);
164 
165  gtk_style_context_save (context);
166  gtk_style_context_add_class (context, "embedded-image");
167 
168  gtk_render_frame (context, cr,
169  0, 0,
170  dest_width, dest_height);
171 
172  gtk_style_context_restore (context);
173  cairo_destroy (cr);
174 
175  gtk_widget_path_unref (path);
176  g_object_unref (provider);
177  g_object_unref (context);
178  g_free (css_str);
179 
180  return surface;
181 }