]> www.fi.muni.cz Git - evince.git/blobdiff - pdf/xpdf/pdf-document.cc
Fix crash when opening in new window
[evince.git] / pdf / xpdf / pdf-document.cc
index 5a7304c6162afe6d5b73fea8b138a40cb822dcc7..4e90c0910f863a466ec0658f0b007dae6f107dc5 100644 (file)
@@ -23,9 +23,9 @@
 #include "pdf-document.h"
 #include "ev-ps-exporter.h"
 #include "ev-document-find.h"
+#include "ev-document-misc.h"
 #include "gpdf-g-switch.h"
 #include "ev-document-links.h"
-#include "ev-document-misc.h"
 #include "ev-document-security.h"
 #include "ev-document-thumbnails.h"
 
@@ -90,7 +90,6 @@ struct _PdfDocument
        UnicodeMap *umap;
 
        gchar *password;
-       gboolean page_valid;
 
        PdfDocumentSearch *search;
 };
@@ -136,10 +135,10 @@ document_init_links (PdfDocument *pdf_document)
        obj.free ();
 }
 
-static gboolean
-document_validate_page (PdfDocument *pdf_document)
+static void
+document_display_page (PdfDocument *pdf_document)
 {
-       if (!pdf_document->page_valid) {
+       if (pdf_document->out != NULL) {
                pdf_document->doc->displayPage (pdf_document->out, pdf_document->page,
                                                72 * pdf_document->scale,
                                                72 * pdf_document->scale,
@@ -147,18 +146,12 @@ document_validate_page (PdfDocument *pdf_document)
 
                document_init_links (pdf_document);
 
-               pdf_document->page_valid = TRUE;
-
-               ev_document_changed (EV_DOCUMENT (pdf_document));
-
-                /* Update the search results available to the app since
-                 * we only provide full results on the current page
-                 */
-                if (pdf_document->search)
-                        pdf_document_search_page_changed (pdf_document->search);
+               /* Update the search results available to the app since
+                * we only provide full results on the current page
+                */
+               if (pdf_document->search)
+                       pdf_document_search_page_changed (pdf_document->search);
        }
-
-       return pdf_document->page_valid;
 }
 
 static gboolean
@@ -227,8 +220,6 @@ pdf_document_load (EvDocument  *document,
        if (pdf_document->out)
                pdf_document->out->startDoc(pdf_document->doc->getXRef());
 
-       pdf_document->page_valid = FALSE;
-
        g_object_notify (G_OBJECT (pdf_document), "title");
 
        return TRUE;
@@ -274,7 +265,8 @@ pdf_document_set_page (EvDocument  *document,
 
        if (page != pdf_document->page) {
                pdf_document->page = page;
-               pdf_document->page_valid = FALSE;
+               document_display_page (pdf_document);
+               ev_document_page_changed (EV_DOCUMENT (pdf_document));
        }
 }
 
@@ -319,9 +311,8 @@ pdf_document_set_target (EvDocument  *document,
                        if (pdf_document->doc)
                                pdf_document->out->startDoc(pdf_document->doc->getXRef());
 
+                       document_display_page (pdf_document);
                }
-
-               pdf_document->page_valid = FALSE;
        }
 }
 
@@ -333,7 +324,8 @@ pdf_document_set_scale (EvDocument  *document,
 
        if (pdf_document->scale != scale) {
                pdf_document->scale = scale;
-               pdf_document->page_valid = FALSE;
+               document_display_page (pdf_document);
+               ev_document_scale_changed (EV_DOCUMENT (pdf_document));
        }
 }
 
@@ -350,21 +342,26 @@ pdf_document_set_page_offset (EvDocument  *document,
 
 static void
 pdf_document_get_page_size (EvDocument   *document,
+                           int           page,
                            int          *width,
                            int          *height)
 {
        PdfDocument *pdf_document = PDF_DOCUMENT (document);
+       Page *the_page;
 
-       if (document_validate_page (pdf_document)) {
-               if (width)
-                       *width = pdf_document->out->getBitmapWidth();
-               if (height)
-                       *height = pdf_document->out->getBitmapHeight();
-       } else {
-               if (width)
-                       *width = 1;
-               if (height)
-                       *height = 1;
+       /* set some default values */
+       if (width)
+               *width = 1;
+       if (height)
+               *height = 1;
+
+       if (page == -1) 
+               page = pdf_document->page;
+
+       the_page = pdf_document->doc->getCatalog ()->getPage (page);
+       if (the_page) {
+               *width = (int) ((the_page->getWidth () * pdf_document->scale) + 0.5);
+               *height = (int) ((the_page->getHeight () * pdf_document->scale) + 0.5);
        }
 }
 
@@ -379,7 +376,7 @@ pdf_document_render (EvDocument  *document,
        GdkRectangle page;
        GdkRectangle draw;
 
-       if (!document_validate_page (pdf_document) || !pdf_document->target)
+       if (!pdf_document->target)
                return;
 
        page.x = pdf_document->page_x_offset;
@@ -399,6 +396,30 @@ pdf_document_render (EvDocument  *document,
                                           draw.width, draw.height);
 }
 
+double
+pdf_document_find_get_progress (EvDocumentFind *document_find)
+{
+       PdfDocumentSearch *search;
+       int n_pages, pages_done;
+
+       search = PDF_DOCUMENT (document_find)->search;
+
+       if (search == NULL) {
+               return 0;
+       }
+
+       n_pages = ev_document_get_n_pages (EV_DOCUMENT (document_find));
+       if (search->search_page > search->start_page) {
+               pages_done = search->search_page - search->start_page + 1;
+       } else if (search->search_page == search->start_page) {
+               pages_done = n_pages;
+       } else {
+               pages_done = n_pages - search->start_page + search->search_page;
+       }
+
+       return pages_done / (double) n_pages;
+}
+
 int
 pdf_document_find_page_has_results (EvDocumentFind *document_find,
                                    int             page)
@@ -427,15 +448,17 @@ pdf_document_find_get_result (EvDocumentFind *document_find,
                              int             n_result,
                              GdkRectangle   *rectangle)
 {
-       PdfDocumentSearch *search = PDF_DOCUMENT (document_find)->search;
+       PdfDocument *pdf_document = PDF_DOCUMENT (document_find);
+       PdfDocumentSearch *search = pdf_document->search;
        GdkRectangle r;
 
-       if (search != NULL) {
+       if (search != NULL &&
+           n_result < search->current_page_results->len) {
                r = g_array_index (search->current_page_results,
                                   GdkRectangle, n_result);
 
-               rectangle->x = r.x;
-               rectangle->y = r.y;
+               rectangle->x = r.x + pdf_document->page_x_offset;
+               rectangle->y = r.y + pdf_document->page_y_offset;
                rectangle->width = r.width;
                rectangle->height = r.height;
 
@@ -455,12 +478,6 @@ pdf_document_search_page_changed (PdfDocumentSearch   *search)
 
         current_page = pdf_document->page;
 
-        if (!pdf_document->page_valid) {
-                /* we can't do anything until displayPage() */
-                search->current_page = -1;
-                return;
-        }
-
         if (search->current_page == current_page)
                 return;
 
@@ -498,7 +515,7 @@ pdf_document_search_idle_callback (void *data)
 {
         PdfDocumentSearch *search = (PdfDocumentSearch*) data;
         PdfDocument *pdf_document = search->document;
-        int n_pages;
+        int n_pages, changed_page;
         double xMin, yMin, xMax, yMax;
 
         /* Note that PDF page count is 1 through n_pages INCLUSIVE
@@ -533,11 +550,7 @@ pdf_document_search_idle_callback (void *data)
                search->other_page_flags[search->search_page] = 0;
        }
 
-        if (search->search_page != search->start_page) {
-               ev_document_find_changed (EV_DOCUMENT_FIND (pdf_document),
-                                         search->search_page);
-               return TRUE;
-       }
+       changed_page = search->start_page;
 
         search->search_page += 1;
         if (search->search_page > n_pages) {
@@ -545,6 +558,12 @@ pdf_document_search_idle_callback (void *data)
                 search->search_page = 1;
         }
 
+        if (search->search_page != search->start_page) {
+               ev_document_find_changed (EV_DOCUMENT_FIND (pdf_document),
+                                         changed_page);
+               return TRUE;
+       }
+
 end_search:
         /* We're done. */
         search->idle = 0; /* will return FALSE to remove */
@@ -623,7 +642,7 @@ pdf_document_find_begin (EvDocumentFind   *document,
 }
 
 static void
-pdf_document_find_cancel (EvDocumentFind   *document)
+pdf_document_find_cancel (EvDocumentFind *document)
 {
         PdfDocument *pdf_document = PDF_DOCUMENT (document);
 
@@ -773,8 +792,14 @@ build_link_from_action (PdfDocument *pdf_document,
 {
        EvLink *link = NULL;
 
-       if (link_action == NULL) {
-               link = ev_link_new_title (title);
+       if (link_action->getKind () == actionGoToR) {
+               g_warning ("actionGoToR links not implemented");
+       } else if (link_action->getKind () == actionLaunch) {
+               g_warning ("actionLaunch links not implemented");
+       } else if (link_action->getKind () == actionNamed) {
+               g_warning ("actionNamed links not implemented");
+       } else if (link_action->getKind () == actionMovie) {
+               g_warning ("actionMovie links not implemented");
        } else if (link_action->getKind () == actionGoTo) {
                LinkDest *link_dest;
                LinkGoTo *link_goto;
@@ -812,8 +837,17 @@ build_link_from_action (PdfDocument *pdf_document,
                link_uri = dynamic_cast <LinkURI *> (link_action);
                link = ev_link_new_external
                        (title, link_uri->getURI()->getCString());
-       } else if (link_action->getKind () == actionNamed) {
-                       /*Skip, for now */
+       } else if (link_action->getKind () == actionUnknown) {
+               LinkUnknown *link_unknown;
+
+               link_unknown = dynamic_cast <LinkUnknown *> (link_action);
+
+               g_warning ("Unknown link type %s",
+                          link_unknown->getAction()->getCString());
+       }
+
+       if (link == NULL) {
+               link = ev_link_new_title (title);
        }
 
        return link;
@@ -998,10 +1032,10 @@ pdf_document_get_text (EvDocument *document, GdkRectangle *rect)
        const char *text;
        int x1, y1, x2, y2;
 
-       x1 = rect->x + pdf_document->page_x_offset;
-       y1 = rect->y + pdf_document->page_y_offset;
-       x2 = x1 + rect->width + pdf_document->page_x_offset;
-       y2 = y1 + rect->height + pdf_document->page_y_offset;
+       x1 = rect->x - pdf_document->page_x_offset;
+       y1 = rect->y - pdf_document->page_y_offset;
+       x2 = x1 + rect->width;
+       y2 = y1 + rect->height;
 
        sel_text = pdf_document->out->getText (x1, y1, x2, y2);
        text = sel_text->getCString ();
@@ -1104,6 +1138,7 @@ pdf_document_find_iface_init (EvDocumentFindIface *iface)
        iface->get_n_results = pdf_document_find_get_n_results;
        iface->get_result = pdf_document_find_get_result;
        iface->page_has_results = pdf_document_find_page_has_results;
+       iface->get_progress = pdf_document_find_get_progress;
         iface->cancel = pdf_document_find_cancel;
 }
 
@@ -1223,8 +1258,7 @@ pdf_document_thumbnails_get_dimensions (EvDocumentThumbnails *document_thumbnail
        Thumb *thumb = NULL;
        gdouble page_ratio;
 
-       /* getPage seems to want page + 1 for some reason; */
-       the_page = pdf_document->doc->getCatalog ()->getPage (page + 1);
+       the_page = pdf_document->doc->getCatalog ()->getPage (page);
        the_page->getThumb (&the_thumb);
 
        if (!(the_thumb.isNull () || the_thumb.isNone())) {
@@ -1317,7 +1351,6 @@ pdf_document_init (PdfDocument *pdf_document)
        pdf_document->page_y_offset = 0;
        pdf_document->scale = 1.;
 
-       pdf_document->page_valid = FALSE;
        pdf_document->password = NULL;
 }