1 | //======================================================================== |
---|---|
2 | // |
3 | // StructTreeRoot.h |
4 | // |
5 | // This file is licensed under the GPLv2 or later |
6 | // |
7 | // Copyright 2013, 2014 Igalia S.L. |
8 | // Copyright 2018, 2019 Albert Astals Cid <aacid@kde.org> |
9 | // Copyright 2018 Adrian Johnson <ajohnson@redneon.com> |
10 | // Copyright 2018 Adam Reichold <adam.reichold@t-online.de> |
11 | // |
12 | //======================================================================== |
13 | |
14 | #ifndef STRUCTTREEROOT_H |
15 | #define STRUCTTREEROOT_H |
16 | |
17 | #include "Object.h" |
18 | #include "StructElement.h" |
19 | #include <map> |
20 | #include <vector> |
21 | |
22 | class Dict; |
23 | class PDFDoc; |
24 | |
25 | class StructTreeRoot |
26 | { |
27 | public: |
28 | StructTreeRoot(PDFDoc *docA, Dict *rootDict); |
29 | ~StructTreeRoot(); |
30 | |
31 | StructTreeRoot &operator=(const StructTreeRoot &) = delete; |
32 | StructTreeRoot(const StructTreeRoot &) = delete; |
33 | |
34 | PDFDoc *getDoc() { return doc; } |
35 | Dict *getRoleMap() { return roleMap.isDict() ? roleMap.getDict() : nullptr; } |
36 | Dict *getClassMap() { return classMap.isDict() ? classMap.getDict() : nullptr; } |
37 | unsigned getNumChildren() const { return elements.size(); } |
38 | const StructElement *getChild(int i) const { return elements.at(n: i); } |
39 | StructElement *getChild(int i) { return elements.at(n: i); } |
40 | |
41 | void appendChild(StructElement *element) |
42 | { |
43 | if (element && element->isOk()) { |
44 | elements.push_back(x: element); |
45 | } |
46 | } |
47 | |
48 | const StructElement *findParentElement(int key, unsigned mcid = 0) const |
49 | { |
50 | auto it = parentTree.find(x: key); |
51 | if (it != parentTree.end()) { |
52 | if (mcid < it->second.size()) { |
53 | return it->second[mcid].element; |
54 | } |
55 | } |
56 | return nullptr; |
57 | } |
58 | |
59 | private: |
60 | typedef std::vector<StructElement *> ElemPtrArray; |
61 | |
62 | // Structure for items in /ParentTree, it keeps a mapping of |
63 | // object references and pointers to StructElement objects. |
64 | struct Parent |
65 | { |
66 | Ref ref; |
67 | StructElement *element; |
68 | |
69 | Parent() : element(nullptr) { ref = Ref::INVALID(); } |
70 | Parent(const Parent &p) = default; |
71 | Parent &operator=(const Parent &) = default; |
72 | ~Parent() { } |
73 | }; |
74 | |
75 | PDFDoc *doc; |
76 | Object roleMap; |
77 | Object classMap; |
78 | ElemPtrArray elements; |
79 | std::map<int, std::vector<Parent>> parentTree; |
80 | std::multimap<Ref, Parent *> refToParentMap; |
81 | |
82 | void parse(Dict *rootDict); |
83 | void parseNumberTreeNode(Dict *node); |
84 | void parentTreeAdd(const Ref objectRef, StructElement *element); |
85 | |
86 | friend class StructElement; |
87 | }; |
88 | |
89 | #endif |
90 |