Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Classes | Public Member Functions | List of all members
SkPDFTagTree Class Reference

#include <SkPDFTag.h>

Classes

class  Mark
 

Public Member Functions

 SkPDFTagTree ()
 
 ~SkPDFTagTree ()
 
void init (SkPDF::StructureElementNode *, SkPDF::Metadata::Outline)
 
Mark createMarkIdForNodeId (int nodeId, unsigned pageIndex, SkPoint)
 
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 ()
 

Detailed Description

Definition at line 20 of file SkPDFTag.h.

Constructor & Destructor Documentation

◆ SkPDFTagTree()

SkPDFTagTree::SkPDFTagTree ( )

Definition at line 155 of file SkPDFTag.cpp.

155: fArena(4 * sizeof(SkPDFTagNode)) {}

◆ ~SkPDFTagTree()

SkPDFTagTree::~SkPDFTagTree ( )
default

Member Function Documentation

◆ addNodeAnnotation()

void SkPDFTagTree::addNodeAnnotation ( int  nodeId,
SkPDFIndirectReference  annotationRef,
unsigned  pageIndex 
)

Definition at line 320 of file SkPDFTag.cpp.

320 {
321 if (!fRoot) {
322 return;
323 }
324 SkPDFTagNode** tagPtr = fNodeMap.find(nodeId);
325 if (!tagPtr) {
326 return;
327 }
328 SkPDFTagNode* tag = *tagPtr;
329 SkASSERT(tag);
330
331 SkPDFTagNode::AnnotationInfo annotationInfo = {pageIndex, annotationRef};
332 tag->fAnnotations.push_back(annotationInfo);
333}
#define SkASSERT(cond)
Definition SkAssert.h:116
V * find(const K &key) const
Definition SkTHash.h:479
std::vector< AnnotationInfo > fAnnotations
Definition SkPDFTag.cpp:87

◆ addNodeTitle()

void SkPDFTagTree::addNodeTitle ( int  nodeId,
SkSpan< const char >  title 
)

Definition at line 335 of file SkPDFTag.cpp.

335 {
336 if (!fRoot) {
337 return;
338 }
339 SkPDFTagNode** tagPtr = fNodeMap.find(nodeId);
340 if (!tagPtr) {
341 return;
342 }
343 SkPDFTagNode* tag = *tagPtr;
344 SkASSERT(tag);
345
346 if (tag->fWantTitle) {
347 tag->fTitle.append(title.data(), title.size());
348 // Arbitrary cutoff for size.
349 if (tag->fTitle.size() > 1023) {
350 tag->fWantTitle = false;
351 }
352 }
353}
constexpr T * data() const
Definition SkSpan_impl.h:94
constexpr size_t size() const
Definition SkSpan_impl.h:95
size_t size() const
Definition SkString.h:131
void append(const char text[])
Definition SkString.h:203
SkString fTitle
Definition SkPDFTag.cpp:73
bool fWantTitle
Definition SkPDFTag.cpp:71

◆ createMarkIdForNodeId()

auto SkPDFTagTree::createMarkIdForNodeId ( int  nodeId,
unsigned  pageIndex,
SkPoint  point 
)

Definition at line 209 of file SkPDFTag.cpp.

209 {
210 if (!fRoot) {
211 return Mark();
212 }
213 SkPDFTagNode** tagPtr = fNodeMap.find(nodeId);
214 if (!tagPtr) {
215 return Mark();
216 }
217 SkPDFTagNode* tag = *tagPtr;
218 SkASSERT(tag);
219 while (SkToUInt(fMarksPerPage.size()) < pageIndex + 1) {
220 fMarksPerPage.push_back();
221 }
222 TArray<SkPDFTagNode*>& pageMarks = fMarksPerPage[pageIndex];
223 int markId = pageMarks.size();
224 tag->fMarkedContent.push_back({{point, pageIndex}, markId});
225 pageMarks.push_back(tag);
226 return Mark(tag, tag->fMarkedContent.size() - 1);
227}
constexpr unsigned SkToUInt(S x)
Definition SkTo.h:30
int size() const
Definition SkTArray.h:416
TArray< MarkedContentInfo > fMarkedContent
Definition SkPDFTag.cpp:69

