From: Anders Carlsson Date: Wed, 22 Dec 2004 20:54:22 +0000 (+0000) Subject: Add thumbnail support. X-Git-Tag: EVINCE_0_1_0~70 X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=commitdiff_plain;h=ca0836cb912f3b88834cae97774079314727c6e2;p=evince.git Add thumbnail support. 2004-12-22 Anders Carlsson * backend/Makefile.am: * backend/ev-document-thumbnails.c: (ev_document_thumbnails_get_type), (ev_document_thumbnails_get_thumbnail): * backend/ev-document-thumbnails.h: * pixbuf/pixbuf-document.c: (G_DEFINE_TYPE_WITH_CODE), (pixbuf_document_thumbnails_get_thumbnail), (pixbuf_document_document_thumbnails_iface_init): * shell/Makefile.am: * shell/ev-sidebar-thumbnails.c: (ev_sidebar_thumbnails_destroy), (ev_sidebar_thumbnails_class_init), (ev_sidebar_thumbnails_init), (populate_thumbnails), (ev_sidebar_thumbnails_set_document): * shell/ev-sidebar-thumbnails.h: * shell/ev-sidebar.c: (ev_sidebar_init), (ev_sidebar_add_page), (ev_sidebar_set_document): * shell/ev-utils.c: (gaussian), (create_blur_filter), (create_shadow), (ev_pixbuf_add_shadow): * shell/ev-utils.h: Add thumbnail support. --- diff --git a/backend/Makefile.am b/backend/Makefile.am index 44502979..2f54157c 100644 --- a/backend/Makefile.am +++ b/backend/Makefile.am @@ -13,6 +13,8 @@ libevbackend_la_SOURCES= \ ev-backend-marshal.c \ ev-document.c \ ev-document.h \ + ev-document-thumbnails.c \ + ev-document-thumbnails.h \ ev-document-bookmarks.c \ ev-document-bookmarks.h \ $(NULL) diff --git a/backend/ev-document-thumbnails.c b/backend/ev-document-thumbnails.c new file mode 100644 index 00000000..e9c53ab9 --- /dev/null +++ b/backend/ev-document-thumbnails.c @@ -0,0 +1,55 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */ +/* + * Copyright (C) 2004 Anders Carlsson + * + * 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, 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#include "config.h" + +#include "ev-document-thumbnails.h" + +GType +ev_document_thumbnails_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) + { + static const GTypeInfo our_info = + { + sizeof (EvDocumentThumbnailsIface), + NULL, + NULL, + }; + + type = g_type_register_static (G_TYPE_INTERFACE, + "EvDocumentThumbnails", + &our_info, (GTypeFlags)0); + } + + return type; +} + +GdkPixbuf * +ev_document_thumbnails_get_thumbnail (EvDocumentThumbnails *document, + gint page, + gint width) +{ + EvDocumentThumbnailsIface *iface = EV_DOCUMENT_THUMBNAILS_GET_IFACE (document); + + return iface->get_thumbnail (document, page, width); +} diff --git a/backend/ev-document-thumbnails.h b/backend/ev-document-thumbnails.h new file mode 100644 index 00000000..fdc1e80a --- /dev/null +++ b/backend/ev-document-thumbnails.h @@ -0,0 +1,56 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */ +/* + * Copyright (C) 2004 Anders Carlsson + * + * 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, 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#ifndef EV_DOCUMENT_THUMBNAILS_H +#define EV_DOCUMENT_THUMBNAILS_H + +#include + +G_BEGIN_DECLS + +#define EV_TYPE_DOCUMENT_THUMBNAILS (ev_document_thumbnails_get_type ()) +#define EV_DOCUMENT_THUMBNAILS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EV_TYPE_DOCUMENT_THUMBNAILS, EvDocumentThumbnails)) +#define EV_DOCUMENT_THUMBNAILS_IFACE(k) (G_TYPE_CHECK_CLASS_CAST((k), EV_TYPE_DOCUMENT_THUMBNAILS, EvDocumentThumbnailsIface)) +#define EV_IS_DOCUMENT_THUMBNAILS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EV_TYPE_DOCUMENT_THUMBNAILS)) +#define EV_IS_DOCUMENT_THUMBNAILS_IFACE(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EV_TYPE_DOCUMENT_THUMBNAILS)) +#define EV_DOCUMENT_THUMBNAILS_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), EV_TYPE_DOCUMENT_THUMBNAILS, EvDocumentThumbnailsIface)) + +typedef struct _EvDocumentThumbnails EvDocumentThumbnails; +typedef struct _EvDocumentThumbnailsIface EvDocumentThumbnailsIface; + +struct _EvDocumentThumbnailsIface +{ + GTypeInterface base_iface; + + /* Methods */ + GdkPixbuf * (* get_thumbnail) (EvDocumentThumbnails *document, + gint page, + gint width); +}; + +GType ev_document_thumbnails_get_type (void); + +GdkPixbuf *ev_document_thumbnails_get_thumbnail (EvDocumentThumbnails *document, + gint page, + gint width); + +G_END_DECLS + +#endif diff --git a/pixbuf/pixbuf-document.c b/pixbuf/pixbuf-document.c index c8efd2d9..7eeb8fda 100644 --- a/pixbuf/pixbuf-document.c +++ b/pixbuf/pixbuf-document.c @@ -1,5 +1,5 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */ -/* pixbuf-document.h: Implementation of EvDocument for PIXBUF +/* * Copyright (C) 2004, Anders Carlsson * * This program is free software; you can redistribute it and/or modify @@ -18,6 +18,7 @@ */ #include "pixbuf-document.h" +#include "ev-document-thumbnails.h" struct _PixbufDocumentClass { @@ -38,10 +39,14 @@ struct _PixbufDocument typedef struct _PixbufDocumentClass PixbufDocumentClass; static void pixbuf_document_document_iface_init (EvDocumentIface *iface); +static void pixbuf_document_document_thumbnails_iface_init (EvDocumentThumbnailsIface *iface); G_DEFINE_TYPE_WITH_CODE (PixbufDocument, pixbuf_document, G_TYPE_OBJECT, { G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT, - pixbuf_document_document_iface_init) }); + pixbuf_document_document_iface_init); + G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_THUMBNAILS, + pixbuf_document_document_thumbnails_iface_init) + }); static GObjectClass *parent_class; @@ -219,6 +224,34 @@ pixbuf_document_document_iface_init (EvDocumentIface *iface) iface->end_find = pixbuf_document_end_find; } +static GdkPixbuf * +pixbuf_document_thumbnails_get_thumbnail (EvDocumentThumbnails *document, + gint page, + gint width) +{ + PixbufDocument *pixbuf_document = PIXBUF_DOCUMENT (document); + GdkPixbuf *pixbuf; + gdouble scale_factor; + gint height; + + scale_factor = (gdouble)width / gdk_pixbuf_get_width (pixbuf_document->pixbuf); + + height = gdk_pixbuf_get_height (pixbuf_document->pixbuf) * scale_factor; + + pixbuf = gdk_pixbuf_scale_simple (pixbuf_document->pixbuf, width, height, + GDK_INTERP_BILINEAR); + + return pixbuf; +} + + +static void +pixbuf_document_document_thumbnails_iface_init (EvDocumentThumbnailsIface *iface) +{ + iface->get_thumbnail = pixbuf_document_thumbnails_get_thumbnail; +} + + static void pixbuf_document_init (PixbufDocument *pixbuf_document) { diff --git a/shell/Makefile.am b/shell/Makefile.am index a36511ae..47404852 100644 --- a/shell/Makefile.am +++ b/shell/Makefile.am @@ -35,6 +35,8 @@ evince_SOURCES= \ ev-sidebar-thumbnails.h \ ev-stock-icons.c \ ev-stock-icons.h \ + ev-utils.c \ + ev-utils.h \ main.c \ $(NULL) diff --git a/shell/ev-sidebar-thumbnails.c b/shell/ev-sidebar-thumbnails.c index a2f5d76f..c727abff 100644 --- a/shell/ev-sidebar-thumbnails.c +++ b/shell/ev-sidebar-thumbnails.c @@ -1,9 +1,11 @@ /* this file is part of evince, a gnome document viewer * * Copyright (C) 2004 Red Hat, Inc. + * Copyright (C) 2004 Anders Carlsson * - * Author: + * Authors: * Jonathan Blandford + * Anders Carlsson * * Evince is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by @@ -28,23 +30,61 @@ #include #include "ev-sidebar-thumbnails.h" +#include "ev-document-thumbnails.h" +#include "ev-utils.h" + +#define THUMBNAIL_WIDTH 96 struct _EvSidebarThumbnailsPrivate { - int dummy; + GtkWidget *tree_view; + GtkListStore *list_store; + EvDocument *document; + + guint idle_id; + gint current_page, n_pages; +}; + +enum { + COLUMN_PAGE_STRING, + COLUMN_PIXBUF, + NUM_COLUMNS }; -G_DEFINE_TYPE (EvSidebarThumbnails, ev_sidebar_thumbnails, GTK_TYPE_VBOX) +static GtkVBoxClass *parent_class; + +G_DEFINE_TYPE (EvSidebarThumbnails, ev_sidebar_thumbnails, GTK_TYPE_VBOX); #define EV_SIDEBAR_THUMBNAILS_GET_PRIVATE(object) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((object), EV_TYPE_SIDEBAR_THUMBNAILS, EvSidebarThumbnailsPrivate)) + (G_TYPE_INSTANCE_GET_PRIVATE ((object), EV_TYPE_SIDEBAR_THUMBNAILS, EvSidebarThumbnailsPrivate)); + +static void +ev_sidebar_thumbnails_destroy (GtkObject *object) +{ + EvSidebarThumbnails *ev_sidebar_thumbnails = EV_SIDEBAR_THUMBNAILS (object); + EvSidebarThumbnailsPrivate *priv = ev_sidebar_thumbnails->priv; + + if (priv->idle_id != 0) { + g_source_remove (priv->idle_id); + + priv->idle_id = 0; + } + + GTK_OBJECT_CLASS (parent_class)->destroy (object); +} static void ev_sidebar_thumbnails_class_init (EvSidebarThumbnailsClass *ev_sidebar_thumbnails_class) { GObjectClass *g_object_class; - + GtkObjectClass *gtk_object_class; + g_object_class = G_OBJECT_CLASS (ev_sidebar_thumbnails_class); + gtk_object_class = GTK_OBJECT_CLASS (ev_sidebar_thumbnails_class); + parent_class = g_type_class_peek_parent (ev_sidebar_thumbnails_class); + + gtk_object_class->destroy = ev_sidebar_thumbnails_destroy; + g_type_class_add_private (g_object_class, sizeof (EvSidebarThumbnailsPrivate)); } @@ -52,14 +92,34 @@ ev_sidebar_thumbnails_class_init (EvSidebarThumbnailsClass *ev_sidebar_thumbnail static void ev_sidebar_thumbnails_init (EvSidebarThumbnails *ev_sidebar_thumbnails) { - GtkWidget *label; + GtkWidget *swindow; + EvSidebarThumbnailsPrivate *priv; + + priv = ev_sidebar_thumbnails->priv = EV_SIDEBAR_THUMBNAILS_GET_PRIVATE (ev_sidebar_thumbnails); - ev_sidebar_thumbnails->priv = EV_SIDEBAR_THUMBNAILS_GET_PRIVATE (ev_sidebar_thumbnails); + priv->list_store = gtk_list_store_new (NUM_COLUMNS, G_TYPE_STRING, GDK_TYPE_PIXBUF); + priv->tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (priv->list_store)); + + gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (priv->tree_view), FALSE); + gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (priv->tree_view), -1, + NULL, gtk_cell_renderer_pixbuf_new (), + "pixbuf", 1, NULL); + gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (priv->tree_view), -1, + NULL, gtk_cell_renderer_text_new (), + "text", 0, NULL); - label = gtk_label_new ("Thumbnails!"); - gtk_box_pack_start (GTK_BOX (ev_sidebar_thumbnails), label, - TRUE, TRUE, 0); - gtk_widget_show (label); + g_object_unref (priv->list_store); + + swindow = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow), + GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (swindow), + GTK_SHADOW_IN); + + gtk_container_add (GTK_CONTAINER (swindow), priv->tree_view); + gtk_box_pack_start (GTK_BOX (ev_sidebar_thumbnails), swindow, TRUE, TRUE, 0); + + gtk_widget_show_all (swindow); } GtkWidget * @@ -71,3 +131,82 @@ ev_sidebar_thumbnails_new (void) return ev_sidebar_thumbnails; } + +static gboolean +populate_thumbnails (gpointer data) +{ + EvSidebarThumbnails *ev_sidebar_thumbnails = EV_SIDEBAR_THUMBNAILS (data); + EvSidebarThumbnailsPrivate *priv = ev_sidebar_thumbnails->priv; + GdkPixbuf *tmp, *pixbuf; + GtkTreePath *path; + GtkTreeIter iter; + + tmp = ev_document_thumbnails_get_thumbnail (EV_DOCUMENT_THUMBNAILS (priv->document), + priv->current_page, THUMBNAIL_WIDTH); + + + /* Add shadow */ + pixbuf = ev_pixbuf_add_shadow (tmp, 5, 0, 0, 0.5); + + path = gtk_tree_path_new_from_indices (priv->current_page, -1); + gtk_tree_model_get_iter (GTK_TREE_MODEL (priv->list_store), &iter, path); + gtk_tree_path_free (path); + + gtk_list_store_set (priv->list_store, &iter, + COLUMN_PIXBUF, pixbuf, + -1); + + g_object_unref (tmp); + g_object_unref (pixbuf); + + priv->current_page++; + + if (priv->current_page == priv->n_pages) + return FALSE; + else + return TRUE; +} + +void +ev_sidebar_thumbnails_set_document (EvSidebarThumbnails *sidebar_thumbnails, + EvDocument *document) +{ + GtkIconTheme *theme; + GdkPixbuf *loading_icon; + gint i, n_pages; + EvSidebarThumbnailsPrivate *priv = sidebar_thumbnails->priv; + + g_return_if_fail (EV_IS_DOCUMENT_THUMBNAILS (document)); + + if (priv->idle_id != 0) { + g_source_remove (priv->idle_id); + } + + theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (sidebar_thumbnails))); + + loading_icon = gtk_icon_theme_load_icon (theme, "gnome-fs-loading-icon", + THUMBNAIL_WIDTH, 0, NULL); + + n_pages = ev_document_get_n_pages (document); + + for (i = 0; i < n_pages; i++) { + GtkTreeIter iter; + gchar *page; + + page = g_strdup_printf ("Page %d", i + 1); + gtk_list_store_append (sidebar_thumbnails->priv->list_store, + &iter); + gtk_list_store_set (sidebar_thumbnails->priv->list_store, + &iter, + COLUMN_PAGE_STRING, page, + COLUMN_PIXBUF, loading_icon, + -1); + g_free (page); + } + + priv->document = document; + priv->idle_id = g_idle_add (populate_thumbnails, sidebar_thumbnails); + priv->n_pages = n_pages; + priv->current_page = 0; +} + diff --git a/shell/ev-sidebar-thumbnails.h b/shell/ev-sidebar-thumbnails.h index e0ccccfc..45f68fce 100644 --- a/shell/ev-sidebar-thumbnails.h +++ b/shell/ev-sidebar-thumbnails.h @@ -26,6 +26,8 @@ #include +#include "ev-document.h" + G_BEGIN_DECLS typedef struct _EvSidebarThumbnails EvSidebarThumbnails; @@ -52,6 +54,9 @@ struct _EvSidebarThumbnailsClass { GType ev_sidebar_thumbnails_get_type (void); GtkWidget *ev_sidebar_thumbnails_new (void); +void ev_sidebar_thumbnails_set_document (EvSidebarThumbnails *sidebar_thumbnails, + EvDocument *document); + G_END_DECLS #endif /* __EV_SIDEBAR_THUMBNAILS_H__ */ diff --git a/shell/ev-sidebar.c b/shell/ev-sidebar.c index 780f9f6a..98beaa50 100644 --- a/shell/ev-sidebar.c +++ b/shell/ev-sidebar.c @@ -28,7 +28,9 @@ #include #include "ev-sidebar.h" +#include "ev-document-thumbnails.h" #include "ev-sidebar-bookmarks.h" +#include "ev-sidebar-thumbnails.h" typedef struct { @@ -77,7 +79,7 @@ ev_sidebar_init (EvSidebar *ev_sidebar) { GtkWidget *hbox; GtkCellRenderer *renderer; - + ev_sidebar->priv = EV_SIDEBAR_GET_PRIVATE (ev_sidebar); gtk_box_set_spacing (GTK_BOX (ev_sidebar), 6); @@ -100,6 +102,7 @@ ev_sidebar_init (EvSidebar *ev_sidebar) gtk_box_pack_start (GTK_BOX (hbox), ev_sidebar->priv->option_menu, FALSE, FALSE, 0); + renderer = gtk_cell_renderer_text_new (); gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (ev_sidebar->priv->option_menu), renderer, TRUE); @@ -172,6 +175,10 @@ ev_sidebar_add_page (EvSidebar *ev_sidebar, PAGE_COLUMN_MAIN_WIDGET, main_widget, PAGE_COLUMN_NOTEBOOK_INDEX, index, -1); + + /* Set the first item added as active */ + if (gtk_combo_box_get_active (GTK_COMBO_BOX (ev_sidebar->priv->option_menu))) + gtk_combo_box_set_active (GTK_COMBO_BOX (ev_sidebar->priv->option_menu), 0); } void @@ -204,7 +211,13 @@ ev_sidebar_set_document (EvSidebar *sidebar, && ev_bookmarks_has_bookmarks (document)... */ ev_sidebar_bookmarks_set_document (EV_SIDEBAR_BOOKMARKS (widget), document); - /* else if EV_IS_SIDEBAR_THUMBNAILS... */ + else if (EV_IS_SIDEBAR_THUMBNAILS (widget) && + EV_IS_DOCUMENT_THUMBNAILS (document)) + ev_sidebar_thumbnails_set_document (EV_SIDEBAR_THUMBNAILS (widget), + document); + + + } diff --git a/shell/ev-utils.c b/shell/ev-utils.c new file mode 100644 index 00000000..cf8a67c8 --- /dev/null +++ b/shell/ev-utils.c @@ -0,0 +1,179 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */ +/* + * Copyright (C) 2004 Anders Carlsson + * + * 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, 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#include "ev-utils.h" +#include + +typedef struct +{ + int size; + double *data; +} ConvFilter; + +static double +gaussian (double x, double y, double r) +{ + return ((1 / (2 * M_PI * r)) * + exp ((- (x * x + y * y)) / (2 * r * r))); +} + +static ConvFilter * +create_blur_filter (int radius) +{ + ConvFilter *filter; + int x, y; + double sum; + + filter = g_new0 (ConvFilter, 1); + filter->size = radius * 2 + 1; + filter->data = g_new (double, filter->size * filter->size); + + sum = 0.0; + + for (y = 0 ; y < filter->size; y++) + { + for (x = 0 ; x < filter->size; x++) + { + sum += filter->data[y * filter->size + x] = gaussian (x - (filter->size >> 1), + y - (filter->size >> 1), + radius); + } + } + + for (y = 0; y < filter->size; y++) + { + for (x = 0; x < filter->size; x++) + { + filter->data[y * filter->size + x] /= sum; + } + } + + return filter; + +} + +static GdkPixbuf * +create_shadow (GdkPixbuf *src, int blur_radius, + int x_offset, int y_offset, double opacity) +{ + int x, y, i, j; + int width, height; + GdkPixbuf *dest; + static ConvFilter *filter = NULL; + int src_rowstride, dest_rowstride; + int src_bpp, dest_bpp; + + guchar *src_pixels, *dest_pixels; + + if (!filter) + filter = create_blur_filter (blur_radius); + + if (x_offset < 0) + x_offset = (blur_radius * 4) / 5; + + if (y_offset < 0) + y_offset = (blur_radius * 4) / 5; + + + width = gdk_pixbuf_get_width (src) + blur_radius * 2 + x_offset; + height = gdk_pixbuf_get_height (src) + blur_radius * 2 + y_offset; + + dest = gdk_pixbuf_new (gdk_pixbuf_get_colorspace (src), TRUE, + gdk_pixbuf_get_bits_per_sample (src), + width, height); + gdk_pixbuf_fill (dest, 0); + src_pixels = gdk_pixbuf_get_pixels (src); + src_rowstride = gdk_pixbuf_get_rowstride (src); + src_bpp = gdk_pixbuf_get_has_alpha (src) ? 4 : 3; + + dest_pixels = gdk_pixbuf_get_pixels (dest); + dest_rowstride = gdk_pixbuf_get_rowstride (dest); + dest_bpp = gdk_pixbuf_get_has_alpha (dest) ? 4 : 3; + + for (y = 0; y < height; y++) + { + for (x = 0; x < width; x++) + { + int sumr = 0, sumg = 0, sumb = 0, suma = 0; + + for (i = 0; i < filter->size; i++) + { + for (j = 0; j < filter->size; j++) + { + int src_x, src_y; + + src_y = -(blur_radius + x_offset) + y - (filter->size >> 1) + i; + src_x = -(blur_radius + y_offset) + x - (filter->size >> 1) + j; + + if (src_y < 0 || src_y > gdk_pixbuf_get_height (src) || + src_x < 0 || src_x > gdk_pixbuf_get_width (src)) + continue; + + sumr += src_pixels [src_y * src_rowstride + + src_x * src_bpp + 0] * + filter->data [i * filter->size + j]; + sumg += src_pixels [src_y * src_rowstride + + src_x * src_bpp + 1] * + filter->data [i * filter->size + j]; + + sumb += src_pixels [src_y * src_rowstride + + src_x * src_bpp + 2] * + filter->data [i * filter->size + j]; + + if (src_bpp == 4) + suma += src_pixels [src_y * src_rowstride + + src_x * src_bpp + 3] * + filter->data [i * filter->size + j]; + else + suma += 0xff; + + } + } + + if (dest_bpp == 4) + dest_pixels [y * dest_rowstride + + x * dest_bpp + 3] = (suma * opacity) / (filter->size * filter->size); + + } + } + + return dest; +} + +GdkPixbuf * +ev_pixbuf_add_shadow (GdkPixbuf *src, int size, + int x_offset, int y_offset, double opacity) +{ + GdkPixbuf *dest; + + dest = create_shadow (src, size, x_offset, y_offset, opacity); + + gdk_pixbuf_composite (src, dest, + size, size, + gdk_pixbuf_get_width (src), + gdk_pixbuf_get_height (src), + size, size, + 1.0, 1.0, + GDK_INTERP_NEAREST, 255); + + return dest; +} + + diff --git a/shell/ev-utils.h b/shell/ev-utils.h new file mode 100644 index 00000000..084a2851 --- /dev/null +++ b/shell/ev-utils.h @@ -0,0 +1,33 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */ +/* + * Copyright (C) 2004 Anders Carlsson + * + * 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, 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#ifndef __EV_UTILS_H__ +#define __EV_UTILS_H__ + +#include + +G_BEGIN_DECLS + +GdkPixbuf *ev_pixbuf_add_shadow (GdkPixbuf *src, int size, + int x_offset, int y_offset, double opacity); + +G_END_DECLS + +#endif /* __EV_VIEW_H__ */