]> www.fi.muni.cz Git - evince.git/commitdiff
Remove pixbuf backend for now
authorJonathan Blandford <jrb@redhat.com>
Thu, 31 Mar 2005 15:34:35 +0000 (15:34 +0000)
committerJonathan Blandford <jrb@src.gnome.org>
Thu, 31 Mar 2005 15:34:35 +0000 (15:34 +0000)
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.

20 files changed:
ChangeLog
Makefile.am
backend/ev-document-thumbnails.h
backend/ev-document.c
backend/ev-document.h
backend/ev-jobs.c
backend/ev-jobs.h
backend/ev-link.c
backend/ev-link.h
backend/ev-page-cache.c
configure.ac
pdf/Makefile.am
pdf/ev-poppler.cc [new file with mode: 0644]
pdf/ev-poppler.h [new file with mode: 0644]
ps/ps-document.c
shell/ev-pixbuf-cache.c
shell/ev-pixbuf-cache.h
shell/ev-sidebar-thumbnails.c
shell/ev-view.c
shell/ev-window.c

index 00b6ceb248d4825e38cf67fb4ce79ff967f2d5e8..940e8550e2e2b15c5645ad0bdc611f79fbfeda72 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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 41d8abdd64736a95e0cd29b8fdd1ff474cb2defe..155dac801e5098ca8bd471c4a77602875544d357 100644 (file)
@@ -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 76b0cc8cdea4e9c52c66edb11c9dcccdc23d5ea0..c84e4268bcdbd0abff7b9d843e476061d98168d4 100644 (file)
@@ -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 6238ac54b93d01f6e8d0b0c31adfb303f5ca3150..080af0bd7ff18855c5ba4a0df3e763ce255ce2b4 100644 (file)
 
 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;
 }
 
@@ -204,16 +179,6 @@ ev_document_get_page (EvDocument *document)
        return retval;
 }
 
-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)
@@ -224,17 +189,6 @@ ev_document_set_scale (EvDocument   *document,
        iface->set_scale (document, scale);
 }
 
-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,
@@ -269,25 +223,29 @@ ev_document_get_link (EvDocument   *document,
        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 *document)
        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 be0d1dbfedb70d2e6e912e9f674f79d5b2a51b8b..15b2cc95447e776bdee357694a251a94ab6990ae 100644 (file)
@@ -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 (EvDocument *document);
 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 355a10378e422ed8af0424db31f88979fdd25c08..8265aebd184c18839441b4bc4684695f21c8a45a 100644 (file)
@@ -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 a212349a3597ac32e6105b0785b67cab8f91e915..1b64e01da3c9d7ac8ee5618220056395ca99c7d4 100644 (file)
@@ -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         (EvDocument     *document,
                                           gint            page,
                                           double          scale,
                                           gint            width,
-                                          gint            height);
+                                          gint            height,
+                                          gboolean        include_links);
 void            ev_job_render_run         (EvJobRender    *thumbnail);
 
 /* EvJobThumbnail */
index 7e6eb52251c42dfbaaa53024210ddf29fa3e71c4..7e26a580dae9ac43d784fa1c1badfc939d4de612 100644 (file)
@@ -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, const char *uri)
                                      "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 d92d428e186223a94dbf6c319c30e3eed9f17dff..b79e2fa4686284305fb96eeaada6ad15a4578d08 100644 (file)
@@ -37,6 +37,8 @@ typedef struct _EvLinkPrivate EvLinkPrivate;
 
 #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 e2771b66c32d7b0d25d1c81d92c4d0d6eeb72be8..f16ddc553c7b89b103d8f6b123a1a9dcafeeec17 100644 (file)
@@ -48,7 +48,7 @@ G_DEFINE_TYPE (EvPageCache, ev_page_cache, G_TYPE_OBJECT)
 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 (EvPageCache *page_cache,
                                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 *page_cache,
                        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 *page_cache,
        } 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 *page_cache)
 {
        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 *page_cache)
 {
        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 d5c6624ceb387dbead89b56cd8f2e5c90058e211..0d9f5dd3b0c91db558982a1bd80c068ae002dff7 100644 (file)
@@ -32,12 +32,12 @@ AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE", [Gettext package.])
 
 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 4604706d60df2a9d04df2ba130f25fbb2abbd853..dd7ccc73c4c3538a1a9a328437e427e27c4ff414 100644 (file)
@@ -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                       \
diff --git a/pdf/ev-poppler.cc b/pdf/ev-poppler.cc
new file mode 100644 (file)
index 0000000..6a51672
--- /dev/null
@@ -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));
+}
diff --git a/pdf/ev-poppler.h b/pdf/ev-poppler.h
new file mode 100644 (file)
index 0000000..8cc65d1
--- /dev/null
@@ -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 4dd344be573d51efedec486eddc065163f27b3c8..4b2d4c43e36d23ef37e2466e49f3c8f39f028c9d 100644 (file)
@@ -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  *document,
 
        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  *document)
 
        g_return_val_if_fail (ps != NULL, -1);
 
-       return ps->current_page + 1;
+       return ps->current_page;
 }
 
 static void
@@ -1232,17 +1230,6 @@ ps_document_set_scale (EvDocument  *document,
        compute_dimensions (gs, gs->current_page);
 }
 
-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,
@@ -1338,7 +1325,6 @@ ps_document_document_iface_init (EvDocumentIface *iface)
        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 7d076dba219a7fcfabc2b6363e2daee2d282964d..7200b37c4367982cf6e3952a295cb2b55b7a5148 100644 (file)
@@ -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            (EvJob              *job,
                                                 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_cache, G_TYPE_OBJECT)
 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 *job_info,
                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 (EvPixbufCache *pixbuf_cache,
        /* 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 (EvPixbufCache *pixbuf_cache,
        }
 
        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 (EvPixbufCache *pixbuf_cache,
        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_cache,
        /* 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 (EvPixbufCache *pixbuf_cache,
 
        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 (EvPixbufCache *pixbuf_cache,
        /* 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 e49faa02e4d959e134dd4963d8e2446dfd69b07e..0bd1cbc771080bb3bb31e84bec4e588c1b7f1ed7 100644 (file)
@@ -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 c548e297fbc6b77fe9631076562830246e7d375e..7bbaa098f2b2c9a983d3be6724613d78a180f22c 100644 (file)
@@ -118,7 +118,7 @@ ev_sidebar_tree_selection_changed (GtkTreeSelection *selection,
 
        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         *page_cache,
        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 (EvSidebarThumbnails *sidebar_thumbnails,
        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 9921ed4590f8e3cc2b7426a43372a436512096d0..97e0c549618fa3d754957c318b10235b3e71590c 100644 (file)
@@ -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, EvViewCursor new_cursor)
        }
 }
 
+
+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      *widget,
                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      *widget,
                        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      *widget,
        } 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 849adaf18c8d93c6f3f6c9ff2d4f593513efd6dc..8b3044f1799924563b56ca63750fc06dfc9a1503 100644 (file)
@@ -202,10 +202,10 @@ update_action_sensitivity (EvWindow *ev_window)
                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