]> www.fi.muni.cz Git - evince.git/blobdiff - pdf/ev-poppler.cc
Enable print to a PDF. Fixes bug #332121.
[evince.git] / pdf / ev-poppler.cc
index efdd15f28aef4cb6762f429bfb2bd20b312304fc..dc5510e619841b08a1a10250db7577bb52147113 100644 (file)
@@ -80,9 +80,11 @@ static void pdf_document_thumbnails_get_dimensions      (EvDocumentThumbnails
                                                         gint                      *height);
 static int  pdf_document_get_n_pages                   (EvDocument                *document);
 
                                                         gint                      *height);
 static int  pdf_document_get_n_pages                   (EvDocument                *document);
 
-static EvLinkDest *ev_link_dest_from_dest (PopplerDest *dest);
-static EvLink *ev_link_from_action (PopplerAction *action);
-static void pdf_document_search_free (PdfDocumentSearch   *search);
+static EvLinkDest *ev_link_dest_from_dest   (PdfDocument       *pdf_document,
+                                            PopplerDest       *dest);
+static EvLink     *ev_link_from_action      (PdfDocument       *pdf_document,
+                                            PopplerAction     *action);
+static void        pdf_document_search_free (PdfDocumentSearch *search);
 
 
 G_DEFINE_TYPE_WITH_CODE (PdfDocument, pdf_document, G_TYPE_OBJECT,
 
 
 G_DEFINE_TYPE_WITH_CODE (PdfDocument, pdf_document, G_TYPE_OBJECT,
@@ -134,8 +136,10 @@ pdf_document_search_free (PdfDocumentSearch   *search)
                g_list_foreach (search->pages[i], (GFunc) g_free, NULL);
                g_list_free (search->pages[i]);
        }
                g_list_foreach (search->pages[i], (GFunc) g_free, NULL);
                g_list_free (search->pages[i]);
        }
+       g_free (search->pages);
        
        
-        g_free (search->text);
+       g_free (search->text);
+       g_free (search);
 }
 
 static void
 }
 
 static void
@@ -781,37 +785,62 @@ pdf_document_links_has_document_links (EvDocumentLinks *document_links)
 }
 
 static EvLinkDest *
 }
 
 static EvLinkDest *
