From 217797d63b2d3b1c9a7a0511af1bbf3d99f0d482 Mon Sep 17 00:00:00 2001 From: Carlos Garcia Campos Date: Wed, 13 Jun 2007 08:54:53 +0000 Subject: Use cairo image surfaces instead of GDK pixbufs for drawing pages and 2007-06-13 Carlos Garcia Campos * backend/dvi/dvi-document.c: (dvi_document_render), (dvi_document_render_pixbuf), (dvi_document_document_iface_init): * backend/impress/impress-document.c: (imp_render_get_from_drawable), (impress_document_render_pixbuf), (impress_document_render), (impress_document_document_iface_init), (impress_document_thumbnails_get_thumbnail): * backend/djvu/djvu-document-private.h: * backend/djvu/djvu-document.c: (djvu_document_render), (djvu_document_finalize), (djvu_document_document_iface_init), (djvu_document_thumbnails_get_thumbnail), (djvu_document_init): * backend/tiff/tiff-document.c: (tiff_document_render), (tiff_document_render_pixbuf), (tiff_document_document_iface_init): * backend/pdf/ev-poppler.cc: (pdf_document_render), (pdf_document_render_pixbuf), (pdf_document_document_iface_init), (pdf_selection_render_selection): * backend/comics/comics-document.c: (comics_document_render_pixbuf), (comics_document_render), (comics_document_document_iface_init): * backend/pixbuf/pixbuf-document.c: (pixbuf_document_render), (pixbuf_document_document_iface_init): * libdocument/ev-document-misc.[ch]: (ev_document_misc_surface_from_pixbuf), (ev_document_misc_surface_rotate_and_scale): * libdocument/ev-document.[ch]: (ev_document_render): * libdocument/ev-selection.[ch]: (ev_selection_render_selection): * shell/ev-pixbuf-cache.[ch]: (dispose_cache_job_info), (move_one_job), (copy_job_to_job_info), (add_job_if_needed), (ev_pixbuf_cache_get_surface), (new_selection_surface_needed), (clear_selection_if_needed), (ev_pixbuf_cache_style_changed), (ev_pixbuf_cache_get_selection_surface), (clear_job_selection): * shell/ev-jobs.[ch]: (ev_job_render_dispose), (render_finished_cb), (ev_job_render_run): * shell/ev-view.c: (draw_loading_text), (draw_one_page), (merge_selection_region): Use cairo image surfaces instead of GDK pixbufs for drawing pages and selections. svn path=/trunk/; revision=2499 --- (limited to 'libdocument') diff --git a/libdocument/ev-document-misc.c b/libdocument/ev-document-misc.c index 89ff5fa..e8739a1 100644 --- a/libdocument/ev-document-misc.c +++ b/libdocument/ev-document-misc.c @@ -1,3 +1,21 @@ +/* + * Copyright (c) 2007 Carlos Garcia Campos + * Copyright (C) 2000-2003 Marco Pesenti Gritti + * + * 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-document-misc.h" #include @@ -8,7 +26,6 @@ * NULL, then it will fill the return pixbuf with the contents of * source_pixbuf. */ - GdkPixbuf * ev_document_misc_get_thumbnail_frame (int width, int height, @@ -128,3 +145,77 @@ ev_document_misc_paint_one_page (GdkDrawable *drawable, border->right - border->left); } + +cairo_surface_t * +ev_document_misc_surface_from_pixbuf (GdkPixbuf *pixbuf) +{ + cairo_surface_t *surface; + cairo_t *cr; + + surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, + gdk_pixbuf_get_width (pixbuf), + gdk_pixbuf_get_height (pixbuf)); + cr = cairo_create (surface); + gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0); + cairo_paint (cr); + cairo_destroy (cr); + + return surface; +} + +cairo_surface_t * +ev_document_misc_surface_rotate_and_scale (cairo_surface_t *surface, + gint dest_width, + gint dest_height, + gint dest_rotation) +{ + cairo_surface_t *new_surface; + cairo_t *cr; + gint width, height; + gint new_width = dest_width; + gint new_height = dest_height; + + width = cairo_image_surface_get_width (surface); + height = cairo_image_surface_get_height (surface); + + if (dest_width == width && + dest_height == height && + dest_rotation == 0) { + return cairo_surface_reference (surface); + } + + if (dest_rotation == 90 || dest_rotation == 270) { + new_width = dest_height; + new_height = dest_width; + } + + new_surface = cairo_surface_create_similar (surface, + CAIRO_CONTENT_COLOR_ALPHA, + new_width, new_height); + + cr = cairo_create (new_surface); + switch (dest_rotation) { + case 90: + cairo_translate (cr, new_width, 0); + break; + case 180: + cairo_translate (cr, new_width, new_height); + break; + case 270: + cairo_translate (cr, 0, new_height); + break; + default: + cairo_translate (cr, 0, 0); + } + cairo_pattern_set_filter (cairo_get_source (cr), CAIRO_FILTER_BILINEAR); + cairo_scale (cr, + (gdouble)dest_width / width, + (gdouble)dest_height / height); + cairo_rotate (cr, dest_rotation * G_PI / 180.0); + cairo_set_source_surface (cr, surface, 0, 0); + cairo_paint (cr); + cairo_destroy (cr); + + return new_surface; +} + diff --git a/libdocument/ev-document-misc.h b/libdocument/ev-document-misc.h index 5d84671..0860774 100644 --- a/libdocument/ev-document-misc.h +++ b/libdocument/ev-document-misc.h @@ -25,6 +25,7 @@ #include #include +#include G_BEGIN_DECLS @@ -40,6 +41,11 @@ void ev_document_misc_paint_one_page (GdkDrawable *drawable, GdkRectangle *area, GtkBorder *border, gboolean highlight); +cairo_surface_t *ev_document_misc_surface_from_pixbuf (GdkPixbuf *pixbuf); +cairo_surface_t *ev_document_misc_surface_rotate_and_scale (cairo_surface_t *surface, + gint dest_width, + gint dest_height, + gint dest_rotation); G_END_DECLS diff --git a/libdocument/ev-document.c b/libdocument/ev-document.c index a951bfa..776e4bd 100644 --- a/libdocument/ev-document.c +++ b/libdocument/ev-document.c @@ -230,17 +230,17 @@ ev_document_get_attachments (EvDocument *document) return retval; } -GdkPixbuf * -ev_document_render_pixbuf (EvDocument *document, - EvRenderContext *rc) +cairo_surface_t * +ev_document_render (EvDocument *document, + EvRenderContext *rc) { EvDocumentIface *iface = EV_DOCUMENT_GET_IFACE (document); - GdkPixbuf *retval; + cairo_surface_t *retval; LOG ("ev_document_render_pixbuf"); - g_assert (iface->render_pixbuf); + g_assert (iface->render); - retval = iface->render_pixbuf (document, rc); + retval = iface->render (document, rc); return retval; } diff --git a/libdocument/ev-document.h b/libdocument/ev-document.h index 33b7f4d..ce887fc 100644 --- a/libdocument/ev-document.h +++ b/libdocument/ev-document.h @@ -25,6 +25,7 @@ #include #include #include +#include #include "ev-link.h" #include "ev-document-info.h" @@ -32,14 +33,14 @@ G_BEGIN_DECLS -#define EV_TYPE_DOCUMENT (ev_document_get_type ()) -#define EV_DOCUMENT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EV_TYPE_DOCUMENT, EvDocument)) -#define EV_DOCUMENT_IFACE(k) (G_TYPE_CHECK_CLASS_CAST((k), EV_TYPE_DOCUMENT, EvDocumentIface)) -#define EV_IS_DOCUMENT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EV_TYPE_DOCUMENT)) -#define EV_IS_DOCUMENT_IFACE(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EV_TYPE_DOCUMENT)) +#define EV_TYPE_DOCUMENT (ev_document_get_type ()) +#define EV_DOCUMENT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EV_TYPE_DOCUMENT, EvDocument)) +#define EV_DOCUMENT_IFACE(k) (G_TYPE_CHECK_CLASS_CAST((k), EV_TYPE_DOCUMENT, EvDocumentIface)) +#define EV_IS_DOCUMENT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EV_TYPE_DOCUMENT)) +#define EV_IS_DOCUMENT_IFACE(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EV_TYPE_DOCUMENT)) #define EV_DOCUMENT_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), EV_TYPE_DOCUMENT, EvDocumentIface)) -typedef struct _EvDocument EvDocument; +typedef struct _EvDocument EvDocument; typedef struct _EvDocumentIface EvDocumentIface; typedef struct _EvPageCache EvPageCache; typedef struct _EvPageCacheClass EvPageCacheClass; @@ -50,91 +51,91 @@ typedef struct _EvPageCacheClass EvPageCacheClass; typedef enum { - EV_DOCUMENT_ERROR_INVALID, - EV_DOCUMENT_ERROR_ENCRYPTED + EV_DOCUMENT_ERROR_INVALID, + EV_DOCUMENT_ERROR_ENCRYPTED } EvDocumentError; typedef struct { - double x; - double y; + double x; + double y; } EvPoint; typedef struct { - double x1; - double y1; - double x2; - double y2; + double x1; + double y1; + double x2; + double y2; } EvRectangle; struct _EvDocumentIface { - GTypeInterface base_iface; - - /* Methods */ - gboolean (* load) (EvDocument *document, - const char *uri, - GError **error); - gboolean (* save) (EvDocument *document, - const char *uri, - GError **error); - int (* get_n_pages) (EvDocument *document); - void (* get_page_size) (EvDocument *document, - int page, - double *width, - double *height); - char * (* get_page_label) (EvDocument *document, - int page); - gboolean (* can_get_text) (EvDocument *document); - char * (* get_text) (EvDocument *document, - int page, - EvRectangle *rect); - gboolean (* has_attachments) (EvDocument *document); - GList * (* get_attachments) (EvDocument *document); - GdkPixbuf * (* render_pixbuf) (EvDocument *document, - EvRenderContext *rc); - EvDocumentInfo * (* get_info) (EvDocument *document); + GTypeInterface base_iface; + + /* Methods */ + gboolean (* load) (EvDocument *document, + const char *uri, + GError **error); + gboolean (* save) (EvDocument *document, + const char *uri, + GError **error); + int (* get_n_pages) (EvDocument *document); + void (* get_page_size) (EvDocument *document, + int page, + double *width, + double *height); + char * (* get_page_label) (EvDocument *document, + int page); + gboolean (* can_get_text) (EvDocument *document); + char * (* get_text) (EvDocument *document, + int page, + EvRectangle *rect); + gboolean (* has_attachments) (EvDocument *document); + GList * (* get_attachments) (EvDocument *document); + cairo_surface_t * (* render) (EvDocument *document, + EvRenderContext *rc); + EvDocumentInfo * (* get_info) (EvDocument *document); }; -GType ev_document_get_type (void); -GQuark ev_document_error_quark (void); +GType ev_document_get_type (void) G_GNUC_CONST; +GQuark ev_document_error_quark (void); /* Document mutex */ -GMutex *ev_document_get_doc_mutex (void); -void ev_document_doc_mutex_lock (void); -void ev_document_doc_mutex_unlock (void); +GMutex *ev_document_get_doc_mutex (void); +void ev_document_doc_mutex_lock (void); +void ev_document_doc_mutex_unlock (void); /* FontConfig mutex */ -GMutex *ev_document_get_fc_mutex (void); -void ev_document_fc_mutex_lock (void); -void ev_document_fc_mutex_unlock (void); - -EvDocumentInfo *ev_document_get_info (EvDocument *document); -gboolean ev_document_load (EvDocument *document, - const char *uri, - GError **error); -gboolean ev_document_save (EvDocument *document, - const char *uri, - GError **error); -int ev_document_get_n_pages (EvDocument *document); -void ev_document_get_page_size (EvDocument *document, - int page, - double *width, - double *height); -char *ev_document_get_page_label (EvDocument *document, - int page); -gboolean ev_document_can_get_text (EvDocument *document); -char *ev_document_get_text (EvDocument *document, - int page, - EvRectangle *rect); -gboolean ev_document_has_attachments (EvDocument *document); -GList *ev_document_get_attachments (EvDocument *document); -GdkPixbuf *ev_document_render_pixbuf (EvDocument *document, - EvRenderContext *rc); - -gint ev_rect_cmp (EvRectangle *a, - EvRectangle *b); +GMutex *ev_document_get_fc_mutex (void); +void ev_document_fc_mutex_lock (void); +void ev_document_fc_mutex_unlock (void); + +EvDocumentInfo *ev_document_get_info (EvDocument *document); +gboolean ev_document_load (EvDocument *document, + const char *uri, + GError **error); +gboolean ev_document_save (EvDocument *document, + const char *uri, + GError **error); +int ev_document_get_n_pages (EvDocument *document); +void ev_document_get_page_size (EvDocument *document, + int page, + double *width, + double *height); +char *ev_document_get_page_label (EvDocument *document, + int page); +gboolean ev_document_can_get_text (EvDocument *document); +char *ev_document_get_text (EvDocument *document, + int page, + EvRectangle *rect); +gboolean ev_document_has_attachments (EvDocument *document); +GList *ev_document_get_attachments (EvDocument *document); +cairo_surface_t *ev_document_render (EvDocument *document, + EvRenderContext *rc); + +gint ev_rect_cmp (EvRectangle *a, + EvRectangle *b); G_END_DECLS -#endif +#endif /* EV_DOCUMENT_H */ diff --git a/libdocument/ev-selection.c b/libdocument/ev-selection.c index 2aa45a7..f7aee2f 100644 --- a/libdocument/ev-selection.c +++ b/libdocument/ev-selection.c @@ -59,7 +59,7 @@ ev_selection_base_init (gpointer g_class) void ev_selection_render_selection (EvSelection *selection, EvRenderContext *rc, - GdkPixbuf **pixbuf, + cairo_surface_t **surface, EvRectangle *points, EvRectangle *old_points, GdkColor *text, @@ -68,7 +68,7 @@ ev_selection_render_selection (EvSelection *selection, EvSelectionIface *iface = EV_SELECTION_GET_IFACE (selection); iface->render_selection (selection, rc, - pixbuf, + surface, points, old_points, text, base); } diff --git a/libdocument/ev-selection.h b/libdocument/ev-selection.h index d081604..5ba9776 100644 --- a/libdocument/ev-selection.h +++ b/libdocument/ev-selection.h @@ -45,7 +45,7 @@ struct _EvSelectionIface void (* render_selection) (EvSelection *selection, EvRenderContext *rc, - GdkPixbuf **pixbuf, + cairo_surface_t **surface, EvRectangle *points, EvRectangle *old_points, GdkColor *text, @@ -60,7 +60,7 @@ struct _EvSelectionIface GType ev_selection_get_type (void); void ev_selection_render_selection (EvSelection *selection, EvRenderContext *rc, - GdkPixbuf **pixbuf, + cairo_surface_t **surface, EvRectangle *points, EvRectangle *old_points, GdkColor *text, -- cgit v0.9.1