aboutsummaryrefslogtreecommitdiffstats
path: root/libqpdf/QPDFOutlineDocumentHelper.cc
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2018-12-19 03:08:53 +0100
committerJay Berkenbilt <ejb@ql.org>2018-12-22 01:11:57 +0100
commitd5d179f4419dfbbbc3598b91071f6ca7cc44357c (patch)
treec2824094f0ac9aed1788014b6a2031e803a8a3bd /libqpdf/QPDFOutlineDocumentHelper.cc
parent30a0c070e41212172f5516936594ec0f6e72ac70 (diff)
downloadqpdf-d5d179f4419dfbbbc3598b91071f6ca7cc44357c.tar.zst
Add document and object helpers for outlines (bookmarks)
Diffstat (limited to 'libqpdf/QPDFOutlineDocumentHelper.cc')
-rw-r--r--libqpdf/QPDFOutlineDocumentHelper.cc137
1 files changed, 137 insertions, 0 deletions
diff --git a/libqpdf/QPDFOutlineDocumentHelper.cc b/libqpdf/QPDFOutlineDocumentHelper.cc
new file mode 100644
index 00000000..411ccf34
--- /dev/null
+++ b/libqpdf/QPDFOutlineDocumentHelper.cc
@@ -0,0 +1,137 @@
+#include <qpdf/QPDFOutlineDocumentHelper.hh>
+#include <qpdf/QTC.hh>
+
+QPDFOutlineDocumentHelper::Members::~Members()
+{
+}
+
+QPDFOutlineDocumentHelper::Members::Members()
+{
+}
+
+QPDFOutlineDocumentHelper::QPDFOutlineDocumentHelper(QPDF& qpdf) :
+ QPDFDocumentHelper(qpdf),
+ m(new Members())
+{
+ QPDFObjectHandle root = qpdf.getRoot();
+ if (! root.hasKey("/Outlines"))
+ {
+ return;
+ }
+ QPDFObjectHandle outlines = root.getKey("/Outlines");
+ if (! (outlines.isDictionary() && outlines.hasKey("/First")))
+ {
+ return;
+ }
+ QPDFObjectHandle cur = outlines.getKey("/First");
+ while (! cur.isNull())
+ {
+ this->m->outlines.push_back(
+ QPDFOutlineObjectHelper::Accessor::create(cur, *this, 1));
+ cur = cur.getKey("/Next");
+ }
+}
+
+QPDFOutlineDocumentHelper::~QPDFOutlineDocumentHelper()
+{
+}
+
+bool
+QPDFOutlineDocumentHelper::hasOutlines()
+{
+ return ! this->m->outlines.empty();
+}
+
+std::list<QPDFOutlineObjectHelper>
+QPDFOutlineDocumentHelper::getTopLevelOutlines()
+{
+ return this->m->outlines;
+}
+
+void
+QPDFOutlineDocumentHelper::initializeByPage()
+{
+ std::list<QPDFOutlineObjectHelper> queue;
+ queue.insert(queue.end(), this->m->outlines.begin(), this->m->outlines.end());
+
+ while (! queue.empty())
+ {
+ QPDFOutlineObjectHelper oh = queue.front();
+ queue.pop_front();
+ this->m->by_page[oh.getDestPage().getObjGen()].push_back(oh);
+ std::list<QPDFOutlineObjectHelper> kids = oh.getKids();
+ queue.insert(queue.end(), kids.begin(), kids.end());
+ }
+}
+
+std::list<QPDFOutlineObjectHelper>
+QPDFOutlineDocumentHelper::getOutlinesForPage(QPDFObjGen const& og)
+{
+ if (this->m->by_page.empty())
+ {
+ initializeByPage();
+ }
+ std::list<QPDFOutlineObjectHelper> result;
+ if (this->m->by_page.count(og))
+ {
+ result = this->m->by_page[og];
+ }
+ return result;
+}
+
+QPDFObjectHandle
+QPDFOutlineDocumentHelper::resolveNamedDest(QPDFObjectHandle name)
+{
+ QPDFObjectHandle result;
+ if (name.isName())
+ {
+ if (! this->m->dest_dict.isInitialized())
+ {
+ this->m->dest_dict = this->qpdf.getRoot().getKey("/Dests");
+ }
+ if (this->m->dest_dict.isDictionary())
+ {
+ QTC::TC("qpdf", "QPDFOutlineDocumentHelper name named dest");
+ result = this->m->dest_dict.getKey(name.getName());
+ }
+ }
+ else if (name.isString())
+ {
+ if (0 == this->m->names_dest.getPointer())
+ {
+ QPDFObjectHandle names = this->qpdf.getRoot().getKey("/Names");
+ if (names.isDictionary())
+ {
+ QPDFObjectHandle dests = names.getKey("/Dests");
+ if (dests.isDictionary())
+ {
+ this->m->names_dest =
+ new QPDFNameTreeObjectHelper(dests);
+ }
+ }
+ }
+ if (this->m->names_dest.getPointer())
+ {
+ if (this->m->names_dest->findObject(name.getUTF8Value(), result))
+ {
+ QTC::TC("qpdf", "QPDFOutlineDocumentHelper string named dest");
+ }
+ }
+ }
+ if (! result.isInitialized())
+ {
+ result = QPDFObjectHandle::newNull();
+ }
+ return result;
+}
+
+bool
+QPDFOutlineDocumentHelper::checkSeen(QPDFObjGen const& og)
+{
+ if (this->m->seen.count(og) > 0)
+ {
+ return true;
+ }
+ this->m->seen.insert(og);
+ return false;
+}