blob: 7c63bf9820ee124e363b09d294f3f68578f21497 [file] [log] [blame]
/*
* 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);
SkString getRootLanguage();
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