[evince] EvSidebarThumbnails: switch to using cairo_surface_t for images
- From: Carlos Garcia Campos <carlosgc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evince] EvSidebarThumbnails: switch to using cairo_surface_t for images
- Date: Sat, 22 Mar 2014 11:54:37 +0000 (UTC)
commit 0a0d99b1c6f7d42fe37b270798b60420325fdc32
Author: Owen W. Taylor <otaylor fishsoup net>
Date: Thu Feb 27 11:37:04 2014 -0500
EvSidebarThumbnails: switch to using cairo_surface_t for images
To support high resolution thumbnails on hi-dpi displays, we need to
use cairo surfaces instead of using GdkPixbuf for images. In preparation
for high resolution thumbnails, switch over to cairo_surface_t. This
adds a GTK+ 3.10 dependency.
Add new:
ev_document_misc_render_loading_thumbnail_surface()
ev_document_misc_render_thumbnail_surface_with_frame()
To avoid converting surface => pixbuf => surface.
https://bugzilla.gnome.org/show_bug.cgi?id=723431
configure.ac | 2 +-
.../libdocument/libevdocument-sections.txt | 2 +
libdocument/ev-document-misc.c | 85 ++++++++++++++++---
libdocument/ev-document-misc.h | 9 ++
shell/ev-sidebar-thumbnails.c | 49 +++++++-----
5 files changed, 113 insertions(+), 34 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index f4388ae..51a4e46 100644
--- a/configure.ac
+++ b/configure.ac
@@ -118,7 +118,7 @@ dnl Specify required versions of dependencies
CAIRO_REQUIRED=1.10.0
GLIB_REQUIRED=2.36.0
LIBSECRET_REQUIRED=0.5
-GTK_REQUIRED=3.8.0
+GTK_REQUIRED=3.10.0
NAUTILUS_REQUIRED=2.91.4
AC_SUBST([GLIB_REQUIRED])
diff --git a/help/reference/libdocument/libevdocument-sections.txt
b/help/reference/libdocument/libevdocument-sections.txt
index e2f26cf..674248e 100644
--- a/help/reference/libdocument/libevdocument-sections.txt
+++ b/help/reference/libdocument/libevdocument-sections.txt
@@ -852,6 +852,8 @@ ev_document_misc_invert_pixbuf
ev_document_misc_format_date
ev_document_misc_render_loading_thumbnail
ev_document_misc_render_thumbnail_with_frame
+ev_document_misc_render_loading_thumbnail_surface
+ev_document_misc_render_thumbnail_surface_with_frame
<SUBSECTION Deprecated>
ev_document_misc_get_loading_thumbnail
ev_document_misc_get_page_border_size
diff --git a/libdocument/ev-document-misc.c b/libdocument/ev-document-misc.c
index f76c15c..fdc5fbb 100644
--- a/libdocument/ev-document-misc.c
+++ b/libdocument/ev-document-misc.c
@@ -126,12 +126,13 @@ ev_document_misc_get_loading_thumbnail (int width,
return create_thumbnail_frame (width, height, NULL, !inverted_colors);
}
-static GdkPixbuf *
-ev_document_misc_render_thumbnail_frame (GtkWidget *widget,
- int width,
- int height,
- gboolean inverted_colors,
- GdkPixbuf *source_pixbuf)
+static cairo_surface_t *
+ev_document_misc_render_thumbnail_frame (GtkWidget *widget,
+ int width,
+ int height,
+ gboolean inverted_colors,
+ GdkPixbuf *source_pixbuf,
+ cairo_surface_t *source_surface)
{
GtkStyleContext *context = gtk_widget_get_style_context (widget);
GtkStateFlags state = gtk_widget_get_state_flags (widget);
@@ -140,7 +141,6 @@ ev_document_misc_render_thumbnail_frame (GtkWidget *widget,
cairo_surface_t *surface;
cairo_t *cr;
GtkBorder border = {0, };
- GdkPixbuf *retval;
if (source_pixbuf) {
g_return_val_if_fail (GDK_IS_PIXBUF (source_pixbuf), NULL);
@@ -164,8 +164,12 @@ ev_document_misc_render_thumbnail_frame (GtkWidget *widget,
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
width_f, height_f);
+
cr = cairo_create (surface);
- if (source_pixbuf) {
+ if (source_surface) {
+ cairo_set_source_surface (cr, source_surface, border.left, border.top);
+ cairo_paint (cr);
+ } else if (source_pixbuf) {
gdk_cairo_set_source_pixbuf (cr, source_pixbuf, border.left, border.top);
cairo_paint (cr);
} else {
@@ -176,10 +180,7 @@ ev_document_misc_render_thumbnail_frame (GtkWidget *widget,
gtk_style_context_restore (context);
- retval = gdk_pixbuf_get_from_surface (surface, 0, 0, width_f, height_f);
- cairo_surface_destroy (surface);
-
- return retval;
+ return surface;
}
/**
@@ -199,7 +200,34 @@ ev_document_misc_render_loading_thumbnail (GtkWidget *widget,
int height,
gboolean inverted_colors)
{
- return ev_document_misc_render_thumbnail_frame (widget, width, height, inverted_colors, NULL);
+ GdkPixbuf *retval;
+ cairo_surface_t *surface;
+
+ surface = ev_document_misc_render_thumbnail_frame (widget, width, height, inverted_colors, NULL,
NULL);
+ retval = gdk_pixbuf_get_from_surface (surface, 0, 0, width, height);
+ cairo_surface_destroy (surface);
+
+ return retval;
+}
+
+/**
+ * ev_document_misc_render_loading_thumbnail_surface:
+ * @widget: a #GtkWidget to use for style information
+ * @width: the desired width
+ * @height: the desired height
+ * @inverted_colors: whether to invert colors
+ *
+ * Returns: (transfer full): a #cairo_surface_t
+ *
+ * Since: 3.14
+ */
+cairo_surface_t *
+ev_document_misc_render_loading_thumbnail_surface (GtkWidget *widget,
+ int width,
+ int height,
+ gboolean inverted_colors)
+{
+ return ev_document_misc_render_thumbnail_frame (widget, width, height, inverted_colors, NULL, NULL);
}
/**
@@ -215,7 +243,36 @@ GdkPixbuf *
ev_document_misc_render_thumbnail_with_frame (GtkWidget *widget,
GdkPixbuf *source_pixbuf)
{
- return ev_document_misc_render_thumbnail_frame (widget, -1, -1, FALSE, source_pixbuf);
+ GdkPixbuf *retval;
+ cairo_surface_t *surface;
+
+ surface = ev_document_misc_render_thumbnail_frame (widget, -1, -1, FALSE, source_pixbuf, NULL);
+ retval = gdk_pixbuf_get_from_surface (surface, 0, 0,
+ cairo_image_surface_get_width (surface),
+ cairo_image_surface_get_height (surface));
+ cairo_surface_destroy (surface);
+
+ return retval;
+}
+
+/**
+ * ev_document_misc_render_thumbnail_surface_with_frame:
+ * @widget: a #GtkWidget to use for style information
+ * @source_surface: a #cairo_surface_t
+ * @width: the desired width
+ * @height: the desired height
+ *
+ * Returns: (transfer full): a #cairo_surface_t
+ *
+ * Since: 3.14
+ */
+cairo_surface_t *
+ev_document_misc_render_thumbnail_surface_with_frame (GtkWidget *widget,
+ cairo_surface_t *source_surface,
+ int width,
+ int height)
+{
+ return ev_document_misc_render_thumbnail_frame (widget, width, height, FALSE, NULL, source_surface);
}
void
diff --git a/libdocument/ev-document-misc.h b/libdocument/ev-document-misc.h
index ac59682..566d594 100644
--- a/libdocument/ev-document-misc.h
+++ b/libdocument/ev-document-misc.h
@@ -50,6 +50,15 @@ GdkPixbuf *ev_document_misc_render_loading_thumbnail (GtkWidget *widget,
GdkPixbuf *ev_document_misc_render_thumbnail_with_frame (GtkWidget *widget,
GdkPixbuf *source_pixbuf);
+cairo_surface_t *ev_document_misc_render_loading_thumbnail_surface (GtkWidget *widget,
+ int width,
+ int height,
+ gboolean inverted_colors);
+cairo_surface_t *ev_document_misc_render_thumbnail_surface_with_frame (GtkWidget *widget,
+ cairo_surface_t *source_surface,
+ int width,
+ int height);
+
EV_DEPRECATED
void ev_document_misc_get_page_border_size (gint page_width,
gint page_height,
diff --git a/shell/ev-sidebar-thumbnails.c b/shell/ev-sidebar-thumbnails.c
index 181e12b..d747d79 100644
--- a/shell/ev-sidebar-thumbnails.c
+++ b/shell/ev-sidebar-thumbnails.c
@@ -31,6 +31,8 @@
#include <glib/gi18n.h>
#include <gtk/gtk.h>
+#include <cairo-gobject.h>
+
#include "ev-document-misc.h"
#include "ev-job-scheduler.h"
#include "ev-sidebar-page.h"
@@ -80,7 +82,7 @@ struct _EvSidebarThumbnailsPrivate {
enum {
COLUMN_PAGE_STRING,
- COLUMN_PIXBUF,
+ COLUMN_SURFACE,
COLUMN_THUMBNAIL_SET,
COLUMN_JOB,
NUM_COLUMNS
@@ -371,14 +373,14 @@ ev_sidebar_thumbnails_new (void)
return ev_sidebar_thumbnails;
}
-static GdkPixbuf *
+static cairo_surface_t *
ev_sidebar_thumbnails_get_loading_icon (EvSidebarThumbnails *sidebar_thumbnails,
gint width,
gint height)
{
EvSidebarThumbnailsPrivate *priv = sidebar_thumbnails->priv;
- GdkPixbuf *icon;
- gchar *key;
+ cairo_surface_t *icon;
+ gchar *key;
key = g_strdup_printf ("%dx%d", width, height);
icon = g_hash_table_lookup (priv->loading_icons, key);
@@ -386,8 +388,9 @@ ev_sidebar_thumbnails_get_loading_icon (EvSidebarThumbnails *sidebar_thumbnails,
gboolean inverted_colors;
inverted_colors = ev_document_model_get_inverted_colors (priv->model);
- icon = ev_document_misc_render_loading_thumbnail (GTK_WIDGET (sidebar_thumbnails),
- width, height, inverted_colors);
+ icon = ev_document_misc_render_loading_thumbnail_surface (GTK_WIDGET (sidebar_thumbnails),
+ width, height,
+ inverted_colors);
g_hash_table_insert (priv->loading_icons, key, icon);
} else {
g_free (key);
@@ -415,7 +418,7 @@ clear_range (EvSidebarThumbnails *sidebar_thumbnails,
result && start_page <= end_page;
result = gtk_tree_model_iter_next (GTK_TREE_MODEL (priv->list_store), &iter), start_page ++) {
EvJobThumbnail *job;
- GdkPixbuf *loading_icon = NULL;
+ cairo_surface_t *loading_icon = NULL;
gint width, height;
gtk_tree_model_get (GTK_TREE_MODEL (priv->list_store),
@@ -444,7 +447,7 @@ clear_range (EvSidebarThumbnails *sidebar_thumbnails,
gtk_list_store_set (priv->list_store, &iter,
COLUMN_JOB, NULL,
COLUMN_THUMBNAIL_SET, FALSE,
- COLUMN_PIXBUF, loading_icon,
+ COLUMN_SURFACE, loading_icon,
-1);
}
gtk_tree_path_free (path);
@@ -610,7 +613,7 @@ ev_sidebar_thumbnails_fill_model (EvSidebarThumbnails *sidebar_thumbnails)
for (i = 0; i < sidebar_thumbnails->priv->n_pages; i++) {
gchar *page_label;
gchar *page_string;
- GdkPixbuf *loading_icon = NULL;
+ cairo_surface_t *loading_icon = NULL;
gint width, height;
page_label = ev_document_get_page_label (priv->document, i);
@@ -630,7 +633,7 @@ ev_sidebar_thumbnails_fill_model (EvSidebarThumbnails *sidebar_thumbnails)
gtk_list_store_append (priv->list_store, &iter);
gtk_list_store_set (priv->list_store, &iter,
COLUMN_PAGE_STRING, page_string,
- COLUMN_PIXBUF, loading_icon,
+ COLUMN_SURFACE, loading_icon,
COLUMN_THUMBNAIL_SET, FALSE,
-1);
g_free (page_label);
@@ -703,7 +706,7 @@ ev_sidebar_init_tree_view (EvSidebarThumbnails *ev_sidebar_thumbnails)
NULL);
gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (priv->tree_view), -1,
NULL, renderer,
- "pixbuf", 1,
+ "surface", 1,
NULL);
gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (priv->tree_view), -1,
NULL, gtk_cell_renderer_text_new (),
@@ -728,7 +731,7 @@ ev_sidebar_init_icon_view (EvSidebarThumbnails *ev_sidebar_thumbnails)
NULL);
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (priv->icon_view), renderer, FALSE);
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (priv->icon_view),
- renderer, "pixbuf", 1, NULL);
+ renderer, "surface", 1, NULL);
renderer = g_object_new (GTK_TYPE_CELL_RENDERER_TEXT,
"alignment", PANGO_ALIGN_CENTER,
@@ -765,7 +768,7 @@ ev_sidebar_thumbnails_init (EvSidebarThumbnails *ev_sidebar_thumbnails)
priv->list_store = gtk_list_store_new (NUM_COLUMNS,
G_TYPE_STRING,
- GDK_TYPE_PIXBUF,
+ CAIRO_GOBJECT_TYPE_SURFACE,
G_TYPE_BOOLEAN,
EV_TYPE_JOB_THUMBNAIL);
@@ -886,22 +889,30 @@ static void
thumbnail_job_completed_callback (EvJobThumbnail *job,
EvSidebarThumbnails *sidebar_thumbnails)
{
+ GtkWidget *widget = GTK_WIDGET (sidebar_thumbnails);
EvSidebarThumbnailsPrivate *priv = sidebar_thumbnails->priv;
GtkTreeIter *iter;
- GdkPixbuf *pixbuf;
+ cairo_surface_t *surface;
+ cairo_surface_t *thumbnail;
- pixbuf = ev_document_misc_render_thumbnail_with_frame (GTK_WIDGET (sidebar_thumbnails),
job->thumbnail);
+ thumbnail = gdk_cairo_surface_create_from_pixbuf (job->thumbnail,
+ 1,
+ gtk_widget_get_window (widget));
+ surface = ev_document_misc_render_thumbnail_surface_with_frame (widget, thumbnail,
+ gdk_pixbuf_get_width
(job->thumbnail),
+ gdk_pixbuf_get_height
(job->thumbnail));
+ cairo_surface_destroy (thumbnail);
iter = (GtkTreeIter *) g_object_get_data (G_OBJECT (job), "tree_iter");
if (priv->inverted_colors)
- ev_document_misc_invert_pixbuf (pixbuf);
+ ev_document_misc_invert_surface (surface);
gtk_list_store_set (priv->list_store,
iter,
- COLUMN_PIXBUF, pixbuf,
+ COLUMN_SURFACE, surface,
COLUMN_THUMBNAIL_SET, TRUE,
COLUMN_JOB, NULL,
-1);
- g_object_unref (pixbuf);
+ cairo_surface_destroy (surface);
}
static void
@@ -925,7 +936,7 @@ ev_sidebar_thumbnails_document_changed_cb (EvDocumentModel *model,
priv->loading_icons = g_hash_table_new_full (g_str_hash,
g_str_equal,
(GDestroyNotify)g_free,
- (GDestroyNotify)g_object_unref);
+ (GDestroyNotify)cairo_surface_destroy);
ev_sidebar_thumbnails_clear_model (sidebar_thumbnails);
ev_sidebar_thumbnails_fill_model (sidebar_thumbnails);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]