-ev_link_dest_from_dest (PopplerDest *dest)
+ev_link_dest_from_dest (PdfDocument *pdf_document,
+                       PopplerDest *dest)
 {
        EvLinkDest *ev_dest = NULL;
        const char *unimplemented_dest = NULL;
 
        g_assert (dest != NULL);
 {
        EvLinkDest *ev_dest = NULL;
        const char *unimplemented_dest = NULL;
 
        g_assert (dest != NULL);
-       
+
        switch (dest->type) {
        switch (dest->type) {
-               case POPPLER_DEST_XYZ:
+               case POPPLER_DEST_XYZ: {
+                       PopplerPage *poppler_page;
+                       double height;
+
+                       poppler_page = poppler_document_get_page (pdf_document->document,
+                                                                 MAX (0, dest->page_num - 1));
+                       poppler_page_get_size (poppler_page, NULL, &height);
                        ev_dest = ev_link_dest_new_xyz (dest->page_num - 1,
                                                        dest->left,
                        ev_dest = ev_link_dest_new_xyz (dest->page_num - 1,
                                                        dest->left,
-                                                       dest->top,
+                                                       height - dest->top,
                                                        dest->zoom);
                                                        dest->zoom);
+                       g_object_unref (poppler_page);
+               }
                        break;
                case POPPLER_DEST_FIT:
                        ev_dest = ev_link_dest_new_fit (dest->page_num - 1);
                        break;
                        break;
                case POPPLER_DEST_FIT:
                        ev_dest = ev_link_dest_new_fit (dest->page_num - 1);
                        break;
-               case POPPLER_DEST_FITH:
+               case POPPLER_DEST_FITH: {
+                       PopplerPage *poppler_page;
+                       double height;
+
+                       poppler_page = poppler_document_get_page (pdf_document->document,
+                                                                 MAX (0, dest->page_num - 1));
+                       poppler_page_get_size (poppler_page, NULL, &height);
                        ev_dest = ev_link_dest_new_fith (dest->page_num - 1,
                        ev_dest = ev_link_dest_new_fith (dest->page_num - 1,
-                                                        dest->top);
+                                                        height - dest->top);
+                       g_object_unref (poppler_page);
+               }
                        break;
                case POPPLER_DEST_FITV:
                        ev_dest = ev_link_dest_new_fitv (dest->page_num - 1,
                                                         dest->left);
                        break;
                        break;
                case POPPLER_DEST_FITV:
                        ev_dest = ev_link_dest_new_fitv (dest->page_num - 1,
                                                         dest->left);
                        break;
-               case POPPLER_DEST_FITR:
+               case POPPLER_DEST_FITR: {
+                       PopplerPage *poppler_page;
+                       double height;
+
+                       poppler_page = poppler_document_get_page (pdf_document->document,
+                                                                 MAX (0, dest->page_num - 1));
+                       poppler_page_get_size (poppler_page, NULL, &height);
                        ev_dest = ev_link_dest_new_fitr (dest->page_num - 1,
                                                         dest->left,
                        ev_dest = ev_link_dest_new_fitr (dest->page_num - 1,
                                                         dest->left,
-                                                        dest->bottom,
+                                                        height - dest->bottom,
                                                         dest->right,
                                                         dest->right,
-                                                        dest->top);
+                                                        height - dest->top);
+                       g_object_unref (poppler_page);
+               }
                        break;
                case POPPLER_DEST_FITB:
                        unimplemented_dest = "POPPLER_DEST_FITB";
                        break;
                case POPPLER_DEST_FITB:
                        unimplemented_dest = "POPPLER_DEST_FITB";
@@ -829,9 +858,11 @@ ev_link_dest_from_dest (PopplerDest *dest)
                        unimplemented_dest = "POPPLER_DEST_UNKNOWN";
                        break;
        }
                        unimplemented_dest = "POPPLER_DEST_UNKNOWN";
                        break;
        }
-       
+
        if (unimplemented_dest) {
        if (unimplemented_dest) {
-               g_warning ("Unimplemented destination: %s, please post a bug report with a testcase.",
+               g_warning ("Unimplemented named action: %s, please post a "
+                          "bug report in Evince bugzilla "
+                          "(http://bugzilla.gnome.org) with a testcase.",
                           unimplemented_dest);
        }
 
                           unimplemented_dest);
        }
 
@@ -842,7 +873,8 @@ ev_link_dest_from_dest (PopplerDest *dest)
 }
 
 static EvLink *
 }
 
 static EvLink *
