Commit 7770a1b036433be7a47b65da7c34297353c7e77d
Committed by
Jay Berkenbilt
1 parent
235188df
Added public method QPDF::pushInheritedAttributesToPage
Refactored optimizePagesTree to pushInheritedAttributesToPage and made public
Showing
3 changed files
with
35 additions
and
25 deletions
include/qpdf/QPDF.hh
| @@ -374,6 +374,11 @@ class QPDF | @@ -374,6 +374,11 @@ class QPDF | ||
| 374 | QPDF_DLL | 374 | QPDF_DLL |
| 375 | void updateAllPagesCache(); | 375 | void updateAllPagesCache(); |
| 376 | 376 | ||
| 377 | + // The PDF /Pages tree allows inherited values. Working with | ||
| 378 | + // the pages of a pdf is much easier when the inheritance is | ||
| 379 | + // resolved by explicitly setting the values in each /Page. | ||
| 380 | + void pushInheritedAttributesToPage(); | ||
| 381 | + | ||
| 377 | // Add new page at the beginning or the end of the current pdf | 382 | // Add new page at the beginning or the end of the current pdf |
| 378 | QPDF_DLL | 383 | QPDF_DLL |
| 379 | void addPage(QPDFObjectHandle newpage, bool first); | 384 | void addPage(QPDFObjectHandle newpage, bool first); |
| @@ -903,11 +908,11 @@ class QPDF | @@ -903,11 +908,11 @@ class QPDF | ||
| 903 | 908 | ||
| 904 | // Methods to support optimization | 909 | // Methods to support optimization |
| 905 | 910 | ||
| 906 | - void optimizePagesTree(bool allow_changes); | ||
| 907 | - void optimizePagesTreeInternal( | 911 | + void pushInheritedAttributesToPage(bool allow_changes); |
| 912 | + void pushInheritedAttributesToPageInternal( | ||
| 908 | QPDFObjectHandle, | 913 | QPDFObjectHandle, |
| 909 | std::map<std::string, std::vector<QPDFObjectHandle> >&, | 914 | std::map<std::string, std::vector<QPDFObjectHandle> >&, |
| 910 | - int& pageno, bool allow_changes); | 915 | + bool allow_changes); |
| 911 | void updateObjectMaps(ObjUser const& ou, QPDFObjectHandle oh); | 916 | void updateObjectMaps(ObjUser const& ou, QPDFObjectHandle oh); |
| 912 | void updateObjectMapsInternal(ObjUser const& ou, QPDFObjectHandle oh, | 917 | void updateObjectMapsInternal(ObjUser const& ou, QPDFObjectHandle oh, |
| 913 | std::set<ObjGen>& visited, bool top); | 918 | std::set<ObjGen>& visited, bool top); |
libqpdf/QPDF_optimization.cc
| @@ -167,7 +167,16 @@ QPDF::optimize(std::map<int, int> const& object_stream_data, | @@ -167,7 +167,16 @@ QPDF::optimize(std::map<int, int> const& object_stream_data, | ||
| 167 | 167 | ||
| 168 | // Traverse pages tree pushing all inherited resources down to the | 168 | // Traverse pages tree pushing all inherited resources down to the |
| 169 | // page level. | 169 | // page level. |
| 170 | - optimizePagesTree(allow_changes); | 170 | + pushInheritedAttributesToPage(allow_changes); |
| 171 | + getAllPages(); | ||
| 172 | + | ||
| 173 | + // Traverse pages | ||
| 174 | + int n = this->all_pages.size(); | ||
| 175 | + for (int pageno = 0; pageno < n; ++pageno) | ||
| 176 | + { | ||
| 177 | + updateObjectMaps(ObjUser(ObjUser::ou_page, pageno), | ||
| 178 | + this->all_pages[pageno]); | ||
| 179 | + } | ||
| 171 | 180 | ||
| 172 | // Traverse document-level items | 181 | // Traverse document-level items |
| 173 | std::set<std::string> keys = this->trailer.getKeys(); | 182 | std::set<std::string> keys = this->trailer.getKeys(); |
| @@ -212,26 +221,32 @@ QPDF::optimize(std::map<int, int> const& object_stream_data, | @@ -212,26 +221,32 @@ QPDF::optimize(std::map<int, int> const& object_stream_data, | ||
| 212 | } | 221 | } |
| 213 | 222 | ||
| 214 | void | 223 | void |
| 215 | -QPDF::optimizePagesTree(bool allow_changes) | 224 | +QPDF::pushInheritedAttributesToPage() |
| 225 | +{ | ||
| 226 | + // Public API should not have access to allow_changes. | ||
| 227 | + pushInheritedAttributesToPage(true); | ||
| 228 | +} | ||
| 229 | + | ||
| 230 | +void | ||
| 231 | +QPDF::pushInheritedAttributesToPage(bool allow_changes) | ||
| 216 | { | 232 | { |
| 217 | // Traverse pages tree pushing all inherited resources down to the | 233 | // Traverse pages tree pushing all inherited resources down to the |
| 218 | // page level. | 234 | // page level. |
| 219 | 235 | ||
| 220 | // key_ancestors is a mapping of page attribute keys to a stack of | 236 | // key_ancestors is a mapping of page attribute keys to a stack of |
| 221 | - // Pages nodes that contain values for them. pageno is the | ||
| 222 | - // current page sequence number numbered from 0. | 237 | + // Pages nodes that contain values for them. |
| 223 | std::map<std::string, std::vector<QPDFObjectHandle> > key_ancestors; | 238 | std::map<std::string, std::vector<QPDFObjectHandle> > key_ancestors; |
| 224 | - int pageno = 0; | ||
| 225 | - optimizePagesTreeInternal(this->trailer.getKey("/Root").getKey("/Pages"), | ||
| 226 | - key_ancestors, pageno, allow_changes); | 239 | + pushInheritedAttributesToPageInternal( |
| 240 | + this->trailer.getKey("/Root").getKey("/Pages"), | ||
| 241 | + key_ancestors, allow_changes); | ||
| 227 | assert(key_ancestors.empty()); | 242 | assert(key_ancestors.empty()); |
| 228 | } | 243 | } |
| 229 | 244 | ||
| 230 | void | 245 | void |
| 231 | -QPDF::optimizePagesTreeInternal( | 246 | +QPDF::pushInheritedAttributesToPageInternal( |
| 232 | QPDFObjectHandle cur_pages, | 247 | QPDFObjectHandle cur_pages, |
| 233 | std::map<std::string, std::vector<QPDFObjectHandle> >& key_ancestors, | 248 | std::map<std::string, std::vector<QPDFObjectHandle> >& key_ancestors, |
| 234 | - int& pageno, bool allow_changes) | 249 | + bool allow_changes) |
| 235 | { | 250 | { |
| 236 | // Extract the underlying dictionary object | 251 | // Extract the underlying dictionary object |
| 237 | std::string type = cur_pages.getKey("/Type").getName(); | 252 | std::string type = cur_pages.getKey("/Type").getName(); |
| @@ -301,8 +316,8 @@ QPDF::optimizePagesTreeInternal( | @@ -301,8 +316,8 @@ QPDF::optimizePagesTreeInternal( | ||
| 301 | int n = kids.getArrayNItems(); | 316 | int n = kids.getArrayNItems(); |
| 302 | for (int i = 0; i < n; ++i) | 317 | for (int i = 0; i < n; ++i) |
| 303 | { | 318 | { |
| 304 | - optimizePagesTreeInternal( | ||
| 305 | - kids.getArrayItem(i), key_ancestors, pageno, allow_changes); | 319 | + pushInheritedAttributesToPageInternal( |
| 320 | + kids.getArrayItem(i), key_ancestors, allow_changes); | ||
| 306 | } | 321 | } |
| 307 | 322 | ||
| 308 | // For each inheritable key, pop the stack. If the stack | 323 | // For each inheritable key, pop the stack. If the stack |
| @@ -350,15 +365,6 @@ QPDF::optimizePagesTreeInternal( | @@ -350,15 +365,6 @@ QPDF::optimizePagesTreeInternal( | ||
| 350 | QTC::TC("qpdf", "QPDF opt page resource hides ancestor"); | 365 | QTC::TC("qpdf", "QPDF opt page resource hides ancestor"); |
| 351 | } | 366 | } |
| 352 | } | 367 | } |
| 353 | - | ||
| 354 | - // Traverse from this point, updating the mappings of object | ||
| 355 | - // users to objects and objects to object users. | ||
| 356 | - | ||
| 357 | - updateObjectMaps(ObjUser(ObjUser::ou_page, pageno), cur_pages); | ||
| 358 | - | ||
| 359 | - // Increment pageno so that its value will be correct for the | ||
| 360 | - // next page. | ||
| 361 | - ++pageno; | ||
| 362 | } | 368 | } |
| 363 | else | 369 | else |
| 364 | { | 370 | { |
libqpdf/QPDF_pages.cc
| @@ -102,7 +102,7 @@ QPDF::flattenPagesTree() | @@ -102,7 +102,7 @@ QPDF::flattenPagesTree() | ||
| 102 | } | 102 | } |
| 103 | 103 | ||
| 104 | // Push inherited objects down to the /Page level | 104 | // Push inherited objects down to the /Page level |
| 105 | - optimizePagesTree(true); | 105 | + pushInheritedAttributesToPage(); |
| 106 | getAllPages(); | 106 | getAllPages(); |
| 107 | 107 | ||
| 108 | QPDFObjectHandle pages = getRoot().getKey("/Pages"); | 108 | QPDFObjectHandle pages = getRoot().getKey("/Pages"); |
| @@ -225,7 +225,6 @@ QPDF::addPageAt(QPDFObjectHandle newpage, bool before, | @@ -225,7 +225,6 @@ QPDF::addPageAt(QPDFObjectHandle newpage, bool before, | ||
| 225 | insertPage(newpage, refpos); | 225 | insertPage(newpage, refpos); |
| 226 | } | 226 | } |
| 227 | 227 | ||
| 228 | - | ||
| 229 | void | 228 | void |
| 230 | QPDF::addPage(QPDFObjectHandle newpage, bool first) | 229 | QPDF::addPage(QPDFObjectHandle newpage, bool first) |
| 231 | { | 230 | { |