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,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&lt;int, int&gt; const&amp; object_stream_data, @@ -167,7 +167,16 @@ QPDF::optimize(std::map&lt;int, int&gt; const&amp; 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&lt;int, int&gt; const&amp; object_stream_data, @@ -212,26 +221,32 @@ QPDF::optimize(std::map&lt;int, int&gt; const&amp; 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 {