Commit 1fec40454ef72c6e2f079b599e9c807ce69a4bec
1 parent
ce19ec5c
Add example of name/number trees and dictionary/array iteration
Showing
10 changed files
with
502 additions
and
1 deletions
ChangeLog
| 1 | +2021-01-30 Jay Berkenbilt <ejb@ql.org> | ||
| 2 | + | ||
| 3 | + * Add examples/pdf-name-number-tree.cc to illustrate new | ||
| 4 | + name/number tree API and new array/dictionary iterator API. | ||
| 5 | + | ||
| 1 | 2021-01-29 Jay Berkenbilt <ejb@ql.org> | 6 | 2021-01-29 Jay Berkenbilt <ejb@ql.org> |
| 2 | 7 | ||
| 3 | * Add wrappers QPDFDictItems and QPDFArrayItems around | 8 | * Add wrappers QPDFDictItems and QPDFArrayItems around |
examples/build.mk
| @@ -7,6 +7,7 @@ BINS_examples = \ | @@ -7,6 +7,7 @@ BINS_examples = \ | ||
| 7 | pdf-filter-tokens \ | 7 | pdf-filter-tokens \ |
| 8 | pdf-invert-images \ | 8 | pdf-invert-images \ |
| 9 | pdf-mod-info \ | 9 | pdf-mod-info \ |
| 10 | + pdf-name-number-tree \ | ||
| 10 | pdf-npages \ | 11 | pdf-npages \ |
| 11 | pdf-overlay-page \ | 12 | pdf-overlay-page \ |
| 12 | pdf-parse-content \ | 13 | pdf-parse-content \ |
examples/pdf-name-number-tree.cc
0 → 100644
| 1 | +#include <qpdf/QPDF.hh> | ||
| 2 | +#include <qpdf/QPDFNameTreeObjectHelper.hh> | ||
| 3 | +#include <qpdf/QPDFNumberTreeObjectHelper.hh> | ||
| 4 | +#include <qpdf/QPDFWriter.hh> | ||
| 5 | +#include <qpdf/QUtil.hh> | ||
| 6 | +#include <iostream> | ||
| 7 | +#include <cstring> | ||
| 8 | + | ||
| 9 | +static char const* whoami = 0; | ||
| 10 | + | ||
| 11 | +void usage() | ||
| 12 | +{ | ||
| 13 | + std::cerr << "Usage: " << whoami << " outfile.pdf" | ||
| 14 | + << std::endl | ||
| 15 | + << "Create some name/number trees and write to a file" | ||
| 16 | + << std::endl; | ||
| 17 | + exit(2); | ||
| 18 | +} | ||
| 19 | + | ||
| 20 | +int main(int argc, char* argv[]) | ||
| 21 | +{ | ||
| 22 | + whoami = QUtil::getWhoami(argv[0]); | ||
| 23 | + | ||
| 24 | + // For libtool's sake.... | ||
| 25 | + if (strncmp(whoami, "lt-", 3) == 0) | ||
| 26 | + { | ||
| 27 | + whoami += 3; | ||
| 28 | + } | ||
| 29 | + | ||
| 30 | + if (argc != 2) | ||
| 31 | + { | ||
| 32 | + usage(); | ||
| 33 | + } | ||
| 34 | + | ||
| 35 | + char const* outfilename = argv[1]; | ||
| 36 | + | ||
| 37 | + QPDF qpdf; | ||
| 38 | + qpdf.emptyPDF(); | ||
| 39 | + | ||
| 40 | + // This example doesn't do anything particularly useful other than | ||
| 41 | + // just illustrate how to use the APIs for name and number trees. | ||
| 42 | + // It also demonstrates use of the iterators for dictionaries and | ||
| 43 | + // arrays introduced at the same time with qpdf 10.2. | ||
| 44 | + | ||
| 45 | + // To use this example, compile it and run it. Study the output | ||
| 46 | + // and compare it to what you expect. When done, look at the | ||
| 47 | + // generated output file in a text editor to inspect the structure | ||
| 48 | + // of the trees as left in the file. | ||
| 49 | + | ||
| 50 | + // We're just going to create some name and number trees, hang | ||
| 51 | + // them off the document catalog (root), and write an empty PDF to | ||
| 52 | + // a file. The PDF will have no pages and won't be viewable, but | ||
| 53 | + // you can look at it in a text editor to see the resulting | ||
| 54 | + // structure of the PDF. | ||
| 55 | + | ||
| 56 | + // Create a dictionary off the root where we will hang our name | ||
| 57 | + // and number tree. | ||
| 58 | + auto root = qpdf.getRoot(); | ||
| 59 | + auto example = QPDFObjectHandle::newDictionary(); | ||
| 60 | + root.replaceKey("/Example", example); | ||
| 61 | + | ||
| 62 | + // Create a name tree, attach it to the file, and add some items. | ||
| 63 | + auto name_tree = QPDFNameTreeObjectHelper::newEmpty(qpdf); | ||
| 64 | + auto name_tree_oh = name_tree.getObjectHandle(); | ||
| 65 | + example.replaceKey("/NameTree", name_tree_oh); | ||
| 66 | + name_tree.insert("K", QPDFObjectHandle::newUnicodeString("king")); | ||
| 67 | + name_tree.insert("Q", QPDFObjectHandle::newUnicodeString("queen")); | ||
| 68 | + name_tree.insert("R", QPDFObjectHandle::newUnicodeString("rook")); | ||
| 69 | + name_tree.insert("B", QPDFObjectHandle::newUnicodeString("bishop")); | ||
| 70 | + name_tree.insert("N", QPDFObjectHandle::newUnicodeString("knight")); | ||
| 71 | + auto iter = name_tree.insert( | ||
| 72 | + "P", QPDFObjectHandle::newUnicodeString("pawn")); | ||
| 73 | + // Look at the iterator | ||
| 74 | + std::cout << "just inserted " << iter->first << " -> " | ||
| 75 | + << iter->second.unparse() << std::endl; | ||
| 76 | + --iter; | ||
| 77 | + std::cout << "predecessor: " << iter->first << " -> " | ||
| 78 | + << iter->second.unparse() << std::endl; | ||
| 79 | + ++iter; | ||
| 80 | + ++iter; | ||
| 81 | + std::cout << "successor: " << iter->first << " -> " | ||
| 82 | + << iter->second.unparse() << std::endl; | ||
| 83 | + | ||
| 84 | + // Use range-for iteration | ||
| 85 | + std::cout << "Name tree items:" << std::endl; | ||
| 86 | + for (auto i: name_tree) | ||
| 87 | + { | ||
| 88 | + std::cout << " " << i.first << " -> " | ||
| 89 | + << i.second.unparse() << std::endl; | ||
| 90 | + } | ||
| 91 | + | ||
| 92 | + // This is a small tree, so everything will be at the root. We can | ||
| 93 | + // look at it using dictionary and array iterators. | ||
| 94 | + std::cout << "Keys in name tree object:" << std::endl; | ||
| 95 | + QPDFObjectHandle names; | ||
| 96 | + for (auto const& i: QPDFDictItems(name_tree_oh)) | ||
| 97 | + { | ||
| 98 | + std::cout << i.first << std::endl; | ||
| 99 | + if (i.first == "/Names") | ||
| 100 | + { | ||
| 101 | + names = i.second; | ||
| 102 | + } | ||
| 103 | + } | ||
| 104 | + // Values in names array: | ||
| 105 | + std::cout << "Values in names:" << std::endl; | ||
| 106 | + for (auto& i: QPDFArrayItems(names)) | ||
| 107 | + { | ||
| 108 | + std::cout << " " << i.unparse() << std::endl; | ||
| 109 | + } | ||
| 110 | + | ||
| 111 | + // pre 10.2 API | ||
| 112 | + std::cout << "Has Q?: " << name_tree.hasName("Q") << std::endl; | ||
| 113 | + std::cout << "Has W?: " << name_tree.hasName("W") << std::endl; | ||
| 114 | + QPDFObjectHandle obj; | ||
| 115 | + std::cout << "Found W?: " << name_tree.findObject("W", obj) << std::endl; | ||
| 116 | + std::cout << "Found Q?: " << name_tree.findObject("Q", obj) << std::endl; | ||
| 117 | + std::cout << "Q: " << obj.unparse() << std::endl; | ||
| 118 | + | ||
| 119 | + // 10.2 API | ||
| 120 | + iter = name_tree.find("Q"); | ||
| 121 | + std::cout << "Q: " << iter->first << " -> " | ||
| 122 | + << iter->second.unparse() << std::endl; | ||
| 123 | + iter = name_tree.find("W"); | ||
| 124 | + std::cout << "W found: " << (iter != name_tree.end()) << std::endl; | ||
| 125 | + // Allow find to return predecessor | ||
| 126 | + iter = name_tree.find("W", true); | ||
| 127 | + std::cout << "W's predecessor: " << iter->first << " -> " | ||
| 128 | + << iter->second.unparse() << std::endl; | ||
| 129 | + | ||
| 130 | + // We can also remove items | ||
| 131 | + std::cout << "Remove P: " << name_tree.remove("P", &obj) << std::endl; | ||
| 132 | + std::cout << "Value removed: " << obj.unparse() << std::endl; | ||
| 133 | + std::cout << "Has P?: " << name_tree.hasName("P") << std::endl; | ||
| 134 | + // Or we can remove using an iterator | ||
| 135 | + iter = name_tree.find("K"); | ||
| 136 | + std::cout << "Find K: " << iter->second.unparse() << std::endl; | ||
| 137 | + iter.remove(); | ||
| 138 | + std::cout << "Iter after removing K: " << iter->first << " -> " | ||
| 139 | + << iter->second.unparse() << std::endl; | ||
| 140 | + std::cout << "Has K?: " << name_tree.hasName("K") << std::endl; | ||
| 141 | + | ||
| 142 | + // Illustrate some more advanced usage using number trees. These | ||
| 143 | + // calls work for name trees too. | ||
| 144 | + | ||
| 145 | + // The safe way to populate a tree is to call insert repeatedly as | ||
| 146 | + // above, but if you know you are definitely inserting items in | ||
| 147 | + // order, it is more efficient to insert them using insertAfter, | ||
| 148 | + // which avoids doing a binary search through the tree for each | ||
| 149 | + // insertion. Note that if you don't insert items in order using | ||
| 150 | + // this method, you will create an invalid tree. | ||
| 151 | + auto number_tree = QPDFNumberTreeObjectHelper::newEmpty(qpdf); | ||
| 152 | + auto number_tree_oh = number_tree.getObjectHandle(); | ||
| 153 | + example.replaceKey("/NumberTree", number_tree_oh); | ||
| 154 | + auto iter2 = number_tree.begin(); | ||
| 155 | + for (int i = 7; i <= 350; i += 7) | ||
| 156 | + { | ||
| 157 | + iter2.insertAfter(i, QPDFObjectHandle::newString( | ||
| 158 | + "-" + QUtil::int_to_string(i) + "-")); | ||
| 159 | + } | ||
| 160 | + std::cout << "Numbers:" << std::endl; | ||
| 161 | + int n = 1; | ||
| 162 | + for (auto& i: number_tree) | ||
| 163 | + { | ||
| 164 | + std::cout << i.first << " -> " << i.second.getUTF8Value(); | ||
| 165 | + if (n % 5) | ||
| 166 | + { | ||
| 167 | + std::cout << ", "; | ||
| 168 | + } | ||
| 169 | + else | ||
| 170 | + { | ||
| 171 | + std::cout << std::endl; | ||
| 172 | + } | ||
| 173 | + ++n; | ||
| 174 | + } | ||
| 175 | + | ||
| 176 | + // When you remove an item with an iterator, the iterator | ||
| 177 | + // advances. This makes it possible to filter while iterating. | ||
| 178 | + // Remove all items that are multiples of 5. | ||
| 179 | + iter2 = number_tree.begin(); | ||
| 180 | + while (iter2 != number_tree.end()) | ||
| 181 | + { | ||
| 182 | + if (iter2->first % 5 == 0) | ||
| 183 | + { | ||
| 184 | + iter2.remove(); // also advances | ||
| 185 | + } | ||
| 186 | + else | ||
| 187 | + { | ||
| 188 | + ++iter2; | ||
| 189 | + } | ||
| 190 | + } | ||
| 191 | + std::cout << "Numbers after filtering:" << std::endl; | ||
| 192 | + n = 1; | ||
| 193 | + for (auto& i: number_tree) | ||
| 194 | + { | ||
| 195 | + std::cout << i.first << " -> " << i.second.getUTF8Value(); | ||
| 196 | + if (n % 5) | ||
| 197 | + { | ||
| 198 | + std::cout << ", "; | ||
| 199 | + } | ||
| 200 | + else | ||
| 201 | + { | ||
| 202 | + std::cout << std::endl; | ||
| 203 | + } | ||
| 204 | + ++n; | ||
| 205 | + } | ||
| 206 | + | ||
| 207 | + // Write to an output file | ||
| 208 | + QPDFWriter w(qpdf, outfilename); | ||
| 209 | + w.setQDFMode(true); | ||
| 210 | + w.setStaticID(true); // for testing only | ||
| 211 | + w.write(); | ||
| 212 | + | ||
| 213 | + return 0; | ||
| 214 | +} |
examples/qtest/name-number-tree.test
0 → 100644
| 1 | +#!/usr/bin/env perl | ||
| 2 | +require 5.008; | ||
| 3 | +BEGIN { $^W = 1; } | ||
| 4 | +use strict; | ||
| 5 | + | ||
| 6 | +chdir("name-number-tree") or die "chdir testdir failed: $!\n"; | ||
| 7 | + | ||
| 8 | +require TestDriver; | ||
| 9 | + | ||
| 10 | +my $td = new TestDriver('name-number-tree'); | ||
| 11 | + | ||
| 12 | +cleanup(); | ||
| 13 | + | ||
| 14 | +$td->runtest("name/number tree", | ||
| 15 | + {$td->COMMAND => 'pdf-name-number-tree a.pdf'}, | ||
| 16 | + {$td->FILE => 'nn.out', $td->EXIT_STATUS => 0}, | ||
| 17 | + $td->NORMALIZE_NEWLINES); | ||
| 18 | + | ||
| 19 | +$td->runtest("check output", | ||
| 20 | + {$td->FILE => "a.pdf"}, | ||
| 21 | + {$td->FILE => "out.pdf"}); | ||
| 22 | + | ||
| 23 | +cleanup(); | ||
| 24 | + | ||
| 25 | +$td->report(2); | ||
| 26 | + | ||
| 27 | +sub cleanup | ||
| 28 | +{ | ||
| 29 | + unlink 'a.pdf'; | ||
| 30 | +} |
examples/qtest/name-number-tree/nn.out
0 → 100644
| 1 | +just inserted P -> (pawn) | ||
| 2 | +predecessor: N -> (knight) | ||
| 3 | +successor: Q -> (queen) | ||
| 4 | +Name tree items: | ||
| 5 | + B -> (bishop) | ||
| 6 | + K -> (king) | ||
| 7 | + N -> (knight) | ||
| 8 | + P -> (pawn) | ||
| 9 | + Q -> (queen) | ||
| 10 | + R -> (rook) | ||
| 11 | +Keys in name tree object: | ||
| 12 | +/Names | ||
| 13 | +Values in names: | ||
| 14 | + (B) | ||
| 15 | + (bishop) | ||
| 16 | + (K) | ||
| 17 | + (king) | ||
| 18 | + (N) | ||
| 19 | + (knight) | ||
| 20 | + (P) | ||
| 21 | + (pawn) | ||
| 22 | + (Q) | ||
| 23 | + (queen) | ||
| 24 | + (R) | ||
| 25 | + (rook) | ||
| 26 | +Has Q?: 1 | ||
| 27 | +Has W?: 0 | ||
| 28 | +Found W?: 0 | ||
| 29 | +Found Q?: 1 | ||
| 30 | +Q: (queen) | ||
| 31 | +Q: Q -> (queen) | ||
| 32 | +W found: 0 | ||
| 33 | +W's predecessor: R -> (rook) | ||
| 34 | +Remove P: 1 | ||
| 35 | +Value removed: (pawn) | ||
| 36 | +Has P?: 0 | ||
| 37 | +Find K: (king) | ||
| 38 | +Iter after removing K: N -> (knight) | ||
| 39 | +Has K?: 0 | ||
| 40 | +Numbers: | ||
| 41 | +7 -> -7-, 14 -> -14-, 21 -> -21-, 28 -> -28-, 35 -> -35- | ||
| 42 | +42 -> -42-, 49 -> -49-, 56 -> -56-, 63 -> -63-, 70 -> -70- | ||
| 43 | +77 -> -77-, 84 -> -84-, 91 -> -91-, 98 -> -98-, 105 -> -105- | ||
| 44 | +112 -> -112-, 119 -> -119-, 126 -> -126-, 133 -> -133-, 140 -> -140- | ||
| 45 | +147 -> -147-, 154 -> -154-, 161 -> -161-, 168 -> -168-, 175 -> -175- | ||
| 46 | +182 -> -182-, 189 -> -189-, 196 -> -196-, 203 -> -203-, 210 -> -210- | ||
| 47 | +217 -> -217-, 224 -> -224-, 231 -> -231-, 238 -> -238-, 245 -> -245- | ||
| 48 | +252 -> -252-, 259 -> -259-, 266 -> -266-, 273 -> -273-, 280 -> -280- | ||
| 49 | +287 -> -287-, 294 -> -294-, 301 -> -301-, 308 -> -308-, 315 -> -315- | ||
| 50 | +322 -> -322-, 329 -> -329-, 336 -> -336-, 343 -> -343-, 350 -> -350- | ||
| 51 | +Numbers after filtering: | ||
| 52 | +7 -> -7-, 14 -> -14-, 21 -> -21-, 28 -> -28-, 42 -> -42- | ||
| 53 | +49 -> -49-, 56 -> -56-, 63 -> -63-, 77 -> -77-, 84 -> -84- | ||
| 54 | +91 -> -91-, 98 -> -98-, 112 -> -112-, 119 -> -119-, 126 -> -126- | ||
| 55 | +133 -> -133-, 147 -> -147-, 154 -> -154-, 161 -> -161-, 168 -> -168- | ||
| 56 | +182 -> -182-, 189 -> -189-, 196 -> -196-, 203 -> -203-, 217 -> -217- | ||
| 57 | +224 -> -224-, 231 -> -231-, 238 -> -238-, 252 -> -252-, 259 -> -259- | ||
| 58 | +266 -> -266-, 273 -> -273-, 287 -> -287-, 294 -> -294-, 301 -> -301- | ||
| 59 | +308 -> -308-, 322 -> -322-, 329 -> -329-, 336 -> -336-, 343 -> -343- |
examples/qtest/name-number-tree/out.pdf
0 → 100644
| 1 | +%PDF-1.3 | ||
| 2 | +%¿÷¢þ | ||
| 3 | +%QDF-1.0 | ||
| 4 | + | ||
| 5 | +%% Original object ID: 1 0 | ||
| 6 | +1 0 obj | ||
| 7 | +<< | ||
| 8 | + /Example << | ||
| 9 | + /NameTree << | ||
| 10 | + /Names [ | ||
| 11 | + (B) | ||
| 12 | + (bishop) | ||
| 13 | + (N) | ||
| 14 | + (knight) | ||
| 15 | + (Q) | ||
| 16 | + (queen) | ||
| 17 | + (R) | ||
| 18 | + (rook) | ||
| 19 | + ] | ||
| 20 | + >> | ||
| 21 | + /NumberTree << | ||
| 22 | + /Kids [ | ||
| 23 | + 2 0 R | ||
| 24 | + 3 0 R | ||
| 25 | + 4 0 R | ||
| 26 | + ] | ||
| 27 | + /Limits [ | ||
| 28 | + 7 | ||
| 29 | + 343 | ||
| 30 | + ] | ||
| 31 | + >> | ||
| 32 | + >> | ||
| 33 | + /Pages 5 0 R | ||
| 34 | + /Type /Catalog | ||
| 35 | +>> | ||
| 36 | +endobj | ||
| 37 | + | ||
| 38 | +%% Original object ID: 3 0 | ||
| 39 | +2 0 obj | ||
| 40 | +<< | ||
| 41 | + /Limits [ | ||
| 42 | + 7 | ||
| 43 | + 112 | ||
| 44 | + ] | ||
| 45 | + /Nums [ | ||
| 46 | + 7 | ||
| 47 | + (-7-) | ||
| 48 | + 14 | ||
| 49 | + (-14-) | ||
| 50 | + 21 | ||
| 51 | + (-21-) | ||
| 52 | + 28 | ||
| 53 | + (-28-) | ||
| 54 | + 42 | ||
| 55 | + (-42-) | ||
| 56 | + 49 | ||
| 57 | + (-49-) | ||
| 58 | + 56 | ||
| 59 | + (-56-) | ||
| 60 | + 63 | ||
| 61 | + (-63-) | ||
| 62 | + 77 | ||
| 63 | + (-77-) | ||
| 64 | + 84 | ||
| 65 | + (-84-) | ||
| 66 | + 91 | ||
| 67 | + (-91-) | ||
| 68 | + 98 | ||
| 69 | + (-98-) | ||
| 70 | + 112 | ||
| 71 | + (-112-) | ||
| 72 | + ] | ||
| 73 | +>> | ||
| 74 | +endobj | ||
| 75 | + | ||
| 76 | +%% Original object ID: 4 0 | ||
| 77 | +3 0 obj | ||
| 78 | +<< | ||
| 79 | + /Limits [ | ||
| 80 | + 119 | ||
| 81 | + 224 | ||
| 82 | + ] | ||
| 83 | + /Nums [ | ||
| 84 | + 119 | ||
| 85 | + (-119-) | ||
| 86 | + 126 | ||
| 87 | + (-126-) | ||
| 88 | + 133 | ||
| 89 | + (-133-) | ||
| 90 | + 147 | ||
| 91 | + (-147-) | ||
| 92 | + 154 | ||
| 93 | + (-154-) | ||
| 94 | + 161 | ||
| 95 | + (-161-) | ||
| 96 | + 168 | ||
| 97 | + (-168-) | ||
| 98 | + 182 | ||
| 99 | + (-182-) | ||
| 100 | + 189 | ||
| 101 | + (-189-) | ||
| 102 | + 196 | ||
| 103 | + (-196-) | ||
| 104 | + 203 | ||
| 105 | + (-203-) | ||
| 106 | + 217 | ||
| 107 | + (-217-) | ||
| 108 | + 224 | ||
| 109 | + (-224-) | ||
| 110 | + ] | ||
| 111 | +>> | ||
| 112 | +endobj | ||
| 113 | + | ||
| 114 | +%% Original object ID: 5 0 | ||
| 115 | +4 0 obj | ||
| 116 | +<< | ||
| 117 | + /Limits [ | ||
| 118 | + 231 | ||
| 119 | + 343 | ||
| 120 | + ] | ||
| 121 | + /Nums [ | ||
| 122 | + 231 | ||
| 123 | + (-231-) | ||
| 124 | + 238 | ||
| 125 | + (-238-) | ||
| 126 | + 252 | ||
| 127 | + (-252-) | ||
| 128 | + 259 | ||
| 129 | + (-259-) | ||
| 130 | + 266 | ||
| 131 | + (-266-) | ||
| 132 | + 273 | ||
| 133 | + (-273-) | ||
| 134 | + 287 | ||
| 135 | + (-287-) | ||
| 136 | + 294 | ||
| 137 | + (-294-) | ||
| 138 | + 301 | ||
| 139 | + (-301-) | ||
| 140 | + 308 | ||
| 141 | + (-308-) | ||
| 142 | + 322 | ||
| 143 | + (-322-) | ||
| 144 | + 329 | ||
| 145 | + (-329-) | ||
| 146 | + 336 | ||
| 147 | + (-336-) | ||
| 148 | + 343 | ||
| 149 | + (-343-) | ||
| 150 | + ] | ||
| 151 | +>> | ||
| 152 | +endobj | ||
| 153 | + | ||
| 154 | +%% Original object ID: 2 0 | ||
| 155 | +5 0 obj | ||
| 156 | +<< | ||
| 157 | + /Count 0 | ||
| 158 | + /Kids [ | ||
| 159 | + ] | ||
| 160 | + /Type /Pages | ||
| 161 | +>> | ||
| 162 | +endobj | ||
| 163 | + | ||
| 164 | +xref | ||
| 165 | +0 6 | ||
| 166 | +0000000000 65535 f | ||
| 167 | +0000000052 00000 n | ||
| 168 | +0000000448 00000 n | ||
| 169 | +0000000775 00000 n | ||
| 170 | +0000001130 00000 n | ||
| 171 | +0000001505 00000 n | ||
| 172 | +trailer << | ||
| 173 | + /Root 1 0 R | ||
| 174 | + /Size 6 | ||
| 175 | + /ID [<31415926535897932384626433832795><31415926535897932384626433832795>] | ||
| 176 | +>> | ||
| 177 | +startxref | ||
| 178 | +1567 | ||
| 179 | +%%EOF |
include/qpdf/QPDFNameTreeObjectHelper.hh
| @@ -35,6 +35,9 @@ | @@ -35,6 +35,9 @@ | ||
| 35 | // up items in the name tree, use UTF-8 strings. All names are | 35 | // up items in the name tree, use UTF-8 strings. All names are |
| 36 | // normalized for lookup purposes. | 36 | // normalized for lookup purposes. |
| 37 | 37 | ||
| 38 | +// See examples/pdf-name-number-tree.cc for a demonstration of using | ||
| 39 | +// QPDFNameTreeObjectHelper. | ||
| 40 | + | ||
| 38 | class NNTreeImpl; | 41 | class NNTreeImpl; |
| 39 | class NNTreeIterator; | 42 | class NNTreeIterator; |
| 40 | class NNTreeDetails; | 43 | class NNTreeDetails; |
include/qpdf/QPDFNumberTreeObjectHelper.hh
| @@ -32,6 +32,9 @@ | @@ -32,6 +32,9 @@ | ||
| 32 | // This is an object helper for number trees. See section 7.9.7 in the | 32 | // This is an object helper for number trees. See section 7.9.7 in the |
| 33 | // PDF spec (ISO 32000) for a description of number trees. | 33 | // PDF spec (ISO 32000) for a description of number trees. |
| 34 | 34 | ||
| 35 | +// See examples/pdf-name-number-tree.cc for a demonstration of using | ||
| 36 | +// QPDFNumberTreeObjectHelper. | ||
| 37 | + | ||
| 35 | class NNTreeImpl; | 38 | class NNTreeImpl; |
| 36 | class NNTreeIterator; | 39 | class NNTreeIterator; |
| 37 | class NNTreeDetails; | 40 | class NNTreeDetails; |
include/qpdf/QPDFObjectHandle.hh
| @@ -1237,6 +1237,9 @@ class QPDFDictItems | @@ -1237,6 +1237,9 @@ class QPDFDictItems | ||
| 1237 | // // iter.second is a QPDFObjectHandle | 1237 | // // iter.second is a QPDFObjectHandle |
| 1238 | // } | 1238 | // } |
| 1239 | 1239 | ||
| 1240 | + // See examples/pdf-name-number-tree.cc for a demonstration of | ||
| 1241 | + // using this API. | ||
| 1242 | + | ||
| 1240 | public: | 1243 | public: |
| 1241 | QPDF_DLL | 1244 | QPDF_DLL |
| 1242 | QPDFDictItems(QPDFObjectHandle& oh); | 1245 | QPDFDictItems(QPDFObjectHandle& oh); |
| @@ -1324,6 +1327,9 @@ class QPDFArrayItems | @@ -1324,6 +1327,9 @@ class QPDFArrayItems | ||
| 1324 | // // iter is a QPDFObjectHandle | 1327 | // // iter is a QPDFObjectHandle |
| 1325 | // } | 1328 | // } |
| 1326 | 1329 | ||
| 1330 | + // See examples/pdf-name-number-tree.cc for a demonstration of | ||
| 1331 | + // using this API. | ||
| 1332 | + | ||
| 1327 | public: | 1333 | public: |
| 1328 | QPDF_DLL | 1334 | QPDF_DLL |
| 1329 | QPDFArrayItems(QPDFObjectHandle& oh); | 1335 | QPDFArrayItems(QPDFObjectHandle& oh); |
manual/qpdf-manual.xml
| @@ -4854,7 +4854,8 @@ print "\n"; | @@ -4854,7 +4854,8 @@ print "\n"; | ||
| 4854 | <classname>QPDFObjectHandle</classname>, allowing C++-style | 4854 | <classname>QPDFObjectHandle</classname>, allowing C++-style |
| 4855 | iteration, including range-for iteration, over dictionary | 4855 | iteration, including range-for iteration, over dictionary |
| 4856 | and array QPDFObjectHandles. See comments in | 4856 | and array QPDFObjectHandles. See comments in |
| 4857 | - <filename>include/qpdf/QPDFObjectHandle.hh</filename> for | 4857 | + <filename>include/qpdf/QPDFObjectHandle.hh</filename> and |
| 4858 | + <filename>examples/pdf-name-number-tree.cc</filename> for | ||
| 4858 | details. | 4859 | details. |
| 4859 | </para> | 4860 | </para> |
| 4860 | </listitem> | 4861 | </listitem> |