◆ createStructParentKeyForNodeId()

int SkPDFTagTree::createStructParentKeyForNodeId ( int  nodeId,
unsigned  pageIndex 
)

Definition at line 229 of file SkPDFTag.cpp.

229 {
230 if (!fRoot) {
231 return -1;
232 }
233 SkPDFTagNode** tagPtr = fNodeMap.find(nodeId);
234 if (!tagPtr) {
235 return -1;
236 }
237 SkPDFTagNode* tag = *tagPtr;
238 SkASSERT(tag);
239
241
242 int nextStructParentKey = kFirstAnnotationStructParentKey +
243 static_cast<int>(fParentTreeAnnotationNodeIds.size());
244 fParentTreeAnnotationNodeIds.push_back(nodeId);
245 return nextStructParentKey;
246}
const int kFirstAnnotationStructParentKey
Definition SkPDFTag.cpp:23
enum SkPDFTagNode::State fCanDiscard

◆ getRootLanguage()

SkString SkPDFTagTree::getRootLanguage ( )

Definition at line 574 of file SkPDFTag.cpp.

574 {
575 return fRoot ? fRoot->fLang : SkString();
576}
SkString fLang
Definition SkPDFTag.cpp:75

◆ init()

void SkPDFTagTree::init ( SkPDF::StructureElementNode node,
SkPDF::Metadata::Outline  outline 
)

Definition at line 193 of file SkPDFTag.cpp.

193 {
194 if (node) {
195 fRoot = fArena.make<SkPDFTagNode>();
196 fOutline = outline;
197 Copy(*node, fRoot, &fArena, &fNodeMap, false);
198 }
199}
auto make(Ctor &&ctor) -> decltype(ctor(nullptr))

◆ makeOutline()

SkPDFIndirectReference SkPDFTagTree::makeOutline ( SkPDFDocument doc)

Definition at line 550 of file SkPDFTag.cpp.

