diff options
Diffstat (limited to 'libqpdf')
-rw-r--r-- | libqpdf/QPDFObjectHandle.cc | 20 | ||||
-rw-r--r-- | libqpdf/QPDFPageDocumentHelper.cc | 10 | ||||
-rw-r--r-- | libqpdf/QPDFPageObjectHelper.cc | 43 | ||||
-rw-r--r-- | libqpdf/QPDF_optimization.cc | 8 |
4 files changed, 46 insertions, 35 deletions
diff --git a/libqpdf/QPDFObjectHandle.cc b/libqpdf/QPDFObjectHandle.cc index a0d45c86..b802a55c 100644 --- a/libqpdf/QPDFObjectHandle.cc +++ b/libqpdf/QPDFObjectHandle.cc @@ -18,6 +18,7 @@ #include <qpdf/Pl_QPDFTokenizer.hh> #include <qpdf/BufferInputSource.hh> #include <qpdf/QPDFExc.hh> +#include <qpdf/QPDFPageObjectHelper.hh> #include <qpdf/QTC.hh> #include <qpdf/QUtil.hh> @@ -1109,24 +1110,11 @@ QPDFObjectHandle::getGeneration() const std::map<std::string, QPDFObjectHandle> QPDFObjectHandle::getPageImages() { - // Note: this code doesn't handle inherited resources. If this - // page dictionary doesn't have a /Resources key or has one whose - // value is null or an empty dictionary, you are supposed to walk - // up the page tree until you find a /Resources dictionary. As of - // this writing, I don't have any test files that use inherited - // resources, and hand-generating one won't be a good test because - // any mistakes in my understanding would be present in both the - // code and the test file. - - // NOTE: If support of inherited resources (see above comment) is - // implemented, edit comment in QPDFObjectHandle.hh for this - // function. Also remove call to pushInheritedAttributesToPage - // from qpdf.cc when show_page_images is true. - std::map<std::string, QPDFObjectHandle> result; - if (this->hasKey("/Resources")) + QPDFObjectHandle resources = + QPDFPageObjectHelper(*this).getAttribute("/Resources", false); + if (resources.isDictionary()) { - QPDFObjectHandle resources = this->getKey("/Resources"); if (resources.hasKey("/XObject")) { QPDFObjectHandle xobject = resources.getKey("/XObject"); diff --git a/libqpdf/QPDFPageDocumentHelper.cc b/libqpdf/QPDFPageDocumentHelper.cc index fa50c471..3eec789b 100644 --- a/libqpdf/QPDFPageDocumentHelper.cc +++ b/libqpdf/QPDFPageDocumentHelper.cc @@ -79,20 +79,12 @@ QPDFPageDocumentHelper::flattenAnnotations( "document does not have updated appearance streams," " so form fields will not be flattened"); } - pushInheritedAttributesToPage(); std::vector<QPDFPageObjectHelper> pages = getAllPages(); for (std::vector<QPDFPageObjectHelper>::iterator iter = pages.begin(); iter != pages.end(); ++iter) { QPDFPageObjectHelper ph(*iter); - QPDFObjectHandle page_oh = ph.getObjectHandle(); - if (page_oh.getKey("/Resources").isIndirect()) - { - QTC::TC("qpdf", "QPDFPageDocumentHelper indirect resources"); - page_oh.replaceKey("/Resources", - page_oh.getKey("/Resources").shallowCopy()); - } - QPDFObjectHandle resources = ph.getObjectHandle().getKey("/Resources"); + QPDFObjectHandle resources = ph.getAttribute("/Resources", true); if (! resources.isDictionary()) { // This should never happen and is not exercised in the diff --git a/libqpdf/QPDFPageObjectHelper.cc b/libqpdf/QPDFPageObjectHelper.cc index c5ede04f..4d58da32 100644 --- a/libqpdf/QPDFPageObjectHelper.cc +++ b/libqpdf/QPDFPageObjectHelper.cc @@ -15,6 +15,42 @@ QPDFPageObjectHelper::QPDFPageObjectHelper(QPDFObjectHandle oh) : { } +QPDFObjectHandle +QPDFPageObjectHelper::getAttribute(std::string const& name, + bool copy_if_shared) +{ + bool inheritable = ((name == "/MediaBox") || (name == "/CropBox") || + (name == "/Resources") || (name == "/Rotate")); + + QPDFObjectHandle node = this->oh; + QPDFObjectHandle result(node.getKey(name)); + std::set<QPDFObjGen> seen; + bool inherited = false; + while (inheritable && result.isNull() && node.hasKey("/Parent")) + { + seen.insert(node.getObjGen()); + node = node.getKey("/Parent"); + if (seen.count(node.getObjGen())) + { + break; + } + result = node.getKey(name); + if (! result.isNull()) + { + QTC::TC("qpdf", "QPDFPageObjectHelper non-trivial inheritance"); + inherited = true; + } + } + if (copy_if_shared && (inherited || result.isIndirect())) + { + QTC::TC("qpdf", "QPDFPageObjectHelper copy shared attribute"); + result = result.shallowCopy(); + this->oh.replaceKey(name, result); + } + return result; +} + + std::map<std::string, QPDFObjectHandle> QPDFPageObjectHelper::getPageImages() { @@ -159,12 +195,7 @@ QPDFPageObjectHelper::removeUnreferencedResources() std::vector<std::string> to_filter; to_filter.push_back("/Font"); to_filter.push_back("/XObject"); - QPDFObjectHandle resources = this->oh.getKey("/Resources"); - if (resources.isDictionary()) - { - resources = resources.shallowCopy(); - this->oh.replaceKey("/Resources", resources); - } + QPDFObjectHandle resources = getAttribute("/Resources", true); for (std::vector<std::string>::iterator d_iter = to_filter.begin(); d_iter != to_filter.end(); ++d_iter) { diff --git a/libqpdf/QPDF_optimization.cc b/libqpdf/QPDF_optimization.cc index 59a01ea3..f282e5f3 100644 --- a/libqpdf/QPDF_optimization.cc +++ b/libqpdf/QPDF_optimization.cc @@ -208,10 +208,10 @@ QPDF::pushInheritedAttributesToPageInternal2( if (type == "/Pages") { - // Make a list of inheritable keys. Any key other than /Type, - // /Parent, Kids, or /Count is an inheritable attribute. Push - // this object onto the stack of pages nodes that have values - // for this attribute. + // Make a list of inheritable keys. Only the keys /MediaBox, + // /CropBox, /Resources, and /Rotate are inheritable + // attributes. Push this object onto the stack of pages nodes + // that have values for this attribute. std::set<std::string> inheritable_keys; std::set<std::string> keys = cur_pages.getKeys(); |