Big patch, and a partial return to normalcy
- From: Jonathan Blandford <jrb redhat com>
- To: evince-list gnome org
- Subject: Big patch, and a partial return to normalcy
- Date: 31 Mar 2005 02:38:42 -0500
Hi,
I am attaching a big patch that I'm going to commit soon. It requires
the latest poppler from CVS. Since the patch is big, I thought I'd list
the changes it introduces.
* Re-adds links to the document. You can click on them again.
* Speeds up (with a fix in poppler) the creation of the index from 10
seconds to less than .1 seconds. We also don't slowly fill things in
like before, meaning expand-all will actually expand all.
* Moves the pdf backend to use to poppler-glib. Kristian and I have
been cleaning up this API over the last week. It's much nicer, and
is going to let us reenable the searching.
* Changes ev-document page indexing to be '0' based again. We were '1'
based for a while, but we're back to '0'. The reason for this change
is that we now can get page labels from both .ps and .pdf, which
means the need to keep the index the same as the human-readable index
has gone. Unfortunately, bits of xpdf still index by 1, but they're
slowly being excised.
* Fixes some bugs in the pixbuf-cache.
* This also introduces a minor regression from the last commit --
printing doesn't work yet. I will get that going shortly. It just
involves moving some code around.
* Disables the pixbuf backend. I'm going to disable it until we can
find a new maintainer.
Status:
=======
Once that's committed, we have two major features from the pre-threaded
days left to be implemented. They are selection and searching.
Kristian and I are reasonably confident that we can get both of these
working like before. However, we don't really like the way that
selection currently works and search gets updated. I think I'm okay
with turning off selection for now, and focusing mostly on search. Once
that's done, we should make a release.
I think that this is basically the last of the really big changes (for
now). When searching lands, we can start working on doing interesting
features again instead of rewriting the core. I'm pretty excited about
being able to implement continuous scrolling, and there are a lot of
neat things we can do. One cool thing we can think about doing is
adding A11Y support for the documents themselves. Another neat feature
would be Brian's scrolling suggestions (see #170871). Also, we now can
get access to a page label (such as "iii" instead of "3"). We should
use that.
Thanks,
-Jonathan
? evince-glib.patch
? pdf/attachment.cgi?id=39233
? pixbuf/pixbuf-document.loT
? shell/Japan Tour3.tif
? shell/U206G_InFlight2.svg
? shell/cvs.ps
? shell/forjrb.passwd
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/evince/ChangeLog,v
retrieving revision 1.255
diff -u -p -r1.255 ChangeLog
--- ChangeLog 25 Mar 2005 21:57:13 -0000 1.255
+++ ChangeLog 31 Mar 2005 07:33:35 -0000
@@ -1,3 +1,58 @@
+Thu Mar 31 01:21:58 2005 Jonathan Blandford <jrb redhat com>
+
+ * Makefile.am: Remove pixbuf backend for now
+
+ * configure.ac: Require poppler-glib instead of just poppler.
+
+ * backend/ev-document-thumbnails.h: Add a comment
+
+ * backend/ev-document.h:
+ * backend/ev-document.c: (ev_document_class_init),
+ (ev_document_load), (ev_document_get_link),
+ (ev_document_get_links): Remove 3 methods and add get_links.
+ Also, made 0 based.
+
+ * backend/ev-jobs.c: (ev_job_render_new), (ev_job_render_run):
+ * backend/ev-jobs.h: now EvJobRender can grab the links for a document.
+
+ * backend/ev-link.c: (ev_link_set_title),
+ (ev_link_mapping_free_foreach), (ev_link_mapping_free),
+ (ev_link_mapping_find):
+ * backend/ev-link.h: Allow NULL titles. Also, introduce a mapping link.
+
+ * backend/ev-page-cache.c: (ev_page_cache_init),
+ (_ev_page_cache_new), (ev_page_cache_set_current_page),
+ (ev_page_cache_get_size), (ev_page_cache_next_page),
+ (ev_page_cache_prev_page): Fix to be 0 based.
+
+ * pdf/Makefile.am:
+ * pdf/ev-poppler.h:
+ * pdf/ev-poppler.cc: New backend.
+
+ * ps/ps-document.c: (ps_document_init), (ps_document_set_page),
+ (ps_document_get_page), (ps_document_document_iface_init):
+
+ * shell/ev-pixbuf-cache.h:
+ * shell/ev-pixbuf-cache.c: (ev_pixbuf_cache_init),
+ (dispose_cache_job_info), (job_finished_cb), (move_one_job),
+ (ev_pixbuf_cache_update_range), (copy_job_to_job_info),
+ (add_job_if_needed), (ev_pixbuf_cache_set_page_range),
+ (ev_pixbuf_cache_get_pixbuf), (ev_pixbuf_cache_get_link_mapping):
+ Fix up code to grab a page cache per each doc. Also, fix to be 0
+ based.
+
+ * shell/ev-sidebar-thumbnails.c:
+ (ev_sidebar_tree_selection_changed), (page_changed_cb),
+ (ev_sidebar_thumbnails_set_document): Fix to be 0 based.
+
+ * shell/ev-view.c: (status_message_from_link),
+ (find_page_at_location), (get_link_at_location),
+ (ev_view_motion_notify_event), (ev_view_button_release_event),
+ (ev_view_init): Use the new link code. Fix to be 0 based.
+
+ * shell/ev-window.c: (update_action_sensitivity),
+ (document_supports_sidebar): 0 based.
+
Fri Mar 25 16:55:58 2005 Jonathan Blandford <jrb redhat com>
* pdf/pdf-document.cc: Patch from Fernando Herrera
Index: Makefile.am
===================================================================
RCS file: /cvs/gnome/evince/Makefile.am,v
retrieving revision 1.12
diff -u -p -r1.12 Makefile.am
--- Makefile.am 3 Mar 2005 10:06:42 -0000 1.12
+++ Makefile.am 31 Mar 2005 07:33:35 -0000
@@ -1,4 +1,4 @@
-SUBDIRS = lib cut-n-paste data backend po pdf ps pixbuf shell thumbnailer
+SUBDIRS = lib cut-n-paste data backend po pdf ps shell thumbnailer
intltool_extra = intltool-extract.in intltool-merge.in intltool-update.in
Index: configure.ac
===================================================================
RCS file: /cvs/gnome/evince/configure.ac,v
retrieving revision 1.44
diff -u -p -r1.44 configure.ac
--- configure.ac 16 Mar 2005 13:07:44 -0000 1.44
+++ configure.ac 31 Mar 2005 07:33:35 -0000
@@ -32,12 +32,12 @@ AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GET
PKG_CHECK_MODULES(LIBEVPRIVATE, gtk+-2.0 >= 2.4.0)
PKG_CHECK_MODULES(RECENT_FILES, gtk+-2.0 >= 2.4.0 libgnomeui-2.0 >= 2.4.0)
-PKG_CHECK_MODULES(SHELL, gtk+-2.0 >= 2.6.0 libgnomeui-2.0 gnome-vfs-2.0 libgnomeprint-2.2 libgnomeprintui-2.2 libglade-2.0 gconf-2.0 poppler >= 0.1.1)
-PKG_CHECK_MODULES(THUMBNAILER, gtk+-2.0 >= 2.6.0 gnome-vfs-2.0 poppler >= 0.1.1)
+PKG_CHECK_MODULES(SHELL, gtk+-2.0 >= 2.6.0 libgnomeui-2.0 gnome-vfs-2.0 libgnomeprint-2.2 libgnomeprintui-2.2 libglade-2.0 gconf-2.0 poppler-glib >= 0.1.1)
+PKG_CHECK_MODULES(THUMBNAILER, gtk+-2.0 >= 2.6.0 gnome-vfs-2.0 poppler-glib >= 0.1.1)
PKG_CHECK_MODULES(DVI, gtk+-2.0 >= 2.6.0)
PKG_CHECK_MODULES(GTK, gtk+-2.0 >= 2.6.0)
PKG_CHECK_MODULES(PS, gtk+-2.0 >= 2.6.0 gnome-vfs-2.0 libgnomeui-2.0)
-PKG_CHECK_MODULES(POPPLER, poppler >= 0.1.1)
+PKG_CHECK_MODULES(POPPLER_GLIB, poppler-glib >= 0.1.2)
GLIB_GENMARSHAL=`$PKG_CONFIG --variable=glib_genmarshal glib-2.0`
AC_SUBST(GLIB_GENMARSHAL)
Index: backend/ev-document-thumbnails.h
===================================================================
RCS file: /cvs/gnome/evince/backend/ev-document-thumbnails.h,v
retrieving revision 1.3
diff -u -p -r1.3 ev-document-thumbnails.h
--- backend/ev-document-thumbnails.h 7 Mar 2005 13:51:11 -0000 1.3
+++ backend/ev-document-thumbnails.h 31 Mar 2005 07:33:35 -0000
@@ -52,6 +52,12 @@ struct _EvDocumentThumbnailsIface
};
GType ev_document_thumbnails_get_type (void);
+
+/* FIXME: This is a little bit busted. We call get_thumbnail w/ a suggested
+ * width, but we should call it with a scale so that different sized pages get
+ * sized proportionally.
+ */
+
GdkPixbuf *ev_document_thumbnails_get_thumbnail (EvDocumentThumbnails *document,
gint page,
gint size,
Index: backend/ev-document.c
===================================================================
RCS file: /cvs/gnome/evince/backend/ev-document.c,v
retrieving revision 1.18
diff -u -p -r1.18 ev-document.c
--- backend/ev-document.c 23 Mar 2005 11:07:31 -0000 1.18
+++ backend/ev-document.c 31 Mar 2005 07:33:35 -0000
@@ -27,17 +27,9 @@
static void ev_document_class_init (gpointer g_class);
-enum
-{
- PAGE_CHANGED,
- SCALE_CHANGED,
- LAST_SIGNAL
-};
-static guint signals[LAST_SIGNAL] = { 0 };
GMutex *ev_doc_mutex = NULL;
-
#define LOG(x)
GType
ev_document_get_type (void)
@@ -75,26 +67,6 @@ ev_document_error_quark (void)
static void
ev_document_class_init (gpointer g_class)
{
- signals[PAGE_CHANGED] =
- g_signal_new ("page_changed",
- EV_TYPE_DOCUMENT,
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EvDocumentIface, page_changed),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE,
- 0);
-
- signals[SCALE_CHANGED] =
- g_signal_new ("scale_changed",
- EV_TYPE_DOCUMENT,
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EvDocumentIface, scale_changed),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE,
- 0);
-
g_object_interface_install_property (g_class,
g_param_spec_string ("title",
"Document Title",
@@ -140,8 +112,11 @@ ev_document_load (EvDocument *document,
gboolean retval;
LOG ("ev_document_load");
retval = iface->load (document, uri, error);
+
/* Call this to make the initial cached copy */
- ev_document_get_page_cache (document);
+ if (retval)
+ ev_document_get_page_cache (document);
+
return retval;
}
@@ -205,16 +180,6 @@ ev_document_get_page (EvDocument *docume
}
void
-ev_document_set_target (EvDocument *document,
- GdkDrawable *target)
-{
- EvDocumentIface *iface = EV_DOCUMENT_GET_IFACE (document);
-
- LOG ("ev_document_set_target");
- iface->set_target (document, target);
-}
-
-void
ev_document_set_scale (EvDocument *document,
double scale)
{
@@ -225,17 +190,6 @@ ev_document_set_scale (EvDocument *doc
}
void
-ev_document_set_page_offset (EvDocument *document,
- int x,
- int y)
-{
- EvDocumentIface *iface = EV_DOCUMENT_GET_IFACE (document);
-
- LOG ("ev_document_set_page_offset");
- iface->set_page_offset (document, x, y);
-}
-
-void
ev_document_get_page_size (EvDocument *document,
int page,
int *width,
@@ -269,25 +223,29 @@ ev_document_get_link (EvDocument *docu
EvLink *retval;
LOG ("ev_document_get_link");
+ if (iface->get_link == NULL)
+ return NULL;
retval = iface->get_link (document, x, y);
return retval;
}
-void
-ev_document_render (EvDocument *document,
- int clip_x,
- int clip_y,
- int clip_width,
- int clip_height)
+GList *
+ev_document_get_links (EvDocument *document)
{
EvDocumentIface *iface = EV_DOCUMENT_GET_IFACE (document);
+ GList *retval;
+
+ LOG ("ev_document_get_link");
+ if (iface->get_links == NULL)
+ return NULL;
+ retval = iface->get_links (document);
- LOG ("ev_document_render");
- iface->render (document, clip_x, clip_y, clip_width, clip_height);
+ return retval;
}
+
GdkPixbuf *
ev_document_render_pixbuf (EvDocument *document)
{
@@ -302,15 +260,3 @@ ev_document_render_pixbuf (EvDocument *d
return retval;
}
-
-void
-ev_document_page_changed (EvDocument *document)
-{
- g_signal_emit (G_OBJECT (document), signals[PAGE_CHANGED], 0);
-}
-
-void
-ev_document_scale_changed (EvDocument *document)
-{
- g_signal_emit (G_OBJECT (document), signals[SCALE_CHANGED], 0);
-}
Index: backend/ev-document.h
===================================================================
RCS file: /cvs/gnome/evince/backend/ev-document.h,v
retrieving revision 1.17
diff -u -p -r1.17 ev-document.h
--- backend/ev-document.h 23 Mar 2005 11:07:31 -0000 1.17
+++ backend/ev-document.h 31 Mar 2005 07:33:35 -0000
@@ -73,13 +73,8 @@ struct _EvDocumentIface
void (* set_page) (EvDocument *document,
int page);
int (* get_page) (EvDocument *document);
- void (* set_target) (EvDocument *document,
- GdkDrawable *target);
void (* set_scale) (EvDocument *document,
double scale);
- void (* set_page_offset) (EvDocument *document,
- int x,
- int y);
void (* get_page_size) (EvDocument *document,
int page,
int *width,
@@ -89,15 +84,8 @@ struct _EvDocumentIface
EvLink * (* get_link) (EvDocument *document,
int x,
int y);
- void (* render) (EvDocument *document,
- int clip_x,
- int clip_y,
- int clip_width,
- int clip_height);
- GdkPixbuf *(* render_pixbuf) (EvDocument *document);
-
-
-
+ GList * (* get_links) (EvDocument *document);
+ GdkPixbuf * (* render_pixbuf) (EvDocument *document);
};
GType ev_document_get_type (void);
@@ -106,42 +94,31 @@ EvPageCache *ev_document_get_page_cache
GMutex *ev_document_get_doc_mutex (void);
-gboolean ev_document_load (EvDocument *document,
- const char *uri,
- GError **error);
-gboolean ev_document_save (EvDocument *document,
- const char *uri,
- GError **error);
-char *ev_document_get_title (EvDocument *document);
-int ev_document_get_n_pages (EvDocument *document);
-void ev_document_set_page (EvDocument *document,
- int page);
-int ev_document_get_page (EvDocument *document);
-void ev_document_set_target (EvDocument *document,
- GdkDrawable *target);
-void ev_document_set_scale (EvDocument *document,
- double scale);
-void ev_document_set_page_offset (EvDocument *document,
- int x,
- int y);
-void ev_document_get_page_size (EvDocument *document,
- int page,
- int *width,
- int *height);
-char *ev_document_get_text (EvDocument *document,
- GdkRectangle *rect);
-EvLink *ev_document_get_link (EvDocument *document,
- int x,
- int y);
-void ev_document_render (EvDocument *document,
- int clip_x,
- int clip_y,
- int clip_width,
- int clip_height);
-/* Quick hack to test threaded rendering */
-GdkPixbuf *ev_document_render_pixbuf (EvDocument *document);
-void ev_document_page_changed (EvDocument *document);
-void ev_document_scale_changed (EvDocument *document);
+gboolean ev_document_load (EvDocument *document,
+ const char *uri,
+ GError **error);
+gboolean ev_document_save (EvDocument *document,
+ const char *uri,
+ GError **error);
+char *ev_document_get_title (EvDocument *document);
+int ev_document_get_n_pages (EvDocument *document);
+void ev_document_set_page (EvDocument *document,
+ int page);
+int ev_document_get_page (EvDocument *document);
+void ev_document_set_scale (EvDocument *document,
+ double scale);
+void ev_document_get_page_size (EvDocument *document,
+ int page,
+ int *width,
+ int *height);
+char *ev_document_get_text (EvDocument *document,
+ GdkRectangle *rect);
+EvLink *ev_document_get_link (EvDocument *document,
+ int x,
+ int y);
+GList *ev_document_get_links (EvDocument *document);
+GdkPixbuf *ev_document_render_pixbuf (EvDocument *document);
+
G_END_DECLS
Index: backend/ev-jobs.c
===================================================================
RCS file: /cvs/gnome/evince/backend/ev-jobs.c,v
retrieving revision 1.2
diff -u -p -r1.2 ev-jobs.c
--- backend/ev-jobs.c 23 Mar 2005 11:07:31 -0000 1.2
+++ backend/ev-jobs.c 31 Mar 2005 07:33:35 -0000
@@ -182,7 +182,8 @@ ev_job_render_new (EvDocument *document,
gint page,
double scale,
gint width,
- gint height)
+ gint height,
+ gboolean include_links)
{
EvJobRender *job;
@@ -193,6 +194,7 @@ ev_job_render_new (EvDocument *document,
job->scale = scale;
job->target_width = width;
job->target_height = height;
+ job->include_links = include_links;
return EV_JOB (job);
}
@@ -204,9 +206,11 @@ ev_job_render_run (EvJobRender *job)
g_mutex_lock (EV_DOC_MUTEX);
- ev_document_set_scale (EV_JOB (job)->document, job->scale);
ev_document_set_page (EV_JOB (job)->document, job->page);
+ ev_document_set_scale (EV_JOB (job)->document, job->scale);
job->pixbuf = ev_document_render_pixbuf (EV_JOB (job)->document);
+ if (job->include_links)
+ job->link_mapping = ev_document_get_links (EV_JOB (job)->document);
EV_JOB (job)->finished = TRUE;
g_mutex_unlock (EV_DOC_MUTEX);
Index: backend/ev-jobs.h
===================================================================
RCS file: /cvs/gnome/evince/backend/ev-jobs.h,v
retrieving revision 1.2
diff -u -p -r1.2 ev-jobs.h
--- backend/ev-jobs.h 23 Mar 2005 11:07:31 -0000 1.2
+++ backend/ev-jobs.h 31 Mar 2005 07:33:35 -0000
@@ -97,6 +97,8 @@ struct _EvJobRender
gint target_width;
gint target_height;
GdkPixbuf *pixbuf;
+ GList *link_mapping;
+ gboolean include_links;
};
struct _EvJobRenderClass
@@ -134,7 +136,8 @@ EvJob *ev_job_render_new
gint page,
double scale,
gint width,
- gint height);
+ gint height,
+ gboolean include_links);
void ev_job_render_run (EvJobRender *thumbnail);
/* EvJobThumbnail */
Index: backend/ev-link.c
===================================================================
RCS file: /cvs/gnome/evince/backend/ev-link.c,v
retrieving revision 1.3
diff -u -p -r1.3 ev-link.c
--- backend/ev-link.c 23 Mar 2005 11:07:31 -0000 1.3
+++ backend/ev-link.c 31 Mar 2005 07:33:35 -0000
@@ -85,13 +85,14 @@ void
ev_link_set_title (EvLink* self, const char *title)
{
g_assert (EV_IS_LINK (self));
- g_assert (title != NULL);
if (self->priv->title != NULL) {
g_free (self->priv->title);
}
-
- self->priv->title = g_strdup (title);
+ if (title)
+ self->priv->title = g_strdup (title);
+ else
+ self->priv->title = NULL;
g_object_notify (G_OBJECT (self), "title");
}
@@ -314,3 +315,50 @@ ev_link_new_external (const char *title,
"type", EV_LINK_TYPE_EXTERNAL_URI,
NULL));
}
+
+
+
+static void
+ev_link_mapping_free_foreach (EvLinkMapping *mapping)
+{
+ g_object_unref (G_OBJECT (mapping->link));
+ g_free (mapping);
+}
+
+void
+ev_link_mapping_free (GList *link_mapping)
+{
+ if (link_mapping == NULL)
+ return;
+
+ g_list_foreach (link_mapping, (GFunc) (ev_link_mapping_free_foreach), NULL);
+ g_list_free (link_mapping);
+}
+
+
+EvLink *
+ev_link_mapping_find (GList *link_mapping,
+ gdouble x,
+ gdouble y)
+{
+ GList *list;
+ EvLink *link = NULL;
+ int i;
+
+ i = 0;
+ for (list = link_mapping; list; list = list->next) {
+ EvLinkMapping *mapping = list->data;
+
+ i++;
+ if ((x >= mapping->x1) &&
+ (y >= mapping->y1) &&
+ (x <= mapping->x2) &&
+ (y <= mapping->y2)) {
+ link = mapping->link;
+ break;
+ }
+ }
+
+ return link;
+}
+
Index: backend/ev-link.h
===================================================================
RCS file: /cvs/gnome/evince/backend/ev-link.h,v
retrieving revision 1.2
diff -u -p -r1.2 ev-link.h
--- backend/ev-link.h 23 Mar 2005 11:07:31 -0000 1.2
+++ backend/ev-link.h 31 Mar 2005 07:33:35 -0000
@@ -37,6 +37,8 @@ typedef struct _EvLinkPrivate EvLinkPriv
#define EV_TYPE_LINK_TYPE (ev_link_type_get_type ())
+
+
typedef enum
{
EV_LINK_TYPE_TITLE,
@@ -67,6 +69,22 @@ int ev_link_get_page (EvLink *link)
void ev_link_set_page (EvLink *link,
int page);
+/* Link Mapping stuff */
+
+typedef struct _EvLinkMapping EvLinkMapping;
+struct _EvLinkMapping
+{
+ EvLink *link;
+ gdouble x1;
+ gdouble y1;
+ gdouble x2;
+ gdouble y2;
+};
+
+void ev_link_mapping_free (GList *link_mapping);
+EvLink *ev_link_mapping_find (GList *link_mapping,
+ gdouble x,
+ gdouble y);
G_END_DECLS
#endif /* !EV_LINK_H */
Index: backend/ev-page-cache.c
===================================================================
RCS file: /cvs/gnome/evince/backend/ev-page-cache.c,v
retrieving revision 1.2
diff -u -p -r1.2 ev-page-cache.c
--- backend/ev-page-cache.c 23 Mar 2005 11:07:31 -0000 1.2
+++ backend/ev-page-cache.c 31 Mar 2005 07:33:35 -0000
@@ -48,7 +48,7 @@ G_DEFINE_TYPE (EvPageCache, ev_page_cach
static void
ev_page_cache_init (EvPageCache *page_cache)
{
- page_cache->current_page = 1;
+ page_cache->current_page = 0;
}
static void
@@ -102,13 +102,13 @@ _ev_page_cache_new (EvDocument *document
page_cache->title = ev_document_get_title (document);
ev_document_set_scale (document, 1.0);
- for (i = 1; i <= page_cache->n_pages; i++) {
+ for (i = 0; i < page_cache->n_pages; i++) {
gint page_width = 0;
gint page_height = 0;
ev_document_get_page_size (document, i, &page_width, &page_height);
- if (i == 1) {
+ if (i == 0) {
page_cache->uniform_width = page_width;
page_cache->uniform_height = page_height;
} else if (page_cache->uniform &&
@@ -169,7 +169,7 @@ ev_page_cache_set_current_page (EvPageCa
int page)
{
g_return_if_fail (EV_IS_PAGE_CACHE (page_cache));
- g_return_if_fail (page > 0 || page <= page_cache->n_pages);
+ g_return_if_fail (page >= 0 || page < page_cache->n_pages);
if (page == page_cache->current_page)
return;
@@ -204,7 +204,7 @@ ev_page_cache_get_size (EvPageCache *pag
gint *height)
{
g_return_if_fail (EV_IS_PAGE_CACHE (page_cache));
- g_return_if_fail (page > 0 && page <= page_cache->n_pages);
+ g_return_if_fail (page >= 0 && page < page_cache->n_pages);
if (page_cache->uniform) {
if (width)
@@ -214,7 +214,7 @@ ev_page_cache_get_size (EvPageCache *pag
} else {
EvPageCacheInfo *info;
- info = &(page_cache->size_cache [page - 1]);
+ info = &(page_cache->size_cache [page]);
if (width)
*width = info->width;
@@ -234,7 +234,7 @@ ev_page_cache_next_page (EvPageCache *pa
{
g_return_val_if_fail (EV_IS_PAGE_CACHE (page_cache), FALSE);
- if (page_cache->current_page >= page_cache->n_pages)
+ if (page_cache->current_page > page_cache->n_pages)
return FALSE;
ev_page_cache_set_current_page (page_cache, page_cache->current_page + 1);
@@ -247,7 +247,7 @@ ev_page_cache_prev_page (EvPageCache *pa
{
g_return_val_if_fail (EV_IS_PAGE_CACHE (page_cache), FALSE);
- if (page_cache->current_page <= 1)
+ if (page_cache->current_page <= 0)
return FALSE;
ev_page_cache_set_current_page (page_cache, page_cache->current_page - 1);
Index: pdf/Makefile.am
===================================================================
RCS file: /cvs/gnome/evince/pdf/Makefile.am,v
retrieving revision 1.2
diff -u -p -r1.2 Makefile.am
--- pdf/Makefile.am 1 Mar 2005 22:24:08 -0000 1.2
+++ pdf/Makefile.am 31 Mar 2005 07:33:35 -0000
@@ -1,24 +1,16 @@
INCLUDES = \
-I$(top_srcdir) \
-I$(top_srcdir)/backend \
- $(POPPLER_CFLAGS) \
+ $(POPPLER_GLIB_CFLAGS) \
$(GTK_CFLAGS) \
-DDATADIR=\""$(datadir)"\"
-noinst_PROGRAMS = test-gdk-output-dev
-
noinst_LTLIBRARIES = libpdfdocument.la
libpdfdocument_la_SOURCES = \
- GDKSplashOutputDev.cc \
- GDKSplashOutputDev.h \
- Thumb.cc \
- Thumb.h \
- pdf-document.cc \
- pdf-document.h
+ ev-poppler.cc \
+ ev-poppler.h
-test_gdk_output_dev_SOURCES = \
- test-gdk-output-dev.cc
test_gdk_output_dev_LDADD = \
libpdfdocument.la \
Index: pdf/ev-poppler.cc
===================================================================
RCS file: pdf/ev-poppler.cc
diff -N pdf/ev-poppler.cc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ pdf/ev-poppler.cc 31 Mar 2005 07:33:36 -0000
@@ -0,0 +1,592 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */
+/* pdfdocument.h: Implementation of EvDocument for PDF
+ * Copyright (C) 2004, Red Hat, Inc.
+ *
+ * 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 <gtk/gtk.h>
+#include <poppler.h>
+#include <poppler-document.h>
+#include <poppler-page.h>
+
+#include "ev-poppler.h"
+#include "ev-ps-exporter.h"
+#include "ev-document-find.h"
+#include "ev-document-misc.h"
+#include "ev-document-links.h"
+#include "ev-document-security.h"
+#include "ev-document-thumbnails.h"
+
+
+enum {
+ PROP_0,
+ PROP_TITLE
+};
+
+
+struct _PdfDocumentClass
+{
+ GObjectClass parent_class;
+};
+
+struct _PdfDocument
+{
+ GObject parent_instance;
+
+ PopplerDocument *document;
+ PopplerPage *page;
+ double scale;
+ gchar *password;
+};
+
+static void pdf_document_document_iface_init (EvDocumentIface *iface);
+static void pdf_document_security_iface_init (EvDocumentSecurityIface *iface);
+static void pdf_document_document_thumbnails_iface_init (EvDocumentThumbnailsIface *iface);
+static void pdf_document_document_links_iface_init (EvDocumentLinksIface *iface);
+static void pdf_document_thumbnails_get_dimensions (EvDocumentThumbnails *document_thumbnails,
+ gint page,
+ gint size,
+ gint *width,
+ gint *height);
+static EvLink * ev_link_from_action (PopplerAction *action);
+
+
+G_DEFINE_TYPE_WITH_CODE (PdfDocument, pdf_document, G_TYPE_OBJECT,
+ {
+ G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT,
+ pdf_document_document_iface_init);
+ G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_SECURITY,
+ pdf_document_security_iface_init);
+ G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_THUMBNAILS,
+ pdf_document_document_thumbnails_iface_init);
+ G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_LINKS,
+ pdf_document_document_links_iface_init);
+#if 0
+ G_IMPLEMENT_INTERFACE (EV_TYPE_PS_EXPORTER,
+ pdf_document_ps_exporter_iface_init);
+ G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_FIND,
+ pdf_document_find_iface_init);
+#endif
+ });
+
+
+
+
+
+
+static void
+pdf_document_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ PdfDocument *pdf_document = PDF_DOCUMENT (object);
+
+ switch (prop_id)
+ {
+ case PROP_TITLE:
+ if (pdf_document->document == NULL)
+ g_value_set_string (value, NULL);
+ else
+ g_object_get_property (G_OBJECT (pdf_document->document), "title", value);
+ break;
+ }
+}
+
+static void
+pdf_document_class_init (PdfDocumentClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ gobject_class->get_property = pdf_document_get_property;
+
+ g_object_class_override_property (gobject_class, PROP_TITLE, "title");
+}
+
+static void
+pdf_document_init (PdfDocument *pdf_document)
+{
+ pdf_document->page = NULL;
+ pdf_document->scale = 1.0;
+ pdf_document->password = NULL;
+}
+
+static void
+convert_error (GError *poppler_error,
+ GError **error)
+{
+ if (poppler_error == NULL)
+ return;
+
+ if (poppler_error->domain == POPPLER_ERROR) {
+ /* convert poppler errors into EvDocument errors */
+ gint code = EV_DOCUMENT_ERROR_INVALID;
+ if (poppler_error->code == POPPLER_ERROR_INVALID)
+ code = EV_DOCUMENT_ERROR_INVALID;
+ else if (poppler_error->code == POPPLER_ERROR_ENCRYPTED)
+ code = EV_DOCUMENT_ERROR_ENCRYPTED;
+
+
+ g_set_error (error,
+ EV_DOCUMENT_ERROR,
+ code,
+ poppler_error->message,
+ NULL);
+ } else {
+ g_propagate_error (error, poppler_error);
+ }
+}
+
+
+/* EvDocument */
+static gboolean
+pdf_document_save (EvDocument *document,
+ const char *uri,
+ GError **error)
+{
+ gboolean retval;
+ GError *poppler_error = NULL;
+
+ retval = poppler_document_save (PDF_DOCUMENT (document)->document,
+ uri,
+ &poppler_error);
+ if (! retval)
+ convert_error (poppler_error, error);
+
+ return retval;
+}
+
+static gboolean
+pdf_document_load (EvDocument *document,
+ const char *uri,
+ GError **error)
+{
+ GError *poppler_error = NULL;
+ PdfDocument *pdf_document = PDF_DOCUMENT (document);
+
+ pdf_document->document =
+ poppler_document_new_from_file (uri, pdf_document->password, &poppler_error);
+
+ if (pdf_document->document == NULL) {
+ convert_error (poppler_error, error);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static int
+pdf_document_get_n_pages (EvDocument *document)
+{
+ return poppler_document_get_n_pages (PDF_DOCUMENT (document)->document);
+}
+
+static void
+pdf_document_set_page (EvDocument *document,
+ int page)
+{
+ page = CLAMP (page, 0, poppler_document_get_n_pages (PDF_DOCUMENT (document)->document) - 1);
+
+ PDF_DOCUMENT (document)->page = poppler_document_get_page (PDF_DOCUMENT (document)->document, page);
+}
+
+static int
+pdf_document_get_page (EvDocument *document)
+{
+ PdfDocument *pdf_document;
+
+ pdf_document = PDF_DOCUMENT (document);
+
+ if (pdf_document->page)
+ return poppler_page_get_index (pdf_document->page);
+
+ return 1;
+}
+
+static void
+pdf_document_set_scale (EvDocument *document,
+ double scale)
+{
+ PDF_DOCUMENT (document)->scale = scale;
+}
+
+
+static void
+get_size_from_page (PopplerPage *poppler_page,
+ double scale,
+ int *width,
+ int *height)
+{
+ gdouble width_d, height_d;
+ poppler_page_get_size (poppler_page, &width_d, &height_d);
+ if (width)
+ *width = (int) (width_d * scale);
+ if (height)
+ *height = (int) (height_d * scale);
+
+}
+
+static void
+pdf_document_get_page_size (EvDocument *document,
+ int page,
+ int *width,
+ int *height)
+{
+ PopplerPage *poppler_page = NULL;
+
+ if (page == -1)
+ poppler_page = PDF_DOCUMENT (document)->page;
+ else
+ poppler_page = poppler_document_get_page (PDF_DOCUMENT (document)->document,
+ page);
+
+ if (poppler_page == NULL)
+ poppler_document_get_page (PDF_DOCUMENT (document)->document, 0);
+
+ get_size_from_page (poppler_page,
+ PDF_DOCUMENT (document)->scale,
+ width, height);
+}
+
+static GList *
+pdf_document_get_links (EvDocument *document)
+{
+ PdfDocument *pdf_document;
+ GList *retval = NULL;
+ GList *mapping_list;
+ GList *list;
+ gint height;
+
+ pdf_document = PDF_DOCUMENT (document);
+ g_return_val_if_fail (pdf_document->page != NULL, NULL);
+
+ mapping_list = poppler_page_get_link_mapping (pdf_document->page);
+ get_size_from_page (pdf_document->page, 1.0, NULL, &height);
+
+ for (list = mapping_list; list; list = list->next) {
+ PopplerLinkMapping *link_mapping;
+ EvLinkMapping *ev_link_mapping;
+
+ link_mapping = (PopplerLinkMapping *)list->data;
+ ev_link_mapping = g_new (EvLinkMapping, 1);
+ ev_link_mapping->link = ev_link_from_action (link_mapping->action);
+ ev_link_mapping->x1 = link_mapping->x1;
+ ev_link_mapping->x2 = link_mapping->x2;
+ /* Invert this for X-style coordinates */
+ ev_link_mapping->y1 = height - link_mapping->y2;
+ ev_link_mapping->y2 = height - link_mapping->y1;
+
+ retval = g_list_prepend (retval, ev_link_mapping);
+ }
+
+ poppler_page_free_link_mapping (mapping_list);
+
+ return g_list_reverse (retval);
+}
+
+
+static GdkPixbuf *
+pdf_document_render_pixbuf (EvDocument *document)
+{
+ PdfDocument *pdf_document;
+ GdkPixbuf *pixbuf;
+ gint width, height;
+
+ pdf_document = PDF_DOCUMENT (document);
+ g_return_val_if_fail (pdf_document->page != NULL, NULL);
+
+ get_size_from_page (pdf_document->page,
+ pdf_document->scale,
+ &width, &height);
+
+ pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
+ FALSE, 8,
+ width, height);
+
+ poppler_page_render_to_pixbuf (pdf_document->page,
+ 0, 0,
+ width, height,
+ pdf_document->scale,
+ pixbuf,
+ 0, 0);
+
+ return pixbuf;
+}
+
+/* EvDocumentSecurity */
+
+static gboolean
+pdf_document_has_document_security (EvDocumentSecurity *document_security)
+{
+ /* FIXME: do we really need to have this? */
+ return FALSE;
+}
+
+static void
+pdf_document_set_password (EvDocumentSecurity *document_security,
+ const char *password)
+{
+ PdfDocument *document = PDF_DOCUMENT (document_security);
+
+ if (document->password)
+ g_free (document->password);
+
+ document->password = g_strdup (password);
+}
+
+
+
+static void
+pdf_document_document_iface_init (EvDocumentIface *iface)
+{
+ iface->save = pdf_document_save;
+ iface->load = pdf_document_load;
+ iface->get_n_pages = pdf_document_get_n_pages;
+ iface->set_page = pdf_document_set_page;
+ iface->get_page = pdf_document_get_page;
+ iface->set_scale = pdf_document_set_scale;
+ iface->get_page_size = pdf_document_get_page_size;
+ iface->get_links = pdf_document_get_links;
+ iface->render_pixbuf = pdf_document_render_pixbuf;
+};
+
+static void
+pdf_document_security_iface_init (EvDocumentSecurityIface *iface)
+{
+ iface->has_document_security = pdf_document_has_document_security;
+ iface->set_password = pdf_document_set_password;
+}
+
+static gboolean
+pdf_document_links_has_document_links (EvDocumentLinks *document_links)
+{
+ PdfDocument *pdf_document = PDF_DOCUMENT (document_links);
+ PopplerIndexIter *iter;
+
+ g_return_val_if_fail (PDF_IS_DOCUMENT (document_links), FALSE);
+
+ iter = poppler_index_iter_new (pdf_document->document);
+ if (iter == NULL)
+ return FALSE;
+ poppler_index_iter_free (iter);
+
+ return TRUE;
+}
+
+static EvLink *
+ev_link_from_action (PopplerAction *action)
+{
+ EvLink *link;
+ const char *title;
+
+ title = action->any.title;
+
+ if (action->type == POPPLER_ACTION_GOTO_DEST) {
+ link = ev_link_new_page (title, action->goto_dest.dest->page_num - 1);
+ } else if (action->type == POPPLER_ACTION_URI) {
+ link = ev_link_new_external (title, action->uri.uri);
+ } else {
+ link = ev_link_new_title (title);
+ }
+
+ return link;
+}
+
+
+static void
+build_tree (PdfDocument *pdf_document,
+ GtkTreeModel *model,
+ GtkTreeIter *parent,
+ PopplerIndexIter *iter)
+{
+
+ do {
+ GtkTreeIter tree_iter;
+ PopplerIndexIter *child;
+ PopplerAction *action;
+ EvLink *link;
+
+ action = poppler_index_iter_get_action (iter);
+ if (action) {
+ gtk_tree_store_append (GTK_TREE_STORE (model), &tree_iter, parent);
+ link = ev_link_from_action (action);
+ poppler_action_free (action);
+
+ gtk_tree_store_set (GTK_TREE_STORE (model), &tree_iter,
+ EV_DOCUMENT_LINKS_COLUMN_MARKUP, ev_link_get_title (link),
+ EV_DOCUMENT_LINKS_COLUMN_LINK, link,
+ -1);
+ child = poppler_index_iter_get_child (iter);
+ if (child)
+ build_tree (pdf_document, model, &tree_iter, child);
+ poppler_index_iter_free (child);
+ }
+ } while (poppler_index_iter_next (iter));
+}
+
+
+static GtkTreeModel *
+pdf_document_links_get_links_model (EvDocumentLinks *document_links)
+{
+ PdfDocument *pdf_document = PDF_DOCUMENT (document_links);
+ GtkTreeModel *model = NULL;
+ PopplerIndexIter *iter;
+
+ g_return_val_if_fail (PDF_IS_DOCUMENT (document_links), NULL);
+
+ iter = poppler_index_iter_new (pdf_document->document);
+ /* Create the model iff we have items*/
+ if (iter != NULL) {
+ model = (GtkTreeModel *) gtk_tree_store_new (EV_DOCUMENT_LINKS_COLUMN_NUM_COLUMNS,
+ G_TYPE_STRING,
+ G_TYPE_POINTER);
+ build_tree (pdf_document, model, NULL, iter);
+ poppler_index_iter_free (iter);
+ }
+
+
+ return model;
+}
+
+
+static void
+pdf_document_document_links_iface_init (EvDocumentLinksIface *iface)
+{
+ iface->has_document_links = pdf_document_links_has_document_links;
+ iface->get_links_model = pdf_document_links_get_links_model;
+}
+
+
+static GdkPixbuf *
+make_thumbnail_for_size (PdfDocument *pdf_document,
+ gint page,
+ gint size,
+ gboolean border)
+{
+ PopplerPage *poppler_page;
+ GdkPixbuf *pixbuf;
+ int width, height;
+ int x_offset, y_offset;
+ double scale;
+ gdouble unscaled_width, unscaled_height;
+
+ poppler_page = poppler_document_get_page (pdf_document->document, page);
+
+ g_return_val_if_fail (poppler_page != NULL, NULL);
+
+ pdf_document_thumbnails_get_dimensions (EV_DOCUMENT_THUMBNAILS (pdf_document), page, size, &width, &height);
+ poppler_page_get_size (poppler_page, &unscaled_width, &unscaled_height);
+ scale = width / unscaled_width;
+
+ if (border) {
+ pixbuf = ev_document_misc_get_thumbnail_frame (width, height, NULL);
+ x_offset = 1;
+ y_offset = 1;
+ } else {
+ pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8,
+ width, height);
+ gdk_pixbuf_fill (pixbuf, 0xffffffff);
+ x_offset = 0;
+ y_offset = 0;
+ }
+
+ poppler_page_render_to_pixbuf (poppler_page, 0, 0,
+ width, height,
+ scale, pixbuf,
+ x_offset, y_offset);
+
+ return pixbuf;
+}
+
+static GdkPixbuf *
+pdf_document_thumbnails_get_thumbnail (EvDocumentThumbnails *document_thumbnails,
+ gint page,
+ gint size,
+ gboolean border)
+{
+ PdfDocument *pdf_document;
+ PopplerPage *poppler_page;
+ GdkPixbuf *pixbuf;
+
+ pdf_document = PDF_DOCUMENT (document_thumbnails);
+
+ poppler_page = poppler_document_get_page (pdf_document->document, page);
+ g_return_val_if_fail (poppler_page != NULL, NULL);
+
+ pixbuf = poppler_page_get_thumbnail (poppler_page);
+ if (pixbuf != NULL) {
+ /* The document provides its own thumbnails. */
+ if (border) {
+ GdkPixbuf *real_pixbuf;
+
+ real_pixbuf = ev_document_misc_get_thumbnail_frame (-1, -1, pixbuf);
+ g_object_unref (pixbuf);
+ pixbuf = real_pixbuf;
+ }
+ } else {
+ /* There is no provided thumbnail. We need to make one. */
+ pixbuf = make_thumbnail_for_size (pdf_document, page, size, border);
+ }
+ return pixbuf;
+}
+
+static void
+pdf_document_thumbnails_get_dimensions (EvDocumentThumbnails *document_thumbnails,
+ gint page,
+ gint size,
+ gint *width,
+ gint *height)
+{
+ PdfDocument *pdf_document;
+ PopplerPage *poppler_page;
+ gint has_thumb;
+
+ pdf_document = PDF_DOCUMENT (document_thumbnails);
+ poppler_page = poppler_document_get_page (pdf_document->document, page);
+
+ g_return_if_fail (width != NULL);
+ g_return_if_fail (height != NULL);
+ g_return_if_fail (poppler_page != NULL);
+
+ has_thumb = poppler_page_get_thumbnail_size (poppler_page, width, height);
+
+ if (!has_thumb) {
+ int page_width, page_height;
+
+ get_size_from_page (poppler_page, 1.0, &page_width, &page_height);
+
+ if (page_width > page_height) {
+ *width = size;
+ *height = (int) (size * page_height / page_width);
+ } else {
+ *width = (int) (size * page_width / page_height);
+ *height = size;
+ }
+ }
+}
+
+static void
+pdf_document_document_thumbnails_iface_init (EvDocumentThumbnailsIface *iface)
+{
+ iface->get_thumbnail = pdf_document_thumbnails_get_thumbnail;
+ iface->get_dimensions = pdf_document_thumbnails_get_dimensions;
+}
+
+PdfDocument *
+pdf_document_new (void)
+{
+ return PDF_DOCUMENT (g_object_new (PDF_TYPE_DOCUMENT, NULL));
+}
Index: pdf/ev-poppler.h
===================================================================
RCS file: pdf/ev-poppler.h
diff -N pdf/ev-poppler.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ pdf/ev-poppler.h 31 Mar 2005 07:33:36 -0000
@@ -0,0 +1,39 @@
+/* pdfdocument.h: Implementation of EvDocument for PDF
+ * Copyright (C) 2004, Red Hat, Inc.
+ *
+ * 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 __PDF_DOCUMENT_H__
+#define __PDF_DOCUMENT_H__
+
+#include "ev-document.h"
+
+G_BEGIN_DECLS
+
+#define PDF_TYPE_DOCUMENT (pdf_document_get_type ())
+#define PDF_DOCUMENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PDF_TYPE_DOCUMENT, PdfDocument))
+#define PDF_IS_DOCUMENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PDF_TYPE_DOCUMENT))
+
+typedef struct _PdfDocument PdfDocument;
+typedef struct _PdfDocumentClass PdfDocumentClass;
+
+PdfDocument *pdf_document_new (void);
+GType pdf_document_get_type (void) G_GNUC_CONST;
+
+
+G_END_DECLS
+
+#endif /* __PDF_DOCUMENT_H__ */
Index: ps/ps-document.c
===================================================================
RCS file: /cvs/gnome/evince/ps/ps-document.c,v
retrieving revision 1.24
diff -u -p -r1.24 ps-document.c
--- ps/ps-document.c 23 Mar 2005 11:07:31 -0000 1.24
+++ ps/ps-document.c 31 Mar 2005 07:33:36 -0000
@@ -137,8 +137,6 @@ ps_document_init (PSDocument *gs)
gs->bytes_left = 0;
gs->buffer_bytes_left = 0;
- gs->page_x_offset = 0;
- gs->page_y_offset = 0;
gs->zoom_factor = 1.0;
gs->gs_status = _("No document loaded.");
@@ -1208,7 +1206,7 @@ ps_document_set_page (EvDocument *docum
LOG ("Set document page %d\n", page);
- gs->current_page = page - 1;
+ gs->current_page = page;
compute_dimensions (gs, page);
}
@@ -1219,7 +1217,7 @@ ps_document_get_page (EvDocument *docum
g_return_val_if_fail (ps != NULL, -1);
- return ps->current_page + 1;
+ return ps->current_page;
}
static void
@@ -1233,17 +1231,6 @@ ps_document_set_scale (EvDocument *docu
}
static void
-ps_document_set_page_offset (EvDocument *document,
- int x,
- int y)
-{
- PSDocument *gs = PS_DOCUMENT (document);
-
- gs->page_x_offset = x;
- gs->page_y_offset = y;
-}
-
-static void
ps_document_get_page_size (EvDocument *document,
int page,
int *width,
@@ -1338,7 +1325,6 @@ ps_document_document_iface_init (EvDocum
iface->set_page = ps_document_set_page;
iface->get_page = ps_document_get_page;
iface->set_scale = ps_document_set_scale;
- iface->set_page_offset = ps_document_set_page_offset;
iface->get_page_size = ps_document_get_page_size;
iface->render_pixbuf = ps_document_render_pixbuf;
}
Index: shell/ev-pixbuf-cache.c
===================================================================
RCS file: /cvs/gnome/evince/shell/ev-pixbuf-cache.c,v
retrieving revision 1.2
diff -u -p -r1.2 ev-pixbuf-cache.c
--- shell/ev-pixbuf-cache.c 23 Mar 2005 11:07:32 -0000 1.2
+++ shell/ev-pixbuf-cache.c 31 Mar 2005 07:33:36 -0000
@@ -6,6 +6,7 @@ typedef struct _CacheJobInfo
{
EvJob *job;
GdkPixbuf *pixbuf;
+ GList *link_mapping;
} CacheJobInfo;
struct _EvPixbufCache
@@ -50,14 +51,16 @@ static void job_finished_cb
EvPixbufCache *pixbuf_cache);
static CacheJobInfo *find_job_cache (EvPixbufCache *pixbuf_cache,
int page);
-
+static void copy_job_to_job_info (EvJobRender *job_render,
+ CacheJobInfo *job_info,
+ EvPixbufCache *pixbuf_cache);
/* These are used for iterating through the prev and next arrays */
#define FIRST_VISABLE_PREV(pixbuf_cache) \
(MAX (0, pixbuf_cache->preload_cache_size + 1 - pixbuf_cache->start_page))
#define VISIBLE_NEXT_LEN(pixbuf_cache, page_cache) \
- (MIN(pixbuf_cache->preload_cache_size, ev_page_cache_get_n_pages (page_cache) - pixbuf_cache->end_page))
+ (MIN(pixbuf_cache->preload_cache_size, ev_page_cache_get_n_pages (page_cache) - (1 + pixbuf_cache->end_page)))
#define PAGE_CACHE_LEN(pixbuf_cache) \
((pixbuf_cache->end_page - pixbuf_cache->start_page) + 1)
@@ -66,8 +69,8 @@ G_DEFINE_TYPE (EvPixbufCache, ev_pixbuf_
static void
ev_pixbuf_cache_init (EvPixbufCache *pixbuf_cache)
{
- pixbuf_cache->start_page = 1;
- pixbuf_cache->end_page = 1;
+ pixbuf_cache->start_page = 0;
+ pixbuf_cache->end_page = 0;
pixbuf_cache->job_list = g_new0 (CacheJobInfo, PAGE_CACHE_LEN (pixbuf_cache));
pixbuf_cache->preload_cache_size = 1;
@@ -123,6 +126,10 @@ dispose_cache_job_info (CacheJobInfo *jo
g_object_unref (G_OBJECT (job_info->pixbuf));
job_info->pixbuf = NULL;
}
+ if (job_info->link_mapping) {
+ ev_link_mapping_free (job_info->link_mapping);
+ job_info->link_mapping = NULL;
+ }
}
static void
@@ -177,6 +184,12 @@ job_finished_cb (EvJob *job,
g_object_unref (job_info->pixbuf);
job_info->pixbuf = pixbuf;
+ if (job_render->link_mapping) {
+ if (job_info->link_mapping)
+ ev_link_mapping_free (job_info->link_mapping);
+ job_info->link_mapping = job_render->link_mapping;
+ }
+
if (job_info->job == job)
job_info->job = NULL;
g_object_unref (job);
@@ -268,6 +281,7 @@ move_one_job (CacheJobInfo *job_info,
*target_page = *job_info;
job_info->job = NULL;
job_info->pixbuf = NULL;
+ job_info->link_mapping = NULL;
if (new_priority != priority && target_page->job) {
g_print ("FIXME: update priority \n");
@@ -303,7 +317,7 @@ ev_pixbuf_cache_update_range (EvPixbufCa
/* Start with the prev cache. */
page = pixbuf_cache->start_page - pixbuf_cache->preload_cache_size;
for (i = 0; i < pixbuf_cache->preload_cache_size; i++) {
- if (page < 1) {
+ if (page < 0) {
dispose_cache_job_info (pixbuf_cache->prev_job + i, pixbuf_cache);
} else {
move_one_job (pixbuf_cache->prev_job + i,
@@ -324,7 +338,7 @@ ev_pixbuf_cache_update_range (EvPixbufCa
}
for (i = 0; i < pixbuf_cache->preload_cache_size; i++) {
- if (page > ev_page_cache_get_n_pages (page_cache)) {
+ if (page >= ev_page_cache_get_n_pages (page_cache)) {
dispose_cache_job_info (pixbuf_cache->next_job + i, pixbuf_cache);
} else {
move_one_job (pixbuf_cache->next_job + i,
@@ -347,6 +361,22 @@ ev_pixbuf_cache_update_range (EvPixbufCa
pixbuf_cache->end_page = end_page;
}
+static void
+copy_job_to_job_info (EvJobRender *job_render,
+ CacheJobInfo *job_info,
+ EvPixbufCache *pixbuf_cache)
+{
+ GdkPixbuf *pixbuf;
+
+ pixbuf = g_object_ref (job_render->pixbuf);
+
+ dispose_cache_job_info (job_info, pixbuf_cache);
+
+ job_info->pixbuf = pixbuf;
+ if (job_render->link_mapping)
+ job_info->link_mapping = job_render->link_mapping;
+}
+
static CacheJobInfo *
find_job_cache (EvPixbufCache *pixbuf_cache,
int page)
@@ -426,7 +456,8 @@ add_job_if_needed (EvPixbufCache *pixbuf
/* make a new job now */
job_info->job = ev_job_render_new (pixbuf_cache->document,
page, scale,
- width, height);
+ width, height,
+ (job_info->link_mapping == NULL)?TRUE:FALSE);
ev_job_queue_add_job (job_info->job, priority);
g_signal_connect (job_info->job, "finished", G_CALLBACK (job_finished_cb), pixbuf_cache);
}
@@ -484,8 +515,8 @@ ev_pixbuf_cache_set_page_range (EvPixbuf
page_cache = ev_document_get_page_cache (pixbuf_cache->document);
- g_return_if_fail (start_page > 0 && start_page <= ev_page_cache_get_n_pages (page_cache));
- g_return_if_fail (end_page > 0 && end_page <= ev_page_cache_get_n_pages (page_cache));
+ g_return_if_fail (start_page >= 0 && start_page < ev_page_cache_get_n_pages (page_cache));
+ g_return_if_fail (end_page >= 0 && end_page < ev_page_cache_get_n_pages (page_cache));
g_return_if_fail (end_page >= start_page);
/* First, resize the page_range as needed. We cull old pages
@@ -514,12 +545,27 @@ ev_pixbuf_cache_get_pixbuf (EvPixbufCach
/* We don't need to wait for the idle to handle the callback */
if (job_info->job &&
EV_JOB (job_info->job)->finished) {
- GdkPixbuf *pixbuf;
-
- pixbuf = g_object_ref (EV_JOB_RENDER (job_info->job)->pixbuf);
- dispose_cache_job_info (job_info, pixbuf_cache);
- job_info->pixbuf = pixbuf;
+ copy_job_to_job_info (EV_JOB_RENDER (job_info->job), job_info, pixbuf_cache);
}
return job_info->pixbuf;
+}
+
+GList *
+ev_pixbuf_cache_get_link_mapping (EvPixbufCache *pixbuf_cache,
+ gint page)
+{
+ CacheJobInfo *job_info;
+
+ job_info = find_job_cache (pixbuf_cache, page);
+ if (job_info == NULL)
+ return NULL;
+
+ /* We don't need to wait for the idle to handle the callback */
+ if (job_info->job &&
+ EV_JOB (job_info->job)->finished) {
+ copy_job_to_job_info (EV_JOB_RENDER (job_info->job), job_info, pixbuf_cache);
+ }
+
+ return job_info->link_mapping;
}
Index: shell/ev-pixbuf-cache.h
===================================================================
RCS file: /cvs/gnome/evince/shell/ev-pixbuf-cache.h,v
retrieving revision 1.2
diff -u -p -r1.2 ev-pixbuf-cache.h
--- shell/ev-pixbuf-cache.h 23 Mar 2005 11:07:32 -0000 1.2
+++ shell/ev-pixbuf-cache.h 31 Mar 2005 07:33:36 -0000
@@ -37,14 +37,17 @@ G_BEGIN_DECLS
typedef struct _EvPixbufCache EvPixbufCache;
typedef struct _EvPixbufCacheClass EvPixbufCacheClass;
-GType ev_pixbuf_cache_get_type (void) G_GNUC_CONST;
-EvPixbufCache *ev_pixbuf_cache_new (EvDocument *document);
-void ev_pixbuf_cache_set_page_range (EvPixbufCache *pixbuf_cache,
- gint start_page,
- gint end_page,
- gfloat scale);
-GdkPixbuf *ev_pixbuf_cache_get_pixbuf (EvPixbufCache *pixbuf_cache,
- gint page);
+GType ev_pixbuf_cache_get_type (void) G_GNUC_CONST;
+EvPixbufCache *ev_pixbuf_cache_new (EvDocument *document);
+void ev_pixbuf_cache_set_page_range (EvPixbufCache *pixbuf_cache,
+ gint start_page,
+ gint end_page,
+ gfloat scale);
+GdkPixbuf *ev_pixbuf_cache_get_pixbuf (EvPixbufCache *pixbuf_cache,
+ gint page);
+GList *ev_pixbuf_cache_get_link_mapping (EvPixbufCache *pixbuf_cache,
+ gint page);
+
G_END_DECLS
Index: shell/ev-sidebar-thumbnails.c
===================================================================
RCS file: /cvs/gnome/evince/shell/ev-sidebar-thumbnails.c,v
retrieving revision 1.21
diff -u -p -r1.21 ev-sidebar-thumbnails.c
--- shell/ev-sidebar-thumbnails.c 23 Mar 2005 11:07:32 -0000 1.21
+++ shell/ev-sidebar-thumbnails.c 31 Mar 2005 07:33:36 -0000
@@ -118,7 +118,7 @@ ev_sidebar_tree_selection_changed (GtkTr
path = gtk_tree_model_get_path (GTK_TREE_MODEL (priv->list_store),
&iter);
- page = gtk_tree_path_get_indices (path)[0] + 1;
+ page = gtk_tree_path_get_indices (path)[0];
gtk_tree_path_free (path);
page_cache = ev_document_get_page_cache (priv->document);
@@ -189,7 +189,7 @@ page_changed_cb (EvPageCache *pa
GtkTreePath *path;
GtkTreeSelection *selection;
- path = gtk_tree_path_new_from_indices (page - 1, -1);
+ path = gtk_tree_path_new_from_indices (page, -1);
selection = gtk_tree_view_get_selection
(GTK_TREE_VIEW (sidebar->priv->tree_view));
@@ -247,12 +247,12 @@ ev_sidebar_thumbnails_set_document (EvSi
loading_icon = ev_document_misc_get_thumbnail_frame (width, height, NULL);
gtk_list_store_clear (priv->list_store);
- for (i = 1; i <= n_pages; i++) {
+ for (i = 0; i < n_pages; i++) {
EvJob *job;
/* FIXME: Bah. This is still -1 for some reason. Need to track it down.. */
- job = ev_job_thumbnail_new (priv->document, i - 1, THUMBNAIL_WIDTH);
- page = g_strdup_printf ("<i>%d</i>", i);
+ job = ev_job_thumbnail_new (priv->document, i, THUMBNAIL_WIDTH);
+ page = g_strdup_printf ("<i>%d</i>", i + 1); /* FIXME: replace with string. */
gtk_list_store_append (priv->list_store, &iter);
gtk_list_store_set (priv->list_store, &iter,
COLUMN_PAGE_STRING, page,
Index: shell/ev-view.c
===================================================================
RCS file: /cvs/gnome/evince/shell/ev-view.c,v
retrieving revision 1.65
diff -u -p -r1.65 ev-view.c
--- shell/ev-view.c 23 Mar 2005 11:07:32 -0000 1.65
+++ shell/ev-view.c 31 Mar 2005 07:33:37 -0000
@@ -704,14 +704,15 @@ static char *
status_message_from_link (EvLink *link)
{
EvLinkType type;
- char *msg;
+ char *msg = NULL;
int page;
type = ev_link_get_link_type (link);
switch (type) {
case EV_LINK_TYPE_TITLE:
- msg = g_strdup (ev_link_get_title (link));
+ if (ev_link_get_title (link))
+ msg = g_strdup (ev_link_get_title (link));
break;
case EV_LINK_TYPE_PAGE:
page = ev_link_get_page (link);
@@ -721,7 +722,7 @@ status_message_from_link (EvLink *link)
msg = g_strdup (ev_link_get_uri (link));
break;
default:
- msg = NULL;
+ break;
}
return msg;
@@ -799,6 +800,56 @@ ev_view_set_cursor (EvView *view, EvView
}
}
+
+static void
+find_page_at_location (EvView *view,
+ gdouble x,
+ gdouble y,
+ gint *page,
+ gint *x_offset,
+ gint *y_offset)
+{
+ GtkBorder border;
+ gint width, height;
+
+ ev_page_cache_get_size (view->page_cache,
+ view->current_page,
+ view->scale,
+ &width, &height);
+ ev_document_misc_get_page_border_size (width, height, &border);
+
+ x -= (border.left + view->spacing);
+ y -= (border.top + view->spacing);
+
+ if ((x < 0) || (y < 0) ||
+ (x >= width) || (y >= height)) {
+ *page = -1;
+ return;
+ }
+ *page = view->current_page;
+ *x_offset = (gint) x;
+ *y_offset = (gint) y;
+}
+
+static EvLink *
+get_link_at_location (EvView *view,
+ gdouble x,
+ gdouble y)
+{
+ gint page;
+ gint x_offset, y_offset;
+ GList *link_mapping;
+
+ find_page_at_location (view, x, y, &page, &x_offset, &y_offset);
+ if (page == -1)
+ return NULL;
+
+ link_mapping = ev_pixbuf_cache_get_link_mapping (view->pixbuf_cache, page);
+
+ return ev_link_mapping_find (link_mapping, x_offset /view->scale, y_offset /view->scale);
+}
+
+
static gboolean
ev_view_motion_notify_event (GtkWidget *widget,
GdkEventMotion *event)
@@ -816,13 +867,10 @@ ev_view_motion_notify_event (GtkWidget
view_rect_to_doc_rect (view, &selection, &view->selection);
gtk_widget_queue_draw (widget);
- } else if (FALSE && view->document) {
+ } else if (view->document) {
EvLink *link;
- g_mutex_lock (EV_DOC_MUTEX);
- link = ev_document_get_link (view->document, event->x, event->y);
- g_mutex_unlock (EV_DOC_MUTEX);
-
+ link = get_link_at_location (view, event->x, event->y);
if (link) {
char *msg;
@@ -830,8 +878,6 @@ ev_view_motion_notify_event (GtkWidget
ev_view_set_status (view, msg);
ev_view_set_cursor (view, EV_VIEW_CURSOR_LINK);
g_free (msg);
-
- g_object_unref (link);
} else {
ev_view_set_status (view, NULL);
if (view->cursor == EV_VIEW_CURSOR_LINK) {
@@ -856,14 +902,9 @@ ev_view_button_release_event (GtkWidget
} else if (view->document) {
EvLink *link;
- g_mutex_lock (EV_DOC_MUTEX);
- link = ev_document_get_link (view->document,
- event->x,
- event->y);
- g_mutex_unlock (EV_DOC_MUTEX);
+ link = get_link_at_location (view, event->x, event->y);
if (link) {
ev_view_go_to_link (view, link);
- g_object_unref (link);
}
}
@@ -1089,7 +1130,7 @@ ev_view_init (EvView *view)
view->spacing = 10;
view->scale = 1.0;
- view->current_page = 1;
+ view->current_page = 0;
view->pressed_button = -1;
view->cursor = EV_VIEW_CURSOR_NORMAL;
}
Index: shell/ev-window.c
===================================================================
RCS file: /cvs/gnome/evince/shell/ev-window.c,v
retrieving revision 1.83
diff -u -p -r1.83 ev-window.c
--- shell/ev-window.c 23 Mar 2005 11:07:32 -0000 1.83
+++ shell/ev-window.c 31 Mar 2005 07:33:37 -0000
@@ -202,10 +202,10 @@ update_action_sensitivity (EvWindow *ev_
page = ev_page_cache_get_current_page (ev_window->priv->page_cache);
n_pages = ev_page_cache_get_n_pages (ev_window->priv->page_cache);
- set_action_sensitive (ev_window, "GoPreviousPage", page > 1);
- set_action_sensitive (ev_window, "GoNextPage", page < n_pages);
- set_action_sensitive (ev_window, "GoFirstPage", page > 1);
- set_action_sensitive (ev_window, "GoLastPage", page < n_pages);
+ set_action_sensitive (ev_window, "GoPreviousPage", page > 0);
+ set_action_sensitive (ev_window, "GoNextPage", page < n_pages - 1);
+ set_action_sensitive (ev_window, "GoFirstPage", page > 0);
+ set_action_sensitive (ev_window, "GoLastPage", page < n_pages - 1);
} else {
set_action_sensitive (ev_window, "GoFirstPage", FALSE);
set_action_sensitive (ev_window, "GoPreviousPage", FALSE);
@@ -495,7 +495,8 @@ update_total_pages (EvWindow *ev_window)
static gboolean
document_supports_sidebar (EvDocument *document)
{
- return (EV_IS_DOCUMENT_THUMBNAILS (document) && EV_IS_DOCUMENT_LINKS (document));
+ /* FIXME: Remove the (TRUE ||) after links are fixed in poppler-glib */
+ return (EV_IS_DOCUMENT_THUMBNAILS (document) && (EV_IS_DOCUMENT_LINKS (document)));
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]