2
1
mirror of https://github.com/qpdf/qpdf.git synced 2024-06-08 21:22:25 +00:00

Rewrite bookmark example to use outline helpers

Now uses QPDFOutlineDocumentHelper and QPDFOutlineObjectHelper.
This commit is contained in:
Jay Berkenbilt 2018-12-19 13:11:59 -05:00
parent d5d179f441
commit 4fbffdf8ed

View File

@ -3,6 +3,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <qpdf/QPDF.hh> #include <qpdf/QPDF.hh>
#include <qpdf/QPDFPageDocumentHelper.hh> #include <qpdf/QPDFPageDocumentHelper.hh>
#include <qpdf/QPDFOutlineDocumentHelper.hh>
#include <qpdf/QUtil.hh> #include <qpdf/QUtil.hh>
#include <qpdf/QTC.hh> #include <qpdf/QTC.hh>
@ -56,111 +57,99 @@ void generate_page_map(QPDF& qpdf)
} }
} }
void extract_bookmarks(QPDFObjectHandle outlines, std::vector<int>& numbers) void show_bookmark_details(QPDFOutlineObjectHelper outline,
std::vector<int> numbers)
{ {
if (outlines.hasKey("/Title")) // No default so gcc will warn on missing tag
switch (style)
{ {
// No default so gcc will warn on missing tag case st_none:
switch (style) QTC::TC("examples", "pdf-bookmarks none");
{ break;
case st_none:
QTC::TC("examples", "pdf-bookmarks none");
break;
case st_numbers: case st_numbers:
QTC::TC("examples", "pdf-bookmarks numbers"); QTC::TC("examples", "pdf-bookmarks numbers");
for (std::vector<int>::iterator iter = numbers.begin(); for (std::vector<int>::iterator iter = numbers.begin();
iter != numbers.end(); ++iter) iter != numbers.end(); ++iter)
{ {
std::cout << *iter << "."; std::cout << *iter << ".";
} }
std::cout << " "; std::cout << " ";
break; break;
case st_lines: case st_lines:
QTC::TC("examples", "pdf-bookmarks lines"); QTC::TC("examples", "pdf-bookmarks lines");
print_lines(numbers); print_lines(numbers);
std::cout << "|" << std::endl; std::cout << "|" << std::endl;
print_lines(numbers); print_lines(numbers);
std::cout << "+-+ "; std::cout << "+-+ ";
break; break;
}
if (show_open)
{
if (outlines.hasKey("/Count"))
{
QTC::TC("examples", "pdf-bookmarks has count");
int count = outlines.getKey("/Count").getIntValue();
if (count > 0)
{
// hierarchy is open at this point
QTC::TC("examples", "pdf-bookmarks open");
std::cout << "(v) ";
}
else
{
QTC::TC("examples", "pdf-bookmarks closed");
std::cout << "(>) ";
}
}
else
{
QTC::TC("examples", "pdf-bookmarks no count");
std::cout << "( ) ";
}
}
if (show_targets)
{
QTC::TC("examples", "pdf-bookmarks targets");
std::string target = "unknown";
// Only explicit destinations supported for now
if (outlines.hasKey("/Dest"))
{
QTC::TC("examples", "pdf-bookmarks dest");
QPDFObjectHandle dest = outlines.getKey("/Dest");
if ((dest.isArray()) && (dest.getArrayNItems() > 0))
{
QPDFObjectHandle first = dest.getArrayItem(0);
QPDFObjGen og = first.getObjGen();
if (page_map.count(og))
{
target = QUtil::int_to_string(page_map[og]);
}
}
std::cout << "[ -> " << target << " ] ";
}
}
std::cout << outlines.getKey("/Title").getUTF8Value() << std::endl;
} }
if (outlines.hasKey("/First")) if (show_open)
{ {
numbers.push_back(0); int count = outline.getCount();
QPDFObjectHandle child = outlines.getKey("/First"); if (count)
while (1) {
{ QTC::TC("examples", "pdf-bookmarks has count");
++(numbers.back()); if (count > 0)
bool has_next = child.hasKey("/Next"); {
if ((style == st_lines) && (! has_next)) // hierarchy is open at this point
{ QTC::TC("examples", "pdf-bookmarks open");
numbers.back() = 0; std::cout << "(v) ";
} }
extract_bookmarks(child, numbers); else
if (has_next) {
{ QTC::TC("examples", "pdf-bookmarks closed");
child = child.getKey("/Next"); std::cout << "(>) ";
} }
else }
{ else
break; {
} QTC::TC("examples", "pdf-bookmarks no count");
} std::cout << "( ) ";
numbers.pop_back(); }
} }
if (show_targets)
{
QTC::TC("examples", "pdf-bookmarks targets");
std::string target = "unknown";
QPDFObjectHandle dest_page = outline.getDestPage();
if (! dest_page.isNull())
{
QTC::TC("examples", "pdf-bookmarks dest");
QPDFObjGen og = dest_page.getObjGen();
if (page_map.count(og))
{
target = QUtil::int_to_string(page_map[og]);
}
}
std::cout << "[ -> " << target << " ] ";
}
std::cout << outline.getTitle() << std::endl;
}
void extract_bookmarks(std::list<QPDFOutlineObjectHelper> outlines,
std::vector<int>& numbers)
{
numbers.push_back(0);
for (std::list<QPDFOutlineObjectHelper>::iterator iter = outlines.begin();
iter != outlines.end(); ++iter)
{
++(numbers.back());
show_bookmark_details(*iter, numbers);
std::list<QPDFOutlineObjectHelper>::iterator next = iter;
++next;
bool has_next = (next != outlines.end());
if ((style == st_lines) && (! has_next))
{
numbers.back() = 0;
}
extract_bookmarks((*iter).getKids(), numbers);
}
numbers.pop_back();
} }
int main(int argc, char* argv[]) int main(int argc, char* argv[])
@ -233,15 +222,15 @@ int main(int argc, char* argv[])
QPDF qpdf; QPDF qpdf;
qpdf.processFile(filename, password); qpdf.processFile(filename, password);
QPDFObjectHandle root = qpdf.getRoot(); QPDFOutlineDocumentHelper odh(qpdf);
if (root.hasKey("/Outlines")) if (odh.hasOutlines())
{ {
std::vector<int> numbers; std::vector<int> numbers;
if (show_targets) if (show_targets)
{ {
generate_page_map(qpdf); generate_page_map(qpdf);
} }
extract_bookmarks(root.getKey("/Outlines"), numbers); extract_bookmarks(odh.getTopLevelOutlines(), numbers);
} }
else else
{ {