Commit 4fbffdf8ed3992bd1bdd0d742d101202fd462835

Authored by Jay Berkenbilt
1 parent d5d179f4

Rewrite bookmark example to use outline helpers

Now uses QPDFOutlineDocumentHelper and QPDFOutlineObjectHelper.
Showing 1 changed file with 89 additions and 100 deletions
examples/pdf-bookmarks.cc
... ... @@ -3,6 +3,7 @@
3 3 #include <stdlib.h>
4 4 #include <qpdf/QPDF.hh>
5 5 #include <qpdf/QPDFPageDocumentHelper.hh>
  6 +#include <qpdf/QPDFOutlineDocumentHelper.hh>
6 7 #include <qpdf/QUtil.hh>
7 8 #include <qpdf/QTC.hh>
8 9  
... ... @@ -56,111 +57,99 @@ void generate_page_map(QPDF&amp; qpdf)
56 57 }
57 58 }
58 59  
59   -void extract_bookmarks(QPDFObjectHandle outlines, std::vector<int>& numbers)
  60 +void show_bookmark_details(QPDFOutlineObjectHelper outline,
  61 + std::vector<int> numbers)
60 62 {
61   - if (outlines.hasKey("/Title"))
  63 + // No default so gcc will warn on missing tag
  64 + switch (style)
62 65 {
63   - // No default so gcc will warn on missing tag
64   - switch (style)
65   - {
66   - case st_none:
67   - QTC::TC("examples", "pdf-bookmarks none");
68   - break;
69   -
70   - case st_numbers:
71   - QTC::TC("examples", "pdf-bookmarks numbers");
72   - for (std::vector<int>::iterator iter = numbers.begin();
73   - iter != numbers.end(); ++iter)
74   - {
75   - std::cout << *iter << ".";
76   - }
77   - std::cout << " ";
78   - break;
79   -
80   - case st_lines:
81   - QTC::TC("examples", "pdf-bookmarks lines");
82   - print_lines(numbers);
83   - std::cout << "|" << std::endl;
84   - print_lines(numbers);
85   - std::cout << "+-+ ";
86   - break;
87   - }
88   -
89   - if (show_open)
90   - {
91   - if (outlines.hasKey("/Count"))
92   - {
93   - QTC::TC("examples", "pdf-bookmarks has count");
94   - int count = outlines.getKey("/Count").getIntValue();
95   - if (count > 0)
96   - {
97   - // hierarchy is open at this point
98   - QTC::TC("examples", "pdf-bookmarks open");
99   - std::cout << "(v) ";
100   - }
101   - else
102   - {
103   - QTC::TC("examples", "pdf-bookmarks closed");
104   - std::cout << "(>) ";
105   - }
106   - }
107   - else
108   - {
109   - QTC::TC("examples", "pdf-bookmarks no count");
110   - std::cout << "( ) ";
111   - }
112   - }
113   -
114   - if (show_targets)
115   - {
116   - QTC::TC("examples", "pdf-bookmarks targets");
117   - std::string target = "unknown";
118   - // Only explicit destinations supported for now
119   - if (outlines.hasKey("/Dest"))
120   - {
121   - QTC::TC("examples", "pdf-bookmarks dest");
122   - QPDFObjectHandle dest = outlines.getKey("/Dest");
123   - if ((dest.isArray()) && (dest.getArrayNItems() > 0))
124   - {
125   - QPDFObjectHandle first = dest.getArrayItem(0);
126   - QPDFObjGen og = first.getObjGen();
127   - if (page_map.count(og))
128   - {
129   - target = QUtil::int_to_string(page_map[og]);
130   - }
131   - }
  66 + case st_none:
  67 + QTC::TC("examples", "pdf-bookmarks none");
  68 + break;
  69 +
  70 + case st_numbers:
  71 + QTC::TC("examples", "pdf-bookmarks numbers");
  72 + for (std::vector<int>::iterator iter = numbers.begin();
  73 + iter != numbers.end(); ++iter)
  74 + {
  75 + std::cout << *iter << ".";
  76 + }
  77 + std::cout << " ";
  78 + break;
  79 +
  80 + case st_lines:
  81 + QTC::TC("examples", "pdf-bookmarks lines");
  82 + print_lines(numbers);
  83 + std::cout << "|" << std::endl;
  84 + print_lines(numbers);
  85 + std::cout << "+-+ ";
  86 + break;
  87 + }
132 88  
133   - std::cout << "[ -> " << target << " ] ";
134   - }
135   - }
  89 + if (show_open)
  90 + {
  91 + int count = outline.getCount();
  92 + if (count)
  93 + {
  94 + QTC::TC("examples", "pdf-bookmarks has count");
  95 + if (count > 0)
  96 + {
  97 + // hierarchy is open at this point
  98 + QTC::TC("examples", "pdf-bookmarks open");
  99 + std::cout << "(v) ";
  100 + }
  101 + else
  102 + {
  103 + QTC::TC("examples", "pdf-bookmarks closed");
  104 + std::cout << "(>) ";
  105 + }
  106 + }
  107 + else
  108 + {
  109 + QTC::TC("examples", "pdf-bookmarks no count");
  110 + std::cout << "( ) ";
  111 + }
  112 + }
136 113  
137   - std::cout << outlines.getKey("/Title").getUTF8Value() << std::endl;
  114 + if (show_targets)
  115 + {
  116 + QTC::TC("examples", "pdf-bookmarks targets");
  117 + std::string target = "unknown";
  118 + QPDFObjectHandle dest_page = outline.getDestPage();
  119 + if (! dest_page.isNull())
  120 + {
  121 + QTC::TC("examples", "pdf-bookmarks dest");
  122 + QPDFObjGen og = dest_page.getObjGen();
  123 + if (page_map.count(og))
  124 + {
  125 + target = QUtil::int_to_string(page_map[og]);
  126 + }
  127 + }
  128 + std::cout << "[ -> " << target << " ] ";
138 129 }
139 130  
140   - if (outlines.hasKey("/First"))
  131 + std::cout << outline.getTitle() << std::endl;
  132 +}
  133 +
  134 +void extract_bookmarks(std::list<QPDFOutlineObjectHelper> outlines,
  135 + std::vector<int>& numbers)
  136 +{
  137 + numbers.push_back(0);
  138 + for (std::list<QPDFOutlineObjectHelper>::iterator iter = outlines.begin();
  139 + iter != outlines.end(); ++iter)
141 140 {
142   - numbers.push_back(0);
143   - QPDFObjectHandle child = outlines.getKey("/First");
144   - while (1)
145   - {
146   - ++(numbers.back());
147   - bool has_next = child.hasKey("/Next");
148   - if ((style == st_lines) && (! has_next))
149   - {
150   - numbers.back() = 0;
151   - }
152   - extract_bookmarks(child, numbers);
153   - if (has_next)
154   - {
155   - child = child.getKey("/Next");
156   - }
157   - else
158   - {
159   - break;
160   - }
161   - }
162   - numbers.pop_back();
  141 + ++(numbers.back());
  142 + show_bookmark_details(*iter, numbers);
  143 + std::list<QPDFOutlineObjectHelper>::iterator next = iter;
  144 + ++next;
  145 + bool has_next = (next != outlines.end());
  146 + if ((style == st_lines) && (! has_next))
  147 + {
  148 + numbers.back() = 0;
  149 + }
  150 + extract_bookmarks((*iter).getKids(), numbers);
163 151 }
  152 + numbers.pop_back();
164 153 }
165 154  
166 155 int main(int argc, char* argv[])
... ... @@ -233,15 +222,15 @@ int main(int argc, char* argv[])
233 222 QPDF qpdf;
234 223 qpdf.processFile(filename, password);
235 224  
236   - QPDFObjectHandle root = qpdf.getRoot();
237   - if (root.hasKey("/Outlines"))
  225 + QPDFOutlineDocumentHelper odh(qpdf);
  226 + if (odh.hasOutlines())
238 227 {
239 228 std::vector<int> numbers;
240 229 if (show_targets)
241 230 {
242 231 generate_page_map(qpdf);
243 232 }
244   - extract_bookmarks(root.getKey("/Outlines"), numbers);
  233 + extract_bookmarks(odh.getTopLevelOutlines(), numbers);
245 234 }
246 235 else
247 236 {
... ...