Coverage Report

Created: 2025-11-11 07:02

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/qpdf/include/qpdf/QPDFPageDocumentHelper.hh
Line
Count
Source
1
// Copyright (c) 2005-2021 Jay Berkenbilt
2
// Copyright (c) 2022-2025 Jay Berkenbilt and Manfred Holger
3
//
4
// This file is part of qpdf.
5
//
6
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
7
// in compliance with the License. You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing, software distributed under the License
12
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
13
// or implied. See the License for the specific language governing permissions and limitations under
14
// the License.
15
//
16
// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic
17
// License. At your option, you may continue to consider qpdf to be licensed under those terms.
18
// Please see the manual for additional information.
19
20
#ifndef QPDFPAGEDOCUMENTHELPER_HH
21
#define QPDFPAGEDOCUMENTHELPER_HH
22
23
#include <qpdf/Constants.h>
24
#include <qpdf/QPDFDocumentHelper.hh>
25
#include <qpdf/QPDFPageObjectHelper.hh>
26
27
#include <qpdf/DLL.h>
28
29
#include <vector>
30
31
#include <qpdf/QPDF.hh>
32
33
class QPDFAcroFormDocumentHelper;
34
35
class QPDFPageDocumentHelper: public QPDFDocumentHelper
36
{
37
  public:
38
    // Get a shared document helper for a given QPDF object.
39
    //
40
    // Retrieving a document helper for a QPDF object rather than creating a new one avoids repeated
41
    // validation of the Acroform structure, which can be expensive.
42
    QPDF_DLL
43
    static QPDFPageDocumentHelper& get(QPDF& qpdf);
44
45
    // Re-validate the Pages structure. This is useful if you have modified the Pages structure  in
46
    // a way that would invalidate the cache.
47
    //
48
    // If repair is true, the document will be repaired if possible if the validation encounters
49
    // errors.
50
    QPDF_DLL
51
    void validate(bool repair = true);
52
53
    QPDF_DLL
54
    QPDFPageDocumentHelper(QPDF&);
55
56
0
    ~QPDFPageDocumentHelper() override = default;
57
58
    // Traverse page tree, and return all /Page objects wrapped in QPDFPageObjectHelper objects.
59
    // Unlike with QPDF::getAllPages, the vector of pages returned by this call is not affected by
60
    // additions or removals of pages. If you manipulate pages, you will have to call this again to
61
    // get a new copy. Please see comments in QPDF.hh for getAllPages() for additional details.
62
    QPDF_DLL
63
    std::vector<QPDFPageObjectHelper> getAllPages();
64
65
    // The PDF /Pages tree allows inherited values. Working with the pages of a pdf is much easier
66
    // when the inheritance is resolved by explicitly setting the values in each /Page.
67
    QPDF_DLL
68
    void pushInheritedAttributesToPage();
69
70
    // This calls QPDFPageObjectHelper::removeUnreferencedResources for every page in the document.
71
    // See comments in QPDFPageObjectHelper.hh for details.
72
    QPDF_DLL
73
    void removeUnreferencedResources();
74
75
    // Add a new page at the beginning or the end of the current pdf. The newpage parameter may be
76
    // either a direct object, an indirect object from this QPDF, or an indirect object from another
77
    // QPDF. If it is a direct object, it will be made indirect. If it is an indirect object from
78
    // another QPDF, this method will call pushInheritedAttributesToPage on the other file and then
79
    // copy the page to this QPDF using the same underlying code as copyForeignObject. At this
80
    // stage, if the indirect object is already in the pages tree, a shallow copy is made to avoid
81
    // adding the same page more than once. In version 10.3.1 and earlier, adding a page that
82
    // already existed would throw an exception and could cause qpdf to crash on subsequent page
83
    // insertions in some cases. Note that this means that, in some cases, the page actually added
84
    // won't be exactly the same object as the one passed in. If you want to do subsequent
85
    // modification on the page, you should retrieve it again.
86
    //
87
    // Note that you can call copyForeignObject directly to copy a page from a different file, but
88
    // the resulting object will not be a page in the new file. You could do this, for example, to
89
    // convert a page into a form XObject, though for that, you're better off using
90
    // QPDFPageObjectHelper::getFormXObjectForPage.
91
    //
92
    // This method does not have any specific awareness of annotations or form fields, so if you
93
    // just add a page without thinking about it, you might end up with two pages that share form
94
    // fields or annotations. While the page may look fine, it will probably not function properly
95
    // with regard to interactive features. To work around this, you should call
96
    // QPDFAcroFormDocumentHelper::fixCopiedAnnotations. A future version of qpdf will likely
97
    // provide a higher-level interface for copying pages around that will handle document-level
98
    // constructs in a less error-prone fashion.
99
100
    QPDF_DLL
101
    void addPage(QPDFPageObjectHelper newpage, bool first);
102
103
    // Add new page before or after refpage. See comments for addPage for details about what newpage
104
    // should be.
105
    QPDF_DLL
106
    void addPageAt(QPDFPageObjectHelper newpage, bool before, QPDFPageObjectHelper refpage);
107
108
    // Remove page from the pdf.
109
    QPDF_DLL
110
    void removePage(QPDFPageObjectHelper page);
111
112
    // For every annotation, integrate the annotation's appearance stream into the containing page's
113
    // content streams, merge the annotation's resources with the page's resources, and remove the
114
    // annotation from the page. Handles widget annotations associated with interactive form fields
115
    // as a special case, including removing the /AcroForm key from the document catalog. The values
116
    // passed to required_flags and forbidden_flags are passed along to
117
    // QPDFAnnotationObjectHelper::getPageContentForAppearance. See comments there in
118
    // QPDFAnnotationObjectHelper.hh for meanings of those flags.
119
    QPDF_DLL
120
    void flattenAnnotations(int required_flags = 0, int forbidden_flags = an_invisible | an_hidden);
121
122
  private:
123
    class Members;
124
125
    std::shared_ptr<Members> m;
126
};
127
128
#endif // QPDFPAGEDOCUMENTHELPER_HH