Commit 7770a1b036433be7a47b65da7c34297353c7e77d

Authored by Tobias Hoffmann
Committed by Jay Berkenbilt
1 parent 235188df

Added public method QPDF::pushInheritedAttributesToPage

Refactored optimizePagesTree to pushInheritedAttributesToPage and made
public
include/qpdf/QPDF.hh
... ... @@ -374,6 +374,11 @@ class QPDF
374 374 QPDF_DLL
375 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 382 // Add new page at the beginning or the end of the current pdf
378 383 QPDF_DLL
379 384 void addPage(QPDFObjectHandle newpage, bool first);
... ... @@ -903,11 +908,11 @@ class QPDF
903 908  
904 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 913 QPDFObjectHandle,
909 914 std::map<std::string, std::vector<QPDFObjectHandle> >&,
910   - int& pageno, bool allow_changes);
  915 + bool allow_changes);
911 916 void updateObjectMaps(ObjUser const& ou, QPDFObjectHandle oh);
912 917 void updateObjectMapsInternal(ObjUser const& ou, QPDFObjectHandle oh,
913 918 std::set<ObjGen>& visited, bool top);
... ...
libqpdf/QPDF_optimization.cc
... ... @@ -167,7 +167,16 @@ QPDF::optimize(std::map&lt;int, int&gt; const&amp; object_stream_data,
167 167  
168 168 // Traverse pages tree pushing all inherited resources down to the
169 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 181 // Traverse document-level items
173 182 std::set<std::string> keys = this->trailer.getKeys();
... ... @@ -212,26 +221,32 @@ QPDF::optimize(std::map&lt;int, int&gt; const&amp; object_stream_data,
212 221 }
213 222  
214 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 233 // Traverse pages tree pushing all inherited resources down to the
218 234 // page level.
219 235  
220 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 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 242 assert(key_ancestors.empty());
228 243 }
229 244  
230 245 void
231   -QPDF::optimizePagesTreeInternal(
  246 +QPDF::pushInheritedAttributesToPageInternal(
232 247 QPDFObjectHandle cur_pages,
233 248 std::map<std::string, std::vector<QPDFObjectHandle> >& key_ancestors,
234   - int& pageno, bool allow_changes)
  249 + bool allow_changes)
235 250 {
236 251 // Extract the underlying dictionary object
237 252 std::string type = cur_pages.getKey("/Type").getName();
... ... @@ -301,8 +316,8 @@ QPDF::optimizePagesTreeInternal(
301 316 int n = kids.getArrayNItems();
302 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 323 // For each inheritable key, pop the stack. If the stack
... ... @@ -350,15 +365,6 @@ QPDF::optimizePagesTreeInternal(
350 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 369 else
364 370 {
... ...
libqpdf/QPDF_pages.cc
... ... @@ -102,7 +102,7 @@ QPDF::flattenPagesTree()
102 102 }
103 103  
104 104 // Push inherited objects down to the /Page level
105   - optimizePagesTree(true);
  105 + pushInheritedAttributesToPage();
106 106 getAllPages();
107 107  
108 108 QPDFObjectHandle pages = getRoot().getKey("/Pages");
... ... @@ -225,7 +225,6 @@ QPDF::addPageAt(QPDFObjectHandle newpage, bool before,
225 225 insertPage(newpage, refpos);
226 226 }
227 227  
228   -
229 228 void
230 229 QPDF::addPage(QPDFObjectHandle newpage, bool first)
231 230 {
... ...