]> www.fi.muni.cz Git - evince.git/blobdiff - pdf/xpdf/pdf-document.cc
Keep offset in consideration in a few places
[evince.git] / pdf / xpdf / pdf-document.cc
index a8824e8845036310d9cf57424155ec1a96a777fe..b9180bd9988b1e712c4c79a445401f5777e33e3e 100644 (file)
@@ -26,6 +26,7 @@
 #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"
 
 #include "GlobalParams.h"
@@ -33,6 +34,7 @@
 #include "SplashBitmap.h"
 #include "PDFDoc.h"
 #include "Outline.h"
+#include "ErrorCodes.h"
 #include "UnicodeMap.h"
 #include "GlobalParams.h"
 #include "GfxState.h"
@@ -87,18 +89,21 @@ struct _PdfDocument
        Links *links;
        UnicodeMap *umap;
 
+       gchar *password;
        gboolean page_valid;
 
        PdfDocumentSearch *search;
 };
 
-static void pdf_document_document_links_iface_init      (EvDocumentLinksIface  *iface);
+static void pdf_document_document_links_iface_init      (EvDocumentLinksIface      *iface);
 static void pdf_document_document_thumbnails_iface_init (EvDocumentThumbnailsIface *iface);
 static void pdf_document_document_iface_init            (EvDocumentIface           *iface);
-static void pdf_document_ps_exporter_iface_init (EvPSExporterIface   *iface);
-static void pdf_document_find_iface_init        (EvDocumentFindIface *iface);
-static void pdf_document_search_free            (PdfDocumentSearch   *search);
-static void pdf_document_search_page_changed    (PdfDocumentSearch   *search);
+static void pdf_document_ps_exporter_iface_init         (EvPSExporterIface         *iface);
+static void pdf_document_find_iface_init                (EvDocumentFindIface       *iface);
+static void pdf_document_security_iface_init            (EvDocumentSecurityIface   *iface);
+static void pdf_document_search_free                    (PdfDocumentSearch         *search);
+static void pdf_document_search_page_changed            (PdfDocumentSearch         *search);
+
 
 G_DEFINE_TYPE_WITH_CODE (PdfDocument, pdf_document, G_TYPE_OBJECT,
                          {
@@ -112,6 +117,8 @@ G_DEFINE_TYPE_WITH_CODE (PdfDocument, pdf_document, G_TYPE_OBJECT,
                                                        pdf_document_ps_exporter_iface_init);
                                 G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_FIND,
                                                        pdf_document_find_iface_init);
+                                G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_SECURITY,
+                                                       pdf_document_security_iface_init);
                         });
 
 static void
@@ -142,6 +149,8 @@ document_validate_page (PdfDocument *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
                  */
@@ -184,18 +193,27 @@ pdf_document_load (EvDocument  *document,
        g_free (filename);
 
        // open the PDF file, assumes ownership of filename_g
-       newDoc = new PDFDoc(filename_g, 0, 0);
+       GString *password = NULL;
+       if (pdf_document->password)
+               password = new GString (pdf_document->password);
+       newDoc = new PDFDoc(filename_g, password, password);
+       if (password)
+               delete password;
 
        if (!newDoc->isOk()) {
                err = newDoc->getErrorCode();
                delete newDoc;
-
-               /* FIXME: Add a real error enum to EvDocument */
-               g_set_error (error, G_FILE_ERROR,
-                            G_FILE_ERROR_FAILED,
-                            "Failed to load document (error %d) '%s'\n",
-                            err,
-                            uri);
+               if (err == errEncrypted) {
+                       g_set_error (error, EV_DOCUMENT_ERROR,
+                                    EV_DOCUMENT_ERROR_ENCRYPTED,
+                                    "Document is encrypted.");
+               } else {
+                       g_set_error (error, G_FILE_ERROR,
+                                    G_FILE_ERROR_FAILED,
+                                    "Failed to load document (error %d) '%s'\n",
+                                    err,
+                                    uri);
+               }
 
                return FALSE;
        }
@@ -258,8 +276,6 @@ pdf_document_set_page (EvDocument  *document,
                pdf_document->page = page;
                pdf_document->page_valid = FALSE;
        }
-
-       ev_document_changed (document);
 }
 
 static int
@@ -468,8 +484,8 @@ pdf_document_search_page_changed (PdfDocumentSearch   *search)
                                          &xMin, &yMin, &xMax, &yMax)) {
                 result.page_num = pdf_document->page;
 
-                result.highlight_area.x = xMin;
-                result.highlight_area.y = yMin;
+                result.highlight_area.x = xMin + pdf_document->page_x_offset;
+                result.highlight_area.y = yMin + pdf_document->page_y_offset;
                 result.highlight_area.width = xMax - xMin;
                 result.highlight_area.height = yMax - yMin;
 
@@ -483,8 +499,8 @@ pdf_document_search_page_changed (PdfDocumentSearch   *search)
 
                         result.page_num = pdf_document->page;
 
-                        result.highlight_area.x = xMin;
-                        result.highlight_area.y = yMin;
+                        result.highlight_area.x = xMin + pdf_document->page_x_offset;
+                        result.highlight_area.y = yMin + pdf_document->page_y_offset;
                         result.highlight_area.width = xMax - xMin;
                         result.highlight_area.height = yMax - yMin;
 
@@ -660,6 +676,25 @@ pdf_document_search_free (PdfDocumentSearch   *search)
        g_free (search);
 }
 
+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_ps_export_begin (EvPSExporter *exporter, const char *filename)
 {
@@ -988,10 +1023,10 @@ pdf_document_get_text (EvDocument *document, GdkRectangle *rect)
        const char *text;
        int x1, y1, x2, y2;
 
-       x1 = rect->x;
-       y1 = rect->y;
-       x2 = x1 + rect->width;
-       y2 = y1 + rect->height;
+       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;
 
        sel_text = pdf_document->out->getText (x1, y1, x2, y2);
        text = sel_text->getCString ();
@@ -1004,8 +1039,21 @@ pdf_document_get_link (EvDocument *document, int x, int y)
 {
        PdfDocument *pdf_document = PDF_DOCUMENT (document);
        LinkAction *action;
+       double link_x, link_y;
+
+       /* Zoom */
+       link_x = x / pdf_document->scale;
+       link_y = y / pdf_document->scale;
+
+       /* Offset */
+       link_x -= pdf_document->page_x_offset;
+       link_y -= pdf_document->page_y_offset;
 
-       action = pdf_document->links->find (x, y);
+       /* Inverse y */
+       link_y = pdf_document->out->getBitmapHeight() - link_y;
+
+       action = pdf_document->links->find (link_x, link_y);
+       
        if (action) {
                return build_link_from_action (pdf_document, action, "");
        } else {
@@ -1077,6 +1125,13 @@ pdf_document_find_iface_init (EvDocumentFindIface *iface)
         iface->cancel = pdf_document_find_cancel;
 }
 
+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 void
 pdf_document_document_links_iface_init (EvDocumentLinksIface *iface)
 {
@@ -1281,5 +1336,6 @@ pdf_document_init (PdfDocument *pdf_document)
        pdf_document->scale = 1.;
 
        pdf_document->page_valid = FALSE;
+       pdf_document->password = NULL;
 }