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,6 +3,7 @@
3 #include <stdlib.h> 3 #include <stdlib.h>
4 #include <qpdf/QPDF.hh> 4 #include <qpdf/QPDF.hh>
5 #include <qpdf/QPDFPageDocumentHelper.hh> 5 #include <qpdf/QPDFPageDocumentHelper.hh>
  6 +#include <qpdf/QPDFOutlineDocumentHelper.hh>
6 #include <qpdf/QUtil.hh> 7 #include <qpdf/QUtil.hh>
7 #include <qpdf/QTC.hh> 8 #include <qpdf/QTC.hh>
8 9
@@ -56,111 +57,99 @@ void generate_page_map(QPDF&amp; qpdf) @@ -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 int main(int argc, char* argv[]) 155 int main(int argc, char* argv[])
@@ -233,15 +222,15 @@ int main(int argc, char* argv[]) @@ -233,15 +222,15 @@ int main(int argc, char* argv[])
233 QPDF qpdf; 222 QPDF qpdf;
234 qpdf.processFile(filename, password); 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 std::vector<int> numbers; 228 std::vector<int> numbers;
240 if (show_targets) 229 if (show_targets)
241 { 230 {
242 generate_page_map(qpdf); 231 generate_page_map(qpdf);
243 } 232 }
244 - extract_bookmarks(root.getKey("/Outlines"), numbers); 233 + extract_bookmarks(odh.getTopLevelOutlines(), numbers);
245 } 234 }
246 else 235 else
247 { 236 {