550 {
551 if (!fRoot || can_discard(fRoot) ||
553 {
554 return SkPDFIndirectReference();
555 }
556
558 OutlineEntry top{{SkString(), Location()}, 0, {}, {}};
559 stack.push_back(&top);
560 create_outline_from_headers(doc, fRoot, stack);
561 if (top.fChildren.empty()) {
562 return SkPDFIndirectReference();
563 }
564 top.emitDescendents(doc);
565 SkPDFIndirectReference outlineRef = doc->reserveRef();
566 SkPDFDict outline("Outlines");
567 outline.insertRef("First", top.fChildren.front().fRef);
568 outline.insertRef("Last", top.fChildren.back().fRef);
569 outline.insertInt("Count", top.fDescendentsEmitted);
570
571 return doc->emit(outline, outlineRef);
572}
static bool can_discard(SkPDFTagNode *node)
Definition SkPDFTag.cpp:248
SkPDFIndirectReference emit(const SkPDFObject &, SkPDFIndirectReference)
SkPDFIndirectReference reserveRef()

◆ makeStructTreeRoot()

SkPDFIndirectReference SkPDFTagTree::makeStructTreeRoot ( SkPDFDocument doc)

Definition at line 355 of file SkPDFTag.cpp.

355 {
356 if (!fRoot || can_discard(fRoot)) {
357 return SkPDFIndirectReference();
358 }
359
361
362 unsigned pageCount = SkToUInt(doc->pageCount());
363
364 // Build the StructTreeRoot.
365 SkPDFDict structTreeRoot("StructTreeRoot");
366 structTreeRoot.insertRef("K", PrepareTagTreeToEmit(ref, fRoot, doc));
367 structTreeRoot.insertInt("ParentTreeNextKey", SkToInt(pageCount));
368
369 // Build the parent tree, which consists of two things:
370 // (1) For each page, a mapping from the marked content IDs on
371 // each page to their corresponding tags
372 // (2) For each annotation, an indirect reference to that
373 // annotation's struct tree element.
374 SkPDFDict parentTree("ParentTree");
375 auto parentTreeNums = SkPDFMakeArray();
376
377 // First, one entry per page.
378 SkASSERT(SkToUInt(fMarksPerPage.size()) <= pageCount);
379 for (int j = 0; j < fMarksPerPage.size(); ++j) {
380 const TArray<SkPDFTagNode*>& pageMarks = fMarksPerPage[j];
381 SkPDFArray markToTagArray;
382 for (SkPDFTagNode* mark : pageMarks) {
383 SkASSERT(mark->fRef);
384 markToTagArray.appendRef(mark->fRef);
385 }
386 parentTreeNums->appendInt(j);
387 parentTreeNums->appendRef(doc->emit(markToTagArray));
388 }
389
390 // Then, one entry per annotation.
391 for (size_t j = 0; j < fParentTreeAnnotationNodeIds.size(); ++j) {
392 int nodeId = fParentTreeAnnotationNodeIds[j];
393 int structParentKey = kFirstAnnotationStructParentKey + static_cast<int>(j);
394
395 SkPDFTagNode** tagPtr = fNodeMap.find(nodeId);
396 if (!tagPtr) {
397 continue;
398 }
399 SkPDFTagNode* tag = *tagPtr;
400 parentTreeNums->appendInt(structParentKey);
401 parentTreeNums->appendRef(tag->fRef);
402 }
403
404 parentTree.insertObject("Nums", std::move(parentTreeNums));
405 structTreeRoot.insertRef("ParentTree", doc->emit(parentTree));
406
407 // Build the IDTree, a mapping from every unique ID string to
408 // a reference to its corresponding structure element node.
409 if (!fIdTreeEntries.empty()) {
410 std::sort(fIdTreeEntries.begin(), fIdTreeEntries.end(),
411 [](const IDTreeEntry& a, const IDTreeEntry& b) {
412 return a.nodeId < b.nodeId;
413 });
414
415 SkPDFDict idTree;
416 SkPDFDict idTreeLeaf;
417 auto limits = SkPDFMakeArray();
418 SkString lowestNodeIdString = SkPDFTagNode::nodeIdToString(
419 fIdTreeEntries.begin()->nodeId);
420 limits->appendByteString(lowestNodeIdString);
421 SkString highestNodeIdString = SkPDFTagNode::nodeIdToString(
422 fIdTreeEntries.rbegin()->nodeId);
423 limits->appendByteString(highestNodeIdString);
424 idTreeLeaf.insertObject("Limits", std::move(limits));
425 auto names = SkPDFMakeArray();
426 for (const IDTreeEntry& entry : fIdTreeEntries) {
427 SkString idString = SkPDFTagNode::nodeIdToString(entry.nodeId);
428 names->appendByteString(idString);
429 names->appendRef(entry.ref);
430 }
431 idTreeLeaf.insertObject("Names", std::move(names));
432 auto idTreeKids = SkPDFMakeArray();
433 idTreeKids->appendRef(doc->emit(idTreeLeaf));
434 idTree.insertObject("Kids", std::move(idTreeKids));
435 structTreeRoot.insertRef("IDTree", doc->emit(idTree));
436 }
437
438 return doc->emit(structTreeRoot, ref);
439}
static std::unique_ptr< SkPDFArray > SkPDFMakeArray(Args... args)
Definition SkPDFTypes.h:135
constexpr int SkToInt(S x)
Definition SkTo.h:29
void appendRef(SkPDFIndirectReference)
void insertObject(const char key[], std::unique_ptr< SkPDFObject > &&)
static bool b
struct MyStruct a[10]
static void mark(SkCanvas *canvas, SkScalar x, SkScalar y, Fn &&fn)
Definition gm.cpp:211
SkPDFIndirectReference fRef
Definition SkPDFTag.cpp:76
static SkString nodeIdToString(int nodeId)
Definition SkPDFTag.cpp:57

The documentation for this class was generated from the following files: