| /* | 
 |  * Copyright 2018 Google Inc. | 
 |  * | 
 |  * Use of this source code is governed by a BSD-style license that can be | 
 |  * found in the LICENSE file. | 
 |  */ | 
 |  | 
 | #ifndef SkPDFTag_DEFINED | 
 | #define SkPDFTag_DEFINED | 
 |  | 
 | #include "include/docs/SkPDFDocument.h" | 
 | #include "include/private/base/SkTArray.h" | 
 | #include "src/base/SkArenaAlloc.h" | 
 | #include "src/core/SkTHash.h" | 
 |  | 
 | class SkPDFDocument; | 
 | struct SkPDFIndirectReference; | 
 | struct SkPDFTagNode; | 
 |  | 
 | class SkPDFTagTree { | 
 | public: | 
 |     SkPDFTagTree(); | 
 |     ~SkPDFTagTree(); | 
 |     void init(SkPDF::StructureElementNode*, SkPDF::Metadata::Outline); | 
 |  | 
 |     class Mark { | 
 |         SkPDFTagNode *const fNode; | 
 |         size_t const fMarkIndex; | 
 |     public: | 
 |         Mark(SkPDFTagNode* node, size_t index) : fNode(node), fMarkIndex(index) {} | 
 |         Mark() : Mark(nullptr, 0) {} | 
 |         Mark(const Mark&) = delete; | 
 |         Mark& operator=(const Mark&) = delete; | 
 |         Mark(Mark&&) = default; | 
 |         Mark& operator=(Mark&&) = delete; | 
 |  | 
 |         explicit operator bool() const { return fNode; } | 
 |         int id(); | 
 |         SkPoint& point(); | 
 |     }; | 
 |     // Used to allow marked content to refer to its corresponding structure | 
 |     // tree node, via a page entry in the parent tree. Returns a false mark if | 
 |     // nodeId is 0. | 
 |     Mark createMarkIdForNodeId(int nodeId, unsigned pageIndex, SkPoint); | 
 |     // Used to allow annotations to refer to their corresponding structure | 
 |     // tree node, via the struct parent tree. Returns -1 if no struct parent | 
 |     // key. | 
 |     int createStructParentKeyForNodeId(int nodeId, unsigned pageIndex); | 
 |  | 
 |     void addNodeAnnotation(int nodeId, SkPDFIndirectReference annotationRef, unsigned pageIndex); | 
 |     void addNodeTitle(int nodeId, SkSpan<const char>); | 
 |     SkPDFIndirectReference makeStructTreeRoot(SkPDFDocument* doc); | 
 |     SkPDFIndirectReference makeOutline(SkPDFDocument* doc); | 
 |  | 
 | private: | 
 |     // An entry in a map from a node ID to an indirect reference to its | 
 |     // corresponding structure element node. | 
 |     struct IDTreeEntry { | 
 |         int nodeId; | 
 |         SkPDFIndirectReference ref; | 
 |     }; | 
 |  | 
 |     void Copy(SkPDF::StructureElementNode& node, | 
 |               SkPDFTagNode* dst, | 
 |               SkArenaAlloc* arena, | 
 |               skia_private::THashMap<int, SkPDFTagNode*>* nodeMap, | 
 |               bool wantTitle); | 
 |     SkPDFIndirectReference PrepareTagTreeToEmit(SkPDFIndirectReference parent, | 
 |                                                 SkPDFTagNode* node, | 
 |                                                 SkPDFDocument* doc); | 
 |  | 
 |     SkArenaAlloc fArena; | 
 |     skia_private::THashMap<int, SkPDFTagNode*> fNodeMap; | 
 |     SkPDFTagNode* fRoot = nullptr; | 
 |     SkPDF::Metadata::Outline fOutline; | 
 |     skia_private::TArray<skia_private::TArray<SkPDFTagNode*>> fMarksPerPage; | 
 |     std::vector<IDTreeEntry> fIdTreeEntries; | 
 |     std::vector<int> fParentTreeAnnotationNodeIds; | 
 |  | 
 |     SkPDFTagTree(const SkPDFTagTree&) = delete; | 
 |     SkPDFTagTree& operator=(const SkPDFTagTree&) = delete; | 
 | }; | 
 |  | 
 | #endif |