]> www.fi.muni.cz Git - evince.git/blobdiff - pdf/xpdf/pdf-document.cc
add prototype.
[evince.git] / pdf / xpdf / pdf-document.cc
index 8558c822f1faa6a9dee786c955cf746bd8876f7f..fa7c7fcfa4dd380718e47aa77e0b6b04d56283f3 100644 (file)
@@ -1,3 +1,4 @@
+/* -*- 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.
  *
 /* pdfdocument.h: Implementation of EvDocument for PDF
  * Copyright (C) 2004, Red Hat, Inc.
  *
@@ -40,12 +41,15 @@ struct _PdfDocument
        GObject parent_instance;
 
        int page;
        GObject parent_instance;
 
        int page;
-       GdkRectangle page_rect;
+       int page_x_offset;
+       int page_y_offset;
+       double scale;
        GdkDrawable *target;
 
        GDKSplashOutputDev *out;
        PDFDoc *doc;
        GdkDrawable *target;
 
        GDKSplashOutputDev *out;
        PDFDoc *doc;
-       
+
+       gboolean page_valid;
 };
 
 static void pdf_document_document_iface_init (EvDocumentIface *iface);
 };
 
 static void pdf_document_document_iface_init (EvDocumentIface *iface);
@@ -54,6 +58,18 @@ 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,
                                                  pdf_document_document_iface_init) });
 
+static gboolean
+document_validate_page (PdfDocument *pdf_document)
+{
+       if (!pdf_document->page_valid) {
+               pdf_document->doc->displayPage (pdf_document->out, pdf_document->page,
+                                               72 * pdf_document->scale,
+                                               72 * pdf_document->scale,
+                                               0, gTrue, gTrue);
+               
+               pdf_document->page_valid = TRUE;
+       }
+}
 
 static gboolean
 pdf_document_load (EvDocument  *document,
 
 static gboolean
 pdf_document_load (EvDocument  *document,
@@ -68,7 +84,7 @@ pdf_document_load (EvDocument  *document,
        
        if (!globalParams) {
                globalParams = new GlobalParams("/etc/xpdfrc");
        
        if (!globalParams) {
                globalParams = new GlobalParams("/etc/xpdfrc");
-               globalParams->setupBaseFonts(NULL);
+               globalParams->setupBaseFontsFc(NULL);
        }
 
        filename = g_filename_from_uri (uri, NULL, error);
        }
 
        filename = g_filename_from_uri (uri, NULL, error);
@@ -99,10 +115,12 @@ pdf_document_load (EvDocument  *document,
                delete pdf_document->doc;
        pdf_document->doc = newDoc;
 
                delete pdf_document->doc;
        pdf_document->doc = newDoc;
 
-       if (pdf_document->out) {
+       pdf_document->page = 1;
+
+       if (pdf_document->out)
                pdf_document->out->startDoc(pdf_document->doc->getXRef());
                pdf_document->out->startDoc(pdf_document->doc->getXRef());
-               pdf_document->doc->displayPage (pdf_document->out, 1, 72, 72, 0, gTrue, gTrue);
-       }
+
+       pdf_document->page_valid = FALSE;
        
        return TRUE;
 }
        
        return TRUE;
 }
@@ -124,7 +142,21 @@ pdf_document_set_page (EvDocument  *document,
 {
        PdfDocument *pdf_document = PDF_DOCUMENT (document);
 
 {
        PdfDocument *pdf_document = PDF_DOCUMENT (document);
 
-       pdf_document->page = page;
+       page = CLAMP (page, 1, ev_document_get_n_pages (document));
+
+       if (page != pdf_document->page) {
+               pdf_document->page = page;
+               pdf_document->page_valid = FALSE;
+       }
+
+}
+
+static int
+pdf_document_get_page (EvDocument  *document)
+{
+       PdfDocument *pdf_document = PDF_DOCUMENT (document);
+
+       return pdf_document->page;
 }
 
 static void
 }
 
 static void
@@ -148,34 +180,65 @@ pdf_document_set_target (EvDocument  *document,
                if (pdf_document->target)
                        g_object_ref (pdf_document->target);
 
                if (pdf_document->target)
                        g_object_ref (pdf_document->target);
 
-               if (pdf_document->out)
+               if (pdf_document->out) {
                        delete pdf_document->out;
                        delete pdf_document->out;
+                       pdf_document->out = NULL;
+               }
 
                if (pdf_document->target) {
                        pdf_document->out = new GDKSplashOutputDev (gdk_drawable_get_screen (pdf_document->target),
                                                         redraw_callback, (void*) document);
 
 
                if (pdf_document->target) {
                        pdf_document->out = new GDKSplashOutputDev (gdk_drawable_get_screen (pdf_document->target),
                                                         redraw_callback, (void*) document);
 
-                       if (pdf_document->doc) {
+                       if (pdf_document->doc)
                                pdf_document->out->startDoc(pdf_document->doc->getXRef());
                                pdf_document->out->startDoc(pdf_document->doc->getXRef());
-                               pdf_document->doc->displayPage (pdf_document->out, 1, 72, 72, 0, gTrue, gTrue);
-                       }
+
                }
                }
+
+               pdf_document->page_valid = FALSE;
        }
 }
 
 static void
        }
 }
 
 static void
-pdf_document_set_page_rect (EvDocument  *document,
-                           int          x,
-                           int          y,
-                           int          width,
-                           int          height)
+pdf_document_set_scale (EvDocument  *document,
+                       double       scale)
 {
        PdfDocument *pdf_document = PDF_DOCUMENT (document);
        
 {
        PdfDocument *pdf_document = PDF_DOCUMENT (document);
        
-       pdf_document->page_rect.x = x;
-       pdf_document->page_rect.y = y;
-       pdf_document->page_rect.width = width;
-       pdf_document->page_rect.height = height;
+       if (pdf_document->scale != scale) {
+               pdf_document->scale = scale;
+               pdf_document->page_valid = FALSE;
+       }
+}
+
+static void
+pdf_document_set_page_offset (EvDocument  *document,
+                             int          x,
+                             int          y)
+{
+       PdfDocument *pdf_document = PDF_DOCUMENT (document);
+       
+       pdf_document->page_x_offset = x;
+       pdf_document->page_y_offset = y;
+}
+
+static void
+pdf_document_get_page_size (EvDocument   *document,
+                           int          *width,
+                           int          *height)
+{
+       PdfDocument *pdf_document = PDF_DOCUMENT (document);
+
+       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;
+       }
 }
 
 static void
 }
 
 static void
@@ -189,11 +252,11 @@ pdf_document_render (EvDocument  *document,
        GdkRectangle page;
        GdkRectangle draw;
 
        GdkRectangle page;
        GdkRectangle draw;
 
-       if (!pdf_document->target)
+       if (!document_validate_page (pdf_document) || !pdf_document->target)
                return;
        
                return;
        
-       page.x = 0;
-       page.y = 0;
+       page.x = pdf_document->page_x_offset;
+       page.y = pdf_document->page_y_offset;
        page.width = pdf_document->out->getBitmapWidth();
        page.height = pdf_document->out->getBitmapHeight();
 
        page.width = pdf_document->out->getBitmapWidth();
        page.height = pdf_document->out->getBitmapHeight();
 
@@ -203,12 +266,94 @@ pdf_document_render (EvDocument  *document,
        draw.height = clip_height;
        
        if (gdk_rectangle_intersect (&page, &draw, &draw))
        draw.height = clip_height;
        
        if (gdk_rectangle_intersect (&page, &draw, &draw))
-               pdf_document->out->redraw (draw.x, draw.y,
+               pdf_document->out->redraw (draw.x - page.x, draw.y - page.y,
                                           pdf_document->target,
                                           draw.x, draw.y,
                                           draw.width, draw.height);
 }
 
                                           pdf_document->target,
                                           draw.x, draw.y,
                                           draw.width, draw.height);
 }
 
+void
+pdf_document_begin_find (EvDocument   *document,
+                         const char   *search_string,
+                         gboolean      case_sensitive)
+{
+        /* FIXME make this incremental (idle handler) and multi-page */
+        /* Right now it's fully synchronous plus only does the current page */
+        
+        PdfDocument *pdf_document = PDF_DOCUMENT (document);
+        gunichar *ucs4;
+        glong ucs4_len;
+        int xMin, yMin, xMax, yMax;
+        GArray *results;
+        EvFindResult result;
+
+        /* FIXME case_sensitive (right now XPDF
+         * code is always case insensitive for ASCII
+         * and case sensitive for all other languaages)
+         */
+        
+        g_assert (sizeof (gunichar) == sizeof (Unicode));
+        ucs4 = g_utf8_to_ucs4_fast (search_string, -1,
+                                    &ucs4_len);
+
+        results = g_array_new (FALSE,
+                               FALSE,
+                               sizeof (EvFindResult));
+
+        if (pdf_document->out->findText (ucs4, ucs4_len,
+                                         gTrue, gTrue, // startAtTop, stopAtBottom
+                                         gFalse, gFalse, // startAtLast, stopAtLast
+                                         &xMin, &yMin, &xMax, &yMax)) {
+
+                result.page_num = pdf_document->page;
+
+                result.highlight_area.x = xMin;
+                result.highlight_area.y = yMin;
+                result.highlight_area.width = xMax - xMin;
+                result.highlight_area.height = yMax - yMin;
+
+                g_array_append_val (results, result);
+        
+                /* Now find further results */
+
+                while (pdf_document->out->findText (ucs4, ucs4_len,
+                                                    gFalse, gTrue,
+                                                    gTrue, gFalse,
+                                                    &xMin, &yMin, &xMax, &yMax)) {
+                        
+                        result.page_num = pdf_document->page;
+                        
+                        result.highlight_area.x = xMin;
+                        result.highlight_area.y = yMin;
+                        result.highlight_area.width = xMax - xMin;
+                        result.highlight_area.height = yMax - yMin;
+                        
+                        g_array_append_val (results, result);
+                }
+        }
+
+        ev_document_found (document,
+                           (EvFindResult*) results->data,
+                           results->len,
+                           1.0);
+
+        g_array_free (results, TRUE);
+}
+
+void
+pdf_document_end_find (EvDocument   *document)
+{
+        PdfDocument *pdf_document = PDF_DOCUMENT (document);
+
+        /* FIXME this will do something once begin_find queues
+         * an incremental find
+         */
+
+        // this should probably be shared among EvDocument
+        // implementations somehow?
+        ev_document_found (document, NULL, 0, 1.0);
+}
+
 static void
 pdf_document_finalize (GObject *object)
 {
 static void
 pdf_document_finalize (GObject *object)
 {
@@ -238,13 +383,24 @@ pdf_document_document_iface_init (EvDocumentIface *iface)
        iface->load = pdf_document_load;
        iface->get_n_pages = pdf_document_get_n_pages;
        iface->set_page = pdf_document_set_page;
        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->set_target = pdf_document_set_target;
        iface->set_target = pdf_document_set_target;
-       iface->set_page_rect = pdf_document_set_page_rect;
+       iface->set_page_offset = pdf_document_set_page_offset;
+       iface->get_page_size = pdf_document_get_page_size;
        iface->render = pdf_document_render;
        iface->render = pdf_document_render;
+        iface->begin_find = pdf_document_begin_find;
+        iface->end_find = pdf_document_end_find;
 }
 
 static void
 }
 
 static void
-pdf_document_init (PdfDocument *document)
+pdf_document_init (PdfDocument *pdf_document)
 {
 {
+       pdf_document->page = 1;
+       pdf_document->page_x_offset = 0;
+       pdf_document->page_y_offset = 0;
+       pdf_document->scale = 1.;
+       
+       pdf_document->page_valid = FALSE;
 }
 
 }