-ev_link_from_action (PopplerAction *action)
+ev_link_from_action (PdfDocument   *pdf_document,
+                    PopplerAction *action)
 {
        EvLink       *link = NULL;
        EvLinkAction *ev_action = NULL;
 {
        EvLink       *link = NULL;
        EvLinkAction *ev_action = NULL;
@@ -852,14 +884,14 @@ ev_link_from_action (PopplerAction *action)
                case POPPLER_ACTION_GOTO_DEST: {
                        EvLinkDest *dest;
                        
                case POPPLER_ACTION_GOTO_DEST: {
                        EvLinkDest *dest;
                        
-                       dest = ev_link_dest_from_dest (action->goto_dest.dest);
+                       dest = ev_link_dest_from_dest (pdf_document, action->goto_dest.dest);
                        ev_action = ev_link_action_new_dest (dest);
                }
                        break;
                case POPPLER_ACTION_GOTO_REMOTE: {
                        EvLinkDest *dest;
                        
                        ev_action = ev_link_action_new_dest (dest);
                }
                        break;
                case POPPLER_ACTION_GOTO_REMOTE: {
                        EvLinkDest *dest;
                        
-                       dest = ev_link_dest_from_dest (action->goto_remote.dest);
+                       dest = ev_link_dest_from_dest (pdf_document, action->goto_remote.dest);
                        ev_action = ev_link_action_new_remote (dest, 
                                                               action->goto_remote.file_name);
                        
                        ev_action = ev_link_action_new_remote (dest, 
                                                               action->goto_remote.file_name);
                        
@@ -873,7 +905,7 @@ ev_link_from_action (PopplerAction *action)
                        ev_action = ev_link_action_new_external_uri (action->uri.uri);
                        break;
                case POPPLER_ACTION_NAMED:
                        ev_action = ev_link_action_new_external_uri (action->uri.uri);
                        break;
                case POPPLER_ACTION_NAMED:
-                       unimplemented_action = "POPPLER_ACTION_NAMED";
+                       ev_action = ev_link_action_new_named (action->named.named_dest);
                        break;
                case POPPLER_ACTION_MOVIE:
                        unimplemented_action = "POPPLER_ACTION_MOVIE";
                        break;
                case POPPLER_ACTION_MOVIE:
                        unimplemented_action = "POPPLER_ACTION_MOVIE";
@@ -924,22 +956,22 @@ build_tree (PdfDocument      *pdf_document,
                                        dest = poppler_document_find_dest (pdf_document->document,
                                                                           action->goto_dest.dest->named_dest);
                                        if (!dest) {
                                        dest = poppler_document_find_dest (pdf_document->document,
                                                                           action->goto_dest.dest->named_dest);
                                        if (!dest) {
-                                               link = ev_link_from_action (action);
+                                               link = ev_link_from_action (pdf_document, action);
                                                break;
                                        }
                                        
                                                break;
                                        }
                                        
-                                       ev_dest = ev_link_dest_from_dest (dest);
+                                       ev_dest = ev_link_dest_from_dest (pdf_document, dest);
                                        poppler_dest_free (dest);
                                        
                                        ev_action = ev_link_action_new_dest (ev_dest);
                                        link = ev_link_new (action->any.title, ev_action);
                                } else {
                                        poppler_dest_free (dest);
                                        
                                        ev_action = ev_link_action_new_dest (ev_dest);
                                        link = ev_link_new (action->any.title, ev_action);
                                } else {
-                                       link = ev_link_from_action (action);
+                                       link = ev_link_from_action (pdf_document, action);
                                }
                        }
                                break;
                        default:
                                }
                        }
                                break;
                        default:
-                               link = ev_link_from_action (action);
+                               link = ev_link_from_action (pdf_document, action);
                                break;
                }
                
                                break;
                }
                
@@ -964,6 +996,7 @@ build_tree (PdfDocument      *pdf_document,
                if (child)
                        build_tree (pdf_document, model, &tree_iter, child);
                poppler_index_iter_free (child);
                if (child)
                        build_tree (pdf_document, model, &tree_iter, child);
                poppler_index_iter_free (child);
+               poppler_action_free (action);
                
        } while (poppler_index_iter_next (iter));
 }
                
        } while (poppler_index_iter_next (iter));
 }
@@ -1014,7 +1047,8 @@ pdf_document_links_get_links (EvDocumentLinks *document_links,
 
                link_mapping = (PopplerLinkMapping *)list->data;
                ev_link_mapping = g_new (EvLinkMapping, 1);
 
                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->link = ev_link_from_action (pdf_document,
+                                                            link_mapping->action);
                ev_link_mapping->x1 = link_mapping->area.x1;
                ev_link_mapping->x2 = link_mapping->area.x2;
                /* Invert this for X-style coordinates */
                ev_link_mapping->x1 = link_mapping->area.x1;
                ev_link_mapping->x2 = link_mapping->area.x2;
                /* Invert this for X-style coordinates */
@@ -1042,7 +1076,7 @@ pdf_document_links_find_link_dest (EvDocumentLinks  *document_links,
        dest = poppler_document_find_dest (pdf_document->document,
                                           link_name);
        if (dest) {
        dest = poppler_document_find_dest (pdf_document->document,
                                           link_name);
        if (dest) {
-               ev_dest = ev_link_dest_from_dest (dest);
+               ev_dest = ev_link_dest_from_dest (pdf_document, dest);
                poppler_dest_free (dest);
        }
 
                poppler_dest_free (dest);
        }
 
@@ -1227,10 +1261,6 @@ pdf_document_search_new (PdfDocument *pdf_document,
 
        search->text = g_strdup (text);
         search->pages = g_new0 (GList *, n_pages);
 
        search->text = g_strdup (text);
         search->pages = g_new0 (GList *, n_pages);
-       for (i = 0; i < n_pages; i++) {
-               search->pages[i] = NULL;
-       }
-
         search->document = pdf_document;
 
         /* We add at low priority so the progress bar repaints */
         search->document = pdf_document;
 
         /* We add at low priority so the progress bar repaints */