Commit 4fbffdf8ed3992bd1bdd0d742d101202fd462835
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& qpdf) | @@ -56,111 +57,99 @@ void generate_page_map(QPDF& 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 | { |