/src/poppler/poppler/Catalog.h
Line | Count | Source |
1 | | //======================================================================== |
2 | | // |
3 | | // Catalog.h |
4 | | // |
5 | | // Copyright 1996-2007 Glyph & Cog, LLC |
6 | | // |
7 | | //======================================================================== |
8 | | |
9 | | //======================================================================== |
10 | | // |
11 | | // Modified under the Poppler project - http://poppler.freedesktop.org |
12 | | // |
13 | | // All changes made under the Poppler project to this file are licensed |
14 | | // under GPL version 2 or later |
15 | | // |
16 | | // Copyright (C) 2005 Kristian Høgsberg <krh@redhat.com> |
17 | | // Copyright (C) 2005, 2007, 2009-2011, 2013, 2017-2026 Albert Astals Cid <aacid@kde.org> |
18 | | // Copyright (C) 2005 Jonathan Blandford <jrb@redhat.com> |
19 | | // Copyright (C) 2005, 2006, 2008 Brad Hards <bradh@frogmouth.net> |
20 | | // Copyright (C) 2007 Julien Rebetez <julienr@svn.gnome.org> |
21 | | // Copyright (C) 2008, 2011 Pino Toscano <pino@kde.org> |
22 | | // Copyright (C) 2010 Hib Eris <hib@hiberis.nl> |
23 | | // Copyright (C) 2012 Fabio D'Urso <fabiodurso@hotmail.it> |
24 | | // Copyright (C) 2013 Thomas Freitag <Thomas.Freitag@alfa.de> |
25 | | // Copyright (C) 2013 Adrian Perez de Castro <aperez@igalia.com> |
26 | | // Copyright (C) 2013, 2017 Adrian Johnson <ajohnson@redneon.com> |
27 | | // Copyright (C) 2013 José Aliste <jaliste@src.gnome.org> |
28 | | // Copyright (C) 2016 Masamichi Hosoda <trueroad@trueroad.jp> |
29 | | // Copyright (C) 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, <info@kdab.com>. Work sponsored by the LiMux project of the city of Munich |
30 | | // Copyright (C) 2018 Adam Reichold <adam.reichold@t-online.de> |
31 | | // Copyright (C) 2020 Oliver Sander <oliver.sander@tu-dresden.de> |
32 | | // Copyright (C) 2020 Katarina Behrens <Katarina.Behrens@cib.de> |
33 | | // Copyright (C) 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, <info@kdab.com>. Work sponsored by Technische Universität Dresden |
34 | | // Copyright (C) 2021 RM <rm+git@arcsin.org> |
35 | | // Copyright (C) 2024-2026 g10 Code GmbH, Author: Sune Stolborg Vuorela <sune@vuorela.dk> |
36 | | // Copyright (C) 2024 Hubert Figuière <hub@figuiere.net> |
37 | | // Copyright (C) 2025 Trystan Mata <trystan.mata@tytanium.xyz> |
38 | | // |
39 | | // To see a description of the changes please see the Changelog file that |
40 | | // came with your tarball or type make ChangeLog if you are building from git |
41 | | // |
42 | | //======================================================================== |
43 | | |
44 | | #ifndef CATALOG_H |
45 | | #define CATALOG_H |
46 | | |
47 | | #include "poppler-config.h" |
48 | | #include "poppler_private_export.h" |
49 | | #include "Object.h" |
50 | | #include "Link.h" |
51 | | #include "GfxState.h" |
52 | | |
53 | | #include <memory> |
54 | | #include <optional> |
55 | | #include <unordered_map> |
56 | | #include <vector> |
57 | | |
58 | | class PDFDoc; |
59 | | class XRef; |
60 | | class Object; |
61 | | class Page; |
62 | | class PageAttrs; |
63 | | struct Ref; |
64 | | class PageLabelInfo; |
65 | | class Form; |
66 | | class OCGs; |
67 | | class ViewerPreferences; |
68 | | class FileSpec; |
69 | | class StructTreeRoot; |
70 | | |
71 | | //------------------------------------------------------------------------ |
72 | | // NameTree |
73 | | //------------------------------------------------------------------------ |
74 | | |
75 | | class POPPLER_PRIVATE_EXPORT NameTree |
76 | | { |
77 | | public: |
78 | | NameTree(); |
79 | | ~NameTree(); |
80 | | |
81 | | NameTree(const NameTree &) = delete; |
82 | | NameTree &operator=(const NameTree &) = delete; |
83 | | |
84 | | void init(XRef *xref, Object *tree); |
85 | | Object lookup(const GooString *name); |
86 | 4.82k | int numEntries() { return entries.size(); }; |
87 | | // iterator accessor, note it returns a pointer to the internal object, do not free nor delete it |
88 | | Object *getValue(int i); |
89 | | const GooString *getName(int i) const; |
90 | | |
91 | | private: |
92 | | struct Entry |
93 | | { |
94 | | Entry(const Array &array, int index); |
95 | | ~Entry(); |
96 | | GooString name; |
97 | | Object value; |
98 | | }; |
99 | | |
100 | | void parse(const Object *tree, RefRecursionChecker &seen); |
101 | | |
102 | | XRef *xref; |
103 | | std::vector<std::unique_ptr<Entry>> entries; |
104 | | }; |
105 | | |
106 | | //------------------------------------------------------------------------ |
107 | | // Catalog |
108 | | //------------------------------------------------------------------------ |
109 | | |
110 | | class POPPLER_PRIVATE_EXPORT Catalog |
111 | | { |
112 | | public: |
113 | | // Constructor. |
114 | | explicit Catalog(PDFDoc *docA); |
115 | | |
116 | | // Destructor. |
117 | | ~Catalog(); |
118 | | |
119 | | Catalog(const Catalog &) = delete; |
120 | | Catalog &operator=(const Catalog &) = delete; |
121 | | |
122 | | // Is catalog valid? |
123 | 6.82k | bool isOk() const { return ok; } |
124 | | |
125 | | // Get number of pages. |
126 | | int getNumPages(); |
127 | | |
128 | | // Get a page. |
129 | | Page *getPage(int i); |
130 | | |
131 | | // Get the reference for a page object. |
132 | | Ref *getPageRef(int i); |
133 | | |
134 | | // Return base URI, or NULL if none. |
135 | 0 | const std::optional<std::string> &getBaseURI() const { return baseURI; } |
136 | | |
137 | | // Return the contents of the metadata stream, or nullopt if there is |
138 | | // no metadata. |
139 | | std::optional<std::string> readMetadata(); |
140 | | |
141 | | // Return the structure tree root object. |
142 | | StructTreeRoot *getStructTreeRoot(); |
143 | | |
144 | | // Return values from the MarkInfo dictionary as flags in a bitfield. |
145 | | enum MarkInfoFlags |
146 | | { |
147 | | markInfoNull = 1 << 0, |
148 | | markInfoMarked = 1 << 1, |
149 | | markInfoUserProperties = 1 << 2, |
150 | | markInfoSuspects = 1 << 3, |
151 | | }; |
152 | | unsigned int getMarkInfo(); |
153 | | |
154 | | // Find a page, given its object ID. Returns page number, or 0 if |
155 | | // not found. |
156 | | int findPage(Ref pageRef); |
157 | | |
158 | | // Find a named destination. Returns the link destination, or |
159 | | // NULL if <name> is not a destination. |
160 | | std::unique_ptr<LinkDest> findDest(const GooString *name); |
161 | | |
162 | | Object *getDests(); |
163 | | |
164 | | // Get the number of named destinations in name-dict |
165 | | int numDests(); |
166 | | |
167 | | // Get the i'th named destination name in name-dict |
168 | | const char *getDestsName(int i); |
169 | | |
170 | | // Get the i'th named destination link destination in name-dict |
171 | | std::unique_ptr<LinkDest> getDestsDest(int i); |
172 | | |
173 | | // Get the number of named destinations in name-tree |
174 | 0 | int numDestNameTree() { return getDestNameTree()->numEntries(); } |
175 | | |
176 | | // Get the i'th named destination name in name-tree |
177 | 0 | const GooString *getDestNameTreeName(int i) { return getDestNameTree()->getName(i); } |
178 | | |
179 | | // Get the i'th named destination link destination in name-tree |
180 | | std::unique_ptr<LinkDest> getDestNameTreeDest(int i); |
181 | | |
182 | | // Get the number of embedded files |
183 | 4.82k | int numEmbeddedFiles() { return getEmbeddedFileNameTree()->numEntries(); } |
184 | | |
185 | | // Get the i'th file embedded (at the Document level) in the document |
186 | | std::unique_ptr<FileSpec> embeddedFile(int i); |
187 | | |
188 | | // Is there an embedded file with the given name? |
189 | | bool hasEmbeddedFile(const std::string &fileName); |
190 | | |
191 | | // Adds and embeddedFile |
192 | | // If there is already an existing embedded file with the given fileName |
193 | | // it gets replaced, if that's not what you want check hasEmbeddedFile first |
194 | | void addEmbeddedFile(GooFile *file, const std::string &fileName); |
195 | | |
196 | | // Get the number of javascript scripts |
197 | 0 | int numJS() { return getJSNameTree()->numEntries(); } |
198 | 0 | const GooString *getJSName(int i) { return getJSNameTree()->getName(i); } |
199 | | |
200 | | // Get the i'th JavaScript script (at the Document level) in the document |
201 | | std::string getJS(int i); |
202 | | |
203 | | // Convert between page indices and page labels. |
204 | | bool labelToIndex(const std::string &label, int *index); |
205 | | bool indexToLabel(int index, std::string *label); |
206 | | |
207 | | Object *getOutline(); |
208 | | // returns the existing outline or new one if it doesn't exist |
209 | | Object *getCreateOutline(); |
210 | | |
211 | 0 | Object *getAcroForm() { return &acroForm; } |
212 | | void addFormToAcroForm(Ref formRef); |
213 | | void removeFormFromAcroForm(Ref formRef); |
214 | | void setAcroFormModified(); |
215 | | |
216 | 35.4k | const OCGs *getOptContentConfig() { return optContent.get(); } |
217 | | |
218 | 0 | int getPDFMajorVersion() const { return catalogPdfMajorVersion; } |
219 | 0 | int getPDFMinorVersion() const { return catalogPdfMinorVersion; } |
220 | | |
221 | | enum FormType |
222 | | { |
223 | | NoForm, |
224 | | AcroForm, |
225 | | XfaForm |
226 | | }; |
227 | | |
228 | | FormType getFormType(); |
229 | | // This can return nullptr if the document is in a very damaged state |
230 | | Form *getCreateForm(); |
231 | | Form *getForm(); |
232 | | |
233 | | ViewerPreferences *getViewerPreferences(); |
234 | | |
235 | | enum PageMode |
236 | | { |
237 | | pageModeNone, |
238 | | pageModeOutlines, |
239 | | pageModeThumbs, |
240 | | pageModeFullScreen, |
241 | | pageModeOC, |
242 | | pageModeAttach, |
243 | | pageModeNull |
244 | | }; |
245 | | enum PageLayout |
246 | | { |
247 | | pageLayoutNone, |
248 | | pageLayoutSinglePage, |
249 | | pageLayoutOneColumn, |
250 | | pageLayoutTwoColumnLeft, |
251 | | pageLayoutTwoColumnRight, |
252 | | pageLayoutTwoPageLeft, |
253 | | pageLayoutTwoPageRight, |
254 | | pageLayoutNull |
255 | | }; |
256 | | |
257 | | // Returns the page mode. |
258 | | PageMode getPageMode(); |
259 | | PageLayout getPageLayout(); |
260 | | |
261 | | enum DocumentAdditionalActionsType |
262 | | { |
263 | | actionCloseDocument, ///< Performed before closing the document |
264 | | actionSaveDocumentStart, ///< Performed before saving the document |
265 | | actionSaveDocumentFinish, ///< Performed after saving the document |
266 | | actionPrintDocumentStart, ///< Performed before printing the document |
267 | | actionPrintDocumentFinish, ///< Performed after printing the document |
268 | | }; |
269 | | |
270 | | std::unique_ptr<LinkAction> getAdditionalAction(DocumentAdditionalActionsType type); |
271 | | |
272 | | std::unique_ptr<LinkAction> getOpenAction() const; |
273 | | |
274 | | #if USE_CMS |
275 | | GfxLCMSProfilePtr getDisplayProfile(); |
276 | | std::shared_ptr<GfxXYZ2DisplayTransforms> getXYZ2DisplayTransforms(); |
277 | | #endif |
278 | | |
279 | | private: |
280 | | // Get page label info. |
281 | | PageLabelInfo *getPageLabelInfo(); |
282 | | |
283 | | PDFDoc *doc; |
284 | | XRef *xref; // the xref table for this PDF file |
285 | | std::vector<std::pair<std::unique_ptr<Page>, Ref>> pages; |
286 | | std::unordered_map<Ref, std::size_t> refPageMap; |
287 | | std::vector<Object> *pagesList; |
288 | | std::vector<Ref> *pagesRefList; |
289 | | std::vector<std::unique_ptr<PageAttrs>> attrsList; |
290 | | std::vector<int> *kidsIdxList; |
291 | | Form *form; |
292 | | ViewerPreferences *viewerPrefs; |
293 | | int numPages; // number of pages |
294 | | Object dests; // named destination dictionary |
295 | | Object names; // named names dictionary |
296 | | NameTree *destNameTree; // named destination name-tree |
297 | | NameTree *embeddedFileNameTree; // embedded file name-tree |
298 | | NameTree *jsNameTree; // Java Script name-tree |
299 | | std::optional<std::string> baseURI; // base URI for URI-type links |
300 | | Object metadata; // metadata stream |
301 | | StructTreeRoot *structTreeRoot; // structure tree root |
302 | | unsigned int markInfo; // Flags from MarkInfo dictionary |
303 | | Object outline; // outline dictionary |
304 | | Object acroForm; // AcroForm dictionary |
305 | | Object viewerPreferences; // ViewerPreference dictionary |
306 | | std::unique_ptr<OCGs> optContent; // Optional Content groups |
307 | | bool ok; // true if catalog is valid |
308 | | PageLabelInfo *pageLabelInfo; // info about page labels |
309 | | PageMode pageMode; // page mode |
310 | | PageLayout pageLayout; // page layout |
311 | | Object additionalActions; // page additional actions |
312 | | |
313 | | bool initPageList(); // init the page list. called by cachePageTree. |
314 | | bool cacheSubTree(); // called by cachePageTree. |
315 | | bool cachePageTree(int page); // Cache first <page> pages. |
316 | | std::size_t cachePageTreeForRef(Ref pageRef); // Cache until <pageRef>. |
317 | | Object *findDestInTree(Object *tree, GooString *name, Object *obj); |
318 | | |
319 | | Object *getNames(); |
320 | | NameTree *getDestNameTree(); |
321 | | NameTree *getEmbeddedFileNameTree(); |
322 | | NameTree *getJSNameTree(); |
323 | | static std::unique_ptr<LinkDest> createLinkDest(Object *obj); |
324 | | |
325 | | int catalogPdfMajorVersion = -1; |
326 | | int catalogPdfMinorVersion = -1; |
327 | | |
328 | | mutable std::recursive_mutex mutex; |
329 | | |
330 | | #if USE_CMS |
331 | | GfxLCMSProfilePtr displayProfile; |
332 | | std::shared_ptr<GfxXYZ2DisplayTransforms> XYZ2DisplayTransforms; |
333 | | #endif |
334 | | }; |
335 | | |
336 | | #endif |