[poppler] [PATCH] [C++ frontend] - show page numbers with Table of Contents items (v2)
Martin Pelikan
martin.pelikan at gmail.com
Thu Oct 16 09:11:45 PDT 2014
Hi,
version 2 of my previous patch (that didn't make it to the list
apparently) is tested on multiple different documents (mostly hw/sw
manuals and documentation, some books or theses).
The problem it solves is simple -- the current C++ frontend does have a
TOC, but it only contains titles and not pages where the TOC entries
point to. This patch (inspired by glib frontend) adds an API to get
a page number passable to poppler::document::create_page.
ok?
--
Martin Pelikan
diff --git a/cpp/poppler-document.cpp b/cpp/poppler-document.cpp
index 1c24b47..ad20c90 100644
--- a/cpp/poppler-document.cpp
+++ b/cpp/poppler-document.cpp
@@ -554,7 +554,7 @@ font_iterator* document::create_font_iterator(int start_page) const
*/
toc* document::create_toc() const
{
- return toc_private::load_from_outline(d->doc->getOutline());
+ return toc_private::load_from_pdfdoc(d->doc);
}
/**
diff --git a/cpp/poppler-toc-private.h b/cpp/poppler-toc-private.h
index e8841ff..b626fae 100644
--- a/cpp/poppler-toc-private.h
+++ b/cpp/poppler-toc-private.h
@@ -25,6 +25,7 @@
#include <vector>
class GooList;
+class PDFDoc;
class Outline;
class OutlineItem;
@@ -37,7 +38,7 @@ public:
toc_private();
~toc_private();
- static toc* load_from_outline(Outline *outline);
+ static toc* load_from_pdfdoc(PDFDoc *);
toc_item root;
};
@@ -49,12 +50,13 @@ public:
toc_item_private();
~toc_item_private();
- void load(OutlineItem *item);
- void load_children(GooList *items);
+ void load(PDFDoc *, OutlineItem *item);
+ void load_children(PDFDoc *, GooList *items);
std::vector<toc_item*> children;
ustring title;
bool is_open;
+ int page_number;
};
}
diff --git a/cpp/poppler-toc.cpp b/cpp/poppler-toc.cpp
index a3149c6..504e696 100644
--- a/cpp/poppler-toc.cpp
+++ b/cpp/poppler-toc.cpp
@@ -23,6 +23,8 @@
#include "GooList.h"
#include "Outline.h"
+#include "PDFDoc.h"
+#include "Link.h"
using namespace poppler;
@@ -34,8 +36,9 @@ toc_private::~toc_private()
{
}
-toc* toc_private::load_from_outline(Outline *outline)
+toc* toc_private::load_from_pdfdoc(PDFDoc *doc)
{
+ Outline *outline = doc->getOutline();
if (!outline) {
return 0;
}
@@ -47,13 +50,13 @@ toc* toc_private::load_from_outline(Outline *outline)
toc *newtoc = new toc();
newtoc->d->root.d->is_open = true;
- newtoc->d->root.d->load_children(items);
+ newtoc->d->root.d->load_children(doc, items);
return newtoc;
}
toc_item_private::toc_item_private()
- : is_open(false)
+ : is_open(false), page_number(0)
{
}
@@ -62,15 +65,41 @@ toc_item_private::~toc_item_private()
delete_all(children);
}
-void toc_item_private::load(OutlineItem *item)
+void toc_item_private::load(PDFDoc *doc, OutlineItem *item)
{
const Unicode *title_unicode = item->getTitle();
const int title_length = item->getTitleLength();
title = detail::unicode_to_ustring(title_unicode, title_length);
is_open = item->isOpen();
+
+ LinkAction *link_action = item->getAction();
+ if (link_action == NULL)
+ return;
+
+ switch (link_action->getKind()) {
+ case actionGoTo:
+ if (LinkGoTo *l = dynamic_cast<LinkGoTo *>(link_action)) {
+ LinkDest *ld = l->getDest();
+
+ if (ld == NULL)
+ ld = doc->findDest(l->getNamedDest());
+
+ if (ld != NULL) {
+ if (ld->isPageRef()) {
+ Ref pr = ld->getPageRef();
+ page_number = doc->findPage(pr.num, pr.gen);
+ }
+ else
+ page_number = ld->getPageNum();
+ }
+ }
+ break;
+ default:
+ break;
+ }
}
-void toc_item_private::load_children(GooList *items)
+void toc_item_private::load_children(PDFDoc *doc, GooList *items)
{
const int num_items = items->getLength();
children.resize(num_items);
@@ -78,13 +107,13 @@ void toc_item_private::load_children(GooList *items)
OutlineItem *item = (OutlineItem *)items->get(i);
toc_item *new_item = new toc_item();
- new_item->d->load(item);
+ new_item->d->load(doc, item);
children[i] = new_item;
item->open();
GooList *item_children = item->getKids();
if (item_children) {
- new_item->d->load_children(item_children);
+ new_item->d->load_children(doc, item_children);
}
}
}
@@ -175,6 +204,14 @@ bool toc_item::is_open() const
}
/**
+ Returns the page number this TOC item points to, to be used in create_page.
+ */
+int toc_item::page_number() const
+{
+ return d->page_number - 1;
+}
+
+/**
\returns the children of the TOC item
*/
std::vector<toc_item *> toc_item::children() const
diff --git a/cpp/poppler-toc.h b/cpp/poppler-toc.h
index 8b09736..9d9618d 100644
--- a/cpp/poppler-toc.h
+++ b/cpp/poppler-toc.h
@@ -55,6 +55,7 @@ public:
ustring title() const;
bool is_open() const;
+ int page_number() const;
std::vector<toc_item *> children() const;
iterator children_begin() const;
More information about the poppler
mailing list