[gthumb] Use a cairo_surface to store thumbnails
- From: Paolo Bacchilega <paobac src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gthumb] Use a cairo_surface to store thumbnails
- Date: Sun, 30 Jun 2013 08:40:18 +0000 (UTC)
commit 03200b8ca91c73e2f0736ca2996f6d992e8b715b
Author: Paolo Bacchilega <paobac src gnome org>
Date: Mon Jun 24 21:55:16 2013 +0200
Use a cairo_surface to store thumbnails
this avoids to converts the GdkPixbuf to a cairo_surface
each time a thumbnail is drawn on the screen.
extensions/file_viewer/gth-file-viewer-page.c | 15 ++-
extensions/list_tools/gth-script.c | 13 ++-
gthumb/cairo-utils.c | 6 +
gthumb/cairo-utils.h | 5 +
gthumb/gth-file-list.c | 93 +++++++++---------
gthumb/gth-file-store.c | 53 +++++-----
gthumb/gth-file-store.h | 4 +-
gthumb/gth-grid-view.c | 68 +++++++------
gthumb/gth-icon-cache.c | 49 ++++++++--
gthumb/gth-icon-cache.h | 23 +++--
gthumb/gth-thumb-loader.c | 126 ++++++++++++++-----------
gthumb/gth-thumb-loader.h | 2 +-
12 files changed, 267 insertions(+), 190 deletions(-)
---
diff --git a/extensions/file_viewer/gth-file-viewer-page.c b/extensions/file_viewer/gth-file-viewer-page.c
index 0da4ef7..4a1a32b 100644
--- a/extensions/file_viewer/gth-file-viewer-page.c
+++ b/extensions/file_viewer/gth-file-viewer-page.c
@@ -220,19 +220,26 @@ thumb_loader_ready_cb (GObject *source_object,
ViewData *view_data = user_data;
GthFileViewerPage *self = view_data->self;
gboolean success;
- GdkPixbuf *pixbuf = NULL;
+ cairo_surface_t *image = NULL;
success = gth_thumb_loader_load_finish (GTH_THUMB_LOADER (source_object),
result,
- &pixbuf,
+ &image,
NULL);
if (g_file_equal (self->priv->file_data->file, view_data->file_data->file)) {
- if (success)
+ if (success) {
+ GdkPixbuf *pixbuf;
+
+ pixbuf = _gdk_pixbuf_new_from_cairo_surface (image);
gtk_image_set_from_pixbuf (GTK_IMAGE (self->priv->icon), pixbuf);
+
+ _g_object_unref (pixbuf);
+ }
+
gth_viewer_page_file_loaded (GTH_VIEWER_PAGE (self), self->priv->file_data, TRUE);
}
- _g_object_unref (pixbuf);
+ cairo_surface_destroy (image);
view_data_free (view_data);
}
diff --git a/extensions/list_tools/gth-script.c b/extensions/list_tools/gth-script.c
index 0dce0de..74defbf 100644
--- a/extensions/list_tools/gth-script.c
+++ b/extensions/list_tools/gth-script.c
@@ -562,20 +562,25 @@ thumb_loader_ready_cb (GObject *source_object,
GAsyncResult *result,
gpointer user_data)
{
- GtkBuilder *builder = user_data;
- GdkPixbuf *pixbuf;
+ GtkBuilder *builder = user_data;
+ cairo_surface_t *image;
if (! gth_thumb_loader_load_finish (GTH_THUMB_LOADER (source_object),
result,
- &pixbuf,
+ &image,
NULL))
{
return;
}
- if (pixbuf != NULL) {
+ if (image != NULL) {
+ GdkPixbuf *pixbuf;
+
+ pixbuf = _gdk_pixbuf_new_from_cairo_surface (image);
gtk_image_set_from_pixbuf (GTK_IMAGE (_gtk_builder_get_widget (builder, "request_image")),
pixbuf);
+
g_object_unref (pixbuf);
+ cairo_surface_destroy (image);
}
g_object_unref (builder);
diff --git a/gthumb/cairo-utils.c b/gthumb/cairo-utils.c
index de9a1e0..ae99a12 100644
--- a/gthumb/cairo-utils.c
+++ b/gthumb/cairo-utils.c
@@ -25,6 +25,12 @@
#include "cairo-utils.h"
+G_DEFINE_BOXED_TYPE (GthCairoSurface,
+ gth_cairo_surface,
+ (GBoxedCopyFunc) cairo_surface_reference,
+ (GBoxedFreeFunc) cairo_surface_destroy)
+
+
const unsigned char cairo_channel[4] = { CAIRO_RED, CAIRO_GREEN, CAIRO_BLUE, CAIRO_ALPHA };
diff --git a/gthumb/cairo-utils.h b/gthumb/cairo-utils.h
index 92e3dad..d3c0ea4 100644
--- a/gthumb/cairo-utils.h
+++ b/gthumb/cairo-utils.h
@@ -118,6 +118,11 @@
/* types */
+typedef cairo_surface_t GthCairoSurface;
+
+GType gth_cairo_surface_get_type (void);
+#define GTH_TYPE_CAIRO_SURFACE (gth_cairo_surface_get_type ())
+
typedef struct {
guchar r;
guchar g;
diff --git a/gthumb/gth-file-list.c b/gthumb/gth-file-list.c
index 847705d..29ee78b 100644
--- a/gthumb/gth-file-list.c
+++ b/gthumb/gth-file-list.c
@@ -86,7 +86,7 @@ typedef struct {
* image. */
guint thumb_created : 1; /* Whether a thumb has been
* created for this image. */
- GdkPixbuf *pixbuf;
+ cairo_surface_t *image;
} ThumbData;
@@ -415,7 +415,7 @@ thumb_data_unref (ThumbData *data)
data->ref--;
if (data->ref > 0)
return;
- _g_object_unref (data->pixbuf);
+ cairo_surface_destroy (data->image);
g_free (data);
}
@@ -888,11 +888,11 @@ gfl_add_files (GthFileList *file_list,
cache_base_uri = g_strconcat (get_home_uri (), "/.thumbnails", NULL);
for (scan = files; scan; scan = scan->next) {
- GthFileData *file_data = scan->data;
- char *uri;
- ThumbData *thumb_data;
- GIcon *icon;
- GdkPixbuf *pixbuf = NULL;
+ GthFileData *file_data = scan->data;
+ char *uri;
+ ThumbData *thumb_data;
+ GIcon *icon;
+ cairo_surface_t *image = NULL;
if (g_file_info_get_file_type (file_data->info) != G_FILE_TYPE_REGULAR)
continue;
@@ -912,14 +912,13 @@ gfl_add_files (GthFileList *file_list,
thumb_data);
icon = g_file_info_get_icon (file_data->info);
- pixbuf = gth_icon_cache_get_pixbuf (file_list->priv->icon_cache, icon);
+ image = gth_icon_cache_get_surface (file_list->priv->icon_cache, icon);
gth_file_store_queue_add (file_store,
file_data,
- pixbuf,
+ image,
TRUE);
- if (pixbuf != NULL)
- g_object_unref (pixbuf);
+ cairo_surface_destroy (image);
g_free (uri);
}
g_free (cache_base_uri);
@@ -1239,10 +1238,10 @@ gfl_enable_thumbs (GthFileList *file_list,
file_store = (GthFileStore*) gth_file_view_get_model (GTH_FILE_VIEW (file_list->priv->view));
if (gth_file_store_get_first (file_store, &iter)) {
do {
- GthFileData *file_data;
- ThumbData *thumb_data;
- GIcon *icon;
- GdkPixbuf *pixbuf;
+ GthFileData *file_data;
+ ThumbData *thumb_data;
+ GIcon *icon;
+ cairo_surface_t *image;
file_data = gth_file_store_get_file (file_store, &iter);
@@ -1251,14 +1250,14 @@ gfl_enable_thumbs (GthFileList *file_list,
thumb_data->thumb_loaded = FALSE;
icon = g_file_info_get_icon (file_data->info);
- pixbuf = gth_icon_cache_get_pixbuf (file_list->priv->icon_cache, icon);
+ image = gth_icon_cache_get_surface (file_list->priv->icon_cache, icon);
gth_file_store_queue_set (file_store,
&iter,
- GTH_FILE_STORE_THUMBNAIL_COLUMN, pixbuf,
+ GTH_FILE_STORE_THUMBNAIL_COLUMN, image,
GTH_FILE_STORE_IS_ICON_COLUMN, TRUE,
-1);
- _g_object_unref (pixbuf);
+ cairo_surface_destroy (image);
}
while (gth_file_store_get_next (file_store, &iter));
@@ -1476,12 +1475,12 @@ update_thumb_in_file_view (GthFileList *file_list,
if (thumb_data == NULL)
return;
- if (thumb_data->pixbuf == NULL)
+ if (thumb_data->image == NULL)
return;
gth_file_store_queue_set (file_store,
&iter,
- GTH_FILE_STORE_THUMBNAIL_COLUMN, thumb_data->pixbuf,
+ GTH_FILE_STORE_THUMBNAIL_COLUMN, thumb_data->image,
GTH_FILE_STORE_IS_ICON_COLUMN, FALSE,
-1);
queue_flash_updates (file_list);
@@ -1493,25 +1492,25 @@ set_mime_type_icon (GthFileList *file_list,
GthFileData *file_data,
int try_pos)
{
- GthFileStore *file_store;
- GtkTreeIter iter;
- GIcon *icon;
- GdkPixbuf *pixbuf;
+ GthFileStore *file_store;
+ GtkTreeIter iter;
+ GIcon *icon;
+ cairo_surface_t *image;
file_store = (GthFileStore *) gth_file_view_get_model (GTH_FILE_VIEW (file_list->priv->view));
if (! get_file_data_iter_with_suggested_pos (file_store, file_data, try_pos, &iter))
return;
icon = g_file_info_get_icon (file_data->info);
- pixbuf = gth_icon_cache_get_pixbuf (file_list->priv->icon_cache, icon);
+ image = gth_icon_cache_get_surface (file_list->priv->icon_cache, icon);
gth_file_store_queue_set (file_store,
&iter,
- GTH_FILE_STORE_THUMBNAIL_COLUMN, pixbuf,
+ GTH_FILE_STORE_THUMBNAIL_COLUMN, image,
GTH_FILE_STORE_IS_ICON_COLUMN, TRUE,
-1);
queue_flash_updates (file_list);
- _g_object_unref (pixbuf);
+ cairo_surface_destroy (image);
}
@@ -1520,37 +1519,37 @@ thumbnail_job_ready_cb (GObject *source_object,
GAsyncResult *result,
gpointer user_data)
{
- ThumbnailJob *job = user_data;
- GthFileList *file_list = job->file_list;
- gboolean success;
- GdkPixbuf *pixbuf = NULL;
- GError *error = NULL;
- ThumbData *thumb_data;
+ ThumbnailJob *job = user_data;
+ GthFileList *file_list = job->file_list;
+ gboolean success;
+ cairo_surface_t *image = NULL;
+ GError *error = NULL;
+ ThumbData *thumb_data;
success = gth_thumb_loader_load_finish (GTH_THUMB_LOADER (source_object),
result,
- &pixbuf,
+ &image,
&error);
job->started = FALSE;
if ((! success && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|| file_list->priv->cancelling)
{
- _g_object_unref (pixbuf);
+ cairo_surface_destroy (image);
thumbnail_job_free (job);
return;
}
thumb_data = g_hash_table_lookup (file_list->priv->thumb_data, job->file_data->file);
if (thumb_data == NULL) {
- _g_object_unref (pixbuf);
+ cairo_surface_destroy (image);
thumbnail_job_free (job);
_gth_file_list_update_next_thumb (file_list);
return;
}
- _g_object_unref (thumb_data->pixbuf);
- thumb_data->pixbuf = NULL;
+ cairo_surface_destroy (thumb_data->image);
+ thumb_data->image = NULL;
if (! success) {
thumb_data->thumb_created = FALSE;
@@ -1561,7 +1560,7 @@ thumbnail_job_ready_cb (GObject *source_object,
thumb_data->error = TRUE;
}
else {
- thumb_data->pixbuf = g_object_ref (pixbuf);
+ thumb_data->image = cairo_surface_reference (image);
thumb_data->thumb_created = TRUE;
thumb_data->error = FALSE;
if (job->update_in_view) {
@@ -1570,7 +1569,7 @@ thumbnail_job_ready_cb (GObject *source_object,
}
}
- _g_object_unref (pixbuf);
+ cairo_surface_destroy (image);
thumbnail_job_free (job);
_gth_file_list_update_next_thumb (file_list);
@@ -1582,25 +1581,25 @@ set_loading_icon (GthFileList *file_list,
GthFileData *file_data,
int try_pos)
{
- GthFileStore *file_store;
- GtkTreeIter iter;
- GIcon *icon;
- GdkPixbuf *pixbuf;
+ GthFileStore *file_store;
+ GtkTreeIter iter;
+ GIcon *icon;
+ cairo_surface_t *image;
file_store = (GthFileStore *) gth_file_view_get_model (GTH_FILE_VIEW (file_list->priv->view));
if (! get_file_data_iter_with_suggested_pos (file_store, file_data, try_pos, &iter))
return;
icon = g_themed_icon_new ("image-loading");
- pixbuf = gth_icon_cache_get_pixbuf (file_list->priv->icon_cache, icon);
+ image = gth_icon_cache_get_surface (file_list->priv->icon_cache, icon);
gth_file_store_queue_set (file_store,
&iter,
- GTH_FILE_STORE_THUMBNAIL_COLUMN, pixbuf,
+ GTH_FILE_STORE_THUMBNAIL_COLUMN, image,
GTH_FILE_STORE_IS_ICON_COLUMN, TRUE,
-1);
queue_flash_updates (file_list);
- _g_object_unref (pixbuf);
+ cairo_surface_destroy (image);
g_object_unref (icon);
}
diff --git a/gthumb/gth-file-store.c b/gthumb/gth-file-store.c
index 5a23416..bc5c30b 100644
--- a/gthumb/gth-file-store.c
+++ b/gthumb/gth-file-store.c
@@ -21,6 +21,7 @@
#include <config.h>
#include <glib/gi18n.h>
+#include "cairo-utils.h"
#include "glib-utils.h"
#include "gth-file-store.h"
#include "gth-marshal.h"
@@ -44,11 +45,10 @@ static guint gth_file_store_signals[LAST_SIGNAL] = { 0 };
typedef struct {
- int ref_count;
-
- GthFileData *file_data;
- GdkPixbuf *thumbnail;
- gboolean is_icon : 1;
+ int ref_count;
+ GthFileData *file_data;
+ cairo_surface_t *thumbnail;
+ gboolean is_icon : 1;
/*< private >*/
@@ -115,13 +115,13 @@ _gth_file_row_set_file (GthFileRow *row,
static void
-_gth_file_row_set_thumbnail (GthFileRow *row,
- GdkPixbuf *thumbnail)
+_gth_file_row_set_thumbnail (GthFileRow *row,
+ cairo_surface_t *thumbnail)
{
if (thumbnail != NULL) {
- g_object_ref (thumbnail);
+ cairo_surface_reference (thumbnail);
if (row->thumbnail != NULL)
- g_object_unref (row->thumbnail);
+ cairo_surface_destroy (row->thumbnail);
row->thumbnail = thumbnail;
}
}
@@ -162,7 +162,7 @@ _gth_file_row_unref (GthFileRow *row)
if (row->file_data != NULL)
g_object_unref (row->file_data);
if (row->thumbnail != NULL)
- g_object_unref (row->thumbnail);
+ cairo_surface_destroy (row->thumbnail);
g_free (row);
}
@@ -263,7 +263,7 @@ gth_file_store_init (GthFileStore *file_store)
if (column_type[0] == G_TYPE_INVALID) {
column_type[GTH_FILE_STORE_FILE_DATA_COLUMN] = GTH_TYPE_FILE_DATA;
- column_type[GTH_FILE_STORE_THUMBNAIL_COLUMN] = GDK_TYPE_PIXBUF;
+ column_type[GTH_FILE_STORE_THUMBNAIL_COLUMN] = GTH_TYPE_CAIRO_SURFACE;
column_type[GTH_FILE_STORE_IS_ICON_COLUMN] = G_TYPE_BOOLEAN;
column_type[GTH_FILE_STORE_EMBLEMS_COLUMN] = GTH_TYPE_STRING_LIST;
}
@@ -370,8 +370,8 @@ gth_file_store_get_value (GtkTreeModel *tree_model,
g_value_set_object (value, row->file_data);
break;
case GTH_FILE_STORE_THUMBNAIL_COLUMN:
- g_value_init (value, GDK_TYPE_PIXBUF);
- g_value_set_object (value, row->thumbnail);
+ g_value_init (value, GTH_TYPE_CAIRO_SURFACE);
+ g_value_set_boxed (value, row->thumbnail);
break;
case GTH_FILE_STORE_IS_ICON_COLUMN:
g_value_init (value, G_TYPE_BOOLEAN);
@@ -1350,11 +1350,11 @@ gth_file_store_get_prev_visible (GthFileStore *file_store,
void
-gth_file_store_add (GthFileStore *file_store,
- GthFileData *file,
- GdkPixbuf *thumbnail,
- gboolean is_icon,
- int position)
+gth_file_store_add (GthFileStore *file_store,
+ GthFileData *file,
+ cairo_surface_t *thumbnail,
+ gboolean is_icon,
+ int position)
{
gth_file_store_queue_add (file_store, file, thumbnail, is_icon);
gth_file_store_exec_add (file_store, position);
@@ -1362,10 +1362,10 @@ gth_file_store_add (GthFileStore *file_store,
void
-gth_file_store_queue_add (GthFileStore *file_store,
- GthFileData *file,
- GdkPixbuf *thumbnail,
- gboolean is_icon)
+gth_file_store_queue_add (GthFileStore *file_store,
+ GthFileData *file,
+ cairo_surface_t *thumbnail,
+ gboolean is_icon)
{
GthFileRow *row;
@@ -1403,9 +1403,9 @@ gth_file_store_queue_set_valist (GthFileStore *file_store,
column = va_arg (var_args, int);
while (column != -1) {
- GthFileData *file_data;
- GdkPixbuf *thumbnail;
- GthStringList *string_list;
+ GthFileData *file_data;
+ cairo_surface_t *thumbnail;
+ GthStringList *string_list;
switch (column) {
case GTH_FILE_STORE_FILE_DATA_COLUMN:
@@ -1416,8 +1416,7 @@ gth_file_store_queue_set_valist (GthFileStore *file_store,
file_store->priv->update_filter = TRUE;
break;
case GTH_FILE_STORE_THUMBNAIL_COLUMN:
- thumbnail = va_arg (var_args, GdkPixbuf *);
- g_return_if_fail (GDK_IS_PIXBUF (thumbnail));
+ thumbnail = va_arg (var_args, cairo_surface_t *);
_gth_file_row_set_thumbnail (row, thumbnail);
row->changed = TRUE;
break;
diff --git a/gthumb/gth-file-store.h b/gthumb/gth-file-store.h
index b4db381..543de31 100644
--- a/gthumb/gth-file-store.h
+++ b/gthumb/gth-file-store.h
@@ -100,12 +100,12 @@ gboolean gth_file_store_get_prev_visible (GthFileStore *file_sto
GtkTreeIter *iter);
void gth_file_store_add (GthFileStore *file_store,
GthFileData *file,
- GdkPixbuf *thumbnail,
+ cairo_surface_t *thumbnail,
gboolean is_icon,
int position);
void gth_file_store_queue_add (GthFileStore *file_store,
GthFileData *file,
- GdkPixbuf *thumbnail,
+ cairo_surface_t *thumbnail,
gboolean is_icon);
void gth_file_store_exec_add (GthFileStore *file_store,
int position);
diff --git a/gthumb/gth-grid-view.c b/gthumb/gth-grid-view.c
index 8865e67..9d34055 100644
--- a/gthumb/gth-grid-view.c
+++ b/gthumb/gth-grid-view.c
@@ -108,7 +108,7 @@ typedef struct {
guint ref;
GthFileData *file_data;
- GdkPixbuf *thumbnail;
+ cairo_surface_t *thumbnail;
gboolean is_icon : 1;
char *caption;
gboolean is_image : 1;
@@ -230,14 +230,14 @@ gth_grid_view_item_set_file_data (GthGridViewItem *item,
static void
gth_grid_view_item_set_thumbnail (GthGridViewItem *item,
- GdkPixbuf *thumbnail)
+ cairo_surface_t *thumbnail)
{
- _g_object_unref (item->thumbnail);
- item->thumbnail = _g_object_ref (thumbnail);
+ cairo_surface_destroy (item->thumbnail);
+ item->thumbnail = cairo_surface_reference (thumbnail);
if (item->thumbnail != NULL) {
- item->pixbuf_area.width = gdk_pixbuf_get_width (item->thumbnail);
- item->pixbuf_area.height = gdk_pixbuf_get_height (item->thumbnail);
+ item->pixbuf_area.width = cairo_image_surface_get_width (item->thumbnail);
+ item->pixbuf_area.height = cairo_image_surface_get_height (item->thumbnail);
}
else {
item->pixbuf_area.width = 0;
@@ -312,11 +312,11 @@ gth_grid_view_item_update_caption (GthGridViewItem *item,
static GthGridViewItem *
-gth_grid_view_item_new (GthGridView *grid_view,
- GthFileData *file_data,
- GdkPixbuf *thumbnail,
- gboolean is_icon,
- char **attributes_v)
+gth_grid_view_item_new (GthGridView *grid_view,
+ GthFileData *file_data,
+ cairo_surface_t *thumbnail,
+ gboolean is_icon,
+ char **attributes_v)
{
GthGridViewItem *item;
@@ -347,7 +347,7 @@ gth_grid_view_item_unref (GthGridViewItem *item)
return;
g_free (item->caption);
- _g_object_unref (item->thumbnail);
+ cairo_surface_destroy (item->thumbnail);
_g_object_unref (item->file_data);
g_free (item);
}
@@ -1270,18 +1270,18 @@ _gth_grid_view_item_draw_thumbnail (GthGridViewItem *item,
GtkStateFlags item_state,
GthGridView *grid_view)
{
- GdkPixbuf *pixbuf;
+ cairo_surface_t *image;
GtkStyleContext *style_context;
cairo_rectangle_int_t frame_rect;
GdkRGBA background_color;
GdkRGBA lighter_color;
GdkRGBA darker_color;
- pixbuf = item->thumbnail;
- if (pixbuf == NULL)
+ image = item->thumbnail;
+ if (image == NULL)
return;
- g_object_ref (pixbuf);
+ cairo_surface_reference (image);
cairo_save (cr);
style_context = gtk_widget_get_style_context (widget);
@@ -1460,7 +1460,7 @@ _gth_grid_view_item_draw_thumbnail (GthGridViewItem *item,
/* thumbnail */
- gdk_cairo_set_source_pixbuf (cr, pixbuf, item->pixbuf_area.x, item->pixbuf_area.y);
+ cairo_set_source_surface (cr, image, item->pixbuf_area.x, item->pixbuf_area.y);
cairo_rectangle (cr, item->pixbuf_area.x, item->pixbuf_area.y, item->pixbuf_area.width,
item->pixbuf_area.height);
cairo_fill (cr);
@@ -1480,7 +1480,7 @@ _gth_grid_view_item_draw_thumbnail (GthGridViewItem *item,
gtk_style_context_restore (style_context);
cairo_restore (cr);
- g_object_unref (pixbuf);
+ cairo_surface_destroy (image);
}
@@ -1538,21 +1538,25 @@ _gth_grid_view_item_draw_emblems (GthGridViewItem *item,
emblem_offset = 0;
emblems = (GthStringList *) g_file_info_get_attribute_object (item->file_data->info,
GTH_FILE_ATTRIBUTE_EMBLEMS);
for (scan = gth_string_list_get_list (emblems); scan; scan = scan->next) {
- char *emblem = scan->data;
- GIcon *icon;
- GdkPixbuf *pixbuf;
+ char *emblem = scan->data;
+ GIcon *icon;
+ cairo_surface_t *image;
if (grid_view->priv->icon_cache == NULL)
grid_view->priv->icon_cache = gth_icon_cache_new (gtk_icon_theme_get_for_screen
(gtk_widget_get_screen (GTK_WIDGET (grid_view))), EMBLEM_SIZE);
icon = g_themed_icon_new (emblem);
- pixbuf = gth_icon_cache_get_pixbuf (grid_view->priv->icon_cache, icon);
- if (pixbuf != NULL) {
- gdk_cairo_set_source_pixbuf (cr, pixbuf, item->thumbnail_area.x + emblem_offset + 1,
item->thumbnail_area.y + 1);
- cairo_rectangle (cr, item->thumbnail_area.x + emblem_offset + 1,
item->thumbnail_area.y + 1, gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf));
+ image = gth_icon_cache_get_surface (grid_view->priv->icon_cache, icon);
+ if (image != NULL) {
+ cairo_set_source_surface (cr, image, item->thumbnail_area.x + emblem_offset + 1,
item->thumbnail_area.y + 1);
+ cairo_rectangle (cr,
+ item->thumbnail_area.x + emblem_offset + 1,
+ item->thumbnail_area.y + 1,
+ cairo_image_surface_get_width (image),
+ cairo_image_surface_get_height (image));
cairo_fill (cr);
- g_object_unref (pixbuf);
+ cairo_surface_destroy (image);
emblem_offset += EMBLEM_SIZE + (EMBLEM_SIZE / 2);
}
@@ -2154,7 +2158,7 @@ model_row_changed_cb (GtkTreeModel *tree_model,
int pos;
GList *link;
GthFileData *file_data;
- GdkPixbuf *thumbnail;
+ cairo_surface_t *thumbnail;
gboolean is_icon;
GthGridViewItem *item;
@@ -2178,7 +2182,7 @@ model_row_changed_cb (GtkTreeModel *tree_model,
_gth_grid_view_queue_relayout_from_position (self, pos);
g_object_unref (file_data);
- g_object_unref (thumbnail);
+ cairo_surface_destroy (thumbnail);
}
@@ -2231,7 +2235,7 @@ model_row_inserted_cb (GtkTreeModel *tree_model,
{
GthGridView *self = user_data;
GthFileData *file_data;
- GdkPixbuf *thumbnail;
+ cairo_surface_t *thumbnail;
gboolean is_icon;
GthGridViewItem *item;
int pos;
@@ -2265,7 +2269,7 @@ model_row_inserted_cb (GtkTreeModel *tree_model,
_gth_grid_view_queue_relayout_from_position (self, pos);
g_object_unref (file_data);
- g_object_unref (thumbnail);
+ cairo_surface_destroy (thumbnail);
}
@@ -2334,7 +2338,7 @@ model_thumbnail_changed_cb (GtkTreeModel *tree_model,
GthGridView *self = user_data;
int pos;
GList *link;
- GdkPixbuf *thumbnail;
+ cairo_surface_t *thumbnail;
gboolean is_icon;
GthGridViewItem *item;
@@ -2356,7 +2360,7 @@ model_thumbnail_changed_cb (GtkTreeModel *tree_model,
_gth_grid_view_place_item_at (self, item, item->area.x, item->area.y);
_gth_grid_view_queue_draw_item (self, item);
- g_object_unref (thumbnail);
+ cairo_surface_destroy (thumbnail);
}
diff --git a/gthumb/gth-icon-cache.c b/gthumb/gth-icon-cache.c
index 514c48d..1806e87 100644
--- a/gthumb/gth-icon-cache.c
+++ b/gthumb/gth-icon-cache.c
@@ -20,6 +20,8 @@
*/
#include <config.h>
+#include <cairo.h>
+#include "cairo-utils.h"
#include "glib-utils.h"
#include "gth-icon-cache.h"
#include "gtk-utils.h"
@@ -28,7 +30,8 @@
struct _GthIconCache {
GtkIconTheme *icon_theme;
int icon_size;
- GHashTable *cache;
+ GHashTable *pixbuf_cache;
+ GHashTable *surface_cache;
GIcon *fallback_icon;
};
@@ -44,7 +47,8 @@ gth_icon_cache_new (GtkIconTheme *icon_theme,
icon_cache = g_new0 (GthIconCache, 1);
icon_cache->icon_theme = icon_theme;
icon_cache->icon_size = icon_size;
- icon_cache->cache = g_hash_table_new_full (g_icon_hash, (GEqualFunc) g_icon_equal, g_object_unref,
g_object_unref);
+ icon_cache->pixbuf_cache = g_hash_table_new_full (g_icon_hash, (GEqualFunc) g_icon_equal,
g_object_unref, g_object_unref);
+ icon_cache->surface_cache = g_hash_table_new_full (g_icon_hash, (GEqualFunc) g_icon_equal,
g_object_unref, (GDestroyNotify) cairo_surface_destroy);
return icon_cache;
}
@@ -79,7 +83,8 @@ gth_icon_cache_free (GthIconCache *icon_cache)
{
if (icon_cache == NULL)
return;
- g_hash_table_destroy (icon_cache->cache);
+ g_hash_table_destroy (icon_cache->pixbuf_cache);
+ g_hash_table_destroy (icon_cache->surface_cache);
if (icon_cache->fallback_icon != NULL)
g_object_unref (icon_cache->fallback_icon);
g_free (icon_cache);
@@ -89,8 +94,10 @@ gth_icon_cache_free (GthIconCache *icon_cache)
void
gth_icon_cache_clear (GthIconCache *icon_cache)
{
- if (icon_cache != NULL)
- g_hash_table_remove_all (icon_cache->cache);
+ if (icon_cache == NULL)
+ return;
+ g_hash_table_remove_all (icon_cache->pixbuf_cache);
+ g_hash_table_remove_all (icon_cache->surface_cache);
}
@@ -104,7 +111,7 @@ gth_icon_cache_get_pixbuf (GthIconCache *icon_cache,
icon = icon_cache->fallback_icon;
if (icon != NULL)
- pixbuf = g_hash_table_lookup (icon_cache->cache, icon);
+ pixbuf = g_hash_table_lookup (icon_cache->pixbuf_cache, icon);
if (pixbuf != NULL)
return g_object_ref (pixbuf);
@@ -116,7 +123,35 @@ gth_icon_cache_get_pixbuf (GthIconCache *icon_cache,
pixbuf = _g_icon_get_pixbuf (icon_cache->fallback_icon, icon_cache->icon_size,
icon_cache->icon_theme);
if ((icon != NULL) && (pixbuf != NULL))
- g_hash_table_insert (icon_cache->cache, g_object_ref (icon), g_object_ref (pixbuf));
+ g_hash_table_insert (icon_cache->pixbuf_cache, g_object_ref (icon), g_object_ref (pixbuf));
return pixbuf;
}
+
+
+cairo_surface_t *
+gth_icon_cache_get_surface (GthIconCache *icon_cache,
+ GIcon *icon)
+{
+ cairo_surface_t *surface = NULL;
+ GdkPixbuf *pixbuf;
+
+ if (icon == NULL)
+ icon = icon_cache->fallback_icon;
+
+ if (icon != NULL)
+ surface = g_hash_table_lookup (icon_cache->surface_cache, icon);
+
+ if (surface != NULL)
+ return cairo_surface_reference (surface);
+
+ pixbuf = gth_icon_cache_get_pixbuf (icon_cache, icon);
+ surface = _cairo_image_surface_create_from_pixbuf (pixbuf);
+
+ if ((icon != NULL) && (surface != NULL))
+ g_hash_table_insert (icon_cache->surface_cache, g_object_ref (icon), cairo_surface_reference
(surface));
+
+ g_object_unref (pixbuf);
+
+ return surface;
+}
diff --git a/gthumb/gth-icon-cache.h b/gthumb/gth-icon-cache.h
index 2da8969..7df557b 100644
--- a/gthumb/gth-icon-cache.h
+++ b/gthumb/gth-icon-cache.h
@@ -23,21 +23,24 @@
#define GTH_ICON_CACHE_H
#include <gtk/gtk.h>
+#include <cairo.h>
G_BEGIN_DECLS
typedef struct _GthIconCache GthIconCache;
-GthIconCache * gth_icon_cache_new (GtkIconTheme *icon_theme,
- int icon_size);
-GthIconCache * gth_icon_cache_new_for_widget (GtkWidget *widget,
- GtkIconSize icon_size);
-void gth_icon_cache_set_fallback (GthIconCache *icon_cache,
- GIcon *icon);
-void gth_icon_cache_free (GthIconCache *icon_cache);
-void gth_icon_cache_clear (GthIconCache *icon_cache);
-GdkPixbuf * gth_icon_cache_get_pixbuf (GthIconCache *icon_cache,
- GIcon *icon);
+GthIconCache * gth_icon_cache_new (GtkIconTheme *icon_theme,
+ int icon_size);
+GthIconCache * gth_icon_cache_new_for_widget (GtkWidget *widget,
+ GtkIconSize icon_size);
+void gth_icon_cache_set_fallback (GthIconCache *icon_cache,
+ GIcon *icon);
+void gth_icon_cache_free (GthIconCache *icon_cache);
+void gth_icon_cache_clear (GthIconCache *icon_cache);
+GdkPixbuf * gth_icon_cache_get_pixbuf (GthIconCache *icon_cache,
+ GIcon *icon);
+cairo_surface_t * gth_icon_cache_get_surface (GthIconCache *icon_cache,
+ GIcon *icon);
G_END_DECLS
diff --git a/gthumb/gth-thumb-loader.c b/gthumb/gth-thumb-loader.c
index f99d57a..e8638c7 100644
--- a/gthumb/gth-thumb-loader.c
+++ b/gthumb/gth-thumb-loader.c
@@ -29,6 +29,7 @@
#define GDK_PIXBUF_ENABLE_BACKEND
#include <gtk/gtk.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
+#include "cairo-utils.h"
#include "gio-utils.h"
#include "glib-utils.h"
#define GNOME_DESKTOP_USE_UNSTABLE_API
@@ -208,9 +209,9 @@ load_cached_thumbnail (GInputStream *istream,
GCancellable *cancellable,
GError **error)
{
- GthImage *image = NULL;
- char *filename;
- GdkPixbuf *pixbuf;
+ GthImage *image = NULL;
+ char *filename;
+ cairo_surface_t *surface;
if (file_data == NULL) {
if (error != NULL)
@@ -219,12 +220,13 @@ load_cached_thumbnail (GInputStream *istream,
}
filename = g_file_get_path (file_data->file);
- pixbuf = gdk_pixbuf_new_from_file (filename, error);
- if (pixbuf != NULL) {
- image = gth_image_new_for_pixbuf (pixbuf);
- g_object_unref (pixbuf);
- }
+ surface = cairo_image_surface_create_from_png (filename);
+ if (cairo_surface_status (surface) == CAIRO_STATUS_SUCCESS)
+ image = gth_image_new_for_surface (surface);
+ else
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, cairo_status_to_string
(cairo_surface_status (surface)));
+ cairo_surface_destroy (surface);
g_free (filename);
return image;
@@ -363,8 +365,8 @@ load_data_unref (LoadData *load_data)
typedef struct {
- GthFileData *file_data;
- GdkPixbuf *pixbuf;
+ GthFileData *file_data;
+ cairo_surface_t *image;
} LoadResult;
@@ -372,7 +374,7 @@ static void
load_result_unref (LoadResult *load_result)
{
g_object_unref (load_result->file_data);
- _g_object_unref (load_result->pixbuf);
+ cairo_surface_destroy (load_result->image);
g_free (load_result);
}
@@ -422,14 +424,14 @@ cache_image_ready_cb (GObject *source_object,
GAsyncResult *res,
gpointer user_data)
{
- LoadData *load_data = user_data;
- GthThumbLoader *self = load_data->thumb_loader;
- GthImage *image = NULL;
- GdkPixbuf *pixbuf;
- int width;
- int height;
- gboolean modified;
- LoadResult *load_result;
+ LoadData *load_data = user_data;
+ GthThumbLoader *self = load_data->thumb_loader;
+ GthImage *image = NULL;
+ cairo_surface_t *surface;
+ int width;
+ int height;
+ gboolean modified;
+ LoadResult *load_result;
if (! gth_image_loader_load_finish (GTH_IMAGE_LOADER (source_object),
res,
@@ -455,12 +457,12 @@ cache_image_ready_cb (GObject *source_object,
/* Thumbnail correctly loaded from the cache. Scale if the user wants
* a different size. */
- pixbuf = gth_image_get_pixbuf (image);
+ surface = gth_image_get_cairo_surface (image);
- g_return_if_fail (pixbuf != NULL);
+ g_return_if_fail (surface != NULL);
- width = gdk_pixbuf_get_width (pixbuf);
- height = gdk_pixbuf_get_height (pixbuf);
+ width = cairo_image_surface_get_width (surface);
+ height = cairo_image_surface_get_height (surface);
modified = normalize_thumb (&width,
&height,
self->priv->requested_size,
@@ -473,7 +475,7 @@ cache_image_ready_cb (GObject *source_object,
load_result = g_new0 (LoadResult, 1);
load_result->file_data = g_object_ref (load_data->file_data);
- load_result->pixbuf = pixbuf;
+ load_result->image = surface;
g_simple_async_result_set_op_res_gpointer (load_data->simple, load_result, (GDestroyNotify)
load_result_unref);
g_simple_async_result_complete_in_idle (load_data->simple);
@@ -506,13 +508,14 @@ is_a_cache_file (const char *uri)
static gboolean
-_gth_thumb_loader_save_to_cache (GthThumbLoader *self,
- GthFileData *file_data,
- GdkPixbuf *pixbuf)
+_gth_thumb_loader_save_to_cache (GthThumbLoader *self,
+ GthFileData *file_data,
+ cairo_surface_t *image)
{
- char *uri;
+ char *uri;
+ GdkPixbuf *pixbuf;
- if ((self == NULL) || (pixbuf == NULL))
+ if ((self == NULL) || (image == NULL))
return FALSE;
uri = g_file_get_uri (file_data->file);
@@ -525,11 +528,17 @@ _gth_thumb_loader_save_to_cache (GthThumbLoader *self,
return FALSE;
}
+ pixbuf = _gdk_pixbuf_new_from_cairo_surface (image);
+ if (pixbuf == NULL)
+ return FALSE;
+
gnome_desktop_thumbnail_factory_save_thumbnail (self->priv->thumb_factory,
pixbuf,
uri,
gth_file_data_get_mtime (file_data));
+ g_object_unref (pixbuf);
+
return TRUE;
}
@@ -537,18 +546,18 @@ _gth_thumb_loader_save_to_cache (GthThumbLoader *self,
static void
original_image_loaded_correctly (GthThumbLoader *self,
LoadData *load_data,
- GdkPixbuf *pixbuf)
+ cairo_surface_t *image)
{
- GdkPixbuf *local_pixbuf;
- int width;
- int height;
- gboolean modified;
- LoadResult *load_result;
+ cairo_surface_t *local_image;
+ int width;
+ int height;
+ gboolean modified;
+ LoadResult *load_result;
- local_pixbuf = g_object_ref (pixbuf);
+ local_image = cairo_surface_reference (image);
- width = gdk_pixbuf_get_width (local_pixbuf);
- height = gdk_pixbuf_get_height (local_pixbuf);
+ width = cairo_image_surface_get_width (local_image);
+ height = cairo_image_surface_get_height (local_image);
if (self->priv->save_thumbnails) {
gboolean modified;
@@ -568,7 +577,7 @@ original_image_loaded_correctly (GthThumbLoader *self,
g_object_unref (tmp);
}
- _gth_thumb_loader_save_to_cache (self, load_data->file_data, local_pixbuf);
+ _gth_thumb_loader_save_to_cache (self, load_data->file_data, local_image);
}
/* Scale if the user wants a different size. */
@@ -585,11 +594,11 @@ original_image_loaded_correctly (GthThumbLoader *self,
load_result = g_new0 (LoadResult, 1);
load_result->file_data = g_object_ref (load_data->file_data);
- load_result->pixbuf = g_object_ref (local_pixbuf);
+ load_result->image = cairo_surface_reference (local_image);
g_simple_async_result_set_op_res_gpointer (load_data->simple, load_result, (GDestroyNotify)
load_result_unref);
g_simple_async_result_complete_in_idle (load_data->simple);
- g_object_unref (local_pixbuf);
+ cairo_surface_destroy (local_image);
}
@@ -698,7 +707,12 @@ watch_thumbnailer_cb (GPid pid,
&load_data->thumbnailer_tmpfile);
if (pixbuf != NULL) {
- original_image_loaded_correctly (self, load_data, pixbuf);
+ cairo_surface_t *surface;
+
+ surface = _cairo_image_surface_create_from_pixbuf (pixbuf);
+ original_image_loaded_correctly (self, load_data, surface);
+
+ cairo_surface_destroy (surface);
g_object_unref (pixbuf);
}
else
@@ -711,11 +725,11 @@ original_image_ready_cb (GObject *source_object,
GAsyncResult *res,
gpointer user_data)
{
- LoadData *load_data = user_data;
- GthThumbLoader *self = load_data->thumb_loader;
- GthImage *image = NULL;
- GdkPixbuf *pixbuf = NULL;
- GError *error = NULL;
+ LoadData *load_data = user_data;
+ GthThumbLoader *self = load_data->thumb_loader;
+ GthImage *image = NULL;
+ cairo_surface_t *surface = NULL;
+ GError *error = NULL;
if (! gth_image_loader_load_finish (GTH_IMAGE_LOADER (source_object),
res,
@@ -766,10 +780,10 @@ original_image_ready_cb (GObject *source_object,
return;
}
- pixbuf = gth_image_get_pixbuf (image);
- original_image_loaded_correctly (self, load_data, pixbuf);
+ surface = gth_image_get_cairo_surface (image);
+ original_image_loaded_correctly (self, load_data, surface);
- g_object_unref (pixbuf);
+ cairo_surface_destroy (surface);
g_object_unref (image);
load_data_unref (load_data);
}
@@ -875,10 +889,10 @@ gth_thumb_loader_load (GthThumbLoader *self,
gboolean
-gth_thumb_loader_load_finish (GthThumbLoader *self,
- GAsyncResult *result,
- GdkPixbuf **pixbuf,
- GError **error)
+gth_thumb_loader_load_finish (GthThumbLoader *self,
+ GAsyncResult *result,
+ cairo_surface_t **image,
+ GError **error)
{
GSimpleAsyncResult *simple;
LoadResult *load_result;
@@ -891,8 +905,8 @@ gth_thumb_loader_load_finish (GthThumbLoader *self,
return FALSE;
load_result = g_simple_async_result_get_op_res_gpointer (simple);
- if (pixbuf != NULL)
- *pixbuf = _g_object_ref (load_result->pixbuf);
+ if (image != NULL)
+ *image = cairo_surface_reference (load_result->image);
return TRUE;
}
diff --git a/gthumb/gth-thumb-loader.h b/gthumb/gth-thumb-loader.h
index 56f8c21..544bf2b 100644
--- a/gthumb/gth-thumb-loader.h
+++ b/gthumb/gth-thumb-loader.h
@@ -72,7 +72,7 @@ void gth_thumb_loader_load (GthThumbLoader *s
gpointer user_data);
gboolean gth_thumb_loader_load_finish (GthThumbLoader *self,
GAsyncResult *res,
- GdkPixbuf **pixbuf,
+ cairo_surface_t **image,
GError **error);
gboolean gth_thumb_loader_has_valid_thumbnail (GthThumbLoader *self,
GthFileData *file_data);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]