From 8e126907002877574ec86fcbd184e56dc8f74683 Mon Sep 17 00:00:00 2001 From: Carlos Garcia Campos Date: Sat, 19 Jan 2008 17:19:42 +0000 Subject: Do not render images when rendering the page but on demand. It reduces the 2008-01-19 Carlos Garcia Campos * configure.ac: * backend/pdf/ev-poppler.cc: (pdf_document_images_get_image_mapping), (pdf_document_images_get_image), (pdf_document_document_images_iface_init): * libdocument/ev-document-images.[ch]: (ev_document_images_get_image_mapping), (ev_document_images_get_image): * libdocument/ev-image.[ch]: (ev_image_new), (ev_image_get_page), (ev_image_get_id), (ev_image_save_tmp): * shell/ev-jobs.c: (ev_job_render_run): * shell/ev-view.c: (ev_view_drag_data_get): * shell/ev-window.c: (image_save_dialog_response_cb), (ev_view_popup_cmd_copy_image): Do not render images when rendering the page but on demand. It reduces the memory comsumption. svn path=/trunk/; revision=2835 --- diff --git a/ChangeLog b/ChangeLog index 1fff2a5..6d19fdc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +2008-01-19 Carlos Garcia Campos + + * configure.ac: + * backend/pdf/ev-poppler.cc: + (pdf_document_images_get_image_mapping), + (pdf_document_images_get_image), + (pdf_document_document_images_iface_init): + * libdocument/ev-document-images.[ch]: + (ev_document_images_get_image_mapping), + (ev_document_images_get_image): + * libdocument/ev-image.[ch]: (ev_image_new), (ev_image_get_page), + (ev_image_get_id), (ev_image_save_tmp): + * shell/ev-jobs.c: (ev_job_render_run): + * shell/ev-view.c: (ev_view_drag_data_get): + * shell/ev-window.c: (image_save_dialog_response_cb), + (ev_view_popup_cmd_copy_image): + + Do not render images when rendering the page but on demand. It + reduces the memory comsumption. + 2008-01-18 Marcelo Lira * configure.a: diff --git a/backend/pdf/ev-poppler.cc b/backend/pdf/ev-poppler.cc index 7c3a594..8885411 100644 --- a/backend/pdf/ev-poppler.cc +++ b/backend/pdf/ev-poppler.cc @@ -1156,8 +1156,8 @@ pdf_document_document_links_iface_init (EvDocumentLinksIface *iface) } static GList * -pdf_document_images_get_images (EvDocumentImages *document_images, - gint page) +pdf_document_images_get_image_mapping (EvDocumentImages *document_images, + gint page) { GList *retval = NULL; PdfDocument *pdf_document; @@ -1176,8 +1176,11 @@ pdf_document_images_get_images (EvDocumentImages *document_images, image_mapping = (PopplerImageMapping *)list->data; ev_image_mapping = g_new (EvImageMapping, 1); - +#ifdef HAVE_POPPLER_PAGE_GET_IMAGE + ev_image_mapping->image = ev_image_new (page, image_mapping->image_id); +#else ev_image_mapping->image = ev_image_new_from_pixbuf (image_mapping->image); +#endif ev_image_mapping->x1 = image_mapping->area.x1; ev_image_mapping->x2 = image_mapping->area.x2; ev_image_mapping->y1 = image_mapping->area.y1; @@ -1192,10 +1195,39 @@ pdf_document_images_get_images (EvDocumentImages *document_images, return retval; } +GdkPixbuf * +pdf_document_images_get_image (EvDocumentImages *document_images, + EvImage *image) +{ +#ifdef HAVE_POPPLER_PAGE_GET_IMAGE + PdfDocument *pdf_document; + PopplerPage *poppler_page; + cairo_surface_t *surface; + GdkPixbuf *retval = NULL; + + pdf_document = PDF_DOCUMENT (document_images); + poppler_page = poppler_document_get_page (pdf_document->document, + ev_image_get_page (image)); + + surface = poppler_page_get_image (poppler_page, ev_image_get_id (image)); + if (surface) { + retval = ev_document_misc_pixbuf_from_surface (surface); + cairo_surface_destroy (surface); + } + + g_object_unref (poppler_page); + + return retval; +#else + return GDK_PIXBUF (g_object_ref (ev_image_get_pixbuf (image))); +#endif /* HAVE_POPPLER_PAGE_GET_IMAGE */ +} + static void pdf_document_document_images_iface_init (EvDocumentImagesIface *iface) { - iface->get_images = pdf_document_images_get_images; + iface->get_image_mapping = pdf_document_images_get_image_mapping; + iface->get_image = pdf_document_images_get_image; } static GdkPixbuf * diff --git a/configure.ac b/configure.ac index 01b391d..cffed87 100644 --- a/configure.ac +++ b/configure.ac @@ -260,6 +260,7 @@ if test "x$enable_pdf" = "xyes"; then LIBS="$LIBS $POPPLER_LIBS" AC_CHECK_FUNCS(poppler_page_render) AC_CHECK_FUNCS(poppler_page_render_for_printing) + AC_CHECK_FUNCS(poppler_page_get_image) LIBS=$evince_save_LIBS PKG_CHECK_MODULES(CAIRO_PDF, cairo-pdf, enable_cairo_pdf=yes, enable_cairo_pdf=no) diff --git a/libdocument/ev-document-images.c b/libdocument/ev-document-images.c index 1de728f..874a24d 100644 --- a/libdocument/ev-document-images.c +++ b/libdocument/ev-document-images.c @@ -42,15 +42,19 @@ ev_document_images_get_type (void) } GList * -ev_document_images_get_images (EvDocumentImages *document_images, - gint page) +ev_document_images_get_image_mapping (EvDocumentImages *document_images, + gint page) { EvDocumentImagesIface *iface = EV_DOCUMENT_IMAGES_GET_IFACE (document_images); - GList *retval; - retval = iface->get_images (document_images, page); - - return retval; + return iface->get_image_mapping (document_images, page); } +GdkPixbuf * +ev_document_images_get_image (EvDocumentImages *document_images, + EvImage *image) +{ + EvDocumentImagesIface *iface = EV_DOCUMENT_IMAGES_GET_IFACE (document_images); + return iface->get_image (document_images, image); +} diff --git a/libdocument/ev-document-images.h b/libdocument/ev-document-images.h index 28eee46..d8699b9 100644 --- a/libdocument/ev-document-images.h +++ b/libdocument/ev-document-images.h @@ -25,6 +25,7 @@ #include #include "ev-document.h" +#include "ev-image.h" G_BEGIN_DECLS @@ -42,13 +43,17 @@ struct _EvDocumentImagesIface { GTypeInterface base_iface; /* Methods */ - GList *(* get_images) (EvDocumentImages *document_images, - gint page); + GList *(* get_image_mapping) (EvDocumentImages *document_images, + gint page); + GdkPixbuf *(* get_image) (EvDocumentImages *document_images, + EvImage *image); }; -GType ev_document_images_get_type (void) G_GNUC_CONST; -GList *ev_document_images_get_images (EvDocumentImages *document_images, - gint page); +GType ev_document_images_get_type (void) G_GNUC_CONST; +GList *ev_document_images_get_image_mapping (EvDocumentImages *document_images, + gint page); +GdkPixbuf *ev_document_images_get_image (EvDocumentImages *document_images, + EvImage *image); G_END_DECLS diff --git a/libdocument/ev-image.c b/libdocument/ev-image.c index 1bf17f2..4276dd4 100644 --- a/libdocument/ev-image.c +++ b/libdocument/ev-image.c @@ -19,10 +19,13 @@ #include #include +#include "ev-document-misc.h" #include "ev-file-helpers.h" #include "ev-image.h" struct _EvImagePrivate { + gint page; + gint id; GdkPixbuf *pixbuf; gchar *tmp_uri; }; @@ -70,6 +73,19 @@ ev_image_init (EvImage *image) } EvImage * +ev_image_new (gint page, + gint img_id) +{ + EvImage *image; + + image = EV_IMAGE (g_object_new (EV_TYPE_IMAGE, NULL)); + image->priv->page = page; + image->priv->id = img_id; + + return image; +} + +EvImage * ev_image_new_from_pixbuf (GdkPixbuf *pixbuf) { EvImage *image; @@ -82,6 +98,22 @@ ev_image_new_from_pixbuf (GdkPixbuf *pixbuf) return image; } +gint +ev_image_get_page (EvImage *image) +{ + g_return_val_if_fail (EV_IS_IMAGE (image), -1); + + return image->priv->page; +} + +gint +ev_image_get_id (EvImage *image) +{ + g_return_val_if_fail (EV_IS_IMAGE (image), -1); + + return image->priv->id; +} + GdkPixbuf * ev_image_get_pixbuf (EvImage *image) { @@ -92,19 +124,20 @@ ev_image_get_pixbuf (EvImage *image) } const gchar * -ev_image_save_tmp (EvImage *image) +ev_image_save_tmp (EvImage *image, + GdkPixbuf *pixbuf) { GError *error = NULL; g_return_val_if_fail (EV_IS_IMAGE (image), NULL); - g_return_val_if_fail (GDK_IS_PIXBUF (image->priv->pixbuf), NULL); + g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL); if (image->priv->tmp_uri) return image->priv->tmp_uri; image->priv->tmp_uri = ev_tmp_filename ("image"); - gdk_pixbuf_save (image->priv->pixbuf, - image->priv->tmp_uri, "png", &error, + gdk_pixbuf_save (pixbuf, image->priv->tmp_uri, + "png", &error, "compression", "3", NULL); if (!error) return image->priv->tmp_uri; diff --git a/libdocument/ev-image.h b/libdocument/ev-image.h index 6688e7a..8b5b595 100644 --- a/libdocument/ev-image.h +++ b/libdocument/ev-image.h @@ -46,12 +46,17 @@ struct _EvImageClass { GObjectClass base_class; }; -GType ev_image_get_type (void) G_GNUC_CONST; -EvImage *ev_image_new_from_pixbuf (GdkPixbuf *pixbuf); +GType ev_image_get_type (void) G_GNUC_CONST; +EvImage *ev_image_new (gint page, + gint img_id); +EvImage *ev_image_new_from_pixbuf (GdkPixbuf *pixbuf); -GdkPixbuf *ev_image_get_pixbuf (EvImage *image); -const gchar *ev_image_save_tmp (EvImage *image); -const gchar *ev_image_get_tmp_uri (EvImage *image); +gint ev_image_get_id (EvImage *image); +gint ev_image_get_page (EvImage *image); +GdkPixbuf *ev_image_get_pixbuf (EvImage *image); +const gchar *ev_image_save_tmp (EvImage *image, + GdkPixbuf *pixbuf); +const gchar *ev_image_get_tmp_uri (EvImage *image); /* Image Mapping stuff */ diff --git a/shell/ev-jobs.c b/shell/ev-jobs.c index 6ffbb57..d22a3bb 100644 --- a/shell/ev-jobs.c +++ b/shell/ev-jobs.c @@ -406,8 +406,8 @@ ev_job_render_run (EvJobRender *job) job->rc->page); if (job->include_images && EV_IS_DOCUMENT_IMAGES (EV_JOB (job)->document)) job->image_mapping = - ev_document_images_get_images (EV_DOCUMENT_IMAGES (EV_JOB (job)->document), - job->rc->page); + ev_document_images_get_image_mapping (EV_DOCUMENT_IMAGES (EV_JOB (job)->document), + job->rc->page); EV_JOB (job)->finished = TRUE; } diff --git a/shell/ev-view.c b/shell/ev-view.c index cb2d026..cb66a2a 100644 --- a/shell/ev-view.c +++ b/shell/ev-view.c @@ -2795,16 +2795,28 @@ ev_view_drag_data_get (GtkWidget *widget, if (view->image_dnd_info.image) { GdkPixbuf *pixbuf; - pixbuf = ev_image_get_pixbuf (view->image_dnd_info.image); + ev_document_doc_mutex_lock (); + pixbuf = ev_document_images_get_image (EV_DOCUMENT_IMAGES (view->document), + view->image_dnd_info.image); + ev_document_doc_mutex_unlock (); + gtk_selection_data_set_pixbuf (selection_data, pixbuf); + g_object_unref (pixbuf); } break; case TARGET_DND_URI: if (view->image_dnd_info.image) { + GdkPixbuf *pixbuf; const gchar *tmp_uri; gchar **uris; - tmp_uri = ev_image_save_tmp (view->image_dnd_info.image); + ev_document_doc_mutex_lock (); + pixbuf = ev_document_images_get_image (EV_DOCUMENT_IMAGES (view->document), + view->image_dnd_info.image); + ev_document_doc_mutex_unlock (); + + tmp_uri = ev_image_save_tmp (view->image_dnd_info.image, pixbuf); + g_object_unref (pixbuf); uris = g_new0 (gchar *, 2); uris[0] = (gchar *)tmp_uri; diff --git a/shell/ev-window.c b/shell/ev-window.c index ab8eb1d..4b4fee3 100644 --- a/shell/ev-window.c +++ b/shell/ev-window.c @@ -46,6 +46,7 @@ #include "ev-document-links.h" #include "ev-document-fonts.h" #include "ev-document-find.h" +#include "ev-document-images.h" #include "ev-document-security.h" #include "ev-document-factory.h" #include "ev-job-queue.h" @@ -4978,17 +4979,17 @@ image_save_dialog_response_cb (GtkWidget *fc, gint response_id, EvWindow *ev_window) { - GnomeVFSURI *target_uri; - gboolean is_local; - GError *error = NULL; - - gchar *uri; - gchar *uri_extension; - gchar **extensions; - gchar *filename; - gchar *file_format; - GdkPixbufFormat* format; - GtkFileFilter *filter; + GnomeVFSURI *target_uri; + gboolean is_local; + GError *error = NULL; + GdkPixbuf *pixbuf; + gchar *uri; + gchar *uri_extension; + gchar **extensions; + gchar *filename; + gchar *file_format; + GdkPixbufFormat *format; + GtkFileFilter *filter; if (response_id != GTK_RESPONSE_OK) { gtk_widget_destroy (fc); @@ -5029,9 +5030,14 @@ image_save_dialog_response_cb (GtkWidget *fc, g_free (uri); g_free (uri_extension); + + ev_document_doc_mutex_lock (); + pixbuf = ev_document_images_get_image (EV_DOCUMENT_IMAGES (ev_window->priv->document), + ev_window->priv->image); + ev_document_doc_mutex_unlock (); - gdk_pixbuf_save (ev_image_get_pixbuf (ev_window->priv->image), - filename, file_format, &error, NULL); + gdk_pixbuf_save (pixbuf, filename, file_format, &error, NULL); + g_object_unref (pixbuf); if (error) { ev_window_error_message (GTK_WINDOW (ev_window), @@ -5094,14 +5100,20 @@ static void ev_view_popup_cmd_copy_image (GtkAction *action, EvWindow *window) { GtkClipboard *clipboard; + GdkPixbuf *pixbuf; if (!window->priv->image) return; clipboard = gtk_widget_get_clipboard (GTK_WIDGET (window), GDK_SELECTION_CLIPBOARD); - gtk_clipboard_set_image (clipboard, - ev_image_get_pixbuf (window->priv->image)); + ev_document_doc_mutex_lock (); + pixbuf = ev_document_images_get_image (EV_DOCUMENT_IMAGES (window->priv->document), + window->priv->image); + ev_document_doc_mutex_unlock (); + + gtk_clipboard_set_image (clipboard, pixbuf); + g_object_unref (pixbuf); } static void -- cgit v0.9.1