aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2022-09-07 01:00:40 +0200
committerJay Berkenbilt <ejb@ql.org>2022-09-07 01:00:40 +0200
commit76cd7ea67aee7edd1004a68a28e63a00a38239dd (patch)
tree66d131387939bc7bf88e802a9f11221aba5eda2e /include
parentc1def4ead4c578862ad6fcda35a9ca65be407893 (diff)
downloadqpdf-76cd7ea67aee7edd1004a68a28e63a00a38239dd.tar.zst
Clarify and improve QPDFPageObjectHelper::get*Box methods
Add copy_if_fallback and explain how it differs from copy_if_shared.
Diffstat (limited to 'include')
-rw-r--r--include/qpdf/QPDFPageObjectHelper.hh157
1 files changed, 142 insertions, 15 deletions
diff --git a/include/qpdf/QPDFPageObjectHelper.hh b/include/qpdf/QPDFPageObjectHelper.hh
index df4c7864..ef3c09ca 100644
--- a/include/qpdf/QPDFPageObjectHelper.hh
+++ b/include/qpdf/QPDFPageObjectHelper.hh
@@ -45,29 +45,151 @@ class QPDFPageObjectHelper: public QPDFObjectHelper
QPDF_DLL
virtual ~QPDFPageObjectHelper() = default;
- // Works with pages and form XObjects. Return the effective value
- // of this attribute for the page/form XObject. For pages, if the
- // requested attribute is not present on the page but is
- // inheritable, look up through the page's ancestors in the page
- // tree. If copy_if_shared is true, then this method will replace
- // the attribute with a shallow copy if it is in indirect or
- // inherited and return the copy. You should do this if you are
- // going to modify the returned object and want the modifications
- // to apply to the current page/form XObject only.
+ // PAGE ATTRIBUTES
+
+ // The getAttribute method works with pages and form XObjects. It
+ // return the value of the requested attribute from the page/form
+ // XObject's dictionary, taking inheritance from the pages tree
+ // into consideration. For pages, the attributes /MediaBox,
+ // /CropBox, /Resources, and /Rotate are inheritable, meaning that
+ // if they are not present directly on the page node, they may be
+ // inherited from ancestor nodes in the pages tree.
+ //
+ // There are two ways that an attribute can be "shared":
+ //
+ // * For inheritable attributes on pages, it may appear in a
+ // higher level node of the pages tree
+ //
+ // * For any attribute, the attribute may be an indirect object
+ // which may be referenced by more than one page/form XObject.
+ //
+ // If copy_if_shared is true, then this method will replace the
+ // attribute with a shallow copy if it is indirect or inherited
+ // and return the copy. You should do this if you are going to
+ // modify the returned object and want the modifications to apply
+ // to the current page/form XObject only.
QPDF_DLL
QPDFObjectHandle getAttribute(std::string const& name, bool copy_if_shared);
- // Return the TrimBox. If not defined, fall back to CropBox
+ // PAGE BOXES
+ //
+ // Pages have various types of boundary boxes. These are described
+ // in detail in the PDF specification (section 14.11.2 Page
+ // boundaries). They are, by key in the page dictionary:
+ //
+ // * /MediaBox -- boundaries of physical page
+ // * /CropBox -- clipping region of what is displayed
+ // * /BleedBox -- clipping region for production environments
+ // * /TrimBox -- dimensions of final printed page after trimming
+ // * /ArtBox -- extent of meaningful content including margins
+ //
+ // Of these, only /MediaBox is required. If any are absent, the
+ // fallback value for /CropBox is /MediaBox, and the fallback
+ // values for the other boxes are /CropBox.
+ //
+ // As noted above (PAGE ATTRIBUTES), /MediaBox and /CropBox can be
+ // inherited from parent nodes in the pages tree. The other boxes
+ // can't be inherited.
+ //
+ // When the comments below refer to the "effective value" of an
+ // box, this takes into consideration both inheritance through the
+ // pages tree (in the case of /MediaBox and /CropBox) and fallback
+ // values for missing attributes (for all except /MediaBox).
+ //
+ // For the methods below, copy_if_shared is passed to getAttribute
+ // and therefore refers only to indirect objects and values that
+ // are inherited through the pages tree.
+ //
+ // If copy_if_fallback is true, a copy is made if the object's
+ // value was obtained by falling back to a different box.
+ //
+ // The copy_if_shared and copy_if_fallback parameters carry across
+ // multiple layers. This is explained below.
+ //
+ // You should set copy_if_shared to true if you want to modify a
+ // bounding box for the current page without affecting other pages
+ // but you don't want to change the fallback behavior. For
+ // example, if you want to modify the /TrimBox for the current
+ // page only but have it continue to fall back to the value of
+ // /CropBox or /MediaBox if they are not defined, you could set
+ // copy_if_shared to true.
+ //
+ // You should set copy_if_fallback to true if you want to modify a
+ // specific box as distinct from any other box. For example, if
+ // you want to make /TrimBox differ from /CropBox, then you should
+ // set copy_if_fallback to true.
+ //
+ // The copy_if_fallback flags were added in qpdf 11.
+ //
+ // For example, suppose that neither /CropBox nor /TrimBox is
+ // present on a page but /CropBox is present in the page's parent
+ // node in the page tree.
+ //
+ // * getTrimBox(false, false) would return the /CropBox from the
+ // parent node.
+ //
+ // * getTrimBox(true, false) would make a shallow copy of the
+ // /CropBox from the parent node into the current node and
+ // return it.
+ //
+ // * getTrimBox(false, true) would make a shallow copy of the
+ // /CropBox from the parent node into /TrimBox of the current
+ // node and return it.
+ //
+ // * getTrimBox(true, true) would make a shallow copy of the
+ // /CropBox from the parent node into the current node, then
+ // make a shallow copy of the resulting copy to /TrimBox of the
+ // current node, and then return that.
+ //
+ // To illustrate how these parameters carry across multiple
+ // layers, suppose that neither /MediaBox, /CropBox, nor /TrimBox
+ // is present on a page but /MediaBox is present on the parent. In
+ // this case:
+ //
+ // * getTrimBox(false, false) would return the value of /MediaBox
+ // from the parent node.
+ //
+ // * getTrimBox(true, false) would copy /MediaBox to the current
+ // node and return it.
+ //
+ // * getTrimBox(false, true) would first copy /MediaBox from the
+ // parent to /CropBox, then copy /CropBox to /TrimBox, and then
+ // return the result.
+ //
+ // * getTrimBox(true, true) would first copy /MediaBox from the
+ // parent to the current page, then copy it to /CropBox, then
+ // copy /CropBox to /TrimBox, and then return the result.
+ //
+ // If you need different behavior, call getAttribute directly and
+ // take care of your own copying.
+
+ // Return the effective MediaBox
QPDF_DLL
- QPDFObjectHandle getTrimBox(bool copy_if_shared = false);
+ QPDFObjectHandle getMediaBox(bool copy_if_shared = false);
- // Return the CropBox. If not defined, fall back to MediaBox
+ // Return the effective CropBox. If not defined, fall back to
+ // MediaBox
QPDF_DLL
- QPDFObjectHandle getCropBox(bool copy_if_shared = false);
+ QPDFObjectHandle
+ getCropBox(bool copy_if_shared = false, bool copy_if_fallback = false);
- // Return the MediaBox
+ // Return the effective BleedBox. If not defined, fall back to
+ // CropBox.
QPDF_DLL
- QPDFObjectHandle getMediaBox(bool copy_if_shared = false);
+ QPDFObjectHandle
+ getBleedBox(bool copy_if_shared = false, bool copy_if_fallback = false);
+
+ // Return the effective TrimBox. If not defined, fall back to
+ // CropBox.
+ QPDF_DLL
+ QPDFObjectHandle
+ getTrimBox(bool copy_if_shared = false, bool copy_if_fallback = false);
+
+ // Return the effective ArtBox. If not defined, fall back to
+ // CropBox.
+ QPDF_DLL
+ QPDFObjectHandle
+ getArtBox(bool copy_if_shared = false, bool copy_if_fallback = false);
// Iterate through XObjects, possibly recursing into form
// XObjects. This works with pages or form XObjects. Call action
@@ -373,6 +495,11 @@ class QPDFPageObjectHelper: public QPDFObjectHelper
QPDFAcroFormDocumentHelper* from_afdh = nullptr);
private:
+ QPDFObjectHandle getAttribute(
+ std::string const& name,
+ bool copy_if_shared,
+ std::function<QPDFObjectHandle()> get_fallback,
+ bool copy_if_fallback);
static bool removeUnreferencedResourcesHelper(
QPDFPageObjectHelper ph, std::set<std::string>& unresolved);